Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How do you get document focus in Word 2000? 1

Status
Not open for further replies.

tolan

IS-IT--Management
Jun 9, 2001
15
GB
Hi, I've been tearing my hair out of this and I just can't get it right (bit of a VBA newbie!).

I've created a form for a word template which allows the user to type/select an address and then place this data onto the word template. Ok I feel I've done most of the hard work, I can access and select addresses from the address book and it works well. The problem I have is that when the new document is created I can't get the active (focus?) document on screen to be my new template file .... Word just remains on the blank 'document 1'.

I've looked at all the following options

Windows("document2").activate
activedocument.activate and other variations.

I'd be very grateful of any assistance on how to get my new document on the screen!

Here's the code that works (without all my attempts to get away from the evil blank document 1!!!)


'Get username from Address Book
Private Sub Cmdaddbook_Click()

Do

sFirstname = Application.GetAddress _
(AddressProperties:=&quot;<PR_DISPLAY_NAME>&quot;, _
Displayselectdialog:=1)

Loop Until sFirstname <> &quot;&quot;

txtTo = sFirstname

Dim sUsername As String
sUsername = Application.UserName
txtfrom = sUsername

End Sub

' This section opens the template file and dumps the variables in replace of the bookmarks
Private Sub cmdok_Click()
Dim sUserTemplates As String

'Path for User Templates
sUserTemplates = Options.DefaultFilePath(wdUserTemplatesPath)

'Create memo Coversheet
Set objNewDoc = Documents.Add(sUserTemplates & &quot;\memTemplate.doc&quot;)

Dim rng As Range

Set rng = ActiveDocument.Bookmarks(&quot;To&quot;).Range
rng.InsertAfter txtTo

Set rng = ActiveDocument.Bookmarks(&quot;From&quot;).Range
rng.InsertAfter txtfrom

Set rng = ActiveDocument.Bookmarks(&quot;Subject&quot;).Range
rng.InsertAfter txtSubject

'ActiveDocument.SaveAs FileName:=&quot;c:\temp\letters\Memo - &quot; & txtTo & &quot; - &quot; & txtSubject & &quot; - &quot; & Format(Now(), &quot;dd-mm-yyyy&quot;) & &quot; &quot; & Format(Now(), &quot;h.m.s&quot;) & &quot;.doc&quot;
ActiveDocument.Activate

Selection.GoTo What:=wdGoToBookmark, name:=&quot;Content&quot;

Unload Me

End Sub
 
I created a macro to build a style sheet document listing the styles in the current template, and I was able to bring the new document to the front using the following at the end of the macro:
' Bring the style sheet to the front and position to the top
docStyleSheet.Activate
docStyleSheet.Bookmarks(&quot;\StartOfDoc&quot;).Select
This isn't very different from what you have done, so I'm not sure why yours doesn't work.

Have you tried closing Document1? That, at the very least, would force your new document to get the focus. Rick Sprague
 
Thanks for the tip, unfortunately it hasn't resolved my glitch. The trouble with closing document1 is that if the user begins to open a number of documents then the newly created document needs to be the active/in focus document (rather than the last document being closed).

The other thing I've noticed is that when the macro has finished and the form unloaded, if I click anywhere on the right hand scroll bar of Word 2000 the document is displayed (rather than selecting the document from the bottom toolbar).

It's as if the document is there but the screen hasn't refreshed.

Grateful for any other ideas or suggestions!

Tolan

 
Hmm. Try calling the Application.ScreenRefresh method at the end of the macro. Rick Sprague
 
Gave the Application.ScreenRefresh a shot, but still without success (sob, sob). Any other ideas?

Grateful for your assistance (he says trying to keep your interest! :) )

Tolan
 
I seldom do this, but I invite you to send me a copy of your template via email, to handlbar @ broughton-sys.com (leave out the spaces; I put them in to thwart web crawlers that search for email addresses). If possible, I'll try it on my system and see if I duplicate the symptoms. Rick Sprague
 
I got your email and tested your macro, and I'm pretty sure I know what the problem is. Your macro opens your menu userform, which opens the fax info userform. Your code that builds the fax coversheet occurs within the cmdOk_Click event within the fax info userform. Within that, you're doing &quot;objNewDoc.Activate&quot;--but Word can't activate it, because you have modal UserForms open!

I changed both forms to ShowModal = False, and the coversheet popped to the top, as desired.

