Solved

Help with OLE and multiple Word documents

Posted on 2014-07-29
8
227 Views
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").Activate
          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
or
          Set myTable = ActiveDocument.Tables.Add(Range:=myRange,…………….
or
          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!
0
Comment
Question by:Pirie
  • 4
  • 3
8 Comments
 
LVL 8

Expert Comment

by:jawa29
ID: 40226872
Hi

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
0
 
LVL 40

Accepted Solution

by:
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:

objWdDoc.Tables.Add(Range:=myRange,…………….

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.
0
 

Author Comment

by:Pirie
ID: 40228518
Thanks for your comments! I go look at your advices and then come up with my response later.
0
 

Author Comment

by:Pirie
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?
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
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.Add
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

objWdDoc.Paragraphs(objWdDoc.Paragraphs.Count).Range.Text="Toto"
objWdDoc.Paragraphs(objWdDoc.Paragraphs.Count).Range.Font.Bold=True
objWdDoc.Paragraphs(objWdDoc.Paragraphs.Count).Range.Font.Bold=Italic

you could write

With objWdDoc.Paragraphs(objWdDoc.Paragraphs.Count).Range
     .Text="Toto"
     .Font.Bold=True
     .Font.Bold=Italic
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.
0
 

Author Comment

by:Pirie
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?
0
 
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)
0
 

Author Comment

by:Pirie
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!
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
"Disruption" is the most feared word for C-level executives these days. They agonize over their industry being disturbed by another player - most likely by startups.
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.

743 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now