2009-07-13 26 views
23

sto copiando un frammento di codice VBA da MSDN che mi mostra come afferrare i risultati di una query SQL in foglio Excel (Excel 2007):Database Accesso SQL in Excel-VBA

Sub GetDataFromADO() 

    'Declare variables' 
     Set objMyConn = New ADODB.Connection 
     Set objMyCmd = New ADODB.Command 
     Set objMyRecordset = New ADODB.Recordset 

    'Open Connection' 
     objMyConn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;User ID=abc;Password=abc;" 
     objMyConn.Open 

    'Set and Excecute SQL Command' 
     Set objMyCmd.ActiveConnection = objMyConn 
     objMyCmd.CommandText = "select * from myTable" 
     objMyCmd.CommandType = adCmdText 
     objMyCmd.Execute 

    'Open Recordset' 
     Set objMyRecordset.ActiveConnection = objMyConn 
     objMyRecordset.Open objMyCmd 

    'Copy Data to Excel' 
     ActiveSheet.Range("A1").CopyFromRecordset (objMyRecordset) 

End Sub 

ho già aggiunto Microsoft ActiveX Data Objects 2.1 Libreria sotto come riferimento. E questo database è accessibile.

Ora, quando si esegue questa subroutine, si ha un errore:

Errore di runtime 3704: L'operazione non è consentita quando l'oggetto è chiuso.

Sulla dichiarazione:

ActiveSheet.Range("A1").CopyFromRecordset (objMyRecordset) 

Qualsiasi idea del perché?

Grazie.

+0

Aiuto! Sto avendo lo stesso errore, ma le soluzioni di seguito non sono state d'aiuto: http://stackoverflow.com/questions/1682717/vba-adodb-run-time-error-3704 – Steven

risposta

20

Ho aggiunto il catalogo iniziale alla stringa di connessione. Ho anche abbandonato la sintassi ADODB.Command per creare semplicemente la mia istruzione SQL e aprire il recordset su quella variabile.

Spero che questo aiuti.

Sub GetDataFromADO() 
    'Declare variables' 
     Set objMyConn = New ADODB.Connection 
     Set objMyRecordset = New ADODB.Recordset 
     Dim strSQL As String 

    'Open Connection' 
     objMyConn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=MyDatabase;User ID=abc;Password=abc;" 
     objMyConn.Open 

    'Set and Excecute SQL Command' 
     strSQL = "select * from myTable" 

    'Open Recordset' 
     Set objMyRecordset.ActiveConnection = objMyConn 
     objMyRecordset.Open strSQL    

    'Copy Data to Excel' 
     ActiveSheet.Range("A1").CopyFromRecordset (objMyRecordset) 

End Sub 
+2

Ha funzionato per me, grazie, ricordati di aggiungere il riferimento a Microsoft ActiveX Data Objects 2.1, tuttavia ho aggiunto la versione 2.6. Inoltre non hai bisogno di chiudere la connessione alla fine? come objMyRecordset.Close? –

0

È una stringa di connessione corretta?
Dove si trova l'istanza di SQL Server?

È necessario verificare che sia possibile eseguire la connessione a SQL Server utilizzando la stringa di connessione, specificata in precedenza.

MODIFICA: esaminare la proprietà State del recordset per verificare se è aperta?
Inoltre, modificare la proprietà CursorLocation su adUseClient prima di aprire il recordset.

1

Sono seduto a un computer con nessuno dei bit rilevanti del software, ma dalla memoria quel codice sembra sbagliato. Stai eseguendo il comando ma scartando lo RecordSet restituito da objMyCommand.Execute.

farei:

Set objMyRecordset = objMyCommand.Execute 

... e poi perdono la parte "aperta di record".

15

modifiche suggerite:

  • Non invocare il comando Oggetto del metodo Execute;
  • Impostare la proprietà Origine dell'oggetto Recordset come oggetto Command;
  • Richiamare il metodo Open dell'oggetto Recordset senza parametri;
  • Rimuovere le parentesi dall'oggetto Recordset nella chiamata a CopyFromRecordset;
  • realtà dichiarare le variabili :)

codice rivisto:

Sub GetDataFromADO() 

    'Declare variables' 
     Dim objMyConn As ADODB.Connection 
     Dim objMyCmd As ADODB.Command 
     Dim objMyRecordset As ADODB.Recordset 

     Set objMyConn = New ADODB.Connection 
     Set objMyCmd = New ADODB.Command 
     Set objMyRecordset = New ADODB.Recordset 

    'Open Connection' 
     objMyConn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;User ID=abc;Password=abc;"  
     objMyConn.Open 

    'Set and Excecute SQL Command' 
     Set objMyCmd.ActiveConnection = objMyConn 
     objMyCmd.CommandText = "select * from mytable" 
     objMyCmd.CommandType = adCmdText 

    'Open Recordset' 
     Set objMyRecordset.Source = objMyCmd 
     objMyRecordset.Open 

    'Copy Data to Excel' 
     ActiveSheet.Range("A1").CopyFromRecordset objMyRecordset 

End Sub 
+0

+1 per rimuovere le parentesi. Le parentesi non necessarie combinate con riferimenti a oggetti sembrano causare strani errori VBA – barrowc

+0

Questo esempio ha funzionato per me, grazie! – nekomatic

+0

Mi rendo conto che questo è un thread vecchio, ma mi chiedevo se c'è un modo per modificare il codice sopra per recuperare anche le intestazioni della tabella? – firedrawndagger

0

Aggiungere set nocount on all'inizio del proc memorizzato (se siete su SQL Server). Ho appena risolto questo problema nel mio lavoro ed è stato causato da risultati intermedi, come "1203 Rows Affected", caricati nel Recordset che stavo cercando di utilizzare.

0

@firedrawndagger: per elencare i nomi di campo/colonna iterare attraverso i campi di raccolta di record e inserire il nome:

Dim myRS as ADODB.Recordset 
Dim fld as Field 
Dim strFieldName as String 

For Each fld in myRS.Fields 
    Activesheet.Selection = fld.Name 
    [Some code that moves to next column] 
Next 
Problemi correlati