I have the following code, which is technically a nested loop
Dim compareRange As Range
Dim toCompare As Range
Dim rFound As Range
Dim cel As Range
Set compareRange = Worksheets("sheet2").Range("A2:A" & Lastrow3)
Set toCompare = Worksheets("sheet3").Range("A2:A" & Lastrow4)
Set rFound = Nothing
For Each cel In toCompare
Set rFound = compareRange.Find(cel)
How do I find which row the value was found in a separate sheet? For instance if AAAA was in row 1 on sheet3 and it was found on row 5 of sheet2 how do I retrieve the value 5 for row 5?
FIND returns a reference to the cell. From that reference you gain access to all the properties of the cell, the same way you would if you manually set a reference to it.
Use FINDNEXT or FINDPREVIOUS to move to the next or previous instance of a found item.
The code below shows how to return various values from each found item:
Sub Test()
Dim compareRange As Range
Dim toCompare As Range
Dim rFound As Range
Dim cel As Range
Dim FirstAddress As String
Dim LastRow3 As Long
Dim LastRow4 As Long
LastRow3 = 189: LastRow4 = 9
Set compareRange = Worksheets("sheet2").Range("A2:A" & LastRow3)
Set toCompare = Worksheets("sheet3").Range("A2:A" & LastRow4)
With compareRange
For Each cel In toCompare
'Find the first instance of cel.
Set rFound = .Find(cel)
'Check that rFound contains a value otherwise an error will occur when
'trying to return values from it.
If Not rFound Is Nothing Then
FirstAddress = rFound.Address
Do
With rFound
Debug.Print "Row: " & .Row & " - Col: " & .Column & _
" - Sheet: " & .Parent.Name & " - Book: " & .Parent.Parent.Name
End With
'Find the next instance of cel.
Set rFound = .FindNext(rFound)
Loop While FirstAddress <> rFound.Address
End If
Next cel
End With
End Sub
https://msdn.microsoft.com/VBA/Excel-VBA/articles/range-find-method-excel
https://msdn.microsoft.com/VBA/Language-Reference-VBA/articles/with-statement
Related
Thank you in advance. New to VBA and trying to teach myself in my spare time. I am hoping someone can provide me some code to build on.
I want to loop through column K and search for each cell in columns A:I. Then I want to select the whole row and cut to another sheet. This is the code I have written, it utilized activecell but as you can imagine I would like to avoid having to click the cell I want to search for every time I execute the Macro. Especially, if I have 150 values in column K.
Sub Lineups()
Dim rng As Range
Set rng = Range("A2:I1501")
Dim ac As Range
Set ac = Application.ActiveCell
rng.Find(what:=ac).Select
ac.Interior.Color = 65535
Range("A" & ActiveCell.Row).Resize(1, 9).Cut
ActiveWindow.ScrollRow = 1
Sheets("Lineups").Select
NextRow = Cells(Rows.Count, 1).End(xlUp).Row + 1
Cells(NextRow, 1).Select
ActiveSheet.Paste
Sheets("Data").Select
End Sub
Picture of the Data Set is below.
Data Set
Please, try the next code. Not tested, but it should work. Selecting, activating is not ta good habit. It only consumes Excel resources without bringing any benefit. Then, coloring, copying each cell/range during iteration, takes time and makes code slower. The best way is to build Union ranges and color/copy at the end of the code, at once:
Sub Lineups()
Dim ws As Worksheet, rng As Range, ac As Range, rngCol As Range
Dim lastRow As Long, rngCopy As Range, arrRng, i As Long
Set ws = ActiveSheet 'use there the sheet you want processing (probably Sheets("Data")
'lastRow = ws.Range("K" & ws.rows.count).End(xlUp).row 'the last row in column K:K
lastRow = 1501 'if you need last cell in K:K, uncomment the line above and comment this one
Set rng = ws.Range("A2:H" & lastRow)
For i = 2 To lastRow
Set ac = rng.Find(what:=ws.Range("K" & i).value, After:=ws.Range("A2"), LookIn:=xlValues, Lookat:=xlWhole)
If Not ac Is Nothing Then 'if a match has been found:
If rngCol Is Nothing Then 'build the range with matching cells, to be colored at the end, at once:
Set rngCol = ws.Range("K" & i)
Else
Set rngCol = Union(rngCol, ws.Range("K" & i))
End If
If rngCopy Is Nothing Then 'build the range with matching cells, to be colored at the end, at once:
Set rngCopy = ws.Range("A" & ac.row, ws.cells(ac.row, "i"))
Else
Set rngCopy = Union(rngCopy, ws.Range("A" & ac.row, ws.cells(ac.row, "i")))
End If
End If
Next i
If Not rngCol Is Nothing Then rngCol.Interior.Color = 65535 ' color the interior of the matching cells in K:K
'Copy the necessary range in sheet "Lineups" and clear the copied range:
Dim wsL As Worksheet, nextRow As Long
Set wsL = Sheets("Lineups")
nextRow = wsL.cells(rows.count, 1).End(xlUp).row + 1
If Not rngCopy Is Nothing Then 'if at least a match has been found:
rngCopy.Copy wsL.cells(nextRow, 1) 'copy the union range at once
rngCopy.ClearContents 'clear contents of the union range at once
End If
End Sub
I am leaving now my office. If something does not work as you need, or you do not understand the code, do not hesitate to ask or specify what is happening against what you need. I will be able to reply after some hours when I will be at home.
Edited:
Please, test the next version and send some feedback:
Sub Lineups_()
Dim ws As Worksheet, rng As Range, rngSearch As Range, ac As Range, rngCol As Range
Dim lastRow As Long, rngCopy As Range, rngExcl As Range, i As Long, k As Long
Set ws = ActiveSheet 'use there the sheet you want processing (probably Sheets("Data")
lastRow = ws.Range("K" & ws.Rows.Count).End(xlUp).Row 'the last row in column K:K
ws.Range("K2:K" & lastRow).Interior.Color = xlNone 'clear interior color to see the changes (you can comment it, if not necessary)
Set rng = ws.Range("A2:H1501")
Set rngSearch = rng 'set a so named search range, adapted by excluding of processed rows
For i = 2 To lastRow
Set ac = rngSearch.Find(what:=ws.Range("K" & i).Value, After:=rngSearch.Cells(1, 1), LookIn:=xlValues, Lookat:=xlWhole)
If Not ac Is Nothing Then 'if a match has been found:
If rngCol Is Nothing Then 'build the range with matching cells, to be colored at the end, at once:
Set rngCol = ws.Range("K" & i)
Else
Set rngCol = Union(rngCol, ws.Range("K" & i))
End If
If rngCopy Is Nothing Then 'build the range with matching cells, to be colored at the end, at once:
Set rngCopy = ws.Range("A" & ac.Row, ws.Cells(ac.Row, "i")):
Set rngExcl = ws.Range("A" & ac.Row) 'set the range to be excluded
Else
Set rngCopy = Union(rngCopy, ws.Range("A" & ac.Row, ws.Cells(ac.Row, "i")))
Set rngExcl = Union(rngExcl, ws.Range("A" & ac.Row)) 'build the range to be excluded
End If
End If
'build the string where to search for:
Set rngSearch = InverseIntersect(rngSearch, rngExcl.EntireRow)
Next i
If Not rngCol Is Nothing Then rngCol.Interior.Color = 65535 ' color the interior of the matching cells in K:K
'Copy the necessary range in sheet "Lineups" and clear the copied range:
Dim wsL As Worksheet, nextRow As Long
Set wsL = ws.Next ' Sheets("Lineups")
nextRow = wsL.Cells(Rows.Count, 1).End(xlUp).Row + 1
If Not rngCopy Is Nothing Then 'if at least a match has been found:
rngCopy.Copy wsL.Cells(nextRow, 1) 'copy the union range at once
rngCopy.ClearContents 'clear contents of the union range at once
End If
MsgBox "Ready..."
End Sub
Function InverseIntersect(bigRng As Range, rngExtract As Range) As Range
Dim rng As Range, rngRow As Range
For Each rngRow In bigRng.rows 'iterate between the range to be processed rows:
If Intersect(rngRow, rngExtract) Is Nothing Then 'if iterated row intersects with range to be extracted:
'creates a range only from rows which do not intersect
If rng Is Nothing Then 'Set the range as the current row
Set rng = rngRow
Else
Set rng = Union(rng, rngRow) 'creates a Union between the previous existing range and the current row
End If
End If
Next
Set InverseIntersect = rng 'set the function as the newly created range
End Function
Instead of hard coding the value to be looked up ("1234"), I would like to use a range of values, on a separate worksheet("Items") to use as the search criteria.
I would also like to substitute that same value for the destination sheet.
For example, the first value in the range could be "8754", I would like the code to look for this value then paste the columns, A,B,C,F and the cell containing the value onto the worksheet "8754". (I have all of the worksheets created already)
TIA
Sub Test()
Dim Cell As Range
With Sheets("Sheet1") 'Sheet with data to check for value
For Each Cell In .Range("H1:H" & .Cells(.Rows.Count, "H").End(xlUp).Row)
pos = InStr(Cell.Value, "1234")
If pos > 0 Then
NextFreeRow = Sheets("Sheet2").Cells(Sheets("Sheet2").Rows.Count,
"A").End(xlUp).Row + 1
'get the next empty row to paste data to
.Range("A" & Cell.Row & ",B" & Cell.Row & ",C" & Cell.Row & ",F" &
Cell.Row & "," & Cell.Address).Copy Destination:=Sheets("Sheet2").Range("A" & NextFreeRow)
End If
Next Cell
End With
End Sub
This uses FIND rather than FILTER to copy the correct rows.
The Main procedure defines the range you're searching and which values will be searched for. The FindValues procedure finds the value and copies it to the correct sheet.
This assumes that Sheet3!A1:A3 contains a unique list of values to be searched for and the these values can be found in Sheet1!H:H.
It also assumes that all sheets already exist.
Public Sub Main()
Dim rToFind As Range
Dim rValue As Range
Dim rSearchRange As Range
With ThisWorkbook
'Update to the range being searched.
With .Worksheets("Sheet1")
Set rSearchRange = .Range("H1", .Cells(.Rows.Count, 8).End(xlUp))
End With
'Update to the range containing the values to be searched for.
Set rToFind = .Worksheets("Sheet3").Range("A1:A3")
End With
'Passe each of the values to be searched to the FindValues procedure.
For Each rValue In rToFind
FindValues rValue, rSearchRange
Next rValue
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Alternative method to look for hard-coded values.
' `ValuesToFind` in FindValues procedure will needed changing to a Variant.
'
' Dim vAlternativeSearch As Variant
' Dim vAlternativeValue As Variant
' vAlternativeSearch = Array(1475, 1683, 219)
'
' For Each vAlternativeValue In vAlternativeSearch
' FindValues vAlternativeValue, rSearchRange
' Next vAlternativeValue
End Sub
Public Sub FindValues(ValueToFind As Range, RangeToSearch As Range)
Dim rFound As Range
Dim sFirstAddress
Dim rLastUsedCell As Range
'Find the next available row on the referenced sheet.
With ThisWorkbook.Worksheets(CStr(ValueToFind))
Set rLastUsedCell = .Range("A1", .Cells(.Rows.Count, 1).End(xlUp)).Offset(1)
End With
With RangeToSearch
'Find the first value.
Set rFound = .Find(What:=ValueToFind, _
After:=RangeToSearch.Cells(RangeToSearch.Cells.Count), _
LookAt:=xlPart, _
SearchDirection:=xlNext)
'If the first value exists then remember the address, copy the cells to the
'correct sheet and look for the next row with the same value. Stop when
'it reaches the first address again.
If Not rFound Is Nothing Then
sFirstAddress = rFound.Address
Do
'You may have to muck around with this to get the correct range to copy.
'If rFound is in column H this will copy columns B:D and F.
Union(rFound.Offset(, -6).Resize(, 3), rFound.Offset(, -2)).Copy Destination:=rLastUsedCell
Set rLastUsedCell = rLastUsedCell.Offset(1)
Set rFound = .FindNext(rFound)
Loop While rFound.Address <> sFirstAddress
End If
End With
End Sub
Edit 1:
You say the worksheets already exists, but in your comment you say put it in a brand new sheet.
To add a new sheet add this function:
Public Function WorkSheetExists(SheetName As String, Optional WrkBk As Workbook) As Boolean
Dim wrkSht As Worksheet
If WrkBk Is Nothing Then
Set WrkBk = ThisWorkbook
End If
On Error Resume Next
Set wrkSht = WrkBk.Worksheets(SheetName)
WorkSheetExists = (Err.Number = 0)
Set wrkSht = Nothing
On Error GoTo 0
End Function
and then add this code directly after the variable declaration in the FindValues procedure:
Dim wrkSht As Worksheet
If Not WorkSheetExists(CStr(ValueToFind)) Then
Set wrkSht = ThisWorkbook.Worksheets.Add
wrkSht.Name = CStr(ValueToFind)
End If
Edit 2:
This updated code searches columns Q:Z, returns the values from A:L as well as the found cell.
To update from the original code I had to change rSearchRange to look from Q1 to column 26, and update the Copy/Paste line to return the correct range.
Public Sub Main()
Dim rToFind As Range
Dim rValue As Range
Dim rSearchRange As Range
With ThisWorkbook
'Update to the range being searched.
With .Worksheets("Data")
Set rSearchRange = .Range("Q1", .Cells(.Rows.Count, 26).End(xlUp))
End With
'Update to the range containing the values to be searched for.
Set rToFind = .Worksheets("Items").Range("A1:A2")
End With
'Passe each of the values to be searched to the FindValues procedure.
For Each rValue In rToFind
FindValues rValue, rSearchRange
Next rValue
End Sub
Public Sub FindValues(ValueToFind As Range, RangeToSearch As Range)
Dim rFound As Range
Dim sFirstAddress
Dim rLastUsedCell As Range
'Find the next available row on the referenced sheet.
With ThisWorkbook.Worksheets(CStr(ValueToFind))
Set rLastUsedCell = .Range("A1", .Cells(.Rows.Count, 1).End(xlUp)).Offset(1)
End With
With RangeToSearch
'Find the first value.
Set rFound = .Find(What:=ValueToFind, _
After:=RangeToSearch.Cells(RangeToSearch.Cells.Count), _
LookAt:=xlPart, _
SearchDirection:=xlNext)
'If the first value exists then remember the address, copy the cells to the
'correct sheet and look for the next row with the same value. Stop when
'it reaches the first address again.
If Not rFound Is Nothing Then
sFirstAddress = rFound.Address
Do
'Parent of RangeToSeach range which will be the Data worksheet.
With .Parent
'Copy columns A:L (columns 1 to 12) and the found cell.
Union(.Range(.Cells(rFound.Row, 1), .Cells(rFound.Row, 12)), rFound).Copy Destination:=rLastUsedCell
End With
Set rLastUsedCell = rLastUsedCell.Offset(1)
Set rFound = .FindNext(rFound)
Loop While rFound.Address <> sFirstAddress
End If
End With
End Sub
Option Explicit
Public Sub Test()
Dim ws1 As Worksheet, ws2 As Worksheet, ws3 As Worksheet, lr1 As Long, lr2 As Long
Dim luArr As Variant, luVal As Variant, r As String, itm As Variant, itmRow As Long
Set ws1 = ThisWorkbook.Worksheets("Data") 'Sheet with data to check for value
Set ws3 = ThisWorkbook.Worksheets("Items") 'LookUp values
luArr = ws3.UsedRange.Columns("A") 'LookUp column
lr1 = ws1.Cells(ws1.Rows.Count, "H").End(xlUp).Row
Dim findRng As Range, copyRng As Range, toRng As Range, fr As Long
Set findRng = ws1.Range("H1:H" & lr1)
On Error Resume Next 'Expected error: sheet not found
Application.ScreenUpdating = False
For Each luVal In luArr
Set ws2 = Nothing
Set ws2 = ThisWorkbook.Worksheets(luVal) 'Copy to
If ws2 Is Nothing Then
Err.Clear
Else
itm = Application.Match(luVal, findRng, 0)
If Not IsError(itm) Then
findRng.AutoFilter Field:=1, Criteria1:="*" & luVal & "*"
fr = IIf(findRng.SpecialCells(xlCellTypeVisible).Cells.Count = 1, 1, 2)
With ws1.UsedRange
Set copyRng = .Range("A" & fr & ":C" & lr1)
Set copyRng = Union(copyRng, .Range("F" & fr & ":F" & lr1))
Set copyRng = Union(copyRng, .Range("H" & fr & ":H" & lr1))
End With
lr2 = ws2.Cells(ws2.Rows.Count, "A").End(xlUp).Row + 1
copyRng.Copy
ws2.Cells(lr2, 1).PasteSpecial
findRng.AutoFilter
End If
End If
Next
Application.ScreenUpdating = True
End Sub
Sheet1
Items
Before (Sheet A1, A2, and A3)
After
I have an excel workbook where I want to find the cell that contains "A0_" & A where A is the value from another worksheet. The end goal is to copy the column with "A0_" & A to another sheet titled. Here is my code so far.
Sub Copy_A()
Dim A As String
Dim iRng As Range
Dim cel As Range
Dim dataws As Worksheet
Dim Rng1, Rng2, Rng3, NewRng As Range
Set dataws = Worksheets("Data Importation Sheet")
Set iRng = dataws.Range(dataws.Cells(1, 1), dataws.Cells(1, dataws.Cells(1, Columns.Count).End(xlToLeft).Column))
A = Worksheets("Information Sheet").Range("E12").Value
For Each cel In iRng
If cel.Value = "A0_" & A Then
Set Rng1 = cel.EntireColumn.Find(What:="", LookIn:=xlValues, lookat:=xlPart)
Debug.Print Rng1.FormulaR1C1
Set Rng2 = dataws.Cells(Rng1.Row - 1, Rng1.Column + 1)
Debug.Print Rng2.FormulaR1C1
Set Rng3 = Cells(cel.Row + 1, cel.Column)
Debug.Print Rng3.FormulaR1C1
End If
Next cel
With dataws
Set NewRng = .Range(Rng3.Address & ":" & Rng1.Address)
Debug.Print NewRng.Address
NewRng.Select
End With
End Sub
For some reason the code does not recognize "A0_" & A when it reaches that cell. The code goes through each column but does not execute setting the ranges. Any tips/help would be greatly appreciated! Here is a picture of my workbook to give you a better idea of what is happening
I have used a variable named rng as Range.
I have found the last row by using:
lastrow = tmpSheet.Cells(tmpSheet.Rows.Count, "A").End(xlUp).Row
& after finding a word in a Foundcell(Range format) using:
Set Foundcell = tmpSheet.Range("A2:A" & lastrow).Find(What:="ABC")
Do Until Foundcell Is Nothing
Set rng = tmpSheet.Range(Cells(1, 1), Cells(lastrow, 1))
.
.
(Copy the row from a aheet to another)
.
.
errHandler:
End Sub
After getting the value in Foundcell the control goes to End Sub directly from the line "Set rng" . I am not getting Why it's happening ?
If you are getting the range Cells(1,1) to Cells(lastrow,1) on tmpsheet, you should change the Set Rng line to:
Set rng = Range(tmpSheet.Cells(1,1), tmpSheet.Cells(lastrow,1))
instead.
You did not supply the entire code, but this is probably what you are looking for.
Sub Button1_Click()
Dim tmpSheet As Worksheet
Dim PasteSH As Worksheet
Dim lastrow As Long
Dim rng As Range
Dim c As Range
Set tmpSheet = Sheets("Sheet1")
Set PasteSH = Sheets("Sheet2")
With tmpSheet
lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
Set rng = .Range("A2:A" & lastrow)
End With
For Each c In rng.Cells
If c = "ABC" Then
c.EntireRow.Copy PasteSH.Cells(PasteSH.Rows.Count, "A").End(xlUp).Offset(1)
End If
Next c
End Sub
I have compiled a code that searches for a value in a excel file say for example that value is 'D0'. When i tested the Search code separately it worked. But, when i combine my search code with a code that loops through files it does not work . The problem found is that the search does not returns the value.I have pointed out in the code, the Part thats not working. All, I am trying to do is to combine a search code with a code which will pick up file names written in the column of an excel sheet and then open those files and execute the search code.
Sub MyMacro()
Dim MyCell, Rng As Range
Dim Fname As String
Dim FirstAddress As String
Set Rng = Sheets("Sheet1").Range("A1:A6") 'sets the range to Read from
For Each MyCell In Rng 'checks each cell in range
If MyCell <> "" Then 'Picks up the file name present in the cell
MyCell.Activate 'Activates the cell
Fname = ActiveCell.Value 'Assigns the value of the cell to fname
Application.ScreenUpdating = False
Set wb = Workbooks.Open("C:\Users\" & Fname, True, True)
'opens the file
wb.Worksheets("Sheet1").Activate 'activates the opened workbook
Call Find_String 'calls the search code
wb.Close SaveChanges:=False
End If
Next
End Sub
Sub Find_String()
Dim FirstAddress As String
Dim MySearch As Variant
Dim Rng As Range
Dim I As Long
Dim strMyValu
Dim Axis
Dim wb As Workbook
MySearch = Array("D0") 'value that needs to be searched
Set wb = ActiveWorkbook 'trying to bring the opened workbook as active sheet
With Sheets("Sheet1").Range("B1:H100")
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 'this is the part not working
'It should return the search value instead it returns nothing
'so as the value returned by the code is nothing and hence the code goes to endif
FirstAddress = Rng.Address
Do
Sheets("Sheet1").Select 'Selecting sheet1 on opened file
Rng.Activate
strMyValue = ActiveCell.Offset(0, 6).Value 'Copying the offset value of the located cell
Axis = ActiveCell.Offset(0, 3).Value
Workbooks("book22.xlsx").Worksheets("Sheet2").Activate
'Activating the workbook where i want to paste the result
Range("B" & Rows.Count).End(xlUp).Offset(1, 0).Value = strMyValue
Range("A" & Rows.Count).End(xlUp).Offset(1, 0).Value = Axis
wb.Activate
'Activating the opened file again for loop to search for more values
Set Rng = .FindNext(Rng)
Loop While Not Rng Is Nothing And Rng.Address <> FirstAddress
End If
Next I
End With
End Sub
Kindly help.
I am struck. I am new to VBA. So, unable to figure out what went wrong as when i tested the search code seperately it worked. Is it something related to the activation of file opened?
When i open a file it is not activated and hence search runs on the workbook that contains the macro instead of the opened file and so its unable to return search value???
Thank you
Part of your problem is the naming of your variables and the changing workbook and worksheet contexts. Be specific in you naming of variables so that you know what it should be and it will help you debug.
Also you don't need to activate workbooks and worksheets to get values from the ranges and cells. just getting a reference to the sheet,range cell will allow you to get what you need.
See it this does the trick for you.
Option Explicit
Sub MyMacro()
Dim MyCell, Rng As Range
Dim Fname As String
Dim FirstAddress As String
Dim searchSheet As Worksheet
Dim copyToSheet As Worksheet
Dim copyToWorkbook As Workbook
Dim searchWorkbook As Workbook
Set copyToWorkbook = Workbooks.Open("C:\Temp\workbook22.xlsx")
Set copyToSheet = copyToWorkbook.Worksheets("Sheet2")
Set Rng = Sheets("Sheet1").Range("A1:A6") 'sets the range to Read from
For Each MyCell In Rng 'checks each cell in range
If MyCell <> "" Then 'Picks up the file name present in the cell
Fname = MyCell.Value 'Assigns the value of the cell to fname
Set searchWorkbook = Workbooks.Open("C:\Temp\" & Fname, True, True)
Set searchSheet = searchWorkbook.Worksheets("Sheet1") 'get a reference to the sheet to be searched
Find_String searchSheet, copyToSheet 'calls the search code with the referenece sheet
searchWorkbook.Close SaveChanges:=False
End If
Next
copyToWorkbook.Close True
End Sub
Sub Find_String(searchSheet As Worksheet, copyToSheet As Worksheet)
Dim FirstAddress As String
Dim MySearch As Variant
Dim Rng As Range
Dim I As Long
Dim strMyValue As String
Dim Axis
Dim foundCell As Range
MySearch = Array("D0") 'value that needs to be searched
With searchSheet.Range("B1:H100")
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 'this is the part not working
'It should return the search value instead it returns nothing
'so as the value returned by the code is nothing and hence the code goes to endif
FirstAddress = Rng.Address
Do
strMyValue = Rng.Offset(0, 6).Value 'Copying the offset value of the located cell
Axis = Rng.Offset(0, 3).Value
copyToSheet.Range("B" & Rows.Count).End(xlUp).Offset(1, 0).Value = strMyValue
copyToSheet.Range("A" & Rows.Count).End(xlUp).Offset(1, 0).Value = Axis
Set Rng = .FindNext(Rng)
Loop While Not Rng Is Nothing And Rng.Address <> FirstAddress
End If
Next I
End With
End Sub
Agreed with Nathan.
Also, always avoid Application.ScreenUpdating = False with mix of ActiveWorkbook, ActiveSheet, ActiveCell.
Your Find_String should reference the object instead of just range of the activeworkbook
Range("B" & Rows.Count).End(xlUp).Offset(1, 0).Value
Set oWSResult = Workbooks("book22.xlsx").Worksheets("Sheet2")
oWSResult.Range("B" & ...
It is hard to debug if you presume the active objects are always the one you are after.
Here's a revamped version of the code. This should run more quickly, and the FindAll function is a bit more versatile.
Sub MyMacro()
Dim wbDest As Workbook
Dim wsDest As Worksheet
Dim wsFileNames As Worksheet
Dim DataBookCell As Range
Dim rngCopy As Range
Dim CopyCell As Range
Dim arrData(1 To 65000, 1 To 2) As Variant
Dim MySearch As Variant
Dim varFind As Variant
Dim BookIndex As Long
Dim DataIndex As Long
Set wbDest = ActiveWorkbook
Set wsFileNames = wbDest.Sheets("Sheet1")
Set wsDest = wbDest.Sheets("Sheet2")
MySearch = Array("D0")
For Each DataBookCell In wsFileNames.Range("A1", wsFileNames.Cells(Rows.Count, "A").End(xlUp)).Cells
If Len(Dir("C:\Users\" & DataBookCell.Text)) > 0 And Len(DataBookCell.Text) > 0 Then
With Workbooks.Open("C:\Users\" & DataBookCell.Text)
For Each varFind In MySearch
Set rngCopy = FindAll(varFind, .Sheets(1).Range("B1:H100"))
If Not rngCopy Is Nothing Then
For Each CopyCell In rngCopy.Cells
DataIndex = DataIndex + 1
arrData(DataIndex, 1) = CopyCell.Offset(, 3).Value
arrData(DataIndex, 2) = CopyCell.Offset(, 6).Value
Next CopyCell
End If
Next varFind
.Close False
End With
End If
Next DataBookCell
If DataIndex > 0 Then wsDest.Cells(Rows.Count, "A").End(xlUp).Offset(1).Resize(DataIndex, UBound(arrData, 2)).Value = arrData
Set wbDest = Nothing
Set wsFileNames = Nothing
Set wsDest = Nothing
Set DataBookCell = Nothing
Set rngCopy = Nothing
Set CopyCell = Nothing
Erase arrData
If IsArray(MySearch) Then Erase MySearch
End Sub
Public Function FindAll(ByVal varFind As Variant, ByVal rngSearch As Range, _
Optional ByVal LookIn As XlFindLookIn = xlValues, _
Optional ByVal LookAt As XlLookAt = xlWhole, _
Optional ByVal MatchCase As Boolean = False) As Range
Dim rngAll As Range
Dim rngFound As Range
Dim strFirst As String
Set rngFound = rngSearch.Find(varFind, rngSearch.Cells(rngSearch.Cells.Count), LookIn, LookAt, MatchCase:=MatchCase)
If Not rngFound Is Nothing Then
strFirst = rngFound.Address
Set rngAll = rngFound
Do
Set rngAll = Union(rngAll, rngFound)
Set rngFound = rngSearch.Find(varFind, rngFound, LookIn, LookAt, MatchCase:=MatchCase)
Loop While rngFound.Address <> strFirst
Set FindAll = rngAll
Else
Set FindAll = Nothing
End If
Set rngAll = Nothing
Set rngFound = Nothing
End Function