How to use ListIndex to find row of Combobox value? - excel

I'm trying to set a "Make Changes" button for my userform that changes the appropriate record in the spreadsheet according to any changes made in the userform.
The userform populates according to the selection made on "BusCombo".
I'm trying to set n to the row of the "BusCombo" selection. I found a suggestion to use ListIndex. I can't find information on how ListIndex works.
Private Sub MkChgButton_Click()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("Customers")
Dim n
With Me.BusCombo
n = .ListIndex
End With
''''''submit changes
sh.Range("A" & n).Value = Me.BusCombo.Value
sh.Range("B" & n).Value = Me.ServFreqCombo.Value
sh.Range("K" & n).Value = Me.TimeText.Value
sh.Range("C" & n).Value = Me.RateText.Value
sh.Range("D" & n).Value = Me.PayFormCombo.Value
sh.Range("E" & n).Value = Me.PayFreqCombo.Value
sh.Range("F" & n).Value = Me.DayText.Value
sh.Range("G" & n).Value = Me.StartText.Value
sh.Range("H" & n).Value = Me.PayDateText.Value
sh.Range("I" & n).Value = Me.EmpCombo.Value
End Sub

Here's a little demo that shows you how to search through the List items in the Combobox:
Option Explicit
Private Sub UserForm_Initialize()
' add items to the combobox
With ComboBox1
.AddItem ("stuff1")
.List(0, 1) = "test1"
.AddItem ("stuff2")
.List(1, 1) = "test2"
.AddItem ("stuff3")
.List(2, 1) = "test3"
End With
End Sub
Private Sub CommandButton1_Click()
Dim i As Integer
Dim SearchString As String
SearchString = "test3"
' loop through all the items, looking in the 2nd column (column index=1)
For i = 0 To ComboBox1.ListCount - 1
If ComboBox1.List(i, 1) = SearchString Then
MsgBox ("Found it at row index " & i)
Exit Sub
End If
Next
MsgBox SearchString & " not found"
End Sub

Related

Excel Userform coding revise

