目次

目的

  • 一つの変数で複数の値を保持できる「配列」というものを使用する。
  • マクロを一行ずつ実行して配列の中身を見てみる。
a(0) , a(1) , a(2) の 3 つのデータを保持できる配列を定義。
a(0) , a(1) , a(2) の 3 つのデータを保持できる配列を定義。
a(0) , a(1) , a(2) に別々の値を代入できる。
a(0) , a(1) , a(2) に別々の値を代入できる。
マクロが終了するとパソコンのメモリーから消去される。
マクロが終了するとパソコンのメモリーから消去される。
VBE のローカルウィンドウで配列を可視化。
VBE のローカルウィンドウで配列を可視化。

目次まで戻る

配列定義

  1. 下記コードを記述してみます。
    Sub 配列定義()
    Dim a(3)
    End Sub
    1. 「Dim a(3)」
      • 「Dim 変数名( 配列のインデックス番号の最大値 ) 」の書式になっています。
      • a(0) , a(1) , a(2) , a(3) の 4 つの要素が生成されます。
      • 「Dim a( 0 To 3 )」としても同じ結果になると思います。
      • 配列のインデックス番号の範囲は「Dim 変数名( 最小値 To 最大値 )」の書式で定義可能なようです。
      • 「Dim a( 2 To 3 )」とすると a(2) , a(3) の要素が生成されます。
      • 「Dim a(3) As String」のようにデータ型指定も可能です。上記マクロの場合、データ型を指定していないのでバリアント型の配列になります。
  2. 下記操作を行ってみます。上記マクロを一行ずつ実行(ステップインという)してみます。
    ユーザーの操作 その時の VBE コード/ローカルウィンドウの状態
    Sub から End Sub の間のどこかをクリック。文字入力カーソルを実行するマクロに合わせるのが目的です。
    文字入力カーソルが合いました。
    文字入力カーソルが合いました。
    何も表示されていません。
    何も表示されていません。

    「デバッグ > ステップイン」または「F8」キーを押します。

    ステップイン
    ステップイン
    マクロの実行が開始されました。
    マクロの実行が開始されました。
    変数「a」の左に「+」ボタンが表示されました。
    変数「a」の左に「+」ボタンが表示されました。
    ローカルウィンドウの「a」の左の「+」ボタンをクリックしてみます。
    配列の中身が表示されました。a(0) , a(1) , a(2) , a(3) の 4 つの要素が生成されています。
    配列の中身が表示されました。a(0) , a(1) , a(2) , a(3) の 4 つの要素が生成されています。
    F8 キーを押します。
    End Sub まで進みました。
    End Sub まで進みました。

    ローカルウィンドウは変化なし。

    F8 キーを押します。
    マクロが終了しました。
    マクロが終了しました。
    リセットされました。
    リセットされました。

目次まで戻る

値代入, 変更, 取得

  1. 下記コードを記述してみます。
    Sub 値代入_変更_取得()
    Dim a(3)
    '値代入
    a(0) = "A"
    a(1) = "B"
    a(2) = "C"
    a(3) = "D"
    '値変更
    a(0) = "AA"
    a(2) = "CC"
    '値取得
    Debug.Print a(0)
    Debug.Print a(1)
    Debug.Print a(2)
    Debug.Print a(3)
    End Sub
    1. 「a(0) = "A"」
      • 配列のインデックス番号を指定して、値を代入しています。
  2. 上記マクロをステップインで実行してみます。
    ユーザーの操作 その時の VBE コード/ローカルウィンドウの状態
    Sub ~ End Sub の間をクリック。
    文字の入力カーソルが合いました。
    文字の入力カーソルが合いました。
    何も表示されていません。
    何も表示されていません。
    F8 キーを押す。
    マクロの実行が開始されました。
    マクロの実行が開始されました。
    変数 a が表示されています。
    変数 a が表示されています。

    ローカルウィンドウの「a」の左の「+」ボタンをクリックします。

    配列の各要素が表示されています。値は「Empty」になっています。
    配列の各要素が表示されています。値は「Empty」になっています。
    F8 キーを押す。
    マクロが進んでいます。
    マクロが進んでいます。

    ローカルウィンドウに変化なし。

    F8 キーを押す。
    a(0) = "A" の行が実行されました。
    a(0) = "A" の行が実行されました。
    a(0) に A の値が代入されました。
    a(0) に A の値が代入されました。
    F8 キーを押す。(3 回繰り返す)
    マクロが進んでいます。
    マクロが進んでいます。
    値の代入が完了しました。
    値の代入が完了しました。
    F8 キーを押す。(2 回繰り返す)
    マクロが進んでいます。
    マクロが進んでいます。
    値の変更が完了しました。
    値の変更が完了しました。
    F8 キーを押す。(4 回繰り返す)
    マクロが進んでいます。
    マクロが進んでいます。
    VBE イミディエイトウィンドウへの出力結果です。値が取得出来ています。
    VBE イミディエイトウィンドウへの出力結果です。値が取得出来ています。
    F8 キーを押す。

    マクロが終了しました。

    ローカルウィンドウがリセットされました。

