Help with OLE and multiple Word documents

Posted on 2014-07-29
Last Modified: 2014-09-18
We still have a VB6 application in use. In this application, documents are created in Word for Windows by using an OLE link (Office Automation). The connection is set up with the following code.

2 global variables are declared:

          Global objWdApp As WORD.Application
          Global objWdDoc As WORD.Document

Then the Word object objWdDoc is created for the document that has to be edited:

          Set objWdApp = CreateObject("Word.Application")
          Set objWdDoc = objWdApp.Documents.Open("C:\test\test.doc")

, and the document is activated and made invisible:

          objWdApp.Documents("test.doc").Windows(1).Visible = False

The document can then  be generated , for example using code like this:

          objWdApp.Selection.Font.Bold = true
          Set myTable = ActiveDocument.Tables.Add(Range:=myRange,…………….
          Selection.Borders(wdBorderRight) = true

and so on. This works fine.

However, there is a problem if there are more Word documents open at the time the OLE link is initialized and opened. Using the user interface, the user is able to put the focus on to one of the other Word documents. The OLE commands will then be sent to the document that has the focus, which may not be the one intended. We have solved this by making Word completely invisible so that all other Word documents disappear from view:
          objWdApp.Visible = False

This solves the problem, even though it might not be very elegant.

Later, however, we also received a message from one of our customers saying that the same problem also occurs when an email is created in Outlook using a Word module for writing emails. In that situation the focus will be put on the e-mail (it is seen as a Word document) and the OLE commands will be sent to this email! We can make Outlook invisible too, but I am looking for a better solution for this behavior.

Does anyone have an idea how we can manage this problem?

Any help is greatly appreciated!
Question by:Pirie
  • 4
  • 3

Expert Comment

ID: 40226872

When using the CreateObject, you should be creating a unique instance of Word. This will run outside of all the other instances.

Now the issue looks to be that in the code where you set the text etc.. is targeting ActiveDocument and not objWdDoc. So as an example
Set myTable = ActiveDocument.Tables.Add(Range:=myRange,…………….

Open in new window

Would be
Set myTable = objWdDoc.Tables.Add(Range:=myRange,…………….

Open in new window

This would then target the file currently open in the instance of Word opened by you app.

Hope this helps
LVL 40

Accepted Solution

Jacques Bourgeois (James Burger) earned 300 total points
ID: 40227416
The code that you use if Office automation usually needs to be different than the one that is used in VBA macros.

For instance, instead of working with ActiveDocument, work with the specific document:


You are then sure that the code will apply to the specified document.

It is also usually better to work with Range objects (Bookmarks, Tables, Words, Pages, Sentences) rather than with Selection. This lets you manipulate the document without using the cursor. It's faster and safer, but might require getting used to.

Author Comment

ID: 40228518
Thanks for your comments! I go look at your advices and then come up with my response later.
Online Training Solution

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action. Forget about retraining and skyrocket knowledge retention rates.


Author Comment

ID: 40292097
I took the advice to replace ActiveDocument by objWdDoc and implemented it in my application. It improved it already significantly! So thanks for that advice.

 But what I see now is that the cursor in Word is very active (flashing very much) in other open documents as a document is created by my application (which is invisible).

 Besides that I see that my document have not be created properly when I click into another open Word document during the process of creating the document by my application.

 I think it has to do with the use of .Selection and that the use of .Range as you suggest in your answers should be better. But how do I add that way a new paragraph at the end of my document? Now I use: objWdDoc.ActiveWindow.Selection.TypeParagraph. Do I need to count all the paragraphs and use that in combination with Range?
LVL 40
ID: 40292598
No, you do not need to count.

And TypeParagraph is not the fastest way to go, because it mimics the user typing. Same as ActiveDocument, this is something that is recorded by the macro recorder, so to mimic as close as possible what you do while recording, but it is not the most efficient way to work for most situation.

Everything you find in a document is available through a collection. The same way we worked with the Tables collection in my last post, there is a collection of Words, a collection of Pages, a collection of Paragraphs, Lines, Section, Sentences. If you do not know the concept, a collection is similar to an array in many ways, but it is more versatile with dynamic data such as you have in a Word document.

A collection has a Count property that let's you know how many there are. It also has an Add method that let's you add an element at the end of the collection.

So, to add a paragraph at the end of the document and fill it with text without having to move the cursor around and simulate typing, simply do the following:

objWdDoc.Paragraphs(objWdDoc.Paragraphs.Count).Range.Text="Here goes the text that you want to put in the paragraph."

You can also improve on the speed if you have many lines of code that works with the same object by using a With structure. As an example, instead of


you could write

With objWdDoc.Paragraphs(objWdDoc.Paragraphs.Count).Range
End With

The difference is negligible if you have only a few lines, but the more dots you have in the reference to an object and the more properties and methods of an object that you use, specially in a loop, the more you gain from using With. You might have seen it in code generated by the macro editor.

Author Comment

ID: 40327578
Hi James,

Thanks again for your information.

I'm implementing your advices now. One conclusion I can draw is that it will be a lot of work to replace all the code I am using now and to achieve a good result.

If I use
         Set myTable = objWdDoc.Tables.Add(Range:=myRange, NuwRows:=4, NumCols:=3)
then I have to set myRange to a value. What is a good way to set myRange not using Selection or ActiveWindow?
LVL 40
ID: 40328229
If you know beforehand where you will need to insert the table, you can manually prepare the document with a bookmark at the position where you want to insert the table, and use that bookmark as your range:

 Set myTable = objWdDoc.Tables.Add(Range:=Bookmarks("YourBookmark").Range, NuwRows:=4, NumCols:=3)

Author Comment

ID: 40330099
Hi James,

After implementing your responses I come more and more to the conclusion that changing my code on these points is not enough and a complete adaptation of the whole concept will be needed! So I think we first need to ask ourselves whether we want this.

Therefore I will close this question for now. If other questions come up later, I will add a new post.

Thanks for your help!

Featured Post

Secure Your Active Directory - April 20, 2017

Active Directory plays a critical role in your company’s IT infrastructure and keeping it secure in today’s hacker-infested world is a must.
Microsoft published 300+ pages of guidance, but who has the time, money, and resources to implement? Register now to find an easier way.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
has12 challenge 13 77
sumDigits  challenge 7 140
Convert GUI app into console app for Win32 Env 5 125
What are the big features of MVC5? 4 95
A theme is a collection of property settings that allow you to define the look of pages and controls, and then apply the look consistently across pages in an application. Themes can be made up of a set of elements: skins, style sheets, images, and o…
The Fluent Interface Design Pattern You can use the Fluent Interface ( design pattern to make your PHP code easier to read and maintain.  "Fluent Interface" is an object-oriented design pattern that r…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA.…

756 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question