Я запускаю симуляции в Python, которые генерируют выходные данные, которые нужно непосредственно потреблять модельером в своих книгах excel. Я создал код, который будет напрямую выводить мои данные в их шаблон Excel Excel. Код, который я сгенерировал для вывода данных непосредственно на их шаблон, хорош, но проблема, с которой я сталкиваюсь, заключается в том, что модельер имеет серию книг, которые «связаны» вместе. Если я вставляю свои данные в свою электронную таблицу, ссылки на эту книгу не обновляются, если пользователь физически не открывает книгу «Изменить ссылки» -> «Обновить значения». Если бы была одна книга, пользователь мог бы просто открыть книгу без проблем. В действительности, будет более 100 книг, которые нуждаются в обновлении ссылок. К сожалению, я ничего не могу поделать, чтобы изменить подход модельера при связывании книг - единственное, что я могу сделать, - это их подход.Обновление ссылок для таблицы Excel с использованием Python
Моя цель - создать решение Python, которое позволит мне: 1) Создать имитированные данные; 2) Вставить мои сгенерированные данные в книгу моделлера и 3) Обновить все ссылки между книгами. В конечном счете, для того, чтобы быть упорядоченным, я хочу иметь возможность делать все три в одной сквозной программе python. Я решил (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
если запустить этот макрос и выхода отладки, программа будет продолжать работать, пока он снова не встречает ту же ошибку. Моя первая мысль заключалась в том, что, возможно, существует проблема с тем, что я открываю книгу и пытаюсь запустить макрос. Обходной, что я нашел, что я могу изменить макрос и приложение видимости:
vba_sub = \
'''
sub UpdateLinkValues()
Application.AskToUpdateLinks = False
end sub
'''
и
xl_app.Visible = True
Это прекрасно работает, но я не поклонник того, чтобы каждый из книг открытых и закрыть, потому что это занимает много времени. Мой вопрос в том, кто-нибудь знает, почему эта ошибка во время исполнения - с решением? Или, может быть, кто-нибудь знает, как перехватить эту ошибку во время выполнения в Python как исключение? Если я могу перехватить эту ошибку как исключение в python, тогда я мог бы использовать свое альтернативное решение для этих конкретных книг.
Заранее благодарен!
Интересно, что это даже работало отдельно от случайной ошибки, поскольку вы не можете сохранять макросы в форматах «.xlsx». Вам нужны типы «.xlsm» или «.xlsb». – Parfait