I would need help on how to revise the code below. I was able to create the template to enter all the informations needed in the userform when the header is in row 1 on the template. But when I need to relocate the header to row 29. It doesn't work as expected even though I did revised the coded to match with row 29. Please help.
This is a good picture of the header in row1 with the code below. It is working fine.
here is the file https://1drv.ms/x/s!AixhKuqjnB1cgW8qhYoRMmt0oN0o?e=W52afT
You will find "Original" Tab. with the original VBA coding working with header in row 1. The "CID" tab will be the one I need to revise the code to work with the header moved to row 29.
This is the original code that work with header in row 1
Sub Refresh_Data()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("Original")
Dim last_row As Long
last_row = Application.WorksheetFunction.CountA(sh.Range("A:A"))
With Me.ListBox1
.ColumnHeads = True
.ColumnCount = 12
.ColumnWidths = "30,100,100,70,100,100,50,100,50,50,120,200"
If last_row = 1 Then
.RowSource = "Original!A2:L2"
Else
.RowSource = "Original!A2:L" & last_row
End If
End With
End Sub
Private Sub Add_Click()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("Original")
Dim last_row As Long
last_row = Application.WorksheetFunction.CountA(sh.Range("A:A"))
'Validations---------------------------------------------------------------------------------------
If Me.TextBox1.Value = "" Then
MsgBox "Please Fill Signal Name. If it is not required, fill -", vbCritical
Exit Sub
End If
'------------------
If Me.TextBox2.Value = "" Then
MsgBox "Please Fill (From) Connector REF DES", vbCritical
Exit Sub
End If
'------------------
If Me.TextBox3.Value = "" Then
MsgBox "Please Fill (From) Connector Pin Location", vbCritical
Exit Sub
End If
'------------------
If Me.TextBox4.Value = "" Then
MsgBox "Please Fill Contact P/N or Supplied with Connector", vbCritical
Exit Sub
End If
'------------------
If Me.TextBox5.Value = "" Then
MsgBox "Please Fill Wire Gauge", vbCritical
Exit Sub
End If
'------------------
If Me.TextBox6.Value = "" Then
MsgBox "Please Fill Wire/Cable P/N", vbCritical
Exit Sub
End If
'------------------
If Me.TextBox7.Value = "" Then
MsgBox "Please Fill (To) Connector REF DES", vbCritical
Exit Sub
End If
'------------------
If Me.TextBox8.Value = "" Then
MsgBox "Please Fill (To) Pin Location", vbCritical
Exit Sub
End If
'------------------
If Me.TextBox9.Value = "" Then
MsgBox "Please Fill Contact P/N or Supplied with Connector", vbCritical
Exit Sub
End If
'------------------
If Me.ComboBox10.Value = "" Then
MsgBox "Use Drop Down Arrow to Select Wire Color", vbCritical
Exit Sub
End If
'--------------------------------------------------------------------------------------------------
sh.Range("A" & last_row + 1).Value = "=Row()-1"
sh.Range("B" & last_row + 1).Value = Me.TextBox1.Value
sh.Range("C" & last_row + 1).Value = Me.TextBox2.Value
sh.Range("D" & last_row + 1).Value = Me.TextBox3.Value
sh.Range("E" & last_row + 1).Value = Me.TextBox4.Value
sh.Range("F" & last_row + 1).Value = Me.TextBox5.Value
sh.Range("G" & last_row + 1).Value = Me.TextBox6.Value
sh.Range("H" & last_row + 1).Value = Me.TextBox7.Value
sh.Range("I" & last_row + 1).Value = Me.TextBox8.Value
sh.Range("J" & last_row + 1).Value = Me.TextBox9.Value
sh.Range("K" & last_row + 1).Value = Me.ComboBox10.Value
sh.Range("L" & last_row + 1).Value = Me.TextBox11.Value
'------------------
Me.TextBox1.Value = ""
Me.TextBox2.Value = ""
Me.TextBox3.Value = ""
Me.TextBox4.Value = ""
Me.TextBox5.Value = ""
Me.TextBox6.Value = ""
Me.TextBox7.Value = ""
Me.TextBox8.Value = ""
Me.TextBox9.Value = ""
Me.ComboBox10.Value = ""
Me.TextBox11.Value = ""
'------------------
Call Refresh_Data
End Sub""
And this is the picture of the header moved to row 29.
Use a constant for the header row and then it's easy to change in the future.
Option Explicit
Const HEADER = 29
Private Sub CommandButton1_Click()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("CID")
Dim last_row As Long
last_row = sh.Cells(Rows.Count, "A").End(xlUp).Row
If last_row < HEADER Then
last_row = HEADER
End If
Dim arMsg(10) As String, n As Integer, msg As String
arMsg(1) = "Signal Name. If it is not required, fill -"
arMsg(2) = "(From) Connector REF DES"
arMsg(3) = "(From) Connector Pin Location"
arMsg(4) = "Contact P/N or Supplied with Connector"
arMsg(5) = "Wire Gauge"
arMsg(6) = "Wire/Cable P/N"
arMsg(7) = "(To) Connector REF DES"
arMsg(8) = "(To) Pin Location"
arMsg(9) = "Contact P/N or Supplied with Connector"
arMsg(10) = "Use Drop Down Arrow to Select Wire Color"
For n = 1 To 9
If Me.Controls("TextBox" & n).Value = "" Then
msg = msg & vbLf & n & ") " & arMsg(n)
End If
Next
If Me.Controls("ComboBox10").Value = "" Then
msg = msg & vbLf & arMsg(10)
End If
If Len(msg) > 0 Then
MsgBox "Please Fill " & msg, vbCritical
Exit Sub
End If
Dim c As Control
With sh.Range("A" & last_row + 1)
.Offset(0, 0).Value = "=Row()-" & HEADER
For n = 1 To 11
If n = 10 Then
Set c = Me.Controls("ComboBox" & n)
Else
Set c = Me.Controls("TextBox" & n)
End If
.Offset(0, n).Value = c.Value
c.Value = ""
Next
End With
Call Refresh_Data(sh)
End Sub
Sub Refresh_Data(sh As Worksheet)
Dim last_row As Long
last_row = sh.Cells(Rows.Count, "A").End(xlUp).Row
With Me.ListBox1
.ColumnHeads = True
.ColumnCount = 12
.ColumnWidths = "30,100,100,70,100,100,50,100,50,50,120,200"
If last_row <= HEADER Then
last_row = HEADER + 1
End If
.RowSource = sh.Name & "!A" & HEADER + 1 & ":L" & last_row
End With
End Sub

UserForm check the existing list before creating new data VBA

