配列になってなかった(失敗談)

今回は、配列にまつわる失敗談。
f:id:Infoment:20200623222839p:plain

例えば、こんな名簿があるとする。
f:id:Infoment:20200623223159p:plain

この「名前」の部分を一旦配列に格納して、処理したいと考えた。

Sub Test()
    ' テーブルを変数に格納。
    Dim Tb As Excel.ListObject
    Set Tb = ActiveSheet.ListObjects(1)
    
    ' 名前の列を配列に格納。
    Dim arr As Variant
        arr = Tb.ListColumns("名前").DataBodyRange
    
    ' 繰り返し処理で配列の中身をイミディエイトウィンドウに表示。
    Dim person As Variant
        For Each person In arr
            Debug.Print person
        Next
End Sub

For Eachで繰り返し処理しているので、テーブルの行数は不問となる。
f:id:Infoment:20200623223814p:plain

ところが、色々とテストしていると、エラーになるパターンがあった。
f:id:Infoment:20200623223851p:plain

どういう場合かというと、それは、レコードが一行しかないとき。
f:id:Infoment:20200623223954p:plain

変数をVariantで宣言していたため、レコードが一行しかない場合、arrはString型の変数として振舞ってしまった(?)ようだ。
f:id:Infoment:20200623224133p:plain

配列ではないため、ループさせようとした結果、エラーとなった。

そこで、今回採った解決策がコチラ。

Sub Test()
    ' テーブルを変数に格納。
    Dim Tb As Excel.ListObject
    Set Tb = ActiveSheet.ListObjects(1)
    
    ' 名前の列を配列に格納。
    Dim arr As Variant
        arr = Tb.ListColumns("名前").DataBodyRange
        
    ' 文字列の場合、要素が1個だけの配列に変換。
        If IsArray(arr) = False Then
            arr = Array(arr)
        End If
    
    ' 繰り返し処理で配列の中身をイミディエイトウィンドウに表示。
    Dim person As Variant
        For Each person In arr
            Debug.Print person
        Next
End Sub

配列でなかった場合は、強引に配列化している。
でもきっと、もっとスマートな方法があるに違いない。です。

参考まで。