Accès à la base de données SQL dans Excel-VBA
je copie un extrait de code VBA de MSDN qui me montre comment saisir les résultats d'une requête SQL dans une feuille excel (Excel 2007):
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
J'ai déjà ajouté Microsoft ActiveX Data Objects 2.1 Library comme référence. Et cette base de données est accessible.
maintenant, quand j'exécute ce sous-programme, il a une erreur:
<!-Erreur 3704: L'opération n'est pas autorisée lorsque l'objet est fermé.Sur la déclaration:
ActiveSheet.Range("A1").CopyFromRecordset (objMyRecordset)
<!-- 2-vous savez pourquoi?
Merci.
6 réponses
j'ai ajouté le catalogue Initial à votre chaîne de connexion. J'ai aussi abandonné L'ADODB.La syntaxe de commande en faveur de la création de mon propre énoncé SQL et d'ouvrir le recordset sur cette variable.
Espérons que cette aide.
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
les modifications Suggérées:
- N'invoquez pas la méthode Execute de L'objet Command;
- définissez la propriété Source de L'objet Recordset comme étant votre objet de commande;
- Invoque le jeu d'enregistrements méthode Open de l'objet sans paramètres;
- Supprimer les parenthèses autour de l'objet Recordset dans l'appel à
CopyFromRecordset
; - en fait, déclarez vos variables :)
Code révisé:
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
je suis assis devant un ordinateur sans aucune des parties pertinentes du logiciel, mais de mémoire ce code semble erroné. Vous exécutez la commande mais abandonnez le RecordSet
objMyCommand.Execute
retourne.
ce que je ferais:
Set objMyRecordset = objMyCommand.Execute
...et puis perdre la "ouvrir le jeu d'enregistrements".
Est une chaîne de connexion?
Où se trouve L'instance SQL Server?
vous devrez vérifier que vous êtes en mesure de conenct à SQL Server en utilisant la chaîne de connexion que vous avez spécifiée ci-dessus.
EDIT: regardez la propriété D'État du recordset pour voir si elle est ouverte?
De plus, changez la propriété CursorLocation en adUseClient avant d'ouvrir le recordset.
Ajouter set nocount on
au début du proc stocké (si vous êtes sur SQL Server). Je viens de résoudre ce problème dans mon propre travail et il a été causé par des résultats intermédiaires, tels que "1203 Rows Affected"
, d'être chargées dans le Recordset
j'ai essayé d'utiliser.
@fireddrawndagger: pour lister les noms de champ/en-têtes de colonne itérer à travers la collection de champs recordset et insérer le nom:
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