webentwicklung-frage-antwort-db.com.de

Ein Excel-Makro über Python ausführen?

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)

BEARBEITEN

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
30
Ryflex

Ich würde erwarten, dass der Fehler mit dem Makro zusammenhängt, das Sie aufrufen.

Code

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
42
SMNALLY

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
3
Alejandro BR

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:

  1. Datei> Optionen> Vertrauensstellungscenter
  2. Klicken Sie auf die Schaltfläche Trust Center Settings ...
  3. Makro-Einstellungen> Aktivieren Sie Alle Makros aktivieren
2
Boud

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
0
PyBoss

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
0
Peter Mabbott

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
0
William Tong

Nur eine kurze Notiz mit einem xlsm mit Leerzeichen. 

file = 'file with spaces.xlsm'
Excel_macro.Application.Run('\'' + file + '\'' + "!Module1.Macro1")
0
coldbyte