Modal forms retain the focus, yielding it only to other Windows applications or to other forms they open (which are then forced to be modal as well). This creates a stack of modal windows which can only be closed in the reverse order they were opened. Windows won't allow you to bring another window on top of a modal one, because you'd be deadlocked; the window on top can't respond to user input (because of the modality), but the modal window can't be reached (because it's covered by the first window). That would leave you with no choice but to kill the application.

True, Microsoft could have allowed you to bring another window to the top, if you would still be able to move or minimize it. But the user could easily not realize that the application was modal at the time, and start clicking all over the top (non-modal) window, getting beeps left and right. If the top window completely covers the modal window, which is often the case because modal windows tend to be small, there would be absolutely no visual feedback of what the user needed to do to get unstuck. So Microsoft decided not to allow reordering windows on top of modal windows. (How would you like to be inundated with confused users who can't tell you they have a modal window open, because they can't even see it?)

In your case, the original document window which launched the menu is at the bottom of the modality chain, so it kind of inherits this on-top privilege. Thus your new document window is stuck at the bottom.

You have two choices: (1) make the userforms non-modal, as I did, or (2) move your .Activate call so that it executes after all the modal forms are closed or hidden.

To elaborate on the second option, there are several solutions. One solution would be to create a public Document variable in a standard module. This would be used to pass the newly created document back to the initial macro (insfaxtmplate, which opens the menu). The initial macro should set this to Nothing before it opens the menu. The fax info userform should set it to the document it creates, if it creates one. When the fax info form returns to the menu, and the menu returns to the initial macro, the initial macro tests the public Document variable. If it's not Nothing, the initial macro .Activates it.

That still means the document won't come to the top until you close the forms. Because your code is still in development, it's not clear to me whether you intend them to close right away.

Here's a general approach that will avoid this kind of problem. If you intend a userform to stay open, it should be non-modal. Menus are usually a good example (but in the case of your menu, it's not, because it's not really a menu, it's just the first in a series of forms). If you intend a userform to just collect data and then go away, it should be modal, but it should be very lean on code. In particular, it shouldn't do any real work. Its OK and Cancel buttons should set an indicator of which was chosen, and should then hide (not close) the form; the form or macro which opened it should be responsible for extracting and using the data in the form's controls, and should then unload the hidden form. (This is the customary Windows way of using a dialog box.)

Applying this approach to your application, it would work like this:
---If you choose to leave both forms modal---
Toolbar macro:
Dim frm1 As frmmenu, frm2 As UserForm1
Dim fax As Boolean, letter As Boolean
Dim memo As Boolean, attend As Boolean
Dim toName As String, toCompany As String

Set frm1 = New frmmenu
Load frm1
frm1.Show
If frm1.Canceled Then Exit Sub
fax = frm1.Optionfax
letter = frm1.Optionletter
memo = frm1.OptionMemo
attend = frm1.OptionAttend
Unload frm1
If fax Then
Set frm2 = New UserForm1
Load frm2
' If you wanted to pre-fill some fields in
' in UserForm1, you could do that like this:
frm2.TxtRe = ActiveDocument.Title
frm2.Show
If frm2.Canceled Then Exit Sub
toName = frm2.txtToName
toCompany = frm2.txtToCompany
' other fields omitted for brevity
Unload frm2
' BuildFaxCover() is defined somewhere else. It
' builds the document and activates it.
Call BuildFaxCover(toName, toCompany, ...)
ElseIf letter Then
...etc. for Memo and Attend options
End If
Form &quot;frmmenu&quot;
Public Canceled As Boolean
Private Sub cmdOK_Click
Canceled = False
Me.Hide
End Sub
Private Sub cmdCancel_Click
Canceled = True
Me.Hide
End Sub
(You might have additional event procedures to enable/
disable the OK button, validate choices, etc.)
Form &quot;UserForm1&quot;:
Public Canceled As Boolean
Private Sub cmdOK_Click
Canceled = False
Me.Hide
End Sub
Private Sub cmdCancel_Click
Canceled = True
Me.Hide
End Sub
(Again, you might have additional event procedures.)

Do you see how this works? The insfaxtmplate macro really drives the whole process. The modal userforms are treated like simple subroutines that collect some data and return it. This structure keeps your call stack shallow (which minimizes resource usage). It also keeps all your application-specific code in one module, which is easier to maintain. (You could still break it into multiple modules, one for each document type, if you like that better. The BuildFaxCover procedure could be in a module of its own, for example.)

Well, that should give you some options. The easiest way, given what you've already written, would be to pass the Document variable back to the insfaxtmplate macro and let it activate the new document. But the 'right' way, in the sense of writing the most robust and maintainable code, would be to move the application-specific code out of the modal forms. I think in the long run you'd have fewer problems that way. Rick Sprague
 
Rick,

Your a star, thanks for your help and guidance on this, truly appreciated. I think I'll become comfortable with idea number 1, then once that's working and I become more confident, redesign to the efficient option 2.

Thanks again.

Tolan
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top