select multi range with .find, .findnext variable (copies EMPTY cells) - vba

I'm struggling with the following code which you can see below. It is totally a pain in the *** now. I really need some help.
This code is a search tool which looks for criteria from every worksheet except the summary and the list. After the .Find founds the word, then the code selects a 4 wide range around the searched word, then it copies and pastes it on the Summary sheet.
When the first searched word is found, I also would like to copy and paste the actual worksheet (where the word is found) title (on each worksheet "G3:J3") right after the search result on the summary page. This search tool could help me to find quickly which search criteria where can be found, at which sheet and some properties which also inside the title.
The result should look like this: (r1 = the first 4 columns, r2= the rest 4 columns (that is the excel header))
item nr. Item Owner Used Capacity ESD_nr. box Owner Free capacity location
Sorry for the long description.
CODE:
Private Sub searchTool()
Dim ws As Worksheet, OutputWs As Worksheet, wbName As Worksheet
Dim rFound As Range, r1 As Range, r2 As Range, multiRange As Range
Dim strName As String
Dim count As Long, lastRow As Long
Dim IsValueFound As Boolean
IsValueFound = False
Set OutputWs = Worksheets("Summary") '---->change the sheet name as required
lastRow = OutputWs.Cells(Rows.count, "K").End(xlUp).Row
On Error Resume Next
strName = ComboBox1.Value
If strName = "" Then Exit Sub
For Each ws In Worksheets
If ws.Name <> "lists" And ws.Name <> "Summary" Then
With ws.UsedRange
Set rFound = .Find(What:=strName, LookIn:=xlValues, LookAt:=xlWhole)
If Not rFound Is Nothing Then
firstAddress = rFound.Address
Do
IsValueFound = True
Set r1 = Range(rFound.EntireRow.Cells(1, "B"), rFound.EntireRow.Cells(1, "D"))
Set r2 = Range("G3:J3")
Set multiRange = Application.Union(r1, r2)
multiRange.Copy
OutputWs.Cells(lastRow + 1, 11).PasteSpecial xlPasteAll
Application.CutCopyMode = False
lastRow = lastRow + 1
Set rFound = .FindNext(rFound)
Loop While Not rFound Is Nothing And rFound.Address <> firstAddress
End If
End With
End If
Next ws
On Error GoTo 0
If IsValueFound Then
OutputWs.Select
MsgBox "Seach complete!"
Else
MsgBox "Name not found!"
End If
End Sub

I must admit I had trouble following your requirements and there was not a definition of where it wasn't working, to that end I re-wrote it to help me understand.
Private Sub SearchTool_2()
Dim BlnFound As Boolean
Dim LngRow As Long
Dim RngFind As Excel.Range
Dim RngFirstFind As Excel.Range
Dim StrName As String
Dim WkShtOutput As Excel.Worksheet
Dim WkSht As Excel.Worksheet
StrName = "Hello" 'ComboBox1.Value
If StrName = "" Then Exit Sub
Set WkShtOutput = ThisWorkbook.Worksheets("Summary")
LngRow = WkShtOutput.Cells(WkShtOutput.Rows.count, "K").End(xlUp).Row + 1
For Each WkSht In ThisWorkbook.Worksheets
If (WkSht.Name <> "lists") And (WkSht.Name <> "Summary") Then
With WkSht.UsedRange
Set RngFind = .Find(What:=StrName, LookIn:=xlValues, LookAt:=xlWhole)
If Not RngFind Is Nothing Then
Set RngFirstFind = RngFind
BlnFound = True
Do
WkSht.Range(RngFind.Address & ":" & WkSht.Cells(RngFind.Row, RngFind.Column + 2).Address).Copy WkShtOutput.Range(WkShtOutput.Cells(LngRow, 11).Address)
WkSht.Range("G3:J3").Copy WkShtOutput.Range(WkShtOutput.Cells(LngRow + 1, 11).Address)
LngRow = LngRow + 2
Set RngFind = .FindNext(RngFind)
Loop Until RngFind.Address = RngFirstFind.Address
End If
End With
End If
Next
Set WkShtOutput = Nothing
If BlnFound Then
ThisWorkbook.Worksheets("Summary").Select
MsgBox "Seach complete!"
Else
MsgBox "Name not found!"
End If
End Sub
I found the copy statement was the better option rather than using the clipboard, I also found a missing reference of firstAddress.

