Prevent OptionButton preselection in UserForms - vba

I have the following code in a UserForm:
Private Sub CommandButton1_Click()
Warning_Box.Hide
End Sub
Private Sub OptionButton1_Click()
KeepGoing = 0
End Sub
Private Sub OptionButton2_Click()
KeepGoing = 1
End Sub
The first time this code runs, it works fine as none of the OptionButtons is preselected by the VBA code. The second time however, the previous choice is preselected. This appears to stop the correct setting of the KeepGoing value (as an earlier section sets KeepGoing = 2).
Basically, how do I make it so no OptionButton is preselected after the first run?

You will need to change
Warning_Box.Hide
to
Unload Me

You may have good reasons not to use Unload Me. If so, you can just set values of all option buttons to false somewhere in your code.
Warning_Box.OptionButton1.Value = False
for every option button. You can also loop trough Warning_Box.Controls and set value to false if it is option button.
Dim con As Control
For Each con In ufMain.Controls
If TypeName(con) = "OptionButton" Then con.Value = False
Next con

Related

VBA multiple option dialog box output

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

If statement is not working in Excel VBA

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

How make VBA run on clicking any checkbox in a userform?

I have a userform with a multiple frames, all filled with multiple checkboxes. I've named the checkboxes to their corresponding Excel cells. Now I want to make VBA run on clicking any of these checkboxes on run time. I know I can do this by creating a click-sub for every individual checkbox, but there must be a cleaner way to do this.
So far I've tried to put this code in the userform_Click and userform_Mousedown events, but they don't run when I click the checkboxes. Does anyone have an idea how to do this?
Dim iControl As Control
For Each iControl In Me.Controls
If TypeName(iControl) = "CheckBox" Then
If iControl.Value = True And Range(iControl.Name).Value = "" Then
Range(iControl.Name).Value = Format(Now, "dd.mm.yyyy")
ElseIf iControl.Value = True And Range(iControl.Name).Font.Color = vbWhite Then
Range(iControl.Name).Font.Color = vbBlack
ElseIf iControl.Value = False And Range(iControl.Name).Value <> "" Then
Range(iControl.Name).Font.Color = vbWhite
End If
End If
Next
As SilentRevolution said - you need an event to fire when you click the button. You're just after a single procedure to fire all check box click events.
So:
Create a class module called cls_ChkBox.
In the class module you'll add the Click event code:
Option Explicit
Private WithEvents chkBox As MSForms.CheckBox
Public Sub AssignClicks(ctrl As Control)
Set chkBox = ctrl
End Sub
Private Sub chkBox_Click()
ThisWorkbook.Worksheets("Sheet1").Range(chkBox.Name).Value = Format(Now, "dd.mm.yyyy")
End Sub
Now you just need to attach the chkBox_Click event to each check box on your form. In your user form add this code:
Option Explicit
Private colTickBoxes As Collection
Private Sub UserForm_Initialize()
Dim ChkBoxes As cls_ChkBox
Dim ctrl As Control
Set colTickBoxes = New Collection
For Each ctrl In Me.Controls
If TypeName(ctrl) = "CheckBox" Then
Set ChkBoxes = New cls_ChkBox
ChkBoxes.AssignClicks ctrl
colTickBoxes.Add ChkBoxes
End If
Next ctrl
End Sub
Each check box is given its own instance of the class, which is stored in the colTickBoxes collection.
Open the form and the cell in Sheet1 will update to show the date depending on the name of the check box.
You need an event to run code, if there is no event, the macro cannot start. I don't know if there is a single event that triggers for any button or checkbox that is clicked.
If the code you want to execute is the same every time except the control, you could write a private sub in the userform module which is called for each event, the private sub can take an input between the () for example.
Private Sub CheckBox1_Click()
Call ExecuteCode(Me.CheckBox1)
End Sub
Private Sub CheckBox2_Click()
Call ExecuteCode(Me.CheckBox2)
End Sub
Private Sub CheckBox3_Click()
Call ExecuteCode(Me.CheckBox2)
End Sub
Private Sub ExecuteCode(IControl As Control)
If TypeName(IControl) = "CheckBox" Then
If IControl.Value = True And Range(IControl.Name).Value = "" Then
Range(IControl.Name).Value = Format(Now, "dd.mm.yyyy")
ElseIf IControl.Value = True And Range(IControl.Name).Font.Color = vbWhite Then
Range(IControl.Name).Font.Color = vbBlack
ElseIf IControl.Value = False And Range(IControl.Name).Value <> "" Then
Range(IControl.Name).Font.Color = vbWhite
End If
End If
End Sub
I just learned this today and thought it might help? Most of the questions, and responses for that matter, to questions regarding checkboxes, listboxes, etc. seem to not distinguish between those forms are inserted directly on the worksheet or are imbedded in a UserForm.
This may work for a checkbox - it works for a ListBox on a UserForm. If you want code to run after a selection, the code you must write has to be in module of the UserForm. I had no clue how to access. Once you have inserted a UserForm in your VBE, add the ListBoxes or whatever to the UserForm. Right click on the UserForm in the upper left project window and select "view code." Here is where you'll place the code, in my case a "change event" such that after a selection is made from the ListBox, other code is automatically run. Her for example:
Sub lstBoxDates_Change()
Dim inputString1 As String
inputString1 = Format(UserForm1.lstBoxDates.Value, "mm-dd-yyyy")
Call EnterDates(inputString1)
Unload Me
End Sub
To explain: Again this code is in the UserForm Module. I named my ListBox,
lstBoxDates. In my main code that I call - EnterDates, I use the variable name = inputString1. The value or date that I have selected from the ListBox is captured from the UserForm1 by UserForm1.lstBoxDates.Value - and I format that to a date, otherwise you see just a number. This is for only one selection.
Because I Dim here, no need to Dim in your main code. The sub for the main code
needs to accept the variable you are passing to it:
Sub EnterDates(inputString1)
This is very generalized but maybe something will click so you can get what you are after. I hope so, for I've worked on this a full two days!!

