前提・実現したいこと
Pythonを使用してVBAを操作したいです。
VBAにて.xmlファイルを編集し、.xlsxファイル形式で別のフォルダに保存するというマクロを作成しました。
これをPythonから実行したいので
まず、Tkinterで作成したGUIで親フォルダをユーザーに指定させ、
それを元に.xmlファイルのフルパス、新しく保存する.xlsxファイルのフルパスを作成し、
VBAに引数として渡して実行という流れを考えました。
マクロが入ったExcelファイルはカレントディレクトリに保存しています。
発生している問題・エラーメッセージ
親フォルダを文字列で指定した場合は問題なく動くのですが、
Tkinterで親フォルダのパスを取得するとVBA側でエラーが出てしまいます。
どうにか解決できないでしょうか。
実行時エラー'1004': ファイル'C://Users/username/Desktop/After/(文字列)にアクセスできません。 次のいずれかの理由が考えられます。 ・ファイル名またはパスが存在しません ・ファイルがほかのプログラムによって使用されています ・保存しようとしているブックと同じ名前のブックが現在開かれています
エラーメッセージではファイル名が英字+数字の文字列になっていますが、
ローカルの値は正しいファイル名になっています。
該当のソースコード
Python
1import os 2from tkinter import * 3from tkinter import ttk 4from tkinter import filedialog 5import xlwings as xw 6 7 8def dirdialog_clicked(): #フォルダ取得用 9 iDir = os.path.abspath(os.path.dirname(__file__)) 10 iDirPath = filedialog.askdirectory(initialdir = iDir) 11 entry.set(iDirPath) 12 13def conductMain(): 14 folder_list = ["Book1","Book2","Book3"] 15 wb = xw.Book(os.getcwd() + os.sep + "Excel_edit.xlsm") 16 macro = wb.macro("edit") 17 for file in folder_list: 18 oldpath = entry.get() + os.sep + "Before" + os.sep + file + ".xml" 19 newpath = entry.get() + os.sep + "After" + os.sep + file + ".xlsx" 20 if os.path.exists(newpath) or not os.path.exists(oldpath): 21 continue 22 macro(oldpath, newpath) 23 wb.app.kill() 24 25 26if __name__ == "__main__": 27 28 # rootの作成 29 root = Tk() 30 root.title("CFU assay copy&rename") 31 32 # Frame1の作成 33 frame1 = ttk.Frame(root, padding=10) 34 frame1.grid(row=0, column=1, sticky=E) 35 36 # 「フォルダ参照」ラベルの作成 37 IDirLabel = ttk.Label(frame1, text="画像フォルダ", padding=(5, 2)) 38 IDirLabel.pack(side=LEFT) 39 40 # 「フォルダ参照」エントリーの作成 41 entry = StringVar() 42 IDirEntry = ttk.Entry(frame1, textvariable=entry, width=30) 43 IDirEntry.pack(side=LEFT) 44 45 # 「フォルダ参照」ボタンの作成 46 IDirButton = ttk.Button(frame1, text="参照", command=dirdialog_clicked) 47 IDirButton.pack(side=LEFT) 48 49 # Frame2の作成 50 frame2 = ttk.Frame(root, padding=10) 51 frame2.grid(row=8,column=1,sticky=E ) 52 53 # 実行ボタンの設置 54 button1 = ttk.Button(frame2, text="実行", command=conductMain) 55 button1.pack(fill = "x", padx=30, side = "left") 56 57 # キャンセルボタンの設置 58 button2 = ttk.Button(frame2, text=("閉じる"), command= root.destroy) 59 button2.pack(fill = "x", padx=30, side = "left") 60 61 root.mainloop()
VBA
1Sub edit(oldpath As String, newpath As String) 2 3 Workbooks.Open oldpath 4 5 '本来はここでセルの値を編集しています 6 7 ActiveWorkbook.SaveAs Filename:=newpath, FileFormat:=xlWorkbookDefault 8 ActiveWorkbook.Close 9 10End Sub
試したこと
Tkinterを使用せずに、指定したいフォルダのフルパスを直接記述した場合は問題なく動きました。
Python
1import os 2import xlwings as xw 3 4mainfolder = r"C:\Users\usename\Desktop\mainfolder" 5folder_list = ["Book1","Book2","Book3"] 6wb = xw.Book(os.getcwd() + os.sep + "Excel_edit.xlsm") 7macro = wb.macro("edit") 8for file in folder_list: 9 oldpath = mainfolder + os.sep + os.sep + "Before" + os.sep + file + ".xml" 10 newpath = mainfolder + os.sep + os.sep + "After" + os.sep + file + ".xlsx" 11 if os.path.exists(newpath) or not os.path.exists(oldpath): 12 continue 13 macro(oldpath, newpath) 14wb.app.kill()
該当ソースコード内のconductMain()をこのように書き換えた場合はエラーが発生しませんでしたが、
Python
1def conductMain(): 2 mainfolder = r"C:\Users\usename\Desktop\mainfolder" 3 folder_list = ["Book1","Book2","Book3"] 4 wb = xw.Book(os.getcwd() + os.sep + "Excel_edit.xlsm") 5 macro = wb.macro("edit") 6 for file in folder_list: 7 oldpath = entry.get() + os.sep + "Before" + os.sep + file + ".xml" #書き換え個所 8 newpath = mainfolder + os.sep + "After" + os.sep + file + ".xlsx" #書き換え個所 9 if os.path.exists(newpath) or not os.path.exists(oldpath): 10 continue 11 macro(oldpath, newpath) 12 wb.app.kill()
このように書き換えるとエラーが発生しましたので、
Excelファイルの保存先にTkinterを用いて取得したパスが含まれているのが原因の可能性が高いと思われます。
Python
1def conductMain(): 2 mainfolder = r"C:\Users\usename\Desktop\mainfolder" 3 folder_list = ["Book1","Book2","Book3"] 4 wb = xw.Book(os.getcwd() + os.sep + "Excel_edit.xlsm") 5 macro = wb.macro("edit") 6 for file in folder_list: 7 oldpath = mainfolder + os.sep + "Before" + os.sep + file + ".xml" #書き換え個所 8 newpath = entry.get() + os.sep + "After" + os.sep + file + ".xlsx" #書き換え個所 9 if os.path.exists(newpath) or not os.path.exists(oldpath): 10 continue 11 macro(oldpath, newpath) 12 wb.app.kill()
補足情報(FW/ツールのバージョンなど)
Windows10(64bit)
python 3.9.5
xlwings 0.24.5
エディタ:Visual Code Studio
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/08/03 07:55