VBA技術解説
配列の使い方について

ExcelマクロVBAの問題点と解決策、エクセルVBAの技術的解説
最終更新日:2019-11-29

配列の使い方について


配列に関する記事は多数掲載していますが、今回は配列についての基礎知識をまとめました。
配列に関する基本的事項のみを解説しています。


配列とは

まずシートのセルを考えて下さい。
縦1列だけを取り出した場合は、1次元の配列です。
縦横の複数行列を取り出した場合は、2次元の配列です。
このようなデータを変数で扱うのが、配列になります。

2次元以上の次元の配列を、多次元配列とも言います。

1次元の配列

Dim 配列名(10) As Variant

これで、11個の要素を持つ1次元の配列になります。
あれっ、10個じゃないの?となりますが、
10個で正しいのです。
配列は、0~10になるのです、ですから11個になります。
データ型は、自由に指定可能です。

1次元配列の使用方法
配列名(インデックス)
インデックスとは、つまりは何番目かという事です。
添え字とも言います。
配列の要素に振られた番号です。
通常は、0,1,2と振られています。
また、
Dim 配列名(5 To 10) As Variant
のような記述もあります。
これは、5番目から10番目のみ使用するといった感じです。
さすがに、下限として5を指定することはないのですが、
1から開始することは頻繁に使用されます。
Dim 配列名(1 To 10) As Variant
後述の注意でもあるように、使用すると便利な場合が多々あります。

2次元の配列

Dim 配列名(10, 5) As Variant

これで、縦11個、横6個の要素を持つ2次元の配列になります。
縦横と表現しましたが、イメージしやすいように言ったまでで、
10が1次元目、5が2次元目になります。

2次元配列の使用方法
配列名(1次元インデックス上限, 2次元インデックス上限)

Dim 配列名(10, 5)
これは、つまり、
配列名(0, 0)~配列名(0, 5)

配列名(10, 0)~配列名(10, 5)
このようになります。

3次元以上の配列

3次元以上についても同様に扱えますが、使用はお勧めしません。
エクセルVBAにおいて、感覚的に直ぐに理解できるのは、2次元までだと思います。

動的配列

上記のように、最初から次元数、要素数を定義する配列の事を、
以下で説明する動的配列に対し、静的配列と呼びます。

プログラムを作成していると、配列の要素数が固定で決められない場合が多くなります。
実行時に、シートの内容によって、要素数を決定したくなります。
このような場合に、使用するのが、動的配列です。
プログラムの中で、次元数、要素数を決定したり、途中で要素数の変更をします。

動的配列

Dim 配列名() As Variant
このように、変数宣言時は配列であることだけを定義します。

1次元配列の要素数の変更
ReDim 配列名(10)
これで、1次元10の配列になります。
これは何回でも、変更(ReDim)可能です。
ただし、それまでのデータは全てなくなります。

データが消えてしまっては都合が悪い場合があります。
それまでのデータをそのままにして、要素数のみ変更したい場合は、
ReDim Preserve 配列名(10)
このようにPreserveを指定することで、データが残り要素数のみ変更できます。

ただし、Preserveを指定した場合は、
添字(インデックス)の下限は変更できません、変更できるのは上限だけです。
ReDim 配列名(0 To 10)
これを
ReDim Preserve 配列名(1 To 10)
これはエラーとなります。。

2次元配列の次元、要素数の指定
ReDim 配列名(5, 10)
これで、2次元配列になり、1次元目が5、2次元目が10の配列になります。
これも何回でも、変更(ReDim)可能です。

1次元配列同様に、データを残す場合は、
Preserve
を指定します。
ただし、Preserveを指定した場合は、
変更できるのは、最下位の次元のみです。
上で言えば、2次元目の10のみ変更可能です。
つまり、
ReDim 配列名(5, 10)
ReDim Preserve 配列名(6, 10) '×
これはエラーとなります。
できるのは、最下位の次元のみになります。
ReDim 配列名(5, 10)

ReDim Preserve 配列名(5, 11) '〇

動的配列の要素数の取得

動的配列を使っていると、VBA実行の中で今この配列の要素数がいくつなのかを知る必要が出てきます。
取得方法は、

要素数の最大値:UBound(配列名[,次元数])
要素数の最小値:LBound(配列名[,次元数])
※次元数を省略した場合は1次元目になります。

例えば、
ReDim 配列名(5, 10)
この場合、
UBound(配列名) → 5が返されます。
UBound(配列名, 1) → 5が返されます。
UBound(配列名, 2) → 10が返されます。

