Using Excel user form to search and update - excel

I need advise from the pros here. i basically have 0 knowledge on vba excel.
I recently had designed a UserForm and i took advantage of online code.
First of all, i have this UserForm allowing me to key in a part number and search from this sheet call "MASTER" in "pntxt" textbox and it will return a list of values to text box 2 to 10. This part of the code is already working and running well.
To further enhance it, i would like to have the "update" button in this user form.
For example, one of the text box is name as "pricetxt" after calling out using values from "pntxt", as a user, i need to amend the "pricetxt" textbox. after which, it will update back my excel sheet.
I had tried the following code and it's not working.
Private Sub update2_Click()
Dim lastRow As Variant
Dim partno As Variant
Dim rowSelect As Variant
Dim x As Variant
If Trim(pntxt.Value) = vbNullString Then
MsgBox "Enter Part Number"
Else
partno = pntxt.Value
Sheets("MASTER").Select
Set wS = Worksheets("MASTER")
lastRow = wS.Cells(Rows.count, 2).End(xlUp).Row
For x = 2 To lastRow
If wS.Cells(x, 2).Value = partno Then Rows(x).Select
Next
rowSelect = ActiveCell.Row
Cells(rowSelect, 20) = Me.pricetxt.Value
End If
End Sub
The code above does not returned the "pricetxt" values to the corresponding rows as "pntxt" values.

Related

VBA: Default selected listbox value from a cell