目次まで戻る

配列かどうか

Sub 配列になっているか調べる()
Dim a(3)
Debug.Print IsArray(a)
Debug.Print TypeName(a)
Debug.Print VarType(a) 'vbArray(8192) + vbVariant(12) を足した値
End Sub
True
Variant()
8204
True
Variant()
8204
Sub 配列になっているか調べる2()
Dim a '配列ではない変数
Debug.Print IsArray(a)
Debug.Print TypeName(a)
Debug.Print VarType(a) '結果 0 は vbEmpty
End Sub
False
Empty
0
False
Empty
0

目次まで戻る

配列ループ

Sub 配列ループ()
Dim a(2)
a(0) = "A"
a(1) = "B"
a(2) = "C"

Dim b
For Each b In a
Debug.Print b
Next
End Sub
イミディエイトウィンドウへの出力結果です。
イミディエイトウィンドウへの出力結果です。
Sub 配列ループ_for()
Dim a(2)
a(0) = "A"
a(1) = "B"
a(2) = "C"
Debug.Print "最初のキー番号="; LBound(a)
Debug.Print "最後のキー番号="; UBound(a)

Dim i
For i = LBound(a) To UBound(a)
Debug.Print i; a(i)
Next
End Sub
  1. 「LBound(a)」
    インデックス番号の最小値を取得しています。
  2. 「UBound(a)」
    インデックス番号の最大値を取得しています。
イミディエイトウィンドウへの出力結果です。
イミディエイトウィンドウへの出力結果です。

目次まで戻る

インデックス番号 , 要素数変更

Option Base 1 '0 か 1
Sub OptionBaseステートメントで配列の開始番号を1に変更()
Dim a(3)
a(1) = "A"
a(2) = "B"
a(3) = "C"
End Sub
  1. 「Option Base 1」
    配列の開始番号の既定値を 0 か 1 に設定できます。
ブレークポイントでマクロ一時停止中。
ブレークポイントでマクロ一時停止中。
a(1) から a(3) に配列になっている。
a(1) から a(3) に配列になっている。
Sub 配列定義の時に配列のインデックス番号を2から4の範囲に変更()
Dim a(2 To 4)
a(2) = "A"
a(3) = "B"
a(4) = "C"
End Sub
マクロ一時停止中。
マクロ一時停止中。
a(2) から a(4) の範囲になっている。
a(2) から a(4) の範囲になっている。
Sub 動的配列ではない配列の要素数変更を試みる()
Dim a(3)
ReDim a(5) '要素を二つ増やそうとしてみる
End Sub
  1. 動的配列ではない場合、要素数を変更できないようです。
コンパイルエラー
配列は既に宣言されています。
コンパイルエラー
配列は既に宣言されています。
Sub インデックス番号をマイナスからスタートする()
Dim a(-3 To 3)
Debug.Print LBound(a)
Debug.Print UBound(a)
a(-3) = "A"
a(0) = "B"
a(3) = "C"
End Sub
(図 1 )インデックス番号が -3 からスタートしている。
(図 1 )インデックス番号が -3 からスタートしている。
LBound , UBound の取得結果。
LBound , UBound の取得結果。

目次まで戻る

動的配列

後で配列長を変更可能な動的配列を定義してみます。

