If #REF! is found then Error Box Macro - excel

I am trying to complete a simple macro that looks for '#REF!' in a worksheet due to a user alterting a row and ruining underlying formulas.
I have got as far as the find:
Sheets("Location_Multiple").Select
Range("A1:AL10000").Select
Selection.Find(What:="#REF!", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
From what I understand I need to enter an If parameter is true then
MsgBox"Please go back and check...."
Im just not sure what should follow the if....
Any pointers would be very much appreciated.

Try below code
Sub DisplayError()
On Error Resume Next
Dim rng As Range
Set rng = Sheets("Location_Multiple").Range("A1:AL10000")
Dim rngError As Range
Set rngError = rng.SpecialCells(xlCellTypeFormulas, xlErrors)
If Not rngError Is Nothing Then
For Each cell In rngError
MsgBox "Please go back and check.... " & cell.Address
Next
End If
End Sub

Use this, change the LookIn argument to xlValues instead of xlFormulas:
Selection.Find(What:="#REF!", After:=ActiveCell, LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
For a bit cleaner implementation:
Dim sht as Worksheet
Dim rngSrch as Range
Dim rngErr as Range
Set sht = Sheets("Location_Multiple")
Set rngSrch = sht.Range("A1:AL10000")
Set rngErr = rngSearch.Find(What:="#REF!", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not rngErr Is Nothing Then
'Do something to the offending cell, like, highlight it:
rngErr.Interior.ColorIndex = 39
End If
Anticipating there may be multiple cells with an error like this, you'll probably have to implement your .Find within a Do...While loop. There are several examples of that sort of problem on SO. If you have trouble implementing the loop, let me know.

The problem you have is because you're searching for a string - whereas #REF is an error.
You could use the IsError function, to return true for a cell with an error. Combine this with a loop, and you could achieve what you require. I haven't tested this, but you get the jist:
Set rng = Sheets("Location_Multiple").Range("A1:AL10000")
For Each cell In rngError
If IsError(cell) == true
MsgBox "Please go back and check.... " & cell.Address
Endif
Next

Related

Excel VBA: Using FIND: How to select the cell where the item is found?

I am using Excel VBA to search for a string e.g. "CCC" in an Excel worksheet.
I used the simple code shown.
However, I want VBA to select the cell where the first occurrence of "CCC" is found. (Just like when you do a FIND manually).
How can I modify my code to achieve this?`
Private Sub CommandButton1_Click()
Dim rng As Range
Set rng = Cells.Find(What:="CCC", After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False)
If Not rng Is Nothing Then
MsgBox ("found")
Else
MsgBox ("not found")
End If
End Sub
To select a cell, you can use the Select method. So, if you have a Range object which has been set to the cell you want, you can apply the Select method to that object, i.e.
rng.Select
Incorporated into your existing code, it might look something like:
Private Sub CommandButton1_Click()
Dim rng As Range
Set rng = Cells.Find(What:="CCC", After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False)
If Not rng Is Nothing Then
MsgBox "found"
rng.Select
Else
MsgBox "not found"
End If
End Sub
You can use rng.Select but it needs the worksheet to be active on top (or you habe to activate it first i.e. rng.Parent.Activate). Simplest is to use Application.Goto rng
If Not rng Is Nothing Then
Application.Goto rng
MsgBox ("found")
Else
MsgBox ("Not found")
End If
Private Sub CommandButton1_Click()
Range("A1").select
Cells.Find(What:="CCC", After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False).activate
activcecell.select
If Not rng Is Nothing Then
MsgBox ("found")
Else
MsgBox ("not found")
End If
End Sub
Using activecell.select will select your first find cell.

Find method raise error 91 in excel Macro

I use a find method in the Excel macro for searching VLOOKUP in a cell, my goal is I need to know which formula that does not contain VLOOKUP, my method was running well, until in a cell there was
no VLOOKUP and macro kept debugging with the Run time error '91'
My question is how should I write the macro correctly so I wont get the debug until the activecell
contains *, below is my macro:
Sub findvlookup()
Do While Not ActiveCell.Value = "*"
If Selection.Find(What:="VLOOKUP", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate Then
ActiveCell.Offset(1, 0).Select
End If
Loop
End Sub
Thanks for the help
You don't need a loop to find the first occurrence of your 'What:=" string
Dim fndVL as Range
fndVL = Selection.Find(What:="VLOOKUP", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not fndVL is Nothing Then
MsgBox "Found it"
Else
NsgBox "Not found"
End If
If you want to find subsequent instances then have a look at FindNext and possibly use this within a loop.
Sub findvlookup()
Dim rngFind As Range
Do While Not ActiveCell.Value = "*"
Set rngFind = Selection.Find(What:="VLOOKUP", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not rngFind Is Nothing Then
ActiveCell.Offset(1, 0).Select
Else
Exit Sub
End If
Loop
End Sub
You are using Find method that technical details are Here.
You can find (in example) that:
Common Err.Numbers (9, 91) : the specified text wasn't in the target workbook.
And if you have a cell with an error value you will have another type of errors: like #Value

How to Delete Rows of Text After Finding Specific Words in Excel and continue deleting rows until it finds other specific words

I'm relatively new to the whole Visual Basic scene but do have basic knowledge in programming and I understand how to read code and follow the logic patterns.
What I am trying to accomplish in this macro is the following:
Find the row in the spreadsheet that says the word "Suppressed" then delete that row and the following rows until it finds the row which says "Other Response Categories" in it, and stop there without deleting that from the row.
Find the row in the spreadsheet that says the words "Requires Challenge Response" and delete that row along with all rows underneath it until it finds a row which has a line of text in it named "Tracking Links Clicked" and stop there without deleting that from the row.
Find the row in the spreadsheet that says the words "Link Name (HTML)" and delete that row along with all rows underneath it.
I have used the "Record Macro" function to get a general idea on how to remove lines of text from excel but only by using ranged areas which are selected then deleted; not searching for key phrases.
I'm in the works on researching a lot of VB stuff in order to actually write what I want to accomplish.
Edit2: So I modified and simplified down the VB code that you provided to at least try and get the same response you provided; but only searching for one of the values. I wanted to get correct input for one value before trying to add in more.
Edit 3: Was able to write the script with the assistance of a friend, thank you so much everyone for their input. I have attached the working script on here:
Option Explicit
Sub Autoformat()
Dim WSA As Worksheet
Dim Rng1 As Range
Dim Rng2 As Range
Dim lpRange As Range
Dim sArr As Variant
Set WSA = ActiveSheet
Dim i As Long
sArr = Array("Suppressed", "Other Response Categories", "Requires Challenge Response", "Tracking Links Clicked", "Link Name (HTML)")
Rows("6:9").Delete
With Application
.Calculation = xlCalculationManual
.ScreenUpdating = False
.DisplayAlerts = False
.EnableEvents = False
End With
For i = 0 To 3 Step 2
Set lpRange = WSA.UsedRange
Set Rng1 = lpRange.Find(What:=sArr(i), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
MatchCase:=False)
Set Rng2 = lpRange.Find(What:=sArr(i + 1), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
MatchCase:=False)
On Error Resume Next
If Not Rng1 Is Nothing And Not Rng2 Is Nothing And Rng2.Row > Rng1.Row Then
WSA.Rows(Rng1.Row & ":" & Rng2.Row - 1).Delete
ElseIf Not Rng1 Is Nothing And Rng2 Is Nothing Then
WSA.Rows(Rng1.Row).Delete
End If
Next i
Set lpRange = WSA.UsedRange
Set Rng2 = lpRange.Find(What:=sArr(i), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
MatchCase:=False)
If Not Rng2 Is Nothing Then
WSA.Rows(Rng2.Row & ":" & Rows.Count).Clear
End If
With Application
.Calculation = xlCalculationAutomatic
.ScreenUpdating = True
.DisplayAlerts = True
.EnableEvents = True
End With
End Sub
Sub ClearNames()
Dim n As Name
For Each n In ThisWorkbook.Names
n.Delete
Next n
End Sub
The Macro Recorder is a great way of discovering the syntax of statements you do not know. However, the Macro Recorder does not know your objectives; it just records each of your actions. The result needs a lot of tidying up.
You must learn Excel VBA if you are going to post questions and expect to understand the answers. Search the web for "Excel VBA Tutorial". There are many to choose from so pick one that matches your learning style. I preferred to visit a large library and try out the VB Excel primers they had. I then bought the one I liked.
This is to give you are start at tidying up something created with the Macro Recorder.
I placed your key phrases in random cells down a worksheet and then searched for them in turn. The macro recorder's output was:
Sub Macro1()
'
' Macro1 Macro
' Macro recorded 07/05/2014 by Tony Dallimore
'
Cells.Find(What:="Suppressed", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
Cells.Find(What:="Other Response Categories", After:=ActiveCell, LookIn:= _
xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False).Activate
Cells.Find(What:="Requires Challenge Response", After:=ActiveCell, LookIn _
:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False).Activate
Cells.Find(What:="Link Name (HTML)", After:=ActiveCell, LookIn:= _
xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False).Activate
End Sub
This code finds the four phrases but does not do anything else. This shows the syntax of the Find method. We need to tidy this code and save row numbers rather than activate (select) cells. Rather than try to explain each change I have created the code below from the code above. Study the differences and try to understand what I have done and why. Come back with questions if necessary but the more you can achieve on your own, the faster you will build up your skills.
Sub Demo()
Dim Rng As Range
Dim RowSupp As Long
Dim RowOther As Long
Dim RowReq As Long
Dim RowLink As Long
With Worksheets("Sheet1")
Set Rng = .Cells.Find(What:="Suppressed", After:=.Cells(Rows.Count, Columns.Count), _
LookIn:=xlFormulas, LookAt:=xlWhole, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
' Note in the above statement I have replaced "ActiveCell" with ".Cells(Rows.Count, Columns.Count)"
' which is the bottom right cell. Find does not look at the start cell, it wraps and starts
' searching from A1. I have also replaced "xlPart" with "xlWhole".
If Rng Is Nothing Then
Call MsgBox("""Suppressed"" not found", vbOKOnly)
Exit Sub
End If
RowSupp = Rng.Row
Set Rng = .Cells.Find(What:="Other Response Categories", After:=.Cells(Rng.Row, Rng.Column), _
LookIn:=xlFormulas, LookAt:=xlWhole, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
If Rng Is Nothing Then
Call MsgBox("""Other Response Categories"" not found", vbOKOnly)
Exit Sub
End If
RowOther = Rng.Row
Set Rng = .Cells.Find(What:="Requires Challenge Response", After:=.Cells(Rng.Row, Rng.Column), _
LookIn:=xlFormulas, LookAt:=xlWhole, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
If Rng Is Nothing Then
Call MsgBox("""Requires Challenge Response"" not found", vbOKOnly)
Exit Sub
End If
RowReq = Rng.Row
Set Rng = .Cells.Find(What:="Link Name (HTML)", After:=.Cells(Rng.Row, Rng.Column), _
LookIn:=xlFormulas, LookAt:=xlWhole, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
If Rng Is Nothing Then
Call MsgBox("""Requires Challenge Response"" not found", vbOKOnly)
Exit Sub
End If
RowLink = Rng.Row
End With
Debug.Print """Suppressed"" found on row " & RowSupp
Debug.Print """Other Response Categories"" found on row " & RowOther
Debug.Print """Requires Challenge Response"" found on row " & RowReq
Debug.Print """Link Name (HTML)"" found on row " & RowLink
End Sub
The above macro has found the four rows and has proved it has found them by outputting their values to the Immediate Window.
For my dummy worksheet, the output is:
"Suppressed" found on row 6
"Other Response Categories" found on row 11
"Requires Challenge Response" found on row 16
"Link Name (HTML)" found on row 22
If I am unsure what I am doing, I always code this way. I identify step 1 and code a routine to achieve step 1. I then identify step 2 and update my code to achieve that as well.
If my data matched yours, you would want rows 6 to 10 deleted.
You have posted:
Rows("6:9").Select
Selection.Delete Shift:=xlUp
If we tidy that up we first get:
.Rows("6:9").Delete Shift:=xlUp
The next step is to replace the 6 and the 9 with the row numbers that macro Demo discovered:
.Rows(RowSupp & ":" & RowOther - 1).Delete Shift:=xlUp
Place this under RowOther = Rng.Row and run Demo again.
The first lot of rows are deleted.
Step 3 is to consider how to adjust the third Find statement. The current macro relies on RowOther not moving between Finds 2 and 3. But it has moved up by the number of lines deleted. You cannot use .Cells(Rng.Row, Rng.Column) as the start point for Find 3.
I leave you to think about where to start Find 3.

Seach and find value based on value in another cell

I am trying to build a macro that will search a specific column.
Here are the steps:
1. user enters a number into the cell and then executes the macro.
2. based on the value of what the user has entered, the macro will find the text in a column.
I got everything to work pretty well except I don't know how to define the value of the cell that the user enters. Any help here would be appreciated.
Sheets("New Version ").Select
Range("B4").Select
Sheets("PN_List").Select
Columns("I:I").Select
'below is where I struggle
Selection.Find(What:=(""), After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
Let's say the user enters a number into cell B4, then you just have to adjust your code into:
Selection.Find(What:=Range("B4").Value, After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
You can do this in 2 ways.
Number1:
Module based: (code in module)
Sub Sample()
Dim search_range as Range, search_value as Range, _
lastcell as Range, foundcell as Range
Dim ws as Worksheet
Set ws = Thisworkbook.Sheets("PN_List")
Set search_range = ws.Range("I1", ws.Range("I" & Rows.Count).End(xlUp))
Set lastcell = search_range.Cells(search_range.Cells.Count)
Set search_value = Thisworkbook.Sheets("New Version").Range("B4")
Set foundcell = search_range.Find(What:=search_value, After:=lastcell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
If Not foundcell Is Nothing Then foundcell.Activate Else Msgbox "Not Found"
End Sub
Number2:
Worksheet Event based. (code in Sheet)
Private Sub Worksheet_Change(ByVal Target as Range)
Dim search_range as Range, search_value as Range, _
lastcell as Range, foundcell as Range
Dim ws as Worksheet
Set ws = Thisworkbook.Sheets("PN_List")
Set search_range = ws.Range("I1", ws.Range("I" & Rows.Count).End(xlUp))
Set lastcell = search_range.Cells(search_range.Cells.Count)
Set search_value = Thisworkbook.Sheets("New Version").Range("B4")
If Not Intersect(Target, search_value) Is Nothing Then
query = Msgbox("Search data?", vbYesNo)
If query = 7 Then Exit Sub
Set foundcell = search_range.Find(What:=search_value, After:=lastcell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
If Not foundcell Is Nothing Then foundcell.Activate Else Msgbox "Not Found"
End Sub
The first one you enter data in B4 then run the macro.
The second one fires every time you change value in B4.
A msgbox will appear asking if you want to search the data entered.
Hope this helps.

Excel Input Box VBA Error Checking Problem

Below is the code that I changed. I cannot figure out VBA for the life of me. If this was c++ it would have taken me 30 seconds to write. I am still getting the errors.
Sub CodeFinder()
Dim userInput As String
Dim errorCheck As String
userInput = InputBox("Please enter the code to search", "Code Search Engine")
errorCheck = Cells.Find(What:=userInput, _
After:=ActiveCell, LookIn:=xlFormulas, LookAt:=xlPart, _
SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False)
If errorCheck = False Then
MsgBox ("Error")
Else
Cells.Find(What:=userInput, _
After:=ActiveCell, LookIn:=xlFormulas, LookAt:=xlPart, _
SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False).Activate
End If
End Sub
If Cells.Find fails it returns Nothing. So you need to assign it to a variable, and check its value before trying to .Activate it.
In fact you should also check the return value of InputBox in case Cancel was clicked.
EDIT: Still contains a number of errors.
Cells.Find returns a Range, but you are trying to assign it to a String variable. (Also don't forget that Range and String variables have different assignment statements.)
You then try to compare the variable to False instead of checking that it isn't Nothing.
You then need to activate the found Range rather than trying to find it again.
Sub CodeFinder()
Dim userInput As String
Dim rFound As Range
userInput = InputBox("Please enter the code to search", "Code Search Engine")
If Len(userInput) > 0 Then
Set rFound = ActiveSheet.Cells.Find(What:=userInput, _
After:=ActiveCell, LookIn:=xlFormulas, LookAt:=xlPart, _
SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False)
If Not rFound Is Nothing Then
rFound.Select
Else
MsgBox "No cells found"
End If
End If
End Sub

Resources