13

QueryTables を使用する VBA を使用した MS Excel 2013 ツールを開発しています。

1 つの不都合は、Excel ワークシート内の既存のQueryTables にアクセスすることです。現在、クエリ テーブルにアクセスする唯一の方法は、整数インデックスを使用することです。概念を簡単に証明するために、次のコードを思いつきました。

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

これはうまくいきますが、私はこのようにしたくありません。最終製品ツールには、最大 5 つの異なる QueryTable があります。名前で QueryTable を参照したい。

どのように翻訳できますか:

Set QT = querySheet.ListObjects.item(1).QueryTable

次のようなものに:

Set QT = querySheet.ListObjects.items.QueryTable("My Query Table")
4

3 に答える 3

10

Excel 2003 以前では、外部データ接続によって、親がワークシートである QueryTable オブジェクトが作成されました。たとえば、QueryTables コレクション オブジェクトを介して QueryTable オブジェクトにアクセスできます。ほとんどのコレクション オブジェクトと同様に、インデックス番号または名前を (既定の) Item メソッドに渡して取得できます。

Sheet1.QueryTables("MyQtName")

新しいバージョンで 2003 のワークシートを開くと、まだ QueryTable オブジェクトがあり、同じ方法でアクセスできます。ファイル形式を変換しても、QueryTable は保持されます。

2007 以降のバージョンでは、Worksheet.QueryTables のメンバーとなる QueryTable を作成する方法は 3 つしかありません。

  1. コードを通して
  2. データ - テキストから
  3. データ - ウェブから

これらの新しいバージョンの他のすべての UI 外部データ接続は、QueryTables メンバーではなく、ListObject になります。その ListObject には、ListObject.QueryTable プロパティを介してアクセスできる QueryTable オブジェクトが 1 つだけあります。

これが悪いニュースです。ListObject 内の親が Name プロパティを持たない QueryTable。そこにはありますが、アクセスしようとすると実行時エラー 1004 が発生します。ListObject ごとに QueryTable が 1 つしかないため、MS が決定したと思います。名前を付ける必要はありませんでした。

Worksheet.QueryTables.QueryTable を ListObject に変換しようとすると、外部データ接続が失われ、新しい ListObject には QueryTable がありません。

QueryTables.Count がゼロを返すため、すべての QueryTables は ListObjects 内にあり、名前がありません。ListObject には名前があります。使用できます

Sheet1.ListObjects("MyListName").QueryTable

名前とワークシートを受け取り、その名前を持つか、その名前を持つ ListObject の子である QueryTable を返す関数を次に示します。

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
于 2013-08-05T22:47:54.920 に答える
6

この ListObject の MSDN リンクによるとQueryTables、 のプロパティであるコレクションはありませんListObjects。正しいコードは次のとおりです。

Set QT = querySheet.ListObjects.items(1).QueryTable

おそらく必要なのは、適切なListObject itemようなものを参照することです(サンプルコードのみ):

Dim LS as ListObject
Set LS = querySheet.ListObjects("My LO 1")
Set QT = LS.QueryTable

もう 1 つの方法は、次の方法で QT を参照することWorkSheet propertyです。

Set QT = Worksheet("QTable").QueryTables("My Query Table")
于 2013-08-05T20:41:53.240 に答える