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

13
VBAにおける配列の データ構造と行列 2017-02-04 森下功啓 1

Upload: katsuhiro-morishita

Post on 13-Apr-2017

90 views

Category:

Education


4 download

TRANSCRIPT

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

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

2017-02-04

森下功啓

1

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

変数• 変数は値を格納するための箱のようなものです。• VBAはメモリを節約しつつ高速に計算するために変数に「型」が有ります。箱には格納できる型が決まっています。

• 箱には名前をつけて区別します。この名前が「変数名」です。

https://www.bestcarton.com/item/0093-1.jpg

2.3533 数値を格納した箱型はDouble型である。

foo = 2.3533

foo変数名

2

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

普通の配列• 配列は、連続した箱である。• 「Dim a(2) as Double」の様に宣言して使う。• ↑の丸括弧()の中の数字は最大要素番号である。• 箱には同じ型の変数しか入れられない。• 配列の中に格納する一つ一つの値のことを要素と呼ぶ。• 「a(1)」の様にして要素にアクセスできる。• アクセスに使うカッコ()内の数字を添え字という。

Dim a(2) as Double

a(0) a(1) a(2)a変数名

3

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

ちなみに、これは要素数0の配列である。

Dim a() as Double

4

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

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

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

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

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

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 1321 22 2331 32 33

• すなわち、第1次元目の要素番号を行番号とし、第2次元目の要素番号を列番号とみなす。1だけずれているが。

• つまり、a(1,2)は行列の2行3列目に相当する。7

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

Array型• ところで、VBAにはArray型が用意されている。• Arrayを関数の返り値に指定できない、Variant変数にしか格納できないなどから厳密には型とは言いづらいけども。

• これも配列として利用できる。Dim a as Varianta = Array(2,3,4)

a(0) a(1) a(2)a変数名

Dim a as Varianta = Array()Redim a(2)

or宣言の方法は2通りある。

Arrayのサイズと初期化を行う要素には2と3と4が順に

格納される。Arrayのサイズを変更しながら宣言

8

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

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

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

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

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

Arrayの入れ子と行列• VBAでは、Arrayの入れ子に行列の値を格納することもできる。• この場合、大抵の場合は以下のように扱う。

11 12 1321 22 2331 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

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

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)) + 112

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

13

VBAが分かりやすいとか言い出したのは誰だ・・・