I would like to programmatically decide if the user has clicked the top right "x" button while using a form in visual basic.
I have tried:
Private Sub nameOfForm_Exit()
'code goes here
End Sub
Which has been unsuccessful. Any help would be much appreciated.
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
MsgBox "Good bye"
'/ To prevent user from closing the form
'/ Set cancel to True
Cancel = True
MsgBox "You can't close me!"
End Sub
You can't invent your own terms like "Exit". You have to take them in the combo boxes above (known as Events). Since your event pertains to the Userform itself, you need to choose Userform in the left combo box. You will also see all the controls your userform has, they each have a set of events.
As has been said QueryClose will refer to the red X in the top right corner. You also have Deactivate, which will happen whenever the UserForm loses focus (if it is ModeLess, meaning that a user can click the sheet behind the userform without closing it, this will trigger Deactivate) and Terminate, which occurs after the Userform closes with QueryClose.
Related
Whenever people clicks on the Debit Account or Credit Account fields on the userform, another userform with a Treeview will pop-out. However, the user will always have to press cancel in order to close the userform. Is there a way for the userform to automatically close when the Voucher Entry Form userform's area is selected?
If the question is "How to unload a user-form if it is not more the active object?" then the user-form in question must be modeless. Because else it cannot be deactivated without closing it's window. And because it is not possible opening a modeless user-form from a modal userform, the main user-form also must be modeless.
Example:
Do having two user-forms:
First user-form is named "MainForm" and has one button control and the following code applied:
Private Sub CommandButton1_Click()
Load SubForm
SubForm.Show vbModeless
SubForm.Left = Me.Left + 100
SubForm.Top = Me.Top + 100
End Sub
Second user-form is named "SubForm" and can be empty but has following code applied:
Private Sub UserForm_Deactivate()
Unload Me
End Sub
Then following Sub within a default module shows the main form:
Sub test()
MainForm.Show vbModeless
End Sub
Now after MainForm is shown, SubForm can be opened by button click. And if MainForm get the active form again (gets the focus again), the SubForm will unload.
I have a dynamic Userform. When loaded only a Combobox is visible, and user selects one option and accordingly some Labels and Textboxes with values are populated. But when I choose another option from Combobox and click on the button, all labels disappears but Textboxes remains there. Is there any way to clear or reset the Userform completely before loading?
I am not entirely sure how you set up your routines, I just based this answer on assumption. From what I understand, you want to reload the Userform using the same CommandButton in it. If that is the case, you can try this:
In a module, write a procedure that loads your form. Something like:
Sub marine()
Load Userform1
Userform1.Show
End Sub
In your CommandButton, create a routine that will call the load procedure and at the same time unloads the form. Something like:
Private Sub CommandButton1_Click()
'/* call the marine procedure after 0.5s */
Application.OnTime DateAdd("s", 0.5, Now), "marine"
Me.Hide
Unload Me '/* unloads the userform
End Sub
Your Userform will be invisible momentarily (like it flickers) but it will be reloaded just like the way you want it to be. HTH.
Is there a way to create a macro that, when activated, will present the user with some options, then call some other macro depends on what the user selected?
For example:
Message box: Are you a male or female?
Option 1: Male
Option 2: Female
If the user selects "Male," execute macro A. If "Female," macro B.
while in Word UI press ALT F11 to open VBA IDE
in main ribbon click Insert -> Userform
and there you have a toolbox (if not, click View->ToolBox) and a Userform canvas
from toolbox drag the option button icon and drop it into desired position of Userform. repeat it twice
select first option button in the userform, click on its caption (some "OptionButton1" is shown as default) and edit it to "Male"
do the same with second option button and edit its caption to "Female"
click twice on the first option button on the userform
it will show you
Private Sub OptionButton1_Click()
End Sub
then fill it as follows:
Private Sub OptionButton1_Click()
macroA
End Sub
click twice on the second option button on the userform
it will show you
Private Sub OptionButton2_Click()
End Sub
then fill it as follows:
Private Sub OptionButton2_Click()
macroB
End Sub
this will get you started
I'm building a userform where it has two text boxes to enter dates. Once the date is entered, I'm validating them when the Exit event fires. If the validation turns up that the user data isn't what is needed, the user is notified, the text box is cleared, and the focus is returned back to the textbox.
The issue comes if the user uses the mouse to select outside of the box, rather than Tab. If Tab is used, it fires perfectly and as expected, and the field is cleared and the focus is returned. If the mouse is used, it doesn't fire. According to this article, this is expected behavior (It's for Access, but I didn't see the similar relevant MSDN article for Excel.)
So instead I tried the AfterUpdate event. However, SetFocus doesn't work within an AfterUpdate event, I'm assuming because of the chain of events as outlined in the response to this question. Thus, I don't have a way to return the focus back to the textbox after it has fired. That thread had a suggestion as an alternate answer to SetFocus to another control and come back as a workaround, but that doesn't work for me, so I assume that may be an Access-specific workaround.
My last option I've considered is having the AfterUpdate event just call the Exit event, however the Exit event has a required argument (ByVal Cancel As MSForms.ReturnBoolean), which is how you cancel out of the exit and return the user to the textbox. As such, there isn't a value that you can pass to it that doesn't throw an error that I can find (the closest I found was passing Nothing but it failed out when trying to set it to True later to cancel the exit.)
Is there a way to achieve what I'm looking for here, or should I just stick to the AfterUpdate and ignore the SetFocus I'm trying to achieve?
I know that this was answered a few months back but giving an alternative solution. For any one who finds this question.
For validation of Excel Textbox data use the BeforeUpdate Event, it fires before the AfterUpdate Event and has the ability to prevent losing Focus on the control.
Rework the sample code to your requirements
Remember Cancel = True stops the control update to the control and it remains in focus.
Private Sub TextBox1_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
Cancel = doValidation(Textbox1.Text) 'Validation Route
End Sub
Private Function doValidation(strText) as Boolean
'Do Validation
if Valid then
doValidation = False
Else
msgBox "Not Valid"
doValidation = True
End if
End Sub
In my opinion this is the easiest way to validate an input on an Excel Userform Textbox
I can't right now find the correct MSDN article at this time, all Google wants to return is Access Results.
Exit event works on all the mouse clicks which fire up Enter for another Control on the Form. But When you click, directly on the form instead of any other control, nothing happens.
Here, use the ActiveControl property to determine about the last control you were in, before exiting and moving to user form.
Sample Code, rework it according to your requirement.
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Call doValidation(Me.TextBox1.Text) '/ Validation Routine when user leaves TextBox
End Sub
Private Sub UserForm_Click()
'/ If user clicked on the user form instead of ay other control
If Me.ActiveControl.Name = Me.TextBox1.Name Then
Call doValidation(Me.TextBox1.Text) '/ Validation Routine when user leaves TextBox
End If
End Sub
Private Sub doValidation(strText)
MsgBox strText
End Sub
Advise: For Date inputs, use DateTimePicker instead of TextBox, will save you from alot of trouble in future.
In VBA you can call any defined sub or function with the word Call Subname:
e.g. Call Textbox1_exit(params)
However from the somewhat confusing description I believe your problem is that you limit yourself to just a few event functions. I would suggest exploring all event functions and see which one is a good fit for your event fire.
Here is a list of events and their sequences in Access VBA:
https://msdn.microsoft.com/en-us/library/office/jj249049.aspx
and the order of form events:
https://support.office.com/en-us/article/Order-of-events-for-database-objects-e76fbbfe-6180-4a52-8787-ce86553682f9
I think for your application from the description you gave the lost_focus or got_focus for certain components might be useful.
Furthermore, you can manually set the focus to almost any component it is a built in method: compName.SetFocus()
Longtime viewer, first time question asker.
I'm currently working with UserForms within MS Word and have a particular form that can have up to 20 different labels and accompanying textboxes with varying texts. I have all but the first hidden while not in use, however I would like the next label and text box to become visible following input in the previous textbox. So if you enter data (anything) in the first textbox, the next label and text box will become visible. Does this make sense? I've seen other responses here suggest using AfterUpdate() rather than Change() or Click() but can't figure out how to use any of them. I would share my code but at this point I don't have any code to share, other than my labels and textboxes are lblField1 txtField1, lblField2 txtField2...
Any suggestions?
I would suggest using Change event, when using AfterUpdate you need to leave you TextBox for a while to fire the event. If you have only one TextBox visible there is nothing to move to. If you have more TextBoxes you would need to move back to fire AfterEvent and I don't think this is what you expect.
So, double click wherever on your userform and add the following code in code area:
Private Sub txtField1_Change()
txtField2.Visible = True
lblField2.Visible = True
End Sub
Next, add next portion for next textbox:
Private Sub txtField2_Change()
txtField3.Visible = True
lblField3.Visible = True
End Sub
And so on, if only you have an order in controls name you just need to change numbers in the end of control names.