Close an Excel session with Python

Hi to Everyone, i create a Python Script who allow me to bring some data by an .xlsx file.
I import the clr, i can read the data. I have trouble when i must close the session with the file.
If I try to open the file evrithing is fine. If I open my task manager the EXCEL.exe process is already open.
How i can close it. Because everytime i run the script it open a new process!
Here my code:

import clr
import scriptcontext
import rhinoscriptsyntax as rs
clr.AddReference("Microsoft.Office.Interop.Excel")
from Microsoft.Office.Interop import Excel

if( scriptcontext.sticky.has_key("ExcelApp") ):
        xl = scriptcontext.sticky["ExcelApp"]
        return xl
xl = Excel.ApplicationClass()
scriptcontext.sticky["ExcelApp"] = xl
wb = xl.Workbooks.Open(r'path\to\myfile.xlsx',False,True)
sh=wb.Worksheets(1)
value=sh.Range["B4"].Text
close=wb.Close(True)
close=xl.Quit

Thanks!
Daniele

I don’t have excel on my computer at the moment, but I noticed the last line in your script

close=xl.Quit

This does not actually call the Quit function, instead it assigns the close variable to the Quit function. You probably want

xl.Quit()

instead

Here’s an old excel interop sample I wrote that fills an excell worksheet with values from a point cloud. Maybe it will help.

import clr
import scriptcontext
import rhinoscriptsyntax as rs
clr.AddReference("Microsoft.Office.Interop.Excel")
from Microsoft.Office.Interop import Excel
import System.Array

def GetExcelApplication():
    if( scriptcontext.sticky.has_key("ExcelApp") ):
        return scriptcontext.sticky["ExcelApp"]
    # start Excel and save the instance in our sticky dictionary
    # so we can reuse it
    xl = Excel.ApplicationClass()
    scriptcontext.sticky["ExcelApp"] = xl
    return xl

if( __name__ == "__main__" ):
    xl = GetExcelApplication()
    wb = xl.ActiveWorkbook
    if wb==None:
        wb = xl.Workbooks.Add()
    sheet = wb.ActiveSheet
    pointcloud = rs.GetObject("Select point cloud", rs.filter.pointcloud)
    points = rs.PointCloudPoints(pointcloud)
    if points:
        xl.Visible = False
        a = System.Array.CreateInstance(object, 3)
        for i, point in enumerate(points):
            cell = "A" + str(i+1) + ":C" + str(i+1)
            a[0] = point[0]
            a[1] = point[1]
            a[2] = point[2]
            sheet.Range[cell].Value = a
        xl.Visible = True

Not to hijack this thread, but is there some sort of easy general listing of the methods available for Excel? I looked around the net and found things like this:

http://msdn.microsoft.com/en-us/library/Microsoft.Office.Interop.Excel(v=office.11).aspx

but for example trying to find a page in there that outlines the method to assign a value to a specific cell (as in the above example) is beyond my comprehension… :confounded:

–Mitch

http://www.ironpython.info/index.php?title=Interacting_with_Excel

seems like a good place to start

OK, thanks Steve!
–Mitch

Many thanks to all!
Steve, I start by the same thread! I’m sorry but xl.quit() didn’t work…

Sorry guys, but I can’t fix it!
The Excel.exe process is still there! I try everything but nothing change.
Now i’m trying to kill the process opened by my script. But it is only a bad work around.
There is my code. Try that and tell me if for you is the same.

import clr
clr.AddReference("Microsoft.Office.Interop.Excel")
from Microsoft.Office.Interop import Excel
import rhinoscriptsyntax as rs
if __name__ == '__main__':
    FileLocation = "path\to\my\xls\file.xls" 
    ExcelApp = ApplicationClass() 
    workbook= None 
    workbook = ExcelApp.Workbooks.Open(FileLocation) 
    workbook.Save() 
    workbook.Close(SaveChanges=0)
    del (workbook)
    ExcelApp.Quit()
    del (ExcelApp)
    pass

After tweaking your code a bit to run here, I saw the same thing… Then I tried playing around a bit and I found that if you use ExcelApp.Quit and not ExcelApp.Quit() then Excel quits properly…

HTH, --Mitch

Thanks Mitch, can you update your code?
I try the ExcelApp.Quit but it doesn’t work. Maybe my code need some change.

Hi Daniele,

This is a complex problem indeed, you might try ExcelApp.Dispose() as a last resort and if this doesn`t work, see here especially look at the post by VVS from Feb 4. talking about “two dots”.

c.

It’s an old thread but if someone runs across this to find a solution, using the info by @clement this seems to work for me:

import clr
import System
clr.AddReference("Microsoft.Office.Interop.Excel")
from Microsoft.Office.Interop import Excel

def sample_excel_session():
    excelApp = Excel.ApplicationClass()
    excelApp.Visible = False
    excelApp.DisplayAlerts = False
    wBooks = excelApp.Workbooks
    wBook = wBooks.Open("path\\filename.xls")
    
    # do some stuff
    
    wBook.Close(True)
    System.Runtime.InteropServices.Marshal.ReleaseComObject(wBooks)
    System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp)

sample_excel_session()

Hi everyone,

I’ve been dealing with killing excel issue for a long time now.

( my thread with no practicable solution at that moment [End MS Excel process with python script] )

So far the best method to “kill” Excel I came up with is this one:

I got it after reading this link on StackOverflow

import rhinoscriptsyntax as rs
import clr
import System.GC

clr.AddReference("Microsoft.Office.Interop.Excel")
from Microsoft.Office.Interop import Excel

def XLS_cleanup():
    
    System.GC.Collect()
    System.GC.WaitForPendingFinalizers()
    return
    
def Excel_Open():

    myfile = rs.OpenFileName("Select Excel File:","Excel file|*.xls;*.xlsx|")

    if not myfile:
        return
  
    xl = Excel.ApplicationClass()
    WB=xl.Workbooks.Open (myfile)

    print WB.Name

    WB.Close()
    xl.Quit()

Excel_Open()
XLS_cleanup()

Note that I have intentionally violated the “two dot” rule when creating WB variable and it still works

The catch is to put the script inside the one function and the cleanup code inside another.
First you call the script function, and then the cleanup, and it works

Placing everything inside the same function did not work for me…

BR
Aleksandar Djordjic

1 Like