I want to create a userform with inputs: Name (TextBox1), Surname (TextBox2), Date of birth (TextBox3) and 1 output which would basically be their ID (goes from 1 to inf). What bothers me is that I want to code that if lets say Name and Surname already exists in database, msg will popup and form will reset else everything will be put to the table. I kind of managed to do that. Problem is now if I do put name and surname that already exists it wont input it in the table and it will show the message, but even if it doesn't exists the message will still pop up but it will input it in the table. This is the code:
Private Sub CommandButton1_Click()
Dim iRow As Long
Dim ws As Worksheet
Set ws = Sheet2
Dim a As Integer
Application.ScreenUpdating = False
iRow = ws.Range("A1048576").End(xlUp).Row + 1
If Not (TextBox1.Text = "" Or TextBox2.Text = "" Or TextBox3.Text = "") Then
With ws
Label1.Caption = iRow - 1
For a = 1 To iRow
If (ws.Cells(a, 2).Value = TextBox1.Value And ws.Cells(a, 3).Value = TextBox2.Value) Then
MsgBox "Values you entered already exists!"
Call Reset
Exit Sub
Else
.Range("A" & iRow).Value = Label1.Caption
.Range("B" & iRow).Value = TextBox1.Value
.Range("C" & iRow).Value = TextBox2.Value
.Range("D" & iRow).Value = TextBox3.Value
End If
Next a
End With
End If
Application.ScreenUpdating = True
End Sub
The problem is you are checking down to the row where the new record is inserted. So for every row that does not match the new record is inserted at iRow. When the loop gets to the end it checks iRow, matches and shows the message. Separate code into 2 steps, first check then update or reset.
Private Sub CommandButton1_Click()
If TextBox1.Text = "" Or TextBox2.Text = "" Or TextBox3.Text = "" Then
Exit Sub
End If
Dim ws As Worksheet
Dim iRow As Long, r As Long, bExists As Boolean
Set ws = Sheet2
iRow = ws.Cells(Rows.Count, "A").End(xlUp).Row
' check exists
For r = 1 To iRow
If (ws.Cells(r, 2).Value = TextBox1.Value) _
And (ws.Cells(r, 3).Value = TextBox2.Value) Then
bExists = True
Exit For
End If
Next
' update sheet
If bExists Then
MsgBox "Values you entered already exists!"
Call Reset
Exit Sub
Else
Label1.Caption = iRow
iRow = iRow + 1
With ws
.Range("A" & iRow).Value = Label1.Caption
.Range("B" & iRow).Value = TextBox1.Value
.Range("C" & iRow).Value = TextBox2.Value
.Range("D" & iRow).Value = TextBox3.Value
End With
End If
End Sub

Copied sheet with userform won't insert data into new userform

