Can not run Excel macro via Python using xlwings - python

I'm trying to run simple Excel macro via Python using xlwings but it doesn't work.
I tried to run Python in JupyterLab. Both code, VBA and Python, are so simple and when I run VBA code in Excel, it works correctly. Also, I tried some simple python code using xlwings like
import xlwings as xw
wb = xw.Book('test.xlsm')
sheet = wb.sheets[0]
sheet.range('A1').value = 'test'
works correctly.
However, the python code below doesn't work.
import xlwings as xw
wb = xw.Book('test.xlsm')
macro = wb.macro('test')
macro()
I put this VBA code below on "ThisWorkbook" in ExcelVBA editor.
Sub test()
Range("A1").Value = "This is a test."
End Sub
Error message is like this.
com_error: "Cannot run the macro 'test.xlsm'!test'. The macro may not be available in this workbook or all macros may be disabled."

I solved it by myself.
I edited the code like this and it works correctly.
macro = wb.macro('ThisWorkbook.test')

Related

Python xlwings "Unable to get repr for <class 'xlwings.main.Book'>" when reading workbook

 I´m trying to update a worksheet named table by passing a dataframe to it. I wrote the code in VSCode and it works fine, but when I have to run it on the company´s PC using PyCharm I get the error "Unable to get repr for <class 'xlwings.main.Book'>".
This is the part of the code that´s giving me an error:
import xlwings as xw
with xw.App(visible=False) as app:
app.display_alerts = False
wb = app.books.open(myfilepath, update_links=False) #HERE
ws = wb.sheets[sheet_name] #Consequently, from this point on nothing works...
ws.tables["Tabelle1"].update(dataframe, index=False)
wb.save(myfilepath)
wb.close()
Does someone know what could the problem be? I have looked all over the internet but found nothing helpful.
The current answer to a similar question on SO is "If the code works fine without it, then it is nothing to worry about.". In my case the code does not work properly.

How to run Excel Macro on MacOS using XLWINGS?

I have an API file that takes in dates, and then when the macro is run pulls in data for said date range.
I can run this on a Windows computer without use of Python, however I am automating a data clean up process and would like to be able to run this macro from MacOS.
I am using XLWINGS.
My logic is :
Open the workbook.
Update the date values.
Execute the macro.
Save workbook as a new file.
Close workbook.
Eventually set it on a loop to update itself
Current Code :
import xlwings as xw
start = dt.datetime(2022,2,1)
end = dt.datetime(2022,3,31)
excel_app = xw.App(visible=False)
wb = excel_app.books.open('sheet.xlsm')
sheet = wb.sheets['Start']
sheet.range('E5').value = start
sheet.range('E7').value = end
update = wb.macro("'sheet.xlsm'!Code.update_report")
update()
wb.save('PATH')
wb.close()
I get prompted with no errors, the script opens the workbook, updates the values, then saves it in the new location I defined with the new name.
However when I open the .xlsm file after its run its course - it does not have the update data for the inputted date range. Essentially, the macro does not run.
Other ways I've tried to run the macro (instead of running the macro on the original file, I save the original file once the date range has been updated and then try to execute the macro):
import xlwings as xw
if os.path.exists('sheet.xlsm'):
excel_app = xlwings.App(visible=False)
wb = xw.Book('sheet.xlsm')
app = wb.app
update = app.macro("!Code.update_report")
update()
wb.save()
Still - runs fine, no errors, except it does not execute the macro.
Any help welcomed! Thank you.

python code that activates a workbook and run the vba code?

I have this code that can run VBA or macro code from python but only when the workbook is active, means i have manually to open the workbook before i run the python code.
import xlwings as xw
import win32com.client
xl_app = win32com.client.Dispatch("Excel.Application")
xl_app = xw.App(visible=False,add_book=False)
wk = xw.books.open(r'C:\Users\afoto001.000\Desktop\All projects\FS\VBA\Perform.xlsm')
wk.api.Unprotect(Password='')
macro = wk.app.macro("Module1.shappen")
macro()
print('yes')
I'd like to completely automate the process, with no manual contact with the workbook. Is there a python package or something that I can use to execute the code and have it activate the workbook so that the code can run the marco? Any assistance or suggestions would be greatly appreciated?

How to suppress "Update Links" Alert with xlwings

