2013-06-19 12 views
12

既存のスプレッドシートを使用したいマクロがあります。唯一の問題は、非常に多くのスプレッドシートがあり、手作業でそれを行うには時間がかかりすぎるということです!Pythonを使用してマクロをスプレッドシートに挿入する

私はpyWin32を使用して必要なファイルにアクセスするためのPythonスクリプトを書きましたが、私はマクロを追加するためにそれを使用する方法を見つけ出すように見えることはできません。

ここに同様の質問はこの答えを与えました(これは、Pythonではないのですが、それはまだCOMを使用するように見えます)が、私のCOMオブジェクトは、VBProjectメンバーと呼ばれているように見えるしません:Inject and execute Excel VBA code into spreadsheet received from external source

:同様の質問参照へのリンク:

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 

EDITを

私はまた、 Pythonではないので、同様のオブジェクトメンバーがCOMオブジェクトを通じて私に利用可能になることを期待していました。

+0

"ここにも同様の質問がありましたが、「このリンクはここにはありませんか? –

+2

まず、あなたのサンプルコードはPythonでさえありません。私はそれがVisual Basicだと確信しています。 –

+1

私は私の質問を修正しました! –

答えて

7

これは変換されたコードです。 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() 
+0

助けてくれてありがとう!ちょうど徹底的にするには、 "Excelオプション" - > "トラストセンター"タブ - > "トラストセンター設定..." - > "マクロ設定"タブの "VBAプロジェクトオブジェクトモジュールへのアクセスを信頼する"このコードを実行することができます。 –

3

私もこの権利を取得するためにいくつかの時間を苦労したように、私は、Excel 2007の/ 2010/2013年のxlsm形式で動作するようになっている別の例を提供します。上記の例とあまり違いはありませんが、異なるファイルを繰り返したりコメントを追加したりしなければ、少し単純です。さらに、マクロのソースコードは、Pythonスクリプトでハードコーディングするのではなく、テキストファイルからロードされます。

必要に応じて、スクリプトの上部にあるファイルパスを覚えておいてください。

さらに、Excel 2007/2010/2013はxlsm形式のマクロを含むブックのみを格納でき、xlsxでは使用できないことに注意してください。 xlsxファイルにマクロを挿入すると、そのファイルを別の形式で保存するかどうかを確認するメッセージが表示されます。この場合、マクロはファイルに含まれません。

最後に、Excel以外のアプリケーションからVBAコードを実行するオプションが有効になっていることを確認します(セキュリティ上の理由からデフォルトで無効になります)。そうでない場合は、エラーメッセージが表示されます。 Excelを開き、Trust access to the VBA project object modelのチェックマークを有効にすると、Excelを開き、

ファイル - >オプション - >セキュリティセンター - >セキュリティセンター設定 - >マクロ設定 - >に移動します。

# 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' 

# necessary imports 
import os, sys 
import win32com.client 

# 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 
関連する問題