I've looked high and low for an explanation of this and I really am at my wits end, I don't even know if I'm asking the right question because I can't find any answers.
I have a userform where there are 2 modes: NEW and EDIT
When someone enters a NEW entry, there is a listbox field that allows multiple entries. This information gets concatenated into a single cell of the worksheet separated by commas.
When the form is in EDIT mode, it retrieves the information from the worksheet and populates the form with the existing row details based on an ID number. I can't seem to figure out how to get the list box to pull the selection from the worksheet back into the userform in EDIT mode
On clicking edit button to pull details from sheet into form:
Dim DataID as String
DataID = Trim(txt_RetrieveID.Text) Sheets("Lists").Range("I2").Value = DataID
lastrow = Worksheets("Data").Cells(Rows.Count, 1).End(xlUp).Row
For I=3 to lastrow
If Worksheets("Data").Cells(i, 1).Value = DataID then
txt_date.Text=Sheets("Data").Cells(i,4).Value
''''etc for all the different fields
I was thinking that I'd have to split the concatenated field
Dim GroupValue as String
GroupValue = Sheets("Lists").Range("J2").Value
'"J2" is a fixed point where the list of items populates for the referenced record
Dim SingleValue() As String
SingleValue = Split(GroupValue, ", ")
Next
but I can't figure out how to bring those values back in as the default selection on the listbox in EDIT mode.
How can I take these multiple items and have them highlight as the selected value in EDIT mode?
this is an example that uses the Dictionary object to accomplish what you are asking
Dim dict As Scripting.Dictionary ' add microsoft scripting runtime to your tools/references
Private Sub CommandButton1_Click()
Dim x As Integer, y As Integer, Key As Variant
'clear prior selections in listbox1
ListBox1.MultiSelect = fmMultiSelectSingle
ListBox1.MultiSelect = fmMultiSelectMulti
y = 24 ' your "record selection" is done somehow
For x = 4 To 20 ' referencing your data values from the sheet, set as needed
If Cells(y, x) = "" Then Exit For
Key = Cells(y, x) ' must be a variant to read the key's value
ListBox1.Selected(dict(Key)) = True
Next x
End Sub
Private Sub UserForm_Initialize()
Dim x As Integer
Set dict = New Scripting.Dictionary
ListBox1.List = Split("Item3,Item2,Item0,Iterm8,Item10,Item44,Item09,Item23,Item11,item1,item12,item9,item31", ",")
'after the listbox is populated, build your dictionary
With ListBox1
For x = 0 To .ListCount - 1
dict.Add .List(x), x
Next x
End With
End Sub

Select name from combobox, find all the matching names in column E, then put all the the corresponding numbers from H into another combobox

I have been searching for almost 2 days to find an answer to this and it is driving me insane. I am very new to VBA so I don't have any code to share, just been trying out things I find on other sites and youtube. I have a technician sign in sheet that I have been working on and these are the steps I need done:
select your name from the "Metrology Tech." combobox on the 'Metrology Tech log-in' sheet
VBA searches thru column H in 'metrology tracker' to find all matching names
The lot numbers from column E in 'metrology tracker' sheet are put into the "Lot Number" combobox if the value in column M in 'metrology tracker' sheet is equal to "Pend."
I've tried this Create Dependent Combo Boxes on a Userform - Excel VBA and it did not work it just returned all the values of the column I need and all the other articles and videos were pretty much the same thing.
one thing I should note is that most of the values in the metrology tracker are referenced from another file so the lot numbers are equal to a cell value in another file.
Edit:
Ive tried this even though I knew it wasn't going to work
Private Sub cboTech_change()
Select Case cboTech.Value
Case Is = "employee 1"
cboLotNum.RowSource = "LotNumber"
Case Is = "employee 2"
cboLotNum.RowSource = "LotNumber"
Case Is = "employee 3"
cboLotNum.RowSource = "LotNumber"
End Select
End Sub
and also tried this, but kept on gettting a "run-time error '424' object required"
Sub FndLot()
Dim idx As Long
Dim lngRow As Long
idx = TechBox.ListIndex
If idx <> -1 Then
lngRow = TechBox.ListIndex
Worksheets("Metrology Tracker").Range("E" & lngRow).Value = LotNum.Value
End If
End Sub
Not too sure what you want but this should get you started.
Private Sub cboTech_Change()
Dim sName As String
sName = cboTech.Text
cboLotNum.Clear
Dim ws As Worksheet, lastrow As Long, i As Long
Set ws = Sheets("metrology tracker")
With ws
lastrow = .Cells(.Rows.Count, "H").End(xlUp).Row
For i = 1 To lastrow
If .Cells(i, "H") = sName And .Cells(i, "M") = "pend" Then
cboLotNum.AddItem .Cells(i, "E")
End If
Next
End With
End Sub

How do I make a list in a MsgBox (VBA)?

Using VBA, I'm making a sub that should, in some instances, output maybe hundreds of strings. Can I make a long MsgBox where all of those strings are occupying a different paragraph each? In my workbook, the worksheets have tables with the code of a product in the first column and the stock in the eighth (last), I have made the function AverageStock that returns the average stock of a certain product code in a worksheet.
Sub test()
Dim product_code as String
Dim LRow as Integer
Dim k as Integer
LRow = Range("A3").End(xlDown).Row
product_code = InputBox("Product Code")
For k = 3 To LRow
If Cells(k, 8) > AverageStock(product_code) Then
I only have this till now, any help/suggestions?
MsgBox will only contain text and a title:
https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/msgbox-function
The option you have is to create a custom UserForm.

How to address generated ListBoxes and add Items dynamically in VBA?

I successfully managed to generate ListBoxes dynamically. But I am now struggling with addressing and populating those generated ListBoxes. Additionally, I can't figure out how to activate the MultiSelect Property of those ListBoxes. Is that only possible with ActiveX?
I first tried ActiveX - ListBoxes on userForm. Now I switched back to "normal" ListBoxes on the WorkSheet. "FS" is the name of my Worksheet which I am working on. For understanding: I am looping through the columns on worksheet FS and creating one ListBox per Column. In each ListBox the entries of the according column will be added.
For i = 1 To 10
LastRow = FS.Cells(Rows.Count, i).End(xlUp).Row
With FS
Set lb = FS.Shapes.AddFormControl(xlListBox, 100, 10, 100, 100)
lb.ControlFormat.MultiSelect = 2
For Each cell In FS.Range(Cells(1, i), Cells(LastRow,i)).Cells
lb.ControlFormat.AddItem cell.Value 'This is the problematic line
Next cell
End With
Next i
I suggest you do it like so:
Sub test()
''''Declarations'''''''''''''''''''''''''''
Dim lb As ListBox '
Dim sht As Worksheet '
Dim rng As Range '
Dim cell As Range '
Dim i As Long '
'''''''''''''''''''''''''''''''''''''''''''''
Set sht = ThisWorkbook.Worksheets("Name of your worksheet")
For i = 1 To 10
With sht
Set rng = .Range(.Cells(1, i), .Cells(.Rows.Count, i).End(xlUp))
Set lb = sht.ListBoxes.Add(100 * i, 10, 100, 100) 'just an indicative way to create the List boxes without them overlapping
End With
lb.Name = "ListBox" & i
lb.MultiSelect = 2
For Each cell In rng
lb.AddItem cell.Value
Next cell
Next i
End Sub
UPDATE (to cover the comment made)
I updated the code above to name the list boxes as "ListBox1" , "ListBox2" etc instead of "List Box 1"etc.
To refer to one of the list boxes you need to use a reference to the collection of ListBoxes. This collection belongs to the sheet where the listboxes are located. For example, to refer to "ListBoxi", where i=1,2...n you need to do it like so:
sht.ListBoxes("ListBox" & i)
Unfortunately there is no .SelectedItems.Count or similar method, that I know of, which you can use with a form control List Box.
Having that in mind, you can find the number of selected items of "ListBox1" for example, like so:
Dim selectedItems As Long
selectedItems = 0
Set lb = sht.ListBoxes("ListBox" & 1)
For i = 1 To lb.ListCount Step 1
If lb.Selected(i) Then
selectedItems = selectedItems + 1
End If
Next i
If selectedItems = 0 Then
MsgBox "No user selected"
End If
A few things to keep in mind:
The index of the first item varies from 0 to 1 depending on whether the list box is on a userform or not
To refer to a listbox using it's name like Listbox1.DoSomething, it needs to be an ActiveX control and not a Form control.
Use the .ControlFormat.ListFillRange instead, and set MultiSelect to 3. Something like this should work for you:
Sub tgr()
Dim FS As Worksheet
Dim lb As Shape
Dim i As Long
Set FS = ActiveWorkbook.Worksheets("FS")
For i = FS.Columns("A").Column To FS.Cells(1, FS.Columns.Count).End(xlToLeft).Column
Set lb = FS.Shapes.AddFormControl(xlListBox, (i - 1) * 100 + 10, 10, 100, 100)
With lb
.ControlFormat.MultiSelect = 3
.ControlFormat.ListFillRange = FS.Range(FS.Cells(1, i), FS.Cells(FS.Rows.Count, i).End(xlUp)).Address(External:=True)
End With
Next i
End Sub

Return text that is different from combo box text

I am setting up a combo box to update a pivot table.
I need the value the combo box returns to be different from the selected text.
For example. You select a product's name in the drop down box, "Cheerios". It has a SKU number of 1234. I need the combo box to return the 1234.
Edit:
Below is an image of where I am getting my list populated from. Column B is what is being displayed in the drop down, column A is what I need returned.
Edit 2:
Private Sub cmb_SkuSelect_Click()
Dim xlSheetSort As Worksheet
Dim lastRow As Long
Dim skuValue As Integer
Set xlSheetSort = ActiveWorkbook.Worksheets("Sort")
lastRow = xlSheetSort.Range("A1").End(xlDown).Row
With xlSheetSort.Range("B1:B" & lastRow)
Set c = .Find(cmb_SkuSelect.Value, LookIn:=xlValues)
If Not c Is Nothing Then
skuValue = xlSheetSort.Range("A" & c.Row).Value
End If
End With
cmb_SkuSelect.Value = ""
ActiveWorkbook.ActiveSheet.Range("A4").Value = skuValue
updatePivot skuValue
End Sub
updatePivot:
Public Sub updatePivot(ByVal sku As Integer)
Dim xlSheet As Worksheet
Dim xlPTable As PivotTable
Set xlSheet = ActiveWorkbook.Worksheets("Sku Inventory")
For Each xlPTable In xlSheet.PivotTables
With xlPTable
.PivotFields("Sku Number").CurrentPage = sku
End With
Next
End Sub
Try that:
Private Sub ComboBox1_Change()
Dim valueToLook As String
valueToLook = ComboBox1.Value
Dim sku, i As Integer
Dim LastRow As Long
With ActiveSheet
LastRow = .Cells(.Rows.Count, "B").End(xlUp).Row
End With
For i = 1 To LastRow
If Cells(i, 2).Value = valueToLook Then
sku = Cells(i, 1).Value
MsgBox sku
Exit For
End If
Next i
End Sub
Yes, it's definitely possible - all you need to do is make the combobox a multi-column one, set its BoundColumn to the SKU Number's column and hide that column afterwards. It's a late answer, but it solves your problem.
I'm not going to bother with your existing structure, but rather present a simple example that you can adapt to your needs afterwards. Assuming you already have the form (e.g. UserForm1) and the combobox (e.g. ComboBox1) in a standard workbook, paste this into your userform module:
Private Sub ComboBox1_Change()
' Show the expected result to the user
MsgBox Me.ComboBox1.Value
End Sub
Private Sub UserForm_Initialize()
Dim cbitems(2, 1) As Variant
' Set the number of columns in the combobox to 2 (i.e. Product Name and SKU Number)
Me.ComboBox1.ColumnCount = 2
' Set the 2-nd column's value to be used as the value of the combobox (i.e. the SKU Number)
Me.ComboBox1.BoundColumn = 2
' Set the 2-nd column's width to 0, hiding the column (i.e. only the Product Name is visible)
Me.ComboBox1.ColumnWidths = ";0"
' Populate a 2D array with the values of the combobox columns
cbitems(0, 0) = "Cheerios"
cbitems(0, 1) = "1234"
cbitems(1, 0) = "Apples"
cbitems(1, 1) = "1672"
cbitems(2, 0) = "Peaches"
cbitems(2, 1) = "3722"
' Populate the combobox with the above array, using the List method (i.e. not the AddItem one)
Me.ComboBox1.List = cbitems
' Set the 1-st item of the combobox to be its default one
Me.ComboBox1.ListIndex = 0
End Sub
The comments explain what happens. All you have to do is adapt the code to your usage scenario (e.g. you'll probably want to populate the array/combobox using a loop, maybe move the relevant code to a different Sub than the userform's Initialize event, potentially add column headers if you want both columns to be visible, etc.)
Note: The Change event of the combobox will fire a couple of times when the combobox is first drawn on the userform, so you might get a few empty message-boxes at the start. Don't mind them, the important ones are those after you select some item from the list later on. The message boxes are just for convenience anyway, and, along with the last line in the userform's Initialize event, they can be safely removed from the code once you get the idea.

Resources