How do I programmatically reset the Excel Find and Replace dialog box parameters to defaults ("Find what", "Replace with", "Within", "Search", "Look in", "Match case", "Match entire cell contents")?
I am using Application.FindFormat.Clear and Application.ReplaceFormat.Clear to reset find and replace cell formats.
Interestingly, after using expression.Replace(FindWhat, ReplaceWhat, After, MatchCase, WholeWords), the FindWhat string shows in the Find and Replace dialog box but not the ReplaceWhat parameter.
You can use this macro to reset find & replace. Unfortunately, you have to call them both as there are one or two arguments unique to each, so if you want to reset everything, you're stuck. There is no 'reset', so the only way I have found is to execute a fake find & replace using the default parameters.
Sub ResetFind()
Dim r As Range
On Error Resume Next 'just in case there is no active cell
Set r = ActiveCell
On Error Goto 0
Cells.Find what:="", _
After:=ActiveCell, _
LookIn:=xlFormulas, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False, _
SearchFormat:=False
Cells.Replace what:="", Replacement:="", ReplaceFormat:=False
If Not r Is Nothing Then r.Select
Set r = Nothing
End Sub
You can use the following command to open the "Replace" dialog with fields filled:
Application.Dialogs(xlDialogFormulaReplace).Show -arguments here-
the argument list is
find_text, replace_text, look_at, look_by, active_cell, match_case, match_byte
So far, the only way I've found to 'click' the buttons is with SendKey.
After much research and testing, I now know exactly what you want to do, but don't think it can be done (without SendKey). It appears that there is a bug in Excel, that won't reset the replacement value (from VBA), no matter what you try and set it to.
I did find this 'faster' way someone posted on MSDN, so you might give it a try.
Faster than Replace
No need to use sendkeys you can easily refer to the values you need to reset the dialog box values.
Sub ResetFindReplace()
'Resets the find/replace dialog box options
Dim r As Range
On Error Resume Next
Set r = Cells.Find(What:="", _
LookIn:=xlFormulas, _
SearchOrder:=xlRows, _
LookAt:=xlPart, _
MatchCase:=False)
On Error GoTo 0
'Reset the defaults
On Error Resume Next
Set r = Cells.Find(What:="", _
LookIn:=xlFormulas, _
SearchOrder:=xlRows, _
LookAt:=xlPart, _
MatchCase:=False)
On Error GoTo 0
End Sub
I tested this and it works. I have borrowed parts from a few places
Sub RR0() 'Replace Reset & Open dialog (specs: clear settings, search columns, match case)
'Dim r As RANGE 'not seem to need
'Set r = ActiveCell 'not seem to need
On Error Resume Next 'just in case there is no active cell
On Error GoTo 0
Application.FindFormat.Clear 'yes
Application.ReplaceFormat.Clear 'yes
Cells.find what:="", After:=ActiveCell, LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext
Cells.Replace what:="", Replacement:="", ReplaceFormat:=False, MatchCase:=True 'format not seem to do anything
'Cells.Replace what:="", Replacement:="", ReplaceFormat:=False 'orig, wo matchcase not work unless put here - in replace
'If Not r Is Nothing Then r.Select 'not seem to need
'Set r = Nothing
'settings choices:
'match entire cell: LookAt:=xlWhole, or: LookAt:=xlPart,
'column or row: SearchOrder:=xlByColumns, or: SearchOrder:=xlByRows,
Application.CommandBars("Edit").Controls("Replace...").Execute 'YES WORKS
'Application.CommandBars("Edit").Controls("Find...").Execute 'YES same, easier to manipulate
'Application.CommandBars.FindControl(ID:=1849).Execute 'YES full find dialog
'PROBLEM: how to expand options?
'SendKeys ("%{T}") 'alt-T works the first time, want options to stay open
Application.EnableEvents = True 'EVENTS
End Sub
Dave Parillo's solution is very good but it does not reset the formatting options of Excel's Find an Replace dialog. The following is more thorough and does reset those options.
Sub ResetFindAndReplace()
Dim oldActive As Range, oldSelection As Range
On Error Resume Next ' just in case there is no active cell
Set oldActive = ActiveCell
Set oldSelection = Selection
On Error GoTo 0
Cells.Find what:="", _
After:=ActiveCell, _
LookIn:=xlFormulas, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False, _
SearchFormat:=False
Cells.Replace what:="", Replacement:="", ReplaceFormat:=False
Application.FindFormat.Clear
' return selection cell
If Not oldSelection Is Nothing Then oldSelection.Select
' return active cell
If Not oldActive Is Nothing Then oldActive.Activate
Set oldActive = Nothing
End Sub
Related
I need to remove some record from Excel spreadsheet. I want for macro to search for a certain name and upon finding a cell with that name, remove row containing it and next X rows.
So far I have a part that removes content of a cell upon certain words, but now I would need it to not clear but remove whole rows
Range("B2:H100").Replace What:="*Phone", Replacement:="", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Range("B2:H100").Replace What:="*Queue", Replacement:="", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Range("B2:H100").Replace What:="*2nd Line", Replacement:="", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Try something like the code below:
Option Explicit
Sub RemoveRowsFindName()
Dim FindRng As Range
Dim xRows As Long
Dim FindWord As String
xRows = 7 ' number of extra rows to remove
FindWord = "Phone"
Set FindRng = Range("B2:H100").Find(What:=FindWord, LookAt:=xlPart, SearchOrder:=xlByRows)
If Not FindRng Is Nothing Then
Range("A" & FindRng.Row).Resize(1 + xRows, 1).EntireRow.Delete Shift:=xlShiftUp
Else ' word not found in range
MsgBox "Unable to find " & FindWord & " in range", vbCritical, "Find Error!"
End If
End Sub
#Shar Rado -
This would be a part of a bit larger script designed for clearing out excel spreadsheet to be more transparent for HR team, I've pasted your suggesion as:
Dim FindRng As Range
Dim xRows As Long
Dim FindWord As String
xRows = 7
FindWord = "Tony"
Set FindRng = Range("B2:H100").Find(What:=FindWord, LookAt:=xlPart, SearchOrder:=xlByRows)
If Not FindRng Is Nothing Then
Range("A" & FindRng.Row).Resize(1 + xRows, 1).EntireRow.Delete Shift:=xlShiftUp
End If
But the overall macro did the same it done previously - didn't return any errors nor did the needed removal.
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
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.
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
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