how to delete row when multiple criteria is selected - excel

Hi i have below code which delete the rows when it finds particular single criteria from multiple sheets i want to modify the code with multiple criteria
Sub DeleteRow_IMPLEMENTATION()
Dim Header As Range
Dim FoundCell As Range
Dim ws As Worksheet
Dim HeaderToFind As String
Dim ValueToFind As String
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
HeaderToFind = "BankName"
ValueToFind = "abcd"
For Each ws In Worksheets
Set Header = ws.Rows(1).Find(what:=HeaderToFind, LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=True)
If Not Header Is Nothing Then
Set FoundCell = ws.Columns(Header.Column).Find(what:=ValueToFind, LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=True)
Do While Not FoundCell Is Nothing
ws.Rows(FoundCell.Row).delete
Set FoundCell = Nothing
Set FoundCell = ws.Columns(Header.Column).Find(what:=ValueToFind, LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=True)
Loop
End If
Next ws
Application.ScreenUpdating = True
Application.DisplayStatusBar = True
End Sub
i tried something like below
HeaderToFind = "BankName"
ValueToFind = "abcd,xyz "
when i tried its not working any help is appreciated.

Try setting the value you are trying to find in an array instead of a comma seperated string. then foreach value in the array: set ValueToFind equal to the value, and call this code
HeaderToFind = "BankName"
Dim targetValues = New String { "abcd", "xyz" }
For Each targetVal In targetValues
ValueToFind = targetVal
For Each ws In Worksheets
....
Next ws
Next targetVal
Alternatively, you can check out this:
Efficient way to delete entire row if cell doesn't contain '#'
and set the criteria to your array of values

Related

.FindNext keeps returning to the first match, instead of the next

I have a SourceFile.xlsm that contains an X number of field definitions and their contents:
I want to put the contents of these fields into a TargetFile.xlsx, that may contain 0 or more of those field definitions:
The expected end result would be this:
But the actual end result is always this:
And that is because this line in the code below:
Set source_range = sourceSheet.Cells.FindNext(source_range)
always keeps coming back to the first occurrence (cell B5, containing "[Field 1]"), instead of the next (cell B6, containing "[Field 2]"):
Function CopyFromSourceToTarget()
Dim sourceWB As Workbook
Dim targetWB As Workbook
Dim sourceSheet As Worksheet
Dim targetSheet As Worksheet
Dim source_range As Range
Dim target_range As Range
Dim FirstFound_source As String
Dim FirstFound_target As String
Set sourceWB = ActiveWorkbook
Set targetWB = Workbooks.Open("C:\TEMP\TargetFile.xlsx")
For Each sourceSheet In sourceWB.Worksheets
Set source_range = sourceSheet.Cells.Find("[", LookIn:=xlValues)
If Not source_range Is Nothing Then
FirstFound_source = source_range.Address
Debug.Print source_range.Value
Do
sourceWB.Activate
source_range.Select
For Each targetSheet In targetWB.Worksheets
Set target_range = targetSheet.Cells.Find(source_range.Value, LookIn:=xlValues)
If Not target_range Is Nothing Then
FirstFound_target = target_range.Address
Do
target_range.FormulaR1C1 = CStr(source_range.Offset(0, 1).Value)
Set target_range = targetSheet.Cells.FindNext(target_range)
If target_range Is Nothing Then Exit Do
Loop Until target_range.Address = FirstFound_target
End If
Next
Set source_range = sourceSheet.Cells.FindNext(source_range)
Debug.Print source_range.Value
Loop Until source_range.Address = FirstFound_source
End If
Next
End Function
I've tried several options, but all to no avail. Hopefully, someone here can help me along, because this seemingly very simple issue is driving me nuts.
Instead of this line:
Set source_range = sourceSheet.Cells.FindNext(source_range)
try this line:
Set source_range = sourceSheet.Cells.Find(What:="[", After:=source_range, LookIn:=xlValues)
I'd also add some more options to the Find like LookAt:= xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False, but it might not be necessary. Up to you.

Modify Loop to include 3 strings

