Attach to a running instance of a COM application

Introduction

If you want, for example, to make some changes to an Excel spreadsheet which is already on the desktop, say to add a new sheet with extracted data, you don't want to .Dispatch a new instance; you want to attach to the existing one.

The win32com.client module offers the .GetObject function which takes a pathname, eg of the Excel file, and returns a COM instance of that object. If the object is running already, it will return the running instance (calling GetActiveObject under the covers); if not, it will start a new instance and return that. As far as I can tell, using the Class to get the instance will only find the last-opened instance.

Use GetObject

import os, sys
import csv
import tempfile
import win32com.client

#
# Cheating slightly because I know a .csv
# file will register as an Excel object
#

filename = tempfile.mktemp (".csv")
f = open (filename, "wb")
writer = csv.writer (f)
writer.writerows (range (i, i+5) for i in range (10))
f.close ()

#
# NB filename must (in effect) be absolute
#
os.startfile (filename)

wb1 = win32com.client.GetObject (filename)
wb1_c11 = wb1.ActiveSheet.Cells (1, 1)
print wb1_c11.Value
wb1_c11.Value += 1

xl = win32com.client.GetObject (Class="Excel.Application")
# could also use:
# xl = win32com.client.GetActiveObject ("Excel.Application")
xl_c11 = xl.ActiveSheet.Cells (1, 1)
print xl_c11.Value
xl_c11.Value += 1

print wb1_c11.Value
print xl_c11.Value

wb1.Close ()

os.remove (filename)