sourcetip

Python을 사용하여 스프레드시트에 매크로 삽입

fileupload 2023. 6. 7. 23:05
반응형

Python을 사용하여 스프레드시트에 매크로 삽입

여러 개의 기존 스프레드시트를 사용할 매크로가 있습니다.유일한 문제는 스프레드시트가 너무 많아서 손으로 직접 하기에는 시간이 너무 많이 걸린다는 것입니다!

파이윈32를 사용하여 필요한 파일에 액세스하기 위해 파이썬 스크립트를 작성했지만, 매크로를 추가하는 데 사용할 방법을 찾을 수 없는 것 같습니다.

여기서 비슷한 질문이 다음과 같은 대답을 했습니다(파이썬은 아니지만 여전히 COM을 사용하는 것처럼 보입니다). 하지만 제 COM 개체에는 VBProject라는 멤버가 없는 것 같습니다.

Set objExcel = CreateObject("Excel.Application") 
objExcel.Visible = True 
objExcel.DisplayAlerts = False 
Set  objWorkbook = objExcel.Workbooks.Open("C:\scripts\test.xls") 
   Set xlmodule = objworkbook.VBProject.VBComponents.Add(1)  
   strCode = _ 
   "sub test()" & vbCr & _ 
   "   msgbox ""Inside the macro"" " & vbCr & _ 
   "end sub" 
   xlmodule.CodeModule.AddFromString strCode 
objWorkbook.SaveAs "c:\scripts\test.xls" 
objExcel.Quit 

편집: 참조된 유사한 질문에 대한 링크Excel VBA 코드를 외부 소스로부터 수신한 스프레드시트에 주입 및 실행

Python은 아니지만 COM 객체를 통해 비슷한 객체 멤버를 사용할 수 있기를 바랍니다.

변환된 코드입니다.win32com 또는 comtypes 패키지를 사용할 수 있습니다.

import os
import sys

# Import System libraries
import glob
import random
import re

sys.coinit_flags = 0 # comtypes.COINIT_MULTITHREADED

# USE COMTYPES OR WIN32COM
#import comtypes
#from comtypes.client import CreateObject

# USE COMTYPES OR WIN32COM
import win32com
from win32com.client import Dispatch

scripts_dir = "C:\\scripts"
conv_scripts_dir = "C:\\converted_scripts"
strcode = \
'''
sub test()
   msgbox "Inside the macro"
end sub
'''

#com_instance = CreateObject("Excel.Application", dynamic = True) # USING COMTYPES
com_instance = Dispatch("Excel.Application") # USING WIN32COM
com_instance.Visible = True 
com_instance.DisplayAlerts = False 

for script_file in glob.glob(os.path.join(scripts_dir, "*.xls")):
    print "Processing: %s" % script_file
    (file_path, file_name) = os.path.split(script_file)
    objworkbook = com_instance.Workbooks.Open(script_file)
    xlmodule = objworkbook.VBProject.VBComponents.Add(1)
    xlmodule.CodeModule.AddFromString(strcode.strip())
    objworkbook.SaveAs(os.path.join(conv_scripts_dir, file_name))

com_instance.Quit()

저도 이 문제를 해결하기 위해 시간이 좀 걸렸기 때문에 Excel 2007/2010/2013의 예를 하나 더 들어보겠습니다.xlsm서식을 정하다위에 제공된 예제와 큰 차이가 없습니다. 서로 다른 파일을 반복하지 않고 더 많은 주석을 포함하지 않고 조금 더 단순합니다.게다가, 매크로의 소스 코드는 파이썬 스크립트에서 하드 코딩하는 대신 텍스트 파일에서 로드됩니다.

스크립트의 맨 위에 있는 파일 경로를 필요에 맞게 조정해야 합니다.

또한 Excel 2007/2010/2013은 매크로가 있는 워크북만 저장할 수 있습니다.xlsm형식, 형식이 아님xlsx매크로를 에 삽입할 때xlsx파일을 다른 형식으로 저장할지 묻는 메시지가 표시되거나 매크로가 파일에 포함되지 않습니다.

