I have a VBA function that uses the the .find method. In my function I'd like change the LookAt: argument between xlPart or xlWhole. I tried using a parameter variable matchvalue and passing in "xlPart" or "xlWhole". It didn't work.
Is there a way to change the LookAt: argument with a variable I pass into my function?
Public Function getfield(matchvalue as string)
GetRowNumber = Cells.Find(What:="Cat", After:=ActiveCell, LookIn:=xlValues, LookAt:= _
matchvalue, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False).Activate
End Function
Not sure if the way you are splitting the lines makes you can't achieve your goal.
Try with:
Public Function getfield(matchvalue as string)
GetRowNumber = Cells.Find(What:="Cat", After:=ActiveCell, LookIn:=xlValues, _
LookAt:=matchvalue, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False).Activate
End Function
Reading .Find documentation, LookAt value should be Variant Type.
Read the following link.
https://msdn.microsoft.com/en-us/vba/excel-vba/articles/range-find-method-excel
It's not clear what your function is intended to return, but here's how I'd probably handle this:
Public Function getfield(Optional matchWholeValue as Boolean = True)
GetRowNumber = Cells.Find(What:="Cat", After:=ActiveCell, _
LookIn:=xlValues, _
LookAt:= IIf(matchWholeValue, xlWhole, xlPart), _
SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Row
End Function
To match on the whole value use:
getfield()
and to match on part:
getfield(False)
Try:
Public Function GetRowNumber(byval matchvalue as string, optional byval LookAtWhole = True) as long
Dim Result as range
Set Result =
Activesheet.Cells.Find(What:=matchvalue After:=ActiveCell, LookIn:=xlvalues, LookAt:=iif(LookAtWhole,xlwhole,xlpart), SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _ , SearchFormat:=False)
If not (Result is nothing) then
Getrownumber = result.row
Else
Getrownumber = 0
End if
End Function
This function performs FIND method on active sheet's cells. Returns 0, if the criteria returned no results -- else the row number. You could add further parameters.
Hopefully it works and is what you wanted?
Related
When I perform a "Cells.Find" after selecting a column the search unexpectedly leaves the selected column.
I would expect the Find to remain in the column I selected just like when using the 'Find" function in Excel.
'Select first row of data set locations
ActiveWorkbook.Worksheets("Sheet1").Activate
Cells.EntireColumn("C").Select
Set First = Cells.Find(What:=ww_from, After:=ActiveCell, LookIn:= _
xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False).Activate
Thanks in advance for your help.
Scott
Cells.Find( is looking at the whole sheet not just what is selected. If you only want to search in column C then use this in place of all you have given:
With ThisWorkbook.Worksheets("Sheet1")
Set First = .Column("C").Find(What:=ww_from, After:=.Range("C1"), LookIn:= _
xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False)
End With
If you do not want to change Selection, consider:
ActiveWorkbook.Worksheets("Sheet1").Activate
Dim r as Range
Set r = Columns(3).Cells
Set First = r.Find(What:=ww_from, After:=r(1), LookIn:= _
xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False)
My Case 1 excel macro code runs as long as data is being found by the search but bombs with the stated error when there is nothing in the search result. So I tried putting in a "set" see Case 2... but that Case bombs on any search.
CASE 1: Run-time error '91': Object variable or With block variable not set
Cells.Find(What:=sCurrentISOtext & "_", After:=ActiveCell, _
LookIn:=xlFormulas, LookAt :=xlWhole , _
SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:= False, SearchFormat:=False).Activate
CASE 2: Run-time error '424': Object required
Dim c As Range
Set c = Cells.Find(What:=sCurrentISOtext & "_", After:=ActiveCell, _
LookIn:=xlFormulas, LookAt :=xlWhole, _
SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:= False, SearchFormat:=False).Activate
You mean like this?? It still fails.
CASE 3: Run-time error '91': Object variable or With block variable not set
Dim c As Range
c = Cells.Find(What:=sCurrentISOtext & "_", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlWhole = 0, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase _
:=False, SearchFormat:=False)
If Not c Is Nothing Then
c.Activate
' and do something here < >
End If
This would naturally fail, you are calling "activate" on a null (failed) result - so there's nothing to activate at runtime. You have to wrap in an If statement -
Dim c As Range
Set c = Cells.Find(What:=sCurrentISOtext & "_", _
After:=ActiveCell, _
LookIn:=xlFormulas, _
LookAt:=xlWhole = 0, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlNext, _
MatchCase:= False, _
SearchFormat:=False)
If c Is Nothing Then
'do something
Else
c.Activate
End If
Here's an ugly work around that I use when I'm in a hurry -- there are more elegant error traps, but this gets it done.
On Error GoTo notFound
Dim c As Range
Set c = Cells.Find(What:=sCurrentISOtext & "_", _
After:=ActiveCell, _
LookIn:=xlFormulas, _
LookAt:=xlWhole = 0, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlNext, _
MatchCase:=False, _
SearchFormat:=False)
c.Activate
Exit Sub
notFound:
Application.InputBox "Could not find the range you wanted."
' >> You can put in whatever action you want here -- for example, <<
' >> if you're using this as a module, then "Exit Sub" or "Goto nextOne" <<
' >> could be used go to the next step in your process. <<
I am trying to make it so that I can find the second result for "lights", in case of having various occurrences for this term. The code below finds the first occurrence in the range under consideration.
Dim ws As Worksheet
Dim rng1 As Range
Dim y As Range
Columns("B:B").Select
Selection.Find(What:="1", After:=ActiveCell, LookIn:=xlValues, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False).Select
Set x = Range(Selection, Selection.End(xlDown)).Offset(0, 3)
Range(x.Address(0, 0)).Select
Selection.Find(What:="Lights", After:=ActiveCell, LookIn:=xlValues, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False).Activate
Selection.FindNext(After:=ActiveCell).Activate
Selection.FindNext(After:=ActiveCell).Select
FindNext delivers what you want. Using it is easy: perform the first search as you are doing it right now (although by assigning the result to a Range) and take the resulting range as starting point for FindNext. Here you have a sample code adapted to your specific requirements (secondAddress is the Address of the second occurrence of "Light", if any):
Dim foundRange As Range
Dim rangeToSearch As Range
Set rangeToSearch = Selection
Set foundRange = rangeToSearch.Find(What:="Lights", After:=ActiveCell, LookIn:=xlValues, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False) 'First Occurrence
Dim secondAddress As String
If (Not foundRange Is Nothing) Then
foundRange.Activate
Dim count As Integer: count = 0
Dim targetOccurrence As Integer: targetOccurrence = 2
Dim found As Boolean
Do While Not found
Set foundRange = rangeToSearch.FindNext(foundRange)
If Not foundRange Is Nothing Then
count = count + 1
If (count >= targetOccurrence - 1) Then
secondAddress = foundRange.Address
Exit Do
End If
Else
Exit Do
End If
Loop
End If
I found an even easier way as it sounds like I had a similar problem.
If you simplified your search function:
Cells.Find(What:="xxxx", After:=Cells(1, 1), LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Select
Then add another line beneath:
Cells.Find(What:="xxxx", After:=ActiveCell, _
LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByColumns, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).Select
All this does is find the first occurrence of "xxxx", then the second code finds "xxxx", but begins searching from the result of the first find code (which was the ActiveCell).
I have a macro which selects a particular range and then will find the number "0" on it.
I would like to know how many times "0" appears in the range I've selected so that I can create a variable equal to that number. How can I set a variable equal to the number of times find returns a match for the query?
ActiveCell.Select
Selection.Offset(0, 1).Select
item = ActiveCell.Value
Sheets("Lights").Select
Rows(3).Select
Selection.Find(What:=item, After:=ActiveCell, LookIn:=xlValues, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False).Select
q = ActiveCell.row()
z = ActiveCell.Column()
Range(Cells(q, z), Cells(72, z)).Select
Selection.Find(What:="0", After:=ActiveCell, LookIn:=xlValues, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False).Activate
So if there are 7 instance of 0 on the range then I want to set variable m= 7
m = WorksheetFunction.CountIf(Selection, 0)
or for partial matches:
m = WorksheetFunction.CountIf(Selection, "*0*")
I have a first version of the next code in VBA for excel
Function findCell(celda As String, rnc As String) As String
Dim cell As Range
Dim pos As String
Range("A2").Select
Set cell = Cells.Find(What:=celda, After:=ActiveCell, LookIn:= _
xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False)
If cell Is Nothing Then
pos = 0
Else
pos = cell.row
End If
findCell = pos
End Function
The function recive a string and return the position in number of the column, but After I change a parameter because I must be find the full contain of the cell. And I change the value lookAt from x1Part to x1Whole
Set cell = Cells.Find(What:=celda, After:=ActiveCell, LookIn:= _
xlFormulas, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False)
When I try to run the macro doesnt work sometimes and show me that value x1Whole, but when I run from the editor works.
If you seek a string in a formula as xlPart, you always get the string from your function itself (a good idea, btw). There will be a problem with xlWhole: there may be a case (and if the formula is the only thing in the sheet, it is is the case) that there's no match. Find will give an error, if nothing is found, and the formula result will be #N/A.
Below is your code with error handling, resulting in 0 for no match.
Function findCell(celda As String, rnc As String) As String
Dim cell As Range
Dim pos As String
On Error GoTo Nomatch
Set cell = Cells.Find(What:=celda, After:=Range("A2"), LookIn:= _
xlFormulas, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False)
Nomatch:
If cell Is Nothing Then
pos = 0
Else
pos = cell.Row
End If
findCell = pos
End Function
Also, I removed Select("A2"), and moved it to After:=Range("A2").