For nextの繰り返し処理で、二次元配列の各要素を繰り返し処理したいときがあります。
このときFor NextでLBoundとUBoundを2回使うことで、二次元配列の各要素に対して処理を実行できます。
1 2 3 4 5 |
For i = LBound(二次元配列,1) To UBound(二次元配列,1) For j = LBound(二次元配列,2) To UBound(二次元配列,2) 処理 Next Next |
二次元配列の1次元目の要素を(二次元配列,1)で処理し、2次元目の要素を(二次元配列,2)で処理
以下で具体的な説明をしていきます。
目次
For Nextで二次元配列の各要素を処理
ここではエクセルのデータを二次元配列として取得します。
まずは全体のプログラムを紹介します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
'プログラム0|変数宣言の指定 Option Explicit 'プログラム1|プログラム開始 Sub Sample12() 'プログラム2|変数設定 Dim i As Long, j As Long Dim myrange As Variant 'プログラム3|配列の設定 myrange = Range("A1:E10") 'プログラム4|配列の1次元目の各要素を処理 For i = LBound(myrange, 1) To UBound(myrange, 1) 'プログラム5|配列の2次元目の各要素を処理 For j = LBound(myrange, 2) To UBound(myrange, 2) 'プログラム6|A列に値を出力 Range("A11").Offset(i - 1, j - 1).Value = myrange(i, j) Next Next 'プログラム7|プログラム終了 End Sub |
以下で詳しく説明します。
プログラム0|変数宣言の指定
1 |
Option Explicit |
「Option Explicit」とは、変数宣言を強制するためのものです。
予期しないエラーを防止できるため「Option Explicit」を入力することを習慣化することを推奨しています。
詳しい説明は以下のページで紹介しています。
プログラム1|プログラム開始
1 |
Sub Sample12() |
VBAではプロシージャという単位でプログラムを呼び出します。
プロシージャの構文は下記となっています。
1 2 3 |
Sub プロシージャ名() '実行プログラム End Sub |
「Sub」で始まり「End Sub」で終わります。
プロシージャに関連するmoduleの話については以下で説明しています。
プログラム2|変数設定
1 2 |
Dim i As Long, j As Long Dim myrange As Variant |
本プログラムで使用する変数を設定します。
iとjはFornextの数値カウンターとして使用します。
myrangeはプログラム3でエクセルのデータを取得する配列として使用します。
変数については、以下のページで紹介しています。
プログラム3|配列の設定
1 |
myrange = Range("A1:E10") |
エクセルのA1:E10の範囲を二次元配列として取得し、myrangeとして設定します。
プログラム4|配列の1次元目の各要素を処理
1 2 3 4 5 6 7 8 9 |
For i = LBound(myrange, 1) To UBound(myrange, 1) 'プログラム5|配列の2次元目の各要素を処理 'For j = LBound(myrange, 2) To UBound(myrange, 2) 'プログラム6|A列に値を出力 'Range("A11").Offset(i - 1, j - 1).Value = myrange(i, j) 'Next Next |
配列の1次元要素を処理をします。
二次元配列の1次元目の要素の最小値(LBound)と最大値(UBound)
UBound(二次元配列,1):二次元配列の一次元目のインデックスの最大値
LBoundとUBoundを使うことで、二次元配列の一次元目の最小値と最大値を取得できます。
LBoundとUBoundによって、「配列のサイズ(要素数)を意識しないでマクロを書けるので、メンテナンスが不要」になります。
よって配列でForNextを使うときは、LBoundとUBoundを使うと便利です。
Debug.PrintでLBoundとUBoundを検証
1 2 3 4 5 |
Debug.Print "LBound(myrange,1):" & LBound(myrange,1) Debug.Print "UBound(myrange,1):" & UBound(myrange,1) >>>LBound(myrange,1):1 >>>UBound(myrange,1):10 |
この事例ではLBoundとUBoundを確認した結果、上記のように1と10が出力されます。
プログラム5|配列の2次元目の各要素を処理
1 2 3 4 5 |
For j = LBound(myrange, 2) To UBound(myrange, 2) 'プログラム6|A列に値を出力 'Range("A11").Offset(i - 1, j - 1).Value = myrange(i, j) Next |
配列の2次元要素を処理をします。
二次元配列の2次元目の要素の最小値(LBound)と最大値(UBound)
UBound(二次元配列,2):二次元配列の二次元目のインデックスの最大値
二次元配列の二次元目のインデックスの最小値と最大値を取得できます。
Debug.PrintでLBoundとUBoundを検証
1 2 3 4 5 |
Debug.Print "LBound(myrange,2):" & LBound(myrange,2) Debug.Print "UBound(myrange,2):" & UBound(myrange,2) >>>LBound(myrange,2):1 >>>UBound(myrange,2):5 |
この事例ではA列からE列までを二次元配列として取得しているため、LBound(myrange,2)=1, UBound(myrange,2)=5となります。
A列は1列目、E列は5列目です。
Debug.Printでmyarrayを検証
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
For i = LBound(myrange, 1) To UBound(myrange, 1) For j = LBound(myrange, 2) To UBound(myrange, 2) Debug.Print "i:" & i, "j:" & j, myrange(i, j) Next Next >>>i:1 j:1 あ >>>i:1 j:2 い >>>i:1 j:3 う >>>i:1 j:4 え >>>i:1 j:5 お >>>i:2 j:1 か >>>i:2 j:2 き >>>i:2 j:3 く >>>i:2 j:4 け >>>i:2 j:5 こ >>>i:3 j:1 さ >>>i:3 j:2 し >>>i:3 j:3 す >>>i:3 j:4 せ >>>i:3 j:5 そ >>>i:4 j:1 た >>>i:4 j:2 ち >>>i:4 j:3 つ >>>i:4 j:4 て >>>i:4 j:5 と >>>i:5 j:1 な >>>i:5 j:2 に >>>i:5 j:3 ぬ >>>i:5 j:4 ね >>>i:5 j:5 の >>>i:6 j:1 は >>>i:6 j:2 ひ >>>i:6 j:3 ふ >>>i:6 j:4 へ >>>i:6 j:5 ほ >>>i:7 j:1 ま >>>i:7 j:2 み >>>i:7 j:3 む >>>i:7 j:4 め >>>i:7 j:5 も >>>i:8 j:1 や >>>i:8 j:2 い >>>i:8 j:3 ゆ >>>i:8 j:4 え >>>i:8 j:5 よ >>>i:9 j:1 ら >>>i:9 j:2 り >>>i:9 j:3 る >>>i:9 j:4 れ >>>i:9 j:5 ろ >>>i:10 j:1 わ >>>i:10 j:2 を >>>i:10 j:3 ん >>>i:10 j:4 >>>i:10 j:5 |
iとjの値に応じて、myrange(i,j)に格納された値を取得することができます。
これをエクセルに出力していきます。
プログラム6|A列に値を出力
1 |
Range("A12").Offset(i - 1, j - 1).Value = myrange(i, j) |
取得した二次元配列の値をセルA12にから出力します。
やりがちなミス|配列の要素番号は1から開始
エクセルのデータを二次元配列として取得すると、配列の要素番号は1から開始となります。
そのため、以下のようにOffset(i,j)としてしまうと、セルA12から1行1列ずれたところから出力してしまいます。
要はB13から出力をしてしまいます。
1 |
Range("A12").Offset(i, j).Value = myrange(i, j) |
そのため、Offset(i-1,j-1)としないと、想定したセルに出力できません。
ただしOffsetを使用する場合の注意なので、使用するプログラムによって注意点は異なります。
プログラム7|プログラム終了
1 |
End Sub |
プログラム1と対になるプログラムで、プログラム終了させるための記述です。
「End Sub」を読み込むと、プログラムが終了します。
プログラムの解説はここまでです。
Excel VBAについて詳しく理解したいなら
VBAを活用すると、仕事を効率化できる幅を広げることができます。
たとえば私が実際にVBAを活用して効率化してきた作業は以下の記事で紹介しています。
興味がある人は以下の記事もご覧ください。
動画でも解説しています。
エクセルマクロVBAで出来ることを15の事例で紹介|日常業務をラクにするヒントを見つけよう!
(音声が小さいので、ボリュームを上げてご覧いただければと思います)
VBAの勉強方法
私はプログラミング初心者からVBAを勉強を始めて少しずつレベルアップしていきました。
少しずつレベルアップしながら、難しい内容に挑戦していくと効率的に学ぶことができます。
上記のリンクでは、VBA勉強に役立つ内容を紹介しています。
興味がある人はご覧ください。