目次
目的
- 一つの変数で複数の値を保持できる「配列」というものを使用する。
- マクロを一行ずつ実行して配列の中身を見てみる。
配列定義
- 下記コードを記述してみます。
Sub 配列定義()
Dim a(3)
End Sub- 「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」のようにデータ型指定も可能です。上記マクロの場合、データ型を指定していないのでバリアント型の配列になります。
- 「Dim a(3)」
- 下記操作を行ってみます。上記マクロを一行ずつ実行(ステップインという)してみます。
ユーザーの操作 その時の VBE コード/ローカルウィンドウの状態 Sub から End Sub の間のどこかをクリック。文字入力カーソルを実行するマクロに合わせるのが目的です。 「デバッグ > ステップイン」または「F8」キーを押します。
ローカルウィンドウの「a」の左の「+」ボタンをクリックしてみます。 F8 キーを押します。 ローカルウィンドウは変化なし。
F8 キーを押します。
値代入, 変更, 取得
- 下記コードを記述してみます。
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- 「a(0) = "A"」
- 配列のインデックス番号を指定して、値を代入しています。
- 「a(0) = "A"」
- 上記マクロをステップインで実行してみます。
ユーザーの操作 その時の VBE コード/ローカルウィンドウの状態 Sub ~ End Sub の間をクリック。 F8 キーを押す。 ローカルウィンドウの「a」の左の「+」ボタンをクリックします。
F8 キーを押す。 ローカルウィンドウに変化なし。
F8 キーを押す。 F8 キーを押す。(3 回繰り返す) F8 キーを押す。(2 回繰り返す) F8 キーを押す。(4 回繰り返す) F8 キーを押す。 マクロが終了しました。
ローカルウィンドウがリセットされました。
配列かどうか
Sub 配列になっているか調べる()
Dim a(3)
Debug.Print IsArray(a)
Debug.Print TypeName(a)
Debug.Print VarType(a) 'vbArray(8192) + vbVariant(12) を足した値
End Sub
Sub 配列になっているか調べる2()
Dim a '配列ではない変数
Debug.Print IsArray(a)
Debug.Print TypeName(a)
Debug.Print VarType(a) '結果 0 は vbEmpty
End Sub
配列ループ
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
- 「LBound(a)」
インデックス番号の最小値を取得しています。 - 「UBound(a)」
インデックス番号の最大値を取得しています。
インデックス番号 , 要素数変更
Option Base 1 '0 か 1
Sub OptionBaseステートメントで配列の開始番号を1に変更()
Dim a(3)
a(1) = "A"
a(2) = "B"
a(3) = "C"
End Sub
- 「Option Base 1」
配列の開始番号の既定値を 0 か 1 に設定できます。
Sub 配列定義の時に配列のインデックス番号を2から4の範囲に変更()
Dim a(2 To 4)
a(2) = "A"
a(3) = "B"
a(4) = "C"
End Sub
Sub 動的配列ではない配列の要素数変更を試みる()
Dim a(3)
ReDim a(5) '要素を二つ増やそうとしてみる
End Sub
- 動的配列ではない場合、要素数を変更できないようです。
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
動的配列
後で配列長を変更可能な動的配列を定義してみます。
Sub 動的配列定義()
Dim a()
End Sub
Sub 動的配列要素数変更()
Dim a()
ReDim a(2)
End Sub
Sub 動的配列のインデックス番号の開始番号と最終番号取得()
Dim a()
ReDim a(2)
Debug.Print "インデックス番号開始="; LBound(a)
Debug.Print "インデックス番号最終="; UBound(a)
End Sub
Sub 動的配列の値代入()
Dim a()
ReDim a(2)
a(0) = "A"
a(1) = "B"
a(2) = "C"
End Sub
Sub 動的配列のデータを残したまま要素数変更()
Dim a()
ReDim a(2)
a(0) = "A"
a(1) = "B"
a(2) = "C"
ReDim Preserve a(4)
End Sub
Redim の後に Preserve を付加すると元のデータを残したまま要素数を変更できるようです。
Sub 動的配列のデータをリセットして要素数変更()
Dim a()
ReDim a(2)
a(0) = "A"
a(1) = "B"
a(2) = "C"
ReDim a(6)
End Sub
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
関数で配列作成
Sub Array関数で配列作成()
Dim a
a = Array("A", "B", "C") '結果は下図 1
ReDim Preserve a(4) '結果は下図 2
End Sub
Sub Split関数で配列作成()
Dim a, b
a = Split("A,B,C", ",", -1) '-1 は全て
b = Split("A,B,C", ",", 2) '2 個の要素を生成
End Sub
Sub 縦並びデータ限定_一次元配列作成()
Dim a
a = WorksheetFunction.Transpose(Range("A1:A3")) '元データは図 1 '結果は下図 2
End Sub
多次元配列
Sub セル範囲から多次元配列作成()
Dim a
a = Range("A1:C3") '元データは下図 1 '結果は下図 2
Dim b
For Each b In a
Debug.Print b '結果は下図 3
Next
End Sub
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
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
配列で入力
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
以上、閲覧ありがとうございました。