必見!2次元配列から1次元配列にする
動画でExcel 必見!2次元配列から1次元配列にする
必見!2次元配列から1次元配列にする
動画版「マクロ講座103回」です。
2次元配列で配列を1次元配列に分けたり、取り出したりする方法。
今回は2次元配列から1次元配列を取り出すと言うマクロを考えてきます。
すでに2次元配列は、あるのですからそれの一部分を取得するわけです。
そのままではできませんので、2次元配列をワークシート関数Transpose関数を使って、次元の入れ替えをします。
(サンプルファイルは、こちらです。 2次元配列から1次元配列にする。サンプル103回)
マクロ動画 必見!2次元配列から1次元配列にする
コードの簡略化のため、Sheetのコード名、およびシート名をshlist に変更しています。
100回から102回までの振り返りとコードの再利用
コードの簡略化のため、Sheetのコード名、
およびシート名をshlist に変更しています。今回は2次元配列を1次元にするというマクロを考えていきます。
100回のマクロ講座ではParamArrayと動的配列を使って、要素の数が特定できないその文字列を結合するというユーザー定義関数を作成しました。
101回では下図にあるようにA列B列といった、そのセル範囲をそのまま配列として取得するという、 かなりコードを簡略化したものですけれども、十分機能するマクロをご紹介しました。
102回では、配列の要素数の求め方や、重要な関数としてUBOUND,LBUNDの説明をしました。
またOptionBaseステートメントを使うことでインデックスを1から始めることができるという方法も紹介しました。それから配列を作成するときに欠かせないウィンドウとしてローカルウィンドウを表示させておくことで、配列がどのように取得されたかを確認することができるということを説明しました。
配列を取得するのに、シートにデータがあるなら、シートからそっくりそのまま取得して配列にいれるというのが早いし簡単です。
というのも、データ範囲をCurrentRegionで取得すれば、データ範囲の特定が楽ですし、それをそっくり配列に入れることができるのですが、それを1列だけとか、 1次元に変換したいというときは、どうしたらいいのかということ、結構悩まれている方いるようです。こちらは、101回でこのセル範囲を2次元配列として取得したコードです。このコードをリメイクしていきますが、For文のコードは不要です。
最初の部分、2次元配列を取得するコードを再利用します。
Sub getoneDimension_fromTwo_1() Dim two_arr As Variant, one_arr As Variant two_arr = shlist.Range("A1").CurrentRegion End Sub
Transpose関数で行列を入れ替える
コードに1次元配列を宣言して追加します。
two_arr = WorksheetFunction.Transpose(two_arr)
次に、縦並びのt wo_arr データを横並びに変更します。
その行列入れ替えた、two_arr から
one_arr = WorkshesetFunction.Index(two_arr, 1)
1次元を取得します。これで1次元配列を取得することができました。
取得できたかどうかはどうやって見るかというと、debug printで 1次元配列にちゃんとこの支店名が入っているかどうかを確認したいと思います。ジョイン関数を使ってDebug.Printで、イミディエイトウィンドーに表示させましょう。
Debug.Print "one_arr = " & Join(one_arr, ",")
上記コードを実行すると、カンマ区切りで1列に表示されるということです。
2次元配列から取得した1次元配列の確認の方法
また取得した1次元の配列をシート上に転記して確認する場合は、コードは次のようになります。
2次元配列から1次元が取得できたかどうかの確認のためにシートに転記しました。
Sub getoneDimension_fromTwo_1() Dim two_arr As Variant, one_arr As Variant, r As Long two_arr = shlist.Range("A1").CurrentRegion two_arr = WorksheetFunction.Transpose(two_arr) one_arr = WorksheetFunction.Index(two_arr, 1) ' Debug.Print "one_arr = " & Join(one_arr, ",") For r = LBound(one_arr) To UBound(one_arr) Cells(r + 12, 3).Value = one_arr(r) Next r End Sub
Transeposeを使わずに、最初から取得した列だけを取得するコード
上記のコードでは、表全体を取得していました。しかし欲しい列だけ取得することもできます。その場合は、
shlist.Range("A1").CurrentRegion.Select
をリサイズします。
two_arr = Selection.Offset(0, 1).Resize(, 1) データは1列だけになりました。ローカルウィンドーで、配列の中身を確認してみると、最初にリサイズして取得した配列は、1列ですが、2次元です。
それをFor文で2次元から1次元に入れ直しています。
しかし、この場合は、すでにデータをExcelがメモリ上に持っていますので、FOR文で取得するとはいえ、超高速になります。今回の動画では、コードの簡略化のため、Sheetのコード名、
およびシート名をshlist に変更しています。
Sub getrange_onearrfromResize() Dim two_arr As Variant Dim one_arr() As Variant shlist.Range("A1").CurrentRegion.Select two_arr = Selection.Resize(, 1) 'まだ2次元なので ReDim one_arr(1 To UBound(two_arr, 1)) '1次元のサイズ決め Dim i As Long For i = LBound(two_arr, 1) To UBound(two_arr, 1) one_arr(i) = two_arr(i, 1) Next i Debug.Print "one_arr = " & Join(one_arr, ",") End Sub