2009-03-26 31 views
5

Tôi đang cố gắng để tạo ra một QueryTable trong một bảng tính excel bằng cách sử dụng Python comtypes thư viện, nhưng nhận được một lỗi khá uninformative ...Vấn đề sử dụng thư viện Python comtypes để thêm một querytable sang Excel

Trong VBA (trong một mô-đun trong workbook), đoạn mã sau hoạt động tốt:

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 

Nhưng mã Python sau:

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

ném được thông báo lỗi vô ích:

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

Mọi ý tưởng về những gì đang xảy ra ở đây?

Cảm ơn!

+0

Eli, khoảng trống thừa bạn đã có để làm cho mọi thứ xuất hiện chính xác trên bản xem trước. Bây giờ tôi tò mò: Tôi bị mắc kẹt nhưng chính sách của công ty sử dụng IE6 đòi hỏi không gian để nhìn đúng - nó có nhìn ngay trên các trình duyệt khác không có nó? – mavnn

+0

Nó vẫn ổn với tôi trong Firefox 3.0.7 – tgray

+0

Bạn cũng có thể muốn thêm thẻ Visual Basic hoặc VBA vào câu hỏi ... – tgray

Trả lời

2

tôi đơn giản hóa mã của bạn và điều này sẽ làm việc tốt (tôi sẽ giải thích những thay đổi dưới đây):

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

Các QueryTables.Add() chức năng có thể tạo ra các kết nối và Recordset đối tượng cho bạn, để đơn giản hoá rất nhiều thứ ... bạn chỉ cần thêm loại kết nối trong chuỗi conneciton (phần "OLEDB").

Cho phép Excel thực hiện hầu hết công việc có vẻ như để giải quyết vấn đề của bạn :)

+0

Hoàn hảo! Tôi đã thử phiên bản (constring, range, sql) nhưng đã bỏ lỡ một thực tế rằng tôi cần OLEDB thêm vào đầu của chuỗi. Vẫn tò mò là tại sao bản gốc không hoạt động, nhưng đó là cuộc sống. Điểm thưởng cho .Refresh() trên cùng một dòng - rất Pythonic ... – mavnn

1

Dường như lỗi của bạn nằm trên dòng này:

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

Tôi nghĩ vấn đề của bạn là bạn đang sử dụng cú pháp python để tìm kiếm một giá trị trong một Bộ sưu tập VBA. Thử thay đổi dấu ngoặc vuông thành dấu ngoặc đơn.

ví dụ:

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

Lý do được rằng trong VBA khi bạn gọi một Bộ sưu tập như thế này, Range("A1"), bạn đang thực sự kêu gọi đó là phương pháp mặc định, Range.Item("A1"). Về cơ bản, Bộ sưu tập VBA không dịch sang từ điển python.

Tôi nhận được thông tin này từ số forum thread và trải nghiệm của tôi với VBA.


Sửa do bình luận:

Thật không may, tôi đã thử cả: như lưu ý trong liên kết của bạn, đôi khi họ không làm điều tương tự, nhưng tôi cảm giác ruột đây là '[' là nhiều hơn có thể là những gì tôi muốn. - mavnn

Bạn có biết nếu comtypes.client.CreateObject hoạt động giống như win32com.client.Dispatch? Bạn có thể thử tạo đối tượng com của mình bằng gói win32com và xem điều đó có tạo nên sự khác biệt hay không.

+0

Thật không may, tôi đã thử cả hai: như đã lưu ý trong liên kết của bạn, đôi khi họ không 't làm điều tương tự, nhưng cảm giác ruột của tôi ở đây là' ['là nhiều khả năng là những gì tôi muốn. – mavnn

+0

Rất muốn. Thật không may, tôi không có quyền quản trị trên máy được đề cập và do đó không thể cài đặt gói win32com. Vâng, vâng, tôi biết: nếu bạn tin tưởng ai đó đủ để cung cấp cho họ quyền truy cập vào Python và thư viện chuẩn của nó không có ý nghĩa nhiều, nhưng đó là cuộc sống ... – mavnn

Các vấn đề liên quan