Link to home
Start Free TrialLog in
Avatar of brenns
brenns

asked on

SetFocus for built-in Outlook mail form with VBA

As part of a Send and File mail message routine I've implemented using a custom toolbar button in Outlook XP, I attempt to invoke the ActiveInspector.CommandBars("Tools").Controls("Spelling...").Execute method before performing an ActiveInspector.CurrentItem.Send method.  Unfortunately, the Tools/Spelling menu item is inactive (and thus fails when called by VBA code) if the focus of the built-in Outlook mail form is not on the Subject or Body form controls (i.e. if it's instead in the From, To, CC fields).  So, prior to invoking the "Spelling..." menu item, I first need to set the focus of the form to the Subject or Body form control.

This sounds simple enough, but it is not.  Let me tell you a few things that DO NOT work:

1) ActiveInspector.CurrentItem.Body.SetFocus - this does NOT work because the MailItem.Body property is NOT the same as the body form control, and SetFocus will not work
2) ActiveInspector.ModifiedFormPages("Message").Controls("Message").SetFocus - this does NOT work because the ModifiedFormPages collection is empty when you are using the default/built-in Outlook forms.  This option would work if I was using custom forms, but I am not.
3) Prompting the user to place the cursor in the Subject/Body fields if it's not there - this will NOT work as a solution because the customer wants a TRUE solution (nice try though)

So, here's the question, for which an answer would be enormously appreciated

1) How can I set the focus of the default/built-in (NOT custom) Outlook mail message form to the Subject or Body fields using Outlook VBA from the VbaProject.OTM project?

Thanks!
-------------------------------------------------------
P.S.  The reason I'm attempting to use the menus to invoke the spell checker is that I could not figure out a way to invoke it any other way.  There does not appear (in the research I've done at least) to be a way perform the .CheckSpelling method in Outlook like you can in Word or Excel.  If you can tell me how to invoke the spell checker without the menu, which bypasses the SetFocus problem I face, you get the points, a blue ribbon, and a free pizza.
Avatar of brenns
brenns

ASKER

I should also state that another possible solution is to call Microsoft Word externally, paste the MailItem.Body text into a blank document, perform a .checkspelling, and then paste the text BACK into Outlook.  This is kinda messy and not particularly pleasant since I should be able to simply do this within Outlook (you would think).
Avatar of brenns

ASKER

vinnyd79, thanks, but that's the same solution that I described in my first follow-up comment.  Although that solution works, it wont work in this instance because:

a) too slow
b) confusing for the end user
c) ugly

But, as we both know, it does work, so thanks for the comment, even though I had anticipated that response.
ASKER CERTIFIED SOLUTION
Avatar of Diveblue
Diveblue

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of brenns

ASKER

Scott,

Good thought, and yes I have tried that.  The problem is that SendKeys appears (and I could be wrong here) to just be sending keystrokes into never-never-land.  It's as if the code needs to first activate the form somehow before SendKeys knows where to place the keystrokes.  I've tried having SendKeys send vbTab and just plain old text.  If I place my cursor in the "To" field before executing the SendKeys code, I can't get ANY text to be placed in that field, much less tabs.  The problem might stem from the fact that the code for the "Send and File" button is completely independent of the built-in form, but I don't really know.  I just know it doesn't appear to work.

Although I (me, personally) can't get this to work, it's possible that it's a workable solution.  It's still not as good as simply invoking a checkspelling or manually setting the form's focus, but it's more doable than the external Word spell check.

On a related note, I've also tried to use something like Selection.TypeText vbTab (which is how Word records a Tab press in a Macro) to no avail.

If you have some ideas how I can pursue this Scott, I'd be happy to give them a shot.
Avatar of brenns

ASKER

Scott,

Let me add something about SendKeys that I didn't mention before.  If I "manually" execute a macro (using Tools/Macro/Macros... and then selecting my public sub) that houses the line "SendKeys vbTab", I can shift the focus of the form to the next field.  So I know, in theory, SendKeys does work in my scenario.

Hold the presses!

I did in fact figure out how to get the SendKeys procedure to work from my code.  I'm such a dumb-ACK sometimes. If I do a "SendKeys vbTab, 1" and wait for the procedures to process the keypress before continuing (which is what the boolean wait is for in SendKeys string[, wait]), it actually performs the tab press.

Unfortunately, even after the tab keypress moves the cursor into the message body field, the Tools menu is not being updated.  Take a look at my loop below.  I tried adding in a DoEvents hoping that would allow the menu to update, but that doesn't work.  I have to manually break out of the loop with the loopcount variable because the commandbar execute keeps failing (which adds a bunch of tab to the message body).  After falling out of the loop, the final commandbar execute fails.

                On Error Resume Next
                loopcount = 0
                Do
                    Err.Clear
                    SendKeys vbTab, True
                    ActiveInspector.CommandBars("Tools").Controls("Spelling...").Execute
                    loopcount = loopcount + 1
                    DoEvents
                Loop Until Err.Number = 0 Or loopcount > 50
                On Error GoTo 0
                ActiveInspector.CommandBars("Tools").Controls("Spelling...").Execute

However, if after I run the code and it fails, I then manually select Tools/Spelling... or simply click my button again, it works.  We're getting close here.
Avatar of brenns

ASKER

Something new to report. ActiveInspector.CommandBars("Tools").Reset does the trick.  The following code now actually works for my testing.  

On Error Resume Next
loopcount = 0
Do
     Err.Clear
     SendKeys vbTab, True
     ActiveInspector.CommandBars("Tools").Reset
     ActiveInspector.CommandBars("Tools").Controls("Spelling...").Execute
     loopcount = loopcount + 1
Loop Until Err.Number = 0 Or loopcount > 50

This isn't the prettiest code, but it does actually work.  I've been trying to create a situation in which it doesn't work (i.e. setting focus on buttons first), but I can't.  So, Scott, unless someone can tell me how to actually invoke the checkspelling method within Outlook in the next day or so, this solution is "good enough".  And since your thought actually prompted me to take another look at why SendKeys was failing for me, the thanks will go to you.
Glad it worked. I don't do any outlook atomation myself, so I'm not intimate with It's behavior. That's why I gave you the "old school" suggestion.

scott
Brenn,

The solution is fairly simple.  

On Error Resume Next
loopcount = 0
Do
    Err.Clear
    SendKeys vbTab, True
    ActiveInspector.CommandBars("Tools").Reset
    ActiveInspector.CommandBars("Tools").Controls("Spelling...").Execute
    loopcount = loopcount + 1
Loop Until Err.Number = 0 Or loopcount > 50

I'll take the 500pts now.
nice try dj
Avatar of brenns

ASKER

Well, since we didn't get an honest to goodness .CheckSpelling solution, and Scott forced me to go back and look at my SendKeys attempt, thanks go to Scott.
thanks brenns!
Brenn,

I thought we were buddies? :-)