I am interfacing with Excel files in Python using the xlwings api. Some Excel files I am interacting with have old links which cause a prompt to appear when the file is opened asking if the user would like to update the links. This causes the code to hang indefinitely on the line that opened the book until this prompt is closed by a user. Is there a way to modify the settings of the Excel file so that this prompt will not appear or it will be automatically dismissed without opening the actual file?
I have tried using the xlwings method:
xlwings.App.display_alerts = False
to suppress the prompt, but as far as I can tell this can only be run for an instance of Excel after it has been opened. There are some Excel api's that do not require a file to be open in order to read data like xlrd, but they are not very convenient for reading and copying large amounts of data (Multiple/Entire sheets of data).
The following code demonstrates the issue:
import xlwings as xw
wb = xw.Book(r'C:\Path\To\File\Filename')
print('Done')
On a regular Excel file the code proceeds through and prints "Done" without the need of user interference, but on an Excel file where the "update links" prompt comes up, it will not proceed to the print statement until the prompt is dismissed by a user.
Expanding on your first attempt -- you're not handling an App instance, rather you're trying to assign to the xlwings.App class.
However, it seems that the display_alerts doesn't successfully suppress this alert in xlwings, try this:
import xlwings as xw
app = xw.App(add_book=False)
app.display_alerts = False
wb = app.books.api.Open(fullpath, UpdateLinks=False)
I believe there is an implementation in xlwings to avoid update links messages now. I was able to bypass these alerts by adding the following
app.books.open(fname, update_links=False, read_only=True, ignore_read_only_recommended=True)
You can see these arguments available in the documentation xlwings.Book.open(...)
I presently have 20+ source workbooks that I loop though to extract some rows of data. It was intolerable to respond to the update links prompt of each opened workbook. I tried the other solutions here but none worked for me. After reviewing the cited xlwings docs, this is the solution that worked for me:
for fname in workbook_list:
wb = xw.books.open(fname, update_links = False)
# Extract some data...
wb.close()
My environment is Win10Pro / Python 3.8.1 / pywin32 version: 303 / Excel 365 Subscription / xlwings 0.26.2

XLWings data link warning not caught by display_alerts [duplicate]

I am interfacing with Excel files in Python using the xlwings api. Some Excel files I am interacting with have old links which cause a prompt to appear when the file is opened asking if the user would like to update the links. This causes the code to hang indefinitely on the line that opened the book until this prompt is closed by a user. Is there a way to modify the settings of the Excel file so that this prompt will not appear or it will be automatically dismissed without opening the actual file?
I have tried using the xlwings method:
xlwings.App.display_alerts = False
to suppress the prompt, but as far as I can tell this can only be run for an instance of Excel after it has been opened. There are some Excel api's that do not require a file to be open in order to read data like xlrd, but they are not very convenient for reading and copying large amounts of data (Multiple/Entire sheets of data).
The following code demonstrates the issue:
import xlwings as xw
wb = xw.Book(r'C:\Path\To\File\Filename')
print('Done')
On a regular Excel file the code proceeds through and prints "Done" without the need of user interference, but on an Excel file where the "update links" prompt comes up, it will not proceed to the print statement until the prompt is dismissed by a user.
Expanding on your first attempt -- you're not handling an App instance, rather you're trying to assign to the xlwings.App class.
However, it seems that the display_alerts doesn't successfully suppress this alert in xlwings, try this:
import xlwings as xw
app = xw.App(add_book=False)
app.display_alerts = False
wb = app.books.api.Open(fullpath, UpdateLinks=False)
I believe there is an implementation in xlwings to avoid update links messages now. I was able to bypass these alerts by adding the following
app.books.open(fname, update_links=False, read_only=True, ignore_read_only_recommended=True)
You can see these arguments available in the documentation xlwings.Book.open(...)
I presently have 20+ source workbooks that I loop though to extract some rows of data. It was intolerable to respond to the update links prompt of each opened workbook. I tried the other solutions here but none worked for me. After reviewing the cited xlwings docs, this is the solution that worked for me:
for fname in workbook_list:
wb = xw.books.open(fname, update_links = False)
# Extract some data...
wb.close()
My environment is Win10Pro / Python 3.8.1 / pywin32 version: 303 / Excel 365 Subscription / xlwings 0.26.2

Categories