私は、エクセルブックでモデラーが直接消費する必要がある出力を生成するシミュレーションをPythonで実行しています。エクセルのスプレッドシートテンプレートに自分のデータを直接出力するコードを生成しました。データをテンプレートに直接出力するために生成したコードは問題ありませんが、私が実行している問題は、モデラーに一連のブックが「リンク」されていることです。データをスプレッドシートに挿入すると、ユーザーが物理的にブックを開いて「リンクの編集」→「値の更新」を行わない限り、そのブックへのリンクは更新されません。 1つのブックがある場合、ユーザーは問題なくブックを開くことができます。実際には、リンクが更新される必要がある100以上のブックがあります。残念ながら、ワークブックをリンクする際のモデラーのアプローチを変更するために私ができることは何もありません。私ができるのは、そのアプローチに対応することだけです。更新リンクのためのPythonを使用してExcel
私の目標は、1)シミュレートされたデータの生成、2)生成されたデータのモデラーのワークブックへの挿入、3)ワークブック間のすべてのリンクの更新を可能にするPythonソリューションを作成することです。最終的には、合理化するために、私は3つのエンドツーエンドのPythonプログラムで3つすべてを実行できるようにしたいと考えています。私は(1)と(2)を解決しました。(3)の解決法はほとんどあります。私は、以下の機能のスクリプトを生成しています
from win32com.client import Dispatch
import pandas as pd
from openpyxl import load_workbook
import os
import time
def run_macro(workbook_name, vba_sub, com_instance):
wb = com_instance.workbooks.open(workbook_name)
wb.RefreshAll()
xl_module = wb.VBProject.VBComponents.Add(1)
xl_module.CodeModule.AddFromString(vba_sub.strip())
com_instance.Application.Run('UpdateLinkValues')
wb.Save()
wb.Close()
return True
def main():
dir_root = ("C:\\Model_Spreadsheets")
vba_sub = \
'''
sub UpdateLinkValues()
Application.AskToUpdateLinks = False
ActiveWorkbook.UpdateLink Name:=ActiveWorkbook.LinkSources
end sub
'''
xl_app = Dispatch("Excel.Application")
xl_app.Visible = False
xl_app.DisplayAlerts = False
for root, dirs, files in os.walk(dir_root):
for fn in files:
if fn.endswith(".xlsx") and fn[0] is not "~":
run_macro(os.path.join(root, fn), vba_sub, xl_app)
xl_app.Quit()
if __name__ == "__main__":
main()
このスクリプトは私が探しています正しい解には本当に近いですが、私は、一見「ランダム」VBAエラーに遭遇:
run-time error '1004' method 'updatelink' method of object '_workbook' failed
このエラーこのスクリプトを実行しようとするたびに表示されますが、毎回同じワークブックには発生しません。最初のワークブックで、時には15日などに発生します。
私にはオプションがありますVBAでデバッグする方法と、次のワークブックに進むことができる唯一の方法私はこのマクロと終了、デバッグを実行する場合、プログラムは、それが再び同じエラーが発生するまで実行し続けます
sub UpdateLinkValues()
Application.AskToUpdateLinks = False
end sub
にマクロを変更した場合OOKです。私の最初の考えは、ワークブックを開いてマクロを実行しようとするタイミングの問題かもしれないということでした。私が発見した問題を回避するには、私はマクロとアプリケーションの可視性を変更することができるということです。
vba_sub = \
'''
sub UpdateLinkValues()
Application.AskToUpdateLinks = False
end sub
'''
と
xl_app.Visible = True
これは正常に動作しますが、私は開いているブックのそれぞれを持っていることのファンではありませんそれは長い時間がかかりますので近づいてください。私の質問は、誰もこのランタイムエラーが出てくる理由を知っていますか?あるいは、誰かがPythonでこの実行時エラーを例外として傍受する方法を知っていますか?私がこのエラーをPythonの例外として傍受することができれば、その特定のワークブックの代替ソリューションを使用することができます。
ありがとうございます!
興味深いことに、マクロを ".xlsx"形式で保存することはできないため、* random *エラーとは別に作業していました。 ".xlsm"または ".xlsb"タイプが必要です。 – Parfait