/ / Чому макрос Excel працює в Excel, але не при виклику з Python? - python, excel, vba, pywin32

Чому Excel макрос працює в Excel, але не коли викликається з Python? - python, excel, vba, pywin32

Маю макрос Excel, який видаляє аркуш,копіює інший аркуш і перейменовує його на ту ж назву видаленого аркуша. Це відмінно працює при запуску з Excel, але коли я запускаю його, викликаючи макрос з Python, я отримую таке повідомлення про помилку:

Помилка під час виконання "1004" - Неможливо перейменувати аркуш з тим же ім'ям, що і інший аркуш, бібліотеку об'єктів, на які посилаються, або робочу книгу, на яку посилаються VisualBasic.

Макрос має такий код:

Sheets("CC").Delete
ActiveWindow.View = xlPageBreakPreview
Sheets("FY").Copy After:=Sheets(Sheets.Count)
Sheets(Sheets.Count).Name = "CC"

і відладчик виділяє помилку в останньому рядку, де лист перейменовано. Я також спробував помістити ці виклики безпосередньо в python, але отримати те ж повідомлення про помилку.

Будь-які пропозиції дуже цінуються!

Дякую.

Відповіді:

2 для відповіді № 1

Я запустив код всередині Excel VBA.
Я здогадуюсь, що наступна лінія не вдається.

Sheets("CC").Delete

І саме тому ви не можете дати новому аркушу таку саму назву, як існуючий (не видалений) аркуш.

Покласти Application.DisplayAlerts = False раніше Sheets("CC").Delete і
Application.DisplayAlerts = True після завершення коду.

Я не використовував Python, але, здається, бібліотека ковтає цю помилку для вас і дає вам можливість перейти до наступної заяви.

Надія, що допомагає.


1 для відповіді № 2

За кулісами підтримуються VB і VBAпосилання на об'єкти COM для додатків, робочих аркушів тощо. Ось чому у вас є globals "Application", "Worksheets" та ін. .

Спробуйте не використовувати ці неявні глобалі та посилайтеся на елементи об'єктної моделі явно. Крім того, ви можете зробити це безпосередньо в Python.

Тут є скрипт python, який зробить щось подібне до того, що ви хочете:

import win32com.client
xl = win32com.client.Dispatch ("Excel.Application")
xl.Visible = True
wb = xl.Workbooks.Add()
wb.Worksheets[0].Delete()
wb.Worksheets.Add()
wb.Worksheets[0].Name = "Sheet1"