Excel 按名称引用查询表对象
我正在用VBA开发一个MS Excel 2013工具,它涉及到查询表的使用Excel 按名称引用查询表对象,excel,vba,Excel,Vba,我正在用VBA开发一个MS Excel 2013工具,它涉及到查询表的使用 Sub RefreshDataQuery() Dim querySheet As Worksheet Dim interface As Worksheet Set querySheet = Worksheets("QTable") Set interface = Worksheets("Interface") Dim sh As Worksheet Dim QT As QueryTable Dim startTi
Sub RefreshDataQuery()
Dim querySheet As Worksheet
Dim interface As Worksheet
Set querySheet = Worksheets("QTable")
Set interface = Worksheets("Interface")
Dim sh As Worksheet
Dim QT As QueryTable
Dim startTime As Double
Dim endTime As Double
Set QT = querySheet.ListObjects.item(1).QueryTable
startTime = Timer
QT.Refresh
endTime = Timer - startTime
interface.Cells(1, 1).Value = "Elapsed time to run query"
interface.Cells(1, 2).Value = endTime
interface.Cells(1, 3).Value = "Seconds"
End Sub
一个不便之处是访问Excel工作表中的现有查询表。目前,我能找到的唯一访问查询表的方法是通过整数索引。为了快速验证概念,我提出了以下代码:
Sub RefreshDataQuery()
Dim querySheet As Worksheet
Dim interface As Worksheet
Set querySheet = Worksheets("QTable")
Set interface = Worksheets("Interface")
Dim sh As Worksheet
Dim QT As QueryTable
Dim startTime As Double
Dim endTime As Double
Set QT = querySheet.ListObjects.item(1).QueryTable
startTime = Timer
QT.Refresh
endTime = Timer - startTime
interface.Cells(1, 1).Value = "Elapsed time to run query"
interface.Cells(1, 2).Value = endTime
interface.Cells(1, 3).Value = "Seconds"
End Sub
这是可行的,但我不想这样做。最终产品工具最多有五个不同的查询表。我想按名称引用查询表
Sub RefreshDataQuery()
Dim querySheet As Worksheet
Dim interface As Worksheet
Set querySheet = Worksheets("QTable")
Set interface = Worksheets("Interface")
Dim sh As Worksheet
Dim QT As QueryTable
Dim startTime As Double
Dim endTime As Double
Set QT = querySheet.ListObjects.item(1).QueryTable
startTime = Timer
QT.Refresh
endTime = Timer - startTime
interface.Cells(1, 1).Value = "Elapsed time to run query"
interface.Cells(1, 2).Value = endTime
interface.Cells(1, 3).Value = "Seconds"
End Sub
我如何翻译:
Sub RefreshDataQuery()
Dim querySheet As Worksheet
Dim interface As Worksheet
Set querySheet = Worksheets("QTable")
Set interface = Worksheets("Interface")
Dim sh As Worksheet
Dim QT As QueryTable
Dim startTime As Double
Dim endTime As Double
Set QT = querySheet.ListObjects.item(1).QueryTable
startTime = Timer
QT.Refresh
endTime = Timer - startTime
interface.Cells(1, 1).Value = "Elapsed time to run query"
interface.Cells(1, 2).Value = endTime
interface.Cells(1, 3).Value = "Seconds"
End Sub
Set QT = querySheet.ListObjects.item(1).QueryTable
指的是:
Sub RefreshDataQuery()
Dim querySheet As Worksheet
Dim interface As Worksheet
Set querySheet = Worksheets("QTable")
Set interface = Worksheets("Interface")
Dim sh As Worksheet
Dim QT As QueryTable
Dim startTime As Double
Dim endTime As Double
Set QT = querySheet.ListObjects.item(1).QueryTable
startTime = Timer
QT.Refresh
endTime = Timer - startTime
interface.Cells(1, 1).Value = "Elapsed time to run query"
interface.Cells(1, 2).Value = endTime
interface.Cells(1, 3).Value = "Seconds"
End Sub
Set QT = querySheet.ListObjects.items.QueryTable("My Query Table")
根据,没有任何QueryTables
的集合是ListObjects
的属性。正确的代码是:
Sub RefreshDataQuery()
Dim querySheet As Worksheet
Dim interface As Worksheet
Set querySheet = Worksheets("QTable")
Set interface = Worksheets("Interface")
Dim sh As Worksheet
Dim QT As QueryTable
Dim startTime As Double
Dim endTime As Double
Set QT = querySheet.ListObjects.item(1).QueryTable
startTime = Timer
QT.Refresh
endTime = Timer - startTime
interface.Cells(1, 1).Value = "Elapsed time to run query"
interface.Cells(1, 2).Value = endTime
interface.Cells(1, 3).Value = "Seconds"
End Sub
Set QT = querySheet.ListObjects.items(1).QueryTable
您可能需要参考适当的ListObject项
like(只是示例代码):
Sub RefreshDataQuery()
Dim querySheet As Worksheet
Dim interface As Worksheet
Set querySheet = Worksheets("QTable")
Set interface = Worksheets("Interface")
Dim sh As Worksheet
Dim QT As QueryTable
Dim startTime As Double
Dim endTime As Double
Set QT = querySheet.ListObjects.item(1).QueryTable
startTime = Timer
QT.Refresh
endTime = Timer - startTime
interface.Cells(1, 1).Value = "Elapsed time to run query"
interface.Cells(1, 2).Value = endTime
interface.Cells(1, 3).Value = "Seconds"
End Sub
另一种选择是通过以下方式通过工作表属性引用QT:
Sub RefreshDataQuery()
Dim querySheet As Worksheet
Dim interface As Worksheet
Set querySheet = Worksheets("QTable")
Set interface = Worksheets("Interface")
Dim sh As Worksheet
Dim QT As QueryTable
Dim startTime As Double
Dim endTime As Double
Set QT = querySheet.ListObjects.item(1).QueryTable
startTime = Timer
QT.Refresh
endTime = Timer - startTime
interface.Cells(1, 1).Value = "Elapsed time to run query"
interface.Cells(1, 2).Value = endTime
interface.Cells(1, 3).Value = "Seconds"
End Sub
Set QT = Worksheet("QTable").QueryTables("My Query Table")
在Excel2003和更早版本中,外部数据连接将创建一个其父对象为工作表的QueryTable对象。例如,您可以通过QueryTables集合对象访问QueryTable对象。与大多数集合对象一样,您可以将索引号或名称传递给(默认)Item方法以获取它
Sub RefreshDataQuery()
Dim querySheet As Worksheet
Dim interface As Worksheet
Set querySheet = Worksheets("QTable")
Set interface = Worksheets("Interface")
Dim sh As Worksheet
Dim QT As QueryTable
Dim startTime As Double
Dim endTime As Double
Set QT = querySheet.ListObjects.item(1).QueryTable
startTime = Timer
QT.Refresh
endTime = Timer - startTime
interface.Cells(1, 1).Value = "Elapsed time to run query"
interface.Cells(1, 2).Value = endTime
interface.Cells(1, 3).Value = "Seconds"
End Sub
Sheet1.QueryTables("MyQtName")
在新版本中打开2003工作表时,它仍然有一个QueryTable对象,并且可以以相同的方式进行访问。即使您转换了文件格式,查询表仍然存在
Sub RefreshDataQuery()
Dim querySheet As Worksheet
Dim interface As Worksheet
Set querySheet = Worksheets("QTable")
Set interface = Worksheets("Interface")
Dim sh As Worksheet
Dim QT As QueryTable
Dim startTime As Double
Dim endTime As Double
Set QT = querySheet.ListObjects.item(1).QueryTable
startTime = Timer
QT.Refresh
endTime = Timer - startTime
interface.Cells(1, 1).Value = "Elapsed time to run query"
interface.Cells(1, 2).Value = endTime
interface.Cells(1, 3).Value = "Seconds"
End Sub
在2007年及更高版本中,只有三种方法可以创建将成为Worksheet.QueryTables成员的QueryTable:
Sub RefreshDataQuery()
Dim querySheet As Worksheet
Dim interface As Worksheet
Set querySheet = Worksheets("QTable")
Set interface = Worksheets("Interface")
Dim sh As Worksheet
Dim QT As QueryTable
Dim startTime As Double
Dim endTime As Double
Set QT = querySheet.ListObjects.item(1).QueryTable
startTime = Timer
QT.Refresh
endTime = Timer - startTime
interface.Cells(1, 1).Value = "Elapsed time to run query"
interface.Cells(1, 2).Value = endTime
interface.Cells(1, 3).Value = "Seconds"
End Sub
Sub RefreshDataQuery()
Dim querySheet As Worksheet
Dim interface As Worksheet
Set querySheet = Worksheets("QTable")
Set interface = Worksheets("Interface")
Dim sh As Worksheet
Dim QT As QueryTable
Dim startTime As Double
Dim endTime As Double
Set QT = querySheet.ListObjects.item(1).QueryTable
startTime = Timer
QT.Refresh
endTime = Timer - startTime
interface.Cells(1, 1).Value = "Elapsed time to run query"
interface.Cells(1, 2).Value = endTime
interface.Cells(1, 3).Value = "Seconds"
End Sub
这是坏消息。ListObject中其父级没有Name属性的QueryTable。好的,它就在那里,但是如果你试图访问它,你会得到一个运行时错误1004。我猜MS决定了,因为每个ListObject只有一个QueryTable,所以它应该有一个名称是没有意义的
Sub RefreshDataQuery()
Dim querySheet As Worksheet
Dim interface As Worksheet
Set querySheet = Worksheets("QTable")
Set interface = Worksheets("Interface")
Dim sh As Worksheet
Dim QT As QueryTable
Dim startTime As Double
Dim endTime As Double
Set QT = querySheet.ListObjects.item(1).QueryTable
startTime = Timer
QT.Refresh
endTime = Timer - startTime
interface.Cells(1, 1).Value = "Elapsed time to run query"
interface.Cells(1, 2).Value = endTime
interface.Cells(1, 3).Value = "Seconds"
End Sub
如果尝试将工作表.QueryTables.QueryTable转换为ListObject,则外部数据连接将消失,并且新ListObject没有QueryTable
Sub RefreshDataQuery()
Dim querySheet As Worksheet
Dim interface As Worksheet
Set querySheet = Worksheets("QTable")
Set interface = Worksheets("Interface")
Dim sh As Worksheet
Dim QT As QueryTable
Dim startTime As Double
Dim endTime As Double
Set QT = querySheet.ListObjects.item(1).QueryTable
startTime = Timer
QT.Refresh
endTime = Timer - startTime
interface.Cells(1, 1).Value = "Elapsed time to run query"
interface.Cells(1, 2).Value = endTime
interface.Cells(1, 3).Value = "Seconds"
End Sub
由于您的QueryTables.Count返回零,因此您的所有QueryTables都在ListObjects中,并且没有名称。ListObjects具有名称。你可以用
Sub RefreshDataQuery()
Dim querySheet As Worksheet
Dim interface As Worksheet
Set querySheet = Worksheets("QTable")
Set interface = Worksheets("Interface")
Dim sh As Worksheet
Dim QT As QueryTable
Dim startTime As Double
Dim endTime As Double
Set QT = querySheet.ListObjects.item(1).QueryTable
startTime = Timer
QT.Refresh
endTime = Timer - startTime
interface.Cells(1, 1).Value = "Elapsed time to run query"
interface.Cells(1, 2).Value = endTime
interface.Cells(1, 3).Value = "Seconds"
End Sub
Sheet1.ListObjects("MyListName").QueryTable
下面是一个函数,它接受一个名称和一个工作表,并返回一个具有该名称或是具有该名称的ListObject的子级的QueryTable
Sub RefreshDataQuery()
Dim querySheet As Worksheet
Dim interface As Worksheet
Set querySheet = Worksheets("QTable")
Set interface = Worksheets("Interface")
Dim sh As Worksheet
Dim QT As QueryTable
Dim startTime As Double
Dim endTime As Double
Set QT = querySheet.ListObjects.item(1).QueryTable
startTime = Timer
QT.Refresh
endTime = Timer - startTime
interface.Cells(1, 1).Value = "Elapsed time to run query"
interface.Cells(1, 2).Value = endTime
interface.Cells(1, 3).Value = "Seconds"
End Sub
Public Function QueryTableByName(ByVal sName As String, ByRef sh As Worksheet) As QueryTable
Dim qt As QueryTable
Dim lo As ListObject
On Error Resume Next
Set qt = sh.QueryTables(sName)
On Error GoTo 0
If qt Is Nothing Then
On Error Resume Next
Set lo = sh.ListObjects(sName)
On Error GoTo 0
If Not lo Is Nothing Then
On Error Resume Next
Set qt = lo.QueryTable
On Error GoTo 0
End If
End If
Set QueryTableByName = qt
End Function
Set QT=querySheet.ListObjects.items.QueryTable未编译。我没有看到ListObjects的items属性。对于您的第二个建议,设置QT=Worksheet(“QTable”).QueryTables(“我的查询表”),这对我不起作用,因为QTable是预先存在的。我将其更改为:
Set QT=querySheet.ListObjects.items(1)。QueryTable
,它与您的代码类似。您认为“工作表是预先存在的”是什么意思。。。这很明显-将QT的名称更改为您真正拥有的名称。您始终可以通过以下方式检查工作表中QT的数量:Debug.Print Worksheets(“QTable”).QueryTables.Count
以及每个QT的名称:ly have。您始终可以通过以下方式检查工作表中的QT编号:
Debug.Print Worksheets(“QTable”).QueryTables(1).Name`为第一个。如果不清楚,请道歉。查询表不是通过VBA生成的。它是由不同的用户通过数据连接向导构建的。您发布的代码(我之前尝试过)的计数将显示为0,即使我可以通过ListObjects.item(1)访问QueryTable。因此,我猜ListObject数据来自外部源。因此,要访问QT,您需要找到合适的ListObject并使用ListObject.QueryTable
reference。非常好的摘要和功能!这是非常有帮助和描述性的。谢谢@Dick Kusleika遗憾的是,ListObjects在2013年似乎不再具有name属性或QueryTable属性。ListObjects是一个集合对象,在工作表上保存所有ListObject对象。ListObject是一个包含单个实例的对象。集合对象从来没有名称或QueryTable属性,但ListObject仍然有。至少根据MSDN的说法。@DickKusleika我没有看到属于工作表的ListObject对象。他们可能已经处理掉了。