Currently I have 5 group boxes all filled with checkboxes, when I want to unselect all of them (for a 'clear selection' button), I use this code that I found on a forum:
For Each CheckBox In grpbox_Hiragana
CheckBox.checked = "false"
Firstly, I'm sure if this is the correct way to unselect the checkboxes, secondly the "grpbox_Hiragana" groupbox returns the following error:
Expression is of type 'System.Windows.Forms.GroupBox', which is not a collection type
If anyone could confirm this is the correct way of doing this/ help fix the error by telling me why the groupbox won't be accepted that would be great.
if you have all check box on one group box use this code :
Dim ChkBox As CheckBox = Nothing
' to unchecked all
For Each xObject As Object In Me.GroupBox1.Controls
If TypeOf xObject Is CheckBox Then
ChkBox = xObject
ChkBox.Checked = False
End If
Next
' to checked all
For Each xObject As Object In Me.GroupBox1.Controls
If TypeOf xObject Is CheckBox Then
ChkBox = xObject
ChkBox.Checked = True
End If
Next
Or you can use CheckedListBox Control.
A alternative with less lines of code is:
For Each ChkBox As CheckBox In GroupBox1.Controls
ChkBox.Checked = False
Next
Incidentally your code would have worked if you added .controls, the As CheckBox just enables the intellisense (and also ensures it is only Checkbox's that are processed) .
Related
I have a ListBox called ListBox1 and I want to select all of the values automatically when opening the form. How can I do this?
My ListBox looks something like this
You can either in your script set all of the checkboxes to true with this piece of code that will loop over all of your different controls and set the checkbox ones to true
Dim currentControl As Control
For Each currentControl In Me.Controls
If TypeOf currentControl Is msforms.CheckBox Then
currentControl.Value = SelectAllCheckBox.Value
End If
Next
or you can put this code in a button called 'Select All' that will on click select all of the checkboxes.
Use For Loop and embed it in userform initialise event.....
For i = 0 To MyListBox1.ListCount - 1
MyListBox1.Selected(i) = True
Next i
This might help.
I have a checkbox and if the checkbox.Value = False I want to disable my TextInput-Object. On the internet there where some suggestions, but the methods which were used are not working for me, because the methods are not found.
I tried it with the .Valid-method:
Dim tf As TextInput
Dim checkbox As CheckBox
Sub checkbox_click()
Set checkbox = ActiveDocument.FormFields("checkbox").CheckBox
Set tf = ActiveDocument.FormFields("textfield").TextInput
If checkbox.Value = False
tf.Valid = False
End If
End Sub
But that doesn't work for some reason. I found tf.Enabled = False on the internet, but this method is unknown in my case.
You need something more like this:
Dim ff As FormField
Dim checkbox As CheckBox
.
.
Set checkbox = ActiveDocument.FormFields("checkbox").CheckBox
Set ff = ActiveDocument.FormFields("textfield")
If checkbox.Value = False
ff.Enabled = False
End If
With legacy FormField objects, some of the properties you need are associated with the FormField itself, and others are associated with child objects of the FormField such as the FormField.Checkbox
So the problem here is that tf is a FormField.TextInput object, but .Enabled is a property of the FormField object.
Not relevant to your question, but just as an observation, FormFields do not have Word events associated with them in the normal sense of VBA Events. The settings of each field tell Word to run a named Sub "on entry" and/or "on exit" - that's it. No actual click events. No problem with using names that makes those things look like events but I just thought I'd mention it.
Whilst the internet can be helpful you should also use the Object Browser in the VBE along with Help. 5 seconds spent doing a search for FormField would have given you the answer.
Dim tf As TextInput
Dim checkbox As CheckBox
Sub checkbox_click()
Set checkbox = ActiveDocument.FormFields("checkbox").CheckBox
If checkbox.Value = False
ActiveDocument.FormFields("textfield").Enabled = False
End If
End Sub
I can't for the life of me find how to set a form control checkbox background to transparent
Dim cb As CheckBox
For Each cb In ActiveSheet.CheckBoxes
cb.Value = -4146
cb.Interior.Color = ???
Next cb
To be clear I'm talking about a Forms checkbox on a worksheet, not on a form and not an ActiveX checkbox (Developer menu > Insert > Form Controls).
I recorded a macro and got this but I'm wondering if there's a way to do it via the Checkbox object rather than use the Shape object. Even a link to the MSDN Dev page for a Form Controls checkbox would help as I can't find it!
ActiveSheet.Shapes("cb1_1").Fill.Visible = msoFalse
cb.Interior.ColorIndex = xlNone
I know the title is a bit confusing so let me make myself as clear as possible.
In an Access form (2010), I have a set of text fields meant to contain dates. Those fields are all optional, the user can fill in any number of dates.
To make it more user-friendly, I want to associate each field to a toggle button. Then I want 2 things to happen :
On CURRENT event :
If a text field has a value, then it is visible and the toggle button
associated with it is pressed.
If a text field is empty, then it is not visible and the toggle button isn't pressed.
On CLICK of a toggle button :
If the text field associated with it has a value, then this field gets cleared (and invisible) and the toggle button gets de-pressed ;
If the text field associated with it is empty, then the focus is set on it and the toggle button gets pressed (and stay that way if a value is entered in the text field, otherwise everything gets back the way it was, invisible and unpressed).
So far I've achieved the first step by setting two collections of controls based on some examples I found online.
So, when the form is loaded, I call this :
Private mcolGroupTxToggle As New Collection
Private mcolGroupBuToggle As New Collection
Private Sub InitializeCollections()
Dim ctl As Control
If mcolGroupTxToggle.Count = 0 Then
For Each ctl In Me.Controls
If ctl.Tag = "txtoggle" Then
mcolGroupTxToggle.Add ctl, ctl.Name
End If
Next ctl
Set ctl = Nothing
End If
If mcolGroupBuToggle.Count = 0 Then
For Each ctl In Me.Controls
If ctl.Tag = "butoggle" Then
mcolGroupBuToggle.Add ctl, ctl.Name
End If
Next ctl
Set ctl = Nothing
End If
End Sub
And on Form_Current event, I call that :
Private Sub OnLoadToggles(mcol As Collection, pcol As Collection)
Dim ctl As Control
Dim btn As Control
Dim strBtn As String
For Each ctl In mcol
'Every button has the same name than the textbox + "b"
strBtn = ctl.Name & "b"
For Each btn In pcol
If btn.Name = strBtn Then
If IsNull(ctl) Then
ctl.Visible = False
btn.Value = False
Else
ctl.Visible = True
btn.Value = True
End If
End If
Next btn
Next ctl
Set ctl = Nothing
End Sub
Everything works well so far, but I'm not sure that's the best way to do it and I figured I would need to repeat some lines in step 2.
Making the distinction between text boxes and buttons in the procedure seems weird, I feel like it should be done prior so that I don't have to do it in every procedure. I also feel like it would be better to loop through each pair of controls (text + button) instead of each control in both collections.
Basically, I'm wondering if it would be (1) better and (2) possible to have something as simple as this :
Private Sub OnLoadToggles(Collection of pairs)
for each [pair of txt and btn]
if isnull(txt) Then
txt.visible = false
btn.value = false
else
...
end if
...
My guess is that I would need to make a public sub where I set a collection of pairs of buttons and text fields based on their tags (there are other controls in my form that need to be left alone) and names, but I'm not sure how, I'm a beginner in VBA.
Any suggestions please ?
-- Edit step 2 --
Thanks to Andre's answer the second part was easier than I thought. I've updated my sample database. So on click events I call this :
Private Sub ClickToggles()
Dim ctl As Control
Dim btn As Control
Dim strBtn As String
Dim strCtl As String
strBtn = Me.ActiveControl.Name
strCtl = Left(strBtn, Len(strBtn) - 1)
Set ctl = Me(strCtl)
Set btn = Me(strBtn)
If IsNull(ctl) Then
btn.Value = True
ctl.Visible = True
ctl.Enabled = True
ctl.SetFocus
Else
ctl.Value = ""
btn.Value = False
ctl.Visible = False
End If
End Sub
It's not perfect but it works. Probably not a good idea to clear the data at this point because misclicks may happen. It would be better to loop through the textboxes right before saving the form and clear values of invisible and/or disabled controls from the collection. I might to that later.
I had to add the .enabled property next to the .visible one because on lostfocus events I was getting an error saying the control was still active so it couldn't make it not visible.
Right now I'm more concerned about the amount of click and lost focus events. I'd rather have some public functions and event handlers dealing with it but it's getting too complicated for me. I'll get back to it when I know more about... everything.
Suggestions are still welcome anyway =) !
Since your control pairs are "paired" by their name anyway, you don't need any fancy constructs, or even the second collection. Just address the matching control directly by its name.
Instead of using If/Else for setting boolean properties, it is usually easier to assign a variable to the property.
Private Sub OnLoadToggles(mcol As Collection)
Dim ctl As Control
Dim btn As Control
Dim strBtn As String
Dim bShowIt As Boolean
For Each ctl In mcol
'Every button has the same name than the textbox + "b"
strBtn = ctl.Name & "b"
' If you have the control name, you can get the control directly:
Set btn = Me(strBtn)
' Using a variable you don't need If/Else
bShowIt = Not IsNull(ctl.Value)
ctl.Visible = bShowIt
btn.Value = bShowIt
Next ctl
' Note: this is not necessary for local variables - they go automatically out of scope
Set ctl = Nothing
End Sub
Is there anyone who knows how can I find out the number of selected items in a ListView with checkboxes especially in VBA?
My approach is as follows. When I click on a Checkbox in this ListView then the application have to check if the selected items are more than three then throw an error message.
Private Sub ListView1_ItemCheck(ByVal Item As MSComctlLib.ListItem)
If checked items > 3 then
//Error message
Else
//continues
End If
End Sub
You need to loop over the list items and query the Checked property.
Private Sub ListView1_ItemCheck(ByVal Item As MSComctlLib.ListItem)
' Returns the number of selected items.
Dim li As ListItem ' Used to loop over all items.
Dim c As Integer ' Used to count selected items.
' Loop over each item.
For Each li In ListView1.ListItems
' Increase count if selected.
If li.Checked = True Then c = c + 1
Next
' Inform user.
MsgBox c, vbInformation, "Selected Items"
End Sub
Edit
The Checked property only works if your listbox uses checkboxes. In all other cases use the selected property. From MSDN:
This property is useful only if the CheckBoxes property of the
ListView control the item is contained in is set to true. You can use
this property to determine if the item has been checked by the user or
through code at run time. To determine all the items that are checked
in a ListView control, you can use the CheckedItems property. To take
action when an item has been checked, you can create an event handler
for the ItemCheck property of the ListView control.
Maybe try using the SelectedItems property? https://msdn.microsoft.com/en-us/library/system.windows.forms.listview.selecteditems(v=vs.90).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1