Group:  Microsoft Word ยป microsoft.public.word.vba.customization
Thread: Closing orphaned msgbox

Closing orphaned msgbox
Neil Humphries 11/17/2008 9:23:00 PM
If the user cancels or closes the userform while the cursor is in one of the
controls that I validate, the userform closes to reveal a msgbox generated by
the control validation routine which is triggered by the Exit event. How do I
programmatically close the msgbox before the userform Unloads? Or, how do I
keep the validation routine from triggering when the userform Unloads?
Re: Closing orphaned msgbox
"Doug Robbins - Word MVP" <dkr[ at ]REMOVECAPSmvps.org> 11/17/2008 10:25:04 PM
See the article "Intercept the Close button (X) in the title bar of a user
form" at:

http://www.word.mvps.org/FAQs/Userforms/InterceptCloseButton.htm

If the user clicking on a Cancel button on your form, you will need to
modify the code in the Click event of that button to deal with the issue.


--
Hope this helps.

Please reply to the newsgroup unless you wish to avail yourself of my
services on a paid consulting basis.

Doug Robbins - Word MVP

"Neil Humphries" <NeilHumphries[ at ]discussions.microsoft.com> wrote in message
news:4F524B24-752D-4E41-B43D-B60451524A58[ at ]microsoft.com...
[Quoted Text]
> If the user cancels or closes the userform while the cursor is in one of
> the
> controls that I validate, the userform closes to reveal a msgbox generated
> by
> the control validation routine which is triggered by the Exit event. How
> do I
> programmatically close the msgbox before the userform Unloads? Or, how do
> I
> keep the validation routine from triggering when the userform Unloads?


Re: Closing orphaned msgbox
"GordonBentleyMix via OfficeKB.com" <u44607[ at ]uwe> 11/17/2008 11:42:51 PM
Neil,

What's happening is that when you close your UserForm, the Exit event for the
last control that had focus is triggering even though the UserForm is no
longer visible. This is expected because when the UserForm closes the control
loses focus. Try adding the line

If Me.Visible = True

(along with the closing End If statement) around your validation code. This
should solve the problem.

Cheers!

Gordon

Neil Humphries wrote:
[Quoted Text]
>If the user cancels or closes the userform while the cursor is in one of the
>controls that I validate, the userform closes to reveal a msgbox generated by
>the control validation routine which is triggered by the Exit event. How do I
>programmatically close the msgbox before the userform Unloads? Or, how do I
>keep the validation routine from triggering when the userform Unloads?

--
Message posted via OfficeKB.com
http://www.officekb.com/Uwe/Forums.aspx/word-programming/200811/1

Re: Closing orphaned msgbox
Neil Humphries 11/18/2008 1:56:16 PM
Your suggestion worked wonderfully. I much prefer avoiding the problem rather
than resolving it after the fact.

Thanks

"GordonBentleyMix via OfficeKB.com" wrote:

[Quoted Text]
> Neil,
>
> What's happening is that when you close your UserForm, the Exit event for the
> last control that had focus is triggering even though the UserForm is no
> longer visible. This is expected because when the UserForm closes the control
> loses focus. Try adding the line
>
> If Me.Visible = True
>
> (along with the closing End If statement) around your validation code. This
> should solve the problem.
>
> Cheers!
>
> Gordon
>
> Neil Humphries wrote:
> >If the user cancels or closes the userform while the cursor is in one of the
> >controls that I validate, the userform closes to reveal a msgbox generated by
> >the control validation routine which is triggered by the Exit event. How do I
> >programmatically close the msgbox before the userform Unloads? Or, how do I
> >keep the validation routine from triggering when the userform Unloads?
>
> --
> Message posted via OfficeKB.com
> http://www.officekb.com/Uwe/Forums.aspx/word-programming/200811/1
>
>
Re: Closing orphaned msgbox
"GordonBentleyMix via OfficeKB.com" <u44607[ at ]uwe> 11/18/2008 8:57:05 PM
Neil,

