カテゴリー
Microsoft

【Excel VBA】コレクションを 2 次元配列へ変換するいくつかの関数コード

ポイント

  • 配列の要素数がコレクションの要素数より多い場合、コレクション要素を入れられない配列要素には Empty が設定される。
  • 配列のインデックスは 1 次元目、2 次元目とも 1 から始まる。Range.Value に代入することを想定

VBA コード

Option Explicit

''' <summary>
''' コレクションを 2 次元配列へ変換します。
''' 配列のインデックスは 1 から始まります。
''' 2次元配列の要素数 > コレクション要素数の場合、
''' 余った 2 次元配列要素には Empty が設定されます。
''' 2次元配列の要素数 < コレクション要素数の場合、
''' 余っとコレクション要素は破棄されます。
''' </summary>
''' <param name="col">変換対象コレクション</param>
''' <param name="first">1 次元目の要素数</param>
''' <param name="second">2 次元目の要素数</param>
''' <returns>2 次元配列</returns>
Public Function CollectionTo2DArray( _
    ByVal col As Collection, _
    ByVal first As Long, _
    ByVal second As Long) As Variant
    Dim results As Variant: ReDim results(1 To first, 1 To second)
    Dim i As Long, j As Long
    Dim colIndex As Long: colIndex = 1
    ' 配列をループし、要素にコレクションの値を設定する。
    For i = LBound(results, 1) To UBound(results, 1)
        For j = LBound(results, 2) To UBound(results, 2)
            results(i, j) = col.Item(colIndex)
            colIndex = colIndex + 1
            ' コレクション要素がなくなった場合は終了
            If colIndex > col.Count Then
                CollectionTo2DArray = results
                Exit Function
            End If
        Next j
    Next i

    CollectionTo2DArray = results
End Function

''' <summary>
''' 1 次元目の要素数を指定してコレクションを 2 次元配列へ変換します。
''' 配列のインデックスは 1 から始まります。
''' 1 次元目の要素数に合わせて、2 次元目の要素数は定まります。
''' 配列要素数に設定するコレクション要素がない場合は Empty が設定されます。
''' </summary>
''' <param name="col">変換対象コレクション</param>
''' <param name="first">1 次元目の要素数</param>
''' <returns>2 次元配列</returns>
Public Function ColTo2DArrWith1DNum( _
    ByVal col As Collection, _
    ByVal first As Long) As Variant
    ' コレクション要素数を非キスの配列要素数で割った余りがあれば、
    ' もう一つの次元要素数に + 1 する。
    Dim balance As Long: balance = 0
    If Not col.Count Mod first = 0 Then: balance = 1
    Dim second As Long: second = (col.Count ¥ first) + balance
    ' 変換処理
    ColTo2DArrWith1DNum = CollectionTo2DArray(col, first, second)
End Function

''' <summary>
''' 2 次元目の要素数を指定してコレクションを 2 次元配列へ変換します。
''' 配列のインデックスは 1 から始まります。
''' 2 次元目の要素数に合わせて、1 次元目の要素数は定まります。
''' 配列要素数に設定するコレクション要素がない場合は Empty が設定されます。
''' </summary>
''' <param name="col">変換対象コレクション</param>
''' <param name="second">2 次元目の要素数</param>
''' <returns>2 次元配列</returns>
Public Function ColTo2DArrWith2DNum( _
    ByVal col As Collection, _
    ByVal second As Long) As Variant
    ' コレクション要素数を非キスの配列要素数で割った余りがあれば、
    ' もう一つの次元要素数に + 1 する。
    Dim balance As Long: balance = 0
    If Not col.Count Mod second = 0 Then: balance = 1
    Dim second As Long: first = (col.Count ¥ second) + balance
    ' 変換処理
    ColTo2DArrWith2DNum = CollectionTo2DArray(col, first, second)
End Function

関数確認用のテストコードです。

Option Explicit

Public Sub TestCollectionTo2DArray()
    ' 変換前コレクション準備
    Dim colBefores As Collection: Set colBefores = New Collection
    Call colBefores.Add("い")
    Call colBefores.Add("ろ")
    Call colBefores.Add("は")
    Call colBefores.Add("に")
    ' 変換処理
    Dim vntAfters As Variant
    vntAfters = CollectionTo2DArray(colBefores, 10, 10)
    Stop
End Sub

Public Sub TestColTo2DArrWith1DNum()
    ' 変換前コレクション準備
    Dim colBefores As Collection: Set colBefores = New Collection
    Call colBefores.Add("い")
    Call colBefores.Add("ろ")
    Call colBefores.Add("は")
    Call colBefores.Add("に")
    Call colBefores.Add("ほ")
    Call colBefores.Add("へ")
    Call colBefores.Add("と")
    Call colBefores.Add("ち")
    Call colBefores.Add("り")
    Call colBefores.Add("ぬ")
    ' 変換処理
    Dim vntAfters As Variant
    vntAfters = ColTo2DArrWith1DNum(colBefores, 3)
    Stop
End Sub

Public Sub TestColTo2DArrWith2DNum()
    ' 変換前コレクション準備
    Dim colBefores As Collection: Set colBefores = New Collection
    Call colBefores.Add("い")
    Call colBefores.Add("ろ")
    Call colBefores.Add("は")
    Call colBefores.Add("に")
    Call colBefores.Add("ほ")
    Call colBefores.Add("へ")
    Call colBefores.Add("と")
    Call colBefores.Add("ち")
    Call colBefores.Add("り")
    Call colBefores.Add("ぬ")
    ' 変換処理
    Dim vntAfters As Variant
    vntAfters = ColTo2DArrWith2DNum(colBefores, 3)
    Stop
End Sub

関連。他のkレクション・配列変換関数コード

おわりに

Map 関数を実装してみるのに配列やコレクションをループできたほうがよいかしら、そのためにはどちらかに揃える関数があれば後々楽ができるかしら、と思って本投稿の関数を書いてみました。

ところが、実装してみた Map 関数は遅かったですの><。CallByName やダックタイピングを使うなど工夫してみましたけれども、ダメでした。

VBA で避けたほうがよいやり方が 1 つ判明して嬉しいですけれども、強力な手法が使いづらいということですので残念です><。

以上です。

コメントを残す