I'm having trouble with the userform copied to the new sheet to insert data in the new sheet.
The userform code is:
Sub userform_initialize()
Dim LastColumn As Long
Dim aCell As Range
' dont know why this code, but helps the named ranges
With Worksheets("MasterData")
For i = 1 To LastColumn
With .Columns(i)
LastRow = Lookup.Cells(Rows.Count, i).End(xlUp).Row
With Range(Cells(1, i), Cells(LastRow, i))
Range(Cells(1, i), Cells(LastRow, i)).Select
Selection.CreateName Top:=True
End With
End With
Next i
End With
' defining the input to the combobox and lists from masterdata
Me.ComboBoxName.RowSource = "Name"
Me.ComboBoxTMS.RowSource = "TMS"
Me.ComboBoxOtherT.RowSource = "Other_T"
Me.ListBoxPlacement.RowSource = "Placement"
End Sub
Sub CommandSave_click()
' mandatory for picking name in userform
If ComboBoxName.Value = "" Then
MsgBox "You must select a name"
Cancel = True
Exit Sub
End If
'mandatory for writing hours in userform
If TextBoxHours.Value = "" Then
MsgBox "You need to type in hours"
Cancel = True
Exit Sub
End If
'mandatory of either TMS or Other Timeregistration in userform
If ComboBoxOtherT.Value = "" Then
If ComboBoxTMS.Value = "" Then
MsgBox "You must select TMS or Other Timeregistration"
Cancel = True
Exit Sub
End If
End If
'manadatory for picking one in the listbox with placement for userform
If Not IsAnythingSelected(ListBoxPlacement) Then
MsgBox "Please select placement of workday"
Exit Sub
End If
' calling the macro that inserts the data in the correct columns and rows.
Call BSave
' Clear Values
ComboBoxName.Value = ""
ComboBoxTMS.Value = ""
ComboBoxOtherT.Value = ""
TextBoxHours.Value = ""
TextBoxComments.Value = ""
ListBoxPlacement.Value = ""
End Sub
Private Sub BSave()
Dim LastRow As Long, ws As Worksheet
Set ws = Sheets("McLys_Timeregistration") ' declaring which worksheet we are working on
LastRow = ws.Range("B" & Rows.Count).End(xlUp).Row + 1 'Finds the last blank row
ws.Range("B" & LastRow).Value = ComboBoxName.Text 'Adds into Col A & Last Blank Row
ws.Range("C" & LastRow).Value = DTPicker1.Value 'Adds into Col B & Last Blank Row
ws.Range("D" & LastRow).Value = TextBoxHours.Value 'Adds into Col C & Last Blank Row
ws.Range("E" & LastRow).Value = ComboBoxTMS.Text 'Adds into Col D & Last Blank Row
ws.Range("F" & LastRow).Value = ComboBoxOtherT.Text 'Adds into Col E & Last Blank Row
ws.Range("G" & LastRow).Value = TextBoxComments.Text 'Adds into Col F & Last Blank Row
ws.Range("H" & LastRow).Value = ListBoxPlacement.Text 'Adds into Col G & Last Blank Row
End Sub
' function for making sure that at least one of the choices are chosen in the listbox
Function IsAnythingSelected(lBox As Control) As Boolean
Dim i As Long
Dim selected As Boolean
selected = False
For i = 1 To lBox.ListCount
If lBox.selected(i) Then
selected = True
Exit For
End If
Next i
IsAnythingSelected = selected
End Function
Sub CommandCancel_click()
Unload Me ' making the userform closing
End Sub
Private Sub UserForm_Activate()
' every time the userform is activated it makes sure that its todays date there is in the calendar.
DTPicker1.Value = Date
End Sub
and for what i can see and have tried to change only in the code below the sheet name is mentioned
Private Sub BSave()
Dim LastRow As Long, ws As Worksheet
Set ws = Sheets("McLys_Timeregistration") ' declaring which worksheet we are working on
LastRow = ws.Range("B" & Rows.Count).End(xlUp).Row + 1 'Finds the last blank row
ws.Range("B" & LastRow).Value = ComboBoxName.Text 'Adds into Col A & Last Blank Row
ws.Range("C" & LastRow).Value = DTPicker1.Value 'Adds into Col B & Last Blank Row
ws.Range("D" & LastRow).Value = TextBoxHours.Value 'Adds into Col C & Last Blank Row
ws.Range("E" & LastRow).Value = ComboBoxTMS.Text 'Adds into Col D & Last Blank Row
ws.Range("F" & LastRow).Value = ComboBoxOtherT.Text 'Adds into Col E & Last Blank Row
ws.Range("G" & LastRow).Value = TextBoxComments.Text 'Adds into Col F & Last Blank Row
ws.Range("H" & LastRow).Value = ListBoxPlacement.Text 'Adds into Col G & Last Blank Row
End Sub
can anyone tell me where the problem is? if i change the sheet name here its still inserting the information into the old sheet.
in the sheet only this is mentioned to call the userform:
Sub shape_button()
UserForm1.Show
End Sub
Sub placeUser()
With UserForm1
.StartUpPosition = 0
.Left = Application.Left + (0.5 * Application.Width) - (0.5 * .Width)
.Top = Application.Top + (0.5 * Application.Height) - (0.5 * .Height)
.Show
End With
End Sub
Thanks in advance

Applying VBA the same rule to several rows

