Getting run-time error running VBA code not my own - vba

I need to reverse engineer someone else's code and make it run. Right now it is throwing an error at me complaining that some variable isn't set.
I'm not sure what it is talking about exactly. Here is the top part of the subroutine with the error.
Sub OBI_Vendor_Detail_Macro()
Cells.Select
With Selection
.WrapText = False
.MergeCells = False
End With
Range("C4").Select
Cells.Find(What:="Grand Total", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
The last line produces this error Run-time error '91': Object variable or With block variable not set
Hope I've provided enough info. If not please let me know. Thanks.

You need to try to Find first, then check that you found something:
Dim foundCell As Range
Set foundCell = Cells.Find(What:="Grand Total", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not foundCell Is Nothing Then
foundCell.Activate
End If

Related

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

VBA Copy & Find

I have hunted online and not yet managed to find anything to covers what I need.
Hopefully this will make sense.
I need to copy the current cell, select sheet2, then find the string in that sheet.
I'm sure it's a simple bit of code and I have got it to the point where I can find the text, but only when I put it directly into the code. I just need it to use the current cell.
Sub Find()
Selection.Copy
Sheets("Sheet2").Select
Range("A1").Select
Cells.Find(What:="MYDATA", After:=ActiveCell, LookIn:= _
xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False).Activate
End Sub
All help is gratefully received.
Thanks.
Modified your code to include the value of the current cell as a variable findValue and then using that as the what argument in the find function.
Try this out:
Sub Find()
findValue = ActiveCell.Value
Sheets("Sheet2").Select
Range("A1").Select
Cells.Find(What:=findValue, After:=ActiveCell, LookIn:= _
xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False).Activate
End Sub

VBA Run time error 91. Trouble setting object variable debug

I have taken over someone else's macro who has left the organisation. I get the following error as listed in the title with Run time error.
Below is the code it is telling me to debug. Problem is this is my first time to VBA macro's and I am unsure where to begin to solve the error.
Any help would be great as I can't go past this point.
Cells.Find(What:="Top 10 Rank", After:=ActiveCell, LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:= xlNext, MatchCase:=False, _
SearchFormat:=False).Activate
If the value is not found in the search range then you will get an error, so it's best to split up your code into separate operations:
Dim f As Range
Set f = Cells.Find(What:="Top 10 Rank", After:=ActiveCell, LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:= xlNext, MatchCase:=False, _
SearchFormat:=False)
If Not f Is nothing Then
'do somthing with f
Else
Msgbox "not found!"
End If
No data was found, so .Find returned a null object reference (Nothing in VBA), as explained in this Microsoft Support page:
This macro error occurs because the Visual Basic Find method returns a NULL value which makes activating a cell impossible.

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

Excel VBA If there is a run error, ignore a group of codes associated with it

This is a sample of what I'm putting on my macro:
Cells.Find(What:="M104", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
Selection.EntireRow.Delete
If excel can't find "M104", then it gives you a error message and the macro won't run.
I tried "On Error Resume Next" before the coding above and it ignored the find error, but deleted the row. Is there a way to make it ignore both the find function and the row deletion?
Thanks for the help!
On Error Resume Next does exactly what it says it does: resumes execution of code at the next line.
The error arises because you've piggy-backed the Activate on to a method that might return Nothing.
Here is a very crude way of handling this error:
On Error Resume Next
Cells.Find(What:="M104", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
'If there was not an error, then delete the row
If Err.Number = 0 Then
Selection.EntireRow.Delete
End If
'Resume the default error handling
On Error GoTo 0
Here is a more sophisticated way. First, declare a Range object to hold the result of the Find.
Dim foundRange as Range
Set foundRange = Cells.Find(What:="M104", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False)
If Not foundRange Is Nothing Then foundRange.EntireRow.Delete
In the second example, I have programmed to anticipate the error, and built some logic to handle the potential case of "not found".
You can also use error handling GoTo blocks with Resume _line_ option, but that's generally more cumbersome and I try to avoid that where possible