配列使用時の注意

普通に定義した配列、
ReDim 配列名(5, 10)
これは、インデックスが0から始まります。
つまり、0~5、0~10になります。
しかし、人間の感覚では0番目というのはいかにも使いづらく感じます。
そこで、0番目を無視して1番目から使っているVBAを見かけることがあります。
配列名(0, 〇)、配列名(〇, 0)
これらをVBA内では意図的に使用せず、
配列としては0から使えても、実際のVBA記述は1からしか使用しないということです。
これはこれで問題ありませんし、プログラムも分かりやすい場合もあります。
ただし、シートのセル範囲とデータをやりとりする場合は注意が必要です。

ReDim 配列名(5, 10)
この配列に、配列名(1, 1)~配列名(5, 10)の範囲にデータを入れ、
シートに戻す場合、
Range("A1:J5").Value = 配列名
としてしまいそうです。
しかし、これでは、配列名(0,0)~配列名(4,9)の範囲しか入りません。
もちろん、配列を2重ループで1つづつ入れれば良いのでしょうが、
それでは、処理時間がかかり過ぎます。
数千、数万行のデータでは、現実的には厳しくなります。

このような場合は、やはりインデックスの0から使用するか、
ReDim 配列名(1 To 5, 1 To 10)
このように、最初から下限値を指定する必要があります。
これなら全く問題はありません。
また、Option Base 1で変更するのは、誤解のもとになるのでお勧めしません。

また、
Dim 配列名() As Variant
これに対し、
配列名 = Range("A1:J5").Value
とした場合は、配列は、(1 To 5, 1 To 10)となりますので注意して下さい。

0番目をどうするかは、意見の分かれる所でしょうし、まあ好みかもしれません。
私は、ほとんどの場合、LBound~UBoundで処理するように記述しています。
そのようにしておけば、どちらの場合でもプログラムに変更はありません。

ここまで書きすすめると、やはり、
初心者の方は、(1 To 5, 1 To 10)のように定義し、1から使用する。
これが、最も分かりやすく間違いが無いだろうと思います。

追加の説明として、
Split関数(文字列を区切り文字で分割し配列にする)や、
コンボボックスのListの取得等は、Option Base 1に関わらず必ず0からになりますので、
0スタートにも慣れておく必要はあります。



同じテーマ「VBA技術解説」の記事

配列の使い方について
VBAの配列まとめ(静的配列、動的配列)
最終行の判定、Rangeオブジェクトと配列、高速化の為に
記述による処理速度の違い
速度比較決定版【Range,Cells,Do,For,ForEach】
エクセルVBAのパフォーマンス・処理速度に関するレポート
VBAのFindメソッドの使い方には注意が必要です
WorksheetFunction.Matchで配列を指定した場合の制限について
マクロVBAの高速化・速度対策の具体的手順と検証
動的2次元配列の次元を入れ替えてシートへ出力(Transpose)
大量データで処理時間がかかる関数の対処方法(SumIf)


新着記事NEW ・・・新着記事一覧を見る

SQL関数と演算子|SQL入門(12月1日)
データの取得:集約集計、並べ替え(DISTINKT,GROUP BY,ORDER BY)|SQL入門(11月30日)
データの取得:条件指定(SELECT,WHERE)|SQL入門(11月29日)
データの挿入:バルクインサート|SQL入門(11月28日)
データの挿入(INSERT)と全削除|SQL入門(11月26日)
テーブル名変更と列追加(ALTER TABLE)とテーブル自動作成|SQL入門(11月25日)
テーブルの作成/削除(CREATE TABLE,DROP TABLE)|SQL入門(11月24日)
データベースに接続/切断|SQL入門(11月23日)
SQLiteのインストール|SQL入門(11月22日)
SQL入門:VBAでデータベースを使う|エクセルの神髄(11月22日)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
3.RangeとCellsの使い方|VBA入門
4.Range以外の指定方法(Cells,Rows,Columns)|VBA入門
5.変数宣言のDimとデータ型|VBA入門
6.繰り返し処理(For Next)|VBA入門
7.マクロって何?VBAって何?|VBA入門
8.セルに文字を入れるとは(Range,Value)|VBA入門
9.空白セルを正しく判定する方法(IsEmpty,IsError,HasFormula)|VBA技術解説
10.ひらがな⇔カタカナの変換|エクセル基本操作



  • >
  • >
  • >
  • 配列の使い方について

  • このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


    記述には細心の注意をしたつもりですが、
    間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
    掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
    掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。



    このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
    本文下部へ