PDA

View Full Version : Solved: Return focus back to doc after executing VBA code from within a modeless userform?



almeck
04-27-2009, 01:25 PM
I have a userform that I show modeless with, among other things, a button that applies bold to the current selection/insertion point. The hoped for process was:

1) select text to be bolded in the document
2) click on the "bold" button in the modeless user form
3) and have focus return to the selected text/insertion point in the document.

In other words, I want the bold button in the userform to behave in just the same fashion as the Bold button in the Ribbon.

However, after clicking on the bold button in the userform, focus remains in the userform, and I have to click back in the document to return focus there (to continue typing, whatever). So, my question is: how do I ”automatically” return focus back to the doc after executing VBA code from within a modeless userform?

Note: I’m just using my “custom” bold button as a simple example to explain the problem, there are other, more complex functions I want to execute from the userform, but my bold button exemplifies the issue.

In Word 2003, I would have simply created a command button to do these functions, but, alas, I see that is no longer possible in Word 2007.

Charlize
04-27-2009, 01:44 PM
Put this code in a module. Execute the create_menu. There will be a new menu option on top off your screen (if your menu is on top) right from the menu for the developers. It's not exactly the same but if works fine by me (Still haven't found time to study the new ribbon.).

Sub Create_Menu()
Dim MyBar As CommandBar
Dim MyButton As CommandBarButton
Delete_Menu
'name of your floating bar
Set MyBar = CommandBars.Add(Name:="Two Buttons", _
Position:=msoBarFloating, Temporary:=True)
With MyBar
.Top = 50
.Left = 650
'the two buttons that you want
Set MyButton = .Controls.Add(Type:=msoControlButton)
With MyButton
.Caption = "Bold on/off"
.Style = msoButtonCaption
.BeginGroup = False
'here you refer to the code to execute when you select this option
'put code to execute in module (not a private one)
.OnAction = "Macro_Bold"
End With
Set MyButton = .Controls.Add(Type:=msoControlButton)
With MyButton
.Caption = "Italic on/off"
.Style = msoButtonCaption
.BeginGroup = False
.OnAction = "Macro_Italic"
End With
.Width = 150
.Visible = True
End With
End Sub
Sub Delete_Menu()
On Error Resume Next
'remove menu when active before activating again.
CommandBars("Two Buttons").Delete
On Error GoTo 0
End Sub
Sub Macro_Italic()
Selection.Font.italic = wdToggle
End Sub
Sub Macro_Bold()
Selection.Font.Bold = wdToggle
End SubCharlize

almeck
04-27-2009, 02:42 PM
Thnaks, Charlize, I'll give this a try.

Still hoping for a way to return focus to the doc, though.

fumei
04-28-2009, 10:07 AM
The real question is:

After performing one action (say your bolding), do you want to keep the userform alive?

If not - this would be a single action - then simply unload the userform.

If you DO want to keep the userform alive, then one way would be:

1. a shortcut key to .Show the userform (start it up).

2. the procedure that does the action ends with a .Hide of the userform. This will put focus back to the document.

3. any time you want the userform back, just use the shortcut key again.

Demo attached.

Make a selection in the document.

Press Alt-h (the shortcut combination). This displays the userform.

Click the "Do Action" button. This bolds the selection AND hides the userform - focus is in the document.

Do whatever you want in the document. When you want the userform again, press Alt-h.

When you are actually done, then click the Exit button on the userform which truly unloads it.

almeck
04-28-2009, 10:10 AM
After about a day of net research, I did find a solution that allows me to return focus to the doc from my modeless form. It involves a bit of a kludge, but still seems acceptable.

1) Create a “unique” title for the Application (the Word doc). This is done in case you have other instances of Word running:

Public tempUniqueAppTitle As String 'temporary Title for app (Word) to distinguish it from other possibly open Word windows

2) In the form initialization, init this title to something “unique”. In my case, I appended the path/doc name to the existing title:

tempUniqueAppTitle = wordTitle & "_" & ActiveDocument.Path & Application.PathSeparator & _
ActiveDocument.Name 'append doc path/name to title to create (hopefully) unique title (in case other instances of word are running)
Application.Caption = tempUniqueAppTitle 'use this unique title for the duration of the form

Of course, if you have more than one instance of Word open on this doc, you could have problems (so, don’t do that)

3) Whenever you want to return focus to the doc/app from the form, activate the (now renamed) app:


AppActivate tempUniqueAppTitle 'return focus to the doc


The Insertion point and selection, if any, should be as they were before you clicked on a button in the form (except that, of course, actions taken within the form will have been executed, e.g., bolding in my example case discussed here).

4) When the form terminates, return the app tile to normal:


Private Sub UserForm_Terminate()
' set app title back to normal
Application.Caption = “Microsoft Word”
End Sub

fumei
04-28-2009, 10:58 AM
Mmmm, that is a bit of a kludge, but hey, if it works for you...

wfrancis
01-04-2011, 12:02 PM
Almeck - you are a genius! I have been searching for hours for a solution to this problem, and if you are not worried about other instances of Word running, the solution is 2 words - Application.activate! I thank you! I bet this is the most delayed reply you have received, after 2 years!


After about a day of net research, I did find a solution that allows me to return focus to the doc from my modeless form. It involves a bit of a kludge, but still seems acceptable.

1) Create a “unique” title for the Application (the Word doc). This is done in case you have other instances of Word running:

Public tempUniqueAppTitle As String 'temporary Title for app (Word) to distinguish it from other possibly open Word windows

2) In the form initialization, init this title to something “unique”. In my case, I appended the path/doc name to the existing title:

tempUniqueAppTitle = wordTitle & "_" & ActiveDocument.Path & Application.PathSeparator & _
ActiveDocument.Name 'append doc path/name to title to create (hopefully) unique title (in case other instances of word are running)
Application.Caption = tempUniqueAppTitle 'use this unique title for the duration of the form

Of course, if you have more than one instance of Word open on this doc, you could have problems (so, don’t do that)

3) Whenever you want to return focus to the doc/app from the form, activate the (now renamed) app:


AppActivate tempUniqueAppTitle 'return focus to the doc


The Insertion point and selection, if any, should be as they were before you clicked on a button in the form (except that, of course, actions taken within the form will have been executed, e.g., bolding in my example case discussed here).

4) When the form terminates, return the app tile to normal:


Private Sub UserForm_Terminate()
' set app title back to normal
Application.Caption = “Microsoft Word”
End Sub