Loop through checkboxes to see which ones are checked - vba

I have a userform that contains 10x check boxes.
Each of these check boxes should have a value. Say check box 1 should contain value "Medicine", check box 2 should contain value "Water".
I am giving the users the option to check any of these and press submit. On pressing submit, I would like to check which check boxes were ticked and combine the values.
I.e. if user ticks only check box 1 and 2, then the output will be "MedicineWater".
Rather than doing 10 nested IF statements and then doing all the possible permutations, which would take very long. I wonder if it is possible to loop through the check boxes and see which one is ticked (marked as True) and then store the value that should be assigned to it.
My simplified code is:
Private Sub Submit_Click()
Dim i as Long
Dim Val1 as String
Dim Val2 as String
Dim Array()
Dim Final as String
Val1 = "Medicine"
Val2 = "Water"
For i = 1 to 2
If Me.CheckBox & i = True Then
Array = Val & i
Final = Join(Array, "")
End If
Next i
Msgbox (Final)
End Sub
Can someone please advise me how to do this properly?
Thanks

I believe the following will do what you expect:
Private Sub Submit_Click()
Dim Final As String
Dim ctrl As Control
For Each ctrl In Me.Controls
'loop through controls in your UserForm
If TypeName(ctrl) = "CheckBox" Then 'if control is a CheckBox then
If ctrl.Value = True Then 'if the checkbox is checked
Final = Final & ctrl.Caption 'add the caption to the variable
End If
End If
Next ctrl
MsgBox (Final)
End Sub
UPDATE:
If what you need is to assign the caption of the given checkbox to a variable, you can do so like below, using an Array to store values for each checkbox, this example will only store values for checkboxes that are checked:
Private Sub Submit_Click()
Dim Final() As String
Dim ctrl As Control
Dim counter As Integer
counter = 0
For Each ctrl In Me.Controls
'loop through controls in your UserForm
counter = counter + 1
ReDim Preserve Final(counter)
If TypeName(ctrl) = "CheckBox" Then 'if control is a CheckBox then
If ctrl.Value = True Then 'if the checkbox is checked
Final(counter) = ctrl.Caption 'add the caption to the variable
End If
End If
Next ctrl
End Sub

Related

How to paste clipboard value into a specific ComboBox on a UserForm?

I copy a name in the first column of the active row on a spreadsheet to the clipboard.
I launch a UserForm by the name CommandsUserForm.
The UserForm is overlaid with multiple pages or tabs, so it defaults to the first tab (this is desired).
On this tab, there is a ComboBox by the name DPComboBox.
I want to paste the value in the clipboard into the ComboBox after the userform is launched.
Userform with the ComboBox highlighted.
Sub Show_Quick_Commands()
DPName = ThisWorkbook.ActiveSheet.Cells(ActiveCell.Row, 1).Value
Set DPNameforQ = New DataObject
DPNameforQ.SetText DPName
DPNameforQ.PutInClipboard
CommandsUserForm.Show vbModeless
End Sub
I tried DPComboBox.PasteSpecial Transpose:=True, but that breaks the code and requests a debug.
For example:
Sub Show_Quick_Commands()
Dim frm As CommandsUserForm
Set frm = New CommandsUserForm
frm.DPName = ActiveCell.EntireRow.Cells(1).Value 'set before showing the form
frm.Show vbModeless
End Sub
Userform:
Option Explicit
Private m_DPName As String
Private Sub UserForm_Activate()
Dim i As Long, v
'put some dummy data in the combobox
For i = 1 To 10
Me.DPComboBox.AddItem "ClientPartner_" & Format(i, "000")
Next i
Me.DPComboBox.Text = m_DPName 'set the value
End Sub
'call this before showing the form
Property Let DPName(nm As String)
m_DPName = nm
End Property

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.

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

Returning multiselected responses to a Bookmark in MS Word