Sub 動的配列定義()
Dim a()
End Sub
F8 キーで一行ずつ実行。マクロ一時停止中。
F8 キーで一行ずつ実行。マクロ一時停止中。
その時のローカルウィンドウの状態。Variant() となっています。要素数が決まっていないので空の ( ) になっていいます。
その時のローカルウィンドウの状態。Variant() となっています。要素数が決まっていないので空の ( ) になっていいます。
Sub 動的配列要素数変更()
Dim a()
ReDim a(2)
End Sub
F8 キーで一行ずつ実行。マクロ一時停止中。
F8 キーで一行ずつ実行。マクロ一時停止中。
a(0) , a(1) , a(2) の 3 つの要素が生成されている。変数 a の型が Variant(0 to 2) に変わっている。
a(0) , a(1) , a(2) の 3 つの要素が生成されている。変数 a の型が Variant(0 to 2) に変わっている。
Sub 動的配列のインデックス番号の開始番号と最終番号取得()
Dim a()
ReDim a(2)
Debug.Print "インデックス番号開始="; LBound(a)
Debug.Print "インデックス番号最終="; UBound(a)
End Sub
0 , 2 が取得出来ている。
0 , 2 が取得出来ている。
Sub 動的配列の値代入()
Dim a()
ReDim a(2)
a(0) = "A"
a(1) = "B"
a(2) = "C"
End Sub
F8 キーで一行ずつ実行。マクロ一時停止中。
F8 キーで一行ずつ実行。マクロ一時停止中。
A , B , C が代入されている。
A , B , C が代入されている。
Sub 動的配列のデータを残したまま要素数変更()
Dim a()
ReDim a(2)
a(0) = "A"
a(1) = "B"
a(2) = "C"
ReDim Preserve a(4)
End Sub

Redim の後に Preserve を付加すると元のデータを残したまま要素数を変更できるようです。

マクロ一時停止中。Redim の後に Preserve を記述している。
マクロ一時停止中。Redim の後に Preserve を記述している。
A , B , C の値はそのままで要素数が増えている。
A , B , C の値はそのままで要素数が増えている。
Sub 動的配列のデータをリセットして要素数変更()
  Dim a()
  ReDim a(2)
  a(0) = "A"
  a(1) = "B"
  a(2) = "C"
  ReDim a(6)
End Sub
マクロ一時停止中。Redim(6) 実行前。
マクロ一時停止中。Redim(6) 実行前。
Redim(6) 実行前。A , B , C が代入されている。
Redim(6) 実行前。A , B , C が代入されている。
Redim(6) 実行後。マクロ一時停止中。
Redim(6) 実行後。マクロ一時停止中。
Redim(6) 実行後。値がリセットされている。
Redim(6) 実行後。値がリセットされている。
Sub 動的配列のLBound_UBound取得でエラーが発生する例()
Dim a() '動的配列は要素数を指定しない '結果は下図1
Debug.Print "エラー番号出力 1 回目="; Err.Number
On Error Resume Next 'エラー発生時、次の行から再開する設定
Debug.Print LBound(a) '配列の要素が無い状態なのでエラー
Debug.Print "エラー番号出力 2 回目="; Err.Number
Debug.Print UBound(a) '配列の要素が無い状態なのでエラー
Debug.Print "エラー番号出力 3 回目="; Err.Number
If Err.Number <> 0 Then
Debug.Print "エラー発生"; Err.Number; Err.Description
End If
On Error GoTo 0 '上記 On Error Resume Next を無効化
'Debug.Print LBound(a)'行頭のコメントを外すとエラー発生
ReDim a(2) '要素数設定 '結果は下図2
Debug.Print "インデックス開始番号="; LBound(a)
Debug.Print "インデックス最終番号="; UBound(a)
a(0) = "A"
a(1) = "B"
a(2) = "C"
ReDim Preserve a(4) 'データは残したまま要素数設定 '結果は下図3
ReDim a(6) 'データをリセットして要素数設定 '結果は下図4
End Sub
(図 1 )動的配列宣言直後。要素がない状態。
(図 1 )動的配列宣言直後。要素がない状態。
(図 2 )要素が生成されている。
(図 2 )要素が生成されている。
(図 3 )元の値は残したまま要素が追加されている。
(図 3 )元の値は残したまま要素が追加されている。
(図 4 )値がリセットされている。
(図 4 )値がリセットされている。
エラー番号出力 1 回目= 0 
エラー番号出力 2 回目= 9 
エラー番号出力 3 回目= 9 
エラー発生 9 インデックスが有効範囲にありません。
インデックス開始番号= 0 
インデックス最終番号= 2
エラー番号出力 1 回目= 0
エラー番号出力 2 回目= 9
エラー番号出力 3 回目= 9
エラー発生 9 インデックスが有効範囲にありません。
インデックス開始番号= 0
インデックス最終番号= 2

