MS Office Forum / Word / Programming / August 2007
Avoiding ActiveDocument
|
|
Thread rating:  |
Beeawwb - 20 Aug 2007 08:30 GMT Hi All,
I've been reading various posts mentioning avoiding using ActiveDocument, eg Dim oDoc as Document Set oDoc = Documents.Add(Filename:="NNN")
What I'm trying to get my head around is, this assumes that the document has been saved, doesn't it? What if you're creating a brand new document for the first time, or something like that?
I only ask because here at work, we load templates from our Intranet (e.g. https://.../Domino/library/StandardsLib.nsf/0/A53404DB0ECD2558CA256DC700098F69/$FILE/HADVICE+v2003.dot), which always open as read only documents, and they never actually get saved (we edit them, and then import them into our imaging system which does the saves them in its native format). When I'm running macros to format these documents before they get imported, I have to use oDoc.ActiveDocument to say which document I'm formatting.
Is there any other way of doing this, or am I correct in assuming that I must reference the ActiveDocument, and then set oDoc as nothing on exiting the macro.
Thanks for your help,
-Bob
Shauna Kelly - 20 Aug 2007 09:26 GMT Hi Bob
Yes, avoiding ActiveDocument is generally a good idea. The reason is that Word is prone to having creative ideas about what constitutes the "Active" document. Grabbing a reference to the document you know is the one you want to work with, and using that reference, ensures that you are dealing with the right document. It also helps prevent mistakes in your code when you have more than one document open, and it makes the code easier to read.
With the Documents collection, in general you *Open* an existing document, but you *Add* a new one.
To open an existing document you can do this:
dim oDoc as Document set oDoc = Documents.Open(FileName:="blabla.doc" ) There are a dozen or so other parameters to the .Open method. Look up VBA help for full details.
To create a new document you use the .Add method of the .Documents collection, like this:
dim oDoc as Document set oDoc = Documents.Add(Template:="asdf.dot") There are several other parameters of the .Add method, also described in the VBA help.
You can omit the Template parameter if you want to base your new document on Normal.dot. But just for the record, this set oDoc = Documents.Add oDoc.AttachedTemplate = "mytemplate.dot" is *not* the same as this set oDoc = Documents.Add(Template:="mytemplate.dot")
As an example of how you might use all this, consider a case where you wanted to create a new document and copy into it the first paragraph of text from an existing document. You could do something like this:
Dim oExistingDoc As Document Dim oNewDoc As Document
Set oExistingDoc = Documents.Open(FileName:="test1.doc", _ ReadOnly:=True, AddToRecentFiles:=False)
Set oNewDoc = Documents.Add(Template:="mytemplate.dot")
oNewDoc.Paragraphs(1).Range.FormattedText = _ oExistingDoc.Paragraphs(1).Range
oExistingDoc.Close SaveChanges:=False
The only time I ever use ActiveDocument is where I have a tool that is initiated by the user, and I need to know what document the user has open and wants to apply the tool to. In that case, I use set oDoc = ActiveDocument once, and thereafter work with oDoc.
Hope this helps.
Shauna Kelly. Microsoft MVP. http://www.shaunakelly.com/word
> Hi All, > [quoted text clipped - 26 lines] > > -Bob Jay Freedman - 20 Aug 2007 14:50 GMT Reading between the lines -- please correct me if I'm wrong about this -- I think Bob's setup is that he is indeed *opening* the template, which is marked read-only; modifying the in-memory copy of the template, and passing that in-memory copy to the imaging system to be saved. This is a seriously bad idea.
Bob, the whole intention of templates in Word is that you *add* a document *based on* a template, as shown in Shauna's example of the Documents.Add method. The parameter you pass to the Add method is the name of the template to use, but that template isn't open for modification -- all changes go into the document. That document is the thing whose identity is stored in the oNewDoc variable. After that, it doesn't matter whether oNewDoc is the "active" document or some other document is "active"; any changes that are made to oNewDoc will go into the correct place.
 Signature Regards, Jay Freedman Microsoft Word MVP FAQ: http://word.mvps.org Email cannot be acknowledged; please post all follow-ups to the newsgroup so all may benefit.
> Hi Bob > [quoted text clipped - 88 lines] >> >> -Bob Beeawwb - 21 Aug 2007 01:52 GMT Hi again everyone, and thanks for your detailed responses. I think I may be confusing things by not really understanding what I'm asking either, and I'm not really sure how to explain it.
To clarify, based on Jay's response, I'll take you through what happens, and how the system here works.
We have a number of Word templates, that are our "standard letters". When somebody wants to write a letter, they open these .dot files, from our Intranet. This is because they are used around the country, so our intranet webpage is the only central location that *everybody* has access to. These .dot files contain their own macros (written by our head office) to delete blocks of text (e.g. "I don't need to say that, double click the "Delete" button and that paragraph is removed). The files are read only, and protected for legal reasons (so you can't just add any old text you want).
There are about 50 different letters to choose from. All these letters can be printed on 4 different letterheads. The problem is, when head office designed these templates, they set the default printer tray to tray 3. Our staff have great difficulty changing the printer tray to other letterhead (eg Tray 2, or 4) manually, as the templates are so rigid. So I took it upon myself to design a macro to change printer trays.
What happens is, I call a form which has 4 buttons. These buttons are labelled based on which printer is being used (there are 4 to choose from, all loaded differently). Staff click which letterhead they want (Company 1, company 2, etc), and then are asked to confirm various print options, and finally to print the document.
I was having a lot of difficulty recently with unqualified code, but I've finally sorted this out, and the macro is working fine referencing ActiveDocument. The question arises because with (potentially) 100 staff using this macro, and 50 documents to choose from, I will never know which document has been opened, and hence Documents.Add and Documents.Open won't work.
Essentially, Jay is correct. We open a document, edit the in memory copy, and then our imaging system imports the "in memory" document to itself. It's a dumb way of doing things, I know. Unfortunately I didn't design the system, I just use it and mop up the problems it creates. :P
Sorry for the extremely long winded post, and thanks again for your help. Thanks to this newsgroup my understanding of how Word / Office / VBA works is coming a long way!
-Bob
> Reading between the lines -- please correct me if I'm wrong about this -- I > think Bob's setup is that he is indeed *opening* the template, which is [quoted text clipped - 103 lines] > >> > >> -Bob Russ - 26 Aug 2007 04:23 GMT Bob, See below.
> Hi again everyone, and thanks for your detailed responses. I think I may be > confusing things by not really understanding what I'm asking either, and I'm [quoted text clipped - 31 lines] > using this macro, and 50 documents to choose from, I will never know which > document has been opened, and hence
>>>Documents.Add and Documents.Open won't work. Your print routine would normally assume that the user would want to print the currently active document, unless you use some means to query for which document. I didn't want you to think that you only had an opportunity to create a doc object reference when a file is first opened or added. Anytime you think you may want to reference the current active document later among other opened documents, you could create the reference. Dim myDoc as Word.Document Set myDoc = ActiveDocument
If only one document is opened, then no reference other than the object called ActiveDocument is needed.
> Essentially, Jay is correct. We open a document, edit the in memory copy, > and then our imaging system imports the "in memory" document to itself. It's [quoted text clipped - 115 lines] >>>> >>>> -Bob
 Signature Russ
drsmN0SPAMikleAThotmailD0Tcom.INVALID
Russ - 20 Aug 2007 09:52 GMT Bob, Dim oMyFirstDoc as Word.Document Dim oMySecondDoc as Word.Document
Set oMyFirstDoc = Documents.Add... Starts a new document (it may be based on a template (normal.dot by default)) Set oMySecondDoc = Documents.Open... Opens a saved document See 'working with documents' in Word VBA help by typing in 'document'.
If you have more than one document available in Word, then setting each of them to a document object name makes it less likely to be working on the wrong document with activedocument and by definition the document doesn't have to be active to be worked on, when referred to as a document object name. It doesn't matter whether they are already saved or not. You can refer to specific document when they have been set to a document object. Setting them to Nothing at the end of a subroutine, when they are not needed anymore, frees up memory for other subroutines to use.
Or you can refer to them by filename.. Documents("Document1").Activate.
Your oDoc.ActiveDocument that you mentioned must have oDoc set to an instance of the Word application object because that is the parent object of activedocument object or property.
> Hi All, > [quoted text clipped - 22 lines] > > -Bob
 Signature Russ
drsmN0SPAMikleAThotmailD0Tcom.INVALID
|
|
|