create a loop, that will fill 300 cells, from 300 checkboxes - excel

I want to write a value (1) into a desired cell within Excel 2007, when I select a checkbox. The checkbox is in a Visual Basic userform, not on the active sheet itself.
The value (1) must revert back to zero when the checkbox is not selected.
I managed to get it working, however, I have more than 300 check-boxes, and want to know how to create one code that will do it in a loop?
{
Private Sub CheckBox1_Click()
If CheckBox1.Value = True Then
ThisWorkbook.Sheets("sheet3").Range("b8").Value = 1
Else: ThisWorkbook.Sheets("sheet3").Range("b8").Value = 0
End If
End Sub
Private Sub CheckBox2_Click()
If CheckBox2.Value = True Then
ThisWorkbook.Sheets("sheet3").Range("b9").Value = 1
Else: ThisWorkbook.Sheets("sheet3").Range("b9").Value = 0
End If
End Sub
Private Sub CheckBox3_Click()
If CheckBox3.Value = True Then
ThisWorkbook.Sheets("sheet3").Range("b10").Value = 1
Else: ThisWorkbook.Sheets("sheet3").Range("b10").Value = 0
End If
End Sub
}
from checkbox 1 to checkbox 300, the cell range will be "B8" all the
way to "B308"
checkbox1 = cell range b8
checkbox2 = cell range b9
checkbox3 = cell range b10
checkbox4 = cell range b11
etc.......

Use IIf to set a value based on True or False.
Private Sub CheckBox1_Click()
ThisWorkbook.Sheets("sheet3").Range("B8").Value = IIf(CheckBox1.Value, 1, 0)
End Sub
Private Sub CheckBox2_Click()
ThisWorkbook.Sheets("sheet3").Range("B9").Value = IIf(CheckBox2.Value, 1, 0)
End Sub
Private Sub CheckBox3_Click()
ThisWorkbook.Sheets("sheet3").Range("B10").Value = IIf(CheckBox3.Value, 1, 0)
End Sub

I don't know how your workbook/userform looks in detail, but this should show pretty good how to do it:
First, we need the class which we will call Class1. In this class we put the code:
Option Explicit
Public WithEvents CBoxC As MSForms.CheckBox
Private Sub CBoxC_Change()
Dim i As Long
i = CLng(Replace(CBoxC.Name, "CheckBox", ""))
Sheet3.Cells(i + 7, 2).Value = 0 - CBoxC.Value
End Sub
Now we need a variable which "transfere" the events to our class. We jast add to any module:
Option Explicit
Public CBox() As New Class1
As the last step, we need to insert all the controls into our variable. So we add (or just include, if already there):
Option Explicit
Private Sub UserForm_Initialize()
Dim b As Variant
For Each b In Me.Controls
If TypeName(b) = "CheckBox" Then
If (0 / 1) + (Not Not CBox) = 0 Then ReDim CBox(0) Else ReDim Preserve CBox(UBound(CBox) + 1)
Set CBox(UBound(CBox)).CBoxC = b
End If
Next
End Sub
Instead of _Click we better use _Change. This way also keyboard-input will work...
As it is pretty much no code, it also should be self explaining. Just keep in mind, that such events will come last. (which should not matter in your case)
If you still have any questions, just ask ;)

Related

VBA -- Using a Userbox checkbox as show below, how do I set the value of a variable using a checkbox and then use that variable in a Module?

