月刊プログラム!
VisualBasic For Excel

Vol_07
2001.MAY.22

Presented by kouta_y
感想等は掲示板、苦情はメールへ。


にこちゃん
今回は「配列変数」について。
他の言語で使う配列より、考え方は簡単なので、覚えるのは楽でしょう。

修正(2002.09.03)
サンプルプログラムをちょっと修正しました。

使い方

まず宣言の仕方ですが、下の様な感じになります。

Dim HAIRETU(10) As String

このように変数を宣言した場合どうなるか?
はい。「HAIRETU」というString型変数が11個宣言されたと考えてください。
何故10個ではなく、11個なのかは後で説明します。(後回し・・・)
まぁ「百聞は一見に如かず」とも言いますので、実際どう使うのか見てみましょう。

Sub Sample()

'配列変数の宣言
Dim HAIRETU(10) As String

'値を代入
HAIRETU(1) = "たろの部屋"
HAIRETU(2) = "管理人はたろ"

'シートに反映
Cells(1, 1).Value = HAIRETU(1)
Cells(2, 1).Value = HAIRETU(2)

End Sub

実行結果


はい。もう、一目瞭然ですね。
使い方はこの通りです。
何事も聞くより、実際やってみる方が分かりいいですね。

ものすごく簡単に言えば、変数に「番号」が付いたと思ってください。

ちなみに、

Cells(1,1).Value = HAIRETU

こんな事は出来ません。


なぜ11個?

これは「下限値」を指定しなかったからです。
「下限」を指定しないと、デフォルトで0(ゼロ)からになるからですね。

通常配列宣言は「To」で区切り、「下限」と「上限」を指定してやります。

Dim HAIRETU(1 To 10)

こうすれば、1〜10までの「インデックス値」を持つ配列変数が宣言され、「要素数」は10個となります。


配列とは?

配列の特徴は、要素の1つ1つがインデックス値を持っている事です。
そして上にも書いた通りメモリに順番に配置されるところです。

インデックス値を持ってるとどーなる。

例えばこんなプログラムが組めます。
Sub Test()
Dim HAIRETU(1 To 100) As Long
Dim i As Long

For i = 1 To 100
    HAIRETU(i) = i
Next

For i = 1 To 100
    Cells(HAIRETU(i), 1) = HAIRETU(i)
Next

End Sub

実行結果


実際には100行目まで続いています。
あまり意味のないプログラムに見えますが、インデックス値を持っているということは、番号によって変数を参照できるという利点があります。
番号で参照できるというのは、かなり有利なことです。
例えば上の例のように、行番号にあわせて数字を表示したい時や、また、ループ文によってその効果を抜群に発揮します。


メモリの配置のされ方

何度も言いますが、「配列」は宣言したと同時にメモリ内に「順番」に確保します。
例えば、
Dim AAA(4) As Integer
と宣言したとします。
「Integer」型というのは2バイト領域です。
要素数は5個です。

ここでは前回と同じくエクセルのシートに例えて、メモリ内の様子を見てみましょう。



これが空の状態です。
セルの1つ1つが1バイトの領域を持っています。
この状態で上で書いた配列変数を宣言したとします。
すると、



となります。
配列変数AAAの先頭アドレスは「A1」となります。
AAA(3)のアドレスは「G1」となります。


こんな感じで「順番」に確保されていきます。
型の領域は2バイトなので、2ステップづつになります。
まぁこの辺は参考程度に頭に入れておいてください。


動的配列と静的配列

配列には2種類あり、それが動的配列静的配列です。
動的、静的という言葉はあとあとでも使いますので、覚えておいてください。
上で書いたサンプルは「静的配列」になります。
静的とは、辞書で引くと、
『 動かないものとして考えた様子 』
だそうです。
つまり静的配列とは、要素数を動かせない配列という意味になります。
動かせないというのは、変えられないという意味です。

対して動的とは、
『 変動している様子 』
だそうで、つまり静的とは逆に要素数を動かせる配列という意味になります。


ではここで、静的、動的両方の宣言の仕方を見てみましょう。

Dim seiteki(5) As Integer    ' 静的変数の宣言
Dim douteki()  As Integer    ' 動的変数の宣言
静的の方はわかると思います。
0から5まで6個の要素を持ちます。
さて、動的の方ですが()の中は空です。
つまり動的配列は宣言した時点では領域はゼロ。当然このままでは使い物になりません。
なんせ領域が0ですので、何も格納させれないですし、参照する事もできません。

Cells(1, 1).Value = douteki(0) ' エラーになる

宣言した時点では、こんな事をするとエラーになり処理は中断してしまいます。
動的配列は、宣言したら領域の確保を行い、それから使う事ができます。

領域を確保する

では動的配列の領域を確保してみましょう。
領域の確保はReDimステートメントを使います。

Dim douteki() As Integer        ' 宣言する
ReDim douteki(5) As Integer     ' 領域の確保
Cell(1, 1).Value = douteki(0)   ' 参照できる
ReDimステートメントは、配列の要素を宣言しなおすといった感じで考えてください。
よってここでは0から5まで6個の要素をもった配列が宣言されました。
宣言時に型を明示したなら、ReDimの時の Integer はなくても、Integer 型として領域の確保は行われます。

動的配列の使い道

これもいろいろ役に立ちます。
まず一番のメリットは、静的配列とは違い動的にメモリの確保を行うので常時メモリを消費しないという点があげられます。
しかし、いちいち ReDim を行わないといけないので実行時の負担が大きいというデメリットもあります。
静的、動的配列どちらを使えばいいというのは、時と場合によりけりです。
ただ、動的配列を無理矢理使いまわすというのはお勧めできません。
時には上限を決めて、静的配列にした方がスマートなプログラムになる場合もあります。



多次元配列

配列には動的と静的、2種類あると言いましたが、さらにもう1つ多次元配列と呼ばれるものもあります。
今までのサンプルは全て「1次元配列」になります。
多次元配列とはいわゆる「テーブル」と言われるもので、n×nのような宣言と参照が出来ます。
とにかくやってみましょう


Sub TAZIGEN()
Dim AAA(2, 1) As Byte
Dim i As Long, j As Long

For i = 0 To 1
    For j = 0 To 2
        Cells(j + 1, i + 1).Value = VarPtr(AAA(j, i))
    Next
Next

End Sub

実行結果

VarPtr関数とは、変数のアドレスを取得するVBの隠し関数で、実際にその変数のアドレス番地を取得します。
まず宣言したら、下表のようなテーブルが宣言されたと考えてください。



これはもちろん多次元配列を分かりやすくしただけであって、実際のメモリは、



この様になっています。



終わり

今回はこれで終わりですが、実際の配列というのは結構奥の深いものです。
それは徐々にやっていければ良いなと思っています。