If I may offer another tip: You might want to make your validation code
"modular" - something like this. (I'll explain the advantages in a minute.)

Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
If Me.Visible = True Then
Cancel = Not fcnValidateTextBox1
If Cancel = False Then FormatTextBox1
End If
End Sub

Private Function fcnValidateTextBox1() As Boolean
fcnValidateTextBox1 = True
If Len(TextBox1.Value) > 0 Then
If IsNumeric(TextBox1.Value) = False Then
MsgBox "The value in TextBox1 must be numeric.", vbCritical,
"TextBox1 Error"
fcnValidateTextBox1 = False
Exit Function
End If
End If
End Function

Private Sub FormatTextBox1()
If Len(TextBox1.Value) > 0 Then TextBox1.Value = Format(TextBox1.Value, "
$#,##0.00")
End Sub

In this approach I use a Boolean function to validate the value in the
TextBox and use the result of this function to set the Cancel argument of the
Exit event for the TextBox. (In my example above I want to make sure that the
value is a number so I can format it as dollars, but it could be any sort of
check - a date is the other common one I use.) The advantage of this approach
is that you can then call the validation function in other places, such as
the Exit event of the Frame control containing several TextBoxes or in the
Click event of a CommandButton.

For example, if you have a Frame control called Frame1 that contains three
TextBoxes that must all be validated and all formatted, you could use
something like this:

Private Sub Frame1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
If Me.Visible = True Then
If fcnValidateTextBox1 = False Then
Cancel = True
TextBox1.SetFocus
Exit Sub
Else: FormatTextBox1
End If
If fcnValidateTextBox2 = False Then
Cancel = True
TextBox2.SetFocus
Exit Sub
Else: FormatTextBox2
End If
If fcnValidateTextBox3 = False Then
Cancel = True
TextBox3.SetFocus
Exit Sub
Else: FormatTextBox3
End If
End If
End Sub

This is useful because (as you may have discovered) when you exit a Frame
control, the Exit event for the Frame fires but the Exit event for the last
control with focus does not. In the example above, I simply call the
validation code for each TextBox in the Frame and set the Cancel argument of
the Frame's Exit event to "True" if the validation on any TextBox fails (and
call the formatting code for the TextBox if validation is successful). I also
set focus back to the "failing" TextBox, which in most circumstances will be
the last TextBox with focus anyway - think about if for a bit and I'm sure
you'll see why.

Finally, in the Click event of a CommandButton, I do something similar.
Assume the same three TextBoxes with the same validation requirements as
above but an additional requirement that none of the TextBoxes can be blank.

Private Sub CommandButton1_Click()
If fcnValidateTextBoxes = True Then
'Do the stuff that should be done when the button is clicked
'e.g. hide the UserForm, build the document, etc.
End If
End Sub

Private Function fcnValidateTextBoxes() As Boolean
If Len(TextBox1.Value) = 0 Then
MsgBox "TextBox1 cannot be blank.", vbCritical, "TextBox1 Error"
fcnValidateTextBoxes = False
Exit Function
ElseIf fcnValidateTextBox1 = False Then
fcnValidateTextBoxes = False
Exit Function
Else: FormatTextBox1
End If
If Len(TextBox2.Value) = 0 Then
MsgBox "TextBox2 cannot be blank.", vbCritical, "TextBox2 Error"
fcnValidateTextBoxes = False
Exit Function
ElseIf fcnValidateTextBox2 = False Then
fcnValidateTextBoxes = False
Exit Function
Else: FormatTextBox2
End If
If Len(TextBox3.Value) = 0 Then
MsgBox "TextBox3 cannot be blank.", vbCritical, "TextBox3 Error"
fcnValidateTextBoxes = False
Exit Function
ElseIf fcnValidateTextBox2 = False Then
fcnValidateTextBoxes = False
Exit Function
Else: FormatTextBox3
End If
End Function

I think you get the idea.

BTW, if you use MultiPage controls in your UserForm, you can extend this
approach to work with the Change event of a MultiPage - although you are
somewhat limited in what you can do in this instance. (For example, you can't
set focus to the control that fails validation because it's no longer visible,
and there is no way to make it so.) It's a bit more complicated than the
other examples I've posted so I won't go into it. However, if you do want to
do something like this, you will need to evaluate the .Value property of the
MultiPage control and check to see if the .Value is NOT the one you want to
validate. And even then it's not perfect...

Cheers!

Gordon

Neil Humphries wrote:
[Quoted Text]
>Your suggestion worked wonderfully. I much prefer avoiding the problem rather
>than resolving it after the fact.
>
>Thanks
>
>> Neil,
>>
>[quoted text clipped - 17 lines]
>> >programmatically close the msgbox before the userform Unloads? Or, how do I
>> >keep the validation routine from triggering when the userform Unloads?

--
Message posted via OfficeKB.com
http://www.officekb.com/Uwe/Forums.aspx/word-programming/200811/1

Re: Closing orphaned msgbox
Neil Humphries 11/19/2008 1:56:01 PM
Great suggestion. I validate each control separately and then validate all
the controls on the page when the user clicks OK. This is to validate those
controls the user did not click on. I discovered that you can't call an "on
exit" sub from code. VBA tells you that there is a missing object. To address
this I had modularized the code so the validation is a separate SUB called by
the "on exit" event code and by the OK button. I must say though that your
code looks more elegant.

I am not familiar with the Else: syntax. I will have to look it up. Thanks
again.

"GordonBentleyMix via OfficeKB.com" wrote:

[Quoted Text]
> Neil,
>
> If I may offer another tip: You might want to make your validation code
> "modular" - something like this. (I'll explain the advantages in a minute.)
>
> Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
> If Me.Visible = True Then
> Cancel = Not fcnValidateTextBox1
> If Cancel = False Then FormatTextBox1
> End If
> End Sub
>
> Private Function fcnValidateTextBox1() As Boolean
> fcnValidateTextBox1 = True
> If Len(TextBox1.Value) > 0 Then
> If IsNumeric(TextBox1.Value) = False Then
> MsgBox "The value in TextBox1 must be numeric.", vbCritical,
> "TextBox1 Error"
> fcnValidateTextBox1 = False
> Exit Function
> End If
> End If
> End Function
>
> Private Sub FormatTextBox1()
> If Len(TextBox1.Value) > 0 Then TextBox1.Value = Format(TextBox1.Value, "
> $#,##0.00")
> End Sub
>
> In this approach I use a Boolean function to validate the value in the
> TextBox and use the result of this function to set the Cancel argument of the
> Exit event for the TextBox. (In my example above I want to make sure that the
> value is a number so I can format it as dollars, but it could be any sort of
> check - a date is the other common one I use.) The advantage of this approach
> is that you can then call the validation function in other places, such as
> the Exit event of the Frame control containing several TextBoxes or in the
> Click event of a CommandButton.
>
> For example, if you have a Frame control called Frame1 that contains three
> TextBoxes that must all be validated and all formatted, you could use
> something like this:
>
> Private Sub Frame1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
> If Me.Visible = True Then
> If fcnValidateTextBox1 = False Then
> Cancel = True
> TextBox1.SetFocus
> Exit Sub
> Else: FormatTextBox1
> End If
> If fcnValidateTextBox2 = False Then
> Cancel = True
> TextBox2.SetFocus
> Exit Sub
> Else: FormatTextBox2
> End If
> If fcnValidateTextBox3 = False Then
> Cancel = True
> TextBox3.SetFocus
> Exit Sub
> Else: FormatTextBox3
> End If
> End If
> End Sub
>
> This is useful because (as you may have discovered) when you exit a Frame
> control, the Exit event for the Frame fires but the Exit event for the last
> control with focus does not. In the example above, I simply call the
> validation code for each TextBox in the Frame and set the Cancel argument of
> the Frame's Exit event to "True" if the validation on any TextBox fails (and
> call the formatting code for the TextBox if validation is successful). I also
> set focus back to the "failing" TextBox, which in most circumstances will be
> the last TextBox with focus anyway - think about if for a bit and I'm sure
> you'll see why.
>
> Finally, in the Click event of a CommandButton, I do something similar.
> Assume the same three TextBoxes with the same validation requirements as
> above but an additional requirement that none of the TextBoxes can be blank.
>
> Private Sub CommandButton1_Click()
> If fcnValidateTextBoxes = True Then
> 'Do the stuff that should be done when the button is clicked
> 'e.g. hide the UserForm, build the document, etc.
> End If
> End Sub
>
> Private Function fcnValidateTextBoxes() As Boolean
> If Len(TextBox1.Value) = 0 Then
> MsgBox "TextBox1 cannot be blank.", vbCritical, "TextBox1 Error"
> fcnValidateTextBoxes = False
> Exit Function
> ElseIf fcnValidateTextBox1 = False Then
> fcnValidateTextBoxes = False
> Exit Function
> Else: FormatTextBox1
> End If
> If Len(TextBox2.Value) = 0 Then
> MsgBox "TextBox2 cannot be blank.", vbCritical, "TextBox2 Error"
> fcnValidateTextBoxes = False
> Exit Function
> ElseIf fcnValidateTextBox2 = False Then
> fcnValidateTextBoxes = False
> Exit Function
> Else: FormatTextBox2
> End If
> If Len(TextBox3.Value) = 0 Then
> MsgBox "TextBox3 cannot be blank.", vbCritical, "TextBox3 Error"
> fcnValidateTextBoxes = False
> Exit Function
> ElseIf fcnValidateTextBox2 = False Then
> fcnValidateTextBoxes = False
> Exit Function
> Else: FormatTextBox3
> End If
> End Function
>
> I think you get the idea.
>
> BTW, if you use MultiPage controls in your UserForm, you can extend this
> approach to work with the Change event of a MultiPage - although you are
> somewhat limited in what you can do in this instance. (For example, you can't
> set focus to the control that fails validation because it's no longer visible,
> and there is no way to make it so.) It's a bit more complicated than the
> other examples I've posted so I won't go into it. However, if you do want to
> do something like this, you will need to evaluate the .Value property of the
> MultiPage control and check to see if the .Value is NOT the one you want to
> validate. And even then it's not perfect...
>
> Cheers!
>
> Gordon
>
> Neil Humphries wrote:
> >Your suggestion worked wonderfully. I much prefer avoiding the problem rather
> >than resolving it after the fact.
> >
> >Thanks
> >
> >> Neil,
> >>
> >[quoted text clipped - 17 lines]
> >> >programmatically close the msgbox before the userform Unloads? Or, how do I
> >> >keep the validation routine from triggering when the userform Unloads?
>
> --
> Message posted via OfficeKB.com
> http://www.officekb.com/Uwe/Forums.aspx/word-programming/200811/1
>
>
Re: Closing orphaned msgbox
"Gordon Bentley-Mix via OfficeKB.com" <u44607[ at ]uwe> 11/20/2008 7:02:08 AM
Neil,

The Else: syntax is nothing special; it's just another way of writing

Else
[do some action]

when there's only one "action" to perform. VBA inserts the : automatically.
It's just a shortcut similar to the way you can use

If [some condition] Then [do some action] Else [do some other action]

I only use it because it makes the code a bit more compact and also makes it
clear that there's only one thing that needs to be done in the Else.


Neil Humphries wrote:
[Quoted Text]
>Great suggestion. I validate each control separately and then validate all
>the controls on the page when the user clicks OK. This is to validate those
>controls the user did not click on. I discovered that you can't call an "on
>exit" sub from code. VBA tells you that there is a missing object. To address
>this I had modularized the code so the validation is a separate SUB called by
>the "on exit" event code and by the OK button. I must say though that your
>code looks more elegant.
>
>I am not familiar with the Else: syntax. I will have to look it up. Thanks
>again.
>
>> Neil,
>>
>[quoted text clipped - 138 lines]
>> >> >programmatically close the msgbox before the userform Unloads? Or, how do I
>> >> >keep the validation routine from triggering when the userform Unloads?

--
Message posted via OfficeKB.com
http://www.officekb.com/Uwe/Forums.aspx/word-programming/200811/1

Re: Closing orphaned msgbox
Neil Humphries 11/20/2008 1:52:07 PM
Thanks for the explanation and the help.

"Gordon Bentley-Mix via OfficeKB.com" wrote:

[Quoted Text]
> Neil,
>
> The Else: syntax is nothing special; it's just another way of writing
>
> Else
> [do some action]
>
> when there's only one "action" to perform. VBA inserts the : automatically.
> It's just a shortcut similar to the way you can use
>
> If [some condition] Then [do some action] Else [do some other action]
>
> I only use it because it makes the code a bit more compact and also makes it
> clear that there's only one thing that needs to be done in the Else.
>
>
> Neil Humphries wrote:
> >Great suggestion. I validate each control separately and then validate all
> >the controls on the page when the user clicks OK. This is to validate those
> >controls the user did not click on. I discovered that you can't call an "on
> >exit" sub from code. VBA tells you that there is a missing object. To address
> >this I had modularized the code so the validation is a separate SUB called by
> >the "on exit" event code and by the OK button. I must say though that your
> >code looks more elegant.
> >
> >I am not familiar with the Else: syntax. I will have to look it up. Thanks
> >again.
> >
> >> Neil,
> >>
> >[quoted text clipped - 138 lines]
> >> >> >programmatically close the msgbox before the userform Unloads? Or, how do I
> >> >> >keep the validation routine from triggering when the userform Unloads?
>
> --
> Message posted via OfficeKB.com
> http://www.officekb.com/Uwe/Forums.aspx/word-programming/200811/1
>
>

Home | Search | Terms | Imprint
Newsgroups Reader