I have the following code I use to go through a sheet and parse the information onto separate sheets based on the string [Start].
Private Sub CommandButton7_Click()
Application.ScreenUpdating = False
Dim i As Long, rFind As Range, rFind1 As Range, rFind2 As Range, rFind3 As Range, rFind4 As Range, ws As Worksheet, s As String, s1 As String, s2 As String
s = "[Start]"
With Sheets("Full History File").Columns(1)
Set rFind3 = .Find(What:="[HistoryEnd]", LookAt:=xlPart, MatchCase:=False, SearchFormat:=False)
Set rFind = .Cells(Rows.Count, 1)
For i = 1 To WorksheetFunction.CountIf(.Cells, "*" & s & "*")
Set rFind = .Find(What:=s, After:=rFind, LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
If Not rFind Is Nothing Then
Set rFind1 = .Find(What:=s, After:=rFind)
Set ws = Worksheets.Add(After:=Sheets(Sheets.Count))
ws.Name = "Blasted " & i
If i = WorksheetFunction.CountIf(.Cells, "*" & s & "*") Then
Set rFind1 = rFind2.Offset(1)
End If
Range(rFind, rFind1.Offset(-1)).Copy ws.Range("A1")
End If
Next i
End With
Sheets("Blast Summary Sheet").Select
SheetNames
CommandButton6.Visible = True
Application.ScreenUpdating = True
End Sub
My problem is that the information I am working through has changed and I need to adapt the code to do the following:
Search for the string [TrainingModeChanged]
If not found search for the string [TrainingMode]
If not found search for the string [Start]
Once any of the strings are found create the new sheet Blasted with the number and copy the information between the found string up until the next found string which could be either one of the 3 above.
All help in modify the code to do this would be helpfull thanks
I am not entirely sure what you are after, but you could write a function that returns your required string instead of hardcoding it. Function below:
Option Explicit
Function getString() As String
'we will use On Error Resume Next to by pass the expected error if cannot find the string
On Error Resume Next
Dim searchRng As Range
Dim mySheet As Worksheet
Set mySheet = ThisWorkbook.Sheets("Full History File")
'search for first range
Set searchRng = mySheet.Columns(1).Find(What:="[TrainingModeChanged]", LookIn:=xlValues, LookAt:=xlWhole)
If Not searchRng Is Nothing Then
'this means search range was found
getString = searchRng.Value
'reset error handling
On Error GoTo 0
Exit Function
End If
'implicit to say if program runs here first search was unsuccessful
Set searchRng = mySheet.Columns(1).Find(What:="[TrainingMode]", LookIn:=xlValues, LookAt:=xlWhole)
If Not searchRng Is Nothing Then
'this means search range was found
getString = searchRng.Value
On Error GoTo 0
Exit Function
End If
'implicit to say if program runs here second search was unsuccessful
Set searchRng = mySheet.Columns(1).Find(What:="[Start]", LookIn:=xlValues, LookAt:=xlWhole)
If Not searchRng Is Nothing Then
'this means search range was found
getString = searchRng.Value
On Error GoTo 0
Exit Function
End If
End Function
And you call in your routine as:
s = getString()
And then continue on with your code..

How do I get the Cell Address from a Variable VBA

I created a variable oldPassword which is populated using a VLookup.
I am trying to get now the cell address from that result but nothing seem to work.
Dim oldPassword As String
oldPassword = Application.WorksheetFunction.VLookup(Me.ComboBox1.Value, Worksheets("Employees").Range("A:B"), 2, False)
You should break the task into steps
Get a reference to the cell containing the search value
Use that reference to get the required value and address
Sub Demo
Din rSearch As Range
Dim rUser as Range
Dim rPassword As Range
Dim idx As Variant
Set rSearch = Worksheets("Employees").Range("A:B")
idx = Application.Match(Me.ComboBox1.Value, rSearch.Columns(1), 0)
If Not IsError(idx) Then
Set rUser = rSearch.Cells(idx, 1)
Set rPassword = rUser.Cells(1, 2)
' get the result
oldPassword = rPassword.Value2
' get the address
Debug.Print rPassword.Address
End If
End Sub
I would prefer using .Find as #Andreas suggested but then that is my personal preference.
Option Explicit
Sub Sample()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Employees")
Dim aCell As Range
Set aCell = ws.Columns(1).Find(What:=ComboBox1.Value, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
Dim oldPassword As String
If Not aCell Is Nothing Then
With aCell.Offset(, 1)
'~~> Do what you want with that cell
oldPassword = .Value2
MsgBox .Address
End With
Else '<~~ Optional
MsgBox ComboBox1.Value & " not found!"
End If
End Sub

Expand selection based on cell value and split the expanded selection into a separate file

I've been struggling with this for a while now.
A1:O7 are frozen columns.
Only the Column A contains trigger values that I find using
Dim Cell As Range
Columns("A:A").Select
Set Cell = Selection.Find(What:="BANK:", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=True, SearchFormat:=False)
After that I need to expand the selection so that all the rows and the columns to the right and down from the cell found until the next cell to be found are copied and split into a separate file along with the frozen columns A1:O7 at the top. The range is A7:Oxxxx. There is no data beyond the O column.
Is there a solution to this without using any Excel add-ons?
I tried to understand the task. There are some information missing so this solution might not exactly fitting your needs. I hope it will work for you.
Private Sub Bank()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Bank") 'change according to your workingsheet
Dim rngHeader As Range
Set rngHeader = ws.Range("A1:O7")
Dim iWidth As Integer 'Data and header width
iWidth = rngHeader.Columns.Count
Dim strSearchText As String
strSearchText = "BANK:"
Dim rngSearchArea As Range
Set rngSearchArea = ws.Range(Range("A7"), ws.Range("A" & ws.Range("A:A").Cells.Count).End(xlUp))
Dim strFirstFound As String
Dim rngCurrentFound As Range
Set rngCurrentFound = ws.Range("A7")
Set rngCurrentFound = rngSearchArea.Find(What:=strSearchText, After:=rngCurrentFound, LookIn:=xlFormulas, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=True, SearchFormat:=False)
If rngCurrentFound Is Nothing Then
MsgBox "Nothing found"
Exit Sub
End If
strFirstFound = rngCurrentFound.Address
Dim rngSource As Range
Dim rngNextFound As Range
Do
'Get the position of the next occurence to set the end position
Set rngNextFound = rngSearchArea.FindNext(rngCurrentFound)
If rngNextFound.Row > rngCurrentFound.Row Then
'There is next one
Set rngSource = Range(rngCurrentFound, rngNextFound.Offset(-1)).Resize(, iWidth)
Else
'It was the last one
'If there are data in column A below the last BANK: use the next line
'Set rngSource = ws.Range(rngCurrentFound, Cells(ws.Range("A" & ws.Range("A:A").Cells.Count).End(xlUp), iWidth))
'Use this one to select until the last used cell in the worksheet
Set rngSource = ws.Range(rngCurrentFound, ws.UsedRange.Cells(ws.UsedRange.Cells.Count))
End If
'rngSource.Select
Call Bankcopy(rngSource, rngHeader)
Set rngCurrentFound = rngSearchArea.FindNext(rngCurrentFound)
Loop While rngCurrentFound.Address <> strFirstFound
End Sub
Private Sub Bankcopy(rngSource As Range, ByVal rngHeader As Range)
'Create new book and copy headers
Dim wbNewBook As Workbook
Set wbNewBook = Workbooks.Add()
Dim wsNewSheet As Worksheet
Set wsNewSheet = wbNewBook.Worksheets(1)
Dim rngTarget As Range
'Copy header
Set rngTarget = wsNewSheet.Range("A1") 'To header left upper
rngHeader.Copy
rngTarget.PasteSpecial xlPasteValues
rngTarget.PasteSpecial xlPasteFormats
Application.CutCopyMode = False
'Copy data
Set rngTarget = wsNewSheet.Range("A8") 'Data left upper
rngSource.Copy
rngTarget.PasteSpecial xlPasteValues
rngTarget.PasteSpecial xlPasteFormats
Application.CutCopyMode = False
'MsgBox "Test Stop"
'wbNewBook.Close
End Sub

Find string, change color across all Excel Worksheets

search entire Excel workbook for text string and highlight cell appears to be exactly what I need but I can't get it to work on my Excel workbook. I have hundreds of rows across 10 worksheets. All searched-for Strings (Packet 01, Packet 02, Packet 03, etc) would be in B:8 to row-end on worksheet(1) and B:7 to row-end on the other 9 worksheets (Worksheets are named and the InputBox result for the string would need to be case-sensitive). 45547221 indicates interior color change, but there would be too much color with all strings having cells in different colors, thus changing the string color would be better using font.color.index. Trying the 45547221 code as-is finds it skipping the Do/Loop While code when in step mode.
I would modify the code in 45547221 by adding at a minimum:
Dim myColor As Integer
myColor = InputBox("Enter Color Number (1-56)")
(Configured so I can enter up to 5 FindStrings and 5 ColorIndex numbers as Dim with InputBox(es))
In the Do/Loop While I would change .ColorIndex = myColor
I would like to get this code working as it seems to fit my needs - modified to find string instances across workbook and re-color string instead of cell interior colors and (2) get it to recognize the Do/Loop While code which it isn't now but would apply the ColorIndex number to each string.
Public Sub find_highlight()
'Put Option Explicit at the top of the module and
'Declare your variables.
Dim FindString As String
Dim wrkSht As Worksheet
Dim FoundCell As Range
Dim FirstAddress As String
Dim MyColor As Integer 'Added this
FindString = InputBox("Enter Search Word or Phrase")
MyColor = InputBox("Enter Color Number")
'Use For...Each to cycle through the Worksheets collection.
For Each wrkSht In ThisWorkbook.Worksheets
'Find the first instance on the sheet.
Set FoundCell = wrkSht.Cells.Find( _
What:=FindString, _
After:=wrkSht.Range("B1"), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
'Check it found something.
If Not FoundCell Is Nothing Then
'Save the first address as FIND loops around to the start
'when it can't find any more.
FirstAddress = FoundCell.Address
Do
With FoundCell.Font 'Changed this from Interior to Font
.ColorIndex = MyColor
'.Pattern = xlSolid
'.PatternColorIndex = xlAutomatic 'Deactivated this
End With
'Look for the next instance on the same sheet.
Set FoundCell = wrkSht.Cells.FindNext(FoundCell)
Loop While FoundCell.Address <> FirstAddress
End If
Next wrkSht
End Sub
EDIT: This worked for me on your sample data, using a partial match so you can enter (eg) "Packet 03" and still match.
I like to split out the "find all" function into a separate function: it makes the rest of the logic easier to follow.
Public Sub FindAndHighlight()
Dim FindString As String
Dim wrkSht As Worksheet
Dim FoundCells As Range, FoundCell As Range
Dim MyColor As Integer 'Added this
Dim rngSearch As Range, i As Long, rw As Long
FindString = InputBox("Enter Search Word or Phrase")
MyColor = InputBox("Enter Color Number")
'Cycle through the Worksheets
For i = 1 To ThisWorkbook.Worksheets.Count
Set wrkSht = ThisWorkbook.Worksheets(i)
rw = IIf(i = 1, 8, 7) '<<< Row to search on
' row 8 for sheet 1, then 7
'set the range to search
Set rngSearch = wrkSht.Range(wrkSht.Cells(rw, "B"), _
wrkSht.Cells(Rows.Count, "B").End(xlUp))
Set FoundCells = FindAll(rngSearch, FindString) '<< find all matches
If Not FoundCells Is Nothing Then
'got at least one match, cycle though and color
For Each FoundCell In FoundCells.Cells
FoundCell.Font.ColorIndex = CInt(MyColor)
Next FoundCell
End If
Next i
End Sub
'return a range containing all matching cells from rng
Public Function FindAll(rng As Range, val As String) As Range
Dim rv As Range, f As Range
Dim addr As String
'partial match...
Set f = rng.Find(what:=val, after:=rng.Cells(rng.Cells.CountLarge), _
LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=True) 'case-sensitive
If Not f Is Nothing Then addr = f.Address()
Do Until f Is Nothing
If rv Is Nothing Then
Set rv = f
Else
Set rv = Application.Union(rv, f)
End If
Set f = rng.FindNext(after:=f)
If f.Address() = addr Then Exit Do
Loop
Set FindAll = rv
End Function

Resources