2009-05-27 6 views
15

Tutto ciò che sto cercando di fare è prendere un intervallo standard su un foglio excel (ovvero un intervallo denominato, o anche A1: F100), ed eseguire alcune query SQL su di esso e restituire un recordset che posso passare sia in VBA codice, o anche solo incollare in qualche altro foglio nella stessa cartella di lavoro.Come posso eseguire istruzioni SQL su un intervallo denominato all'interno di un foglio Excel?

L'utilizzo di ADODB era un pensiero, ma come è possibile impostare la connessione per indicare un intervallo all'interno della cartella di lavoro corrente?

So che prima ho fatto uso della procedura guidata di query Microsoft, che non era l'ideale, ma avrebbe funzionato. Non riesco a ottenere questo per fare riferimento a un intervallo all'interno del foglio, solo altri file Excel.


Ecco la funzione che mi rimane. Quando lo eseguo alcune volte, il mio excel si blocca con il solito messaggio di errore relativo alle risorse esaurite. Ho rimosso questa funzione dal mio foglio di calcolo e tutto viene eseguito senza interruzioni più volte, quindi è sicuramente causato dal codice qui.

Ho ripulito tutti gli oggetti (correttamente?). Qualcuno ha qualche idea su cosa potrebbe andare storto? Potrebbe esserci qualcosa nella stringa di connessione che potrebbe essere modificata, o potrebbe essere qualcosa a che fare con la variante che viene restituita dal metodo GetRows?

Sto usando MS ADO 2.8 e ho anche provato 2.5 con lo stesso comportamento.

Function getTimeBuckets() As Collection 

Dim strFile As String 
Dim strCon As String 
Dim strSQL As String 
Dim dateRows As Variant 
Dim i As Integer 
Dim today As Date 

Dim cn As ADODB.Connection 
Dim rs As ADODB.Recordset 

Set cn = CreateObject("ADODB.Connection") 
Set rs = CreateObject("ADODB.Recordset") 
Set getTimeBuckets = New Collection 

strFile = ThisWorkbook.FullName 
strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strFile _ 
    & ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";" 
cn.Open strCon 

strSQL = "SELECT DISTINCT(Expiration) FROM [PositionSummaryTable] where [Instrument Type] = 'LSTOPT'" 

rs.Open strSQL, cn 


dateRows = rs.GetRows 
rs.Close 

'today = Date 
today = "6-may-2009" 

For i = 1 To UBound(dateRows, 2) 
    If (dateRows(0, i) >= today) Then 
     getTimeBuckets.Add (dateRows(0, i)) 
    End If 
Next i 

Set dateRows = Nothing 
Set cn = Nothing 
Set rs = Nothing 
End Function 

risposta

16

Si può semplicemente usare il nome.

Dim cn As ADODB.Connection 
Dim rs As ADODB.Recordset 

strFile = Workbooks(1).FullName 
strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strFile _ 
    & ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";" 

Set cn = CreateObject("ADODB.Connection") 
Set rs = CreateObject("ADODB.Recordset") 

cn.Open strCon 

''Pick one: 
strSQL = "SELECT * FROM DataTable" ''Named range 
strSQL = "SELECT * FROM [Sheet1$A1:E346]" ''Range 

rs.Open strSQL, cn 

Debug.Print rs.GetString 

In risposta alla domanda parte 2

mi accorgo che si desidera solo i record di oggi, così si dovrebbe essere in grado di modificare il codice SQL per:

strSQL = "SELECT DISTINCT(Expiration) FROM [PositionSummaryTable] " _ 
& "where [Instrument Type] = 'LSTOPT' AND [Expiration]=#" _ 
& Format(Date(),"yyyy/mm/dd") & "#" 

Non hai chiuso la connessione:

cn.Close 

E quindi

Set rs=Nothing 
Set cn=Nothing 
+0

Grazie, funziona alla grande. Devo aver avuto qualcos'altro di sbagliato (vedi sopra commento), che mi ha fatto pensare che dovevi fare qualcosa di diverso con la stringa di connessione. – cOrOllArY

+0

È possibile che si verifichino problemi con ADO se non si è salvato. – Fionnuala

+0

Funziona tutto perfettamente, ma c'è una sorta di perdita di memoria in corso. Inserirò la funzione qui sotto perché è troppo lunga per il commento. – cOrOllArY

0

Troverete tutto ciò che serve qui sotto:

primo collegamento è per VB.NET, collega 2-6 sono per VBA.

One

Two

Three

Four

Five

Six

Trovato tutto in google, circa 2 - 4 minuti.

+1

Hi praavDa ho trovato tutti questi stessi collegamenti. Sto cercando un modo per farlo dal file che ho aperto, non un documento excel separato. Tutto ciò di cui ho bisogno è come configurare la stringa di connessione in modo che faccia riferimento al documento corrente da cui si chiama il codice VBA o, se questo è anche possibile. Grazie, Mike – cOrOllArY

+0

Ciao Mike. Da quanto ho capito, il documento di riferimento è quello a cui si fa riferimento come origine dati. Dim stCon As String stCon = "Provider = Microsoft.Jet.OLEDB.4.0;" _ & "Origine dati = c: \ VBExtreme.xls;" _ & "Proprietà estese =" "Excel 8.0; HDR = SÌ" ";" Come percorso della cartella di lavoro attiva può essere acheived con: Dim wb Come cartella di lavoro Set wb = ActiveWorkbook path = a.path & "\" & a.Name Con set percorso, la stringa con destra vorrebbe come: Dim stCon As String stCon = "Provider = Microsoft.Jet.OLEDB.4.0;" _ & "Origine dati =" & percorso _ & "Proprietà estese =" "Excel 8.0; HDR = SÌ" ";" – praavDa

+0

E se non sbaglio, l'ultima parte della stringa è la versione della libreria presente nel menu Strumenti/Riferimenti dell'editor VBA in Excel (molto probabilmente 11 per Excel 2003 o 12 per il 2007). Scusa per la formattazione nell'ultima, non sapevo, che non potevo usare le interruzioni di riga nei commenti :) – praavDa

0

Non so su VBA, ma ci sono code on-line in Delphi e C# che utilizza il formato

SELECT * FROM [SheetName$A1:B2] 

Avete provato?

+1

come eseguiresti una dichiarazione come questa in VBA? – cOrOllArY

1

Come utilizzare la clausola LIKE?

Ho cercato di usare:

select * from [PES$] where PID_TAG like '*5400001' 

senza successo ....

questo funziona:

select * from [PES$] where PID_TAG = 'PIT5400001' 

ma questo non è che voglio.

EDIT

hummm .... abbiamo bisogno di cambiare i caratteri jolly per lavorare ... non usano *, uso%

0

Se si utilizza PowerShell, $ è un personaggio interna . usare `$

esempio:

"Select * from [VM`$A3:F30]"