그리고 마지막으로, 애플리케이션 외부에서 VBA 코드를 실행하는 Excel의 옵션이 활성화되어 있는지(보안상의 이유로 기본적으로 비활성화되어 있는지) 확인하십시오. 그렇지 않으면 오류 메시지가 표시됩니다.Excel을 열고 다음으로 이동합니다.

파일 -> 옵션 -> 신뢰 센터 -> 신뢰 센터 설정 -> 매크로 설정 -> 체크 표시 활성화Trust access to the VBA project object model.

# necessary imports
import os, sys
import win32com.client


# get directory where the script is located
_file = os.path.abspath(sys.argv[0])
path = os.path.dirname(_file)

# set file paths and macro name accordingly - here we assume that the files are located in the same folder as the Python script
pathToExcelFile = path + '/myExcelFile.xlsm'
pathToMacro = path + '/myMacro.txt'
myMacroName = 'UsefulMacro'

# read the textfile holding the excel macro into a string
with open (pathToMacro, "r") as myfile:
    print('reading macro into string from: ' + str(myfile))
    macro=myfile.read()

# open up an instance of Excel with the win32com driver
excel = win32com.client.Dispatch("Excel.Application")

# do the operation in background without actually opening Excel
excel.Visible = False

# open the excel workbook from the specified file
workbook = excel.Workbooks.Open(Filename=pathToExcelFile)

# insert the macro-string into the excel file
excelModule = workbook.VBProject.VBComponents.Add(1)
excelModule.CodeModule.AddFromString(macro)

# run the macro
excel.Application.Run(myMacroName)

# save the workbook and close
excel.Workbooks(1).Close(SaveChanges=1)
excel.Application.Quit()

# garbage collection
del excel

@Dirk와 @dilbert가 언급한 것은 잘 작동합니다.프로그래밍 방식으로 'VBA 개체 모듈'에 액세스할 수 있도록 이 코드를 추가할 수도 있습니다.

import win32api
import win32con

key = win32api.RegOpenKeyEx(win32con.HKEY_CURRENT_USER,
                            "Software\\Microsoft\\Office\\16.0\\Excel"
                            + "\\Security", 0, win32con.KEY_ALL_ACCESS)
win32api.RegSetValueEx(key, "AccessVBOM", 0, win32con.REG_DWORD, 1)

여기에 추가하고 싶습니다.폴더에 있는 모든 .xlsm 파일을 구문 분석하는 데 문제가 있었습니다.glob과 for 문 안에 있는 문을 형식화하는 방법을 알아냈습니다.제가 프로그래밍에 익숙하지 않아서 잘못된 용어를 사용하고 있다면 양해 부탁드립니다.이것이 다른 사람들에게 도움이 되기를 바랍니다.감사해요.

import glob
import os, sys
import win32com.client


_file = os.path.abspath(sys.argv[0])
path = os.path.dirname(_file)
pathToMacro = path + r'\macro2.txt'
myMacroName = 'TestMacro'

for fname in glob.glob(path + "\*.xlsm"):
    with open (pathToMacro, "r") as myfile:
        print('reading macro into string from: ' + str(myfile))
        macro=myfile.read()
        excel = win32com.client.Dispatch("Excel.Application")
        excel.Visible = False
        workbook = excel.Workbooks.Open(Filename=fname)
        excelModule = workbook.VBProject.VBComponents.Add(1)
        excelModule.CodeModule.AddFromString(macro)
        excel.Application.Run('Module1.CleanDataPivot')
        excel.Workbooks(1).Close(SaveChanges=1)
        excel.Application.Quit()
        del excel

이제 Excel을 열지 않고도 폴더의 모든 .xlsm 파일에서 하나의 매크로를 실행할 수 있습니다.

언급URL : https://stackoverflow.com/questions/17197259/use-python-to-inject-macros-into-spreadsheets

반응형