I have a macro to clean up raw input phone numbers, and it generally works great, except after the rare occasions when I've done a global (workbook) find or replace. If I have a brain fart & forget to change from "workbook" back to "sheet" mode it will run rampant, higgledy-piggledy extracting '-' & '.' out of data & formulae alike on all sheets in the workbook, irrespective of the constraints that I thought I'd applied to it.
How do I constrain it properly, so I don't have to spend a couple hours several times a year restoring?
What I have now:
Sheets("Data").Select
Range("DataTbl[[Phone]:[Phone2]]").Select ' DataTbl is 15 col x >800 row
Selection.Replace What:=" ", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
Selection.Replace What:=" ", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
Selection.Replace What:=")", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
Selection.Replace What:="-", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
Selection.Replace What:="(", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
Selection.Replace What:=".", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
Stop relying on .Select and Selection to define your area of concern. It may work some or even most of the time but can only lead to eventual errors due to the inherent ambiguous nature.
Dim r As Range
On Error Resume Next
Set r = Cells.Find(What:=vbNullString, LookIn:=xlFormulas, _
SearchOrder:=xlRows, LookAt:=xlPart, MatchCase:=False)
On Error GoTo 0
With Sheets("Data").Range("DataTbl[[Phone]:[Phone2]]") ' DataTbl is 15 col x >800 row
.Replace What:=" ", Replacement:=vbNullString, LookAt:=xlPart
.Replace What:=" ", Replacement:=vbNullString, LookAt:=xlPart
.Replace What:=")", Replacement:=vbNullString, LookAt:=xlPart
.Replace What:="-", Replacement:=vbNullString, LookAt:=xlPart
.Replace What:="(", Replacement:=vbNullString, LookAt:=xlPart
.Replace What:=".", Replacement:=vbNullString, LookAt:=xlPart
End With
See How to avoid using Select in Excel VBA macros for various methods to get away from .Select.
EDIT: Added four lines of code at the beginning to reset the 'remembered' .Find parameters to defaults (e.g. Within: Sheet, not Within: Workbook).
Related
Look the code below:
With Worksheets("L.NAM.M")
With .Cells.Find(What:="forecast_quarter", After:=ActiveCell, LookIn:= _
xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False)
.Parent.Range(.Offset(1), .Parent.Cells(Rows.Count, .Column).End(xlUp)).Copy _
Destination:=Worksheets("NewForecast").Range("K" & Rows.Count).End(xlUp).Offset(1)
End With
End With
With Worksheets("L.EMEA.O")
With .Cells.Find(What:="forecast_quarter", After:=ActiveCell, LookIn:= _
xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False)
.Parent.Range(.Offset(1), .Parent.Cells(Rows.Count, .Column).End(xlUp)).Copy Destination:=Worksheets("NewForecast").Range("K" & Rows.Count).End(xlUp).Offset(1)
End With
End With
'Record Source
With Worksheets("L.EMEO.O")
With .Cells.Find(What:="Record Source", After:=ActiveCell, LookIn:= _
xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False)
.Parent.Range(.Offset(1), .Parent.Cells(Rows.Count, .Column).End(xlUp)).Copy Destination:=Worksheets("NewForecast").Range("N" & Rows.Count).End(xlUp).Offset(1)
End With
End With
What I am doing here..I am getting data forecast_quarter of those two spreadsheets and pasting below the header of a new spreadsheet. So, it is finding the lastrow with data and pasting below. The trick part comes when look for Record Source from "L.EMEA.O", as the "L.NAM.M" does not have any data for column L, it messes up when I paste the L.EMEA.O data, as it does not align with the L.EMEA.O but with L.NAM.O. What I would like is to paste aligned the row of where it pasted the forecast_quarter for L.EMEA.O.
Any ideas? I attache a photo
In this case it pasted in the K114,if i run the other piece, I want to paste in the same not in the N110, but N114.
store the row index used for "L.EMEA.O" and use it for "L.EMEO.O" as well:
With Worksheets("L.NAM.M")
With .Cells.Find(What:="forecast_quarter", After:=ActiveCell, LookIn:= _
xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False)
.Parent.Range(.Offset(1), .Parent.Cells(Rows.Count, .Column).End(xlUp)).Copy _
Destination:=Worksheets("NewForecast").Range("K" & Rows.Count).End(xlUp).Offset(1)
End With
End With
Dim L_EMEA_ORow As Long '<--| variable to hold "forecast_quarter" sheet column "K" row index where to start pasting "L.EMEA.O" sheet data from
With Worksheets("L.EMEA.O")
With .Cells.Find(What:="forecast_quarter", After:=ActiveCell, LookIn:= _
xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False)
L_EMEA_ORow = Worksheets("NewForecast").Range("K" & Rows.Count).End(xlUp).Offset(1).Row '<--| store relevant row index where to start pasting data from
.Parent.Range(.Offset(1), .Parent.Cells(Rows.Count, .Column).End(xlUp)).Copy Destination:=Worksheets("NewForecast").Range("K" & L_EMEA_ORow) '<--| use relevant row index
End With
End With
'Record Source
With Worksheets("L.EMEO.O")
With .Cells.Find(What:="Record Source", After:=ActiveCell, LookIn:= _
xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False)
.Parent.Range(.Offset(1), .Parent.Cells(Rows.Count, .Column).End(xlUp)).Copy Destination:=Worksheets("NewForecast").Range("N" & L_EMEA_ORow) '<--| use same relevant row index calculated above
End With
End With
I'm trying to use SendKeys to copy a word from one cell into the replace (CTRL+F) function.
The copy bit is fine but this spreadsheet is going to be used as a template so the variable is what is in that cell meaning i'm using send keys.
I'm open to other ideas.
Code is below.
Range("E5:G5").Select
Selection.Copy
Sheets("New Project Schedule").Select
Selection.Replace What:="New Merchant", Replacement:= SendKeys "^v" , LookAt= _
:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Sheets("Out of Scope").Select
Selection.Replace What:="New Merchant", Replacement:= SendKeys "^v", LookAt= _
:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Sheets("New Project Schedule").Select
Selection.Replace What:="Merchant", Replacement:= SendKeys "^v", LookAt:= _
xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Sheets("Out of Scope").Select
Selection.Replace What:="Merchant", Replacement:= SendKeys "^v", LookAt:=
xlPart , SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
End Sub
You don't need to copy and paste - something like this should do:
Dim avSheets, vSheet
Dim sWord As String
avSheets = Array("New Project Schedule", "Out of Scope")
sWord = Range("E5:G5").Value
For Each vSheet In avSheets
With Sheets(vSheet).Cells
.Replace What:="New Merchant", Replacement:=sWord, _
LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, _
SearchFormat:=False, ReplaceFormat:=False
.Replace What:="Merchant", Replacement:=sWord, LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
End With
Next vSheet
Rather than copying the block of three cells and then trying to determine where to paste them is different worksheets, get the three cells into an array and then decide where the array should be deposited in each of the other sheets.
I have an issue where I need to replace a number with a Loan identifier, the problem I am having is the Loan identifier contains the number that needs replacing so I am ending up with something like "LOAN1592LOAN3161LOAN29269704932LOAN2926970411" when what I actually want is if the loan number is 6 for it to be replaced with LOAN31617932 not the above. Any thoughts how I can stop this from happening? I hope this makes sense. Please see the segment of my code as follows:
Columns("e:e").Select
Selection.Replace What:="5", Replacement:="LOAN15926711", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Columns("e:e").Select
Selection.Replace What:="6", Replacement:="LOAN31617932", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Columns("e:e").Select
Selection.Replace What:="7", Replacement:="LOAN29269704", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Columns("e:e").Select
Selection.Replace What:="8", Replacement:="LOAN57538987", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Use xlWhole:
Sub luxation()
Columns("e:e").Replace What:="5", Replacement:="LOAN15926711", LookAt:=xlWhole, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
End Sub
Before:
and after:
Note:
The 55 and 555 are ignored!
I'd do If (or Select Case) instead. See my comment above as to why. Does this work:
Sub t()
Dim cel As Range, rng As Range
Dim lastRow&
lastRow = Cells(Rows.Count, 5).End(xlUp).row
Set rng = Range("E1:E" & lastRow)
For Each cel In rng
If InStr(1, cel.Value, "2") Then cel.Value = "LOAN15926711"
If InStr(1, cel.Value, "6") Then cel.Value = "LOAN31617932"
' etc. etc.
Next cel
End Sub
If the cell will only have 5, 6, etc. then just do
If cel.Value = "6" Then ...
Edit2: But I'd listen to #GarysStudent, adding the simple xlWhole is what you want. Simple, clean, and easy.
Am having this "�" special character in my excel work book, i want to replace all with ".", when i place this � character in the code , it turns to "?" after i run the macro it replaces everything to "."
Sub FindReplaceAll()
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
ws.Cells.Replace What:="�", Replacement:=".", LookAt:= _
xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Next ws
End Sub
Thanks in advance
Try to copy this character in a cell, then have the ASCII number and replace the character by the ASCII num:
Dim num =123
Ex:
Cells.Replace What:=Chr(Num), Replacement:=".", LookAt:= _
xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
I'm trying to select the contents (the range X11:Xnn) of the table:
KEYWORD2
X11 X12 ... X1N
X21 X22 ... X2N
... ... ... ...
XN1 XN2 ... XNN
KEYWORD1
No Important Things…
So, I want select only the range X11:XNN doing a search of the 2 keywords and then select only the Xii.
I'm trying to do this:
Sub Macro3()
Cells.Find(What:="KEYWORD1", After:=ActiveCell, LookIn:=xlFormulas _
, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
Selection.Offset(-1, 0).Select 'I don't want the KeyWord1 appears
Cells.Find(What:="KEYWORD2", After:=ActiveCell, LookIn:=xlFormulas _
, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
Selection.Offset(1, 0).Select 'I don't want the KeyWord2 appears
Range(??, ??).Select
End Sub
Your main issue is that you are not returning the location of the keywords so that you may use them later. Lets capture those results and we can offset them we we call the range.
Sub Macro3()
Dim rngKeywordOneLocation As Range
Dim rngKeywordTwoLocation As Range
Set rngKeywordOneLocation = Cells.Find(What:="KEYWORD1", After:=ActiveCell, LookIn:=xlFormulas _
, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
Set rngKeywordTwoLocation = Cells.Find(What:="KEYWORD2", After:=ActiveCell, LookIn:=xlFormulas _
, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
Range(rngKeywordOneLocation.Offset(1, 0), rngKeywordTwoLocation.Offset(-1, 0)).Select
End Sub
Also, you should be careful with your use of .select.