Need help with ActiveDocument

M

MarieJ

Hi,
I have a very complex template with 10 user forms that collects various
information and inserts information into the Word document in various places
and ways. The person requesting this template wants users to be able to work
on other documents in the middle of the sequence of user forms because it
takes alot of time to fill out the forms and proceed to the end of the
complete template. What is happening is occasionally a user will switch over
to another Word document screen and, for example, create a new document, and
type something into the new document. Then when they switch back to the user
form and fill out some information and click Next to process that information
and move to the next form, Word is thinking the new document they created is
the ActiveDocument instead of the original document created based on the
template, and errors appear such as unable to find a bookmark, etc. What's
the best way for me to prevent this but not restrict the template so users
can still work on other documents? Is there a way to capture what the
ActiveDocument value is when the document is created from the template, and
then whenever the command button is clicked, check what the ActiveDocument
is, and if it isn't the right one, switch to the right one?

I hope I explained that clearly enough.
TIA MarieJ
 
B

Benjamino5

MarieJ,

If you create a variable for the document you want to keep track of, you can
then allow the user to switch around as much as possible without your code
losing track of that document.

Here's an example:

Sub MyDocument
' create variable to store your document
dim myDoc as Document
' make sure the current Active Document is
' the one you want to use, then
Set myDoc=ActiveDocument
' now the rest of your code can refer to myDoc
' instead of ActiveDocument

End Sub
 
B

Benjamino5

Forgot to mention: if you write

myDoc.Activate


then myDoc will become the ActiveDocument again.
 
M

MarieJ

Great! Where do I put that procedure, though, so it will keep that variable
throughout all the user forms, etc.

I do appreciate it! Marie
 
B

Benjamino5

Marie,

I hope the MVPs weigh in here with the best solution, because I'm not sure
what's really the most elegant or correct. But here's a technique that will
work:

1) Create a global variable, which is available to all your code. To do
this, put this statement at the top of the first module that runs:

Public aDoc as Document

(Obviously "aDoc" could be "myDoc" or any other name you want.)

2) Make sure the Sub that set aDoc to the right document runs before you
need to refer to aDoc.

3) Replace all references to ActiveDocument everywhere in your code with
references to aDoc.

4) If you're using the Selection object or making other assumptions about
the ActiveDocument, watch out for errors. You may need to rewrite little
pieces. For example, writing "Selection.Range..." will capture whatever the
current activedocument's selection is, NOT what aDoc's selection/range is.

Another approach that would avoid having to use a Public statement would be
to simply pass "aDoc" as an argument to every Sub or Function throughout your
code, but you still need to watch out for problems with the Selection object,
etc.

Good luck!

Ben
 
J

Jonathan West

MarieJ said:
Great! Where do I put that procedure, though, so it will keep that
variable
throughout all the user forms, etc.

I do appreciate it! Marie

I'm not usually a fan of using global variables, but this is a case where
they are useful

Before the first Sub of a module, add this line

Public myDoc as Document

In the macro which you run, from which the UserForms are called, make one of
the first lines this

Set myDoc = ActiveDocument

at the end of the macro, include this line

Set myDoc = Nothing

Now, in routines or userforms which you call from the initial macro,
wherever you used ActiveDocument, use myDoc instead.
 
M

MarieJ

OK, I think you need to save me from myself. lol

I can't get this to work. I don't have a central macro that runs all the
user forms. In the Private Sub Document_New(), I load the first form. The
"Next" command button on the first form does what it needs to do and then
unloads the first form, and shows the second form, and on and on through all
11 forms. I have tried all kinds of combinations of what you and Benjamino
wrote, and still lose the value of the myDoc variable as I switch between
forms. I put Public myDoc as Document in the General Declarations section of
an autoexec module, and in the Private Sub UserForm_Activate() procedure
entered Set myDoc = ActiveDocument; I tried all kinds of other combinations.
So knowing how my code works, is there a way I can still use that global
variable throughout, instead of having to rewrite the whole thing?

Thanks again! MarieJ
 
J

Jean-Guy Marcil

MarieJ said:
OK, I think you need to save me from myself. lol

I can't get this to work. I don't have a central macro that runs all the
user forms. In the Private Sub Document_New(), I load the first form. The
"Next" command button on the first form does what it needs to do and then
unloads the first form, and shows the second form, and on and on through all
11 forms. I have tried all kinds of combinations of what you and Benjamino
wrote, and still lose the value of the myDoc variable as I switch between
forms. I put Public myDoc as Document in the General Declarations section of
an autoexec module, and in the Private Sub UserForm_Activate() procedure
entered Set myDoc = ActiveDocument; I tried all kinds of other combinations.
So knowing how my code works, is there a way I can still use that global
variable throughout, instead of having to rewrite the whole thing?

Thanks again! MarieJ

I am a bit confused.... If the first userform has a "Next" button that calls
the next userform and so on, then how can the user regain control of the Word
environment before they get to the end? Are your userfom modeless (I.e. users
can interact with the document while the userform is displayed)?
If so, it means that all your code is self contained in each userfrom.
In such a case, the first userfrom should declare a document object as was
suggested in other posts, then when you use the "Next" button, you pass the
doc object as a reference, for example:

(In the ThisDocument module)
Option Explicit

Private Sub Document_New()

Dim ufFirst As UserForm1

Set ufFirst = New UserForm1

ufFirst.Show False

End Sub



Sub SecondForm(doc As Document)

Dim ufSecond As UserForm2

Set ufSecond = New UserForm2

ufSecond.Show False
Set ufSecond.docMain = doc

End Sub



(The code behind the first userform)
Option Explicit

Public docMain As Document

Private Sub CommandButton1_Click()

Me.Hide

'Do stuff in the doc, e.g.:
docMain.Range.Paragraphs(1).Range.Text = Me.TextBox1.Text & vbCrLf

ThisDocument.SecondForm docMain

Unload Me


End Sub

Private Sub UserForm_Initialize()

Set docMain = ActiveDocument

End Sub




(The code behind the second userform)
Option Explicit

Public docMain As Document

Private Sub CommandButton1_Click()

Me.Hide

'Do stuff in the doc, e.g.:
MsgBox docMain.Range.Paragraphs(1).Range.Text

Unload Me

ThisDocument.ThirdForm docMain

End Sub

etc.
 
M

MarieJ

Users can't interact with the document the forms are used with, but they can
click on other documents on their taskbar and access those, and create new
documents from there, etc. and that's what is causing the problem. I did at
one point try to make it modal so they couldn't do that, but was requested to
make it modeless so if interrupted, users can work on other things while this
document is being created.

I'll try your code. Thanks so much for the reply!

MarieJ
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top