Related

How can I search for a string in multiple Wksheets simultaneously?

I have around 30 sheets that I want this code to run in at the same time. I want to find "ABC" and delete the value of the cell next to it in all my worksheets.
I get my error from: Set rSearch = .**range**("A1", .range("A" & rows.count).end(x1up))
When I have specified "Sheet1" next to the "With" statement, it works, but I want this code to run on all my sheets.
Sub soek()
Dim rSearch As Range
Dim rFound As Range
Dim sign12 As String
Dim sheetsarray As Sheets
Set sheetsarray = ActiveWorkbook.Sheets(Array("sheet1", "sheet2", "sheet3"))
sign12 = "ABC"
With sheetsarray
Set rSearch = .Range("A1", .Range("A" & Rows.Count).End(xlUp))
Set rFound = rSearch.Find(What:=sign12, LookIn:=xlValues)
If rFound Is Nothing Then
Else
rFound.Offset(0, 1).ClearContents
End If
End With
End Sub
This question is a lot like: How to search for a string in all sheets of an Excel workbook?
But in my opinion, it's a lot easier to understand how to make code run on additional sheets reading my code than the code from the link above.
Try this (compilation of the comments above ;-)
Sub soek()
Dim rSearch As Range
Dim rFound As Range
Dim sign12 As String
Dim oWB As Workbook
Dim oWS As Worksheet
Set oWB = ThisWorkbook
sign12 = "ABC"
For Each oWS In oWB.Sheets
With oWS
Set rSearch = .Range("A1", .Range("A" & Rows.Count).End(xlUp))
Set rFound = rSearch.Find(What:=sign12, LookIn:=xlValues)
If rFound Is Nothing Then
Else
rFound.Offset(0, 1).ClearContents
End If
End With
Next oWS
End Sub

Using Nexted for loop to iterate through all cells in a worksheet and all worksheets in a workbook

I am trying to update record on all worksheets in a workbook.
My search values are in column No 6 and the replace values are in column No 9
The code is only working for a worksheet not the entire worksheet at a time.
I tried this below but it is giving me an error
Sub AllWorksheetsLoop()
Dim WS_Count As Integer
Dim I As Integer
' Set WS_Count equal to the number of worksheets in the active
' workbook.
WS_Count = ActiveWorkbook.Worksheets.count
' Begin the loop.
For I = 1 To WS_Count
Dim N As Long
Dim count As Long
N = Cells(Rows.count, 1).End(xlUp).Row
For count = 1 To N
v1 = Cells(count, 6).Value
If v1 = "Palm Tree (M)" Then Cells(count, 9).Value = "='Project Comp Rate Akwa Ibom'!K7"
Next count
Next I
End Sub
Kindly assists pls
It sounds like you want something like, search column F of each worksheet for "Palm Tree (M)"; if found, enter the stated formula in the cell, on the same row, 3 columns to the right. I assume that you exclude the sheet referenced in the formula from being searched.
Option Explicit
Public Sub FindThatPhrase()
Application.ScreenUpdating = False
Dim ws As Worksheet, found As Range
For Each ws In ThisWorkbook.Worksheets
If ws.Name <> "Project Comp Rate Akwa Ibom" Then
Set found = GetAllMatches("Palm Tree (M)", ws.Columns("F"))
If Not found Is Nothing Then
Debug.Print ws.Name, found.Address
found.Offset(, 3) = "='Project Comp Rate Akwa Ibom'!$K$7"
End If
End If
Next ws
Application.ScreenUpdating = True
End Sub
Public Function GetAllMatches(ByVal findString As String, ByVal searchRng As Range) As Range
Dim foundCell As Range
Dim gatheredRange As Range
With searchRng
Set foundCell = searchRng.Find(findString)
Set gatheredRange = foundCell
Dim currMatch As Long
For currMatch = 1 To WorksheetFunction.CountIf(.Cells, findString)
Set foundCell = .Find(What:=findString, After:=foundCell, _
LookIn:=xlValues, Lookat:=xlWhole, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False)
If Not gatheredRange Is Nothing Then
Set gatheredRange = Union(gatheredRange, foundCell)
Else
Set gatheredRange = foundCell
End If
Next currMatch
End With
Set GetAllMatches = gatheredRange
End Function

