質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

3041閲覧

PYTHON(xlwings)でエクセルマクロ実行中(ループ処理)に中断するもしくは別の処理をしたい

sena1173

総合スコア4

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2021/02/28 08:17

編集2021/03/01 07:34

PYTHON ライブラリxlwing でエクセルマクロ実行中(do loopにて10分おきにループ処理)に中断もしくは強制終了もしくは別の処理をしたい

xlwings.App 簡易リファレンスやググったり、自分がわかる範疇で試したり、win32comでも少しでも手掛かりになりそうなものを検索しましたが
情報が見つかりませんでした。

app.kill() # アプリ実行環境を強制終了させる
app.quit() # アプリ実行環境を終了させる

上記で行けるかなと思いましたが、VBA側がループしているため、ループが終了するまで割り込むことができません。

windows10 最新
Python 3.9.1
Excel2010

#プログラム1|ライブラリの設定 import xlwings as xw #プログラム2|対象エクセルのファイルパスを指定 filename = 'テストプログラム.xlsm' #プログラム3|マクロVBAを呼び出して実行 App = xw.App() wb = App.books.open(filename) macro=wb.macro('test') macro() # ↑でエクセルのループ処理に移行するため 中断させることができたり、別の処理をしたい #プログラム4|エクセルファイルを保存 wb.save(filename) #プログラム5|エクセルファイルを閉じる wb.close() App.quit()

以上、よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sena1173

2021/03/01 07:35

追記しました。
sena1173

2021/03/01 07:36

xlwings.App 簡易リファレンスやググったり、自分がわかる範疇で試したり、win32comでも少しでも手掛かりになりそうなものを検索しましたが 情報が見つかりませんでした。 app.kill() # アプリ実行環境を強制終了させる app.quit() # アプリ実行環境を終了させる 上記で行けるかなと思いましたが、VBA側がループしているため、ループが終了するまで割り込むことができません。
guest

回答1

0

ベストアンサー

エクセルマクロ実行中にpython上別処理をおこなう場合、下記のようになるでしょうか。
別スレッドでマクロを実行させています。

#ライブラリの設定 import xlwings as xw from xlwings.main import App as XlwingsApp from concurrent.futures import ThreadPoolExecutor import time #指定したファイルパスのマクロの実行を指定 def run_macro(filename, macroname): print("マクロブック[{}]を開いてマクロ[{}]を実行します。".format(filename, macroname)) try: macro = xw.Book(filename).macro(macroname) macro() # セーブはエクセル側でコントロールすべきだと思うが、あえてpython側でセーブしたいなら下記コメントを外すこと。 # xw.Book(filename).save() return xw.Book(filename).app except Exception as e: print(e) return xw.Book(filename).app # run_macro終了時に戻ってくる関数。 # add_done_callbackよりも前に定義すること。 def quit(res): app = res.result() if isinstance(app, XlwingsApp): app.quit() print("マクロブックを閉じました。") else: print("xlwingオブジェクトを正常に受け取れませんでした。") # マクロブックのファイルパス filename = 'テストプログラム.xlsm' # マクロ名 macroname = 'test' # 別スレッドで実行させるためのオブジェクト executor = ThreadPoolExecutor() # ThreadPoolExecutorに実行させたい関数を引数と一緒に渡す。 task = executor.submit(run_macro, filename, macroname) task.add_done_callback(quit) # マクロの実行中に行う別処理。 # 下の例では単純に1秒ごとにカウントアップしている。 for i in range(10): print(i) time.sleep(1) # すべてのプログラム終了時に下記実行してThreadPoolExeccutorを終了させる executor.shutdown()

エクセルで走っているマクロを外部から中断もしくは終了させるというのは、難しいと思います。
マクロ側で工夫するとか(たとえばマクロ側で定期的にファイルを読み取り、そのファイルに終了コマンドが書かれていたら終了するようにする。pythonからはそのファイルに終了コマンドを書き込む→ただし、ファイルのロックとかの問題が生じそう)

投稿2021/03/02 01:19

編集2021/03/02 01:27
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sena1173

2021/03/02 02:15

python初心者のため、丸投げに近い質問に対してご回答有難うございます。 xlwings特有のVBAからpythonを操作する以下で試していました。 Call RunPython("import マクロ複数実行; マクロ複数実行.別処理()") かなり強引なやり方ですが、なんとなく感触がありましたがqnoirさんの 処理が分かり易くスマートで色々と応用が利きそうだと思いました。 # 別スレッドで実行させるためのオブジェクト という処理の存在と今回のような私の変な要望に適していると理解 することができました。非常に勉強になりました。今後も精進して いこうと思います。 この度は、有難うございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問