Wednesday, January 20, 2010

Connecting to One of Many Open Documents

If you've hung around here for a little while, then you probably already know that you can use the WIN32OLE.connect() method to connect to a running instance of applications like Microsoft Word. Just pass the method the ProgID of the Application object:


word = WIN32OLE.connect('Word.Application')

That works great if you have just one instance of the application running, with one or multiple documents open. But suppose you have multiple instances of the application running? How can you be sure that you connect to the instance with Document B, and not the instance with Document A?

Well, assuming that Document B has been saved and you know the full filename, then you can connect to the Document object, rather than to the Application object. And you do this by passing the WIN32OLE.connect() method the full filename:

document = WIN32OLE.connect('C:\Path To File\DocumentB.doc')

This returns an instance of the Word.Document object. You can then grab
an instance of that Document's Application object:

word = document.Application

This works with other multiple-instance applications, such as Excel. The following code connects to a specific instance of an Excel.Workbook object:

workbook = WIN32OLE.connect('C:\Path To File\WorkbookB.xls')
xl = workbook.Application

By the way, some applications, such as PowerPoint, are single-instance applications, so there will never be multiple instances of the application running, avoiding the need to use the process outlined above.

There you have it. Please let me know if you have specific questions or suggestions for future articles.

Thanks for stopping by!

4 comments:

Greg said...

Hi, Thanks for your useful blog posts. I've used the ideas here to automate some of my interactions with MS Visual Studio.

Using the filename as the COM moniker is really useful for connecting to a specific running version.

Do you know of any way of listing what monikers (in this case file names) are registered (ie open) using WIN32OLE?

QPT said...

Thanks for the sharing.
Qualitypoint

Greg said...

Just to follow up to my previous comment. I got so sick of not being able to find open documents I cobbled together a gem that allows you to find all open documents.

Hope you don't mind the "spam".

How to use it:
> gem install win32olerot

---
require 'win32olerot'

rot = WIN32OLE::RunningObjectTable.new

# connect to my_doc only if it is already open
my_doc_path = 'path/to/my.doc'
my_doc = WIN32OLE.connect(my_doc_path) if rot.is_running?(my_doc_path)

# print all open .doc files
rot.each do |x|
  puts x if x =~ /.doc/
end
---

Its my first gem so let me know if its of any use - or if you have any trouble.

Anonymous said...

Hi David, can you tell me how can I do to connect to some particular Excel instance, let's suppose that I have two instances oppened, and I want to connect to the last one created, the one that I've opened using Ruby, how can I connect to it? because I want to keep it hidded until I have all the workbook formated, then show it.