I've got a Excel VBA function that's been working for quite some time. However I found that when i doesn't exist in this code:
Dim rowNum as Integer
for i = 1 to 20
rowNum = Columns(SiteNumCol).Find(What:=i, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).row
<other stuff>
Next i
An error is returned. I tried refactoring the code to include a check:
rowNum = Columns(SiteNumCol).Find(What:=i, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).row
If Not rowNum = 0 Then
<other stuff>
End If
Next i
However it still errored out at the rownum = line. I thought it might be as I'm calling the row number of nothing, so tried this test:
test = Columns(NumCol).Find(What:=i, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not test Is Nothing Then
rowNum = Columns(NumCol).Find(What:=i, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).row
It now errors out at the If statement with a 424 "Object required" error; I think this is because 'test' is currently a double as it errors out on the first iteration. If I change the test to = "0" it goes through iterations until the one that isn't found and then it fails because at test = because of good ol' 91 "Object Variable not set"
How can I successfully catch .find errors when the What is not found?
Like so. You were pretty close, just missing the Set I think.
Dim r As Range
Dim rowNum As Long
For i = 1 To 20
Set r = Columns(SiteNumCol).Find(What:=i, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not r Is Nothing Then rowNum = r.Row
<other stuff>
Next i
Related
I am trying to write a VBA Script to delete a row which is selected from a dropdown list.
My code is
Sub delete_md_entry()
Dim LR As Long
Dim str As Range, rfnd As Range
'LR = Sheets("MASTER_DATA").Range("C2000").End(xlUp).Row
str = Sheets("MASTER_DATA").Range("I2").Value
If Len(str) <> 0 Then
Set rfnd = Selection.Find(str, After:=Range("C5"), LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not rfnd Is Nothing Then
yes = MsgBox("Do you want to delete" & rfnd.Value & " row?", vbYesNo, "Alert!")
If yes = vbYes Then
rfnd.EntireRow.Delete
Else
Exit Sub
End If
Else
MsgBox "NO ROW FOUND"
End If
Else
MsgBox "Kindly select a name!"
End If
End Sub
Unfortunately it is not working and throw an error Run time error 13: Type mismatch.
However there is not with selection.
Where I made the mistake? Please help me to find out the error!
Find works on a Range and not on a single cell Selection.
You need to change
Set rfnd = Selection.Find(str, After:=Range("C5"), LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
To:
Set rfnd = Range("A2:C10").Find(str, After:=Range("C5"), LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
Of course you need to change Range("A2:C10") above to whatever the range it is you are looking in.
I am writing a code there I need to find out a string "total" OR "totals"
I tried this code
Set lRow = ws.Range(nRow & ":" & aRow).Find(what:="total" OR "totals", LookIn:=xlValues, lookat:=xlWhole, searchorder:=xlByRows, searchdirection:=xlNext, MatchCase:=False, searchformat:=False)
I Also tried this
Set lRow = ws.Range(nRow & ":" & aRow).Find(what:="total" OR what:="totals", LookIn:=xlValues, lookat:=xlWhole, searchorder:=xlByRows, searchdirection:=xlNext, MatchCase:=False, searchformat:=False)
Is it possible to use FIND function like this. If not the pls guide me the way to find out one of these two string.
No, you can't search like that. The workaround, however, is easy
Set lRow = ws.Range(nRow & ":" & aRow).Find(what:="total", LookIn:=xlValues, lookat:=xlWhole, searchorder:=xlByRows, searchdirection:=xlNext, MatchCase:=False, searchformat:=False)
If lRow Is Nothing then
Set lRow = ws.Range(nRow & ":" & aRow).Find(what:="totals", LookIn:=xlValues, lookat:=xlWhole, searchorder:=xlByRows, searchdirection:=xlNext, MatchCase:=False, searchformat:=False)
End If
Note that this process can be extended for as many conditions as you would like to check for, assuming that they are exclusive
Because "total" is a sub-string of "totals", we can search for "total" using xlPart to find either word:
Sub ytrewq()
Dim ws As Worksheet, lRow As Range
Set ws = ActiveSheet
Set lRow = ws.Range("A:A").Find(what:="total", after:=Range("A1"), lookat:=xlPart)
MsgBox lRow.Address(0, 0)
End Sub
I have this find in a loop. It works fine when there is a "0" but when there are no more "0" I get Runtime Error 91. Any thoughts?
Cells.Find(What:="0", After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False).Activate
You could do this:
Dim rngFound As Range
Set rngFound = Sheets("WhateverSheet").Cells.Find(What:="0", After:=ActiveCell, LookIn:=xlFormulas, LookAt:= xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
If Not rngFound Is Nothing Then
'you found the value - do whatever
Else
' you didn't find the value
End if
Ah, or just take out the .Activate at the end. You want the cell range, not activating it.
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).