Search for specific words and replace each with a corresponding different word? - excel

I need to search through a range.
If 5062 is found change to 3201, 5063 to 3202, and 5084 to 3204.
Dim myRange As Range
Set myRange = Range(Cells(6, 3), Cells(65, 3))
With myRange.Find
.Execute FindText:="5062", ReplaceWith:="3201"
.Execute FindText:="5063", ReplaceWith:="3202"
.Execute FindText:="5084", ReplaceWith:="3204"
End With
End Sub

Here, try this:
Sub ReplaceValues()
Dim SearchReplaceArray
Dim I As Long
Dim RG As Range
Set RG = Range("A1:O34")
'Array Storage: <_Array_First_Row__> <___Second_Row_____>
SearchReplaceArray = [{"5062","5063","5084";"3201","3202","3204"}]
For I = 1 To UBound(SearchReplaceArray, 2)
RG.Replace _
What:=SearchReplaceArray(1, I), _
Replacement:=SearchReplaceArray(2, I), _
LookAt:=xlWhole, _
MatchCase:=True
Next I
End Sub
Very easy to modify for any number of replacements.
Makes replacements very quickly.
Turns this:
Into This:
I speed tested it like this... because curiosity:
Sub TestSpeed()
Dim SearchReplaceArray
Dim I As Long
Dim Start
Dim RG As Range
Set RG = Range("A1:J10000")
Start = Timer
'Array Storage: <_Array_First_Row__> <___Second_Row_____>
SearchReplaceArray = [{"5062","5063","5084";"3201","3202","3204"}]
For I = 1 To UBound(SearchReplaceArray, 2)
RG.Replace _
What:=SearchReplaceArray(1, I), _
Replacement:=SearchReplaceArray(2, I), _
LookAt:=xlWhole, _
MatchCase:=True
Next I
Debug.Print "Completed " & RG.Cells.Count & " replacements in " & Timer - Start & " seconds."
End Sub
Every single cell had one of the three values required to replace.
The debug output was:
Completed 100000 replacements in 3.027344 seconds.
Completed 100000 replacements in 2.976563 seconds.
Completed 100000 replacements in 2.996094 seconds.
Completed 100000 replacements in 2.976563 seconds.
Completed 100000 replacements in 3.070313 seconds.
Not bad.

I have made a loop which searches the range provided in your question for the given values. If the value is the value of a cell in the range, it is replaced with the intended value. Hope this helps!
Sub FindVals()
Dim myRange As Range
Set myRange = Range(Cells(6, 3), Cells(65, 3))
Dim chngVal1 As Integer, chngVal2 As Integer, chngVal3 As Integer
chngVal1 = 3201
chngVal2 = 3202
chngVal3 = 3204
For Each cell In myRange
If cell.Value = 5062 Then cell.Value = chngVal1
If cell.Value = 5063 Then cell.Value = chngVal2
If cell.Value = 5084 Then cell.Value = chngVal3
Next
End Sub

Related

Find specific text or dates inside a range and mark line with a specific colour

