Send checkbox Name, Value and GroupName to a method OnClick - vba

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

Related

VBA check if all userform comboboxes have an option selected

I have a userform with many comboboxes and an "Ok" button. What I need is that when pressing that "Ok" button, VBA to check if there's no empty comboboxes. If all comboboxes have some value selected - close the userform otherwise return a message box and clicking "Ok" on that messagebox returns me to the userform with no filled values lost.
I've tried all the methods I could think of:
If PackageOuterRadius = null Then
if PackageOuterRadius is nothing Then
If PackageOuterRadius.value = 0 Then
If IsNull(PackageOuterRadius) = True Then
If IsNull(PackageOuterRadius.value) Then
What I've been trying to do is:
Private Sub Rigid_Filme_Ok_Button_Click()
If PackageOuterRadius.ListCount = 0 Then
MsgBox "Select a ""Package Outer Radius!"
End If
And absolutelly nothing actually checks if the combobox is empty and keeps returning a positive (That there's a value selected)
What could be the solution to this problem? Could someone, please, help me?
If you have few ComboBoxes only, you may insert lines underneath the OK button to check if all the ComboBoxes are filled but if you have too many ComboBoxes on UserForm, you may achieve this with the help of a Class Module and to do so, follow these steps...
Insert a Class Module and rename it to clsUserForm and the place the following code on Class Module...
Code for Class Module:
Public WithEvents mCMB As msforms.ComboBox
Public Sub CheckComboBoxes()
Dim cCtl As msforms.Control
Dim cntCBX As Long
Dim cnt As Long
For Each cCtl In frmMyUserForm.Controls
If TypeName(cCtl) = "ComboBox" Then
cntCBX = cntCBX + 1
If cCtl.Value <> "" Then
cnt = cnt + 1
End If
End If
Next cCtl
If cnt = cntCBX Then
Unload frmMyUserForm
Else
MsgBox "All the ComboBoxes are mandatory.", vbExclamation
End If
End Sub
Then place the following code on UserForm Module. The code assumes that the name of the userForm is frmMyUserForm and the name of the CommandButton is cmdOK.
Code for UserForm Module:
Dim GroupCBX() As New clsUserForm
Dim frm As New clsUserForm
Private Sub cmdOK_Click()
frm.CheckComboBoxes
End Sub
Private Sub UserForm_Initialize()
Dim i As Long
Dim ctl As Control
For Each ctl In Me.Controls
If TypeName(ctl) = "ComboBox" Then
i = i + 1
ReDim Preserve GroupCBX(1 To i)
Set GroupCBX(i).mCMB = ctl
End If
Next ctl
End Sub
And you will be good to go.

Dynamic checkboxes mutually exclusive

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

VBA excel change value of multiple checkboxes

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

Access 2016 VBA - Create custom collection of controls, manually specifying control's name

Since you can't have a vertical Control Tab in Access, I'm creating a fake one.
I wrote this piece of code to highlight (change fore color to white) the current page:
Private Sub updateBtnColor()
Dim currentPageIndexSZero As Long
Dim ctl As Control
currentPageIndexSZero = Me.tab1
For Each ctl In Me.Controls
If ctl.Tag = "page" & CStr(currentPageIndexSZero) Then
ctl.ForeColor = white
ElseIf InStr(1, ctl.Tag, "page", vbBinaryCompare) Then
ctl.ForeColor = black
End If
Next ctl
End Sub
Every button has got the page it's referring to as a tag, in the form of:
page0
page1
...
pageN
So the loop basically checks the current page, finds the button with the appropriate tag (assuming I named them correctly) and highlights its text.
Now this can be slow since I've got a heavy loaded form or bad practise, so I thought of creating a custom collection instead of looping through the whole Controls Collection.
I wanted to create such structure so I can loop through it, something like:
Enum myButtons
button1 = Forms!myForm!button1
button2 = Forms!myForm!button2
button3 = Forms!myForm!button3
button4 = Forms!myForm!button4
End Enum
And then:
Public Sub updateBtnColor()
Dim curPageZ as Long
Dim button as Control
For Each button in myButtons
With button
If Right$(CStr(.Name, 1)) = curPageZ
.ForeColor = 16777215 ' White
Else ' No need for an additional ElseIf since I already know these are only the wanted buttons
.ForeColor = 0 ' Black
End If
End With
Next button
End Sub
What is the most elegant/fastest/best/proper way to create such structure or, if my idea is not that good, to create such logic?
Thanks!
Cycling thru controls works quite fast, but if you want to speedup this, use Collection for storing objects, not Enum. Collection can be cycled also using For Each....
On form module level create a collection for your buttons:
Dim mcolMyButtons As New Collection
Then fill this collection in Open or Load events. You can use tags:
Dim ctl As Control
For Each ctl In Me.Controls
If TypeOf ctl Is CommandButton Then
If ctl.Tag Like "page*" Then
mcolMyButtons.Add ctl
End If
End If
Next
Or just directly add buttons you want:
mcolMyButtons.Add Me.Button1
mcolMyButtons.Add Me.Button2
mcolMyButtons.Add Me.Button3
mcolMyButtons.Add Me.Button4
Then your sub:
Private Sub updateBtnColor()
Dim ctl As Control
For Each ctl In mcolMyButtons
If ctl.Tag = "page" & Me.tab1 Then
ctl.ForeColor = vbWhite
Else
ctl.ForeColor = vbBlack
End If
Next ctl
End Sub

VBA: chkbox_click event triggered by changing value chkbox

I have a userform which is dynamically filled by checkboxes. To improve usability I've added a checkbox "Select all" which either selects or deselects all checkboxes. This works perfectly. Now I want the "Select all" checkbox to be unchecked (value=False) automatically once one of the other checkboxes is unchecked.
In order to achieve this I've created a class module. This class module also does what it's supposed to. But, and here's my problem, once the value of "Select all" is changed, the "Select all" checkbox_click event is triggered, which means all other checkboxes are being unchecked as well, and that's obviously not what I want! I've already tried to use the MouseDown and MouseUp events instead, but these events behave irregular and often lead to the wrong results.
Question: How do I stop the Click event from running everytime the value of this checkbox is changed without the checkbox actually being clicked?
Here's my code:
Private colTickBoxes As Collection
Private Sub UserForm_Initialize()
Dim ChkBoxes As cls_RIRI
Dim ctrl As Control
'Controls are created on run time here
'Some events to change the height of the userform and the top value of several buttons
'Make sure click events work
Set colTickBoxes = New Collection
For Each ctrl In Me.Controls
If TypeName(ctrl) = "CheckBox" And Left(ctrl.Name, 1) = "M" Then
Set ChkBoxes = New cls_RIRI
ChkBoxes.AssignClicks ctrl
colTickBoxes.Add ChkBoxes
End If
Next ctrl
Set ctrlCHK = Nothing
Set ChkBoxes = Nothing
Set ctrl = Nothing
End Sub
And the class module:
Private WithEvents chkBox As MSForms.CheckBox
Public Sub AssignClicks(ctrl As Control)
Set chkBox = ctrl
End Sub
Private Sub chkBox_Click()
If chkBox.value = False Then UserForms(0).Controls("chkSelAll").value = False
End Sub
And the chkSelAll_Click sub:
Private Sub chkSelAll_Click()
Dim ctrl As Control
For Each ctrl In Me.Controls
If TypeName(ctrl) = "CheckBox" And Left(ctrl.Name, 1) = "M" Then
If chkSelAll.value = True Then
ctrl.value = True
Else
ctrl.value = False
End If
End If
Next
Set ctrl = Nothing
End Sub
Add a public variable, say blnBypassNonUIClick and set this, then when coming from the UI, by a human click set it to false, and when setting the select all the same. Your select all, shouldnt activate click if you're setting the .value by code. Something like this....
Public blnNonUI As Boolean
Private Sub CheckBox1_Click()
If Not blnNonUI Then
MsgBox "hello"
End If
End Sub
Private Sub UserForm_Click()
blnNonUI = True
Me.CheckBox1.Value = 1
blnNonUI = False
End Sub
Nathan_Sav gave me this idea and it works:
Public blnHumanClick As Boolean
Private Sub chkSelAll_Click()
If blnHumanClick = True Then
Dim ctrl As Control
For Each ctrl In Me.Controls
If TypeName(ctrl) = "CheckBox" And Left(ctrl.Name, 1) = "M" Then
If chkSelAll.value = True Then
ctrl.value = True
Else
ctrl.value = False
End If
End If
Next
Set ctrl = Nothing
blnHumanClick = False
End If
End Sub
Private Sub chkSelAll_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
blnHumanClick = True
End Sub