ゆんの業務改善ブログ

①生産性向上 ②業務改善 ③自動化 について情報発信しています。VBAプログラムは本当の初心者から他のアプリケーションを呼び出して使う上級者的な使い方まで幅広いレベルで解説していきます。

VBA 配列を徹底的に解説する (全5回) ④多次元配列

VBAにおける多次元配列を解説します。

これまで見てきた配列では一階建てのアパートのように一列に並んだ部屋に値を格納していくイメージでした。これからは配列をより使いこなすためにアパートを二階建て、三階建てにしていきます。

<これまでの配列の解説>

目次

多次元配列を使う

この記事ではVBAにおける多次元配列を解説します。そもそも配列になじみがない方はこの配列を解説するシリーズの①から順に読んでいくとスムーズに理解することができます。

多次元配列のイメージ

配列を徹底的に解説するシリーズの①~③で静的配列のイメージを掴みました。今まで配列を説明するにあたり、明言してこなかったことがあります。それは、これまで作ってきた配列は一次元だったと言う事です。下ののイメージ図を見てください。

f:id:mutable_yun:20190921192042p:plain
再掲 静的一次元配列のイメージ

このイメージ図は静的一次元配列のイメージ図です。ゆん荘という一階建てのアパートに一列に部屋が並んでいるイメージです。多次元配列でイメージしやすく、もっとも実務でお世話になるのが二次元配列です。二次元配列のイメージ図は下のようなものです。

f:id:mutable_yun:20190922152030p:plain
2次元配列のイメージ

1階建てだったアパートが3階建てになりました。注意点は3階建てだから3次元ではない、と言う事です。アパートの階にあたる縦と奥行きの横の2次元と言うことです。

○-○と号室が書いてあります。初めの方のインデックスが1次元目、後の方が2次元目です。そして1時限目がアパートの階、2時限目が部屋番号を表しています。この図では1次元目が0、1、2の3つの要素、2次元目が0、1、2、3、4の5つの要素を持った配列と言う事になります。

下に行くほど1次元目の数字が大きくなるのは、アパートのイメージと違うかもしれませんが、そこはエクセルのワークシートの行番号のイメージに脳内変換して理解しましょう。0から始まる事だけ気を付ければワークシートにそっくりですね。

静的2次元配列を作る

それでは実際に2次元配列を作成してみます。1次元のこれまでの配列の宣言方法と違うのは、かっこの中をカンマで区切って1次元目と2次元目2つの最大インデックスを指定する点です。一次元の配列の場合は1つだけ指定していましたが2次元なので2つの最大インデックスを指定します。同様に、3次元配列を作成したい時は3つの値を指定します。

Sub 初めての2次元配列作成()

    Dim 初めての2次元配列(2, 4)
    
End Sub

いつものようにF8で一行ずつステップイン実行していきましょう。

f:id:mutable_yun:20190922194653p:plain
2次元配列の中身。カッコ()の中が将棋や囲碁のようにインデックスが二つ並んでいる。

1次元が2まで、2次元が4までの配列ができました。イミディエイトウィンドウを見ると一見分かりにくいですが、0行目の0列目、1列目、2列目・・・、1行目の0列目、1列目、2列目・・・と言うように見えませんか?

これはもはやワークシートそのものなのでは??(0から始まってるけど)

ファイル⇒一番左下のオプション

f:id:mutable_yun:20190922194959p:plain
エクセルのリボン部分
f:id:mutable_yun:20190922195147p:plain

数式⇒R1C1参照形式を使用する
f:id:mutable_yun:20190922195248p:plain

シートの中のセルの番地を数値で指定できるようになりました。今回作成した配列のインデックスにそっくりですね。
後程、エクセルシートの値を二次元配列に一気に格納する裏ワザを説明しますので、二次元配列がワークシートとそっくりなことを頭に入れておきましょう。

f:id:mutable_yun:20190922195704p:plain
R1C1形式で表示されたエクセルブックのシート

LBound関数とUBound関数の第2引数

