I have a textbox with code on change, and if I press a button with the following code
Private Sub CommandButton1_Click()
Application.EnableEvents = False
TextBox1.Text = "new text"
Application.EnableEvents = True
End Sub
but this still fires the on change event of the textbox.
This happens because Application.EnableEvents allows enabling/disabling events fired from the Application (i.e. Excel).
In your case, the parent firing the TextBox1 change is not the Application but rather the UserForm. This is an example from cpearson about how to create your own EnableEvents property on your Userform. I report the content of the link here (to avoid "link-only answer"):
To suppress events in a form, you can create a variable at the form's
module level called "EnableEvents" and set that to False before
changing a property that will cause an event to be raised.
Public EnableEvents As Boolean
Private Sub UserForm_Initialize()
Me.EnableEvents = True
End Sub
Sub Something()
Me.EnableEvents = False
' some code that would cause an event to run
Me.EnableEvents = True
End Sub
Then, all of the controls on form should have a test if that variable
as their order of business in any event code. For example,
Private Sub ListBox1_Change()
If Me.EnableEvents = False Then
Exit Sub
End If
MsgBox "List Box Change"
End Sub
You can declare the EnableEvents as Private if only procedures with
that form need to suppress events. However, if you have forms that are
programmatically linked together, such UserForm2 adding an item to a
ListBox on UserForm1, you should declare the variable as Public and
set it for another form with code like the following:
UserForm1.EnableEvents = False
'
' change something on UserForm1
'
UserForm1.EnableEvents = True
Related
There is a sub, it creates a CourtForm userform and then takes a data from it. The problem appears when said form is closed prematurely, by pressing "X" window button and I get a runtime error somewhere later. For reference, this is what I'm talking about:
In my code I tried to make a check to exit sub:
Private Sub test()
'Create an exemplar of a form
Dim CourtForm As New FormSelectCourt
CourtForm.Show
'The form is terminated at this point
'Checking if the form is terminated. The check always fails. Form exists but without any data.
If CourtForm Is Nothing Then
Exit Sub
End If
'This code executes when the form proceeds as usual, recieves
'.CourtName and .CourtType variable data and then .hide itself.
CourtName = CourtForm.CourtName
CourtType = CourtForm.CourtType
Unload CourtForm
'Rest of the code, with the form closed a runtime error occurs here
End Sub
Apparently the exemplar of the form exists, but without any data. Here's a screenshot of the watch:
How do I make a proper check for the form if it's closed prematurely?
Add the following code to your userform
Private m_Cancelled As Boolean
' Returns the cancelled value to the calling procedure
Public Property Get Cancelled() As Boolean
Cancelled = m_Cancelled
End Property
Private Sub UserForm_QueryClose(Cancel As Integer _
, CloseMode As Integer)
' Prevent the form being unloaded
If CloseMode = vbFormControlMenu Then Cancel = True
' Hide the Userform and set cancelled to true
Hide
m_Cancelled = True
End Sub
Code taken from here. I would really recommend to have a read there as you will find a pretty good basic explanation how to use a userform.
One of the possible solutions is to pass a dictionary to the user form, and store all entered data into it. Here is the example:
User form module code:
' Add reference to Microsoft Scripting Runtime
' Assumed the userform with 2 listbox and button
Option Explicit
Public data As New Dictionary
Private Sub UserForm_Initialize()
Me.ListBox1.List = Array("item1", "item2", "item3")
Me.ListBox2.List = Array("item1", "item2", "item3")
End Sub
Private Sub CommandButton1_Click()
data("quit") = False
data("courtName") = Me.ListBox1.Value
data("courtType") = Me.ListBox2.Value
Unload Me
End Sub
Standard module code:
Option Explicit
Sub test()
Dim data As New Dictionary
data("quit") = True
Load UserForm1
Set UserForm1.data = data
UserForm1.Show
If data("quit") Then
MsgBox "Ввод данных отменен пользователем"
Exit Sub
End If
MsgBox data("courtName")
MsgBox data("courtType")
End Sub
Note the user form in that case can be closed (i. e. unloaded) right after all data is filled in and action button is clicked by user.
Another way is to check if the user form actually loaded:
Sub test()
UserForm1.Show
If Not isUserFormLoaded("UserForm1") Then
MsgBox "Ввод данных отменен пользователем"
Exit Sub
End If
End Sub
Function isUserFormLoaded(userFormName As String) As Boolean
Dim uf As Object
For Each uf In UserForms
If LCase(uf.Name) = LCase(userFormName) Then
isUserFormLoaded = True
Exit Function
End If
Next
End Function
I created a user form with multiple options and now I want that the option the user selects is shown in a label under the button that calls the user form.I changed the caption in the text box under the button to resemble what should happen
However my options aren't working. Should I save the output in a global variable and then call it back to change the label and if so how do I do that? Or is it possible to just call the selection within the user form?
The code I was trying to run was this one to call the message box and then change the text box which is actually a label called "labelpage"
Private Sub CommandButton1_Click()
UserForm1.Show
If UserForm1.OptionButton1 = True Then LabelPage.Caption = "Company Restricted"
If UserForm1.OptionButton2 = True Then LabelPage.Caption = "Strictly Confidential"
If UserForm1.OptionButton2 = True Then LabelPage.Caption = "Public Information (does not need to be marked)"
End Sub
I also had this for each button click just to close them after selection, within the user form code.
Private Sub OptionButton1_Click()
OptionButton1.Value = True
Unload Me
End Sub
Private Sub OptionButton2_Click()
OptionButton2.Value = True
Unload Me
End Sub
Private Sub OptionButton3_Click()
OptionButton3.Value = True
Unload Me
End Sub
Is there just a tiny mistake of syntax or something like that or is this just completely wrong? Thank you in advance for your help.
The issue is that you are unloading the UserForm, meaning the controls are not available to you. The solution is to just hide the UserForm:
Private Sub OptionButton1_Click()
Hide
End Sub
Private Sub OptionButton2_Click()
Hide
End Sub
Private Sub OptionButton3_Click()
Hide
End Sub
I have a userform with 2 OptionButton choices, and I'm modifying the form (hiding labels and controls, and resizing frame) for the default Option (name = BwaIsNew), but then restoring the full userform when Option #2 (name = BwaIsOld) is selected. (see separate question for background).
When Option #2 is selected I'm calling a fresh userform, and coding the change in value. But this coding of the value dlgInformation.BwaIsOld.Value = True then triggers an event (?) that calls the Sub BwaIsOld_Click() code to run. This then sets up a perpetual loop.
What's the best way to solve this?
Problem code (the one looping) is:
Private Sub BwaIsOld_Click()
Unload Me
dlgInformation.BwaIsNew.Value = False
dlgInformation.BwaIsOld.Value = True
dlgInformation.Show
End Sub
Update:
Thanks #Tim & #CommonSense. I'm still not quite there yet. What am I doing wrong? Here is the code
Public EnableEvents As Boolean
Private Sub UserForm_Initialize()
Me.EnableEvents = True
End Sub
Private Sub BwaIsNew_Click()
Call changeform(280)
End Sub
Private Sub BwaIsOld_Click()
Unload Me
Me.EnableEvents = False
dlgInformation.BwaIsNew.Value = False
dlgInformation.BwaIsOld.Value = True
Me.EnableEvents = True
dlgInformation.Show
End Sub
You need to actually use that EnableEvents in the rest of your code.
BTW I would choose a different name from the built-in Application.EnableEvents property just for clarity.
Public EnableEvents As Boolean
Private Sub UserForm_Initialize()
Me.EnableEvents = True
End Sub
Private Sub BwaIsNew_Click()
'don't respond to events triggered by BwaIsOld_Click
If Me.EnableEvents Then
Call changeform(280)
End If
End Sub
Private Sub BwaIsOld_Click()
Unload Me '<< why do this here?
Me.EnableEvents = False
dlgInformation.BwaIsNew.Value = False
dlgInformation.BwaIsOld.Value = True
Me.EnableEvents = True
dlgInformation.Show
End Sub
Iam trying to create a simple if statement in Excel with VBA.
I'm creating a new checkbox
Adds the following code to the box.
Sub CheckBox1_Click()
HideRows "2:5"
End Sub
Sub HideRows(rowRange)
If CheckBox1 = False Then
Rows(rowRange).EntireRow.Hidden = True
Else: Rows(rowRange).EntireRow.Hidden = False
End If
End Sub
Result: The rows are hidden both if the checkbox is checked or unchecked.
(checkbox is checked)
All rows are visible
Uncheck the checkbox
Result: All rows are hidden
(checkbox is unchecked)
All rows are visible
Uncheck the checkbox
Result: All rows are hidden
You want it in a Change Event.
You do not need the If Then. CheckBox1 rturns a TRUE/FALSE, just use that.
And the EntireRow is also not needed when refering to Rows(). You are already refering to the whole row.
Also, it is good practice to always declare the parent to any Range Object, which Rows() is. If the the code is in the Worksheet code then use Me as it will refer to itself. If the code is in a module then use ActiveSheet or more preferably the specific sheet, Worksheets("Sheet1") :
Private Sub CheckBox1_Change()
HideRows "2:5"
End Sub
Sub HideRows(rowRange)
'if this code is not in the worksheet code then change `Me` to `ActiveSheet`
Me.Rows(rowRange).Hidden = Not CheckBox1
End Sub
Assuming its an ActiveX CheckBox, place this code in Sheet Module...
Private Sub CheckBox1_Click()
If CheckBox1 = True Then
Rows("2:5").Hidden = True
Else
Rows("2:5").Hidden = False
End If
End Sub
Edit:
Or just use this...
Private Sub CheckBox1_Click()
Rows("2:5").Hidden = CheckBox1
End Sub
You can put this in one sub, assuming its an activeX checkbox
Private Sub CheckBox1_Click()
If CheckBox1 = True Then
[2:5].EntireRow.Hidden = False
Else: [2:5].EntireRow.Hidden = True
End If
End Sub
I have a UserForm with this function:
Public MyVariable As String
Private Sub UserForm_Initialize()
[...my code...]
End Sub
To call my Userform from a button i do:
Sub CallUserForm_Appro()
UserForm1.MyVariable = "Appro"
UserForm1.Show
End Sub
Sub CallUserForm_User()
UserForm1.MyVariable = "User"
UserForm1.Show
End Sub
My goal is to remove "Label1" if user click on button to call CallUserForm_Appro()
So, i tried in UserForm_Initialize() to do:
Public MyVariable As String
Private Sub UserForm_Initialize()
[...my code...]
If MyVariable = "Appro" Then
UserForm1.Controls.Remove "Label1"
End If
End Sub
I have no error but my Label1 is always visible.
This is how you set the visibility of the label to false:
UserForm1.label1.Visible = false
Then it should not be visible any more.
The `Initialize event occurs before the variable is set (because you can't access any property of the form without it being loaded first).
You should use the Activate event instead as long as the control is added at run time. If it's a design time control, you can't delete it, only hide it. Alternatively, you might only add it to the form if the variable is not set to "Appro"