ExcelマクロVBA技術解説 | 配列の使い方について | Excelマクロの問題点と解決策、エクセルVBAの技術的解説



最終更新日:2013-02-18

配列の使い方について


今回は、配列についての基礎知識をまとめました。


配列とは


シートのセルを考えて下さい。


縦1列だけを取り出した場合は、1次元の配列です。


縦横の複数行列を取り出した場合は、2次元の配列です。


このようなデータを変数で扱うのが、配列になります。


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



1次元の配列


Dim 配列名(10) As Variant

これで、11個の要素を持つ1次元の配列になります。

あれっ、10個じゃないの?となりますが、

正しいのです。

配列は、0〜10になるのです、ですから11個になります。

データ型は、自由に指定可能です。



使用方法は


配列名(インデックス)

インデックスとは、つまりは何番目かという事です。

配列の要素に振られた番号です。

通常は、0,1,2と振られています。


また、

Dim 配列名(5 To 10) As Variant

のような記述もあります。

これは、5番目から10番目のみ使用するといった感じです。

これを使用するのは、かなり限定的だと思われますが、

後述の注意でもあるように、使用すると便利な場合もあります。



2次元の配列なら


Dim 配列名(10,5) As Variant

これで、縦11個、横6個の要素を持つ2次元の配列になります。

縦横と表現しましたが、イメージしやすいように言ったまでで、

10が1次元、5が2次元になります。


使用方法は、

配列名(1次元インデックス,2次元インデックス)

つまり、

配列名(0,0)〜配列名(10,5)

のようになります。



3次元以上も同様ですが、あまり使用はお勧めしません。

エクセルVBAにおいて、感覚的に直ぐに理解できるのは、2次元までだと思っています。


上記のように、最初から、次元数、要素数を定義する配列の事を、

下の動的配列に対し、静的配列と呼びます。



動的配列


プログラムを作成していると、配列の要素数が固定で決められない場合が多くなります。


実行時に、シートの内容によって、要素数を決定したくなります。


このような場合に、使用するのが、動的配列です。


プログラムの中で、次元数、要素数を決定したり、途中で要素数の変更をします。



動的配列の定義


Dim 配列名() As Variant

のように、配列であることだけを定義します。



1次元配列の要素数の指定


ReDim 配列名(10)

これで、1次元10の配列になります。


これは何回でも、変更可能です。

ただし、それまでのデータは全てなくなります。

それでは都合が悪い場合があります。

それまでのデータをそのままにして、要素数のみ変更したい場合は、

ReDim Preserve 配列名(10)

データが残り、要素数のみ変更されます。



2次元以上の配列の次元、要素数の指定


ReDim 配列名(5,10)

これで、2次元配列になり、1次元が5、2次元が10の配列になります。


これも何回でも、変更可能です。

ただし、変更できるのは、最下位の次元のみです。

上で言えば、2次元目の10のみ変更可能です。

つまり、ReDim 配列名(6,10)とは変更できません。

できるのは、ReDim 配列名(5,11)のような指定だけです。


1次元配列同様に、データを残す場合は、

Preserve

を指定します。



動的配列の要素数の取得


動的配列を使っていると、今この配列の要素数がいくつなのかを知る必要が出てきます。

取得方法は、

要素数の最大値:UBound(配列名[,次元数])

要素数の最小値:LBound(配列名[,次元数])

次元数を省略した場合は、1次元になります。


例えば、ReDim 配列名(5,10)

の場合、UBound(配列名,1)なら5、UBound(配列名,2)なら10が返されます。



配列使用時の注意


普通に定義した配列、

ReDim 配列名(5,10)

は、インデックスが0から始まります。


しかし、人間の感覚では、0番目というのは、いかにも使いづらいです。

そこで、0番目を無視して、1番目から使う事がよくあります。


それはそれで問題ありませんし、プログラムも分かりやすいと思います。

