HOME > 即効テクニック集 > Excel VBA > その他関連のテクニック > 動的配列の初期値を設定する
その他関連のテクニック

動的配列の初期値を設定する

(Excel 97/2000/2002/2003/2007)
動的配列とは、マクロのコード中に要素数を変更できるような配列です。
一般的な配列は

Dim Files(3) As String
のように、要素数を指定して宣言しますが、動的配列は
Dim Files() As String
と、宣言時には要素数を指定しません。そして、マクロのコード中で
ReDim Files(3)
のように要素数を指定します。 マクロを実行してみないと、いくつの要素が必要なのかわからないようなときに便利です。 たとえば、Windowsフォルダに存在するファイルのうち、サイズが1MBを越えるファイルの名前だけを動的配列に格納するようなマクロを考えてみましょう。
Sub Sample1()
  Dim Files() As String          ''動的配列を宣言する
  Dim buf As String, n As Long
  buf = Dir("C:\Windows\*.*")
  Do While buf <> ""
    If FileLen("C:\Windows\" & buf) > 1024000 Then
      n = UBound(Files) + 1  ''直前の大きさに+1する
      ReDim Files(n)         ''新しい大きさを定義する
      Files(n) = buf         ''そこにファイル名を格納する
    End If
    buf = Dir()
  Loop
  MsgBox UBound(Files) & "個あります"
End Sub
配列の大きさ(最も大きいインデックス値)は、UBound関数で取得できます。 Dir関数でファイルを1つずつ取得して、もしサイズが1MBを越えていたら、配列のサイズを、直前のサイズに1を加えた大きさにReDimしてから格納します。 考え方に間違いはありませんが、上記のマクロを実行するとエラーになります。 宣言してから、まだ一度も要素数を定義していない動的配列は、UBound関数で要素数を取得しようとするとエラーになるからです。 2回目以降は上記のコードでうまくいきますが、かんじんの1回目でエラーになるわけです。 これは、ついやってしまうミスです。 こうしたとき、とりあえず要素数を1回でも定義すればいいので、次のように対処することがあります。
Sub Sample1()
  Dim Files() As String
  Dim buf As String, n As Long
  ReDim Files(0)    ''とりあえず要素数を定義する
  buf = Dir("C:\Windows\*.*")
  Do While buf <> ""
    If FileLen("C:\Windows\" & buf) > 1024000 Then
      n = UBound(Files) + 1
      ReDim Files(n)
      Files(n) = buf
    End If
    buf = Dir()
  Loop
  MsgBox UBound(Files) & "個あります"
End Sub   
これならうまくいきます。しかし、何となくスマートさに欠けます。 こんなときは、動的配列の宣言と最初の要素数定義を一度で済ませましょう。
Sub Sample1()
  Dim buf As String, n As Long
  ReDim Files(0)
  buf = Dir("C:\Windows\*.*")
  Do While buf <> ""
    If FileLen("C:\Windows\" & buf) > 1024000 Then
      n = UBound(Files) + 1
      ReDim Files(n)
      Files(n) = buf
    End If
    buf = Dir()
  Loop
  MsgBox UBound(Files) & "個あります"
End Sub   
ReDimステートメントは、動的配列の要素数を変更するだけでなく、新しく動的配列を宣言することも可能です。 ヘルプにもちゃんと記載されています。 もちろん、変数の宣言を強制しているモジュールでも使用できます。 たとえば、次のような使い方も可能です。
Sub Sample2()
  ReDim UserName(2)
  UserName(1) = "tanaka"
  UserName(2) = "suzuki"
  ReDim Preserve UserName(3)
  UserName(3) = "yamada"
End Sub   
覚えておくと、何かのときに役立つかもしれません。