I'm trying to add checkboxes during the initialization of my Userform. They have to be mutually exclusive. I know about option buttons but I can't use them for my form.
For now, I can't set them to be mutually exclusive. They are in a frame and I've set their .GroupName property to be the same. This is where I don't understand why it won't work. I read this MSDN article which tells that "All check boxes with the same GroupName within a single container are mutually exclusive".
I've also tried this on a blank Userform with and without frames but I can always select more than one checkbox.
Any idea of what I'm missing?
You may use code to achieve same functionality:
Private Sub CheckBox1_Click(): Check_Just CheckBox1: End Sub
Private Sub CheckBox2_Click(): Check_Just CheckBox2: End Sub
Private Sub CheckBox3_Click(): Check_Just CheckBox3: End Sub
Sub Check_Just(CheckBox)
'Disable false triggers when unchecking boxes
If CheckBox.Value = False Or CheckBox.GroupName = "" Then Exit Sub
'Uncheck all other control with same groupname
Dim ctl As control
For Each ctl In CheckBox.Parent.Controls
If TypeName(ctl) = "CheckBox" Then If ctl.GroupName = CheckBox.GroupName And Not ctl Is CheckBox Then ctl.Value = Unchecked
Next
End Sub
Related
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 big row of 250 ActiveX checkboxes of which I want to change the values all back from checked to unchecked, is there a way to put that in a macro?
checkbox names are just Checkbox3 to Checkbox253
An easy way:
Private Sub UnchkAllBox()
For i = 3 to 253
Controls("Checkbox" & i).Value = False
Next i
End Sub
In this way, the names of the checkboxes are very important. Use it only you named your checkboxes orderly.
Other way:
Private Sub UnchkAllBox2()
Dim Ctrl As Control
For Each Ctrl In Me.Controls
If TypeName(Ctrl) = "CheckBox" Then Ctrl.Value = False
Next Ctrl
End Sub
In this case, you don't have to concern the names. However, it will uncheck all checkboxes in your form.
Both methods mentioned are assuming all checkboxes were placed in a userform. For checkboxes in a worksheet, excel stores them in a OLEObjects collection instead of Controls. Therefore, the code should be re-written as below.
Private Sub UnChkAllBox()
For i = 1 To 5
OLEObjects("CheckBox" & i).Object.Value = False
Next i
End Sub
And
Private Sub UnChkAllBox2()
Dim Obj As OLEObject
For Each Obj In Me.OLEObjects
If TypeOf Obj.Object Is MSForms.CheckBox Then Obj.Object.Value = False
Next Obj
End Sub
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!!
Here's my problem.
I have a userform with 10 comboBoxes.
Instead of Select Case al those comboboxes one by one is
there a smart way to change multiple combobox properties such as backcolor or fontcolor?
So for example:
Sub ChangeMultipleComboBoxes()
Dim comboB as control
For Each comboB In Me.Controls
If TypeName(comboB) = "ComboBox" Then
comboB.BackColor = vbRed
End If
Next comboB
End Sub
The problem is that for comboB I can't seem to find any properties for changing it's backcolor or whatsoever.
Can someone help me please?
As Zaider says, your code works. You just don't get the IntelliSense for the ComboBox-specific properties when it's declared as a Control, even though you can use the properties as you've done in your code. (Note that properties common to all controls, e.g., Caption are available.)
To get the Intellisense for all ComboBox properties, re-declare the Control as a ComboBox once you've determined that's what it is:
Private Sub UserForm_Click()
Dim ctl As MSForms.Control
Dim comboB As MSForms.ComboBox
For Each ctl In Me.Controls
If TypeName(ctl) = "ComboBox" Then
're-declare it as a ComboBox
Set comboB = ctl
'Now you get IntelliSens
comboB.BackColor = vbRed
End If
Next ctl
End Sub
I'm currently trying to call a Sub within the onclick event of a checkbox. What I want to do is grab the groupName, Name and Value parameters of the checkbox that I have clicked and feed them into a sub which uses the variables to toggle the rest of the checkboxes in the group to be hidden or unhidden. However, there are multiple group checkboxes that I want to have the same functionality and rather than create multiple functions for each onclick event I want to just be able to call the sub which processes the change in visibility each time.
Consider the image above. If I set the 'Admin' checkbox to be false the 'Old versions' checkbox within the same box should be hidden. If I check it to true, it should be shown again. I also want to do the same with the client box. I've looked online and many people recommend using ActiveControl.Value or Application.Caller but none of these seem to work. The two subs I am using so far can be found below. In it's current state, the application errors at
admin_value = ActiveControl.Value
Here is the full code snippet:
Private Sub admin_toggle_Click()
Dim admin_group As String
Dim admin_name As String
Dim admin_value As String
admin_value = ActiveControl.Value
admin_name = ActiveControl.Name
admin_group = ActiveControl.GroupName
Call toggle_options
End Sub
Private Sub toggle_options()
Dim ctl As Control
For Each ctl In Me.Controls
If TypeOf ctl Is MSForms.CheckBox Then
If ctl.GroupName = admin_group Then
If ctl.Name <> admin_name Then
If admin_value = True Then
ctl.Visible = True
Else
ctl.Visible = False
End If
End If
End If
End If
Next ctl
End Sub
Thanks in advance.
Is this what you are trying?
Private Sub admin_toggle_Click()
Dim ctl As Control
Set ctl = admin_frame.ActiveControl
ShowHideControls admin_frame, ctl
End Sub
Sub ShowHideControls(frme As Control, cb As Control)
Dim c As Control
For Each c In frme.Controls
If TypeOf c Is MSForms.CheckBox Then
If c.Name <> cb.Name Then
If cb.Value = True Then
c.Visible = True
Else
c.Visible = False
End If
End If
End If
Next
End Sub