So currently, I have the following in a Userbox in VBA; a checkbox and a close window button.
Private Sub CheckBox1_Click()
If CheckBox1.Value = True Then vb1 = -1 Else vb1 = 1
End Sub
Private Sub CommandButton1_Click()
UserForm1.Hide
End Sub
And I have this in my Module.
Option Explicit
Sub GetRangeData_inputbox()
Dim vb1, vb2, vb3, vb4, vb5, vb6, vb7 As Integer
Range("c3") = vb1 * 1000
The primary purpose of the userbox is to check a box. I opted for a userbox since there are many of these boxes to be checked, but I only put one in for simplistic purposes.
The Goal of this is for a box to be checked, change vb1 to -1, or vb1 to 1 if the box is checked or unchecked, then, in the module, flow into a formula that does 1,000 (for example)*VB1.
Let me know,
Thanks!
To use a variable in a sub you must declare it like this Sub GetRangeData_inputbox(vb1 As Integer) and then you must call the sub in the CheckBox1_Click() event.
Here is a proof of concept:
Private Sub CheckBox1_Click()
Dim vb1 As Integer
If CheckBox1.Value = True Then vb1 = -1 Else vb1 = 1
Call GetRangeData_inputbox(vb1)
End Sub
And in the module:
Sub GetRangeData_inputbox(vb1 As Integer)
Range("c3") = vb1 * 1000
End Sub
Also you can replace UserForm1.Hide with UserForm1.Unload, unless you have a reason for hiding it.

Multiple Checkboxes Conditions in VBA - No Two or more Checkboxes to be selected

I need the help with the selection of multiple checkboxes by user. I have a userform in vba that has 8 checkboxes. I want user to select only ONE checkbox at a time. What is the shortest coding possible?
Please, try the next way:
Create a Sub able to untick all the check boxes, except the active one:
Public Sub UnTickCheckBoxes() 'Public to be also called from outside if use a class for event allocation
Dim i As Long
For i = 0 To Me.Controls.count - 1
If TypeName(Me.Controls(i)) = "CheckBox" And Not ActiveControl.Name = Me.Controls(i).Name Then
Application.EnableEvents = False
Me.Controls(i).value = False
Application.EnableEvents = True
End If
Next i
End Sub
Call the above sub from the Click event of all check boxes. You can use Change event for doing something else. The call can be done in this way:
Private Sub CheckBox1_Click()
If ActiveControl.value = True Then
UnTickCheckBoxes
End If
End Sub
2 bis. Automatic event allocation to all check boxes:
2.1 Create a class named "chkBoxesClickEvent". Copy and paste in it the next code:
Option Explicit
Public WithEvents chkBEvent As MSForms.CheckBox
Private Sub chkBEvent_Click()
If chkBEvent.value = True Then
chkBEvent.Parent.UnTickCheckBoxes
End If
End Sub
2.2 Declare on top of the form (in the declarations area) the next variable:
Private chkB() As New chkBoxesClickEvent
2.3 Place the next code in the UserForm_Initialize event:
Private Sub UserForm_Initialize()
Dim C As MSForms.Control, k As Long
ReDim chkB(Me.Controls.count): k = 1
For Each C In Me.Controls
If TypeOf C Is MSForms.CheckBox Then
Set chkB(k).chkBEvent = C: k = k + 1
End If
Next
ReDim Preserve chkB(k - 1)
End Sub
Do not forget to clear all check boxes Click event, if any code inside...
Show the form a see how it works, then send some feedback.

Excel VBA code to update the hide/unhide rows functions when a new row is added within the range wanted to be hidden

