VBAにおける配列の
データ構造と行列
2017-02-04
森下功啓
1
変数
• 変数は値を格納するための箱のようなものです。
• VBAはメモリを節約しつつ高速に計算するために変数に「型」
が有ります。箱には格納できる型が決まっています。
• 箱には名前をつけて区別します。この名前が「変数名」です。
https://www.bestcarton.c
om/item/0093-1.jpg
2.3533 数値を格納した箱
型はDouble型である。
foo = 2.3533
foo
変数名
2
普通の配列
• 配列は、連続した箱である。
• 「Dim a(2) as Double」の様に宣言して使う。
• ↑の丸括弧()の中の数字は最大要素番号である。
• 箱には同じ型の変数しか入れられない。
• 配列の中に格納する一つ一つの値のことを要素と呼ぶ。
• 「a(1)」の様にして要素にアクセスできる。
• アクセスに使うカッコ()内の数字を添え字という。
Dim a(2) as Double
a(0) a(1) a(2)a
変数名
3
ちなみに、これは要素数0の配列である。
Dim a() as Double
4
2次元配列
• 配列は多次元に拡張できる。
• 例えば2次元であれば「 Dim a(2,3) as Double 」の様に宣言する。
• この例では、1次元目の最大要素番号が2で、2次元目の最大要素番
号が3だ。
Dim a(2,3) as Double
a(0,0) a(0,1) a(0,2) a(0,3)
a(1,0) a(1,1) a(1,2) a(1,3)
a(2,0) a(2,1) a(2,2) a(2,3)
a
変数名
5
UBound()は引数の最大要素番号を返す関数である。
変数aが1次元配列の場合、UBound(a)はaの最大要素番号である。
ところで、aが2次元配列の場合はUBound()の使い方が変わる。
例えば、Dim a(2,3) as Double という2次元配列がある場合、UBound(a, 1)はaの1次元
目の最大要素番号の2を返す。
C#などでもオーバーロード機能を使って引数によって関数の挙動を変える機能があるが、
この使い方は本当にわかりにくい。MicrosoftとExcel VBAの信奉者に文句を言いたい。
6
2次元配列と行列
• 行列をVBAで計算する場合、2次元配列に行列の値を格納する。
• 大抵の場合は以下のように扱う。
a(0,0) a(0,1) a(0,2)
a(1,0) a(1,1) a(1,2)
a(2,0) a(2,1) a(2,2)
11 12 13
21 22 23
31 32 33
• すなわち、第1次元目の要素番号を行番号とし、第2次元目の要
素番号を列番号とみなす。1だけずれているが。
• つまり、a(1,2)は行列の2行3列目に相当する。
7
Array型
• ところで、VBAにはArray型が用意されている。
• Arrayを関数の返り値に指定できない、Variant変数にしか格納
できないなどから厳密には型とは言いづらいけども。
• これも配列として利用できる。
Dim a as Variant
a = Array(2,3,4)
a(0) a(1) a(2)a
変数名
Dim a as Variant
a = Array()
Redim a(2)
or
宣言の方法は2通りある。
Arrayのサイズと初期化を行う
要素には2と3と4が順に
格納される。
Arrayのサイズを変更しながら宣言
8
Arrayの入れ子
• Arrayはその要素にArrayを入れることができる。マトリョーシ
カのような構造をネスト(入れ子)構造といいます。
• また、この様に配列の中の配列を持つ構造をジャグ配列という。
a(0) a(1) a(2)
row0(0) row0(1) row0(2) row1(0) row1(1) row1(2) row2(0) row2(1) row2(2)
row0 = Array(11, 12, 13)
row1 = Array(21, 22, 23)
row2 = Array(31, 32, 33)
a = Array(row0, row1, row2)
a(0)(0) a(2)(2)a(2)(0)a(1)(1)a(0)(2) 9
a(0) a(1) a(2)
row0(0) row0(1) row0(2) row1(0) row1(1) row1(2) row2(0) row2(1) row2(2)
UBound()は引数の最大要素番号を返す関数である。
UBound(a)はaの最大要素番号である。下の例では、大枠の箱の数-1となる。
UBound(a(0))はaの第1要素の最大要素番号である。下の例では、a(0)の箱の数-1となる。
10
Arrayの入れ子と行列
• VBAでは、Arrayの入れ子に行列の値を格納することもできる。
• この場合、大抵の場合は以下のように扱う。
11 12 13
21 22 23
31 32 33
a(0) a(0)(0) a(0)(1) a(0)(2)
a(1)(0) a(1)(1) a(1)(2)
a(2)(0) a(2)(1) a(2)(2)
a(1)
a(2)
• すなわち、第1要素番号を行番号とし、第2要素番号を列番号と
みなす。1だけずれているが。
• つまり、a(1)(2)は行列の2行3列目に相当する。
11
2次元配列とArrayの入れ子の違い
2次元配列 Arrayの入れ子
a(i, j)でアクセス a(i)(j)でアクセス
特定の行だけ取り出すことはできない
行ベクトルの取り出しが簡単
例:row = a(1)
Range()関数を使ってcellに貼り付け
られる
例:Range(”A1:C3”) = a
Range関数を使ってcellに貼り付けら
れない
←文法的に関数に代入しているようで
そもそも気持ち悪いのだが。
行数は以下で得られる。
UBound(a, 1) + 1
列数は、UBound(a, 2) + 1
行数は以下で得られる。
UBound(a) + 1
列数は、UBound(a(0)) + 1
12
13
VBAが分かりやすいとか言い出したのは誰だ・・・

VBAにおける配列の データ構造と行列