Initializing a userform with preset values?

Working in VBA for excel 2010. This is my first time working with VBA and userforms. Right now I have a barebones userform "UserForm1" trying to sort this issue out. It consists of two radio buttons "OptionButton1" and "OptionButton2" belonging to GroupName "WK" and two textboxes "TextBox1" and "TextBox2".
When I run the userform, I want "OptionButton1" to be selected and the subsequent if/then statements to be run. However, right now I cannot get it to do this. My code:
Public Sub UserForm1_Initialize()
UserForm1.Show
Me.OptionButton1.Value = False
Me.OptionButton1.Value = True
MsgBox ("dia locked")
Me.TextBox1.Value = "blah"
End Sub
Public Sub UserForm1_Activate()
End Sub
Public Sub OptionButton1_Click()
If Me.OptionButton1.Value = True Then
MsgBox ("dia locked")
Me.TextBox1.Value = "blah"
End If
End Sub
Private Sub TextBox1_Change()
End Sub
When I run the form, nothing happens and "OptionButton1" is false. If I click it, the message box displays and the textbox displays the text. It just won't do it on startup. I have tried going into the optionbutton properties and setting 'value' to true, which makes it true on startup, but the messagebox still doesn't display and the textbox is blank until I click it.
...please help. Thank you.
I figured it out.
I suddenly found the dropdowns. Apparently I should have put Userform_Initialize() instead of UserForm1_Initialize(), and instead of OptionButton1_Click() I put the code into OptionButton1_Change() which ran the subsequent initialization sequence.
You guys/gals are awesomesauce. I have learned everything from reading your threads. Thank you!

How to prevent ActiveX events firing in VBA?