Searching across multiple columns for a match

Currently my Excel VBA script searches column J in main.xlsm for a match, and if a match is found against column A of vda.xlsx, it highlights the text in red. How do I get it to search through column J-L in main.xlsm?
Sub VDA_Update()
Dim wshT As Worksheet
Dim wbk As Workbook
Dim wshS As Worksheet
Dim r As Long
Dim m As Long
Dim cel As Range
Application.ScreenUpdating = False
Set wshT = ThisWorkbook.Worksheets("Master")
On Error Resume Next
' Check whether vda.xlsx is already open
Set wbk = Workbooks("vda.xlsx")
On Error GoTo 0
If wbk Is Nothing Then
' If not, open it
Set wbk = Workbooks.Open("C:\Working\vda_test.xlsx")
End If
' Set worksheet on vda.xlsx
Set wshS = wbk.Worksheets("imac01")
m = wshT.Cells(wshT.Rows.Count, 1).End(xlUp).Row
' Loop though cells in column J on main.xlsm
For r = 1 To m
' Can we find the value in column A of vda.xlsx?
Set cel = wshS.Columns(1).Find(What:="TEST\" + wshT.Cells(r, 10).Value, _
LookAt:=xlWhole, MatchCase:=False)
If Not cel Is Nothing Then
MsgBox wshS.Cells(r, 1)
' If we find a match, then change the text to red
wshT.Cells(r, 10).Font.ColorIndex = 3
End If
Next r
Application.ScreenUpdating = True
End Sub
I just added a for loop, to iterate 1 to 2 columns higher, working off your logic.
Sub VDA_Update()
Dim wshT As Worksheet
Dim wbk As Workbook
Dim wshS As Worksheet
Dim r As Long
Dim m As Long
Dim cel As Range
Application.ScreenUpdating = False
Set wshT = ThisWorkbook.Worksheets("Master")
On Error Resume Next
' Check whether vda.xlsx is already open
Set wbk = Workbooks("vda.xlsx")
On Error GoTo 0
If wbk Is Nothing Then
' If not, open it
Set wbk = Workbooks.Open("C:\Working\vda_test.xlsx")
End If
' Set worksheet on vda.xlsx
Set wshS = wbk.Worksheets("imac01")
m = wshT.Cells(wshT.Rows.Count, 1).End(xlUp).Row
' Loop though cells in column J on main.xlsm
For r = 1 To m
' Can we find the value in column A of vda.xlsx?
Set cel = wshS.Columns(1).Find(What:="TEST\" + wshT.Cells(r, 10).Value, _
LookAt:=xlWhole, MatchCase:=False)
for i = 1 to 2 'K and L columns, Column J=10
If Cel is Nothing then
Set cel = wshS.Columns(1).Find(What:="TEST\" + wshT.Cells(r, 10 + i).Value, _
LookAt:=xlWhole, MatchCase:=False)
else
exit for
end if
next i
If Not cel Is Nothing Then
MsgBox wshS.Cells(r, 1)
' If we find a match, then change the text to red
wshT.Cells(r, 10).Font.ColorIndex = 3
End If
Next r
Application.ScreenUpdating = True
End Sub

My search macro is not returning the search value

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

Excel macro to search multiple urls in one column