ただし、シートのセル範囲と、データをやりとりする場合は注意が必要です。


ReDim 配列名(5,10)

に、配列名(1,1)〜配列名(5,10)の範囲にデータを入れ、

シートに戻す場合、

Range("A1:J5") = 配列名

としてしまいそうです。

しかし、これでは、配列名(0,0)〜配列名(4,9)の範囲しか入りません。


もちろん、配列を2重ループで1つづつ入れれば良いのでしょうが、

それでは、処理時間がかかり過ぎます。

数千、数万行のデータでは、現実的には厳しくなります。


このような場合は、やはり、インデックスの0から使用するか、

ReDim 配列名(1 To 5, 1 To 10)

のように指定する必要があります。

これなら全く問題はありません。


また、

Dim 配列名() As Variant

に対し、

配列名 = Range("A1:J5")

とした場合は、配列は、(1 To 5, 1 To 10)となっていますので注意して下さい。


0番目をどうするかは、意見の分かれる所でしょうし、まあ好みかもしれません。

私は、ほとんどの場合、LBound〜UBoundを処理するように記述しています。

そのようにしておけば、どちらでも、ほとんどプログラムに変更はありません。

しかし、ここまで書いてきて感じたのは、

初心者の方は、(1 To 5, 1 To 10)のように定義し、1から使用する。

これが、最も分かりやすく、間違いが無いだろうと思います。


追加の説明として、

Split関数(文字列を、区切り文字で分割し、配列にする)や、

コンボボックスのListの取得等は、必ず0からになりますので、

0スタートにも慣れておく必要はあります。





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

最終行の判定、Rangeオブジェクトと配列、高速化の為に
記述による処理速度の違い
速度比較決定版【Range,Cells,Do,For,ForEach】
エクセルVBAのパフォーマンス・処理速度に関するレポート
VBAのFindメソッドの使い方には注意が必要です
WorksheetFunction.Matchで配列を指定した場合の制限について
マクロVBAの高速化・速度対策の具体的手順と検証

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

SUMIFの間違いによるパフォーマンスの低下について|エクセル関数超技(6月17日)
条件式のいろいろな書き方:TrueとFalseの判定とは|ExcelマクロVBA技術解説(6月15日)
空白セルを正しく判定する方法2|ExcelマクロVBA技術解説(5月6日)
フルパスをディレクトリ、ファイル名、拡張子に分ける|ExcelマクロVBA技術解説(4月15日)
テキストボックスの各種イベント|Excelユーザーフォーム入門(4月9日)
フォルダ(サブフォルダも全て)削除する、Optionでファイルのみ削除|ExcelマクロVBAサンプル集(4月4日)
最後の空白(や指定文字)以降の文字を取り出す|エクセル関数超技(3月26日)
先頭の数値、最後の数値を取り出す|エクセル関数超技(3月26日)
Excelファイルを開かずにシート名をチェック|ExcelマクロVBAサンプル集(3月23日)
数式の参照しているセルを取得する|ExcelマクロVBAサンプル集(3月18日)

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

1.最終行の取得(End,Rows.Count)|ExcelマクロVBA入門
2.RangeとCellsの使い方|ExcelマクロVBA入門
3.徹底解説(VLOOKUP,MATCH,INDEX,OFFSET)|エクセル関数超技
4.Range以外の指定方法(Cells,Rows,Columns)|ExcelマクロVBA入門
5.変数とデータ型(Dim)|ExcelマクロVBA入門
6.セルのコピー&値の貼り付け(PasteSpecial)|ExcelマクロVBA入門
7.セルの参照範囲を可変にする(OFFSET,COUNTA,MATCH)|エクセル関数超技
8.ひらがな⇔カタカナの変換|エクセル基本操作
9.定数と型宣言文字(Const)|ExcelマクロVBA入門
10.CSVの読み込み方法|ExcelマクロVBAサンプル集



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

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


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

    ↑ PAGE TOP