I am searching for a better way to disable ActiveX events from triggering in an Excel workbook (though this would apply to all Office apps with ActiveX objects).
Hopefully something similar to Application.EnableEvents = false, though this does not work with ActiveX.
In the below example it's trivial to use a global boolean but I have a lot of event handlers for my ActiveX objects and it would be immensely easier for something I could universally apply to temporarily disable ActiveX events. I don't really want to add an if/exit sub statement to every single one of these methods.
To demonstrate this problem, create an ActiveX combobox in a worksheet and add the following to that sheet module
Public initializingContent As Boolean
Private Sub intializeAllActiveXContent()
'this doesn't apply to activeX events :'(
Application.EnableEvents = False
'this could work but is not really elegant
'change this to false to show my problem in
'the intermediate window (called not once but twice)
initializingContent = True
ComboBoxTest.Clear
ComboBoxTest.AddItem ("item1")
ComboBoxTest.AddItem ("item2")
ComboBoxTest.AddItem ("item3")
'select the top value in the box
ComboBoxTest.value = "item1"
initializingContent = False
Application.EnableEvents = True
End Sub
Private Sub ComboBoxTest_Change()
'I really don't want to have to wrap EVERY single ActiveX method
'with something like this for a whole variety of reasons...
If initializingContent Then Exit Sub
Debug.Print "do stuff I don't want to happen when intializeAllActiveXContent() runs " & _
"but I do when user changes box"
End Sub
I know this is really old. But anyone who looks this up (first hit on google) might want a simple answer:
Lets say you have a Private Sub ActiveXControl_Change() that is getting called during an Application.EnableEvents = False and you want it to skip this just go:
Private Sub ActiveXControl_Change()
If Application.EnableEvents = True Then
'enter you code here
End If
End Sub
Why not disable them? That ways you don't have to worry about their individual codes as well.
Try this
Sub DisableActiveXControls()
Dim ws As Worksheet
Dim OLEobj As OLEObject
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
For Each OLEobj In ws.OLEObjects
If TypeOf OLEobj.Object Is MSForms.ComboBox Then
OLEobj.Enabled = False
End If
Next OLEobj
End With
End Sub
Before/After ScreenShots:
FOLLOWUP FROM COMMENTS:
Also turns out this breaks hard core on objects which are grouped together but I can ungroup objects (they are no longer in "Sheet1.OLEobjects" I guess). I still don't really like this since it relies on this fact and there will be times when I do want to group objects.. – enderland 17 mins ago
To disables ActiveX Controls in a group, you don't need to ungroup them. Use this code. The below code will disable Comboboxes in a group.
Sub Disable_ActiveX_Controls_In_A_Group()
Dim shp As Shape, indvShp As Shape
Dim OLEobj As OLEObject
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
For Each shp In ws.Shapes
If shp.Type = msoGroup Then
For Each indvShp In shp.GroupItems
Set objOLE = indvShp.OLEFormat.Object
If objOLE.progID = "Forms.ComboBox.1" Then _
objOLE.Enabled = False
Next
End If
Next
End Sub
came across this post when searching for a similar issue. I decided the answer posted here would not suit my situation, and came up with something else. My approach may be useful here also.
In my workbook, I have a set of 20 (Activex) checkboxes. These essentially filter on/off 20 categories of product to be included in a report. There is a routine that runs each time one of these checkboxes is changed, simply by calling the routing from the CheckBox_Click routine.
Then I also have a combobox that selects various groups of these checkboxes. The trouble is that when EACH of the 20 checkboxes is (un)selected by the combobox code, the calculation routine is triggered.
What I wanted was to run the calculation routine only ONCE at the end of the combobox, but still have it work if I change an individual checkbox manually.
My solution - put in a TRUE/FALSE code in some cell on a hidden worksheet, somewhere it's out of the way and won't interfere.
Then the CheckBox_Click code becomes (for each of the 20 checkboxes):
Private Sub CheckBox6_Click()
If (Sheets("Data").Range("G60")) Then
Call RangeFind
End If
End Sub
The combobox code modifies this same cell, appropriately:
Private Sub ComboBox28_Change()
Sheets("Data").Range("G60").Value = False
Select Case Sheets("Data").Range("F50").Value
Case "1"
CheckBox1.Value = False
CheckBox2.Value = False
CheckBox3.Value = False
....
End Select
' This turns the checkboxes back on
Sheets("Data").Range("G60").Value = True
' This now actually calls the calculation ONCE
Call RangeFind
ActiveSheet.Range("A1").Activate
End Sub
Cheers,
Michael
Here is one option:
Private Sub ToggleButton1_Click()
If Application.EnableEvents = True Then
'This next line forces at least 1 of the toggle's to be selected at all
'times; remove it from all routines if this is not desired.
If Not ToggleButton1.Value Then ToggleButton1.Value = True
Application.EnableEvents = False
ToggleButton2.Value = False
ToggleButton3.Value = False
Application.EnableEvents = True
End If
End Sub
Private Sub ToggleButton2_Click()
If Application.EnableEvents = True Then
If Not ToggleButton2.Value Then ToggleButton2.Value = True
Application.EnableEvents = False
ToggleButton1.Value = False
ToggleButton3.Value = False
Application.EnableEvents = True
End If
End Sub
Private Sub ToggleButton3_Click()
If Application.EnableEvents = True Then
If Not ToggleButton3.Value Then ToggleButton3.Value = True
Application.EnableEvents = False
ToggleButton1.Value = False
ToggleButton2.Value = False
Application.EnableEvents = True
End If
End Sub