Ich versuche, ein Makro über Python auszuführen, aber ich bin mir nicht sicher, wie es funktioniert.
Ich habe den folgenden Code bis jetzt, aber es funktioniert nicht.
import win32com.client
xl=win32com.client.Dispatch("Excel.Application")
xl.Workbooks.Open(Filename="C:\test.xlsm",ReadOnly=1)
xl.Application.Run("macrohere")
xl.Workbooks(1).Close(SaveChanges=0)
xl.Application.Quit()
xl=0
Ich bekomme folgende Rückverfolgung:
Traceback (most recent call last):
File "C:\test.py", line 4, in <module>
xl.Application.Run("macrohere")
File "<COMObject <unknown>>", line 14, in Run
File "C:\Python27\lib\site-packages\win32com\client\dynamic.py", line 282, in _ApplyTypes_
result = self._oleobj_.InvokeTypes(*(dispid, LCID, wFlags, retType, argTypes) + args)
com_error: (-2147352567, 'Exception occurred.', (0, u'Microsoft Excel', u"Cannot run the macro 'macrohere'. The macro may not be available in this workbook or all macros may be disabled.", u'xlmain11.chm', 0, -2146827284), None)
import win32com.client
xl=win32com.client.Dispatch("Excel.Application")
xl.Workbooks.Open(Filename="C:\test.xlsm",ReadOnly=1)
try:
xl.Application.Run("test.xlsm!testmacro.testmacro")
# It does run like this... but we get the following error:
# Traceback (most recent call last):
# File "C:\test.py", line 7, in <module>
# xl.Workbooks(1).Close(SaveChanges=0)
# File "C:\Python27\lib\site-packages\win32com\client\dynamic.py", line 192, in __call__
# return self._get_good_object_(self._oleobj_.Invoke(*allArgs),self._olerepr_.defaultDispatchName,None)
# com_error: (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2147352565), None)
except:
# Except isn't catching the above error... :(
xl.Workbooks(1).Close(SaveChanges=0)
xl.Application.Quit()
xl=0
Ich würde erwarten, dass der Fehler mit dem Makro zusammenhängt, das Sie aufrufen.
import os, os.path
import win32com.client
if os.path.exists("excelsheet.xlsm"):
xl=win32com.client.Dispatch("Excel.Application")
xl.Workbooks.Open(os.path.abspath("excelsheet.xlsm"), ReadOnly=1)
xl.Application.Run("excelsheet.xlsm!modulename.macroname")
## xl.Application.Save() # if you want to save then uncomment this line and change delete the ", ReadOnly=1" part from the open function.
xl.Application.Quit() # Comment this out if your Excel script closes
del xl
Ich habe den Code von SMNALLY geändert, damit er in Python 3.5.2 ausgeführt werden kann. Das ist mein Ergebnis:
#Import the following library to make use of the DispatchEx to run the macro
import win32com.client as wincl
def runMacro():
if os.path.exists("C:\\Users\\Dev\\Desktop\\Development\\completed_apps\\My_Macr_Generates_Data.xlsm"):
# DispatchEx is required in the newest versions of Python.
Excel_macro = wincl.DispatchEx("Excel.application")
Excel_path = os.path.expanduser("C:\\Users\\Dev\\Desktop\\Development\\completed_apps\\My_Macr_Generates_Data.xlsm")
workbook = Excel_macro.Workbooks.Open(Filename = Excel_path, ReadOnly =1)
Excel_macro.Application.Run\
("ThisWorkbook.Template2G")
#Save the results in case you have generated data
workbook.Save()
Excel_macro.Application.Quit()
del Excel_macro
Ich vermute, Sie haben Ihre Excel-Installation nicht zur Ausführung eines Makros aus einem automatisierten Excel autorisiert. Bei der Installation ist dies standardmäßig ein Sicherheitsschutz. Um dies zu ändern:
Für Python 3.7 oder später (2018-10-10) muss ich die Antwort von @Alejandro BR und SMNALLY kombinieren, da @Alejandro vergessen, Wincl zu definieren.
import os, os.path
import win32com.client
if os.path.exists('C:/Users/jz/Desktop/test.xlsm'):
Excel_macro = win32com.client.DispatchEx("Excel.Application") # DispatchEx is required in the newest versions of Python.
Excel_path = os.path.expanduser('C:/Users/jz/Desktop/test.xlsm')
workbook = Excel_macro.Workbooks.Open(Filename = Excel_path, ReadOnly =1)
Excel_macro.Application.Run("test.xlsm!Module1.Macro1") # update Module1 with your module, Macro1 with your macro
workbook.Save()
Excel_macro.Application.Quit()
del Excel_macro
Eine Variante des Codes von SMNALLY, die Excel nicht beendet, wenn Sie es bereits geöffnet haben:
import os, os.path
import win32com.client
if os.path.exists("excelsheet.xlsm"):
xl=win32com.client.Dispatch("Excel.Application")
wb = xl.Workbooks.Open(os.path.abspath("excelsheet.xlsm"), ReadOnly=1) #create a workbook object
xl.Application.Run("excelsheet.xlsm!modulename.macroname")
wb.Close(False) #close the work sheet object rather than quitting Excel
del wb
del xl
Ich habe die win32com way und xlwings way ausprobiert, aber ich hatte kein Glück. Ich verwende PyCharm und habe die .WorkBook-Option in der automatischen Vervollständigung für win32com nicht gesehen. Ich erhielt die Fehlermeldung -2147352567, als ich versuchte, eine Arbeitsmappe als Variable zu übergeben.
Dann fand ich eine Arbeit, in der vba Shell verwendet wurde, um mein Python-Skript auszuführen. Schreiben Sie etwas in die XLS-Datei, mit der Sie arbeiten, wenn alles fertig ist. Damit weiß Excel, dass es Zeit ist, das VBA-Makro auszuführen.
Die vba Application.wait-Funktion nimmt jedoch 100% CPU auf, was seltsam ist. Einige Leute sagten, dass die Windows-Sleep-Funktion das Problem beheben würde.
Import xlsxwriter
Shell "C:\xxxxx\python.exe
C:/Users/xxxxx/pythonscript.py"
exitLoop = 0
warten Sie, bis Python seine Arbeit beendet hat.
Do
waitTime = TimeSerial(Hour(Now), Minute(Now), Second(Now) + 30)
Application.Wait waitTime
Set wb2 = Workbooks.Open("D:\xxxxx.xlsx", ReadOnly:=True)
exitLoop = wb2.Worksheets("blablabla").Cells(50, 1)
wb2.Close exitLoop
Loop While exitLoop <> 1
Call VbaScript
Nur eine kurze Notiz mit einem xlsm mit Leerzeichen.
file = 'file with spaces.xlsm'
Excel_macro.Application.Run('\'' + file + '\'' + "!Module1.Macro1")