Search code examples
excelpython-2.7win32com

How to read(-only) an Excel (with Python) from a network drive and leave the place as it was


I have a little python (2.7) script reading in information from an excel file on a network drive. Works fine, but it was a little annoying during development, that after each script run the excel file was closed. This would be the intended behaviour, if the excel file was already closed when starting the script, but I was making edits to the excel to test the script. Furthermore I expect problems, if somebody already opened the workbook, because I don't automatically open the workbook as read-only copy (which would be fine, since I only read).

So the question is how in python do I fullfil the following requirement:

  • if Excel was closed when starting the script, it must be closed after reading, otherwise not
  • if the workbook was closed when starting the script, it msut be closed after reading, otherwise not
  • If the workbook is opened by another user it shall be opened as read-only copy

?

Efforts so far:

besides googling I already searched this side for similar topics (e.g. "how do I check if Excel is open"). Most of the time the answers were about how to circumvent the core of the question, so they were no help to mine.


Solution

  • I solved this exact problem a while back by first asking Excel for the list of already open workbooks. If the file that I wanted to open was already open, then I would set a flag "leaveOpenOnExit = True", otherwise leave it false, and open it. Then do the processing. Then at end, use the flag to decide whether to close the workbook.

    Actually I also tested if Excel was already started when my script started, by using win32com's GetActiveObject which raises exception if none available, and then I set a flag accordingly. With that flag, on exit I would only close Excel if it was already open on startup of the script. Pattern is:

    from win32com.client import GetActiveObject
    from win32com.client import constants as comConst # will only contain COM constants if 
        # makepy.py has been run on Excel or if EnsureDispatch has been used once
    
    try:
        excelRunsAtStart = True 
        excel = GetActiveObject("Excel.Application")
    except com_error:
        excelRunsAtStart = False
        excel = Dispatch("Excel.Application")
    
    # use comApp...
    wb = excel.Workbooks.Open(excelPath, comConst.ReadOnly=1)