目次まで戻る

関数で配列作成

Sub Array関数で配列作成()
Dim a
a = Array("A", "B", "C") '結果は下図 1
ReDim Preserve a(4) '結果は下図 2
End Sub
(図 1 )配列が生成されている。
(図 1 )配列が生成されている。
(図 2 )要素が増えている。
(図 2 )要素が増えている。
Sub Split関数で配列作成()
Dim a, b
a = Split("A,B,C", ",", -1) '-1 は全て
b = Split("A,B,C", ",", 2) '2 個の要素を生成
End Sub
配列 a,b が作成されている。
配列 a,b が作成されている。
Sub 縦並びデータ限定_一次元配列作成()
Dim a
a = WorksheetFunction.Transpose(Range("A1:A3")) '元データは図 1 '結果は下図 2
End Sub
(図 1 )元データ
(図 1 )元データ
(図 2 )一次元配列
(図 2 )一次元配列

目次まで戻る

多次元配列

Sub セル範囲から多次元配列作成()
Dim a
a = Range("A1:C3") '元データは下図 1 '結果は下図 2
Dim b
For Each b In a
Debug.Print b '結果は下図 3
Next
End Sub
(図 1 )元データ
(図 1 )元データ
(図 2 )多次元配列
(図 2 )多次元配列
(図 3 )イミディエイトウィンドウへの出力結果です。
(図 3 )イミディエイトウィンドウへの出力結果です。
Sub 多次元配列の指定要素の値を取得()
  Dim a
a = Range("A1:C3") '元データは下図 1 '結果は下図 2
Debug.Print a(1, 1) '結果は下図 3
  Debug.Print a(2, 2)
  Debug.Print a(3, 3)
End Sub
(図 1 )元データ
(図 1 )元データ
(図 2 )多次元配列
(図 2 )多次元配列
(図 3 )イミディエイトウィンドウへの出力結果です。
(図 3 )イミディエイトウィンドウへの出力結果です。
Sub 配列定義時に多次元配列を生成()
Dim a(0 To 2, 0 To 3)
End Sub
多次元配列
多次元配列
Sub 動的多次元配列の要素数を変更()
Dim a()
ReDim a(0 To 1, 0 To 2) '0to1 が一次元目 , 0to2 が二次元目
a(0, 0) = "A"
a(1, 2) = "B" '結果は下図 1
'ReDim Preserve a(2, 3) '実行時エラー'9' インデックスが有効範囲にありません
ReDim Preserve a(1, 3) 'Preserve を付けた場合最後の次元(今回は二次元目)のみ上限を変更可能なようです '結果は下図 2
ReDim a(2, 3) 'Preserve を付けない場合一,二次元目の上限を変更可能なようです '結果は下図 3
End Sub
(図 1 )多次元配列
(図 1 )多次元配列
(図 2 )Redim Preserve 後
(図 2 )Redim Preserve 後
(図 3 )Redim 後
(図 3 )Redim 後

目次まで戻る

配列で入力

Sub 表の見出しを配列で入力する()
Range("A1:C1") = Array("A", "B", "C")
End Sub
上記マクロを白紙のワークシートで実行します。
上記マクロを白紙のワークシートで実行します。
見出しを入力出来ました。
見出しを入力出来ました。
Sub 表の見出しを配列で入力する2()
Cells.Delete
Dim a(2)
a(0) = "A"
a(1) = "B"
a(2) = "C"
Range("A1:C1") = a
End Sub
見出しを入力出来ました。
見出しを入力出来ました。

テスト環境

  • Windows 10(64 ビット)
  • Microsoft Office Excel 2003

以上、閲覧ありがとうございました。

目次まで戻る

同じカテゴリの投稿(Excel VBA)

前後の投稿