مشكلة في استخدام مكتبة Python comtypes لإضافة جدول استعلام إلى Excel
سؤال
أحاول إنشاء QueryTable في جدول بيانات Excel باستخدام مكتبة Python comtypes، لكني أتلقى خطأً غير مفيد إلى حدٍ ما...
في vba (في وحدة نمطية داخل المصنف)، تعمل التعليمات البرمجية التالية بشكل جيد:
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
لكن كود بايثون التالي:
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))
أي أفكار حول ما يحدث هنا؟
شكرًا!
المحلول
وأنا تبسيط التعليمات البرمجية وهذا ينبغي أن تعمل بشكل جيد (ساوضح التغييرات أدناه):
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 () يمكن إنشاء اتصال والسجلات الكائنات بالنسبة لك، بحيث يبسط الكثير من الأشياء ... تحتاج فقط إلى إضافة نوع الاتصال هو عليه في سلسلة conneciton (و"OLEDB" جزء).
والسماح إكسل تفعل أكثر من العمل يبدو في حل مشكلتك:)
نصائح أخرى
يبدو أن خطأك موجود في هذا السطر:
qt = ws.QueryTables.Add(rs, ws.Range["A1"])
أعتقد أن مشكلتك تكمن في أنك تستخدم بناء جملة بايثون للبحث عن قيمة في مجموعة VBA.حاول تغيير الأقواس المربعة إلى أقواس.
أي.
qt = ws.QueryTables.Add(rs, ws.Range("A1"))
والسبب هو أنه في VBA عندما تقوم باستدعاء مجموعة مثل هذا، Range("A1")
, ، أنت في الواقع تتصل بالطريقة الافتراضية، Range.Item("A1")
.في الأساس، مجموعات VBA لا تترجم إلى قواميس بايثون.
أنا أحصل على هذا من هذا موضوع المنتدى, وتجربتي مع VBA.
تعديل بسبب التعليق:
للأسف قمت بتجربة كلا من:كما هو مذكور في رابطك ، فإنهم في بعض الأحيان لا يفعلون نفس الشيء ، لكن شعوري الأمعاء هنا هو أن [" من المرجح أن يكون ما أريد.– مافن
هل تعلم لو comtypes.client.CreateObject
يعمل نفس win32com.client.Dispatch
؟يمكنك محاولة إنشاء كائن com الخاص بك باستخدام حزمة win32com ومعرفة ما إذا كان ذلك سيحدث فرقًا.