Close an Excel session with Python


#1

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


(Steve Baer) #2

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

#3

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


(Steve Baer) #4

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

seems like a good place to start


#5

OK, thanks Steve!
–Mitch


#6

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


#7

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

#8

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


#9

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


#10

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.