LBound関数でインデックスの最小値、UBound関数でインデックスの最大値が取得できることは、VBA 配列を徹底的に解説する (全10回) ③静的配列の初期化と実務的なサンプルで学んだ通りです。実はこれらの関数はもう一つ引数をとることができます。

それが、何次元目の最小/最大インデックスを取得するかという、何次元目の何に当たる数値です。

Sub 初めての2次元配列作成の最小_最大インデックスを調べる()

    Dim 初めての2次元配列(2, 4)
    
    Debug.Print LBound(初めての2次元配列, 1)
    Debug.Print UBound(初めての2次元配列, 1)
    Debug.Print LBound(初めての2次元配列, 2)
    Debug.Print UBound(初めての2次元配列, 2)
    
End Sub

実行結果。

 0 
 2 
 0 
 4 

次元数を第2引数にとることによって、明示的に各次元の最小、最大インデックスを取得することができました。

多次元といいながら2次元配列の説明しかしていませんが、現時点ではワークシートのイメージで構いません。

実際、業務効率化で使うVBAの多次元配列は9割が2次元配列だと思います。面のイメージですね。

3次元以上はここで詳しく解説しませんが、実際のデータの入り方と区分けをイメージすることで理解出来ます。

少しだけ、例を挙げると、
日本、中国、韓国、と言った国名を1次元、東京、北京、ソウルなどを2次元に格納していきます。2次元の他の要素には大阪や上海や太田などが入ります。そして3次元には新宿区などが入ります。ちょっと乱暴ですが、階層が格納できるイメージが想像できますでしょうか。これがイメージできれば、4次元は一つずれて、1次元に地球が入ることになります。ワークシートのイメージの延長ではない3次元以上の多次元配列は業務自動化の範囲を超えるのでここでは説明を割愛します。

ワークシートをそのまま代入して2次元配列を作る裏技

エクセルのお気遣いを使い倒す裏技です。ワークシートの範囲をそのままVariant型の変数に代入すると、勝手に2次元配列に変換して格納してくれます。非常に便利なので是非とも覚えておきましょう。

f:id:mutable_yun:20190922202117p:plain
サンプルデータ。商品リスト

このシートがアクティブな状態で下記を実行します。

Sub 裏技的2次元配列()
    
    Dim rw As Long
    Dim clm As Long
    Dim シートの値をそのまま配列にarr As Variant
    
    rw = Cells(Rows.Count, 1).End(xlUp).Row
    clm = Cells(1, Columns.Count).End(xlToLeft).Column
    
    シートの値をそのまま配列にarr = Range(Cells(1, 1), Cells(rw, clm))

End Sub

F8を順に押していくと・・・

f:id:mutable_yun:20190922202628p:plain
もはやシートそのもの!ただし書式などはない。値だけ。

とても簡単ですね!シートの値をそのまま配列にarrというVariant型の変数にRangeを入れると、勝手に二次元配列に変換して変数に格納されました。Rangeはオブジェクトなので、変数に代入する時は、本来Setをつけなければならないのですが、このようにSetを省略することにより、オブジェクトを格納するのではなく値の集合を代入することになり、結果として配列として格納してくれる、と言うわけです。便利!


これでもうシートを参照したりアクティブワークブックを切り替える必要はなくなりました。取り込んだデータは全て配列に取り込んで、値の操作は全部配列でやってしまえば良いからです。エクセルブックとかシートオブジェクトを触るのは背景の色とかセルの書式設定などオブジェクトのプロパティを触りたい時だけでいいのですね。これを使うことによってマクロの大幅な処理時間短縮を図ることができるようになります。

多次元配列まとめ

この記事で解説した内容をまとめます。

  • 二次元配列は2階建て以上のマンションのイメージ
  • 静的二次元配列を作るには、宣言時の引数を2つにする
  • 二次元配列はエクセルのワークシートとそっくり
  • ワークシートを丸ごと二次元配列に格納するには

下の関連記事も参考にして配列を使いこなせるようになっていきましょう。

<関連記事>