I have a worksheet (Sheet2) that contains 27 columns, first row is the columns headers which are A-Z and NUM totaling 27 cols. Each column has a very long list of restricted urls sorted to the letter of the column, and the last (27th) column is for urls that start with a number. The columns' length is between 300-600 thousand cells.
What I have been looking for was a macro script that will examine all newly added urls in col A Sheet1, to find out whether they exist in Sheet2, resulting in flagging each url with "already exist" or "to be added", something like:
Sheet1
Col(A) Col(B)
badsite1.com already exist
badsite2.com already exist
badsite3.com to be added
badsite4.con to be added
badsite5.com already exist
Accordingly "to be added" urls will be added to Sheet2 after running another test online for that url.
Amazingly, I found the following script (missed its source) that does exactly what I'm after applying some minor modifications:
Sub x()
Dim rFind As Range, sFind As Range, sAddr As String, ws As Worksheet, rng As Range, ms As Worksheet
Application.ScreenUpdating = 0
Set ws = Sheets("Sheet2")
Set ms = Sheets("Sheet1")
ms.Range("B2:B" & Rows.Count).ClearContents
Set rng = ms.Range("A2:A" & Cells(Rows.Count, 1).End(xlUp).Row)
For Each sFind In rng
With ws.UsedRange
Set rFind = .Find(sFind, .Cells(.Cells.Count), xlValues, xlPart)
If Not rFind Is Nothing Then
sAddr = rFind.Address
Do
sFind.Offset(, 1) = rFind.Address
sFind.Font.Color = -16776961
Set rFind = .FindNext(rFind)
Loop While rFind.Address <> sAddr
sAddr = ""
Else
sFind.Offset(, 1) = "No Found"
sFind.Offset(, 1).Font.Color = -16776961
End If
End With
Next
Set ms = Nothing
Set ws = Nothing
Set rng = Nothing
Set rFind = Nothing
Application.ScreenUpdating = True
End Sub
Running this script is fantastic with a small list of urls (e.g 5-10). With a longer list in Sheet1 col-A and HUGE lists in Sheet2 like mine, this script is a "tortoise", and it took over one hour to examine a list of 167 urls!!
Can this script be modified to be a "rabbit"? :)
Highly appreciating any offered assistance in this regard.
As usual.. thanks in advance.
Try this - Tested in Excel 2010:
Sub x()
Dim rFind As Range, sFind As Range, sAddr As String, ws As Worksheet
Dim rng As Range, ms As Worksheet, s As String
Application.ScreenUpdating = False
'stop calculation
Application.Calculation = xlCalculationManual
Set ws = Sheets("Sheet2")
Set ms = Sheets("Sheet1")
ms.Range("B2:B" & ms.Rows.Count).ClearContents
ms.Range("A2:B" & ms.Rows.Count).Font.Color = 0
Set rng = ms.Range("A2:A" & ms.Cells(ms.Rows.Count, 1).End(xlUp).Row)
For Each sFind In rng
'get first character of url
s = Left(sFind, 1)
'resort to column aa if not a a to z
If Asc(UCase(s)) < 65 Or Asc(UCase(s)) > 90 Then s = "AA"
'only look in appropriate column
Set rFind = ws.Columns(s).Find(sFind, , xlValues, xlPart, xlByRows, xlPrevious)
If Not rFind Is Nothing Then
'only look once and save that cell ref
sFind.Offset(, 1) = rFind.Address
sFind.Font.Color = -16776961
Else
'if not found put default string
sFind.Offset(, 1) = "No Found"
sFind.Offset(, 1).Font.Color = -16776961
End If
Next
Set ms = Nothing
Set ws = Nothing
Set rng = Nothing
Set rFind = Nothing
'enable calculation
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
Non VBA - Tested on Excel 2010:
=IFERROR(VLOOKUP(A2, INDIRECT("Sheet2!" & IF(OR(CODE(UPPER(LEFT(A2, 1)))<65,
CODE(UPPER(LEFT(A2, 1)))>90), "AA:AA", LEFT(A2, 1)&":"& LEFT(A2, 1))), 1, FALSE),
"Not Found")