2009-03-26 14 views
5

Próbuję utworzyć QueryTable w arkuszu kalkulacyjnym Excel przy użyciu Python comtypes bibliotekę, ale coraz raczej uninformative błąd ...Problem przy użyciu biblioteki Pythona comtypes dodać QueryTable do Excela

w VBA (w sposób moduł w skoroszycie), następujący kod działa poprawnie:

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 

Ale następujący kod Python:

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() 

rzuca pomocny komunikat o błędzie:

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)) 

Jakieś pomysły na to, co się tutaj dzieje?

Dzięki!

+0

Eli, dodatkową przestrzeń usunięto było dokonać rzeczy pojawiają się poprawne na podglądzie. Jestem teraz ciekawy: utknąłem, ale polityka korporacyjna używa IE6, która wymaga przestrzeni, aby wyglądać dobrze - czy bez niej wyglądała ona w innych przeglądarkach? – mavnn

+0

Wciąż wygląda mi dobrze w Firefoksie 3.0.7 – tgray

+0

Możesz również dodać tag Visual Basic lub VBA do pytania ... – tgray

Odpowiedz

2

I uprościć swój kod i to powinno działać dobrze (wytłumaczę poniżej zmianami):

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() 

Funkcja QueryTables.Add() można utworzyć połączenia i obiekty Recordset dla Ciebie, dzięki czemu upraszcza wiele rzeczy ... wystarczy dodać, jaki typ połączenia znajduje się w łańcuchu połączenia (część "OLEDB").

Letting Excel zrobić większość pracy wydaje się rozwiązać problemu :)

+0

Idealnie! Próbowałem (constring, range, sql) wersji, ale brakowało mi tego, że potrzebowałem OLEDB dodanego do początku ściągacza. Ciągle ciekawi, dlaczego oryginał nie zadziałał, ale takie jest życie. Punkt bonusowy dla .Refresh() na tej samej linii - bardzo Python ... – mavnn

1

To wygląda twój błąd na tej linii:

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

Myślę, że problemem jest to, że używasz składni Pythona patrzeć wartość w zbiorze VBA. Spróbuj zmienić nawiasy kwadratowe na nawiasy.

tj

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

Wynika to z faktu, że w VBA podczas wywoływania Collection takiego, Range("A1"), jesteś rzeczywiście nazywając to domyślna metoda, Range.Item("A1"). Zasadniczo kolekcje VBA nie tłumaczą się na słowniki python.

Otrzymuję to z tego forum thread i moje doświadczenie z VBA.


Edit powodu komentarz:

Niestety, próbowałem zarówno: jako zauważyć w linku, czasami nie zrobić to samo, ale mój gut uczucie tutaj jest to, że "[" jest bardziej prawdopodobnie jest tym, czego chcę. - mavnn

Wiesz jeśli comtypes.client.CreateObject działa tak samo jak win32com.client.Dispatch? Możesz spróbować utworzyć obiekt com z pakietem win32com i sprawdzić, czy to robi różnicę.

+0

Niestety, próbowałem obu: jak wspomniano w twoim linku, czasami Nie robię tego samego, ale mam przeczucie, że "[" jest bardziej prawdopodobne, że tego chcę. – mavnn

+0

Chciałbym. Niestety, nie mam uprawnień administratora na danym komputerze i nie mogę zainstalować pakietu win32com. Tak, tak, wiem: jeśli ufasz komuś wystarczająco, by dać im dostęp do Pythona i jego standardowych bibliotek, które nie mają większego sensu, ale takie jest życie ... – mavnn

Powiązane problemy