In my VB.NET form I have 50 groupboxes, each containing a combobox named volt. I used this code to add value to all the comboboxes:
For count = 1 To 50
Dim volt = DirectCast(Me.Controls("volt" & count & ""), ComboBox)
volt.Items.Add("what a code")
Next
but they were placed in different groupbox. When I rewrite it like this:
For count = 1 To 50
Dim volt = DirectCast(groupbox1.Controls("volt" & count & ""), ComboBox)
volt.Items.Add("what a code")
Next
it works in in only groupbox1. How can I make affect the remaining groupboxes?
Something like this might work for you (jmcilhinney suggestion actually):
For Each ctl As Control In Me.Controls
For Each cmb As Combobox In ctl.Controls.OfType(Of Combobox)()
cmb.Text = "Volt"
Next
Next
But be careful with this - If your Groupboxes are in a container such as Panel or Split Container do a loop inside that and not In Me.Controls.
Related
I'm dealing with this issue. I have a userform that addapts after the user enters a value (for example, if he wants to add 3 members, the user form creates 3 different pages with the same boxes, after renaming them).
I have this right now:
After pressing "Lanzar", the userform will create more pages with "Datos Educando 2", "Datos Educando 3"... and so on, taking the value introduced on "Educandos a inscribir:"
The code is the following:
Private Sub lanzar_numero_educandos_Click()
Dim l As Double, r As Double
Dim ctl As Control
Me.MultiPage1.Pages(1).Visible = True
If Me.MultiPage1.Pages.Count > 2 Then
For a = Me.MultiPage1.Pages.Count - 1 To 2 Step -1
Me.MultiPage1.Pages.Remove a
Next a
End If
Me.MultiPage1.Pages(1).Visible = True
If educandos_a_inscribir.Value <> 1 Then
For a = 1 To educandos_a_inscribir.Value
MultiPage1.Pages.Add
MultiPage1.Pages(a).Controls.Copy
MultiPage1.Pages(a + 1).Paste
For Each ctl In MultiPage1.Pages(a).Controls
If TypeOf ctl Is MSForms.Frame Then
l = ctl.Left
r = ctl.Top
Exit For
End If
Next
For Each ctl In MultiPage1.Pages(a + 1).Controls
If TypeOf ctl Is MSForms.Frame Then
ctl.Left = l
ctl.Top = r
Exit For
End If
Next
Me.MultiPage1.Pages(a + 1).Caption = "Datos Educando " & a
Next a
Me.MultiPage1.Pages(1).Visible = False
End If
End Sub
Now, the problem I have is that the pages generated with this code have random names on each TextBox, so I'm not able to locate the information introduced from the user.
For example, this is the first page (the one that has the names I already know):
Here, the TextBox "Nombre Educando" is called "nombre_educando_1", so I can locate it easily on code:
The Textboxes created when copying the first page, have random names (like "TextBox 34", "TextBox 35"... and so on), so I'm not able to controll how are they called.
There is a way of generate the pages editing the TextBox names? Like, for example, for the second page generated, the TextBox in the example above should be "nombre_educando_2" and so on.
Thanks!
Each control on the first page has an attribute named Tag. You can value these with unique and meaningful values. When you paste the controls to the new page the Tag values will follow. Then as you loop through the controls on any page, use a Select Ctl.tag statement to identify what to do with the value of the control.
I have the following textboxes and want to delete them faster.
TxtDrawA1.Clear
TxtDrawA2.Clear
TxtDrawA3.Clear
TxtDrawA4.Clear
TxtDrawA5.Clear
TxtDrawA6.Clear
TxtDrawA7.Clear
TxtDrawA8.Clear
and so on...
Here is how to find them no matter what container they are in (they can all even be in different containers). This approach also demonstrates how to get those controls "in order":
Dim tb As TextBox
Dim ctl As Control
For i As Integer = 1 To 8
ctl = Me.Controls.Find("TxtDrawA" & i, True).FirstOrDefault
If Not IsNothing(ctl) AndAlso TypeOf (ctl) Is TextBox Then
tb = DirectCast(ctl, TextBox)
' ... do stuff with "tb" ...
tb.Clear()
End If
Next
Hello and welcome to StackOverflow!
You could try iterating through the textboxes like this:
For Each txtb As TextBox In Me.Controls.OfType(Of TextBox)()
If txtb.Name.StartsWith("TxtDrawA")
txtb.Clear
End If
Next
Hope this helps!
Here is a bit of background on what I'm trying to do: I'm creating a userform to track Inventory items and prices, using checkboxes in a multipage object. The clerk checks off everything put into an order and uses a submit button, which will take some actions.
In order for the project not to require a coding person every time Inventory items change, the checkboxes are being dynamically generated when the userform is activated, from cell values on an Inventory sheet. The clerks just adjust the Inventory sheet and the form automatically adjusts for them.
This is my code to dynamically create all the checkboxes (currently this form can accommodate up to 160 possible checkboxes), in case this is effecting my issue (side note, each tab on the multipage has a frame on it, and all checkboxes are within the frame, so I could change background colors, the frame in this example being titled "frmreg"):
Sub StoreFrmRegCheckboxGenerator()
'Works with the store userform
Dim curColumn As Long
Dim LastRow As Long
Dim i As Long
Dim chkBox As msforms.CheckBox
'This sub dynamically creates checkboxes on the Regular Items tab based
'on values in Column A of the Inventory sheet
curColumn = 1 'Set your column index here
LastRow = Worksheets("Inventory").Cells(Rows.Count, curColumn).End(xlUp).Row
For i = 2 To 9
If Worksheets("Inventory").Cells(i, curColumn).Value <> "" Then
Set chkBox = store.frmreg.Controls.Add("Forms.CheckBox.1", "CheckBox_" & i)
chkBox.Caption = Worksheets("Inventory").Cells(i, curColumn).Value & " - $" & Worksheets("Inventory").Cells(i, curColumn).Offset(0, 1).Value
chkBox.AutoSize = True
chkBox.WordWrap = True
chkBox.Left = 5
chkBox.Top = 1 + ((i - 1) * 25)
End If
Next i
'Cut some code out here identical to this previous section, but for the rest of the cells in column A up to Row 33, in blocks of 8
End Sub
The above code is in the Userform_Initialize sub, and it works perfectly.
However, since the number of checkboxes is not static, and can be as many as 160, I'm trying to write one sub to take the same set of actions any time any checkbox is clicked.
The closest solution I've found is from this question: Excel Macro Userform - single code handling multiple checkboxes, from sous2817.
Here is his code that I'm trying to use:
In a new class module:
Option Explicit
Public WithEvents aCheckBox As msforms.CheckBox
Private Sub aCheckBox_Click()
MsgBox aCheckBox.Name & " was clicked" & vbCrLf & vbCrLf & _
"Its Checked State is currently " & aCheckBox.Value, vbInformation + vbOKOnly, _
"Check Box # & State"
End Sub
The "store" userform, at the top, right under Option Explicit:
Dim myCheckBoxes() As clsUFCheckBox
At the bottom of the Userform_Initialize sub, AFTER I call the all the subs that dynamically create all the checkboxes:
Dim ctl As Object, pointer As Long
ReDim myCheckBoxes(1 To Me.Controls.Count)
For Each ctl In Me.Controls
If TypeName(ctl) = "CheckBox" Then
pointer = pointer + 1
Set myCheckBoxes(pointer) = New clsUFCheckBox
Set myCheckBoxes(pointer).aCheckBox = ctl
End If
Next ctl
ReDim Preserve myCheckBoxes(1 To pointer)
When I try to open the userform I get this error:
"Compile Error: User-defined type not defined"
Pointing to this line:
Dim myCheckBoxes() As clsUFCheckBox
Am I missing a library reference? I haven't been able to figure this out.
I have a list of controls created dynamically in a control list. The user has options to add textboxes in the control list and to delete them as well.
I have created the textboxes using the following code:
Dim tb As New TextBox
tb.Name = "Textbox" & counter.ToString
tb.Left = 55
tb.Top = fields
Me.Controls.Add(tb)
MyControls.Add(tb)
counter = counter + 1
So, the textbox names when created are Textbox1, Textbox2 and so on maximum up to Textbox10.
The user can delete textboxes by button clicks one by one. If the user wants to delete these textboxes, counter will run backward and will delete Textbox10 first and then Textbox9 and so on (This is the same as First in First Out).
So, for deleting I tried the following code, but it didn't execute, giving an error. The code is written under Button's Click event of the delete button.
For Each CType(Me.Controls("Textbox" & counter), TextBox) As Control In MyControls
Me.Controls.Remove(...) 'The textbox's name to be deleted in place of dots
'The textbox name to be deleted here with .Dispose()
Next
The error is: "Expression is a value and therefore cannot be the target of an assignment" in the first line of the above code.
How to delete a series of textboxes dynamically?
This line is causing the problem:
For Each CType(Me.Controls("Textbox" & counter), TextBox) As Control In MyControls
CType(Me.Controls("Textbox" & counter), TextBox) resolves to a value, so it cannot be a loop increment variable.
To delete based on a loop, you would need to know how many controls you want to delete. Here is one way:
For i As Integer = 1 To Math.Min(NumberOfControlsToDelete, 10) ' Cap deleting at 10.
' Make sure we don't go below 1.
If counter < 1 Then Continue
' Expected that the control will exist.
Me.Controls.Remove(Controls.Find("TextBox" & counter, True)(0))
' Decrement counter.
counter -= 1
Next
It looks like you're already keeping track of those dynamic buttons by adding them to a List? in this line (your 6th line of code):
MyControls.Add(tb)
As such, simply grab the last entry and remove it, no need to go searching for the control by name:
If MyControls.Count > 0 Then
Dim TB As TextBox = MyControls(MyControls.Count - 1)
MyControls.Remove(TB)
TB.Dispose()
End If
If you want to delete all of them at the same time:
For Each TB As TextBox In MyControls
TB.Dispose()
Next
MyControls.Clear()
Is this what you're looking for? I'm not sure I'm reading your question correctly.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.Controls.Remove(Me.Controls.Find(""Textbox" & counter"))
End Sub
I am making an application where there is a form with a column of text boxes that are filled from two different forms with a button on each. when the button of these forms are clicked they input the results into the text boxes in the column.
the problem I am having is that say i click (form2.button 1) three times it will occupy text boxes 1,2 and 3. Now say I want to use (form1.button 1) to input data into text box 4 it will occupy text box 1.
I have each button set up for multiple clicks so I would like to understand how i can have is so say(form2.button 1) is clicked then (form1.button1) will go to 2nd click for example. there are 10 text boxes so I will need it so that they react to how many times each has been clicked.
Assuming the TextBoxes were called TextBox1 thru TextBox10, you could use a sub like this:
Public Sub AddValue(ByVal value As String)
For i As Integer = 1 To 10
Dim tbName As String = "TextBox" & i
Dim matches() As Control = Me.Controls.Find(tbName, True)
If matches.Length > 0 AndAlso TypeOf matches(0) Is TextBox Then
Dim tb As TextBox = DirectCast(matches(0), TextBox)
If tb.Text.Trim.Length = 0 Then
tb.Text = value
Exit Sub
End If
End If
Next
MessageBox.Show("All TextBoxes are already taken!")
End Sub
Why not just store a counter variable in the form that contains the textboxes, say NextTextBoxNumber that increments each time a textbox is filled in and then you know exactly which textbox to go to next based upon the value of this variable?
Also, to continue with #Oded's comment, you can easily accomplish what he meant using something along the lines of If Textbox1.Text <> "" Then ...
Does that make sense??