初期化関数の定義
前回からの続きです。SPILLがInsiderだけでなく、一般に使用できる様になったら、Excel VBAの書法は、
大きく変化していくのでしょう。それに伴い、入門書も大幅に書き換えて欲しいと思います。
(入門書には、Option Explicitが奨励されていますが、VBAには無意味なので、
以下のプログラムには変数定義を行っていません。)
今もまだ一般的でない、テーブルと構造化参照、Rangeと、Rangeと同等に扱える2次元配列について
詳しく見て行く必要があります。
2次元配列を生成する関数L_INITをコンパクトにする為に、
Polymorphismを使いたいのですが、VBAではサポートされていません。
Polymorphism風にしたいので、TypeNameを使った関数を前もって定義します。
Function TN_(R)
TN_ = TypeName(R)
End Function
Function TR_(R, Optional T = "Range")
TR_ = (TypeName(R) = T)
End Function
Function TV_(R, Optional T = "Variant()")
TV_ = TR_(R, T)
End Function
Function TS_(M, Optional N = "", Optional T = "String")
TS_ = TR_(M, T) * TR_(N, T)
End Function
関数L_INITは、自分自身を呼び出すことにより、下記の様に簡潔に定義できます。
L_PAIRを弄っていたら、タイトルを付けられるようにしたかったので、
途中で、Elseif TS_(L1) Then ... を追加しました。
Function L_INIT(M, N, Optional L1 = 1, Optional L2 = 1, Optional S = "")
On Error Resume Next
If TR_(M) Then
S = L_INIT(M.Rows.Count, N, L1, L2)
ElseIf TV_(M) Then
S = L_INIT(UBound(M, 1), N, L1, L2)
ElseIf TS_(M, N) Then
L = Split(M, " "): M = UBound(L) - LBound(L) + 1
T = Split(N, ","): N = UBound(T) - LBound(T) + 1
S = L_INIT(M, N, 0, 0)
For I = 1 To M: S(I, 0) = L(I - 1): Next I
For J = 1 To N: S(0, J) = T(J - 1): Next J
ElseIf TS_(N) Then
T = Split(N, ","): N = UBound(T) - LBound(T) + 1
S = L_INIT(M, N, 0, 1)
For J = 1 To N: S(0, J) = T(J - 1): Next J
ElseIf TS_(L1) Then
T = Split(L1, ",")
N = UBound(T, 1) + 1
S = L_INIT(M, N, 0, 1)
For J = 1 To N: S(0, J) = T(J - 1): Next J
Else
ReDim S(L1 To M, L2 To N)
For J = L2 To N: For I = L1 To M: S(I, J) = "": Next I: Next J
End If
L_INIT = S
End Function
2次元配列を抽象的に扱う為の関数
定義した関数L_INITを使って、ここでは、2つのRange(または2次元配列)を
横につなげる関数L_PAIRと、縦につなげる関数L_CONSを定義します。
関数的プログラムで抽象的に配列を扱うのに、見えてはいけないFor文を関数中に閉じ込めます。
Function L_RMN(R, M, N, Optional S = "")
S = R
M = UBound(S, 1) - LBound(S, 1) + 1
N = UBound(S, 2) - LBound(S, 2) + 1
L_RMN = S
End Function
Function L_PAIR(R1, R2, Optional S = "")
On Error Resume Next
S1 = L_RMN(R1, M1, N1)
S2 = L_RMN(R2, M2, N2)
M = WorksheetFunction.Min(M1, M2)
N = N1 + N2
S = L_INIT(M, N, L1, L2)
For I = 1 To M
For J = 1 To N1: S(I, J) = S1(I, J): Next J
For J = 1 To N2: S(I, J + N1) = S2(I, J): Next J
Next I
L_PAIR = S
End Function
Function L_CONS(R1, R2, Optional S = "")
On Error Resume Next
S1 = L_RMN(R1, M1, N1)
S2 = L_RMN(R2, M2, N2)
N = WorksheetFunction.Min(N1, N2)
M = M1 + M2
S = L_INIT(M, N)
For J = 1 To N
For I = 1 To M1: S(I, J) = S1(I, J): Next I
For I = 1 To M2: S(I + M1, J) = S2(I, J): Next I
Next J
L_CONS = S
End Function
色々、説明が足りてないが、まずはメモなので。