このページの内容について
このページは、VBAエキスパート(ExcelVBAスタンダード)試験合格講座の第十三回記事です。公式テキスト第8章「テーブルの操作」の内容について解説します。自分でも手を動かしながら読み進めてください。主に講座受講者の復習での利用を想定しています。
テーブル(ListObjectオブジェクト)
Excelは表のデータをデータベースのようにして扱うことができる「テーブル」という機能があります。テーブルの操作には「ListObject」というオブジェクトを使用します。

テーブルを特定する方法
テーブルを操作するためのListObjectオブジェクトを取得する方法はいくつか存在します。
Rangeのプロパティ
テーブルに含まれるセルの一つからListObjectオブジェクトを取得する方法です。
サンプルコード(クリックでコピー)
Private Sub Test_GetListObjectByRange()
Dim ws As Worksheet
Dim rng As Range
Dim list As ListObject
Set ws = ThisWorkbook.Worksheets(1)
Set rng = ws.Range("A1")
Set list = rng.ListObject
Debug.Print list.Name
End Sub
実行結果
上記サンプルコードは、マクロが動作中のブックの一番左のシートにセル「A1」を含むテーブルがあると、テーブルの名前をイミディエイトウィンドウに出力します。テーブルがない場合、エラーになります。

WorkSheetのプロパティ
WorkSheetオブジェクトは「ListObjects」コレクションを持っています。インデックスもしくはテーブルの名前でコレクションから取得することができます。インデックスで指定する場合は、テーブルが作成された順番を指定します。
サンプルコード(クリックでコピー)
Private Sub Test_GetListObjectByWorkSheet_IndexVer()
Dim ws As Worksheet
Dim list As ListObject
Set ws = ThisWorkbook.Worksheets(1)
Set list = ws.ListObjects(1)
Debug.Print list.Name
End Sub
Private Sub Test_GetListObjectByWorkSheet_NameVer()
Dim ws As Worksheet
Dim list As ListObject
Set ws = ThisWorkbook.Worksheets(1)
Set list = ws.ListObjects("テーブル1")
Debug.Print list.Name
End Sub
実行結果
上記サンプルコードは、マクロが動作中のブックの一番左のシートで、一番最初に作成されたテーブル、もしくは「テーブル1」というの名前のテーブルを取得し、テーブルの名前をイミディエイトウィンドウに出力します。テーブルがない場合、エラーになります。
テーブルからデータを取得する
ListObjectのプロパティを参照することで、テーブルのデータを取得することができます。
プロパティ | 型 | 役割 |
---|---|---|
Range | Range | タイトル行を含むすべてのテーブル範囲 |
DataBodyRange | Range | タイトル行を除くすべてのテーブル範囲 |
HeaderRowRange | Range | タイトル行のみ |
ListColmunns | ListColumnの コレクション | すべての列 |
ListRows | ListRowの コレクション | すべての行(タイトル行を除く) |
Range(すべてのテーブル範囲)
サンプルコード(クリックでコピー)
Private Sub Test_GetListObjectRange()
Dim ws As Worksheet
Dim list As ListObject
Set ws = ThisWorkbook.Worksheets(1)
Set list = ws.ListObjects("テーブル1")
Debug.Print list.Range.Address
End Sub
実行結果
上記サンプルコードは、マクロが動作中のブックの一番左のシートに「テーブル1」という名前のテーブルが存在する場合、そのテーブルのすべてのセル範囲を示すRangeオブジェクトを取得し、Addressプロパティでセルのアドレスをイミディエイトウィンドウに出力します。
DataBodyRange(タイトル行を含まないすべてのテーブル範囲)
サンプルコード(クリックでコピー)
Private Sub Test_GetListObjectDataBodyRange()
Dim ws As Worksheet
Dim list As ListObject
Dim col As ListColumn
Set ws = ThisWorkbook.Worksheets(1)
Set list = ws.ListObjects("テーブル1")
Debug.Print list.DataBodyRange.Address
End Sub
実行結果
上記サンプルコードは、マクロが動作中のブックの一番左のシートに「テーブル1」という名前のテーブルが存在する場合、そのテーブルのタイトル行を除くすべてのセル範囲を示すRangeオブジェクトを取得し、Addressプロパティでセルのアドレスをイミディエイトウィンドウに出力します。
HeaderRowRange(タイトル行のみ)
サンプルコード(クリックでコピー)
Private Sub Test_GetListObjectHeaderRowRange()
Dim ws As Worksheet
Dim list As ListObject
Dim col As ListColumn
Set ws = ThisWorkbook.Worksheets(1)
Set list = ws.ListObjects("テーブル1")
Debug.Print list.HeaderRowRange.Address
End Sub
実行結果
上記サンプルコードは、マクロが動作中のブックの一番左のシートに「テーブル1」という名前のテーブルが存在する場合、そのテーブルのタイトル行を除くすべてのセル範囲を示すRangeオブジェクトを取得し、Addressプロパティでセルのアドレスをイミディエイトウィンドウに出力します。
ListColumns(すべての列)
ListColumnsコレクションはListColumnオブジェクトの集合体です。Workbooksなどと同様、インデックスもしくは名前でListColumnオブジェクトを参照することができます。
サンプルコード(クリックでコピー)
Private Sub Test_GetListObjectColumnByName()
Dim ws As Worksheet
Dim list As ListObject
Dim col As ListColumn
Set ws = ThisWorkbook.Worksheets(1)
Set list = ws.ListObjects("テーブル1")
Set col = list.ListColumns("商品名")
Debug.Print col.Range.Address
End Sub
Private Sub Test_GetListObjectColumnByIndex()
Dim ws As Worksheet
Dim list As ListObject
Dim col As ListColumn
Set ws = ThisWorkbook.Worksheets(1)
Set list = ws.ListObjects("テーブル1")
Set col = list.ListColumns(3)
Debug.Print col.Range.Address
End Sub
実行結果
上記サンプルコードは、マクロが動作中のブックの一番左のシートに「テーブル1」という名前のテーブルが存在する場合、そのテーブル3列目(商品名)のListCulumnオブジェクトを取得・Rangeプロパティ⇒Addressプロパティと参照しセルのアドレスをイミディエイトウィンドウに出力します。
ListRows(タイトル行を除くすべての行)
ListRowsコレクションはListRowオブジェクトの集合体です。ListColumnsとは異なり、行には名前が付いていないため、インデックスでのみ参照ができます。
サンプルコード(クリックでコピー)
Private Sub Test_GetListObjectRow()
Dim ws As Worksheet
Dim list As ListObject
Dim row As ListRow
Set ws = ThisWorkbook.Worksheets(1)
Set list = ws.ListObjects("テーブル1")
Set row = list.ListRows(1)
Debug.Print row.Range.Address
End Sub
実行結果
上記サンプルコードは、マクロが動作中のブックの一番左のシートに「テーブル1」という名前のテーブルが存在する場合、そのテーブル1行目のListRowオブジェクトを取得・Rangeプロパティ⇒Addressプロパティと参照しセルのアドレスをイミディエイトウィンドウに出力します。
構造化参照
テーブルには「構造化参照」と呼ばれるデータを取得する方法があります。構造化参照ではテーブル名や列名、特殊な記号を使ってテーブル内のデータを取得できます。ExcelVBAでは、この機能の一部を使用することができます。
すべてのテーブル範囲
ListObject.Rangeと同じく、すべてのテーブル範囲を取得できます。
サンプルコード(クリックでコピー)
Private Sub Test_StructuredReferenceAll()
Dim ws As Worksheet
Dim rng As Range
Set ws = ThisWorkbook.Worksheets(1)
Set rng = ws.Range("テーブル1[#All]")
Debug.Print rng.Address
End Sub
実行結果
上記サンプルコードは、マクロが動作中のブックの一番左のシートに「テーブル1」という名前のテーブルが存在する場合、そのテーブルすべてのセル範囲を取得し、アドレスをイミディエイトウィンドウに出力します。
タイトル行除くすべてのテーブル範囲
ListObject.DataBodyRangeと同じく、タイトル行を除くすべてのテーブル範囲を取得できます。
サンプルコード(クリックでコピー)
Private Sub Test_StructuredReferenceData()
Dim ws As Worksheet
Dim rng As Range
Set ws = ThisWorkbook.Worksheets(1)
Set rng = ws.Range("テーブル1[#Data]")
Debug.Print rng.Address
End Sub
実行結果
上記サンプルコードは、マクロが動作中のブックの一番左のシートに「テーブル1」という名前のテーブルが存在する場合、そのテーブルのタイトル行を除くすべてのセル範囲を取得し、アドレスをイミディエイトウィンドウに出力します。
特定の列
ListObject.ListColumnsのようにすべての列を取得する方法はありません。列名を指定して、その列全体を取得することができます。
サンプルコード(クリックでコピー)
Private Sub Test_StructuredReferenceColmnAll()
Dim ws As Worksheet
Dim rng As Range
Set ws = ThisWorkbook.Worksheets(1)
Set rng = ws.Range("テーブル1[[#All],[商品名]]")
Debug.Print rng.Address
End Sub
Private Sub Test_StructuredReferenceColmnData()
Dim ws As Worksheet
Dim rng As Range
Set ws = ThisWorkbook.Worksheets(1)
Set rng = ws.Range("テーブル1[[#Data],[商品名]]")
Debug.Print rng.Address
End Sub
実行結果
上記サンプルコードは、マクロが動作中のブックの一番左のシートに「テーブル1」という名前のテーブルが存在する場合、そのテーブルの「商品名」という列を取得し、そのアドレスをイミディエイトウィンドウに出力します。上段は列全体、下段は、タイトル行を除く列全体。
テーブルへ行・列を追加する
テーブルへの行・列の追加は「ListColumns」「ListRows」のAddメソッドを使用します。
列の追加
サンプルコード(クリックでコピー)
Private Sub Test_GetListObjectAddColumn()
Dim ws As Worksheet
Dim list As ListObject
Set ws = ThisWorkbook.Worksheets(1)
Set list = ws.ListObjects("テーブル1")
Call list.ListColumns.Add
End Sub
実行結果
上記サンプルコードは、マクロが動作中のブックの一番左のシートに「テーブル1」という名前のテーブルが存在する場合、そのテーブルの一番右に1列追加します。
行の追加
サンプルコード(クリックでコピー)
Private Sub Test_GetListObjectAddRow()
Dim ws As Worksheet
Dim list As ListObject
Set ws = ThisWorkbook.Worksheets(1)
Set list = ws.ListObjects("テーブル1")
Call list.ListRows.Add
End Sub
実行結果
上記サンプルコードは、マクロが動作中のブックの一番左のシートに「テーブル1」という名前のテーブルが存在する場合、そのテーブルの一番下に1行追加します。
テーブルの行・列を削除する
テーブルの行・列の削除は「ListColumn」「ListRow」のDeleteメソッドを使用します。
列の削除
サンプルコード(クリックでコピー)
Private Sub Test_GetListObjectDeleteColumn()
Dim ws As Worksheet
Dim list As ListObject
Set ws = ThisWorkbook.Worksheets(1)
Set list = ws.ListObjects("テーブル1")
Call list.ListColumns(1).Delete
End Sub
実行結果
上記サンプルコードは、マクロが動作中のブックの一番左のシートに「テーブル1」という名前のテーブルが存在する場合、そのテーブルの1列目を削除します。
行の追削除
サンプルコード(クリックでコピー)
Private Sub Test_GetListObjectDeleteRow()
Dim ws As Worksheet
Dim list As ListObject
Set ws = ThisWorkbook.Worksheets(1)
Set list = ws.ListObjects("テーブル1")
Call list.ListRows(1).Delete
End Sub
実行結果
上記サンプルコードは、マクロが動作中のブックの一番左のシートに「テーブル1」という名前のテーブルが存在する場合、そのテーブルの1行目を削除します。
Comment