prosource

Python을 통해 Excel 매크로를 실행하시겠습니까?

probook 2023. 4. 28. 21:07
반응형

Python을 통해 Excel 매크로를 실행하시겠습니까?

파이썬을 통해 매크로를 실행하려고 하는데 어떻게 작동하는지 잘 모르겠어요...

지금까지 다음 코드를 받았는데 작동이 안 됩니다.

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

다음 추적을 다시 받습니다.

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

호출 중인 매크로와 관련된 오류일 것으로 예상됩니다. 다음 코드를 사용해 보십시오.

코드

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

SMNALY의 코드를 Python 3.5.2에서 실행할 수 있도록 수정했습니다.제 결과는 다음과 같습니다.

    #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

공백이 있는 xlsm이 있는 간단한 메모입니다.

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

자동화된 Excel에서 매크로를 실행하도록 Excel 설치를 승인하지 않은 것 같습니다.설치 시 기본적으로 보안 보호 기능입니다.변경 방법:

  1. 파일 > 옵션 > 신뢰센터
  2. 신뢰 센터 설정...을 클릭합니다.단추를 채우다
  3. 매크로 설정 > 모든 매크로 활성화 선택

흠, 그 부분에 문제가 좀 있었습니다(네, 여전히 xD):

xl.Application.Run("excelsheet.xlsm!macroname.macroname")

왜냐하면 나는 엑셀을 자주 사용하지 않기 때문입니다(vb나 매크로와 동일하지만 python과 함께 페맵을 사용하려면 필요합니다). 그래서 나는 마침내 매크로 목록을 확인하는 것을 해결했습니다.개발자 -> 매크로: 저는 그것을 보았습니다: 이것.macroname.macroname그래야 한다sheet_name.macroname"마크로스" 목록에 있는 것.

(나는 그것을 해결하기 위해 30분-1시간 정도를 소비하기 때문에 엑셀에서 나와 같은 초보자에게 도움이 될 수 있습니다) xD.

이미 열려 있는 경우 Excel을 종료하지 않는 SMNALY 코드의 변형:

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

저는 win32com way와 xlwings way를 시도해봤지만 운이 없었습니다.저는 PyCharm을 사용하고 그것을 보지 못했습니다.win32com용 자동 완성의 WorkBook 옵션.워크북을 변수로 전달하려고 했을 때 -2147352567 오류가 발생했습니다.

그런 다음 vba 셸을 사용하여 파이썬 스크립트를 실행하는 방법을 찾았습니다.모든 작업이 완료되면 작업 중인 XLS 파일에 무언가를 기록합니다.Excel이 VBA 매크로를 실행할 시간임을 알 수 있도록 합니다.

하지만 vba 애플리케이션.wait 함수는 더 이상한 100% CPU를 차지합니다.어떤 사람들은 윈도우 슬립 기능을 사용하면 해결될 것이라고 말했습니다.

 Import xlsxwriter


 Shell "C:\xxxxx\python.exe 
 C:/Users/xxxxx/pythonscript.py"

 exitLoop = 0

Python이 작업을 마칠 때까지 기다립니다.

  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

Windows 22H2 Build 22621.1194 64비트를 사용하고 있습니다.

파이썬 3.11.2

Microsoft 365 MSO용 Microsoft® Excel®(버전 2302 빌드 16.0.16130.20186) 64비트

나는 필요했습니다.python -m pip install pywin32win32com.client용

파이썬 코드

import time
import win32com.client
xl=win32com.client.Dispatch("Excel.Application")
xl.Workbooks.Open(Filename=r"C:\Users\david\Desktop\xl_HW.xlsm",ReadOnly=1)
xl.Application.Run("sbHelloWorld")
xl.Workbooks(1).Close(SaveChanges=0)
xl.Application.Quit()
xl=0
time.sleep(10)

서브루틴이 선언되었기 때문에 모듈 이름이 필요하지 않았습니다.Public

그리고 VBA의 일상은 -입니다.

Public Sub sbHelloWorld()
    MsgBox "Hello World"
End Sub

Python 3.7 이상(2018-10-10)의 경우, 저는 @Alejandro BR과 SMNALY의 답변을 결합해야 합니다. 왜냐하면 @Alejandro는 wincl을 정의하는 것을 잊었기 때문입니다.

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

언급URL : https://stackoverflow.com/questions/19616205/running-an-excel-macro-via-python

반응형