I am getting this error message when I run the macro:
Run-time error '6': Overflow
I have two worksheets; Search and Data. The 'Data' worksheet contains two columns, column A with numbers I want to search through and column B with an alphanumeric value I want to copy and paste into the 'Search' worksheet when a number match is found. Because a number I am searching for can be listed an unknown number of times I want a macro to loop through to find all of the instances, copy the value to its immediate right and paste it into the 'Search' worksheet in cell D3 and going down a row for multiple instances of the number being found.
The number I am searching for is found in cell B3 on the 'Search' worksheet.
This is a sample of what the 'Data' worksheet looks like:
ID ISS_ID
108143 136KQV4
108143 173HBK3
108143 136KQX0
109728 7805JM1
109706 7805JM1
102791 23252T4
105312 6477LZ6
Here is the code that I have now:
Sub Acct_Search()
Dim searchResult As Range
Dim x As Integer
x = 3
' Search for "Activity" and store in Range
Set searchResult = Worksheets("Data").Range("A1:A3500").Find(What:=Worksheets("Search").Range("B3"), _
LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, _
SearchFormat:=False)
' Store the address of the first occurrence of this word
firstAddress = searchResult.Address
Do
' Set the value in the O column, using the row number and column number
Worksheets("Search").Cells(x, 4) = searchResult.Offset(0, 1).Value
' Increase the counter to go to the next row
x = x + 1
' Find the next occurrence of "Activity"
Set searchResult = Cells.FindNext(searchResult)
' Check if a value was found and that it is not the first value found
Loop While Not searchResult Is Nothing And firstAddress <> searchResult.Address
End Sub
When I Debug it points to the x = x + 1 line. Right now it is able to copy and paste the first value without issue but it is after that point that the error comes into play.
Your problem changed because you are not resetting the origin point of the search with the After:=... parameter of the Range.FindNext Method. Yes, you are passing in searchResult but it was not accepting it as the After:= parameter.
When I ran your code, I was thrown into an infinite loop due to the FindNext always finding the same second instance. This explains the integer coughing at being incremented above 2¹⁵. When it was changed to a long, that gave something else time to choke.
After I changed one line to definitively include the named parameter, everything cleared up.
Set searchResult = Cells.FindNext(After:=searchResult)
This was reproducible simply by adding/removing the parameter designation. It seems that the Cells.FindNext(searchResult) was finding Search!B3 and since that wasn't the firstAddress, it just kept looping on the same Search!B3. It wasn't until I forced after:=searchResult that the .FindNext adjusted itself. It's times like these I think fondly of my C/C++ days without this wallowing overhead.
I've gone through your code and added a With ... End With block that should discourage any questionable parentage.
Sub Acct_Search()
Dim searchResult As Range, firstAddress As String
Dim x As Long, ws As Worksheet
x = 3
Set ws = Worksheets("Search")
' Search for "Activity" and store in Range
With Worksheets("Data").Range("A1:A3500")
Set searchResult = .Find(What:=ws.Range("B3"), LookIn:=xlFormulas, After:=.Cells(.Rows.Count, .Columns.Count), _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
' Store the address of the first occurrence of this word
firstAddress = searchResult.Address
Do
' Set the value in the O column, using the row number and column number
ws.Cells(x, 4) = searchResult.Offset(0, 1).Value
' Increase the counter to go to the next row
x = x + 1
' Find the next occurrence of "Activity"
Set searchResult = .FindNext(After:=searchResult)
'Debug.Print searchResult.Address(0, 0, external:=True)
' Check if a value was found and that it is not the first value found
Loop While Not searchResult Is Nothing And firstAddress <> searchResult.Address
End With
Set ws = Nothing
End Sub
I've left the After:= parameter designation in although it is no longer needed.
Change
Dim x As Integer
to
Dim x As Long
Related
I am trying to write a macro that searches a whole sheet for a value and then stores the values and locations of ALL hits for that value throughout the sheet. I will do something with the locations and values later, but I need to get this bit working first.
Originally, I used the Range.Find function with iteration and noticed that I was returning the same value. I then tried to have the range being searched change each time a value was found. I would take the address of the previously found value and make it the lower bound of the range.
This worked, to a point, but I ended up getting an infinite loop at the end. The end condition for my loop was when the Range.Find found nothing (since the size of the sheet is always changing and I don't know what the real upper limits will be). What happened was the Range.Find would get stuck on the last value and refuse to move from that spot, regardless of the change I made in the range.
My most recent attempt to deal with this was to also change the After:= input to see if that would force the program to move on. It ended up wrecking the process I already had and now I get stuck in an infinite loop with the first value. So, naturally, I just took that part out hoping to make it work again. No luck.
Here's the code:
[code]
Sub SearchLibrary()
'
' SearchLibrary Macro
' Searches MC library for inputed value and returns all related inforamtion
in Search sheet
'
' Keyboard Shortcut: Ctrl+s
'
'Search code to find all matching values and corresponding headers
' Define variables
Dim searchn As Integer ' The value input for the search
If IsNumeric(Sheets("Search").Range("C2")) Then
searchn = Sheets("Search").Range("C2").Value
End If
Dim i As Integer ' Simple counter for loops (column number)
i = 0
Dim j As Integer 'Simple counter for loops (row number)
Dim Data As Worksheet ' Define the search area as all of the sheet MC Library
Worksheets("MC library").Activate
Set Data = Sheets("MC library")
Dim loc As Range
Dim rang As Range
Dim spce As Range
Dim mass() As Single
Dim Found As Variant
Set rang = Sheets("MC library").Range("C3:Z500")
Set loc = Sheets("MC library").Range("C3")
On Error Resume Next
Do
Set Found = rang.Find(What:=searchn, LookIn:=xlValues, LookAt:= _
xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False)
MsgBox (Found)
Set loc = Sheets("MC library").Range(Found.Address)
If Found > 0 Then
ReDim Preserve mass(i)
mass(i) = Found
i = i + 1
Set rang = Sheets("MC library").Range(loc, "Z500")
End If
Loop Until Found Is Nothing
End Sub
[/code]
This is all a work in progress so there's a few things in there that aren't relevant yet. The Do loop is where the real problems kick in.
searchn calls in a value from a cell that is an input for the search from the user and is typically a four-digit number. The MsgBox line is simply used for debugging and won't be in the final version.
Any suggestions and help would be greatly appreciated. The biggest issue (I think), is finding a way to store the location of a cell in a variable and then using that to change the range as I go.
Sub SearchLibrary()
Dim searchn
Dim shtData As Worksheet
Dim hits As Collection, hit
searchn = Sheets("Search").Range("C2").Value
If Len(searchn) = 0 Or Not IsNumeric(searchn) Then
MsgBox "Search term should be numeric!", vbExclamation
Exit Sub
End If
Set shtData = Worksheets("MC library")
Set hits = FindAll(shtData.Range("C3:Z500"), searchn)
For Each hit In hits
Debug.Print hit.Address, hit.Value
Next hit
End Sub
Public Function FindAll(rng As Range, v) As Collection
Dim rv As New Collection, f As Range
Dim addr As String
Set f = rng.Find(what:=v, after:=rng.Cells(1), _
LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False)
If Not f Is Nothing Then addr = f.Address()
Do Until f Is Nothing
rv.Add f
Set f = rng.FindNext(after:=f)
If f.Address() = addr Then Exit Do
Loop
Set FindAll = rv
End Function
here is a find routine that works
Sub findAll()
Dim aaa As Range
With ActiveSheet.Cells
Set aaa = .Find(3, LookIn:=xlValues) ' find number 3
If Not aaa Is Nothing Then
firstFind = aaa.Address
Do
Debug.Print aaa.Address, aaa.Value
Set aaa = .FindNext(aaa)
Loop While aaa.Address <> firstFind
End If
End With
End Sub
This question already has answers here:
Matching similar but not exact text strings in Excel VBA projects
(5 answers)
Closed 5 years ago.
In the above pic i have to search the sap code from sheet 2 to the respective..
By Taking some words like Master/13 or visa/chennai we have match the sapcode from sheet 2..
srchString = "visa/20160927/Chennai/FT"
Set rng = Worksheets("Rulebook_Temp").Cells.find(what:=srchString, After:=ActiveCell, LookIn:=xlFormulas, lookat:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False)
Its returning empty for me...
All you really need is to remove the date part of the card type in your source and destination and then you could do a simple lookup. If you have a string like a/b/c/d in cell A1, this will return a/c/d
=IF(LEN(A1)-LEN(SUBSTITUTE(A1,"/",""))>2,REPLACE(A1,FIND("/",A1),FIND("/",A1,FIND("/",A1)+1)-FIND("/",A1),""),A1)
It also checks to make sure that there are more than 2 /, so in the case of a/b the value will be left unchanged. This therefore also works with your premium/007 value
you can try this too
use excel arrays
use this to return the rows that contain the code
IF(ISNUMBER(FIND("Master/13",Sheet2!$A$2:$A$50,1)),ROW(Sheet2!$B$2:$B$50))
then use SMALL to return the first row on the sheet 2 where the match was found
SMALL(IF(ISNUMBER(FIND("Master/13",Sheet2!$A$2:$A$50,1)),ROW(Sheet2!$B$2:$B$50)),1)
Then use index to return the value
INDEX(Sheet2!$B$2:$B$50,SMALL(IF(ISNUMBER(FIND("Master/13",Sheet2!$A$2:$A$50,1)),ROW(Sheet2!$B$2:$B$50)),1))
Enter as an array Control + Shift + Enter
This should work I have tested
You can do that by iterating through the cells as follows
Private Sub CommandButton1_Click()
Dim rng As Range
Set rng = ThisWorkbook.Sheets(1).Range("A1:A60")
Dim foundString, delimiterStr As String
Dim object() As String
delimiterStr = "||"
Dim n As Integer
For n = 1 To rng.Rows.Count
If CStr(rng.Cells(n, 1).Text) Like "*visa/20160927/Chennai/FT*" Then
foundString = foundString & CStr(rng.Cells(n, 1).Text) & delimiterStr
End If
Next n
object = Split(foundString, delimiterStr)
Dim rng_1 As Range
Set rng_1 = ThisWorkbook.Sheets(1).Range("B1")
Dim i As Integer
For i = LBound(object) To UBound(object)
rng_1.Offset(i + 1, 0).Value = object(i)
Next
End Sub
I've got a list in Excel which shows the titles in column A and values in column B, like this:
ARTICLE_POSNO 1
ARTICLE_ARTNO 111123
ARTICLE_DESCRIPTION black pens
ARTICLE_POSNO 2
ARTICLE_ARTNO 280708
ARTICLE_DESCRIPTION yellow paper
ARTICLE_POSNO 3
ARTICLE_ARTNO 999912
ARTICLE_DESCRIPTION blue scissors
What I'm trying to do is to build a VB function that creates an array that holds the values, so I can then print it something like this:
POS ART NO DESCRIPTION
1 111123 black pens
2 280708 yellow paper
3 999912 blue scissors
Below is my current script which searches for the titles -> gets the values next to them and finally send a Msgbox of the value. For this list, that would mean 9 Msgboxes.
Ideally, it would show just one messagebox with all article information on it.
Any ideas?
Many thanks in advance!
Sub FindArticles()
Dim FirstAddress As String
Dim MySearch As Variant
Dim Rng As Range
Dim I As Long
MySearch = Array("ARTICLE_POSNO", "ARTICLE_ARTNO", "ARTICLE_DESCRIPTION")
With Sheets("Sheet1").Range("A1:A1000")
For I = LBound(MySearch) To UBound(MySearch)
Set Rng = .Find(What:=MySearch(I), _
After:=.Cells(.Cells.Count), _
LookIn:=xlFormulas, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
FirstAddress = Rng.Address
Do
ArtValue = Rng.Offset(0, 1) 'Gather the value to the right
MsgBox ArtValue
Set Rng = .FindNext(Rng)
Loop While Not Rng Is Nothing And Rng.Address <> FirstAddress
End If
Next I
End With
End Sub
I assume your input worksheet is named Input and it has the attributes in sequence as in your example, being first column the names and second the values.
1. Create a new worksheet in your workbook and fill the first row with the names (POS, ART NO...).
2. Put this formula in A2.
=INDEX(Input!$B$1:$B$9,(ROW()-1)*3-3+COLUMN(),1)
Copy this cell and paste in the final array.
Not much to explain: it takes 1st, 2nd and 3rd of every 3 values in the values column using row position. Modify the length of input array from 9 to your needs. If your the sequence of the input is not constant it can also be accomplished but it's a little longer.
I've been stuck trying to figure out what to do with this, but basically I want a way to print out the value in column B given a specific value that matches column A. So for example:
Column A Column B
1 ABC
2 DEF
3 GHI
1 JKL
I want to, after using find/findnext or whatever it is, to print out this string:
ABC JKL
I tried using
Set cellFound = ActiveWorkbook.Worksheets("sheet1").Range("F1:F1000000").Find("1")
string = cellFound.Offset(0, 1).value
And I have a loop to loop through as many time as it needs to get all the rows taken care of. But with find it keeps returning me the same first string ("ABC") and the string ends up being ABC ABC instead of ABC JKL
I tried using FindNext instead of find, but what I got is a 1004 Error. So I'm not really sure where I'm doing this wrong. Anyone has any idea?
You don't need FindNext if you start each Find after the previous one:
Sub qwerty()
Dim rFirst As Range, r As Range
Dim A As Range
Set A = Range("A:A")
Do
If rFirst Is Nothing Then
Set rFirst = A.Find(What:=1, After:=A(1))
Set r = rFirst
Else
Set r = A.Find(What:=1, After:=r)
If r.Address = rFirst.Address Then Exit Do
End If
MyString = MyString & " " & r.Offset(0, 1)
Loop
MsgBox MyString
End Sub
You need to call Find once, and then successively FindNext. But there are a couple of non-obvious things:
Each time you call FindNext, the search will start again from the upper-left corner of the range; unless you pass in the current found cell.
The search will wrap around (up or down, depending on your search direction. You need to write code that handles this possibility.
The minimal working code would look something like this:
Dim rng As Excel.Range
Set rng = ActiveWorkbook.Worksheets("sheet1").Range("F1:F1000000")
Dim lastRow as Integer
Set cellFound = rng.Find("1")
Do While Not cellFound Is Nothing
' handles wraparound
If cellFound.Row < lastRow Then Exit Do
string = cellFound.Offset(0, 1).Value
' do something here with string
Set cellFound = rng.FindNext(cellFound)
Loop
Reference:
Find method
FindNext method
When using the Range.FindNext method, one need just include some reference to the initial find position. For example, I recorded this macro using excel; while I'm not a fan of using selection and activate, I think it helps to understand how the method functions:
Sub Using_Find()
Selection.Find(What:="my search string here", After:=ActiveCell _
, LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).Activate
Selection.FindNext(After:=ActiveCell).Activate
Selection.FindNext(After:=ActiveCell).Activate
Selection.FindNext(After:=ActiveCell).Activate
Selection.FindNext(After:=ActiveCell).Activate
Selection.FindNext(After:=ActiveCell).Activate
Selection.FindNext(After:=ActiveCell).Activate
End Sub
To generate this subroutine, I used the record > macro in excel, then selected Home > Find & Select > Find.
The way I see this subroutine working is:
Step #1: Find the first location of the string, activate it;
Step #2: FindNext looks after the active cell that we just activated, finds the next location of the string, then activates it;
Etc. etc. So, the observation here is that the .FindNext method needs some reference to the prior find cell (which the first answer accomplishes by manually identifying it as a unique reference). I'm not saying anything to that answer, it works just as well. My goal was to help provide some insight into the Range.FindNext method.
Some other points worth mentioning:
Range.FindNext will return a Range object. (Microsoft)
The After parameter is described as:
"The cell after which you want to search. This corresponds to the position of the active cell when a search is done from the user interface. Be aware that After must be a single cell in the range. Remember that the search begins after this cell; the specified cell is not searched until the method wraps back around to this cell. If this argument is not specified, the search starts after the cell in the upper-left corner of the range." (Microsoft)
...and
Under the Remarks section, Microsoft notes that, "The search will wrap around to the beginning of the range." They suggest to save the first address and do a check against it for each subsequent .FindNext. This way, once the method does wrap around, it will check the address against the first and end the check.
So, modeling the Range.FindNext Method provided by Microsoft, I wrote this introductory subroutine for review:
Sub USING_FIND()
'this line sets the range to our used range on the active sheet
With ActiveSheet.UsedRange
'setting c variable to .Find method, where the first value is what we're looking for,
'i.e. "1"; LookIn:= can be changed to our needs but set currently to xlValues
Set c = .Find(1, LookIn:=xlValues)
'begin first conditional; this conditional checks c (our .Find method) to see if it has
'some reference, then sets the address to a constant 'firstAddress' so we can check it
'against the .FindNext returns later to prevent endless loop
If Not c Is Nothing Then
firstAddress = c.Address
'Do...is where we place our "work"; this can be a redirect to another function/sub, etc
'for now I've just tossed a msgbox as a placeholder that returns the offset 1 column over
Do
MsgBox c.Offset(0, 1)
'Now we set c to the .FindNext method, using the original .Find method as the 'after'
Set c = .FindNext(c)
'Another empty reference check/exit as a conditional
If c Is Nothing Then
GoTo DoneFinding
'ends the empty reference conditional
End If
'using our .FindNext method that we replaced 'c' with earlier, we can now loop through
'the remainder of the value returns. The Loop While 'c.Address <> firstAddress' sentence
'is checking that each subsequent .FindNext address IS NOT the first address;
'-our loop will return to the 'Do' sentence to repeat the loop, starting on the
'MsgBox c.Offset(0,1) sentence with the next string occurence
'-the characters '<>' means 'does not equal'; i.e. the opposite of '='
Loop While c.Address <> firstAddress
'this ends the address check loop
End If
DoneFinding:
End With
End Sub
To adjust this code to your specific needs, we can change the sentence after the Do line: 'MsgBox c.Offset(0,1)' to our specific needs.
Depending on how complex your output needs are, you can add all occurrences to an array, then have the array output the values in order of how you want to see them. This can be done by redim array and preserve each return. Once the .Find loop completes, open a new workbook with the Workbooks.Open method, and run a quick loop that takes each array value and places it in the order that you prefer.
Another option is to 'print' to .txt. Open a new .txt as #1, then 'print' accordingly. This can also be done as a second subroutine via the array option suggested previously.
Hope this helps add some context to your initial question with respect to the .FindNext method, as well as provides some ideas for future direction/implementation. Good luck!
Microsoft page on Range.FindNext Method:
https://msdn.microsoft.com/en-us/VBA/Excel-VBA/articles/range-findnext-method-excel
Function FindMultiResut(ByRef What As String, _
ByRef FindRng As Range, _
ByRef OutputRng As Range, _
ByRef Delimite As String)
Dim fRng As Range
Dim Rng1 As Range
Dim Rng2 As Range
Dim temp As String
Set fRng = FindRng
Do
If Rng1 Is Nothing Then
Set Rng1 = fRng.Find(What:=What, After:=fRng(1))
Set Rng2 = Rng1
Else
Set Rng2 = fRng.Find(What:=What, After:=Rng2)
If Rng2.Address = Rng1.Address Then Exit Do
End If
If OutputRng.Worksheet.Cells(Rng2.Row, OutputRng.Column) <> Empty Then
temp = temp & OutputRng.Worksheet.Cells(Rng2.Row, OutputRng.Column) & Delimite
End If
Loop
FindMultiResut = Left(temp, Len(temp) - 1)
End Function
Here is an implementation of the suggestion I made in my comment under your question.
Function RowBeforeLast(ByVal What As Variant) As Long
Dim Fnd As Range
Set Fnd = Range("E:E").Find(What:=What, After:=Range("E1"), _
LookAt:=xlWhole, _
Searchdirection:=xlPrevious)
If Not Fnd Is Nothing Then
Set Fnd = Range("E:E").Find(What:=What, After:=Fnd, _
LookAt:=xlWhole, _
Searchdirection:=xlPrevious)
If Not Fnd Is Nothing Then RowBeforeLast = Fnd.Row
End If
End Function
It's designed as a UDF so that you can call it from the worksheet with a worksheet function like =RowBeforeLast(E5). You can also call it with code like
Private Sub TestGet()
RowBeforeLast "GR 3"
End Sub
Either way it will return the row number in which the search criterium was found for the second time from the bottom of the column. If there is only one or no occurrance the function will return zero.
I have a spreadsheet with a good amount of data (more than 100,000 rows with columns a-h).
I know twenty or more distinct values in Column F are wrong and I know what they should be. For example, every occurrence of "pif" should be "pig" and "coe" should be "cow", etc.
(Note that there are multiple incorrect values (i.e. multiple "pif"s) for each.)
I'm currently building a macro to go through and fix these individually, and that part works:
Sub FixColumnF()
ActiveSheet.Columns("F").Replace What:= _
"pif", _
Replacement:="pig", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:= _
False, SearchFormat:=False, ReplaceFormat:=False
ActiveSheet.Columns("F").Replace What:= _
"coe", _
Replacement:="cow", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:= _
False, SearchFormat:=False, ReplaceFormat:=False
...
End Sub
My problem is that column A is used to keep track of errors, one of which is an incorrect value in column F. How do I erase the value in column A to indicate there is no longer an error for each row where the value in column F is fixed?
I'm extremely new to vba, so any help would be very much appreciated!
Siddharth posted his suggestions while I was testing/typing mine. My first suggestion is a simple variation of his first suggestion and offers no advantage that I can see. However, my second suggestion is different from either of his suggestions and may be appropriate.
You need to loop for each occurrence of "pif" and "coe" if you want to do something extra with each faulty value found. The code below shows how to replace every occurrence of "pif" by "pig" and then do something with column "A". If you like this technique, you would need to duplicate this code for "coe" and "cow".
Option Explicit
Sub ReplaceFaultyA()
Dim Rng As Range
' It is best to avoid "ActiveSheet" in case the use has called the
' macro with the wrong worksheet active. Probably this is not likely
' in this case but I like to follow good practice even if it not not
' necessary
With Worksheets("Data")
Do While True
' Are you sure all your Find parameters are correct? For example,
' "LookAt:=xlPart" means than "pif" in the middle of a word will
' be replaced by "pig". "LookAt:=xlWhole" may better match your
' requirement. I suggest you look up the specification of Find
' and consider the implications of each parameter.
Set Rng = .Columns("F").Find(What:="pif")
If Rng Is Nothing Then
' No [more] occurrences of "pif" in column F
Exit Do
Else
' Occurrences of "pif" found in column F
.Cells(Rng.Row, "F") = "pig"
' Amend column ""A" of Rng.Row as necessary
End If
Loop
End With
End Sub
Duplication my loop and replacing "pif" and "pig" by "coe" and "cow" in the duplicate is probably the simpliest solution if there are only two replacements. However, if there are many replacements, the technique below may be a better choice.
In this code, I place the faulty values and the matching good values in arrays. With this approach, one block of replacement code can handle an indefinite number of replacements providing the action for column A is the same for each replacement.
Sub ReplaceFaultyB()
Dim InxValue As Long
Dim Rng As Range
Dim ValueFaulty() As Variant
Dim ValueGood() As Variant
' The code below assumes there same number of entries in both arrays.
' You can add extra entries to the two arrays as necessary.
' This assumes the action for column "A" is the same for each faulty value
ValueFaulty = Array("pif", "coe", "appme")
ValueGood = Array("pig", "cow", "apple")
With Worksheets("Data")
For InxValue = LBound(ValueFaulty) To UBound(ValueFaulty)
Do While True
Set Rng = .Columns("F").Find(What:=ValueFaulty(InxValue))
If Rng Is Nothing Then
' No [more] occurrences of this faulty value in column F
Exit Do
Else
' Occurrences of faulty value found in column F
.Cells(Rng.Row, "F") = ValueGood(InxValue)
' Amend column ""A" of Rng.Row as necessary
End If
Loop
Next InxValue
End With
End Sub
There are two ways that I can think of.
Way 1
Use .Find/.FindNext to loop though all the cells which have say the word "pif". In that loop not only replace the word but also edit the value in Col A. For example (Untested)
Sub Sample()
Dim oRange As Range, aCell As Range, bCell As Range
Dim ws As Worksheet
Dim SearchString As String, FoundAt As String
On Error GoTo Whoa
Set ws = Worksheets("Sheet1")
Set oRange = ws.Columns(5) '<~~ Column 5
SearchString = "pif"
NewString = "pig"
Set aCell = oRange.Find(What:=SearchString, LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not aCell Is Nothing Then
Set bCell = aCell
'~~> Change value in Cell F
aCell.Value = Replace(aCell.Value, SearchString, NewString)
'~~> Change value in Cell A
aCell.Offset(, -5).Value = "Rectified"
Do
Set aCell = oRange.FindNext(After:=aCell)
If Not aCell Is Nothing Then
If aCell.Address = bCell.Address Then Exit Do
aCell.Value = Replace(aCell.Value, SearchString, NewString)
aCell.Offset(, -5).Value = "Rectified"
Else
Exit Do
End If
Loop
End If
Exit Sub
Whoa:
MsgBox Err.Description
End Sub
Way 2
Use Autofilter to filter Col F on the word "pif". Loop though all the cells in Col A and add the relevant message. Remove Autofilter and then run your original code (mentioned in your question) to do the replace in Col F. see THIS link on how to use Autofilter.