Idea behind the code is that it is supposed to find customer names, then find the level of sales to them throughout the year then paste all this data into another sheet.
Getting a Run-Time error '1004' Application-defined or object-defined error from the following line. I have asterisked the line where I am getting the error.
Sub Import_CustomerData()
Dim strMonth As String
Dim rngMonth As Range
Dim DataImportColum As Integer
Dim DataImportRow As Integer
Dim strFirstCustomer As String
Dim strSecondCustomer As String
Dim strThirdCustomer As String
Dim strFourthCustomer As String
Dim strFifthCustomer As String
Dim lngFirstCustomerSales As Long
Dim lngSecondCustomerSales As Long
Dim lngThirdCustomerSales As Long
Dim lngFourthCustomerSales As Long
Dim lngFifthCustomerSales As Long
Dim lngTotalSales As Long
Dim cell As Range
Dim x As Integer
'Finding Data for clients
For Each cell In Worksheets("Data entry").Range("A1:A99")
If cell.Value = "Customer Sales" Then
strFirstCustomer = cell.Offset(1, 0).Value
strSecondCustomer = cell.Offset(2, 0).Value
strThirdCustomer = cell.Offset(3, 0).Value
strFourthCustomer = cell.Offset(4, 0).Value
strFifthCustomer = cell.Offset(5, 0).Value
End If
Next
'Extracting Data from Customer sheet
***For Each cell In Worksheets("Client_Customer").Range("B83:86")***
'First Customer
If cell.Value = strFirstCustomer Then
lngFirstCustomerSales = Val(cell.Offset(0, 1))
End If
'Second Customer
If cell.Value = strSecondCustomer Then
lngSecondCustomerSales = Val(cell.Offset(0, 1))
End If
'Third Customer
If cell.Value = strThirdCustomer Then
lngThirdCustomerSales = Val(cell.Offset(0, 1))
End If
'Fourth Customer
If cell.Value = strFourthCustomer Then
lngFourthCustomerSales = Val(cell.Offset(0, 1))
End If
'Fifth Customer
If cell.Value = gxdfg Then
lngFifthCustomerSales = Val(cell.Offset(0, 1))
End If
'Total Customers Sales
If cell.Value = "Total:" Then
lngTotalSales = Val(cell.Offset(0, 1))
End If
Next
'Importing it into Data Customer Monthly 2013 sheet.
'Determing month of client system reports
strMonth = Sheets("Client_Customer").Range("B8").Value
If strMonth = "" Then
frmEnter_month.Show
Else
iLenMonth = Len(strMonth)
x = iLenMonth - 5
strLeftMonth = Left(strMonth, x)
End If
'To find Column of Customer imput
For Each cell In Range("B4:M4")
If cell.Value = strLeftMonth Then
DataImportColumn = cell.Column
End If
Next
For Each cell In Worksheets("data customer monthly 2013").Range("A3:A9999")
'First Customer
If cell.Value = strFirstCustomer Then
DataImportRow = cell.Row
** 2 ** lngFirstCustomerSales = Cells(DataImportRow, DataImportColumn).Offset(0, 2).Value ** 2 **
End If
'Second Customer
If cell.Value = strSecondCustomer Then
DataImportRow = cell.Row
lngSecondCustomerSales = Cells(DataImportRow, DataImportColumn).Offset(0, 2).Value
End If
'Third Customer
If cell.Value = strThirdCustomer Then
DataImportRow = cell.Row
lngThirdCustomerSales = Cells(DataImportRow, DataImportColumn).Offset(0, 2).Value
End If
'Fourth customer
If cell.Value = strFourthCustomer Then
DataImportRow = cell.Row
lngFourthCustomerSales = Cells(DataImportRow, DataImportColumn).Offset(0, 2).Value
End If
'Fifth Customer
If cell.Value = strFifthCustomer Then
DataImportRow = cell.Row
lngFifthCustomerSales = Cells(DataImportRow, DataImportColumn).Offset(0, 2).Value
End If
'Total Sales
If cell.Value = "Total Sales" Then
DataImportRow = cell.Row
lngTotalSales = Cells(48, DataImportColumn).Value
End If
Next
DeleteClientSheets
End Sub
Sorry for the large amount of code but does anyone have any suggestions? Couldn't find anything else that help explain the question as cell has been defined as a range.
EDIT1:
Second question: After Silenxor's brilliant solution, I am getting code on the line with the following indicator: ** 2 **
The error I am getting is the same as the first error.
With regards to your asterix line
For Each cell In Worksheets("Client_Customer").Range("B83:86")
Try
For Each cell In Worksheets("Client_Customer").Range("B83:B86")
Related
The below code is not showing the results on the "All Stock Analysis" sheet.
I tried doing a test after the activation of each worksheet (Range("I1).Interior.Color = vbGreen) and cell I1 turns green on each of the desired worksheets. What other tests can I try? No error msg pops up.
Sub AllStocksAnalysisRefactored()
Dim startTime As Single
Dim endTime As Single
yearValue = InputBox("What year would you like to run the analysis on?")
startTime = Timer
'Format the output sheet on All Stocks Analysis worksheet
Worksheets("All Stock Analysis").Activate
Range("A1").Value = "All Stocks (" + yearValue + ")"
'Create a header row
Cells(3, 1).Value = "Ticker"
Cells(3, 2).Value = "Total Daily Volume"
Cells(3, 3).Value = "Return"
'Initialize array of all tickers
Dim tickers(12) As String
tickers(0) = "AY"
tickers(1) = "CSIQ"
tickers(2) = "DQ"
tickers(3) = "ENPH"
tickers(4) = "FSLR"
tickers(5) = "HASI"
tickers(6) = "JKS"
tickers(7) = "RUN"
tickers(8) = "SEDG"
tickers(9) = "SPWR"
tickers(10) = "TERP"
tickers(11) = "VSLR"
'Activate data worksheet
Worksheets(yearValue).Activate
'Get the number of rows to loop over
RowCount = Cells(Rows.Count, "A").End(xlUp).Row
'1a) Create a ticker Index
Dim tickerIndex As Single
tickerIndex = 0
'1b) Create three output arrays
Dim tickerVolumes(12) As LongLong
Dim tickerstartingPrices(12) As Single
Dim tickerendingPrices(12) As Single
''2a) Create a for loop to initialize the tickerVolumes to zero.
For i = 0 To 11
tickerVolumes(i) = 0
''2b) Loop over all the rows in the spreadsheet.
For j = 2 To RowCount
'3a) Increase volume for current ticker
tickerVolumes(tickerIndex) = tickerVolumes(tickerIndex) + Cells(j, 8).Value
'3b) Check if the current row is the first row with the selected tickerIndex.
'If Then
If Cells(j - 1, 1).Value <> tickers(tickerIndex) And _
Cells(j, 1).Value = tickers(tickerIndex) Then
tickerstartingPrices(tickerIndex) = Cells(j, 6).Value
'End If
End If
'3c) check if the current row is the last row with the selected ticker
'If the next row’s ticker doesn’t match, increase the tickerIndex.
'If Then
If Cells(j + 1, 1).Value <> tickers(tickerIndex) And _
Cells(j, 1).Value = tickers(tickerIndex) Then
tickerendingPrices(tickerIndex) = Cells(j, 6).Value
'3d Increase the tickerIndex.
tickerIndex = tickerIndex + 1
'End If
End If
Next j
Next i
'4) Loop through your arrays to output the Ticker, Total Daily Volume, and Return.
For i = 0 To 11
Worksheets("All Stock Analysis").Activate
Next i
'Formatting
Worksheets("All Stock Analysis").Activate
Range("A3:C3").Font.FontStyle = "Bold"
Range("A3:C3").Borders(xlEdgeBottom).LineStyle = xlContinuous
Range("B4:B15").NumberFormat = "#,##0"
Range("C4:C15").NumberFormat = "0.0%"
Columns("B").AutoFit
dataRowStart = 4
dataRowEnd = 15
For i = dataRowStart To dataRowEnd
If Cells(i, 3) > 0 Then
Cells(i, 3).Interior.Color = vbGreen
Else
Cells(i, 3).Interior.Color = vbRed
End If
Next i
endTime = Timer
MsgBox "This code ran in " & (endTime - startTime) & _
" seconds for the year " & (yearValue)
End Sub
Here is how "All Stock Analysis" sheet will look after running the code:
You only need to scan the data sheet once if you use a dictionary object to convert the ticker ID to an array index number.
Option Explicit
Sub AllStocksAnalysisRefactored()
Const SHT_NAME = "All Stock Analysis"
Dim wb As Workbook, ws As Worksheet, wsYr As Worksheet
Dim cell As Range, yr As String, iRow As Long, iLastRow As Long
Dim t As Single: t = Timer
' choose data worksheet
yr = InputBox("What year would you like to run the analysis on ? ", "Enter Year", Year(Date))
Set wb = ThisWorkbook
On Error Resume Next
Set wsYr = wb.Sheets(yr)
On Error GoTo 0
' check if exists
If wsYr Is Nothing Then
MsgBox "Sheet '" & yr & "' does not exists.", vbCritical, "Error"
Exit Sub
End If
'Initialize array of all tickers
Dim tickerID, tickerData(), i As Integer, n As Integer
Dim dict As Object, sId As String
tickerID = Array("AY", "CSIQ", "DQ", "ENPH", "FSLR", "HASI", _
"JKS", "RUN", "SEDG", "SPWR", "TERP", "VSLR")
n = UBound(tickerID) + 1
ReDim tickerData(1 To n, 1 To 5)
' create dict id to index
Set dict = CreateObject("Scripting.Dictionary")
For i = 1 To n
sId = UCase(Trim(tickerID(i - 1)))
tickerData(i, 1) = sId ' id
tickerData(i, 2) = 0 ' volume
tickerData(i, 3) = 0 ' start price
tickerData(i, 4) = 0 ' finish price
tickerData(i, 5) = 0 ' count
dict.Add sId, i
Next
'Get the number of rows to loop over
iLastRow = wsYr.Cells(Rows.Count, "A").End(xlUp).Row
' Loop over all the rows in the spreadsheet.
' A=ticker, F=Price , H=Volume
For iRow = 2 To iLastRow
sId = UCase(Trim(wsYr.Cells(iRow, "A")))
If dict.exists(sId) Then
i = dict(sId)
' volume
tickerData(i, 2) = tickerData(i, 2) + wsYr.Cells(iRow, "H") ' volume
' start price when count is 0
If tickerData(i, 5) = 0 Then
tickerData(i, 3) = wsYr.Cells(iRow, "F")
End If
' end price
tickerData(i, 4) = wsYr.Cells(iRow, "F")
' count
tickerData(i, 5) = tickerData(i, 5) + 1
End If
Next
'Format the output sheet on All Stocks Analysis worksheet
Set ws = wb.Sheets(SHT_NAME)
ws.Cells.Clear
With ws
.Range("A1").Value2 = "All Stocks (" & yr & ")"
With .Range("A3:E3")
.Value2 = Array("Ticker", "Total Daily Volume", "Start Price", "End Price", "Return")
.Font.FontStyle = "Bold"
.Borders(xlEdgeBottom).LineStyle = xlContinuous
End With
.Range("A4").Resize(n, 4).Value2 = tickerData
.Range("B4:D4").Resize(n).NumberFormat = "#,##0"
.Range("E4").Resize(n).NumberFormat = "0.0%"
.Columns("B").AutoFit
End With
' coloring
For Each cell In ws.Range("E4").Resize(n)
cell.FormulaR1C1 = "=(RC[-1]-RC[-2])/RC[-2]" ' end-start/start
If cell > 0 Then
cell.Interior.Color = vbGreen
Else
cell.Interior.Color = vbRed
End If
Next
ws.Activate
ws.Range("A1").Select
MsgBox "This code ran for (" & yr & ")", vbInformation, Int(Timer - t) & " seconds"
End Sub
I created a userform to add data in excel.
The data is been added quite good but the problem is that they are added first in total row then outside the table I have created
here is the code I am using:
Sub Submit_Data()
Dim iRow As Long
If adminpanel.txtRowNumber.Value = "" Then
iRow = student.Range("A" & Rows.Count).End(xlUp).Row + 1
Else
iRow = adminpanel.txtRowNumber.Value
End If
With student.Range("A" & iRow)
.Offset(0, 0).Value = "=Row()-1"
.Offset(0, 1).Value = adminpanel.Studentname.Value
.Offset(0, 2).Value = adminpanel.Class.Value
.Offset(0, 3).Value = adminpanel.School.Value
.Offset(0, 4).Value = adminpanel.Mobile.Value
.Offset(0, 5).Value = adminpanel.Email.Value
.Offset(0, 6).Value = adminpanel.txtImagePath.Value
End With
Call Reset_Form
Application.ScreenUpdating = True
MsgBox "data are done"
End Sub
If you're working with a Table/ListObject then it has a ListRows.Add method which you should use when you need to add a new row. From that row you can get its Range property.
Sub Submit_Data()
Dim iRow As Long, tblRow As Range, lo As ListObject
Set lo = student.ListObjects(1) 'get a reference to your table
If Len(adminpanel.txtRowNumber.Value) = 0 Then
Set tblRow = lo.ListRows.Add.Range '<< add a new row and get its range
Else
'get a reference to the existing row
iRow = CLng(adminpanel.txtRowNumber.Value)
Set tblRow = Application.Intersect(student.Rows(iRow), _
lo.DataBodyRange)
End If
'Fill the row in one operation using an array
tblRow.Value = Array(tblRow.Row - 1, adminpanel.Studentname.Value, _
adminpanel.Class.Value, adminpanel.School.Value, _
adminpanel.Mobile.Value, adminpanel.Email.Value, _
adminpanel.txtImagePath.Value)
Reset_Form
MsgBox "data are done"
End Sub
This is a silly question, but I can't seem to find the issue with the code after a lot of hunting. I'm creating a For Each loop that finds all incidences of "Friday," goes over to the cell 6 columns over from "Friday" (under the "Overtime" heading), inserts the number 0 in that cell, and changes the number format. Here is my worksheet so far.
Here is my code:
Sub Calendar_Generator()
Dim WS As Worksheet
Dim MyInput As String
Dim StartDay As Date
Dim Sp() As String
Dim a As Integer
Dim R As Long
Dim Match As Range
Dim b As Variant
Dim DayNames() As String
Dim FirstAddress As String
Dim DeleteDays As Range
Dim c As Variant
Dim Day1 As Range
Dim WorkDays As Range
Dim d As Variant
'Dim Fri As Range
Set WS = ActiveWorkbook.ActiveSheet
WS.Range("A1:R100").Clear
'This loop is crashing excel
'Do
MyInput = InputBox("Enter the start date for the Calendar:")
'If MyInput = "" Then Exit Sub
'Loop While Not IsDate(MyInput)
' repeat if entry isn't recognized as a date
' Set the date value of the beginning of inputted month.
' -- regardless of the day the user entered, even if missing
StartDay = DateSerial(Year(CDate(MyInput)), Month(CDate(MyInput)), 1)
'Set headers
Range("a1").Value = Format(StartDay, "mmmm") & " Time Sheet"
Sp = Split("Day,Date,Time In,Time Out,Hours,Notes,Overtime", ",")
For a = 0 To UBound(Sp)
WS.Cells(2, 1 + a).Value = Sp(a)
Next a
' fill the days for the selected month
' == the last day of a month is always the day before the first of the next
' here deducting 2 to count from 0
For R = 0 To Day(DateAdd("m", 1, StartDay) - 2)
With WS.Cells(3 + R, 2)
.Value = StartDay + R
.NumberFormat = "d-mmm"
.Offset(, -1).Value = StartDay + R
.Offset(, -1).NumberFormat = "dddd"
End With
Next R
ReDim DayNames(1)
'To add more headers, change statement to 3
DayNames(0) = "Saturday"
DayNames(1) = "Sunday"
For b = LBound(DayNames) To UBound(DayNames)
Set Match = WS.Cells.Find(What:=DayNames(b), LookIn:=xlValues, _
lookat:=xlWhole, searchorder:=xlByRows, searchdirection:=xlPrevious, _
MatchCase:=True, SearchFormat:=False)
If Not Match Is Nothing Then
FirstAddress = Match.Address
Do
Match.EntireRow.Clear
'Highlight cell containing table heading in green
Set Match = WS.Cells.FindNext(Match)
Loop While Not Match Is Nothing
End If
Next b
Set DeleteDays = Range("A3:A50")
For Each c In DeleteDays
If c = "" Then
c.EntireRow.Delete
End If
Next c
'Works for some reason if it's executed twice
Set DeleteDays = Range("A3:A50")
For Each c In DeleteDays
If c = "" Then
c.EntireRow.Delete
End If
Next c
'Insert and format template time values with formula for hours worked in E3
Set Day1 = Range("B3")
Range(Day1, Day1.End(xlDown)).Select
With Selection
Selection.Offset(, 1).Value = "8:00 AM"
Selection.Offset(, 1).NumberFormat = "h:mm AM/PM"
Selection.Offset(, 2).Value = "4:00 PM"
Selection.Offset(, 2).NumberFormat = "h:mm AM/PM"
Selection.Offset(, 3).Value = "0"
Selection.Offset(, 3).NumberFormat = "h:mm"
Day1.Offset(, 3).Formula = "=D3-C3"
End With
'Fill in hours worked formula
Day1.Offset(, 3).Select
Selection.AutoFill Destination:=Range(Selection, Selection.End(xlDown))
'*This is the loop that isn't functioning, but also isn't calling any errors*
'Set Overtime calculation
Set WorkDays = Range("A3:A33")
For Each d In WorkDays
If d = "Friday" Then
d.Offset(, 6).Value = "0"
d.Offset(, 6).NumberFormat = "h:mm"
End If
Next d
End Sub
I've had some trouble with loops crashing Excel since I switched to Excel 365, but this For Each loop isn't crashing it. Any ideas as to why this For Each loop isn't doing its job?
I'm creating a sub that creates a time sheet for a specific month/year. The code is based on this Microsoft example code. The Microsoft code creates this calendar. I'm amending the code to insert the days of the week in a single column, like this.
My amended code correctly inserts the number 1 in the cell corresponding to the first day of the month, but the loop to add the subsequent day numbers does not work; Cell.Value = Cell.Offset(-1, 0).Value + 1 gives a Type Mismatch Error. Here is my amended code:
Sub Calendar_Genorator1()
Dim WS As Worksheet
Dim MyInput As Variant
Dim StartDay As Variant
Dim DayofWeek As Variant
Dim CurYear As Variant
Dim CurMonth As Variant
Dim FinalDay As Variant
Dim Cell As Range
Dim RowCell As Long
Dim ColCell As Long
Set WS = ActiveWorkbook.ActiveSheet
MyInput = InputBox("Type in Month and year for Calendar ")
If MyInput = "" Then Exit Sub
' Get the date value of the beginning of inputted month.
StartDay = DateValue(MyInput)
' Check if valid date but not the first of the month
' -- if so, reset StartDay to first day of month.
If Day(StartDay) <> 1 Then
StartDay = DateValue(Month(StartDay) & "/1/" & Year(StartDay))
End If
' Prepare cell for Month and Year as fully spelled out.
'Range("B3").NumberFormat = "d-mmmm"
'Set headers
Range("a1").Value = Application.Text(MyInput, "mmmm") & " Time Sheet"
Range("a2") = "Day"
Range("b2") = "Date"
Range("c2") = "Time In"
Range("d2") = "Time Out"
Range("e2") = "Hours"
Range("f2") = "Notes"
Range("g2") = "Overtime"
'Set weekdays
Range("a3") = "Sunday"
Range("a4") = "Monday"
Range("a5") = "Tuesday"
Range("a6") = "Wednesday"
Range("a7") = "Thursday"
Range("a8") = "Friday"
Range("a9") = "Saturday"
DayofWeek = Weekday(StartDay)
' Set variables to identify the year and month as separate variables.
CurYear = Year(StartDay)
CurMonth = Month(StartDay)
' Set variable and calculate the first day of the next month.
FinalDay = DateSerial(CurYear, CurMonth + 1, 1)
' Place a "1" in cell position of the first day of the chosen month based on DayofWeek.
Select Case DayofWeek
Case 1
Range("b3").Value = 1
Case 2
Range("b4").Value = 1
Case 3
Range("b5").Value = 1
Case 4
Range("b6").Value = 1
Case 5
Range("b7").Value = 1
Case 6
Range("b8").Value = 1
Case 7
Range("b9").Value = 1
End Select
'Loop through range b3:b44 incrementing each cell after the "1" cell.
For Each Cell In Range("b3:b44")
RowCell = Cell.Row
ColCell = Cell.Column
' Do if "1" is in column B or 2.
If Cell.Row = 1 And Cell.Column = 2 Then
' Do if current cell is not in 1st column.
ElseIf Cell.Row <> 1 Then
If Cell.Offset(-1, 0).Value >= 1 Then
Cell.Value = Cell.Offset(-1, 0).Value + 1 'Type Mismatch Error here
' Stop when the last day of the month has been entered.
If Cell.Value > (FinalDay - StartDay) Then
Cell.Value = ""
' Exit loop when calendar has correct number of days shown.
Exit For
End If
End If
End If
Next
End Sub
I changed the parameters in the loop to work inserting the days incrementally in column B, and I suspect the error is related to that. Any ideas as to why I'm getting an error for Cell.Value = Cell.Offset(-1, 0).Value + 1?
Monthly Calendar
Option Explicit
Sub Calendar_Genorator1()
Const TitleAddress As String = "A1"
Const HeadersAddress As String = "A2"
Const DaysAddress As String = "A3"
Dim Headers As Variant
Headers = Array("Day", "Date", "Time In", "Time Out", "Hours", _
"Notes", "Overtime")
Dim MyInput As Variant, StartDay As Variant
MyInput = InputBox("Type in setMonth and year for Calendar ")
If MyInput = "" Then Exit Sub
' Get the date value of the beginning of inputted Month.
StartDay = DateValue(MyInput)
' Check if valid date but not the first of the Month
' -- if so, reset StartDay to first day of Month.
If Day(StartDay) <> 1 Then
StartDay = DateValue(Month(StartDay) & "/1/" & Year(StartDay))
End If
Dim ws As Worksheet
Set ws = ActiveWorkbook.ActiveSheet
' Write title.
ws.Range(TitleAddress).Value = Application.Text(StartDay, "mmmm") _
& " Time Sheet"
' Write headers.
ws.Range(HeadersAddress).Resize(, UBound(Headers)) = Headers
' Write days.
Dim Target As Variant
Target = getDDDD_D_US(Month(StartDay), Year(StartDay))
ws.Range(DaysAddress).Resize(UBound(Target), UBound(Target, 2)).Value = Target
End Sub
Function getDDDD_D_US(setMonth As Long, setYear As Long)
Dim DaysData As Variant
DaysData = Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", _
"Friday", "Saturday")
Dim Result As Variant
ReDim Result(1 To 42, 1 To 2)
' Write DDDD column.
Dim i As Long, j As Long, k As Long
For i = 1 To 6
k = (i - 1) * 7 + 1
For j = 0 To 6
Result(k + j, 1) = DaysData(j)
Next j
Next i
' Write D column.
Dim Current As Date
Current = DateSerial(setYear, setMonth, 1)
i = Weekday(Current)
For i = i To i + 27
Result(i, 2) = Day(Current)
Current = Current + 1
Next i
For i = i To i + 2
If Month(Current) = setMonth Then
Result(i, 2) = Day(Current)
Current = Current + 1
End If
Next i
getDDDD_D_US = Result
End Function
I have a list with Name, Phone number, City and Dinner.
When the user fills out the user form they type in the abovementioned inputs.
The code updates the list if they fill in the same Name so the list does not append another row. I tried to edit the code such that it take into account Phone number too, but nothing changes.
However, how can I make the list add a new row if the user adds in the same name but different number?
Private Sub OKButton_Click()
Dim emptyRow As Long
'Make Sheet1 active
Sheet1.Activate
'Determine emptyRow
emptyRow = WorksheetFunction.CountA(Range("A:A")) + 1
' try to retrieve the Name
Dim rngIdList As Range, rngId As Range
Dim phoneIdList As Range, phoneId As Range
Set rngIdList = ActiveSheet.Range([a2], [a2].End(xlDown))
Set phoneIdList = ActiveSheet.Range([b2], [b2].End(xlDown))
Set rngId = rngIdList.Find(Me.NameTextBox.Value, LookIn:=xlValues)
Set phoneId = phoneIdList.Find(Me.PhoneTextBox.Value, LookIn:=xlValues)
If rngId Is Nothing And phoneId Is Nothing Then
' if Name is not found, append new one to the end of the table
With rngIdList And phoneIdList
Set rngId = .Offset(.Rows.Count, 0).Resize(1, 1)
Set phoneId = .Offset(.Rows.Count, 0).Resize(1, 1)
End With
End If
' update excel record
rngId.Offset(0, 0).Value = Me.NameTextBox.Value
rngId.Offset(0, 1).Value = Me.PhoneTextBox.Value
rngId.Offset(0, 2).Value = Me.CityListBox.Value
rngId.Offset(0, 3).Value = Me.DinnerComboBox.Value
phoneId.Offset(0, 0).Value = Me.NameTextBox.Value
phoneId.Offset(0, 1).Value = Me.PhoneTextBox.Value
phoneId.Offset(0, 2).Value = Me.CityListBox.Value
phoneId.Offset(0, 3).Value = Me.DinnerComboBox.Value
Expected output:
Here you can see that Jake adds his name multiple times with different phone numbers, but it doesn't get overwritten (as intended). However, if he adds number 888 again with different Dinner, it will get overwritten with Italian. If he adds number 222, then another row will be added to the list.
Try this. It's untested so let me know how you get on. I've added various explanatory comments.
Private Sub OKButton_Click()
Dim emptyRow As Long, s As String, bFound As Boolean
Sheet1.Activate
emptyRow = Range("A" & Rows.Count).End(xlUp).Row
Dim rngIdList As Range, rngId As Range
Set rngIdList = Range("A2:A" & emptyRow)
Set rngId = rngIdList.Find(Me.NameTextBox.Value, LookIn:=xlValues)
If rngId Is Nothing Then 'NAME NOT FOUND SO ADD NEW RECORD
With Range("A" & emptyRow + 1)
.Value = Me.NameTextBox.Value
.Offset(0, 1).Value = Me.PhoneTextBox.Value
.Offset(0, 2).Value = Me.CityListBox.Value
.Offset(0, 3).Value = Me.DinnerComboBox.Value
End With
Else 'NAME FOUND
s = rngId.Address
Do
If rngId.Offset(, 1).Value = Me.PhoneTextBox.Value Then 'PHONE NUMBER FOUND FOR SAME NAME SO UPDATE RECORD
With rngId
.Offset(0, 2).Value = Me.CityListBox.Value
.Offset(0, 3).Value = Me.DinnerComboBox.Value
End With
bFound = True
Exit Do 'NO NEED TO KEEP LOOKING
End If
Set rngId = rngIdList.FindNext(rngId)
Loop While rngId.Address <> s 'KEEP LOOKING UNTIL BACK TO FIRST FOUND VALUE
If Not bFound Then 'IF NAME/PHONE COMBO HAS NOT BEEN FOUND
With Range("A" & emptyRow + 1)
.Value = Me.NameTextBox.Value
.Offset(0, 1).Value = Me.PhoneTextBox.Value
.Offset(0, 2).Value = Me.CityListBox.Value
.Offset(0, 3).Value = Me.DinnerComboBox.Value
End With
End If
End If
End Sub
So many variables to make it easier to understand to you. Something like this (not tested, i didn't build userform)
Dim enteredName As String
enteredName = Me.NameTextBox.Value
Dim headerRow As Long
headerRow = 1 ' row containing headers
Dim lastDataRow As Long
lastDataRow = sheet1.Cells(Rows.Count, 1).End(xlUp).Row
Dim namesRng As Range
Set namesRng = sheet1.Range("A" & headerRow + 1 & ":A" & lastDataRow)
Dim position As Variant
' dim as Variant because if value not found by Match
' instead of Long we'll receive error
position = Application.Match(enteredName, namesRng, False)
Dim dataRow As Long ' row we'll add or update
If IsError(position) Then
dataRow = lastDataRow + 1 ' case: adding new row
Else
dataRow = position + headerRow ' case updating existing row
End If
With sheet1.Range("A" & dataRow)
.Value = enteredName ' not necessary when updating row, but maybe easier to read
.Offset(0, 1).Value = Me.PhoneTextBox.Value
.Offset(0, 2).Value = Me.CityListBox.Value
.Offset(0, 3).Value = Me.DinnerComboBox.Value
End With