動画でExcel 必見!2次元配列から1次元配列にする
動画版「マクロ講座103回」です。
2次元配列で配列を1次元配列に分けたり、取り出したりする方法。
はじめに
この回では、
「シートの表を丸ごと配列に入れたんだけど、1列だけ取り出して使いたい」
という、とてもよくある場面を練習します。
2次元配列(行と列を持つ配列)
1次元配列(縦か横のどちらか一列だけの配列)
の関係を、実際のコードを使いながら確認していきます。
ポイントはこの3つです。
コードの簡略化のため、Sheetのコード名、およびシート名をshlist に変更しています。
コードの簡略化のため、Sheetのコード名、
およびシート名をshlist に変更しています。

この103回は、100~102回の内容の続きになっています。かんたんに振り返っておきましょう。
100回
ParamArray を使って
「引数の数が毎回ちがってもいい関数」を作りました。
動的配列と組み合わせて、文字列の結合を行いました。
101回
シートの表を
Range("A1").CurrentRegion でつかまえて
そのまま配列に入れる方法を学びました。
「セル範囲 ⇒ 配列」は、一気に読み込む方が速くて楽、という考え方でした。
102回
LBound / UBound で、配列の「最小の番号」と「最大の番号」を調べる
Option Base 1 や 1 To 10 の書き方で、インデックスを 1 から始める方法
データ数が分からないときに、動的配列+ReDim でサイズを決める方法
を練習しました。
この103回では、これらの知識を使って、
「2次元配列 ⇒ 1次元配列」 の変換にチャレンジします。

それから配列を作成するときに欠かせないウィンドウとしてローカルウィンドウを表示させておくことで、配列がどのように取得されたかを確認することができるということを説明しました。

2次元配列を用意する(復習)
まずは、シートの表を 2次元配列として取得します。
ここでは、シートのコード名とシート名をどちらも shlist に変更してある前提で話を進めます。
(コードの中に shlist.Range(...) と書きたいからです。)
2次元配列を作るコード
Sub getoneDimension_fromTwo_1()
Dim two_arr As Variant ' 2次元配列を入れる箱
Dim one_arr As Variant ' あとで 1次元配列を入れる箱
' A1 を起点に、表の「かたまり」を CurrentRegion で取得して 2次元配列に入れる
two_arr = shlist.Range("A1").CurrentRegion
End Sub
ここまでで、
two_arr(行番号, 列番号)
という形の 2次元配列 ができました。
たとえば、A1:B6 の表なら、
列方向 … 1~2
というイメージです。
次の目標は、
「支店名が入っている列だけ、1次元配列として取り出したい」
のように「1列だけ欲しい」ケースです。
ところが、2次元配列のままだと、
two_arr(1, 1) … 1行1列目
two_arr(2, 1) … 2行1列目
というように、
「行番号+列番号」が必要なので、そのままでは 1次元になりません。
そこで使うのが、ワークシート関数の
WorksheetFunction.Transpose
です。
コードに Transpose を追加する
Sub getoneDimension_fromTwo_1()
Dim two_arr As Variant, one_arr As Variant
' 2次元配列を取得
two_arr = shlist.Range("A1").CurrentRegion
' 行と列を入れ替える(転置)
two_arr = WorksheetFunction.Transpose(two_arr)
End Sub

元の two_arr:
行方向 = 元の表の「行」
列方向 = 元の表の「列」
転置後の two_arr:
行方向 = 元の表の「列」
列方向 = 元の表の「行」
というふうに、役割がひっくり返ります
Sub getoneDimension_fromTwo_1()
Dim two_arr As Variant, one_arr As Variant
two_arr = shlist.Range("A1").CurrentRegion
two_arr = WorksheetFunction.Transpose(two_arr)
' 転置後の two_arr から「1行目」を 1次元配列として取得
one_arr = WorksheetFunction.Index(two_arr, 1)
End Sub
ここで大事なのは、
転置前:
two_arr(行, 列) で「行・列」を指定
転置後:
「行番号 1」が、「元の表の 1 列目」になっている
という点です。
Index(two_arr, 1) は
「two_arr の 1行目全体 をください」
という意味になり、その結果が
「1次元配列(横に並んだ 1列分)」
として one_arr に入ります。