I have a word document where the user clicks a commandbutton that brings up a userform with a multiselect listbox (listbox1) and a commandbutton (cmnd1) on it. I wish for the user to select multiple items and then click the command button.
This causes the userform to disappear and the selected items to appear as a string at a bookmark in the MS word document (bkmrk1a).
I can do this easily with single select. I am getting tripped up with multiselect.
Here is the code I am using:
`Option Explicit
Private Sub UserForm_Initialize()
Dim i, Str As String
Str = "Rating1,Rating2,Rating3,Rating4,"
For i = 0 To UBound(Split(Str, ","))
ListBox1.AddItem Split(Str, ",")(i)
Next
End Sub
Private Sub CommandButton1_Click()
Selection.Text = ListBox1.Value
Application.ScreenRefresh
End Sub
Any help would be appreciated. I am new to VBA.
Mark
To enable multiselect on a list box, simply set the .MultiSelect property to either fmMultiSelectMulti or fmMultiSelectExtended. The later allows you to use the shift key to select multiple items. ie in the initialization:
ListBox1.MultiSelect = fmMultiSelectExtended
Then when you click the commandbutton, you need to loop through the list items and check if they have been selected. ie:
Private Sub CommandButton1_Click()
Dim ii As Integer
For ii = 0 To ListBox1.ListCount - 1
If ListBox1.Selected(ii) Then
Selection.Text = ListBox1.List(ii)
Selection.MoveRight
Selection.TypeParagraph
End If
Next ii
Application.ScreenRefresh
End Sub

VB.net/Excel- "Backwards" tab index For Each iteration with textboxes

I have a form with 3 textboxes and 1 button.
textbox1 has tab index 0, and it's text = 1
textbox2 has tab index 1, and it's text = 2
textbox3 has tab index 2, and it's text = 3
I want to iterate thru the textboxes and place their values into cells so that...
range("A1").value = txtbox1.text (ie: A1 = "1")
range("A2").value = txtbox2.text (ie: A2 = "2")
range("A3").value = txtbox3.text (ie: A3 = "3")
but what I am getting is...
range("A1").value = txtbox1.text (ie: A1 = "3")
range("A2").value = txtbox2.text (ie: A2 = "2")
range("A3").value = txtbox3.text (ie: A3 = "1")
I have tried reversing the tab index for the text boxes, but it doesn't change the "backwards iteration".
Is there something I can do to change this so that the loop runs from lowest tab index to highest?
Thanks!
Public Class Form1
Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim objExcel As New Microsoft.Office.Interop.Excel.Application 'Declaring the object.
objExcel.Visible = True 'Setting Excel to visible.
Dim cntrl As Control
With objExcel
.Workbooks.Add() 'Adding a workbook.
.Range("A1").Select() 'Selecting cell A1.
End With
'Form contains 3 text boxes, with one number in each (1,2,3), and one button to fire the code in this sub.
For Each cntrl In Me.Controls 'For every control on the form...
If TypeOf (cntrl) Is TextBox Then 'If the control is a textbox, then...
With objExcel
.ActiveCell.Value = cntrl.Text 'place the control's text in the active cell and...
.ActiveCell.Offset(1, 0).Activate() 'offset down one row.
End With
End If 'If the control is not a textbox (if it's the button), do nothing.
Next 'Go to the next control.
objExcel = Nothing 'Release the object.
GC.Collect() 'Clean up.
End Sub
End Class
Sounds like it may be the way Excel is iterating over the controls. Have you tried this to see what the output is?
Dim objExcel As New Microsoft.Office.Interop.Excel.Application 'Declaring the object.
objExcel.Visible = True 'Setting Excel to visible.
Dim cntrl As Control
With objExcel
.Workbooks.Add() 'Adding a workbook.
.Range("A3").Select() 'Selecting cell A3.
End With
'Form contains 3 text boxes, with one number in each (1,2,3), and one button to fire the code in this sub.
For Each cntrl In Me.Controls 'For every control on the form...
If TypeOf (cntrl) Is TextBox Then 'If the control is a textbox, then...
With objExcel
.ActiveCell.Value = cntrl.Text 'place the control's text in the active cell and...
.ActiveCell.Offset(-1, 0).Activate() 'offset up one row.
End With
End If 'If the control is not a textbox (if it's the button), do nothing.
Next 'Go to the next control.
objExcel = Nothing 'Release the object.
GC.Collect() 'Clean up.
Using a For Each loop implies that you don't care what order you are doing them in.
What I would do is use the "tag" property of the control to hold the row number you'd like the answer in:
For Each cntrl In Me.Controls
If TypeOf (cntrl) Is TextBox Then
objExcel.ActiveSheet.Cells(cntrl.Tag, 1).Value = cntrl.Text
End If
Next
You could also add a hidden panel on the form that contains only your key textboxes, then use a traditional FOR loop instead of a 'For Each':
Dim i as integer
Dim myBox as textBox
For i = 1 to 3
set myBox = Me.Panel1.Controls(i)
objExcel.ActiveSheet.Cells(myBox.Tag, 1).Value = myBox.Text
Next i
It should go through in Tab order. You can even skip the typecheck, because you already know what it is.