I have the following groups of check-boxes and radio groups and was wondering how I would validate them each separately in VBA. Can anybody point me in the right direction?
For example I would require that at least checkbox is selected in the weeks group and each of the radio button groups (priority, lecturestyle, roomstruc and roomtype) just require a selection to be made. I would appreciate any code to show me how to accomplish this.
weeks - checkboxes
chk_week1, chk_week2, chk_week3, chk_week4, chk_week5,..., chk_week15
priority - radio buttons
priority_y, priority_n
lecturestyle - radio buttons
lecturestyle_trad, lecturestyle_sem
roomstruc - radio buttons
roomstruc_tiered, roomstruc_flat
roomtype - radio buttons
roomtype_lecture, roomtype_lab
You can try something like this. Naming a frame priority could return weird results so I have renamed your frames frPriority and frLectureStyle
Sub cbValidate_Click()
Dim ctl As Control, strOption As String, lLoop As Long
For lLoop = 1 To 15
If Me.Controls("chk_week" & lLoop).Value = True Then GoTo nxtCheck0
Next
MsgBox "You didn't select a week"
nxtCheck0:
For Each ctl In Me.frPriority.Controls
If ctl.Value = True Then GoTo nxtCheck1
Next
MsgBox "You didn't select a priority"
nxtCheck1:
For Each ctl In Me.frLectureStyle.Controls
If ctl.Value = True Then GoTo nxtCheck1
Next
MsgBox "You didn't select a lecture Style"
nxtCheck1:
Unload Me
End Sub
You might try something like the below coding as it gets tedious when you have many controls in group:
Insert a userform named “MyForm with checkboxes named “chk01”, “chk02”….”chk20 or however many checkboxes you want
Put the following declaration in a code module (not the form module)
Public CheckBoxGroup(1 To 20) As New MyForm
Put the following declarations in the form code
Public WithEvents ChkBoxGrp As CheckBox
Initialize the array in the form activate event
Private Sub UserForm_Activate()
Dim i As Integer
For i = 1 To 20 (or however many checkboxes you have
set CheckBoxGroup (i).ChkBoxGrp = MyForm("chk" + Right("0" + CStr(i), 2))
Next i
End Sub
Private Sub ChkBoxGrp_Click()
Select Case val(Right(ChkBoxGrp.Name, 2))
Case 1
‘Do whaever you want for chk01 box
Case 2
‘Do whaever you want for chk01 box
……………
End Select
End Sub
You can use the same event handling for other checkbox events
Related
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
my question is in what event the submit button enable should be written if text boxes are filled, for VBA
for example im talking about the Private sub userform initialize()
i had created a userform where i used 2 frames. while the macro runs it initialize the first frame and user logins using that form to go the next form which is in the other frame.
in this second frame form i have 3 text box fields. only if the user inputs all the three text box then the command button should be enabled. im now stuck with in which event this code should be written.
Thank you
assuming the button is named after "CommandButton1" and the three textboxes are name after "TextBox1", "TextBox1" and "TextBox3", then in the Userform code pane add the following:
In UserForm_Initialize place:
Me.CommandButton1.Enabled = False
add Change event handler for all those three textboxes
Private Sub TextBox1_Change()
checkEnableButton
End Sub
Private Sub TextBox2_Change()
checkEnableButton
End Sub
Private Sub TextBox3_Change()
checkEnableButton
End Sub
finally add the following:
Sub checkEnableButton()
Me.CommandButton1.Enabled = Me.TextBox1.Value <> "" And Me.TextBox2.Value <> "" And Me.TextBox3.Value <> ""
End Sub
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
a question is : how to load a or give value to a combo box list and then call it in my worksheet and get the selected value from it ?i have a module that i want to call my userform1 which include the combobox in it . but when i debug the program it is just a show of the combo box . i think it doesn't do anything ... thanks for your time ..this is the code for user form:
Private Sub UserForm_Initialize()
With ComboBox1
.AddItem "weibull"
.AddItem "log-normal"
.AddItem "gambel"
.Style = fmStyleDropDownList
End With
End Sub
and this is how i ask in my sub to show the combobox:
UserForm1.Show
If ComboBox1.ListIndex = -1 Then
MsgBox "There is no item currently selected.", _
vbInformation, _
"Combo Box Demo"
Exit Sub
End If
MsgBox "You have selected " & ComboBox1.List(ComboBox1.ListIndex) & "." & vbNewLine _
& "It has " & ComboBox1.ItemData(ComboBox1.ListIndex) ", _
vbInformation, _
"Combo Box Demo"
the second part is what i found in net , but it made the program at least to show the combo box !
I thought Siddharth's answer was pretty clear particularly as it was posted from a mobile! However, I had an email from the OP saying he did not understand the answer. I provided the following background which was apparently sufficient to allow him to understand Siddharth's answer and solve his problem. I post it here for the benefit of any other visitor who needs more background on forms than Siddharth provides.
If you select VBA Help and type “userform show” you will get a description of the Show command.
If your user form is named “UserForm1”, you can have statements:
UserForm1.Show
UserForm1.Show vbModal
UserForm1.Show vbModeless
Statements 1 and 2 are equivalent.
The choice of VbModal or vbModeless completely changes the way the user form is controlled.
If a form is shown modeless, the user can see it but cannot access it. If I have a macro that takes a long time, I will use a modeless form to show progress. If I am working down the rows of a large worksheet I might have a form containing:
I am working on row nnnn of mmmm
Each of the boxes is a label. I set the value of the label containing “mmmm” to the number of rows when I start the macro. I set the value of the label containing “nnnn” to the row number at the start of each repeat of my loop. The user sees:
I am working on row 1 of 5123
then I am working on row 2 of 5123
then I am working on row 3 of 5123
and so on.
If it takes the macro five minutes to process every row, this tells the user that something is happening. Without the form, the user might think the macro had failed. With the form, the user knows the macro is busy and they have time to get a fresh cup of coffee.
On the other hand, if the form is shown modal, the macro stops until the user does something that closes or unloads the form with a statement such as:
Unload Me
The positioning of this statement depends on your form. I normally have a Submit button that saves information before ending with this statement.
Once the Unload Me statement is executed, the macro restarts at the statement after the Show statement. When the macro restarts, the form has gone. This is why the form must save anything the macro needs in global variables.
You are trying to access a control when the userform is already closed. And I say closed becuase you are not using vbmodeless to show the form. So the only way the next line after that can run is when the form is closed. Here is what I recommend.
Declare public variables in a module which will hold the relevant values when the useform closes and then use that later. For example
Paste this code in the userform
Option Explicit
Private Sub UserForm_Initialize()
With ComboBox1
.AddItem "weibull"
.AddItem "log-normal"
.AddItem "gambel"
.Style = fmStyleDropDownList
End With
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If ComboBox1.ListIndex <> -1 Then
SelectItem = ComboBox1.List(ComboBox1.ListIndex)
pos = ComboBox1.ListIndex + 1
End If
End Sub
And paste this in a module
Option Explicit
Public SelectItem As String, pos As Long
Sub Sample()
'
'~~> Rest of your code
'
SelectItem = "": pos = 0
UserForm1.Show
If pos = 0 Then
MsgBox "There is no item currently selected.", _
vbInformation, "Combo Box Demo"
Exit Sub
End If
MsgBox "You have selected " & SelectItem & "." & vbNewLine & _
"It is at position " & pos, vbInformation, "Combo Box Demo"
'
'~~> Rest of your code
'
End Sub
Also
There is no .Itemdata property of the Combobox. It is available in VB6 but not in VBA. With .Itemdata property of the Combobox, I guess you were trying to get the position?
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.