web-dev-qa-db-ja.com

Excel vbaでテーブルを参照するにはどうすればよいですか?

Excel VBAでは、名前付きテーブルを参照できますか?

仮にこれは...

Sheets("Sheet1").Table("A_Table").Select

私はテーブルがリストオブジェクトであるという言及を見てきましたが、それが同じものであるかどうかはわかりません...

28
1212__Hello

たぶんこれはあなたを助けることができます

テーブルを作成する

範囲のテーブルへの変換は、Excel 2003と同じコードで開始されます( この回答 で説明)。

Sub CreateTable()
    ActiveSheet.ListObjects.Add(xlSrcRange, Range("$B$1:$D$16"), , xlYes).Name = _
        "Table1"
        'No go in 2003
    ActiveSheet.ListObjects("Table1").TableStyle = "TableStyleLight2"
End Sub
6
Bgvv1983

OPは、テーブルの追加方法ではなく、テーブルの参照が可能かどうかを尋ねました。そのため、

Sheets("Sheet1").Table("A_Table").Select

このステートメントになります:

Sheets("Sheet1").ListObjects("A_Table").Range.Select

または、パーツを選択するには(テーブル内のデータのみ):

Dim LO As ListObject
Set LO = Sheets("Sheet1").ListObjects("A_Table")
LO.HeaderRowRange.Select        ' Select just header row
LO.DataBodyRange.Select         ' Select just data cells
LO.TotalsRowRange.Select        ' Select just totals row

パーツについては、ヘッダーと合計行の存在をテストしてから選択することができます。

そして真剣に、これはSOでVBAのテーブルを参照する唯一の質問ですか? Excelのテーブルは非常に理にかなっていますが、VBAでの作業は非常に困難です。

80
GlennFromIowa

Excelの「テーブル」は、実際にはListObjectとして知られています。

テーブルを参照する「適切な」方法は、ワークシートからListObjectを取得することです。つまり、SheetObject.ListObjects(ListObjectName)です。

シートを使用せずにテーブルを参照する場合は、ハックApplication.Range(ListObjectName).ListObjectを使用できます。

注:このハックは、ExcelがテーブルのDataBodyRangeと同じ名前の名前付き範囲を常に作成するという事実に依存していますテーブル。ただし、この範囲名canを変更します...ただし、テーブル名を編集すると名前がリセットされるため、やりたいことではありません!また、関連付けられていない名前付き範囲を取得できますListObject

名前を間違えたときにExcelの非常に役に立たない1004エラーメッセージが与えられた場合、ラッパーを作成することができます。

Public Function GetListObject(ByVal ListObjectName As String, Optional ParentWorksheet As Worksheet = Nothing) As Excel.ListObject
On Error Resume Next

    If (Not ParentWorksheet Is Nothing) Then
        Set GetListObject = ParentWorksheet.ListObjects(ListObjectName)
    Else
        Set GetListObject = Application.Range(ListObjectName).ListObject
    End If

On Error GoTo 0 'Or your error handler

    If (Not GetListObject Is Nothing) Then
        'Success
    ElseIf (Not ParentWorksheet Is Nothing) Then
        Call Err.Raise(1004, ThisWorkBook.Name, "ListObject '" & ListObjectName & "' not found on sheet '" & ParentWorksheet.Name & "'!")
    Else
        Call Err.Raise(1004, ThisWorkBook.Name, "ListObject '" & ListObjectName & "' not found!")
    End If

End Function

また、いくつかの優れたListObject情報 ここ

26
AndrewD

さらに、オブジェクトを参照する変数を定義すると便利です。例えば、

Sub CreateTable()
    Dim lo as ListObject
    Set lo = ActiveSheet.ListObjects.Add(xlSrcRange, Range("$B$1:$D$16"), , xlYes)
    lo.Name = "Table1"
    lo.TableStyle = "TableStyleLight2"
    ...
End Sub

おそらくすぐに有利になるでしょう。

7
sancho.s

上記に加えて、これを行うことができます(「YourListObjectName」はテーブルの名前です):

Dim LO As ListObject
Set LO = ActiveSheet.ListObjects("YourListObjectName")

ただし、アクティブなシート上にあるリストオブジェクトを参照する場合にのみ機能すると思います。

別のワークシートのピボットテーブルが参照する1つのワークシートのリストオブジェクト(テーブル)を参照したいので、あなたの質問を見つけました。リストオブジェクトはWorksheetsコレクションの一部であるため、リストオブジェクトを参照するには、リストオブジェクトが存在するワークシートの名前を知っている必要があります。リストオブジェクトが存在するワークシートの名前を取得するには、ピボットテーブルのソースリストオブジェクト(再びテーブル)の名前を取得し、リストを含むワークシートが見つかるまでワークシートとそのリストオブジェクトをループ処理しました。私が探していたオブジェクト。

Public Sub GetListObjectWorksheet()
' Get the name of the worksheet that contains the data
' that is the pivot table's source data.

    Dim WB As Workbook
    Set WB = ActiveWorkbook

    ' Create a PivotTable object and set it to be
    ' the pivot table in the active cell:
    Dim PT As PivotTable
    Set PT = ActiveCell.PivotTable

    Dim LO As ListObject
    Dim LOWS As Worksheet

    ' Loop through the worksheets and each worksheet's list objects
    ' to find the name of the worksheet that contains the list object
    ' that the pivot table uses as its source data:
    Dim WS As Worksheet
    For Each WS In WB.Worksheets
        ' Loop through the ListObjects in each workshet:
        For Each LO In WS.ListObjects
            ' If the ListObject's name is the name of the pivot table's soure data,
            ' set the LOWS to be the worksheet that contains the list object:
            If LO.Name = PT.SourceData Then
                Set LOWS = WB.Worksheets(LO.Parent.Name)
            End If
        Next LO
    Next WS

    Debug.Print LOWS.Name

End Sub

誰かがもっと直接的な方法を知っているかもしれません。

5
Hugh Seagraves