How to have python wait until an Excel Macro/Refresh is done - python

I am using Python to run a macro in excel. and I want Python to close excel. The macro refreshes a data connection in excel which can be slow.
How do I have python wait until the refresh is done to close. This is what I am using, I need something before the xl.Quit that will wait until the refresh in macro is done????
import win32com.client
import os
xl = win32com.client.DispatchEx("Excel.Application")
wb = xl.workbooks.open("X:\Backoffice\Options Trading\BloombergRate.xlsm")
xl.Visible = True
xl.run("Refresh")
xl.Quit()
Wait ways can I make this work?

Edit your Refresh macro to set QueryTable.BackgroundQuery property to False. This should cause the macro to block until it is done.

You don't even have to set up a macro to run this. win32com has a native method to refresh all data connections.
import win32com.client
import os
xl = win32com.client.DispatchEx("Excel.Application")
wb = xl.workbooks.open("X:\Backoffice\Options Trading\BloombergRate.xlsm")
xl.Visible = True
wb.RefreshAll()
xl.Quit()

Related

How to Run Personal Workbook Macro from Python?

H1! I get a file everyday that contains similar information. I wrote a Macro to automate the formatting process and now I want to run the macro using Python.
The Macro is in my personal Workbook since it is ran in different xlsx files everyday.
When I try to run my code I get 'The macro may not be available i this workbook or all macros may be disabled'
This is the my python code
import win32com.client
import os
import datetime
path_dir = r'C:\Users\myuser\Documents\me\directory1\directory2'
dt_today = datetime.date.today().strftime("%b%d")
file = r'{}\xlfile_{}.xlsx'.format(path_dir, dt_today)
Prs_wb_path =
r'C:\Users\myuser\AppData\Roaming\Microsoft\Excel\XLSTART'
xl = win32com.client.Dispatch("Excel.Application")
xlsPath = os.path.expanduser('{}').format(file)
wb = xl.Workbooks.Open(Filename=xlsPath)
xl.Application.Run(r'PERSONAL.XLSB!ContextualData_Formatting')
wb.Save()
xl.Quit()

Getting file exists overwrite alert when trying to refresh and save .xlsm file via python even with DisplayAlerts set to False

I am trying to refresh a macro enabled excel file through a python script. I have used win32com.client package for launching an excel instance and refreshing the file and trying to save it. I have also set DisplayAlerts = False. I am getting an alert like:
A file named 'F:\User\output\testfile.xlsm' already exists. Do you want to overwrite it?
I am not getting this alert for other xlsm files that I am trying to refresh even though there are files present with the same name in the destination folder. Here is a sample of the code I used to refresh the files:
import win32com.client as win32
xl = win32.DispatchEx('Excel.Application')
xl.DisplayAlerts = False
xl.Visible = False
xl.Interactive = False
xl.EnableEvents=False
wb = xl.Workbooks.Open(os.path.join(excel_path),ReadOnly=False, IgnoreReadOnlyRecommended =True)
xl.DeferAsyncQueries = True
wb.RefreshAll()
xl.CalculateUntilAsyncQueriesDone()
xl.DeferAsyncQueries = False
wb.SaveAs(output_filepath,ReadOnlyRecommended =False)
wb.Close(False)
xl.Quit()
Can anyone help me figure out why am I getting the alert only for that particular file?
Thanks in advance.

win32com: work with excel file by opening it in background

So I use following code to open an existing excel file. Even though I make visible to False, but this always open the excel file UI. However I want to run it in the background. How can I do that?
import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Open('my_sheet.xlsm')
excel.Visible = False
I now use one of MS Excel's alternative Kingsoft Spreadsheet. My snippet below used to run the application in the background.
from win32com import client
xApp = None
for aname in ('Excel', 'eT', 'KeT'):
try:
xApp = client.Dispatch(aname + '.Application')
except client.pywintypes.com_error:
continue
else:
break
if xApp is None:
print('No app found')
raise SystemExit # Application is unavailable.
else:
# do something
wb = excel.Workbooks.Open('my_sheet.xlsm')
On older version of MS Excel (before 2013) and KS Spreadsheet (before 2014), the above code worked fine, even without explicitly setting xApp.Visible to False. However, on recent version of Spreadsheet, it would launch a small UI window when quitting the application.

Retrieve Excel Workbook Connection Properties

I am attempting to grab the "Command Text" from the Connection Property window in an Excel file using python. However, I cannot find the object that contains this information. In the below picture I would like to retrieve the highlighted EXEC sp_FooBar as a string:
I am able to retrieve the Connection names with:
import odbc
import win32com.client
file = r'PATH_TO_FILE'
xl = win32com.client.DispatchEx('Excel.Application')
wb = xl.workbooks.open(file)
for x in wb.connections:
print(x)
But I'm not sure how to use the <COMObject <unknown>> object further to grab the command text. I'm thinking win32com may have something, but can't seem to crack the code.
You can get the CommandText property from a OLEDBConnectioninstance like this:
import odbc
import win32com.client
file = r'PATH_TO_FILE'
xl = win32com.client.DispatchEx('Excel.Application')
wb = xl.workbooks.open(file)
for x in wb.Connections:
print(x.OLEDBConnection.CommandText)
xl.Application.Quit()

Release excel workbook after write operations through a script

I am using a python script to write data into the excel workbook. Now, I want to release the pointer. I dont want to close the workbook because of some other reasons. I just want to release the pointer. I searched on google but no answer. Can anyone please help?
from win32com.client import Dispatch
xl = Dispatch('Excel.Application')
xl.ScreenUpdating = True # performance
xl.Visible = 1
xl.DisplayAlerts = True
wbs = xl.Workbooks
return xl, wbs
Then i am using wb to refer to workbook's different sheets.
wb = xl.Workbooks.open(filename)
Variables will be released as they go out of scope. In the example below, the variable xl is released when the get_workbook function is exited. If you need to explicitly remove a variable, use the del statement.
from win32com.client import Dispatch
def get_workbook(path):
xl = Dispatch('Excel.Application')
xl.Visible = 1
return xl.Workbooks.open(path)
wb = get_workbook(r'c:\temp\test.xlsx')
sheet = wb.Worksheets.Item(1)
sheet.Range('A1').Value2 = 'test'
del wb, sheet

Categories