Limit to only 1 selected checkbox - excel

I have imported a table with check-boxes from Access to Excel. Is it possible to set the check-boxes where only one check-box can be selected from that imported table when using Excel?

In the comments Jeeped made an excellent point that radio buttons already have the functionality that you are looking for. On the other hand -- if you prefer the aesthetics of checkboxes then you can certainly use them. I created a userform with two checkboxes in a frame (and no other controls in the frame) and also included a label for displaying the chosen option. The following code deselects all other checkboxes in the frame when one is selected. I used a non-local Boolean variable to circumvent the other checkbox's event handlers while they were being changed to avoid a sort of echo effect I ran into where the events were firing when I didn't want them to (perhaps there is a less kludgy way to do that). The code easily extends to any number of checkboxes in a grouping frame.
Dim selecting As Boolean 'module level variable
Private Sub SelectOne(i As Long)
Dim c As Control
selecting = True
For Each c In Frame1.Controls
If c.Name <> "CheckBox" & i Then c.Value = False
Next c
DoEvents
Label1.Caption = i & " selected"
selecting = False
End Sub
Private Sub CheckBox1_Click()
If Not selecting Then SelectOne 1
End Sub
Private Sub CheckBox2_Click()
If Not selecting Then SelectOne 2
End Sub

I think this works best and its much easier - at least for a few boxes - for more you could write some formulas in excel and drag down then copy as values and copy paste text from excel into vba. Anyway, here it's how I did it:
I went and created code under each button - quite basic
Private Sub DateCheckBox1_Click()
If DateCheckBox1.Value = True Then
DateCheckBox2.Value = False
DateCheckBox3.Value = False
End If
End Sub
Private Sub DateCheckBox2_Click()
If DateCheckBox2.Value = True Then
DateCheckBox3.Value = False
DateCheckBox1.Value = False
End If
End Sub
Private Sub DateCheckBox3_Click()
If DateCheckBox3.Value = True Then
DateCheckBox2.Value = False
DateCheckBox1.Value = False
End If
End Sub

Related

Object required error enabling/disabling combobox/checkbox based on a combobox

I'm working on a sheet that has a repeating series of one combobox linked to one other combobox and a checkbox.
The first box has four selectable options.
If either of the first two options is selected, both the second combobox and the checkbox should be disabled.
If either of the last two options is selected, the second box and checkbox should both become enabled.
When I first set up this code, everything worked. I accidently threw myself into an endless loop and had to start with the "Excel recovered" worksheet, which scrubbed all my controls.
I re-did the controls. Now when I open the workbook, I have to click through fifty (yes, no joke, five-zero) instances of an "object required" run-time error. The same thing happens when I close the workbook. But when I clear all the errors, the code runs. Using "Option Explicit" gives me a "variable not defined" error.
I can't identify any variables which need defining.
Sub ComboBox1_Change()
If ComboBox1.ListIndex = 2 Or ComboBox1.ListIndex = 3 Then
ComboBox6.Enabled = True
CheckBox1.Enabled = True
Else: ComboBox6.Enabled = False
CheckBox1.Enabled = False
End If
End Sub
This is for one instance. I have twenty-five of these repeated, one after the other, in my project.
FYI you can avoid most of that replicated code by using a naming scheme which allows you to associate your sets of 3 controls: eg see below. Then you can have one single procedure which performs the checks, given the first combobox as an argument.
e.g. (you can probably come up with more-meaningful names based on what your controls actually represent):
ComboBox1 - ComboBox1_2 - chkComboBox1
ComboBox2 - ComboBox2_2 - chkComboBox2
ComboBox3 - ComboBox3_2 - chkComboBox3
Then your code can look like this:
Option Explicit
Private Sub ComboBox1_Change()
ProcessChange ComboBox1
End Sub
Private Sub ComboBox2_Change()
ProcessChange ComboBox2
End Sub
'process the supplied combobox value and set properties of
' any related controls
Sub ProcessChange(cmbo As ComboBox)
Dim en As Boolean
en = cmbo.Value = 2 Or cmbo.Value = 3
Me.OLEObjects(cmbo.Name & "_2").Object.Enabled = en
Me.OLEObjects("chk" & cmbo.Name).Object.Enabled = en
End Sub

Either of the checkbox can only be true

