This is my first post on this forum. I have a quick question regarding VBA, Userforms with a listbox. My goal is to select two options and return a list of names in a listbox. I have attached the example userform and the example table that I would be choosing from. Any help would be appreciated.
Worksheet
Current VBA for Userform
Private Sub ListBox1_Click()
Sheets("Trainers1").Range("I2") = ListBox1
End Sub
Private Sub ListBox2_Click()
Sheets("Trainers1").Range("I2") = ListBox2
End Sub
Private Sub ListBox3_Click()
Sheets("Trainers1").Range("I3") = ListBox3
End Sub
Private Sub ListBox4_Change()
.ListBox4 = Sheets("Trainers1").Range("K2:K10")
End Sub
Private Sub UserForm_Initialize()
Dim cnt
Dim cntr As Integer
cntr = Application.WorksheetFunction.CountA(Sheets("Shift Pattern Key").Range("A:A"))
cnt = Application.WorksheetFunction.CountA(Sheets("Training Ratio").Range("A:A"))
For i = 2 To cntr
ListBox2.AddItem Sheets("Shift Pattern Key").Cells(i, 1)
Next i
For i2 = 2 To cnt
ListBox3.AddItem Sheets("Training Ratio").Cells(i2, 1)
Next i2
End Sub
You could iterate through the rows of your table and compare the values in each row to the values selected. If both values in a row match the values selected by the user you can then use the .AddItem method to add the name of the employee to the list.
Related
Sub TextBox19_Change()
If Len(TextBox19.Value) = 4 Then TextBox19.Value = Mid(TextBox19.Value, 1, 3)
End Sub
Sub TextBox18_Change()
If Len(TextBox18.Value) = 4 Then TextBox18.Value = Mid(TextBox18.Value, 1, 3)
End Sub
Sub TextBox17_Change()
If Len(TextBox17.Value) = 4 Then TextBox17.Value = Mid(TextBox17.Value, 1, 3)
End Sub
Sub TextBox16_Change()
If Len(TextBox16.Value) = 4 Then TextBox16.Value = Mid(TextBox16.Value, 1, 3)
End Sub
How can I rephrase the above so that we don't have to duplicate the sub-routines for 100+ TextBoxes? There are more codes than just changing the textbox's value to its first 3 characters. I would appreciate a general efficient code. Thank you.
Edit: This isn't on a form. This is on PowerPoint Slides.
I wasn't sure if you're using form textboxes here, but you could also use event sinking.
So create a class clsCustomText like so
Private WithEvents t As msforms.TextBox
Private Const lMaxLength As Long = 3
Public Sub Init(tIn As msforms.TextBox)
Set t = tIn
End Sub
Private Sub t_Change()
If Len(t.Value) > lMaxLength Then t.Value = Left(t.Value, lMaxLength)
End Sub
Then in a normal module, somewhere to hold them
Public colCustomTextboxes As Collection
and then in the form like so, i did mine on click, so i can test. You'd need to move to initialize.
Private Sub UserForm_Click()
Dim c As Control
Dim t As clsCustomText
Set colCustomTextboxes = New Collection
For Each c In Me.Controls
If TypeOf c Is msforms.TextBox Then
Set t = New clsCustomText
t.Init c
colCustomTextboxes.Add t, c.Name
End If
Next c
End Sub
I am creating a UserForm for an Inventory Clerk who physically counts inventory for auditing purposes. The current process is on paper - I'd like to put it on a tablet.
Goal:
1) Single row comes up on form with item location, product, quantity, and description
2) If the quantity is correct, the user hits "correct" and the next item comes up
3) If the quantity is incorrect, the user keys the observed amount which gets written to column J of the corresponding data table
4) A scroll option to go forward and backward if the user wants to check/re-work an item
Private Sub CommandButton1_Click()
'GET DATA FROM TABLE
ListBox1.ColumnCount = 4
ListBox1.RowSource = "A2:D500"
End Sub
'IF QTY IS CORRECT, NEXT ROW
Private Sub CommandButton_QtyCorrect_Click()
Call SpinButton1_SpinUp
End Sub
'IF QTY DOESN'T MATCH, USER KEYS CORRECT
Private Sub CommandButton2_Click()
Range("K1") = TextBox2_Qty.Value
TextBox2_Qty.Value = ""
End Sub
Private Sub ListBox1_Click()
'DISPLAY DATA TABLE
End Sub
Private Sub SpinButton1_SpinDown()
If ListBox1.ListIndex > 0 Then
ListBox1.Selected(ListBox1.ListIndex - 1) = True
End If
End Sub
Private Sub SpinButton1_SpinUp()
If ListBox1.ListIndex + 1 < ListBox1.ListCount Then
ListBox1.Selected(ListBox1.ListIndex + 1) = True
End If
End Sub
Private Sub TextBox2_Qty_Change()
'USER OVERWRITE
End Sub
Questions:
1) With the current setup, all the rows populate the ListBox. How do I get one row at a time to display?
2) When the current row is displayed on the ListBox, how do I write to the corresponding row in column J in the case of a non-match?
Answers
1) Solved by Ralf S below.
2) Solution:
Private Sub AdjustButton_Click()
'IF QTY DOESN'T MATCH, USER KEYS CORRECT
Range("J" & SpinButton1.Value) = TextBox2_Qty.Value
TextBox2_Qty.Value = ""
End Sub
the following code would be my ansatz:
Private UserForm1_Activate()
ListBox1.ColumnCount = 4
ListBox1.RowSource = "A2:D2" ' show only first row
SpinButton1.Min = 2
SpinButton1.Max = Range("A1048576").end(xlUp).row ' last row as maximum value of spin button
End Sub
Private Sub CommandButton_QtyCorrect_Click()
If SpinButton1.Value < SpinButton1.Max Then _
SpinButton1.Value = SpinButton1.Value + 1
End Sub
Private Sub CommandButton2_Click()
Range("K1") = TextBox2_Qty.Value
TextBox2_Qty.Value = ""
End Sub
Private Sub SpinButton1_Change()
ListBox1.RowSource = "A" & SpinButton1.Value & ":D" & SpinButton1.Value
End Sub
Thus, you could use the spin button's value as the row index for your listbox.
This shows only one row at a time and it might help you out for now. But there is still a lot optimization potential...
I have a list box not linked to any range.
I want to click on a row and remove it. If I step through the code below, the ListBox1_Click() function ends up being called twice for some reason and the application produces an "Unspecified Error" on the second run
My entire code:
Private Sub ListBox1_Click()
ListBox1.RemoveItem (ListBox1.ListIndex)
End Sub
Private Sub UserForm_Initialize()
For i = 0 To 10
ListBox1.AddItem ("A" & Str(i))
Next i
End Sub
If you make a button about it, then this solution would be quite ok there:
Private Sub CommandButton1_Click()
Dim cnt As Long
For cnt = Me.ListBox1.ListCount - 1 To 0 Step -1
If Me.ListBox1.Selected(cnt) Then
Me.ListBox1.RemoveItem cnt
Exit Sub
End If
Next cnt
End Sub
I am very new to excel programming and VBA. I am stuck at a point where I have random number of dynamically created combo boxes (ComboBox1, ComboBox2.... ComboBoxN).
I need to implement a functionality where if I select a value in the ComboBox[i] (where i can be any random number between 1 to N), then it should trigger an event that will populate values in ComboBox[i+1].
How do I write a Sub for this? Is there any other way to implement this if not in a Sub?
In order to create a group events you'll need a custom class to capture the events ( ObjectListener ), public variable to keep the class references alive (usually a collection or array - ComboListener ) and a Macro to fill the collection ( AddListeners_ComboBoxes ).
Call the AddListeners_ComboBoxes Macro from the Workbook_Open(). You will need call AddListeners_ComboBoxes again if the code breaks.
Standard Module
Public ComboListener As Collection
Sub AddListeners_ComboBoxes()
Dim ws As Worksheet
Dim obj As OLEObject
Dim listener As ObjectListener
Set ComboListener = New Collection
For Each ws In Worksheets
For Each obj In ws.OLEObjects
Select Case TypeName(obj.Object)
Case "ComboBox"
Set listener = New ObjectListener
Set listener.Combo = obj.Object
ComboListener.Add listener
End Select
Next
Next
End Sub
Class ObjectListener
Option Explicit
Public WithEvents Combo As MSForms.ComboBox
Private Sub Combo_Change()
MsgBox Combo.Name
Select Case Combo.Name
Case "ComboBox2"
ActiveSheet.OLEObjects("ComboBox3").Object.ListIndex = 1
End Select
End Sub
As an alternative to the "Class" approach shown by Thomas Inzina here's a "less structured" approach:
Private Sub ComboBox1_Change()
PopulateCombo 2
End Sub
Private Sub ComboBox2_Change()
PopulateCombo 3
End Sub
Private Sub ComboBox3_Change()
PopulateCombo 4
End Sub
Private Sub ComboBox4_Change()
PopulateCombo 1 '<--| will "last" combobox populate the "first" one?
End Sub
Private Sub PopulateCombo(cbNr As Long)
With ActiveSheet.OLEObjects("ComboBox" & cbNr) '<--| reference the combobox as per the passed number
.ListFillRange = "Sheet1!J1:J10" '<--| populate it with "Sheet1" worksheet range "A1:A10"
.Object.ListIndex = 1 '<--| select its first item
End With
End Sub
I have a excel sheet and a form. I want to select all the entries from the sheet and put it in a ListBox in my form. how to do that
I have selected the sheet using
Private Sub view_Change()
Sheets("Sheet1").UsedRange.Select
view.Text = .Value
End Sub
Now I dont know how to put the selection in a ListBox
Finally I am able to do it using
Private Sub UserForm_Initialize()
ListBox1.ColumnWidths = "92;140;110;65;"
ListBox1.ColumnCount = 12
ListBox1.List = Sheets("Sheet1").Range("a2:l" & [a65536].End(3).Row).Value
End Sub