2009-03-26 8 views
5

Je suis en train de créer un QueryTable dans une feuille de calcul Excel à l'aide de la bibliothèque Python comtypes, mais obtenir une erreur plutôt uninformative ...problème en utilisant la bibliothèque de Python pour ajouter un QueryTable à Excel

En vba (dans un module dans le classeur), le code suivant fonctionne très bien:

Sub CreateQuery() 
    Dim con As ADODB.Connection 
    Dim rs As ADODB.Recordset 
    Dim ws As Worksheet 
    Dim qt As QueryTable 

    Set ws = ActiveWorkbook.Sheets(1) 

    Set con = New ADODB.Connection 
    con.Open ("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Path\to\Db.mdb;") 

    Set rs = New ADODB.Recordset 
    rs.Open "Select * from [tbl Base Data];", con 

    Set qt = ws.QueryTables.Add(rs, ws.Range("A1")) 
    qt.Refresh 
End Sub 

Mais le code Python suivant:

import sys 
import comtypes.client as client 

def create_querytable(): 
    constring = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Path\\to\\Db.mdb" 
    conn = client.CreateObject("ADODB.Connection", dynamic = True) 
    rs = client.CreateObject("ADODB.Recordset", dynamic = True) 

    SQL = "Select * from [tbl Base Data];" 

    conn.Open(constring) 
    rs.Open(SQL, conn) 
    excel = client.CreateObject("Excel.Application", dynamic = True) 
    excel.Visible = True 
    ws = excel.Workbooks.Add().Sheets(1) 
    qt = ws.QueryTables.Add(rs, ws.Range["A1"]) 
    qt.Refresh() 
    rs.Close() 
    conn.Close() 

Lance le message d'erreur inutile:

Traceback (most recent call last): 
    File "<pyshell#34>", line 1, in <module> 
    create_querytable() 
    File "C:/Documents and Settings/cvmne250/Desktop/temp.py", line 17, in create_querytable 
    qt = ws.QueryTables.Add(rs, ws.Range["A1"]) 
    File "G:\ISA\SPSS\comtypes\lib\comtypes\client\lazybind.py", line 160, in caller 
    File "G:\ISA\SPSS\comtypes\lib\comtypes\automation.py", line 628, in _invoke 
COMError: (-2147352567, 'Exception occurred.', (None, None, None, 0, None)) 

Toutes les idées sur ce qui se passe ici?

Merci!

+0

Eli, l'espace supplémentaire que vous avez retiré était là pour faire les choses semblent correctes sur l'aperçu. Je suis maintenant curieux: je suis coincé mais la politique de l'entreprise en utilisant IE6 qui nécessite l'espace pour regarder à droite - était-il regarder sur d'autres navigateurs sans elle? – mavnn

+0

Il me semble encore bien dans Firefox 3.0.7 – tgray

+0

Vous pouvez également ajouter un tag Visual Basic, ou VBA à la question ... – tgray

Répondre

2

I simplifié votre code et cela fonctionne bien (je vais vous expliquer les changements ci-dessous):

def create_querytable2(): 
    constring = "OLEDB;Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\path\to\db.mdb;" 
    SQL = "Select * from tblName;" 
    excel = client.CreateObject("Excel.Application", dynamic=True) 
    excel.Visible = True 
    ws = excel.Workbooks.Add().Worksheets(1) 
    ws.QueryTables.Add(constring, ws.Range["A1"], SQL).Refresh() 

La fonction QueryTables.Add() peut créer les objets Connection et Recordset pour vous, afin que Simplifie beaucoup de choses ... il suffit d'ajouter le type de connexion dans la chaîne de connexion (la partie "OLEDB").

Laisser Excel faire la plupart des travaux semble résoudre votre problème :)

+0

Parfait! J'avais essayé la version (constring, range, sql) mais j'avais manqué le fait que j'avais besoin de l'OLEDB ajoutée au début de la construction. Toujours curieux de savoir pourquoi l'original n'a pas fonctionné, mais telle est la vie. Point bonus pour .Refresh() sur la même ligne - très Pythonic ... – mavnn

1

Il semble que votre erreur est sur cette ligne:

qt = ws.QueryTables.Add(rs, ws.Range["A1"]) 

Je pense que votre problème est que vous utilisez la syntaxe de Python pour rechercher une valeur dans une collection VBA. Essayez de changer vos crochets entre parenthèses.

à savoir

qt = ws.QueryTables.Add(rs, ws.Range("A1")) 

La raison étant que dans VBA lorsque vous invoquez une collection comme ça, Range("A1"), vous appellent en fait c'est la méthode par défaut, Range.Item("A1"). Fondamentalement, les collections VBA ne sont pas traduites en dictionnaires python.

Je reçois ce à partir de ce forum thread, et mon expérience avec VBA.


Modifier en raison de commentaires:

Malheureusement, j'ai essayé à la fois: comme noté dans votre lien, ils parfois ne font pas la même chose, mais mon instinct sentiment ici est que le '[' est plus susceptible d'être ce que je veux. - mavnn

Savez-vous si comtypes.client.CreateObject fonctionne comme win32com.client.Dispatch? Vous pourriez essayer de créer votre objet com avec le paquet win32com et voir si cela fait une différence.

+0

Malheureusement, j'ai essayé les deux: comme indiqué dans votre lien, ils parfois don Ne fais pas la même chose, mais mon instinct ici est que le '[' est plus susceptible d'être ce que je veux. – mavnn

+0

Aimerait. Malheureusement, je n'ai pas les droits d'administrateur sur la machine en question et je ne peux donc pas installer le paquet win32com. Ouais, ouais, je sais: si vous faites assez confiance à quelqu'un pour leur donner accès à Python et que ses bibliothèques standard n'ont pas beaucoup de sens, mais telle est la vie ... – mavnn

Questions connexes