○第143回目 ユーザー関数(条件付SUMPRO関数、その2)
マクロの中での記述
a = 条件付SUMPRO_02("D20,A42,A20,42,B20,C21")
または、
a = 条件付SUMPRO_02(D18) ‘D18には、D20,A42,A20,42,B20,C21が入っている。
先頭行、末尾行の記述
Function 条件付SUMPRO_02(ByVal NN) As Double
【中味】
End Function
中味の記述
パラメータ='D20,A42,A20,42,B20,C21
まずはパラメータの説明です。
D20…セルの座標です
A42…セルの座標です。場合によっては数値が入ってきます
A20…セルの座標です
42…行数です
B20…セルの座標です
C21…セルの座標です。省略された場合は、機能的には、B列に対するSUM関数となります。
D20のセルにある年齢から
A42のセルにある年齢までについて
B20からはじまる項目と
C21からはじまる項目とを掛け合わせた総和を求める。
(参照すべき基準年齢は、A20からA42にはいっている)
Range().Selectが使えませんので、違う方法で列・行を求めます。
流れです。
1.パラメータを分解します(mm(i))
2.座標の場合、それぞれの項目から、列・行を求めます(mm_retu(i)、mm_gyo(i))
3.列記号は列番号に変換します。(mm_retu(i)の置き換え)
4.数値情報の場合、セルの内容を求めます(XX,XX9)
5.積和をとる範囲(最初と最後の行数)を求めます(gyo91、gyo99)
6.関数式を作ります
1.パラメータを分解します(mm(i))
nn0 = NN
for i = 1 to 5
p1 = InStr(NN, ",")
mm(i) = Left(NN, p1 - 1)
NN = Mid(NN, p1 + 1)
next
mm(6) = NN
If mm(6) = "" Then flag1 = 1
2.座標の場合、それぞれの項目から、列・行を求めます(mm_retu(i)、mm_gyo(i))
ii0 = 6
If flag1 = 1 Then
ii0 = 5
mm_retu(6) = ""
mm_gyo(6) = ""
End If
For i = 1 To ii0
mm(i) = UCase(mm(i))
If Left(mm(i), 1) Like "[0-9]" = True Then '一桁目が数字
mm_retu(i) = ""
mm_gyo(i) = Val(mm(i))
ElseIf Mid(mm(i), 2, 1) Like "[A-Z]" = True Then '二桁目が英字
mm_retu(i) = Left(mm(i), 2)
mm_gyo(i) = Mid(mm(i), 3)
Else '二桁目が数字
mm_retu(i) = Left(mm(i), 1)
mm_gyo(i) = Mid(mm(i), 2)
End If
Next i
3.列記号は列番号に変換します。(mm_retu(i)の置き換え)
省略
4.数値情報の場合、セルの内容を求めます(XX,XX9)
変数を数値に置換えて、通常の変数名の変数に入れる
パラメータ='D20,A42,A20,42,B20,C21
retu00 = Val(mm_retu(1)) 集計したい最初の参照値が入っているセルの列番号
gyo00 = Val(mm_gyo(1)) 集計したい最初の参照値が入っているセルの行番号
retu09 = Val(mm_retu(2)) 集計したい最後の参照値が入っているセルの列番号 数値で入っていた場合、ここが0になります
gyo09 = Val(mm_gyo(2)) 集計したい最後の参照値が入っているセルの行番号
retu11 = Val(mm_retu(3)) 集計の参照となる先頭セルの列番号
gyo11 = Val(mm_gyo(3)) 集計の参照となる先頭セルの行番号
retu19 = retu11 集計の参照となる最後セルの列番号
gyo19 = Val(mm_gyo(4)) 集計の参照となる最後セルの行番号
retu21 = Val(mm_retu(5)) 集計項目1の先頭セルの列番号
gyo21 = Val(mm_gyo(5)) 集計項目1の先頭セルの行番号
retu31 = Val(mm_retu(6)) 集計項目2の先頭セルの列番号
gyo31 = Val(mm_gyo(6)) 集計項目2の先頭セルの行番号
gyo_cnt1 = gyo19 - gyo11 + 1 集計する項目数
XX = Cells(gyo00, retu00) 集計したい最初の参照値
If retu09 = 0 Then
XX9 = gyo09 集計したい最後の参照値。数値の場合
Else
XX9 = Cells(gyo09, retu09) 集計したい最後の参照値。座標の場合
End If
5.積和をとる範囲(最初と最後の行数)を求めます(gyo_cnt91、gyo_cnt99)
For i = 1 To gyo_cnt1
If XX = Cells(gyo11 + i - 1, retu11) Then Exit For
Next
gyo_cnt91 = i '先頭からの相対的な行数
For i = 1 To gyo_cnt1
If XX9 = Cells(gyo11 + i - 1, retu11) Then Exit For
Next
gyo_cnt99 = i '先頭からの行数
6.関数式を作ります
本体のSumProduct関数を使用します。
If flag1 = 1 Then '1項目しか指定していない場合
条件付SUMPRO_02 = Application.WorksheetFunction.Sum(Range(Cells(gyo21 + gyo_cnt91 - 1, retu21), Cells(gyo21 + gyo_cnt99 - 1, retu21)))
Else
条件付SUMPRO_02 = Application.WorksheetFunction.SumProduct(Range(Cells(gyo21 + gyo_cnt91 - 1, retu21), Cells(gyo21 + gyo_cnt99 - 1, retu21)), Range(Cells(gyo31 + gyo_cnt91 - 1, retu31), Cells(gyo31 + gyo_cnt99 - 1, retu31)))
End If
こんなものでしょうか。
ここでこんな問題が出てきました。
仕事ではたまにシミュレーション系のものがあります。その場合は、諸々の機能が複数年必要であり、通常は計算式のコピーで対応可能です。
しかし、この関数はパラメータとセットになっています。これが単純にコピーできないのです。パラメータ(D20,A42,A20,42,B20,C21)は文字ですからコピーしても座標は変わりません。ここでいうA列は変わらなくてもいいのですが、他のものは変わってほしいです。
何とかならないのでしょうか。
2010年4月25日日曜日
登録:
コメントの投稿 (Atom)

0 件のコメント:
コメントを投稿