Finding the cell reference of a "Cells.Find" function - vba

I am using the code below to find a value the user has searched for ("strFindWhat") which is entered into a cell and a button is then pressed to trigger this sub. The system conatains a long list of data and the user will be searching for say a product number so that they can quickly see the corresponding batch no.
Cells.Find(What:=strFindWhat, After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False).Select
What I want to do is find the refrence to the cell that is found by this code. So that I can change the colour or maybe row of the found cell in order to highlight the data they need so they can see it clearer.
I have tried the obvious by making the whole function equal a variable:
foundCell = Cells.Find(What:=strFindWhat, After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False).Select
The value of "foundCell" always comes out as blank and I was hoping someone knows of a way to find the reference to the found cell?

In order to find the address you could do sth like that
Dim foundCell As Range
Set foundCell = Cells.Find(What:=strFindWhat, After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False)
If Not (foundCell Is Nothing) Then
Debug.Print foundCell.Address
End If

Related

Searching for the column that contains a given text, and then searching for the row that contains the last non-blank cell in the worksheet

I am trying to create a code that does two things:
First, the code will search for a column that contains a given text within the worksheet.
Afterwards, the code will search for the row with the last non-blank cell in the worksheet, while remaining on the same column as 1.
picture example
As shown in the example above, the code would first search for the text "FIRST" in A1. Afterwards, it will search for the last non-blank cell in the worksheet, which is C11. However, it should remain in the column that contains "FIRST", so that only the row changes. The final result would be A11.
So far, I found the code that lets me do 1.
Cells.Find(what:="FIRST",
after:=ActiveCell,
LookIn:=xlFormulas,
LookAt:=xlPart,
SearchOrder:=xlByRows,
SearchDirection:=xlNext,
MatchCase:=False,
SearchFormat:=False).Activate
and another code that lets me do 2.,
Cells.Find(what:="*",
after:=Range("A1"),
LookAt:=xlPart,
LookIn:=xlFormulas,
SearchOrder:=xlByRows,
SearchDirection:=xlPrevious,
MatchCase:=False).Activate
However, I am unable to use them together to achieve my intended goal.
Any suggestions to answer this would be appreciated. Thank you!
I was wondering about your starting point of ActiveCell, so I reversed the methods and used the last row as the starting point to search for FIRST.
Dim r As Long, c As Long
With Worksheets("sheet1")
r = .Cells.Find(what:="*", after:=.Cells(1, "A"), _
LookAt:=xlPart, LookIn:=xlFormulas, _
SearchOrder:=xlByRows, SearchDirection:=xlPrevious, _
MatchCase:=False).Row
c = .Cells.Find(what:="FIRST", after:=.Cells(r + 1, "A"), _
LookIn:=xlFormulas, LookAt:=xlPart, _
SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Column
.Cells(r, c).Activate
End With

How to use the find funtion to search for the Value of a text box?

I am trying to make a userform that can bring up data using an ID number.
I am trying to reference a text box and select it, and then using it as a reference to fill out the Time and comments in the sheet. I think the is I cant put "txtID.Value" into the Find function.
Here is an example of my code:
Sheet1.Select
Columns("A:A").Select
Selection.Find(What:="txtID.Value", After:=ActiveCell, LookIn:= _
xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False).Activate
ActiveCell.Select
ActiveCell.Offset(0, 8).Value = txtTime2
ActiveCell.Offset(0, 9).Value = txtComment2
When using the Find function, it's recommended to use a Range object, and set it to the result. This method allows you to trap a possible scenario where Find failed to find a match in the searched range Sheet1.Columns("A:A").
Also, try to avoid using Select, Selection and ActiveCell, and use fully qualified Range objects (like in the code below).
Code
Dim FndRng As Range
Set FndRng = Sheet1.Columns("A:A").Find(What:=txtID.Value, LookIn:=xlFormulas, LookAt:=xlPart, _
SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
If Not FndRng Is Nothing Then ' successful find
FndRng.Offset(, 8).Value = txtTime2
FndRng.Offset(, 9).Value = txtComment2
Else ' unable to fins the value in txtID
MsgBox "Unable to find " & txtID.Value & " in Sheet1"
End If
Note: if you have this code outisde the User_Form module, then you need to add the User_Form reference when trying to get the txtID.Value.
For eaxmple, let's say the name of your form is UserForm1, then change this line to:
Set FndRng = Sheet1.Columns("A:A").Find(What:=UserForm1.txtID.Value, LookIn:=xlFormulas, LookAt:=xlPart, _
SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
To Make it work, you will have to put the code as below, which is quite self explainatory.
Selection.Find(What:=Userform1.textbox1.value, After:=ActiveCell, LookIn:= _
xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False).Activate
ActiveCell.Select
hope this helps

If (search term) found, do (action). If not, end if

If you guys could help me out, that would be great because it would really help me.
Here's what I'm trying to do:
Search for a cell with a specific term
If found, copy the entire row that the cell is in and paste it into a row above it.
If not found, do nothing and continue with the code
Here's my code:
Sub Test()
'
' Test Macro
'
' Keyboard Shortcut: Ctrl+b
'
Range("A5").Select
Cells.Find(What:="PL 1", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
If Not IsEmpty(ActiveCell.Value) Then
ActiveCell.Rows("1:1").EntireRow.Select
Selection.Copy
Range("A5").Select
ActiveSheet.Paste
End If
Range("A5").Select
Cells.Find(What:="PL 2", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
If Not IsEmpty(ActiveCell.Value) Then
ActiveCell.Rows("1:1").EntireRow.Select
Selection.Copy
Range("A6").Select
ActiveSheet.Paste
End If
Range("A5").Select
Cells.Find(What:="PL 3", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
If Not IsEmpty(ActiveCell.Value) Then
ActiveCell.Rows("1:1").EntireRow.Select
Selection.Copy
Range("A7").Select
ActiveSheet.Paste
End If
End Sub
My code only works if the value is found. If it's not found it runs into the error below:
Cells.Find is a function that returns a Range object reference; when it doesn't find anything, the reference will be Nothing. And you can't call .Activate on Nothing:
This method returns Nothing if no match is found. The Find method does not affect the selection or the active cell. (MSDN)
Cells.Find(What:="PL 2", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
You need to rewrite your code and avoid .Select and .Activate, and avoid working with ActiveCell and implicitly with ActiveSheet (which you are doing by not qualifying the Cells call with a proper worksheet reference).
Your formatting makes it hard to read the code, for several reasons:
Arguments are being specified on different lines
Line continuations are being palced at arbitrary locations
Nested member calls aren't lined up
Compare to:
Cells.Find(What:="PL 2", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False) _
.Activate
That's just readability. The problem is that you basically assume that .Find returns a valid object reference. Don't assume, explicitly check:
Set result = Cells.Find(...)
If Not result Is Nothing Then result.Activate
But really, you need to figure out a way to avoid .Select and .Activate.
You can try something like this instead (untested):
Sub HideAndSeek()
Dim foundCell As Range
For i = 1 To 3
Set foundCell = Cells.Find(What:="PL " & i, LookIn:=xlFormulas, LookAt:=xlPart)
If Not foundCell Is Nothing Then
Intersect(foundCell.EntireRow, ActiveSheet.UsedRange).Offset(-1, 0).Value = _
Intersect(foundCell.EntireRow, ActiveSheet.UsedRange).Value
End If
Set foundCell = Nothing
Next
End Sub
The principle being that you write the code you need once and then create a loop to repeat the code for you.
The other part of this answer is checking that the cell was found - to do this we check that the range was actually set (which means it isn't Nothing) using
If Not foundRange Is Nothing

VBA find is looking at hidden rows

I have the code below (loop) to search for 0's in my spreadsheet (Column D) when it finds one if performs a copy/paste and then deletes the row. After all the filtered 0's (the column is filtered by column A - duplicates) I tell it to end sub. But I found the find is finding the 0's in the filtered hidden rows so the loop keeps going.
How can make the find only work on the visible rows and then end when all the 0's have been dealt with.
Set RangeObj = Cells.Find(What:="0", After:=ActiveCell, _
LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False)
If RangeObj Is Nothing Then RangeObj.Activate
Cells.Find(What:="0", After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False).Activate
What you need is the SpecialCells(xlCellTypeVisible) method and the .FindNext method.
See the below code:
Set RangeObj = Cells.SpecialCells(xlCellTypeVisible).Find(What:="0", After:=Range("A1"), _
LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False)
If Not RangeObj Is Nothing Then
Dim sFirstAdd As String, sAdd As String
sFirstAdd = RangeObj.Address
Do
sAdd = RangeObj.Address
With RangeObj.EntireRow 'or limit to just the necessary columns
.Copy 'choose your desired destination
.Delete
End With
Set RangeObj = Cells.SpecialCells(xlCellTypeVisible).FindNext(After:=Range(sAdd))
Loop Until RangeObj Is Nothing Or sAdd = sFirstAdd
End If

VBA: How do I search for a formula driven value?

I am trying to search for the date, which I have in cell K1 as =today()....
Whenever I am recording the macro, however, it will continue to use the date which the macro was written. What I am curious about is a methodology of pasting what is on the clipboard into the VBA search function.
So I want to search column A for what is in cell K1. This is what code I have now (the find what is what I just typed to help you all have an idea of what I'm looking for)
Range("K1").Select
Selection.Copy
Columns("A:A").Select
Selection.Find(What:="COPY CONTENTS OF CELL K1", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
This should do it. Note that your original code will throw an error if today's date isn't found. Typically when working with Find() it's safer to test the returned value before trying to do something with it.
Dim f As Range
Set f = Columns("A:A").Find(What:=Date(), After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not f Is Nothing then
'do something with f
Else
'???? do what
End If
You could replace your entire code with this:
Activesheet.Columns("A:A").Find(What:=ActiveSheet.Range("K1"), After:=ActiveCell, _
LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
What was happening is that there's no way to paste a cell's contents via .Copy directly into a VBA function. So I placed what you wanted to paste into it into the function directly.
I think you will also find this helpful:
How to avoid using Select in Excel VBA macros