I want to use a loop in my SearchFunction in a way it will search for a customer till the right customer is found. I'm using a custom msgbox to define if the found customer is the customer i was looking for.
So basicly i want this:
MsgBox "Is this the customer you were looking for?"
Yes: it will copy cells(sheet2) and paste them into the invoice (sheet1)
No: it will find next customer (and ask same question)**
** And keep doing/asking this till last found customer is shown.
This is how the msgbox looks like when a customer has been found:
Custom msgbox
At the moment it searches for a customer and shows it in a custom msgbox. When i say 'Yes this is the customer', it will copie the values like it should and paste them in the invoice. But when i say 'no this not my customer' it won't go to the next found customer but it will exit the SearchFunction.
I have tried using a Loop but i couldn't get it to work. Also i tried .findnext but i couldn't embed it to the code i'm using..
This is the code that i am using:
Sub SearchCustomer()
'
' Search for customer
'
'*****************************************************************************************************
Dim Finalrow As Integer
Dim I As Integer
Dim cC As Object
Dim iR As Integer
Dim foundrange As Range
'*****************************************************************************************************
' This Searches for the customer
'*****************************************************************************************************
' Set up searchrange
Set foundrange = Sheets("sheet2").Cells.Find(What:=Sheets("sheet1").Range("B12").Value, LookIn:=xlFormulas, LookAt:=xlPart)
' Checks if fields are filled
If Sheets("sheet1").Range("B12").Value = "" Then
MsgBox "Please fill in a search key", vbOKOnly, "Search customer"
Else
'When nothing is found
If foundrange Is Nothing Then
MsgBox "Customer not found," & vbNewLine & vbNewLine & "Refine your search key", vbOKOnly, "Search customer"
Else
Finalrow = Sheets("sheet1").Range("A1000").End(xlUp).Row
For I = 2 To Finalrow
'When range is found
If Worksheets("sheet2").Cells(I, 1) = foundrange Then
Set cC = New clsMsgbox
cC.Title = "Search contact"
cC.Prompt = "Is this the customer you searched for?" & vbNewLine & "" & vbNewLine & Worksheets("sheet2").Cells(I, 1) & vbNewLine & Worksheets("sheet2").Cells(I, 2) _
& vbNewLine & Worksheets("sheet2").Cells(I, 3) & vbNewLine & Worksheets("sheet2").Cells(I, 4) & vbNewLine & Worksheets("sheet2").Cells(I, 5)
cC.Icon = Question + DefaultButton2
cC.ButtonText1 = "Yes"
cC.ButtonText2 = "No"
iR = cC.MessageBox()
If iR = Button1 Then
'Name
Worksheets("sheet2").Cells(I, 1).Copy
Worksheets("sheet1").Range("B12").PasteSpecial xlPasteFormulasAndNumberFormats
'Adress
Worksheets("sheet2").Cells(I, 2).Copy
Worksheets("sheet1").Range("B13").PasteSpecial xlPasteFormulasAndNumberFormats
'Zipcode & City
Worksheets("sheet2").Cells(I, 3).Copy
Worksheets("sheet1").Range("B14").PasteSpecial xlPasteFormulasAndNumberFormats
'Phonenumber
Worksheets("sheet2").Cells(I, 4).Copy
Worksheets("sheet1").Range("B15").PasteSpecial xlPasteFormulasAndNumberFormats
'E-mail
Worksheets("sheet2").Cells(I, 5).Copy
Worksheets("sheet1").Range("B16").PasteSpecial xlPasteFormulasAndNumberFormats
ElseIf iR = Button2 Then
MsgBox "Customer not found", vbOKOnly, "Contact zoeken"
End If
Range("B12").Select
End If 'gevonden item
Next I
Application.CutCopyMode = False
End If
End If
End Sub
Some help would be great! Been searching for a long time now.
Thanks in advanced!
Greets Mikos
You need to restructure your code, the For loop doesn't make sense for looping over search results. You need a Do While Loop, see examples in Range.FindNext Method
Pseudo code:
Set foundrange = Sheets("sheet2").Cells.Find(What:=...)
Do While Not foundrange Is Nothing
If Msgbox(<Customer data from foundrange.Row>) = vbYes Then
' copy stuff
Exit Do ' we're done
Else
Set foundrange = Sheets("sheet2").Cells.FindNext(After:=foundrange)
End If
Loop
P.S. These are not the droids you're looking for!
Many thanks to Andre451 because he solved my problem!
Final code:
Sub SearchCustomer()
'
' Search customer
'
'*****************************************************************************************************
Dim Finalrow As Integer
Dim foundrange As Range
Dim answer As Integer
'*****************************************************************************************************
' Search for customername
'*****************************************************************************************************
' Search Range
Set foundrange = Sheets("sheet2").Cells.Find(What:=Sheets("sheet1").Range("B12").Value, LookIn:=xlFormulas, LookAt:=xlPart)
Finalrow = Sheets("sheet1").Range("A:A").End(xlDown).Row
' Checks if search range is filled
If Sheets("sheet1").Range("B12").Value = "" Then
MsgBox "Please fill in a searchkey", vbOKOnly, "Search customer"
Else
Do While Not foundrange Is Nothing
If MsgBox("Is this the customer you were looking for? " & foundrange, vbYesNo + vbQuestion, "Zoek klant") = vbYes Then
'Name
foundrange.Copy
Worksheets("sheet1").Range("B12").PasteSpecial xlPasteFormulasAndNumberFormats
'Address
foundrange.Offset(0, 1).Copy
Worksheets("sheet1").Range("B13").PasteSpecial xlPasteFormulasAndNumberFormats
'Zipcode and City
foundrange.Offset(0, 2).Copy
Worksheets("sheet1").Range("B14").PasteSpecial xlPasteFormulasAndNumberFormats
'Phonenumber
foundrange.Offset(0, 3).Copy
Worksheets("sheet1").Range("B15").PasteSpecial xlPasteFormulasAndNumberFormats
'Email
foundrange.Offset(0, 4).Copy
Worksheets("sheet1").Range("B16").PasteSpecial xlPasteFormulasAndNumberFormats
Exit Do
Else
Set foundrange = Sheets("sheet2").Cells.FindNext(After:=foundrange)
End If
Loop
Range("B12").Select
Application.CutCopyMode = False
End If
End Sub
Thanks again!
Related
I have the following code to find the phrase "Please Review" in Column "I" and if not found show message, if found it must run the rest of my code but its not liking my IF code:
Sub OUTPUT()
Sheets("OUTPUT").Select
If Range("a2").Value < 1 Then
Else
Range("A2:I" & Range("A1").End(xlDown).Row + 1).ClearContents
End If
Sheets("SF Data").Select
If Range("I2:I192754").Value <> "Please Review" Then
MsgBox "Nudda"
Else
Columns("A:I").Select
Selection.AutoFilter
Range("I2").Select
ActiveSheet.Range("A1:I" & Range("A1").End(xlDown).Row + 1).AutoFilter Field:=9, Criteria1:= _
"Please Review"
Range("A2:I" & Range("A1").End(xlDown).Row + 1).Select
Selection.SpecialCells(xlCellTypeVisible).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("OUTPUT").Select
Range("A2").Select
ActiveSheet.Paste
Sheets("SF Data").Select
ActiveSheet.Range("$A$1:$I$192754").AutoFilter Field:=9
Sheets("OUTPUT").Select
End If
MsgBox "Sanity Check performed. " & Format(Now, "mmmm d, yyyy hh:mm AM/PM")
End Sub
Many thanks guys
I believe the following should help you out, you should try to avoid Select & Activate statements, also by declaring your worksheets your code is more legible, to find the string I used the Find method and allocated the result to a Range variable to see if anything was found:
Sub OUTPUT()
Dim wsOut As Worksheet: Set wsOut = Sheets("OUTPUT")
Dim wsSF As Worksheet: Set wsSF = Sheets("SF Data")
'Declare and set the worksheets you are working with
Dim FoundPlease As Range
Dim LastRow As Long
If wsOut.Range("A2").Value > 1 Then wsOut.Range("A2:I" & wsOut.Range("A1").End(xlDown).Row + 1).ClearContents
'Clear contents if A2 > 1
LastRow = wsSF.Cells(wsSF.Rows.Count, "I").End(xlUp).Row
'find the last row with data on Column I in SF Data
Set FoundPlease = wsSF.Range("I2:I" & LastRow).Find(What:="Please Review", LookAt:=xlWhole)
'Search for "Please Review" on Column I in SF Data
If FoundPlease Is Nothing Then 'if not found
MsgBox "Nudda"
Else 'if found
wsSF.Cells.AutoFilter
wsSF.Range("A1:I" & wsSF.Range("A1").End(xlDown).Row + 1).AutoFilter Field:=9, Criteria1:="Please Review"
wsSF.Range("A2:I" & wsSF.Range("A1").End(xlDown).Row + 1).SpecialCells(xlCellTypeVisible).Copy
wsOut.Range("A2").PasteSpecial xlPasteAll
wsSF.Range("$A$1:$I$" & LastRow).AutoFilter Field:=9
End If
MsgBox "Sanity Check performed. " & Format(Now, "mmmm d, yyyy hh:mm AM/PM")
End Sub
It is giving an error, because Range("I2:I192754").Value <> "Please Review" is a bit illegal. If you want to check whether in one of the cells in the range there is the string "Please Review" present, you may consider using =CountIf() function:
Sub TestMe()
If WorksheetFunction.CountIf(Range("I2:I192754"), "Please Review") > 0 Then
Debug.Print WorksheetFunction.CountIf(Range("I2:I192754"), "Please Review")
End If
End Sub
Later, you may take a look at this topic - How to avoid using Select in Excel VBA.
One way would be to check each cell individually:
Dim TextFound As Boolean
TextFound=False
For Each cell In Range("I2:I192754")
If cell.value="Please Review" Then
TextFound=True
Exit For
End If
Next
If TextFound Then
...
Else
...
End IF
This code searches data on Sheet2 and if it finds it on Sheet2,
it copies full row on Sheet1.
I would like to edit it:
so when I search for example "John%Wayne"
it looks for cells that contain and John and Wayne in its string.
Sub myFind()
'Standard module code, like: Module1.
'Find my data and list found rows in report!
Dim rngData As Object
Dim strDataShtNm$, strReportShtNm$, strMySearch$, strMyCell$
Dim lngLstDatCol&, lngLstDatRow&, lngReportLstRow&, lngMyFoundCnt&
On Error GoTo myEnd
'*******************************************************************************
strDataShtNm = "Sheet2" 'This is the name of the sheet that has the data!
strReportShtNm = "Sheet1" 'This is the name of the report to sheet!
'*******************************************************************************
Sheets(strReportShtNm).Select
Application.ScreenUpdating = False
'Define data sheet's data range!
Sheets(strDataShtNm).Select
With ActiveSheet.UsedRange
lngLstDatRow = .Rows.Count + .Row - 1
lngLstDatCol = .Columns.Count + .Column - 1
End With
Set rngData = ActiveSheet.Range(Cells(1, 1), Cells(lngLstDatRow, lngLstDatCol))
'Get the string to search for!
strMySearch = InputBox("Enter what to search for, below:" & vbLf & vbLf & _
"Note: The search is case sensitive!", _
Space(3) & "Find All", _
"")
'Do the search!
For Each Cell In rngData
strMyCell = Cell.Value
'If found then list entire row!
If strMyCell = strMySearch Then
lngMyFoundCnt = lngMyFoundCnt + 1
ActiveSheet.Rows(Cell.Row & ":" & Cell.Row).Copy
With Sheets(strReportShtNm)
'Paste found data's row!
lngReportLstRow = .UsedRange.Rows.Count + .UsedRange.Row
ActiveSheet.Paste Destination:=.Range("A" & lngReportLstRow).EntireRow
End With
End If
Next Cell
myEnd:
'Do clean-up!
Application.ScreenUpdating = True
Application.CutCopyMode = False
Sheets(strReportShtNm).Select
'If not found then notify!
If lngMyFoundCnt = 0 Then
MsgBox """" & strMySearch & """" & Space(3) & "Was not found!", _
vbCritical + vbOKOnly, _
Space(3) & "Not Found!"
End If
End Sub
You can use Find with the * wildcard (or if you really want to use % then replace % with * in the code):
Sub myFind()
Dim rToSearch As Range
Dim sMySearch As String
Dim rFound As Range
Dim sFirstAddress As String
Dim lLastRow As Long
'Get the string to search for!
sMySearch = InputBox("Enter what to search for, below:" & vbLf & vbLf & _
"Note: The search is case sensitive!", _
Space(3) & "Find All", _
"")
With ThisWorkbook
'Set reference to data in column A.
With .Worksheets("Sheet2")
Set rToSearch = .Range(.Cells(1, 1), .Columns(1).Find("*", , , , xlByColumns, xlPrevious))
End With
'Find the last row containing data in Sheet 1.
With .Worksheets("Sheet1")
On Error Resume Next
lLastRow = .Cells.Find("*", , , , xlByRows, xlPrevious).Row + 1
On Error GoTo 0
If lLastRow = 0 Then lLastRow = 1
End With
End With
'Use find to search your text.
'FindNext will, strangely enough, find the next occurrence and keep looping until it
'reaches the top again - and back to the first found address.
With rToSearch
Set rFound = .Find(What:=sMySearch, LookIn:=xlValues)
If Not rFound Is Nothing Then
sFirstAddress = rFound.Address
Do
rFound.EntireRow.Copy Destination:=ThisWorkbook.Worksheets("Sheet1").Cells(lLastRow, 1)
lLastRow = lLastRow + 1
Set rFound = .FindNext(rFound)
Loop While rFound.Address <> sFirstAddress
End If
End With
End Sub
I have looked up this problem so many times and it still doesnt seem to work for me. I am learning VBA and as a practice project am trying to make a nutritional tracker. I am trying to make a hyperlink that, when clicked, runs a macro to add a new food entry row. Here is my NewFoodEntry():
Sub NewFoodEntry()
'
' NewFoodEntry Macro
' Insert new food entry row.
'
' Keyboard Shortcut: Option+Cmd+Shift+N
'
' Setting selection as input cell'
Dim myRange As Range
Set myRange = Selection
' Select default food entry row'
Range(myRange.Offset(-1, 0), myRange.Offset(-1, 7)).Select
Selection.Copy
'Insert default food entry row below myRange selection'
myRange.Insert Shift:=xlDown
myRange.Select
Application.CutCopyMode = False
'Select correct Totals cell'
Dim totalsRange As Range
Set totalsRange = Sheets("Nutrition").Range("D:D").Find("Totals", After:=myRange.Offset(0, 3), SearchOrder:=xlByRows, SearchDirection:=xlNext)
Debug.Print totalsRange.Address
'Select correct Calories cell'
Dim caloriesRange As Range
Set caloriesRange = Sheets("Nutrition").Range("E:E").Find("Calories", After:=totalsRange.Offset(0, 1), SearchOrder:=xlByRows, SearchDirection:=xlPrevious)
If caloriesRange Is Nothing Then
Debug.Print "Calories still not found."
Else
Debug.Print caloriesRange.Address
End If
'Select correct Protein cell'
Dim proteinRange As Range
Set proteinRange = Sheets("Nutrition").Range("F:F").Find("Protein", After:=totalsRange.Offset(0, 2), SearchOrder:=xlByRows, SearchDirection:=xlPrevious)
If proteinRange Is Nothing Then
Debug.Print "Protein still not found."
Else
Debug.Print proteinRange.Address
End If
'Select correct Carbs cell'
Dim carbsRange As Range
Set carbsRange = Sheets("Nutrition").Range("G:G").Find("Carbs", After:=totalsRange.Offset(0, 3), SearchOrder:=xlByRows, SearchDirection:=xlPrevious)
If carbsRange Is Nothing Then
Debug.Print "Carbs still not found."
Else
Debug.Print carbsRange.Address
End If
'Select correct Fat cell'
Dim fatRange As Range
Set fatRange = Sheets("Nutrition").Range("H:H").Find("Fat", After:=totalsRange.Offset(0, 4), SearchOrder:=xlByRows, SearchDirection:=xlPrevious)
If fatRange Is Nothing Then
Debug.Print "Fat still not found."
Else
Debug.Print fatRange.Address
End If
'Calculate Calories Total
totalsRange.Offset(0, 1).Formula = "=SUM(" & caloriesRange.Offset(1, 0).Address & ":" & totalsRange.Offset(-1, 1).Address & ")"
'Calculate Protein Total
totalsRange.Offset(0, 2).Formula = "=SUM(" & proteinRange.Offset(1, 0).Address & ":" & totalsRange.Offset(-1, 2).Address & ")"
'Calculate Carbs Total
totalsRange.Offset(0, 3).Formula = "=SUM(" & carbsRange.Offset(1, 0).Address & ":" & totalsRange.Offset(-1, 3).Address & ")"
'Calculate Fat Total
totalsRange.Offset(0, 4).Formula = "=SUM(" & fatRange.Offset(1, 0).Address & ":" & totalsRange.Offset(-1, 4).Address & ")"
End Sub
That is under the "module 1" of my VBA editor.
Now I also went to the proper sheet object ("nutrition") in my VBA editor and entered the code.
Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink)
If Target.Range.Address = "$A$37" Then
Debug.Print "It worked"
Exit Sub
End If
End Sub
I can't seem to get this code to work. Clicking the hyperlink doesn't print to the immediate window. Obviously, running the macro via the hyperlink doesnt work either. Here is a screenshot of my excel so you get an idea of what im trying to do.
Excel Screenshot
I should also add that this is the code I used to convert a cell text to a hyperlink:
Sub HyperActive()
'Make a hyperlink
Dim nm As String
nm = ActiveSheet.Name & "!"
For Each r In Selection
t = r.Text
addy = nm & r.Address(0, 0)
ActiveSheet.Hyperlinks.Add Anchor:=r, Address:="", SubAddress:= _
addy, TextToDisplay:=r.Text
Next r
End Sub
EDIT:
After much frustration, I have found that the Worksheet_FollowHyperlink does not work on Macs after Excel 2010. I do not know why or if this is actually true, so if anyone has anymore insight into this, let me know.
https://answers.microsoft.com/en-us/msoffice/forum/msoffice_excel-mso_mac/mac-excel-2011-hyperlinks-dont-work-as-buttons/41192768-45fd-47db-ad8c-f614fc83be5a
I am trying to copy excel row in different worksheet sheet 2 when cell dropdown "Yes" of Column F and when "No" removes the row if "Yes" was selected previously. I also wanted to check if duplicate exists in worksheet 2, then prompt user with "Yes", "No" button. If "Yes" then duplicate if "No" do nothing.
ColA:Customer Name ColB:Customer Address ColC:Customer City ColD:Cust zip ColE:Tel ColF:Yes/No
I have tried this.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim lastrow As Long
If UCase(Range("F" & ActiveCell.Row).Value) <> "YES" Then Exit Sub
With ThisWorkbook.Worksheets("Sheet2")
lastrow = Application.Max(4, .Cells(.Rows.Count, "A").End(xlUp).Row + 1)
If WorksheetFunction.CountIf(.Range("A1:A" & lastrow), _
Range("A" & ActiveCell.Row).Value) > 0 Then Exit Sub
Response = MsgBox("Record already exists, add again?", vbQuestion + vbYesNo + 256)
If Response = vbNo Then Exit Sub
.Range("A" & lastrow).Resize(, 5).Value = _
Range("A" & ActiveCell.Row).Resize(, 5).Value
End With
Response = MsgBox("Record added")
End Sub
If I understand you correctly, you need something like this (code runs only if changed value in column F):
Private Sub Worksheet_Change(ByVal Target As Range)
Dim lastrow As Long
Dim Response
Dim rng As Range, rngToDel As Range
Dim fAddr As String
If Intersect(Target, Range("F:F")) Is Nothing Then Exit Sub
Application.EnableEvents = False
On Error GoTo ErrHandler
With ThisWorkbook.Worksheets("Sheet2")
lastrow = Application.Max(4, .Cells(.Rows.Count, "A").End(xlUp).Row + 1)
If UCase(Target.Value) = "YES" Then
Response = vbYes
If WorksheetFunction.CountIf(.Range("A1:A" & lastrow), _
Range("A" & Target.Row).Value) > 0 Then
Response = MsgBox("Record already exists, add again?", vbQuestion + vbYesNo + 256)
End If
If Response = vbYes Then
.Range("A" & lastrow).Resize(, 5).Value = _
Range("A" & Target.Row).Resize(, 5).Value
MsgBox "Record added"
End If
ElseIf UCase(Target.Value) = "NO" Then
With .Range("A4:A" & lastrow)
Set rng = .Find(What:=Range("A" & Target.Row), _
LookIn:=xlValues, _
lookAt:=xlWhole, _
MatchCase:=False)
If Not rng Is Nothing Then
fAddr = rng.Address
Do
If rngToDel Is Nothing Then
Set rngToDel = rng.Resize(, 5)
Else
Set rngToDel = Union(rngToDel, rng.Resize(, 5))
End If
Set rng = .FindNext(rng)
If rng Is Nothing Then Exit Do
Loop While fAddr <> rng.Address
End If
If Not rngToDel Is Nothing Then
rngToDel.Delete Shift:=xlUp
MsgBox "Records from sheet2 removed"
End If
End With
End If
End With
ExitHere:
Application.EnableEvents = True
Exit Sub
ErrHandler:
Resume ExitHere
End Sub
I have this code, but i want to add the Name etc, directly under the "name" in excel, but this far its only adding it in row 1. Can someone help me?
Example, when i type into the name-box, i want the value to be directly under "Name" in Excel, no matter where the "Name" stands in my Excal sheet.
I'm new here and this is my first question :)
'find first empty row in database
iRow = ws.Cells.Find(What:="Name", SearchOrder:=xlRows, _
SearchDirection:=xlPrevious, LookIn:=xlValues).Row + 1
'check for a part number
If Trim(Me.TxtName.Value) = "" Then
Me.TxtName.SetFocus
MsgBox "Please enter a part number"
Exit Sub
End If
'copy the data to the database
'use protect and unprotect lines,
' with your password
' if worksheet is protected
With ws
' .Unprotect Password:="password"
.Cells(iRow, 1).Value = Me.TxtName.Value
.Cells(iRow, 2).Value = Me.TxtLocation.Value
.Cells(iRow, 3).Value = Me.TxtDate.Value
.Cells(iRow, 4).Value = Me.TxtQuantity.Value
' .Protect Password:="password"
End With
Thanks.
Assuming the OP really wants to populate the first empty row:
Dim pNum, rngName As Range
pNum = Trim(Me.TxtName.Value) 'check for a part number
If Len(pNum) = 0 Then
Me.TxtName.SetFocus
MsgBox "Please enter a part number"
Exit Sub
End If
'find first empty row in database
Set rngName = ws.Cells.Find(What:="Name", SearchOrder:=xlRows, _
SearchDirection:=xlPrevious, LookIn:=xlValues, LookAt:=xlWhole)
If Not rngName is Nothing then
With ws.cells(rows.count, rngName.Column).End(xlUp).offset(1,0).entirerow
.Cells(1).Value = pNum
.Cells(2).Value = Me.TxtLocation.Value
.Cells(3).Value = Me.TxtDate.Value
.Cells(4).Value = Me.TxtQuantity.Value
End With
Else
msgbox "'Name' header not found!"
End if
Try the below as a substitute for that section of code you posted.
Dim anchorCell As Range
'find first empty row in database
If ws.Cells(1,1).Value = "Name" Then
Set anchorCell = ws.Cells(1,1)
Else
Set anchorCell = ws.Cells.Find(What:="Name", SearchOrder:=xlRows, _
SearchDirection:=xlNext, LookIn:=xlValues)
End If
If Not anchorCell Is Nothing Then
'check for a part number
If Trim(Me.TxtName.Value) = "" Then
Me.TxtName.SetFocus
MsgBox "Please enter a part number"
Exit Sub
End If
'copy the data to the database
'use protect and unprotect lines,
' with your password
' if worksheet is protected
With anchorCell
' .Unprotect Password:="password"
.Offset(1, 0).Value = Me.TxtName.Value
.Offset(1, 1).Value = Me.TxtLocation.Value
.Offset(1, 2).Value = Me.TxtDate.Value
.Offset(1, 3).Value = Me.TxtQuantity.Value
' .Protect Password:="password"
End With
End If