I have a code that I want to apply to several rows. I only created for Row 11, my problem is that I need to apply below code until Row 60. How can I write it?
Sorry still new in VBA world & I am having hard time understanding the For Each or looping rule.
Sub RectangleRoundedCorners11_Click()
If Range("A11").Value = "new request" Then
If Range("D11").Value = "" Or Range("E11").Value = "" Or Range("G11").Value = "" Or Range("H11").Value = "" Then
MsgBox "Please fill all mandatory fields"
End If
End If
End Sub
Code below:
Sub RectangleRoundedCorners11_Click()
for i=11 to 60
If Range("A" & i).Value = "new request" Then
If Range("D" & i).Value = "" Or Range("E" & i).Value = "" Or Range("G" & i).Value = "" Or Range("H" & i).Value = "" Then
MsgBox "Please fill all mandatory fields"
End If
End If
next i
End Sub
This will check the rows between 11 and 60. If you need more rows, just edit the values in the for statement.
You can use this code
Sub RectangleRoundedCorners11_Click()
Dim col As Integer
If Range("A11").Value = "new request" Then
'loop from D to ...
For col = 4 To 60
If Range(Col2Letter(col) & "11").Value = "" Then
MsgBox "Please fill all mandatory fields"
Exit For
End If
Next
End If
End Sub
Function Col2Letter(lngCol As Integer) As String
Dim vArr
vArr = Split(Cells(1, lngCol).Address(True, False), "$")
Col2Letter = vArr(0)
End Function
Through Rows
Tips
Use Option Explicit for VBA to detect errors.
Use constants at the beginning of the code to quickly be able to change them in one place.
Declare all variables (e.g. Dim i As Integer)
The Code
Option Explicit
Sub RectangleRoundedCorners11_Click()
Const cFirst As Integer = 11 ' First Row
Const cLast As Integer = 60 ' Last Row
Const cRequest As String = "new request" ' Request Text
Const cMsg As String = "Please fill all mandatory fields" ' MsgBox Text
Dim i As Integer
For i = cFirst To cLast
If Range("A" & i).Value = cRequest Then
If Range("D" & i).Value = "" Or Range("E" & i).Value = "" _
Or Range("G" & i).Value = "" Or Range("H" & i).Value = "" Then
MsgBox cMsg
End If
End If
Next
End Sub
A one cell range can be created using Range or Cells e.g. for A1:
Range("A1") or Cells(1, "A") or Cells(1, 1).
The If statement has a few versions. In this case two of them are
equally valid, simplified as follows:
If x=y Then
x=5
End If
' or
If x=y Then x=5
A More Advanced Version
Sub RectangleRoundedCorners11_Click()
Const cFirst As Integer = 11 ' First Row
Const cLast As Integer = 60 ' Last Row
Const cRequest As String = "new request" ' Request Text
Const cMsg As String = "Please fill all mandatory fields" ' MsgBox Text
Const cColumns As String = "A,D,E,G,H" ' Columns List
Dim vnt As Variant ' Columns Array
Dim i As Integer ' Row Counter
vnt = Split(cColumns, ",") ' An array created with Split is 0-based.
For i = cFirst To cLast
If Cells(i, vnt(0)).Value = cRequest Then
If Cells(i, vnt(1)).Value = "" Or Cells(i, vnt(2)).Value = "" _
Or Cells(i, vnt(3)).Value = "" _
Or Cells(i, vnt(4)).Value = "" Then MsgBox cMsg
End If
Next
End Sub

for....next loop failed after repeat userform

I'm using for next loop with while wend loop inside of it. the problem is when I enter first data and then I want to repeat inserting by choosing vbYes,the loop will repeat but it set the value to i=32 again and proceed while loop eventhough the while{condition} is false.let me give some example,
comboBox1.value = {a,b,c,d}
i={32,33,34,35} ~> i is set to row number.
for the first count,I insert c to combobox1 giving combobox1.value=c and cells(34,2).value=c hence while loop proceed. but when I choose to continue inserting data for second time, it go back to for next loop again but it set the value of i=32, giving cells(32,2).value=c and then proceed to while loop but the while loop suppose to not proceed because the correct value for cells(32,2).value=a . can anyone help?
Dim i As Long
Dim prod As String
Dim RowNo As Long
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Application.ScreenUpdating = False
prod = ComboBox1.Value
For i = 32 To 35
While ComboBox1.Value = Worksheets("Input").Cells(i, 2).Value
Rows(i).Select
Selection.Insert shift = xlDown
With Worksheets("Input")
'~insert data
.Range("B" & i) = ComboBox1.Text
.Range("C" & i) = TextBox1.Text
.Range("D" & i) = TextBox2.Text
.Range("E" & i) = TextBox3.Text
.Range("F" & i) = TextBox4.Text
.Range("G" & i) = TextBox5.Text
.Range("H" & i) = ComboBox2.Text
.Range("I" & i) = TextBox6.Text
.Range("J" & i) = TextBox7.Text
.Range("K" & i) = TextBox8.Text
End With
Workbooks(prod & " Input.xlsm").Activate
'~select row number from another worksheet
RowNo = Workbooks(prod & " Input.xlsm").Worksheets("Input").Cells(31, 3).Value
Set sh1 = Workbooks(prod & " Input.xlsm").Worksheets("Input")
Set sh2 = Workbooks("MasterInput.xlsm").Worksheets("Input")
'~copy inserted data from master input to product input
sh1.Range(sh1.Cells(RowNo, 2), sh1.Cells(RowNo, 11)).Value = sh2.Range(sh2.Cells((i, 2), sh2.Cells(i , 11)).Value
If MsgBox("One record written to Master Input. Do you want to continue entering data?", vbYesNo) = vbYes Then
GoTo repeat1:
Else
Unload Me
End If
Exit Sub
Wend
Next
Application.ScreenUpdating = True
repeat1:
End Sub
You are unloading form from memory.Unload the form when you dont want to continue..
if msgbox("you want to continue",vbyesNo)=vbyes then
goto repeat1
else
unload me
end if
lastly! just a simple one line command that i forgot to put.
insert above for loop
Workbooks("MasterInput.xlsm").Activate
For i = 32 To 35
works now! the i value taken from the second workbook where it suppose to take from first workbook.

Resources