I currently have a code as follows to hide a range of cells when an activeX checkbox is clicked:
Version 1:
Private Sub CheckBox1_Click()
If CheckBox1.Value = True Then
Rows("14:30").Hidden = False
Else
Rows("14:30").Hidden = True
End If
End Sub
Private Sub CheckBox2_Click()
If CheckBox2.Value = True Then
Rows("32:38").Hidden = False
Else
Rows("32:38").Hidden = True
End If
End Sub
Private Sub CheckBox3_Click()
If CheckBox3.Value = True Then
Rows("40:54").Hidden = False
Else
Rows("40:54").Hidden = True
End If
End Sub
Version 2:
Private Sub CheckBox1_Click()
[14:30].EntireRow.Hidden = Not CheckBox1
End Sub
Private Sub CheckBox2_Click()
[32:38].EntireRow.Hidden = Not CheckBox2
End Sub
Private Sub CheckBox3_Click()
[40:54].EntireRow.Hidden = Not CheckBox3
End Sub
THE PROBLEM:
Both versions work fine BUT the problem is that when a new row is added within the ranges specified, the row specifications obviously do not update as they are not variables.
NOTE: There are more than 3 ActiveX checkboxes. I've got about 19.
QUESTION
I know the ranges need to be put to an integer or a variable but I am only new to VBA and not even a programmer (studied a few programming applications in college 4 years ago so can read code a bit) so I have no idea how to do it. Currently working on automating an excel file at work and WOULD LOVE YOUR HELP PLEASEEEE! I have been struggling for days on this :(
Excel file looks like this:
Thank you in advance!!
You need to dynamically determine the starting row and end row for each section. This should work for the top A - General section.
Option Explicit
Private Sub CheckBox1_Click()
Dim m1 As Variant, m2 As Variant
m1 = Application.Match("A -*", Columns(1), 0)
m2 = Application.Match("B -*", Columns(1), 0)
If IsError(m1) Or IsError(m2) Then Exit Sub
With Range(Cells(m1 + 1, "A"), Cells(m2 - 1, "A"))
.EntireRow.Hidden = Not CheckBox1.Value
End With
End Sub

Fill a textbox with varaible text depending on Radio Button selection combo (VBA Excel)

I need some help with getting the right code to do the following:
I have 4 groups of radio buttons inside a frame in a userform
Each group is a simple Yes/No radio button
I have a textbox that I want to autofill with a score range of A-D depending on the # of "yes" radio buttons selected.
The "No" checkboxes really shouldn't do anything in regards to the textbox
Userform Name = TP_UF
Frame Name = fun_opt_frame
Option Button Name for "Yes" = fun_score_yes1-4
Textbox Name = fun_scorebox
Logic:
4 Yesses = A
3 Yesses = B
2 Yesses = C
1 Yes = D
It doesn't matter what order the yesses are selected, its a total count. I tried using code using the frame but not sure if that is the best way. The frame for these radio buttons isn't needed for any reason other then to perhaps make it easier to code. So I could throw out the frame if it's not necessary to get this working.
I am not sure where to start here. Any help would be appreciated.
pic
The quickest and easiest way for you to understand is - I guess - the following code. You have to put the code into the class module of the userform.
Option Explicit
Dim opt1 As Byte
Dim opt2 As Byte
Dim opt3 As Byte
Dim opt4 As Byte
Private Sub opt1Yes_Click()
opt1 = 1
EvalOpt
End Sub
Private Sub opt1No_Click()
opt1 = 0
EvalOpt
End Sub
Private Sub opt2yes_Click()
opt2 = 1
EvalOpt
End Sub
Private Sub opt2No_Click()
opt2 = 0
EvalOpt
End Sub
Private Sub opt3yes_Click()
opt3 = 1
EvalOpt
End Sub
Private Sub opt3No_Click()
opt3 = 0
EvalOpt
End Sub
Private Sub opt4yes_Click()
opt4 = 1
EvalOpt
End Sub
Private Sub opt4No_Click()
opt4 = 0
EvalOpt
End Sub
Private Sub EvalOpt()
Dim sumOpt As Byte
Dim res As String
sumOpt = opt1 + opt2 + opt3 + opt4
Select Case sumOpt
Case 1: res = "D"
Case 2: res = "C"
Case 3: res = "B"
Case 4: res = "A"
Case Else: res = ""
End Select
Me.fun_scorebox.text = res
End Sub
I assumed the option buttons are named opt1Yes, opt1No, opt2Yes, opt2No etc.
A more advanced solution would probably be to use classe modules and "collect" the option buttons in such a way.
I ended up going about this differently and I got it working using a counter. Thanks for the help! Posting code here in case anyone else needs it.
Option Explicit
Private Sub OptionButton1_Change()
set_counter
End Sub
Private Sub OptionButton2_Change()
set_counter
End Sub
Private Sub OptionButton3_Change()
set_counter
End Sub
Private Sub OptionButton4_Change()
set_counter
End Sub
Private Sub OptionButton5_Change()
set_counter
End Sub
Private Sub OptionButton6_Change()
set_counter
End Sub
Private Sub OptionButton7_Change()
set_counter
End Sub
Private Sub OptionButton8_Change()
set_counter
End Sub
Private Sub set_counter()
Dim x As Integer, counter As Integer
Me.TextBox1.Value = ""
counter = 0
For x = 1 To 8 Step 2
If Me.Controls("OptionButton" & x).Value = True Then counter = counter + 1
Next x
Me.TextBox1.Value = Choose(counter, "D", "C", "B", "A")
End Sub
Private Sub UserForm_Activate()
Me.TextBox1.Value = ""
End Sub
Private Sub UserForm_Click()
Dim x As Integer
Me.TextBox1.Value = ""
For x = 1 To 8
Me.Controls("OptionButton" & x).Value = False
Next x
End Sub

Loop repeated code to set userform checkbox values

I've a dashboard that uses a userform box field with checkboxes to choose what data to display on a chart.
My code is very copy and pasted.
Private Sub CommandButton21_Click()
UserForm1.Show
If Worksheets("Data Directorate").Range("X4").Value = True Then UserForm1.CheckBox1 = True
If Worksheets("Data Directorate").Range("X5").Value = True Then UserForm1.CheckBox2 = True
If Worksheets("Data Directorate").Range("X6").Value = True Then UserForm1.CheckBox3 = True
Is there a way to use a loop to do this?
I've more repeated code later on:
Private Sub CheckBox1_Click()
Select Case CheckBox1.Value
Case True
Worksheets("Data Directorate").Range("X4").Value = True
Case False
Worksheets("Data Directorate").Range("X4").Value = False
End Select
End Sub
This repeats for 24 check boxes. Would it be possible to loop this?
All great advice posted in this thread, so I'd like to add something that can maybe help to simplify your loops. Controls have a Tag property which, as best I can tell, does nothing other than to store additional information about the control.
Using this to our advantage, we can include the linked cell in the Tag property for each checkbox. (For example, enter X4 into the Tag for linkage to cell X4). This permits for less of the information to be hardcoded, which makes it more adaptable.
Finally, the code would look like this.
Private Sub UserForm_Click()
For Each octrl In Me.Controls
If TypeName(octrl) = "CheckBox" Then
Sheet1.Range(octrl.Tag).Value = octrl.Value
End If
Next octrl
End Sub
My approach in this scenario would be:
Set ControlSource property of the checkboxes to appropriate cells, leave only:
UserForm1.Show
One thing to simplify: instead of using If statements, just make the two sides equal. Like this:
Private Sub CommandButton21_Click()
UserForm1.Show
UserForm1.CheckBox1 = Worksheets("Data Directorate").Range("X4").Value
And the other one:
Private Sub CheckBox1_Click()
Worksheets("Data Directorate").Range("X4").Value = CheckBox1.Value
End Sub
I recommend using the change event instead of the click event. Some user might use Tab and Space, then the click event won't trigger. Like this:
Private Sub CheckBox1_Change()
...
About looping through the checkboxes in the CommandButton21_Click event, that depends on the order of your checkboxes and your table. This might work, but you will have to try it on your table (the order of the checkboxes compared to the order of your cells can ruin the game...)
Dim contr As control
dim i as integer
i=4
For Each contr In UserForm1.Controls
If TypeName(contr) = "CheckBox" Then
contr.Value = cells(i,24).Value 'column 24 is column X
i=i+1
End If
Next
A possible variation to work when CheckBoxes are not in the expected order or get added/removed:
Dim contr As control
Dim J as Integer
Dim Offset as Integer
Offset = 3 'set this to the difference between 1 and the first row containing data
For Each contr In UserForm1.Controls
If TypeName(contr) = "CheckBox" Then
'set j to the checkboxes "number"
J = cInt(right(contr.name, len(contr.name) - len("CheckBox")))
'use the checkbox number + offset to find the row we want
contr.Value = cells(J + Offset,24).Value 'column 24 is column X
End If
Next
Hope this helps.
For the second portion of your question:
Private Sub CheckBox1_Click()
Worksheets("Data Directorate").Range("X4").Value = CheckBox1.Value
End Sub
You can group the checkboxes inside a given frame and try the the following
Sub Test()
Dim i As Long
i = 5
For Each cb In UserForm1.Frame1.Controls
If Worksheets("Data Directorate").Range("X" & i).Value = True Then cb.Value = True
i = i + 1
Next cb
End Sub

Resources