I have a UserForm where I have 6 check boxes. The role of check box is to select a unique range in Excel. Each checkbox corresponds to a different range in the Excel sheet.
I want to know what methodology can you use to ensure that when a user select a combination of checkboxes max of 6, Excel selects the corresponding ranges of the selected checkbox.
For example:
Checkbox1 programmed to select range A1
Checkbox2 programmed to select range H3
Checkbox3 programmed to select range F6
If User ticks Checkbox1 and Checkbox2 then how can you tell Excel to select A1 and H3 without using If statements since the combination of 6 check boxes would mean a lot of If statements.
Is there anyway when Checkbox1 is selected it keeps that selection in memory and adds it to the next selection.
Thanks
You would loop over the checkboxes, and build a range using Application.Union() (plenty of examples of that here on SO). When you're done looping then select the built-up range.
Or you can build a string like "H3,F6" and use Range(rangeString).Select
For example:
Sub CheckSelection()
Dim s As String, i As Long, sep
For i = 1 To 6
With Me.Controls("Checkbox" & i)
If .Value = True Then
s = s & sep & .Tag 'ranges are stored in checkboxes' Tag property
sep = ","
End If
End With
Next i
If Len(s) = 0 Then s = "A1" 'default selection if none chosen...
ActiveSheet.Range(s).Select
Debug.Print s
End Sub
Private Sub CheckBox1_Click()
CheckSelection
End Sub
'...
' etc
'...
Private Sub CheckBox6_Click()
CheckSelection
End Sub
Related
I wanted to make a checkbox, calling a macro that hides and unhides columns on Excel worksheet with specific value in cell, but it is not working
I tried the following VBA script
Sub Hide_Forecasts()
Dim c As Range
For Each c In Range("E12:CF12").Cells
If c.Value = "Forecast" Then
c.EntireColumn.Hidden = True
End If
Next c
End Sub
Sub Unhide_Forecasts()
Dim c As Range
For Each c In Range("E12:CF12").Cells
If c.Value = "Forecast" Then
c.EntireColumn.Hidden = False
End If
Next c
End Sub
Sub CheckBox_For()
If CheckBox1.Value = True Then
Call Hide_Forecasts
Else
Call Unhide_Forecasts
End If
End Sub
Please help me out
You haven't said what type of checkbox you're using - Form Control or ActiveX Control.
For an ActiveX Control right-click the control and select View Code.
Use this code that sits behind the worksheet (CheckBox1 will be named after your checkbox).
Private Sub CheckBox1_Click()
Dim Cell As Range
For Each Cell In Me.Range("E12:CF12")
If Cell.Value = "Forecast" Then
'Checkbox returns TRUE/FALSE - Hidden takes TRUE/FALSE so just connect the two up.
Cell.EntireColumn.Hidden = Me.CheckBox1.Value
End If
Next Cell
End Sub
For a Form Control right-click the control and select Assign Macro.
Place this code in a normal module.
Sheet1 is the codename for the sheet (that's the name not in brackets in the Project Explorer).
'Form Control can have three values:
' 1 = Checked
' -4146 = Unchecked
' 2 = Mixed - ignoring that this value may occur.
Public Sub Checkbox_For()
Dim ChkValue As Boolean
'Is value different from -4146? Returns TRUE = Checked or Mixed / FALSE = Unchecked
ChkValue = Sheet1.Shapes("Check Box 1").OLEFormat.Object.Value <> -4146
Dim Cell As Range
For Each Cell In Sheet1.Range("E12:CF12")
If Cell.Value = "Forecast" Then
Cell.EntireColumn.Hidden = ChkValue
End If
Next Cell
End Sub
I need some guidance how to create a selection for a excel userform that when the user selects CB1 which may be in A2, that it will also select the next cell B2 for the populated field and also select the next cell in C2 for the next populated field. I am not sure if my first selection should be a CB and the next fields maybe a list box or text field.
current code is:
Private Sub Userform_Initialize()
ComboBox_Combox5.List=Sheets("Sheet1").Range("A1:A650").Value
End Sub
Add two text boxes next to your combo-box.
I've left them with the default names of TextBox1 and TextBox2.
Code behind the form is:
Option Explicit
Private Sub Userform_Initialize()
ComboBox_Combox5.List = Sheets("Sheet1").Range("A1:A650").Value
End Sub
Private Sub ComboBox_Combox5_Change()
'Reference to selected value in column A.
Dim rng As Range
Set rng = ThisWorkbook.Worksheets("Sheet1").Cells(Me.ComboBox_Combox5.ListIndex + 1, 1)
Me.TextBox1 = rng.Offset(, 1)
Me.TextBox2 = rng.Offset(, 2)
End Sub
Always have Option Explicit at the top of your module.
I have a sheet with a column "N" that contains 30 rows with checkbox inside each one
in vba i want to make a loop that stops at the empty cell, means row 31 , i tried this way :
Private Sub CommandButton1_Click()
Range("N9").Select
Do
If CheckBox1.Value = True Then Call do_OM
ActiveCell.Offset(1, 0).Select
Loop while ActiveCell.value = ""
End Sub
this loop works for only one row , which means a cell with checkbox is an empty cell , while what i want is to stop at cell with no checkbox .. what to do ?
+
How to say " If CheckBox(row number).Value = True ? "
Thanks in advance :)
EDIT
This part will iterate through the non-Active X checkboxes
Since the checkbox isn't tied to the sheet, there isn't really a way to say CheckBox(row number). Also makes sense because there could be multiple boxes on one row.
If the names of the checkboxes align with the row number, however, then you can iterate through them. Well, you can iterate through them anyway, but yeah.
You could do something like:
For i = 1 To 30
ActiveSheet.CheckBoxes(i).Value
Next i
or
For Each chk In ActiveSheet.CheckBoxes
chk.Value
Next chk
To iterate through the boxes. Second one would obviously go through the entire sheet.
I don't think you can check a cell for a box, but you can check what cell the box is in, by using .TopLeftCell.Row which should return the row of the top left corner of the object. Then you could cross-reference that (and perhaps .TopLeftCell.Column) with your range using Intersect.
Excel VBA - Ckeck if cell contains a checkbox Might be of interest. But as I said, it's not really checking if a cell has a check box, it's going through all the checkboxes and checking if any of them are in the cell, using Intersect as I suggested. You can argue that the end result is the same however.
Edit For the comment: This is for ACTIVE X Boxes
Dim nm As Object
Set nm = ActiveSheet.CheckBox1
nm.TopLeftCell.Row
'Iteration
For Each nm In ActiveSheet.OLEObjects
If TypeName(nm.Object) = "CheckBox" Then
debug.print nm.TopLeftCell.row
If nm.Object.Value = True Then ' do stuff
End If
Next nm
ActiveX Checkboxes
Remove, replace or out-comment the Debug.Print lines with something you need e.g. do_OM (Call is considered deprecated).
Note this: ole.Name, but ole.Object.Value.
Option Explicit
Sub CheckBoxExample()
Dim ole As OLEObject
For Each ole In ActiveSheet.OLEObjects
If TypeName(ole.Object) = "CheckBox" Then
Debug.Print
Debug.Print ole.Name, ole.TopLeftCell.Address(0, 0), _
ole.BottomRightCell.Address(0, 0)
If ole.Object.Value = True Then
'do_OM
Debug.Print "Check Box '" & ole.Name & "' is ticked."
Else
Debug.Print "Check Box '" & ole.Name & "' is not ticked."
End If
End If
Next ole
End Sub
Sub CheckBoxExample2()
Dim ole As OLEObject
For Each ole In ActiveSheet.OLEObjects
If TypeName(ole.Object) = "CheckBox" Then
Debug.Print ole.Name, ole.TopLeftCell.Address(0, 0), _
ole.BottomRightCell.Address(0, 0)
With ole.Object
Debug.Print .Caption, .Value
End With
End If
Next ole
End Sub
Just playing around with userform. Pretty new to using them . Created a pretty simple userform that find me the percentage change between two values that I enter. (see image below). I'm just interested in going one step further, I want to know how to enter the values based on excel cells that I select. So in this example, if I select K6, the value 15 enters in current year and if I subsequently click on K8, the value 10 enters in base year). Hope that makes sense, let me know if that is possible. Thanks.
current code....
TextBox3_Change()
TextBox3.Value = Format((Val(TextBox1.Value) - Val(TextBox2.Value)) / Val(TextBox2.Value), "#0.00%")
Rather than clicking, why not load the values in those textboxes in the UserForm_Initialize() event? Something like
Private Sub UserForm_Initialize()
TextBox1.Value = Sheets("Sheet1").Range("K6").Value2
End Sub
If you really want to select a cell (after the userform is shown) and then populate the textboxes, then yes that is also possible. Here is an example
For demonstration purpose, I am going to populate 1 textbox. Let's say our userform looks like this. Note, I added a CommandButton1 next to the textbox. I changed the caption to .... We will use Application.InputBox with Type:=8 so that user can select a range.
Next paste this code in the userform code area
Option Explicit
Private Sub CommandButton1_Click()
Dim rng As Range
On Error Resume Next
'~~> Prompt user to select range
Set rng = Application.InputBox(Prompt:="Select the range", Type:=8)
On Error GoTo 0
'~~> Check if the user selected a range
If Not rng Is Nothing Then
'~~> Check if the range is single cell or not
If rng.Columns.Count > 1 Or rng.Rows.Count > 1 Then
MsgBox "Select single cell"
Exit Sub
End If
TextBox1.Text = rng.Value2
End If
End Sub
Demonstration
This isn't a built-in functionality for userforms (unlock the create a graph dialogue box).
One option would be to have the user start by selecting two cells, and then your code runs and calculates the percentage change in those two cells selected and returns the answer in a pop-up. Another option would be to have the userform automatically populate from preselected cells in your workbook (example below).
Private Sub UserForm_Activate()
Dim ActiveR As Long
ActiveR = ActiveCell.Row
TextBox1.Value = Cells(ActiveR, 1).Value
TextBox2.Value = Cells(ActiveR, 2).Value
TextBox3.Value = Cells(ActiveR, 3).Value
TextBox4.Value = Cells(ActiveR, 4).Value
End Sub
I'm trying to create multiple drop down lists that changes based on which list they want to use.
For example, if they changed the control cell to "List 1", all comboboxes (ActiveX) would change their listfillrange to "=List 1". And if the control cell is changed to "List 2", all comboboxes would update their listfillrange to "=List 2". There's a way to do this with Data Validation but I need the ComboBox function of being able to type and the dropdown would change to show the items in the list beginning with the string that was typed.
I'm a complete beginner with VBA so I do not completely understand nuances compared to languages. I feel that I am missing a lot of proper syntax. I've mashed together some code from searches but none match exactly what I'm looking for so I tried to alter it in some way. I think I butchered a lot of it. I'm so sorry aha
Dim i As Integer
Private Sub ListChange()
If Range("B4").Value = "Bonnie" Then
For i = 1 To 182
' 'Iterate from ComboBox1 to ComboBox182 to change
' listfillrange to 'Bonnie' named range
Set cb = Sheet1.Shapes("ComboBox" & i).OLEFormat.Object.Object
cb.ListFillRange = "=Bonnie"
Next i
ElseIf Range("B4").Value = "Christina" Then
For i = 1 To 182
' Iterate from ComboBox1 to ComboBox182 to change
' listfillrange to 'Christina' named range
Set cb = Sheet1.Shapes("ComboBox" & i).OLEFormat.Object.Object
cb.ListFillRange = "=Christina"
Next i
Else:
For i = 1 To 182
' Iterate from ComboBox1 to ComboBox182 to change
' listfillrange to 'Dianne' named range
Set cb = Sheet1.Shapes("ComboBox" & i).OLEFormat.Object.Object
ComboBox.ListFillRange = "=Dianne"
Next i
End If
End Sub
Also I mentioned that I like using ActiveX ComboBoxes because they show the dropdown dynamically changing as you type the string but I've only been able to make the combobox automatically show the dropdown by having
Private Sub ComboBox1_Change()
Me.ComboBox1.DropDown
End Sub
Private Sub ComboBox2_Change()
Me.ComboBox2.DropDown
End Sub
Is there a way to shorten this or would I have to repeat this for 182 ComboBoxes.
Thank you.