VBA

【VBA】テーブルの存在をチェックする方法(シートにいくつあるか、指定の範囲がテーブルか)と安全にテーブル化する関数

記事内に商品プロモーションを含む場合があります

こんにちは、hokkyokunです。

テーブルは便利なんですが、テーブルじゃない方が都合がいい場合もあるかと思います。
そんなときはテーブル化したり、解除したりして使い分けることもあると思いますが、
注意が必要です。

テーブルは既にテーブル化しているところは再度テーブル化するとエラーが起こります
エラーが起きるとプログラムが止まってしまうため、円滑な処理が難しくなります。
そのため、今どういう状態なのかを事前にチェックすることが重要となってきます。

安全にテーブル化する関数をご紹介します。

安全にテーブル化する方法

いきなりですが、
この関数だけ押さえておけば、だいたい、大丈夫です。

この関数は結構便利で私もよく使っています。

  • 関数名
    set_Table( targetCell )
  • 引数
     targetCell : セル(データ型はRangeオブジェクト)
  • 戻り値
    テーブル
Function set_Table(ByVal targetCell As range)
    Dim table As ListObject
    
    '指定したセルをリストオブジェクト(テーブルオブジェクト)にセットする
    Set table = targetCell.ListObject
    
    'セットしたテーブルが「Nothing」の場合は新規でテーブル化
    If table Is Nothing Then
        Set set_Table = targetCell.Worksheet.ListObjects.Add(xlSrcRange, targetCell.CurrentRegion, , xlYes)
    
    'そうでない場合はリストオブジェクトにセットする
    Else
        Set set_Table = targetCell.ListObject
    End If
    
End Function

指定したセルがテーブル化しているところだろうとそうでなかろうと
安全にテーブル化し、テーブルを取得できます。

普通に再度テーブル化するとエラーが出る

いきなり関数をお見せしましたが、
テーブル化はちょっと工夫をしないとエラーが出やすいです。

例えば、下記の表で既にテーブル化しているところを
テーブル化してみるとエラーが発生します

Sub テーブル化している場所を再度テーブル化()

ActiveSheet.ListObjects.Add , ActiveSheet.Range("A1").CurrentRegion, , xlYes

End Sub

エラーが生じます。
既にテーブル化しているので、再度テーブル化を命令すると止まってしまいました。

テーブル化しているかどうかチェックする関数

テーブル化しているかどうかだけチェックするなら
下記の関数を使用してください。

  • 関数名
    IS_table( targetCell )
  • 引数
     targetCell : セル(データ型はRangeオブジェクト)
  • 戻り値
    ブール値
    (テーブル化している=True テーブル化していない=False
Function IS_table(ByVal targetCell As range)
    Dim table As ListObject
    Set table = targetCell.ListObject
    If table Is Nothing Then
        IS_table = False
    Else
        IS_table = True
    End If
End Function

下記のような表で
「A1セル」および「A8セル」がテーブル化している範囲かどうか調べるとします。

Sub test_is_table()
    'A1はテーブル化している範囲なのでTrue
    Debug.Print (IS_table(range("A1")))
    '>>True
    
    'A8はテーブル化していないのでFalse
    Debug.Print (IS_table(range("A8")))
    '>>False
End Sub

シートもしくはセル範囲どちらかでテーブルの存在チェックをしたい場合

最後にシートもしくはセル範囲どちらかでテーブル化しているかどうかをチェックする
汎用性の高い関数をご紹介します。

標準プロパティを使ってテーブル数をカウントする

テーブルが標準で持っている
カウントプロパティを利用します。

ワークシートオブジェクト→wsとします。

ws.ListObjects.Count
でシート内のテーブル数を数えることができます。

例えば以下のように同じシートに二つテーブルがある場合

Sub test()
    Debug.Print (ActiveSheet.ListObjects.Count)
    '>>2
End Sub

シートを指定してテーブル化しているかどうかを判断することもできる

上記の方法を利用して
シートもしくはセル範囲を指定してテーブル化しているかどうかを判定してみます。

  • 関数名
    IS_table2( target )
  • 引数
     target : セル範囲 もしくは ワークシート(データ型はVariant)
  • 戻り値
    ブール値
    (テーブル化している=True テーブル化していない=False
Function IS_table2(ByVal target As Variant)
        
    If TypeName(target) = "Worksheet" Then
        If target.ListObjects.Count = 0 Then
            IS_table2 = False
        Else
            IS_table2 = True
        End If
        
    ElseIf TypeName(target) = "Range" Then
        Dim table As ListObject
        Set table = target.ListObject
        If table Is Nothing Then
            IS_table2 = False
        Else
            IS_table2 = True
        End If
    End If

End Function

シートもしくはセル範囲を引数として判断できます。
下記のように試してみました。

Sub test()

    'シートを引数にする場合
    Debug.Print (IS_table2(Worksheets("テーブル有シート")))
    '>>True
    
    Debug.Print (IS_table2(Worksheets("テーブル無シート")))
    '>>False
    
    'セル範囲を引数にする場合
    'A1はテーブル化している範囲
    Debug.Print (IS_table2(Worksheets("テーブル有シート").range("A1")))
    '>>True
    
    'A8はテーブル化していない範囲
    Debug.Print (IS_table2(Worksheets("テーブル有シート").range("A8")))
    '>>False
    
End Sub

ひとつ注意はシートを指定した場合で、
シート内で一つでもテーブル化しているものがあればTrueとなります。

一つのシートに二つ以上テーブルがある可能性がある場合は
正しく判定できない可能性もあるので注意してください。

まとめ

まとめ

安全にテーブル化する関数
set_Table関数

任意のセル範囲がテーブルかどうか判断する関数
IS_table関数

シートもしくはセル範囲を指定して
テーブル化しているかどうかを判定する関数
IS_table2関数