XLWings Throwing Error on quit after a copy

497 views Asked by At

When running xlwings 0.26.1 (latest for Anaconda 3.83) or 0.10.0 (using for compatibility reasons) with the latest version of Office 365 Excel, I get an error after moving a sheet when running app.quit():

import xlwings as xw
import pythoncom

pythoncom.CoInitialize()
app = xw.apps.add()
app.display_alerts = False
app.screen_updating = False

wbSource = app.books.open('pathSourceTemp')
wsSource = wbSource.sheets['sourceSheet']
wbDestination = app.books.open('pathDestinationTemp')
wsDestination = None

#Grabs first sheet in destination
wsDestination = wbDestination.sheets[0]


#Copy sheet "before" destination sheet (which should be 1 sheet after the destination sheet)
wsSource.api.Copy(Before=wsDestination.api)
wbDestination.save()

#Close workbooks and app
wbDestination.close()
wbSource.close()
app.screen_updating = True
app.quit()

The final line causes Excel to throw an error that I have to click out of for the process to continue.

2

There are 2 answers

0
EliSquared On

The solution I found which works with both xlwings 0.10.0 and 0.26.1 is to simply brute force with the app.kill() method:

#Close workbooks and app
wbDestination.close()
wbSource.close()
app.screen_updating = True
#app.quit() <- throws error
app.kill() <- no error

Not sure what unintended side effects this might have, but apparently the .kill() command was introduced in version 0.9.0. As long as you close the workbooks first, I dont see how it can cause any problems with data loss or corruption.

0
mouwsy On

Since version 0.24.3, the idiomatic way is using with xw.App() as app. The advantage of this is that there won't be any hidden excel processes left over in the background, if you use a hidden instance (visible=False) and your code fails.

import xlwings as xw

# You could also omit .screen_updating (and .display_alerts)
# and use xw.App(visible=False) instead, if appropriate.
with xw.App() as app:
    app.display_alerts = False
    app.screen_updating = False

    wbSource = xw.Book()
    wbDestination = xw.Book()

    # Do your stuff here.

    app.screen_updating = True
    # Save as needed, for example: wbDestination.save()
    wbSource.close()
    wbDestination.close()