テーブルの列を指定して配列を作成するとき、テーブルの行数によって結果が変わる話(失敗談)

例えば、こんなテーブルについてのお話。
f:id:Infoment:20210921231711p:plain

このテーブル(行数可変)で、こんな処理を行ったとする。

Sub Test()

    ' 名前列の値を配列に格納。
    Dim arr As Variant
        arr = ActiveSheet.ListObjects(1).ListColumns("名前").DataBodyRange
    
    ' 一つずつイミディエイトに表示。
    Dim i As Long
        For i = 1 To UBound(arr)
            Debug.Print arr(i, 1)
        Next

End Sub

このような結果を得る。
f:id:Infoment:20210921232112p:plain

テスト段階で問題なく動いたため、本番稼働開始。すると程なくして、
エラーが発生する。
f:id:Infoment:20210921232247p:plain
f:id:Infoment:20210921232303p:plain

なぜだ、何が起きたんだ。と、テーブルを見てみると、行数が一行しかない。
f:id:Infoment:20210921232357p:plain

このような場合、arrはVariant/String型の変数としてふるまう。
f:id:Infoment:20210921232520p:plain

配列ではないのに、配列として扱うから、エラーになる。
そこでエラーを回避するために、場合分けを行う。

  1. テーブルが0行の場合:空配列とする。
  2. テーブルが1行の場合:一行一列の配列を作成して格納する。
  3. テーブルが2行以上の場合:指定列を配列にガバッと格納する。
Sub Test()

    
    Dim Tb As ListObject
    Set Tb = ActiveSheet.ListObjects(1)
    
    ' 名前列の値を配列に格納。
    Dim arr As Variant
    ' テーブルの行数によって処理を変更。
        Select Case Tb.ListRows.Count
            Case 0
                arr = Array()
            Case 1
                ReDim arr(1 To 1, 1 To 1)
                arr(1, 1) = Tb.ListColumns("名前").DataBodyRange
            Case Else
                arr = Tb.ListColumns("名前").DataBodyRange
        End Select
    
    ' 一つずつイミディエイトに表示。
    Dim i As Long
        For i = 1 To UBound(arr)
            Debug.Print arr(i, 1)
        Next

End Sub

すると、テーブルが0または1行の場合でもエラーにならない。
f:id:Infoment:20210921233602p:plain

実はこれ、毎回分かっているのに同じ間違いをしてしまう。
のど元過ぎれば何とやらで、先日も同じ失敗をしてしまった。
気を付けねば。

参考まで。