I have report were I use a VBA Macro to get a list from a large amount of Raw Data.
I have a very specific need, I hope someone can help me with.
My range is from A5:I500, each line from A:I has information to a specific need.
If a cell in the "H" Column has a specific text (in my case "Unconfirmed"), I would like The entire line (for instance A5:I5 or A26:I26), to be marked in a specific color.
If "H" Column has a date which is later than the date of "today", I would like the line (for instance A5:I5 or A26:I26), to be marked in a specific color.
If "H" Column has a date which is before the date of "today", I would like the line (for instance A5:I5 or A26:I26), to be marked in a specific color.
I want to end up like this
I found code which turns just the specific cell in the color I want.
How do I change this code to fill the entire Line from A:I on every line which contains "unconfirmed"?
Sub test1()
Dim FirstAddress As String
Dim MySearch As Variant
Dim myColor As Variant
Dim Rng As Range
Dim I As Long
MySearch = Array("Unconfirmed")
myColor = Array("3")
With Sheets("Ronnie").Range("A5:I1000")
For I = LBound(MySearch) To UBound(MySearch)
Set Rng = .Find(What:=MySearch(I), _
After:=.Cells(.Cells.Count), _
LookIn:=xlFormulas, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
FirstAddress = Rng.Address
Do
Rng.Interior.ColorIndex = myColor(I)
Set Rng = .FindNext(Rng)
Loop While Not Rng Is Nothing And Rng.Address <> FirstAddress
End If
Next I
End With
End Sub
This code will use if statements to check the data, and assign colour to the range of cells on that row.
Sub ColourRng()
Dim RNum As Integer
RNum = 1
For I = 1 To 500
If Sheets("Ronnie").Range("H" & RNum) = "Unconfirmed" Then
Sheets("Ronnie").Range("A" & RNum & ":I" & RNum).Interior.ColorIndex = 6
Else
If Sheets("Ronnie").Range("H" & RNum) >= Date Then
Sheets("Ronnie").Range("A" & RNum & ":I" & RNum).Interior.ColorIndex = 4
Else
If Sheets("Ronnie").Range("H" & RNum) < Date Then
Sheets("Ronnie").Range("A" & RNum & ":I" & RNum).Interior.ColorIndex = 3
End If
End If
End If
RNum = RNum + 1
Next I
End Sub

Extracting two numbers from a cell then adding them together

I am trying to work on a VBA macro that would extract two numbers from a cell and then add them together. The spreadsheet I am working on has a field like this:
Cell D1: .60 #2021-71; 0.90 #2021-71
I need to take the .60 and .90 out, add them together, and place them back in the cell.
For reference, there are other cells in this column that are like this:
Cell D2: .70 #2021-71
I have code that is already looking through the column and removing everything from the # sign on:
Dim tmp As String
For Each cell In Range("D:M")
If InStr(cell.Value, "#") > 0 Then
tmp = cell.Value
cell.Value = Left(tmp, InStr(tmp, "#") - 1)
End If
Is what I am trying to do even possible?
I've taken the approach of providing a custom function which you can then refer to on sheet.
You can call the function whatever you want...!
Public Function SumFirstNumbers(ByVal rngCell As Range) As Variant
Dim arrValues, i As Long, strValue As String, dblValue As String
If InStr(1, rngCell.Text, "#") > 0 Then
arrValues = Split(rngCell.Text, ";")
For i = 0 To UBound(arrValues)
dblValue = 0
strValue = Split(Trim(arrValues(i)), " ")(0)
If IsNumeric(strValue) Then dblValue = CDbl(strValue)
SumFirstNumbers = CDbl(SumFirstNumbers) + dblValue
Next
Else
SumFirstNumbers = rngCell.Value
End If
End Function
Then just use it like any other function in a cell...
This way, you can fill down and across and not have to worry about where the source data actually resides.
To then put it back in the original cells, just Copy → Paste Special → Values.
If it produces an incorrect result (before copying back to the original cells), the function can be changed and the data is still protected.
Naturally, this could still be incorporated into a wider macro if need be. You just need to apply it to your original code.
Dim tmp As String
For Each cell In Range("D:M")
If InStr(cell.Value, "#") > 0 Then
tmp = cell.Value
cell.Value = SumFirstNumbers(cell)
End If
Next
... something like that anyway.
Non VBA Method
Using formulas only. I have indented the formula (you can do that in the formula bar) for a better understanding.
=IFERROR(
IF(
ISNUMBER(SEARCH(";",D1)),
VALUE(MID(D1,SEARCH(";",D1)+1,SEARCH("#",D1,SEARCH(";",D1)+1)-SEARCH(";",D1)-1)) + VALUE(LEFT(D1,SEARCH("#",D1)-1)),
VALUE(LEFT(D1,SEARCH("#",D1)-1))
),0
)
Logic:
Check if there is ; using SEARCH(). Use ISNUMBER() to handle the formula if it doesn't exist.
If there is ; then get the text between ; and # using MID(). Convert them to values using VALUE() and add them up.
If there is no ; then just use LEFT() to get the number before #.
VBA Method
In case you are looking for VBA method to replace the values in the same column then here is a faster method using WildCards. If you have lots of data then in the end where I am using For Each aCell In rng, put the data in an array and loop the array instead.
Logic:
Make Excel do most of the Dirty work!
Replace every thing that is between ";" and "#" with "" using inbuit .Replace with wildcard "#*;"
Replace every thing that is after "#" with "" using wildcard "#*"
Remove all spaces
Use Evaluate.
Code:
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim rng As Range, aCell As Range
Dim lRow As Long
Set ws = Sheet1
With ws
With .Columns(4)
.Replace What:="#*;", Replacement:="+", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False, FormulaVersion:=xlReplaceFormula2
.Replace What:="#*", Replacement:="", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False, FormulaVersion:=xlReplaceFormula2
.Replace What:=" ", Replacement:="", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False, FormulaVersion:=xlReplaceFormula2
End With
lRow = .Range("D" & .Rows.Count).End(xlUp).Row
Set rng = .Range("D1:D" & lRow)
For Each aCell In rng
aCell.Value = .Evaluate(aCell.Value)
Next aCell
End With
End Sub
In Action
Replace by Numbers
Option Explicit
Sub ReplaceByNumbers()
Const Cols As String = "D:M"
Const FindDelimiter As String = "#"
Const SplitDelimiter As String = ";"
Dim ws As Worksheet: Set ws = ActiveSheet ' improve
Dim rg As Range: Set rg = Intersect(ws.UsedRange, ws.Columns(Cols))
If rg Is Nothing Then Exit Sub ' no data
Dim rCount As Long: rCount = rg.Rows.Count
Dim cCount As Long: cCount = rg.Columns.Count
Dim Data As Variant
If rCount + cCount = 2 Then ' one cell only
ReDim Data(1 To 1, 1 To 1): Data(1, 1).Value = rg.Value
Else ' multiple cells
Data = rg.Value
End If
Dim SubStrings() As String
Dim r As Long, c As Long, n As Long
Dim iPos As Long
Dim Total As Double
Dim cString As String
Dim NumberFound As Boolean
For r = 1 To rCount
For c = 1 To cCount
cString = CStr(Data(r, c))
iPos = InStr(cString, FindDelimiter)
If iPos > 0 Then
SubStrings = Split(cString, SplitDelimiter)
For n = 0 To UBound(SubStrings)
If n > 0 Then
iPos = InStr(SubStrings(n), FindDelimiter)
End If
cString = Trim(Left(SubStrings(n), iPos - 1))
If Left(cString, 1) = "." Then cString = "0" & cValue
If IsNumeric(cString) Then
If NumberFound Then
Total = Total + CDbl(cString)
Else
Total = CDbl(cString)
NumberFound = True
End If
End If
Next n
If NumberFound Then
Data(r, c) = Total
NumberFound = False
End If
End If
Next c
Next r
rg.Value = Data
MsgBox "Replaced by numbers.", vbInformation, "ReplaceByNumbers"
End Sub

Exit from a "Find" infinite loop

I have created a Do Loop with Find to replace "Hello" with "Hi" inside column A of Sheet1, but only if the string "XYZ" is not in the same row of column B.
When Find does not replace "Hello", because in column B there is "XYZ", we enter an infinite loop since FindNext always finds "Hello" in column 1
It is possible to avoid infinite loop without making Loop While very complicated?
Please see this image of columns in sheet1
Sub CallMask()
Call Masks("Hello", "XYZ")
End Sub
Sub Masks(sMask_I As String, sNoReplace_I As String)
With Sheets("Sheet1").Columns(1)
Dim CellToReplace As Range
Set CellToReplace = .Find(What:=sMask_I, LookIn:=xlValues, _
SearchDirection:=xlNext, MatchCase:=True, Lookat:=xlPart)
If Not CellToReplace Is Nothing Then
Dim InitialAddress As String
InitialAddress = CellToReplace.Address
Dim MaskRow As Long
Dim Mask As String
On Error Resume Next
Do
MaskRow = WorksheetFunction.Match(sMask_I, _
Sheets("Sheet1").Range("C1:C" & Rows.Count), 0)
Mask = Sheets("Sheet1").Range("D" & MaskRow).Value2
If Sheets("Sheet1").Cells(CellToReplace.Row, 2) <> sNoReplace_I Then
CellToReplace.Value2 = Replace(CellToReplace.Value2, sMask_I, Mask)
End If
Set CellToReplace = .FindNext(CellToReplace)
Loop While Not CellToReplace Is Nothing And CellToReplace.Address _
<> InitialAddress
On Error GoTo 0
End If
End With
End Sub
You could try this:
Option Explicit
Sub CallMask()
Call Masks("Hello", "XYZ", "Hi")
End Sub
Sub Masks(sMask_I As String, sNoReplace_I As String, Replacement As String)
Dim C As Range
With ThisWorkbook.Sheets("Sheet1")
For Each C In .Range("A1", "A" & .Cells(.Rows.Count, 1).End(xlUp).Row)
If C Like "*" & sMask_I & "*" And C.Offset(0, 1) <> sNoReplace_I Then
C.Replace sMask_I, Replacement
End If
Next C
End With
End Sub
When using Find() in a loop it's typically easier to abstract that out into a separate method:
Sub CallMask()
Masks "Hello", "XYZ"
End Sub
Sub Masks(sMask_I As String, sNoReplace_I As String)
Dim matches As Collection, c
Set matches = FindAll(Sheets("Sheet1").Columns(1), sMask_I)
For Each c In matches
If c.Offset(0, 1) <> sNoReplace_I Then
c.Value = Replace(c.Value, sMask_I, c.Offset(0, 3).Value)
End If
Next c
End Sub
'return all matches as a collection
Public Function FindAll(rng As Range, val As String) As Collection
Dim rv As New Collection, f As Range
Dim addr As String
Set f = rng.Find(what:=val, after:=rng.Cells(rng.Cells.Count), _
LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False)
If Not f Is Nothing Then addr = f.Address()
Do Until f Is Nothing
rv.Add f
Set f = rng.FindNext(after:=f)
If f.Address() = addr Then Exit Do
Loop
Set FindAll = rv
End Function
I have tested with arrays as suggested by Damian, AJD and Mathieu. It is the fastest code.
Times for 1600 rows are:
My new code with arrays: 8 ms
Damian code with For Next: 132 ms
The Code with "separate method" of Tim Williams: 402 ms
My first code with Find: 511 ms
This is the new code:
Sub CallMask()
Call Masks("Hello", "XYZ")
End Sub
Sub Masks(ByVal sMask_I As String, ByVal sNoReplace_I As String)
With ThisWorkbook.Sheets("Sheet1")
Dim ArrayRangeToMask As Variant
ArrayRangeToMask = .Range("A1:B" & .Cells(.Rows.Count, 2).End(xlUp).Row)
Dim MaskRow As Long
Dim Mask As String
MaskRow = WorksheetFunction.Match(sMask_I, .Range("C1:C" & Rows.Count), 0)
Mask = .Range("D" & MaskRow).Value2
Dim RowMasking As Long
For RowMasking = 1 To UBound(ArrayRangeToMask)
If InStr(ArrayRangeToMask(RowMasking, 1), sMask_I) And _
ArrayRangeToMask(RowMasking, 2) <> sNoReplace_I Then
ArrayRangeToMask(RowMasking, 1) = _
Replace(ArrayRangeToMask(RowMasking, 1), sMask_I, Mask)
End If
Next RowMasking
.Range("A1:B" & .Cells(.Rows.Count, 2).End(xlUp).Row) = ArrayRangeToMask
End With
End Sub

Selection based on finding 2 different words in 2 columns

I would like to do the following using Excel VBA:
1) look for a certain word_1 within a column;
2) if word_1 was found in step (1), go one column to the right and look for another word which is called word_2. If word_2 was found as well, delete the entire row.
If on the other hand, word_2 was not found, the row does not have to be deleted.
The general idea is to search for multiple words in one column and if they are found, also double-check (for safety) if certain affiliated words are in column 2. Only then the entire rows should be deleted.
I made the following little example for testing:
Col1 Col2
xxx xxx
xxx xxx
xxx xxx
findme acg
xxx xxx
findme xxx
In this example I am searching for the word "findme" in column 1 and for the associated word "acg" in column 2. As you can see, row 4 would have to be deleted because both words occur in one row, as opposed to e.g. row 6, where this is not the case.
My final code:
Sub xxx()
Dim aCell As Range, bCell As Range, aSave As String
Dim fndOne As String, fndTwo As String
fndOne = "findme"
fndTwo = "acg"
Dim ws As Worksheet: Set ws = ActiveWorkbook.ActiveSheet
Application.DisplayAlerts = False
Application.ScreenUpdating = False
With ws
Set aCell = .Columns(1).Find(What:=fndOne, LookIn:=xlValues, _
lookat:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not aCell Is Nothing Then
aSave = aCell.Address
Do
If LCase(.Cells(aCell.row, 2).Value) Like Chr(42) & fndTwo & Chr(42) Then
If bCell Is Nothing Then
Set bCell = .Range("A" & aCell.row)
Else
Set bCell = Union(bCell, .Range("A" & aCell.row))
End If
End If
Set aCell = .Columns(1).FindNext(After:=aCell)
Loop Until aCell.Address = aSave
End If
Set aCell = Nothing
If Not bCell Is Nothing Then bCell.EntireRow.Delete
End With
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
If you used the Range.Find method and Range.FindNext method, deleting as you go and checking for matching records after each deletion, you should be able to loop through the possibilities quickly.
'delete rows as they are found
Sub delTwofers()
Dim rw As Long, n As Long, cnt As Long, rng As Range
Dim v As Long, sALLTERMs As String, vPAIRs As Variant, vTERMs As Variant
On Error GoTo bm_SafeExit
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
Debug.Print Timer
sALLTERMs = "aa;bb|cc;dd|ee;ff"
With Worksheets("Sheet1") 'set this worksheet reference properly!
vPAIRs = Split(LCase(sALLTERMs), Chr(124))
For v = LBound(vPAIRs) To UBound(vPAIRs)
vTERMs = Split(vPAIRs(v), Chr(59))
cnt = Application.CountIfs(.Columns(1), Chr(42) & vTERMs(0) & Chr(42), .Columns(2), Chr(42) & vTERMs(1) & Chr(42))
rw = 1
For n = 1 To cnt
rw = .Columns(1).Find(what:=vTERMs(0), lookat:=xlPart, _
after:=.Columns(1).Cells(rw + (rw <> 1)), MatchCase:=False).Row
Do While True
If LCase(.Cells(rw, 2).Value2) Like Chr(42) & vTERMs(1) & Chr(42) Then
.Rows(rw).Delete
Exit Do
Else
rw = .Columns(1).FindNext(after:=.Cells(rw, 1)).Row
End If
Loop
Next n
Next v
End With
Debug.Print Timer
bm_SafeExit:
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
'collect rows with Union, delete them all at once
Sub delTwofers2()
Dim rw As Long, n As Long, cnt As Long, rng As Range
Dim v As Long, sALLTERMs As String, vPAIRs As Variant, vTERMs As Variant
On Error GoTo bm_SafeExit
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
Debug.Print Timer
sALLTERMs = "aa;bb|cc;dd|ee;ff"
With Worksheets("Sheet1") 'set this worksheet reference properly!
vPAIRs = Split(LCase(sALLTERMs), Chr(124))
For v = LBound(vPAIRs) To UBound(vPAIRs)
vTERMs = Split(vPAIRs(v), Chr(59))
cnt = Application.CountIfs(.Columns(1), Chr(42) & vTERMs(0) & Chr(42), .Columns(2), Chr(42) & vTERMs(1) & Chr(42))
rw = 1
For n = 1 To cnt
rw = .Columns(1).Find(what:=vTERMs(0), lookat:=xlPart, _
after:=.Columns(1).Cells(rw), MatchCase:=False).Row
Do While True
If LCase(.Cells(rw, 2).Value2) Like Chr(42) & vTERMs(1) & Chr(42) Then
If rng Is Nothing Then
Set rng = .Cells(rw, 1)
Else
Set rng = Union(rng, .Cells(rw, 1))
End If
Exit Do
Else
rw = .Columns(1).FindNext(after:=.Cells(rw, 1)).Row
End If
Loop
Next n
Next v
End With
Debug.Print Timer 'check timer before deleting discontiguous rows
If Not rng Is Nothing Then _
rng.EntireRow.Delete
Debug.Print Timer
bm_SafeExit:
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
By first checking to make sure there is something to delete, some error control can be avoided; you only need to find the entry for the double matching criteria that you know exists.
Addendum: Deleting a collection of discontiguous rows is time consuming. The second routine (delTwofers2) above was 5% slower that the one that deleted rows as they were found. 25,000 values, 755 random deletions - 3.60 seconds for the first; 3.75 seconds for the latter.
This code applies a filter to the first two columns of the used range using your criteria. It then deletes the visible rows:
Sub DeleteSelected()
Dim RangeToFilter As Excel.Range
Set RangeToFilter = ActiveSheet.UsedRange
With RangeToFilter
.AutoFilter Field:=1, Criteria1:="find me"
.AutoFilter Field:=2, Criteria1:="access granted"
.SpecialCells(xlCellTypeVisible).EntireRow.Delete Shift:=xlUp
End With
End Sub

How to delete all cells that do not contain specific values (in VBA/Excel)

I fully didn't understand how to follow the answer in vba deleting rows that do not contain set values defined in range (I need to use VBA for this). From what I gathered, i need to specify an array, then use some if then stuff.
In my case, I want to create something that will search just a specified column and delete all values that do not contain specific letters/numbers. 1,2,3,4,5,s,f,p,a,b,c,o are the numbers/letters i want to keep. Cells which do not contain these values (even 11 or 1s should be deleted), I want only to delete the cell (not the whole row) and shift the cells below it up (i believe you can do this with the default .delete command).
For example my columns look like this:
p
a
1
2
5
s
f
s
8
31
4
f
I want to screen my data so that all blank cells and all cells which do not contain the numbers or letter mentioned above (e.g. 31 and 8 in this case) are automatically deleted.
Thanks for your help!
Sub Tester()
Dim sKeep As String, x As Long
Dim rngSearch As Range, c As Range
'C1:C5 has values to keep
sKeep = Chr(0) & Join(Application.Transpose(Range("C1:C5").Value), _
Chr(0)) & Chr(0)
Set rngSearch = Range("A1:A100")
For x = rngSearch.Cells.Count To 1 Step -1
Set c = rngSearch.Cells(x)
If InStr(sKeep, Chr(0) & c.Value & Chr(0)) = 0 Then
c.Delete shift:=xlShiftUp
End If
Next x
End Sub
This will do
Sub Main()
Dim dontDelete
dontDelete = Array("1", "2", "3", "4", "5", "s", "f", "p", "a", "b", "c", "o")
Dim i As Long, j As Long
Dim isThere As Boolean
For i = Range("A" & Rows.Count).End(xlUp).Row To 1 Step -1
For j = LBound(dontDelete) To UBound(dontDelete)
If StrComp(Range("A" & i), dontDelete(j), vbTextCompare) = 0 Then
isThere = True
End If
Next j
If Not isThere Then
Range("A" & i).Delete shift:=xlUp
End If
isThere = False
Next i
End Sub
Sub DeleteValues()
Dim x As Integer
Dim i As Integer
Dim Arr(1 To 3) As String
Arr(1) = "1"
Arr(2) = "2"
Arr(3) = "3"
Range("A1").Select
For x = 1 To 10
For i = 1 To 3
If ActiveCell.Value = Arr(i) Then
ActiveCell.Delete
End If
Next i
ActiveCell.Offset(1, 0).Select
Next x
End Sub
This will loop through range("a1:a10") and delete any cell where the value = any of the array values (1,2,3)
You should hopefully be able to work with this code and suit it to your needs?
Another way :) Which doesn't delete the cells in a loop.
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim rngDEL As Range
Dim strDel As String
Dim arrDel
Dim i As Long
strDel = "1,11,Blah" '<~~ etc... You can pick this from a range as well
arrDel = Split(strDel, ",")
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws.Columns(1) '<~~ Change this to the relevant column
For i = LBound(arrDel) To UBound(arrDel)
.Replace What:=arrDel(i), Replacement:="", LookAt:=xlWhole, SearchOrder:= _
xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
Next i
On Error Resume Next
Set rngDEL = .Cells.SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
If Not rngDEL Is Nothing Then rngDEL.Delete Shift:=xlShiftUp
End With
End Sub

Resources