13
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

EXCELのVBAで2次元配列の特定の列または行を1次元配列に変換する方法

Last updated at Posted at 2019-12-25

#サンプル
以下のコードで2次元配列を簡単に1次元配列に変換できます。

Public Sub Sample()
    Dim 二次元配列 As Variant
    Dim 一次元配列 As Variant
    
    二次元配列 = Range("A1:B6")
    
    '3行目を一次元配列化する
    一次元配列 = WorksheetFunction.Index(二次元配列, 3)
    Debug.Print "3行目= " & Join(一次元配列, ",")
    
    '1列目を一次元配列化する
    '一次元配列 = WorksheetFunction.Index(二次元配列, , 1) 'Index関数のHELP的にはできそうですがエラーになります
    'Transpose()関数を使って行と列を入替えます
    一次元配列 = WorksheetFunction.Index(WorksheetFunction.Transpose(二次元配列), 1)
    Debug.Print "1列目= " & Join(一次元配列, ",")
End Sub

上記の関数をこのようなセルの状態で実行すると
image.png
結果は以下の様になります
3行目= 鈴木,28
1列目= 名前,佐藤,鈴木,高橋,田中,山田

WorksheetFunction.Index()関数を使用することで2次元配列から1次元配列への変換を実現しています。

2021/1/9 追記
データが大量の場合
一次元配列 = WorksheetFunction.Index(WorksheetFunction.Transpose(二次元配列), 1)の部分は
一次元配列 = WorksheetFunction.Transpose(WorksheetFunction.Index(二次元配列, 0, 1))とした方が、高速です。
WorksheetFunction.Index(二次元配列, 0, 1)の結果は1列の2次元配列が返されますが、WorksheetFunction.Transpose()関数に1列の2次元配列を渡すと、1次元配列を返すようです。

以下の様にユーザ定義の2次元配列でも可能です

Public Sub Sample2()
    Dim 二次元配列(1 To 5, 1 To 5) As String
    Dim 一次元配列 As Variant
    
    Dim i, j
    For i = 1 To 5
        For j = 1 To 5
            二次元配列(i, j) = Chr(Asc("A") - 1 + j) & i
        Next
    Next
    
    '3行目を一次元配列化する
    一次元配列 = WorksheetFunction.Index(二次元配列, 3)
    Debug.Print "3行目= " & Join(一次元配列, ",")
    
    '1列目を一次元配列化する
    一次元配列 = WorksheetFunction.Index(WorksheetFunction.Transpose(二次元配列), 1)
    Debug.Print "1列目= " & Join(一次元配列, ",")
End Sub

結果は以下の様になります
3行目= A3,B3,C3,D3,E3
1列目= A1,A2,A3,A4,A5

この手法を使えばサンプルコードの様に、1次元配列を引数にとる関数を実行するようなコードが非常に簡潔に記述できるようになります。

#応用例
ここからは筆者の想像ですが(筆者の環境ではスピルが使えないので)
新しく導入されたSpill関数の1つであるSortBy()関数で以下のような使い方ができるのではないかと想像しています。

Public Sub Sample3()
    Dim ソート前テーブル(1 To 5, 1 To 5)
    Dim ソート後テーブル As Variant
    Dim 一列目 As Variant
    Dim 二列目 As Variant
    
    Dim i, j
    For i = 1 To 5
        For j = 1 To 5
            テーブル(i, j) = いろいろ設定
        Next
    Next
    
    '1列目と2列目でソートする
    一列目 = WorksheetFunction.Index(WorksheetFunction.Transpose(ソート前テーブル), 1)
    二列目 = WorksheetFunction.Index(WorksheetFunction.Transpose(ソート前テーブル), 2)    
    ソート後テーブル = WorksheetFunction.SortBy(ソート前テーブル, 一列目, , 二列目)
End Sub

これが出来れば、内部テーブルのソートが非常に簡単になるのですが。。
Spillが使える方だれか報告お願いします。

13
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?