Debug.Print と Join で中身をチェックする
ちゃんと配列が取れているかどうかは、
コードのままでは見えないので、確認方法もセットで覚えておくと便利です。
ここでは、
Debug.Print
Join 関数
を使って、イミディエイトウィンドウに表示させます。
Sub getoneDimension_fromTwo_1()
Dim two_arr As Variant, one_arr As Variant
two_arr = shlist.Range("A1").CurrentRegion
two_arr = WorksheetFunction.Transpose(two_arr)
one_arr = WorksheetFunction.Index(two_arr, 1)
' one_arr の中身を「,」でつないで 1行で表示
Debug.Print "one_arr = " & Join(one_arr, ",")
End Sub

Join(one_arr, ",")
→ 配列 one_arr の要素を
「A店,B店,C店,…」のようにカンマで結合して 1つの文字列にします。
Debug.Print
→ その文字列をイミディエイトウィンドウに出力します。
こうしておけば、実行するたびに
one_arr = 東京支店,横浜支店,名古屋支店,…
のように、配列の中身を一目で確認できます。
シートに書き戻して 1次元配列を確認する
イミディエイトウィンドウだけでなく、
シート上にも出して確認したい場合は、次のようなコードにします。
Sub getoneDimension_fromTwo_1()
Dim two_arr As Variant
Dim one_arr As Variant
Dim r As Long
' 2次元配列を取得
two_arr = shlist.Range("A1").CurrentRegion
' 行列を入れ替え
two_arr = WorksheetFunction.Transpose(two_arr)
' 1次元配列(1行目)を取得
one_arr = WorksheetFunction.Index(two_arr, 1)
' one_arr の中身を C12 以降のセルに縦に書き出す
For r = LBound(one_arr) To UBound(one_arr)
Cells(r + 12, 3).Value = one_arr(r)
Next r
End Sub
ここで使っているポイント: LBound(one_arr) … 配列の最初の番号 UBound(one_arr) … 配列の最後の番号 Cells(r + 12, 3) … 3列目(C列)の「12行目から下」に、1つずつ書き出す 実行すると、C12 から下に向かって、 1次元配列の中身が順番に表示されます。
ここまでの方法は、
表全体を 2次元配列に入れる
Transpose で行列を入れ替える
Index で 1行分=1次元配列を取り出す
という流れでした。
もう一つの考え方として、
「最初から 欲しい列だけ 2次元配列にして、
For 文で 1次元配列にコピーする」
という方法もあります。
Resize を使ったコード例
Sub getrange_onearrfromResize()
Dim two_arr As Variant ' 2次元配列(1列だけ)
Dim one_arr() As Variant ' 1次元配列
Dim i As Long
' A1 を起点に表全体を取得し、そのうち 1列だけを two_arr に入れる
two_arr = shlist.Range("A1").CurrentRegion.Columns(1) ' 1列目だけ
' two_arr は「行×1列」の2次元配列なので、行数分だけ 1次元配列を用意
ReDim one_arr(1 To UBound(two_arr, 1))
' 2次元配列 two_arr(行, 1) から 1次元配列 one_arr(行) にコピー
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
ここでのポイント
CurrentRegion.Columns(1)
→ 表全体ではなく、「1列目だけ」の範囲を 2次元配列として取得
UBound(two_arr, 1)
→ 行数だけ取り出して、1次元配列 one_arr のサイズを決める
For 文で two_arr(行, 1) → one_arr(行) にコピー
→ メモリ上のデータのコピーだけなので、とても高速です。

この回では、次のような流れで
2次元配列から 1次元配列を作る 方法を学びました。
Range("A1").CurrentRegion で、表をまるごと 2次元配列にする
WorksheetFunction.Transpose で、行と列を入れ替える
WorksheetFunction.Index(two_arr, 1) で、「1行分」を 1次元配列として取り出す
Debug.Print と Join で、配列の中身を確認する
Resize や Columns(1) を使って、「欲しい列だけ」を 2次元→1次元に変換する別解もある
配列をうまく使えるようになると、
ループの回数が減ったり、処理がすごく速くなったりして、
本格的なマクロの世界に一歩近づけます。
1次元を取得します。