【发布时间】:2013-08-04 12:50:57
【问题描述】:
是否可以在 Excel VBA 中引用命名表?
假设这可能是...
Sheets("Sheet1").Table("A_Table").Select
我看到有人提到表是一个列表对象,但我不确定这是否是同一件事。
【问题讨论】:
标签: excel vba listobject excel-tables
是否可以在 Excel VBA 中引用命名表?
假设这可能是...
Sheets("Sheet1").Table("A_Table").Select
我看到有人提到表是一个列表对象,但我不确定这是否是同一件事。
【问题讨论】:
标签: excel vba listobject excel-tables
如this answer 中所述将范围转换为表格:
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
【讨论】:
此外,定义引用对象的变量也很方便。例如,
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
您可能会立即发现它的优势。
【讨论】:
除了上述之外,您还可以这样做(其中“YourListObjectName”是您的表的名称):
Dim LO As ListObject
Set LO = ActiveSheet.ListObjects("YourListObjectName")
但我认为只有当您想要引用活动工作表上的列表对象时才有效。
我找到了您的问题,因为我想在一个工作表上引用另一个工作表上的数据透视表所引用的列表对象(表)。由于列表对象是 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
也许有人知道更直接的方法。
【讨论】:
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 中很难使用它们!
【讨论】:
Excel 中的“表”确实称为 ListObject。
引用表的“正确”方法是从其工作表中获取其 ListObject,即SheetObject.ListObjects(ListObjectName)。
如果您想在不使用工作表的情况下引用表格,可以使用 hack Application.Range(ListObjectName).ListObject。
注意: 此 hack 依赖于 Excel 始终为表的 DataBodyRange 创建与表同名的命名范围这一事实。然而,这个范围名称可以改变......虽然这不是你想要做的事情,因为如果你编辑表名,名称将重置!你也可以得到一个没有关联 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 信息here。
【讨论】:
Application.Names 中找到表DataBodyRange 范围名称!但绝对可以使用Application.Range(...) 访问它们。
ActiveSheet 对象的方法相同。
添加第三个选项。 @AndrewD 的第二个选项的“速记”版本。
是的,括号引用中没有引号。
【讨论】: