2009-03-26 3 views
5

Я пытаюсь создать QueryTable в таблицу Excel с помощью Питон comtypes библиотеки, но получить довольно неинформативное ошибку ...Проблема с использованием библиотеки Python comtypes добавить QueryTable в Excel

В УВА (в модуль в рабочей книге), следующий код работает отлично:

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 

Но следующий код 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() 

Выдает сообщение об ошибке бесполезного:

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

Любые идеи о том, что здесь происходит?

Спасибо!

+0

Эли, дополнительное пространство вы удалили там, чтобы сделать вещи появляются правильно на предварительном просмотре. Мне сейчас любопытно: я застрял, но корпоративная политика, использующая IE6, которая требует, чтобы пространство выглядело правильно - разве это выглядело прямо на других браузерах без него? – mavnn

+0

Он по-прежнему выглядит хорошо для меня в Firefox 3.0.7 – tgray

+0

Вы также можете добавить тег Visual Basic или VBA к вопросу ... – tgray

ответ

2

Я упростил свой код, и это должно работать нормально (я объясню ниже изменений):

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

Функция QueryTables.Add() может создать соединение и объекты Recordset для вас, так что упрощает много вещей ... вам просто нужно добавить, какое соединение оно находится в строке conneciton (часть «OLEDB»).

Позволить Excel сделать большую часть работы, кажется, чтобы решить вашу проблему :)

+0

Perfect! Я попробовал версию (constring, range, sql), но пропустил тот факт, что мне понадобился OLEDB, добавленный в начало constring. Все еще любопытно, почему оригинал не работал, но такова жизнь. Бонусная точка для .Refresh() на той же линии - очень Pythonic ... – mavnn

1

Похоже, ваша ошибка в этой строке:

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

Я думаю, ваша проблема в том, что вы используете синтаксис питона для поиска значения в VBA коллекции. Попробуйте скопировать квадратные скобки в скобки.

т.е.

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

Причина в том, что в VBA, когда вы вызываете коллекции, как это, Range("A1"), вы на самом деле вызывая это по умолчанию метод, Range.Item("A1"). В принципе, VBA Collections не переводят на словари python.

Я получаю это от этого forum thread, и мой опыт работы с VBA.


Редактировать из-за комментарий:

К сожалению, я пытался как: а отметил в вашей ссылке, они иногда не делать то же самое, но моя кишка чувство здесь что «[» больше , вероятно, будет тем, что я хочу. - mavnn

Вы знаете, если comtypes.client.CreateObject работает так же, как win32com.client.Dispatch? Вы можете попытаться создать свой com-объект с пакетом win32com и посмотреть, не изменилось ли это.

+0

К сожалению, я пробовал оба: как отмечено в вашей ссылке, они иногда находят Не делайте то же самое, но мое чувство кишки здесь состоит в том, что «[», скорее всего, будет тем, что я хочу. – mavnn

+0

Хотелось бы полюбить. К сожалению, у меня нет прав администратора на рассматриваемой машине, поэтому я не могу установить пакет win32com. Да, я знаю: если вы доверяете кому-то достаточно, чтобы дать им доступ к Python, и это стандартные библиотеки, которые не имеют большого смысла, но это жизнь ... – mavnn

Смежные вопросы