Situation
I have two form control check boxes. I am trying to write a code that will allow only either of them to be true.
my code is
Sub CheckBox2_Click()
If CheckBox1.Enabled = True Then
CheckBox2.Enabled = False
Else
If CheckBox2.Enabled = True Then
CheckBox1.Enabled = False
End If
End If
End Sub
I have this code in module and have assigned the same macro for both the checkboxes. I get run-time error 424. I beleive this is very basic problem but I unable to dela with it.
Thank you
Please, test the following way. Form check boxes do not have a click event, as ActiveX ones have. You should associate the next sub to both of them. The check boxes I tested, have their names as "Check Box 1" and "Check Box 2". You have to change yours according to the reality in your case, Please, copy the next code in a standard module and then associate it to both used check boxes:
Option Explicit
Sub FormCheckBoxChange()
If ActiveSheet.CheckBoxes(Application.Caller).value = 1 Then
Select Case Application.Caller
Case "Check Box 1": ActiveSheet.CheckBoxes("Check Box 2").value = -4146
Case "Check Box 2": ActiveSheet.CheckBoxes("Check Box 1").value = -4146
End Select
End If
End Sub
Use instead of the used check box names, the appropriate ones for your case.
In case of Form text boxes, their value is not True and False as in case of ActiveX ones. It is 1 and -4146...
Are you sure you want to enable/disable the checkboxes.
Following code makes sure that either one of both boxes is checked.
Public Sub checkbox2_onClick()
Dim oCb1 As Object
Set oCb1 = Table1.Shapes("Checkbox1").OLEFormat.Object
Dim oCb2 As Object
Set oCb2 = Table1.Shapes("Checkbox2").OLEFormat.Object
If oCb2.Value = 1 Then oCb1.Value = 0
End Sub
Public Sub checkbox1_onClick()
Dim oCb1 As Object
Set oCb1 = Table1.Shapes("Checkbox1").OLEFormat.Object
Dim oCb2 As Object
Set oCb2 = Table1.Shapes("Checkbox2").OLEFormat.Object
If oCb1.Value = 1 Then oCb2.Value = 0
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

Assigning Excel VBA ActiveX ListBox .Selection to a TextBox

I'm trying to click a selection on an ActiveX ListBox and have value assigned to a TextBox then clear the ListBox. It seems straightforward but I'm
getting 'Object doesn't support this property or method' on the first line
This is what I'm using:
Private Sub ListBox1_Click()
ActiveSheet.OLEObjects("TextBox3").Object.Value = ActiveSheet.OLEObjects("ListBox1").Object.Selection
ActiveSheet.OLEObjects("ListBox1").Object.Selection = ""
End Sub
Any thoughts on how to make this word or resources to search are appreciated.
Your code would be cleaner written like this:
Private Sub ListBox1_Click()
TextBox1.Value = ListBox1.Text
ListBox1.Selected(ListBox1.ListIndex) = False
End Sub
But there is a problem: the second line doesn't work inside the ListBox1_Change event (because it would create an infinite loop). I tried with Application.EnableEvents = False, but it didn't help.
I think you need to put the reset of the selection in another event, like the KeyUp or MouseUp.

Excel VBA: Can't deselect ListBox items from listbox

I have a command button that processes selected items in a ListBox (ListBox4). While i CAN deselect all the items in that command's Click() procedure, I wanted to, if the user clicked in the ListBox, to THEN deselect everything in the ListBox, prior to their selecting again.
I have code like the following, but it never seems to get called:
Private Sub ListBox4_Click()
If Apply_Format_Occurred Then
For i = 0 To ListBox4.ListCount - 1
ListBox4.Selected(i) = False
Next i
End Sub
Do i need an outside command, etc to do this? I was hoping to be able to do it like how i described.
Any help is greatly appreciated!
thanks,
Russ
You can use the GotFocus event of the ListBox so the code runs when the ListBox receives focus from the user.
Here is an example showing coding for the button and the ListBox:
Dim Apply_Format_Occurred As Boolean
Private Sub CommandButton1_Click()
'<other processes>
Apply_Format_Occurred = True
End Sub
Private Sub ListBox4_Change()
If Apply_Format_Occurred Then
For i = 0 To ListBox4.ListCount - 1
ListBox4.Selected(i) = False
Next i
Apply_Format_Occurred = False
End If
End Sub
I see this thread is old and maybe there is an easy or more elegant way to un-select a list box item. But, I figured out a way for my needs. In my case I wanted the list box to un-select only if the same item was clicked. If a new item was clicked, it would be selected as normal. I had to use two static variable (a boolean and "old selection" placeholder).
There's probably a much easier way. But, I'm new to it and and couldn't find it. Hope this helps. Setting selectedindex to -1 unselects everything. Altenatively and as effective is listboxName.ClearSelected()
Private Sub lstPendingQuotes_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstPendingQuotes.Click
Static blnSelectable As Boolean = True 'use static boolean to retain value between calls
Static objOldSelected As Object = lstPendingQuotes.SelectedIndex 'use old selected in case a different index is selected
'if nothing is already selected (as in first form open) allow the selection but change boolean to false and set the OldSelected variable to the current selection
If blnSelectable Then
blnSelectable = False
objOldSelected = lstPendingQuotes.SelectedIndex
ElseIf lstPendingQuotes.SelectedIndex = objOldSelected Then 'if an item is selected and the same item is clicked un-select all and reset boolean to true for a new possible selection
lstPendingQuotes.SelectedIndex = -1 'can substitute lstPendingQuotes.ClearSelected()
blnSelectable = True
Else 'If a different index is chosen allow the new selection and change boolean to false so if the same item is clicked it will un-select
objOldSelected = lstPendingQuotes.SelectedIndex
blnSelectable = False
End If
End Sub
I had an onclick event for my listbox. I tried listbox.listindex=-1 at the end of the code in that event. It wouldn't work.
I created a separate AfterUpdate event with the single line:
listbox.ListIndex = -1
works like a charm

Resources