I have spreadsheet with 50+ checkboxes from the forms toolbar. In a few instances you can only check 1 checkbox from a group i.e you check one checkbox from checkbox 1 to checkbox 5.
I'm trying to achieve this without any code if possible. Option button is not preferred since I want an uniformed spreadsheet.
How can you group the checkbox1 to checkbox5 so that they become mutually exclusive for a group.
Thank you
You might want to use a radio button, with possibly a separator between the groups, as this also signifies to the end-user that those fields are mutually exclusive.
A radio button, by definition, is Mutually Exclusive within a group.
Remember that using checkboxes in places where you should be using radio boxes will be confusing your end-users, as they wonder why that checkbox is suddenly de-activated, while when using radio buttons the confusion factor is non-existant.
If you can't use Option Buttons, try this code
Private Sub CheckBox1_Change()
With Me.CheckBox1
If .Value Then ClearGroup .GroupName, .Name
End With
End Sub
Private Sub CheckBox2_Change()
With Me.CheckBox2
If .Value Then ClearGroup .GroupName, .Name
End With
End Sub
Private Sub CheckBox3_Change()
With Me.CheckBox3
If .Value Then ClearGroup .GroupName, .Name
End With
End Sub
Private Sub ClearGroup(sGroup As String, sName As String)
Dim ole As OLEObject
For Each ole In Me.OLEObjects
If TypeName(ole.Object) = "CheckBox" Then
If ole.Object.GroupName = sGroup And ole.Name <> sName Then
ole.Object.Value = False
End If
End If
Next ole
End Sub
Why do you think option (radio) buttons are mutually exclusive? I have two of them in a group. When I click one of them, the other turns on. And there is no way to deselect them. They initially worked as intended, but when I created a second group for an unrelated control with a different link box with two more option buttons, the bizarre behavior began. So far, the best I can do is a separate radio button for each COMBINATION of controls and NO group.
Related
I have created a userform and included a combobox populated with numbers 1 to x in userform.initialize and then added .setfocus and .dropdown commands. For some strange reason the combobox (with dropdown) appears on my lefthand screen outside the userform. The combobox also appears on the userform, but without the dropdown displayed. The screen combobox is active and if I click a number in the dropdown list the code accepts this input.
I have tried deleting the combobox and inserting another one with a different name, but the behaviour persists. If I remove the .dropdown command, the combobox appears correctly on the userform without the screen copy and I can click the userform box and display and use the dropdown list.
On reading an unrelated post, I tried adding .visible=false, followed by .visible=true before the .dropdown command, but that didn't stop the behaviour.
I have tried exporting, deleting and re-importing the userform, but the behaviour persists.
The code I am using (in userform_initialize sub) is:
With cbxGroup 'combobox
.Clear
For i = 1 To PlayGroups
.AddItem i
Next
.ListIndex = -1
.Visible = False
.Visible = True
.SetFocus
.DropDown
End With
Has anyone come across such behaviour before and can explain what has happened, and maybe how to fix it. I can just recreate the userform, but it seems a lot of unnecessary work. I am using Office 365
I can confirm the behaviour.
I strongly assume that this is related to the fact that you are using the Initialize-Trigger. When this trigger is executed, the form is still in the creation-process and some internal properties (eg the exact screen position) are likely not calculated. As a consequence, when calling DropDown, the Combobox is painted on the screen but not at the right position.
You can keep the code to fill the combobox in the Initialize-Trigger, but you should move the SetFocus and DropDown-commands to the Activate-Trigger
Private Sub UserForm_Initialize()
fillCombo
End Sub
Private Sub UserForm_Activate()
showCombo
End Sub
Sub fillCombo()
With Me.cbxGroup
.Clear
Dim i
For i = 1 To PlayGroups
.AddItem i
Next
.ListIndex = -1
End With
End Sub
Sub showCombo()
With Me.cbxGroup
.SetFocus
.DropDown
End With
End Sub
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
Hello I am trying to get the selected value from my ComboBox to work in a subroutine in Module1.
Private Sub UserForm_Initialize()
With ComboBox1
.AddItem "Monday"
.AddItem "Tuesday"
End With
End Sub
I'm basically trying to get the value I selected to be pasted onto "Sheet1". I can get this to work if I call "ComboBox1.value" in the UserForm1, but not Module 1 where it throws an error saying "ComboBox1.value" is not defined. I would appreciate any help!
Sub EmailGenerator()
UserForm1.Show
Worksheets("Sheet1").Range("O5").Value = ComboBox1.Value
End Sub()
The form is an object: it's an instance of the class UserForm1 - one that you didn't explicitly create yourself (see UserForm1.Show for everything that entails), but it's an object nonetheless.
There's an instance of a ComboBox control named ComboBox1, living in that UserForm1 object, and exposed on the form's public interface (exactly as if it were a public property of the form itself!) - that's how you're able to access the control from outside the form's code-behind (note: that's the simplest way to do UI, but there are better, more scalable ways that don't break encapsulation like that and leave the form responsible for its controls and the rest of the code blissfully unaware of the layout of the UI and what the specific controls are, see link above).
VBA doesn't know what ComboBox1 you're referring to, unless you qualify that member call with the object it belongs to, using the . dot operator:
UserForm1.ComboBox1
You could have a UserForm2 that also has a ComboBox1 control, and there could be 20 worksheets, each with their own ComboBox1 control: they can't live in global scope, and they don't.
Thus:
Worksheets("Sheet1").Range("O5").Value = UserForm1.ComboBox1.Value
Or better:
Public Sub EmailGenerator()
With New UserForm1
.Show '<~ form is modal, execution is blocked here until form is closed.
Worksheets("Sheet1").Range("O5").Value = .ComboBox1.Value
End With
End Sub
Try this approach, please:
With UserForm1.ComboBox1
.AddItem "Monday"
.AddItem "Tuesday"
.ListIndex = 0
End With
ActiveSheet.Range("I1").value = UserForm1.ComboBox1.value
No necessary to Show the form for doing that. But, if you do not select anything in combo, nothing will be returned in the cell. If you want to do that in consecutive steps, I would recommend to firstly check if the UserForm1.Visible = True. Only supposing that you want to manually change the combo value and only after that to collect values on the sheet.
But this approach is, at least, strange to me... I only tried to show you how it is possible, but I would not recommend it.
I have a userform with multiple pages, each with textboxes that I want to make sure are numbers before I dump them back into a worksheet.
I have other normal userforms that do this:
Private Sub myTextBox_Exit(ByVal Cancel As MSForms.ReturnBoolean)
OnlyNumbers
End Sub
Private Sub OnlyNumbers()
If TypeName(Me.ActiveControl) = "TextBox" Then
With Me.ActiveControl
If Not IsNumeric(.Value) And .Value <> vbNullString Then
MsgBox "Sorry, only numbers allowed"
.Value = vbNullString
End If
End With
End If
End Sub
This works fine, but when I try to do something similar with this multipage userform it doesn't work.
I tried using
Me.ActiveControl.ActiveControl
but get a "Object doesn't support this property or method" run time error. This would work when the textboxes are inside a frame, but it seems like pages are not treated the same way.
Yeah, this one is tricky. The MultiPage control you can think of as the parent of the controls that sit on top of it. What you need to do is select the MultiPage control first, then select the active control from there.
It looks like:
Me.MultiPage1.Pages(Me.MultiPage1.Value).ActiveControl.Name
The Pages property allows you to select which page you want to select. You can get this by using the index of the MultiPage control (the Index starts at 1). Then you can call the ActiveControl and receive the expected control.
Hope it helps!
I am struggling try to solve an easy problem.
I have check boxes in Sheet 1 and check boxes in sheet 2 that have to assume the same value (TRUE or FALSE) of the ones in Sheet 1.
The problem is that when I open Sheet 2 they are not marked but I have to click on them with the mouse.
I'm using this code:
Sheet2.chk_2A.Value = Sheet1.chk_1a.Value
Am I forgetting an auto update command or something similar?
As far as I can tell there is no need for VBA code here if you link the two check boxes to the same cell. Just assign both check boxes the same cell in Format Control..., Control, Cell link:. If that's not an option then you'll have to place your code into a sub and assign this sub to these check boxes upon click.
In this case your code depends if you used form controls or ActiveX controls. For Form controls you'd have to use
Sheet2.Shapes("chk_2A").controlformat.value = Sheet1.Shapes("chk_1a").controlformat.value
and for ActiveX controls your code suggestion should work if the check boxes are named correctly.
Sheet2.chk_2A.value = Sheet1.chk_1a.value
In both cases I assume that you used either form controls or ActiveX controls. If you used one form control and one ActiveX control then you'll have to adjust the above code suggestions accordingly. The following code can help you determine what you used.
Public Sub AllShapes()
For Each ws In ActiveWorkbook.Worksheets
For Each shp In ws.Shapes
Debug.Print shp.Name
Select Case shp.Type
Case 8
Debug.Print "Form Control"
Case 12
Debug.Print "ActiveX Control"
Case Else
Debug.Print shp.Type
End Select
Next shp
Next ws
End Sub