1. はじめに
ARアドバンストテクノロジ株式会社(ARI)の鈴木タクヤです。
今回はExcelフィルタリングツールのソースコード解説第10回です。
(ツールの詳細については以下の記事を、「Excelフィルタリングツール解説シリーズ」タグの記事一覧については以下の記事下部「5. 解説記事のリンク」をご参照ください。)
今回のテーマは「配列」です。記事のボリュームが多くなってしまったこともあり、前後編でお届けします。
2. 配列とは
ざっくり言えば、変数1をつなげて複数の値を入れられるようにした"かたまり"が 配列 (Array)です。同じデータ型であれば複数のデータを一つの配列にまとめられます。
各要素を操作できるように、配列にはインデックス(添え字、要素番号とも)が設定されます。アパートの部屋番号みたいなものです。
このインデックスが少々曲者で、基本的に 0 から始まります。つまり要素数 n の配列のインデックスは以下のようになるイメージ。
以下の使用例をもとに、具体的に解説していきます。
Sub Sample1()
' 配列を宣言(要素数は3、インデックスは 0 ~ 2)
Dim array1(2) As String
' 配列に値を代入
array1(0) = "グー"
array1(1) = "チョキ"
array1(2) = "パー"
'「グー」をメッセージボックスで表示
MsgBox array1(0)
End Sub
使用例①では Dim array1(2) As String
でString型の値を格納する、要素数 3 の配列を宣言しています。この宣言時に指定する数字はインデックスの最大値です(上の例では(2)
)。
その後、配列の各要素のインデックスを指定して値を代入します。この値を取り出す時にも配列名をインデックス付きで array1(1)
のように記述します。
Dim array1(2)
の array1(2)
は「要素数3の配列全体」を表し、
array1(2) = "パー"
の array1(2)
は「インデックスが2の要素」を表すことに注意!
また、配列の要素数は宣言時に指定せず、処理の中で動的に確定させることも可能です。
Sub Sample2()
' 配列を宣言(インデックスの指定なし)
Dim array1() As String
' 要素数を確定
ReDim array1(2)
' 配列に値を代入
array1(0) = "グー"
array1(1) = "チョキ"
array1(2) = "パー"
'「チョキ」をメッセージボックスで表示
MsgBox array1(1)
End Sub
使用例②のように、Dim array1() As String
と括弧内に配列のインデックスの最大値を記述しない場合は、ReDim
ステートメントを使用することで、後から要素数を決めることができます。この例ではReDim
を使用する利点がありませんが、後編で詳しく解説するExcelフィルタリングツールの処理でも登場します。
ReDimは何度でもやり直せますが、それまでの配列内のデータは失われます。データを保持しつつ要素数を変更したい場合は
ReDim Preserve 配列名(インデックスの最大値)
のように記述します。
また Variant型で宣言する場合のみ、以下の使用例③のようにArray関数を用いて要素数と値を同時に指定できます。この場合は配列名の後ろに()
を付けずにarray1
のように宣言可能です。
Sub Sample3()
' 配列を宣言(Variant型の変数として)
Dim array1 As Variant
' 配列に値を代入(要素数が3に確定)
array1 = Array("グー", "チョキ", "パー")
'「パー」をメッセージボックスで表示
MsgBox array1(2)
End Sub
3. おわりに
以上、配列の解説でした。
次回は、Excelフィルタリングツールにおける、配列を用いた具体的な処理について解説します。
・・・しかし、Excel VBAにおける配列の記事としては、ここで終わると中途半端なので、おまけに続きます。
4. おまけ;多次元配列
ここまでの配列はデータが一列に並んだ構造なので 1次元配列 と呼びます。それ以外の配列は 多次元配列 と呼びます。
例えば以下の図のように、縦m行、横n列 の平面的な構造の配列は 2次元配列 と呼びます。(こちらもインデックスは0始まりとしています。)
これは、Dim 配列名(m-1, n-1)
と宣言することで、要素が配列名(0, 0)
から配列名(m-1, n-1)
までの、要素数 m × n の配列として定義できます。
このような図は、Excelを使っているとよく目にしますよね?
そう、Excelのワークシート自体が、2次元配列の一種です。
セル範囲の操作等に2次元配列を使用できます。
Sub Sample4()
'縦2×横3の2次元配列を宣言(各インデックスは0始まり)
Dim array2(1, 2) As String
'セル範囲を配列に格納
For m = 0 To 1
For n = 0 To 2
array2(m, n) = Cells(m + 1, n + 1).Value
Next n
Next m
Range("A4", "C5").Value = array2
'インデックス確認用
MsgBox "array2(1, 2) = " & array2(1, 2)
End Sub
Range
オブジェクトについては 解説第7回 でしれっと触れていますが、この例では array2
という2次元配列に、A1セル(Cells(1, 1)
)からC2セル(Cells(2, 3)
)の値を代入し、それらをA4からC5のセル範囲に出力しています。この時、インデックスが0始まりのため、array2(0, 0) = Cells(1, 1).Value
である(1ずつずれる)ことに注意です。
2次元配列の縦横それぞれの数が出力先として指定するセル範囲と同一であれば、Range("A4", "C5").Value = array2
のように配列の各要素を一括で出力可能です。
またVariant型で配列を宣言しておけば、以下のようにより直感的にセル範囲を配列に格納することができます。
Sub Sample4()
'配列を宣言
Dim array2 As Variant
'セル範囲を配列に格納
array2 = Range("A1", "C2")
'配列をセル範囲に出力
Range("A4", "C5").Value = array2
'インデックス確認用
MsgBox "array2(1, 2) = " & array2(1, 2)
End Sub
こちらの例⑤では例④とは異なり、A1~C2セルの範囲を配列array2
に直接格納しています。一見すると例④と同様の結果が得られそうですが、この方法を使用すると、 2次元配列のインデックスが1始まりになる (array2(1, 1) = Cells(1, 1).Value
である)という違いがあります。
インデックスを増やしていけば、3次元以上の配列も作成・使用することができますが、コードが複雑になり、そもそもワークシート自体が2次元なので、ほとんど使用する機会は無いでしょう。
5. 参考文献
こちらはMicrosoftの公式ドキュメントです。
こちらは私がものすごくお世話になっている「エクセルの神髄」という解説サイト。より深く学習を進めたい方は是非。