2013-08-05 19 views
12

Sto sviluppando uno strumento MS Excel 2013 con VBA che prevede l'utilizzo di QueryTables. Un inconveniente che sto vivendo è l'accesso a esistenti a QueryTables all'interno di un foglio di lavoro Excel. Attualmente, l'unico metodo che riesco a trovare per accedere a una tabella di query è l'indicizzazione di numeri interi. Sono venuto con il seguente codice per una rapida prova di concettoVBA di Excel fa riferimento a oggetti QueryTable per nome

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 

Questo funziona ma davvero non voglio farlo in questo modo. Lo strumento del prodotto finale avrà fino a cinque diversi QueryTables. Quello che voglio è fare riferimento a una QueryTable con il suo nome.

Quanto sarebbe bello è se potessi tradurre il codice qui sotto

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

Per qualcosa sulla falsariga

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

Tutti i suggerimenti molto sarebbero apprezzati.

risposta

6

Secondo this MSDN link for ListObject non esiste alcuna raccolta di QueryTables che sia una proprietà di ListObjects. codice corretto è:

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

Quello che è forse bisogno è di riferimento di appropriarsi ListObject item come (solo codice di esempio):

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

L'altra alternativa è quella di fare riferimento a QT attraverso WorkSheet property in questo modo:

Set QT = Worksheet("QTable").QueryTables("My Query Table") 
+0

Imposta QT = querySheet.ListObjects.items.QueryTable non viene compilato. Non vedo alcun elemento appropriato per ListObjects. Per il tuo secondo suggerimento, Imposta QT = Foglio di lavoro ("QTable"). QueryTables ("My Query Table"), questo non funziona per me in quanto il QTable era preesistente. –

+0

L'ho modificato in: 'Imposta QT = querySheet.ListObjects.items (1) .QueryTable' che è simile al tuo codice. –

+0

cosa intendi con "foglio di lavoro preesistente?" ... il che è ovvio: cambia il nome di QT in uno che hai veramente. È sempre possibile controllare il numero di QT nel foglio in questo modo: 'Fogli di lavoro Debug.Print (" QTable "). QueryTables.Count' e il nome di ciascun QT in questo modo:' l ho. Puoi sempre controllare il numero di QT nel foglio in questo modo: 'Fogli di lavoro Debug.Print (" QTable "). QueryTables (1) .Name' per il primo. –

8

In Excel 2003 e versioni precedenti, una connessione dati esterna creava un oggetto QueryTable il cui padre era un foglio di lavoro. È possibile accedere all'oggetto QueryTable, per esempio, tramite l'oggetto di raccolta QueryTables. Come la maggior parte degli oggetti di raccolta, è possibile passare un numero di indice o un nome al metodo Item (predefinito) per ottenerlo.

Sheet1.QueryTables("MyQtName") 

Quando si apre un foglio di lavoro 2003 in una nuova versione, ha ancora un oggetto QueryTable e si può accedere allo stesso modo. Anche se si converte il formato del file, il QueryTable persiste.

Nel 2007 e versioni successive, ci sono solo tre modi per creare un QueryTable che sarà un membro della Worksheet.QueryTables:

  1. Tramite il codice
  2. dati - Dal testo
  3. dati - Da Web

Tutte le altre connessioni dati esterne dell'interfaccia utente in queste nuove versioni non risultano in un membro QueryTables, ma in un ListObject. Quel ListObject avrà uno e un solo oggetto QueryTable a cui è possibile accedere tramite la proprietà ListObject.QueryTable.

Ecco le cattive notizie. QueryTable il cui genitore in un oggetto ListObject non ha una proprietà Name. Bene, è lì, ma riceverai un errore di runtime 1004 se proverai ad accedervi. Suppongo che MS abbia deciso poiché c'è una sola QueryTable per ListObject, non aveva senso che avrebbe dovuto avere un nome.

Se si tenta di convertire un oggetto Worksheet.QueryTables.QueryTable in un oggetto ListObject, la connessione dati esterna scompare e il nuovo ListObject non dispone di QueryTable.

Poiché QueryTables.Count restituisce zero, tutti i QueryTables sono all'interno di ListObjects e non hanno nomi. Gli oggetti ListObjects hanno nomi. È possibile utilizzare

Sheet1.ListObjects("MyListName").QueryTable 

Ecco una funzione che prende un nome e un foglio di lavoro e restituisce un QueryTable che o ha quel nome o è figlio di un ListObject che ha quel nome.

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 
+1

Ottimo riassunto e funzione! –

+0

Questo è stato molto utile e descrittivo. Grazie! –

+0

@Dick Kusleika Purtroppo sembra che ListObjects non abbia più una proprietà name nel 2013 o una proprietà QueryTable. –