Here's my problem.
I have a userform with 10 comboBoxes.
Instead of Select Case al those comboboxes one by one is
there a smart way to change multiple combobox properties such as backcolor or fontcolor?
So for example:
Sub ChangeMultipleComboBoxes()
Dim comboB as control
For Each comboB In Me.Controls
If TypeName(comboB) = "ComboBox" Then
comboB.BackColor = vbRed
End If
Next comboB
End Sub
The problem is that for comboB I can't seem to find any properties for changing it's backcolor or whatsoever.
Can someone help me please?
As Zaider says, your code works. You just don't get the IntelliSense for the ComboBox-specific properties when it's declared as a Control, even though you can use the properties as you've done in your code. (Note that properties common to all controls, e.g., Caption are available.)
To get the Intellisense for all ComboBox properties, re-declare the Control as a ComboBox once you've determined that's what it is:
Private Sub UserForm_Click()
Dim ctl As MSForms.Control
Dim comboB As MSForms.ComboBox
For Each ctl In Me.Controls
If TypeName(ctl) = "ComboBox" Then
're-declare it as a ComboBox
Set comboB = ctl
'Now you get IntelliSens
comboB.BackColor = vbRed
End If
Next ctl
End Sub
Related
Let's see if anyone knows how to solve this problem:
I have a form with several elements: Some of them are textboxes called A1, A2, A3, A4...
Now, their AfterUpdate SubProcedure is extremely long but barely similar for each of them: A1_AfterUpdate, A2_AfterUpdate, A3_AfterUpdate...etc... are very similar but for the names of the textboxes they change.
My idea was to gather all that was equal in a subprocedure defined this way:
Private Sub Update(Box As String, Menu As Boolean)
If Menu=True{
Me!Box.Text = "This is the text that is going to change"
}
End Sub
So, the only thing I must do is to call it this way, for instance:
Update(A1, True)
But it doesn't seems to work. Any idea on how to reach this objective?
Add a class module - I've called it clsTextBoxEvents.
Add this code to the class:
Public WithEvents txt As Access.TextBox
Private Sub txt_AfterUpdate()
MsgBox txt.Name & " has been updated."
End Sub
In your form module add this code:
Public MyTextBoxes As New Collection
Private Sub Form_Open(Cancel As Integer)
Dim ctl As Control
Dim txtBoxEvent As clsTextBoxEvents
For Each ctl In Me.Controls
If TypeName(ctl) = "TextBox" Then
Set txtBoxEvent = New clsTextBoxEvents
Set txtBoxEvent.txt = ctl
txtBoxEvent.txt.AfterUpdate = "[Event Procedure]"
MyTextBoxes.Add txtBoxEvent
End If
Next ctl
End Sub
The MyTextBoxes declaration must be at the very top of the module.
This just adds the AfterUpdate event to all textboxes on the form. You'll probably want to refine that a bit to textboxes with specific text in the name, or controls that are in a specific frame on the form.
If you use a function instead of a sub:
Private Function UpdateCtl(Menu As Boolean)
If Menu Then
activecontrol = "This is the text that is going to change"
End If
End Sub
then you can call it directly from the control's AfterUpdate property: =UpdateCtl(True).
Simple and fast
I'm trying to add checkboxes during the initialization of my Userform. They have to be mutually exclusive. I know about option buttons but I can't use them for my form.
For now, I can't set them to be mutually exclusive. They are in a frame and I've set their .GroupName property to be the same. This is where I don't understand why it won't work. I read this MSDN article which tells that "All check boxes with the same GroupName within a single container are mutually exclusive".
I've also tried this on a blank Userform with and without frames but I can always select more than one checkbox.
Any idea of what I'm missing?
You may use code to achieve same functionality:
Private Sub CheckBox1_Click(): Check_Just CheckBox1: End Sub
Private Sub CheckBox2_Click(): Check_Just CheckBox2: End Sub
Private Sub CheckBox3_Click(): Check_Just CheckBox3: End Sub
Sub Check_Just(CheckBox)
'Disable false triggers when unchecking boxes
If CheckBox.Value = False Or CheckBox.GroupName = "" Then Exit Sub
'Uncheck all other control with same groupname
Dim ctl As control
For Each ctl In CheckBox.Parent.Controls
If TypeName(ctl) = "CheckBox" Then If ctl.GroupName = CheckBox.GroupName And Not ctl Is CheckBox Then ctl.Value = Unchecked
Next
End Sub
i have a word with 15+ VB forms and 20-50 CheckBoxes in each.
How do i clear (if they are cheched) all the CheckBoxes in active form w/o having to write the name of each CheckBox?
Thank you
This code will do the job. It must be placed in the UserForm's code sheet.
Private Sub ClearCheckBoxes()
Dim Ctl As MSForms.Control
For Each Ctl In Me.Controls
If TypeName(Ctl) = "CheckBox" Then Ctl.Value = False
Next Ctl
End Sub
Since you can't have a vertical Control Tab in Access, I'm creating a fake one.
I wrote this piece of code to highlight (change fore color to white) the current page:
Private Sub updateBtnColor()
Dim currentPageIndexSZero As Long
Dim ctl As Control
currentPageIndexSZero = Me.tab1
For Each ctl In Me.Controls
If ctl.Tag = "page" & CStr(currentPageIndexSZero) Then
ctl.ForeColor = white
ElseIf InStr(1, ctl.Tag, "page", vbBinaryCompare) Then
ctl.ForeColor = black
End If
Next ctl
End Sub
Every button has got the page it's referring to as a tag, in the form of:
page0
page1
...
pageN
So the loop basically checks the current page, finds the button with the appropriate tag (assuming I named them correctly) and highlights its text.
Now this can be slow since I've got a heavy loaded form or bad practise, so I thought of creating a custom collection instead of looping through the whole Controls Collection.
I wanted to create such structure so I can loop through it, something like:
Enum myButtons
button1 = Forms!myForm!button1
button2 = Forms!myForm!button2
button3 = Forms!myForm!button3
button4 = Forms!myForm!button4
End Enum
And then:
Public Sub updateBtnColor()
Dim curPageZ as Long
Dim button as Control
For Each button in myButtons
With button
If Right$(CStr(.Name, 1)) = curPageZ
.ForeColor = 16777215 ' White
Else ' No need for an additional ElseIf since I already know these are only the wanted buttons
.ForeColor = 0 ' Black
End If
End With
Next button
End Sub
What is the most elegant/fastest/best/proper way to create such structure or, if my idea is not that good, to create such logic?
Thanks!
Cycling thru controls works quite fast, but if you want to speedup this, use Collection for storing objects, not Enum. Collection can be cycled also using For Each....
On form module level create a collection for your buttons:
Dim mcolMyButtons As New Collection
Then fill this collection in Open or Load events. You can use tags:
Dim ctl As Control
For Each ctl In Me.Controls
If TypeOf ctl Is CommandButton Then
If ctl.Tag Like "page*" Then
mcolMyButtons.Add ctl
End If
End If
Next
Or just directly add buttons you want:
mcolMyButtons.Add Me.Button1
mcolMyButtons.Add Me.Button2
mcolMyButtons.Add Me.Button3
mcolMyButtons.Add Me.Button4
Then your sub:
Private Sub updateBtnColor()
Dim ctl As Control
For Each ctl In mcolMyButtons
If ctl.Tag = "page" & Me.tab1 Then
ctl.ForeColor = vbWhite
Else
ctl.ForeColor = vbBlack
End If
Next ctl
End Sub
I have a form where i have 23 Comboboxes. Writing SelectedIndex=-1 for every combobox will definitely work but i want to know whether there's any other way of doing it as done in below given example. ?
For Each ctl As Control In (GroupBox1.Controls)
If TypeOf ctl Is TextBox Then
ctl.Text = ""
End If
Next
i tried this,
If TypeOf ctl Is ComboBox Then
ctl.selectedIndex=-1
End If but it doesn't works. Please help me out.
In your example your ctl variable is a Control and not a Combobox so it does not have the SelectIndex property - though you could have casted it back with DirectCast(ctl, Combobox).
For Each ctl As Control In (GroupBox1.Controls)
If TypeOf ctl Is Combobox Then
DirectCast(ctl, Combobox).SelectedIndex = -1
End If
Next
Or create a loop of type specific control for your loop. No need to check type here.
Dim cbs = GroupBox1.Controls.OfType(Of Combobox)()
For Each cb In cbs
cb.SelectedIndex = -1
Next