find in column distinguishing between empty and blank cells - excel

I need to find the first cell in a column that's either empty or contains only blanks. I came up with the following..
Dim FindString As String
Dim Rng As Range
Dim Done As Boolean
FindString = ""
With Sheets("Yahoo").Range("A:A")
Set Rng = .Find(What:=FindString, _
After:=.Cells([Stock_Start_Row], 1), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
j = Rng.Row
Done = False
Do Until Done
FindString = .Cells(j, 1)
FindString = Replace(FindString, " ", "")
If FindString = "" Then
j = j - 1
Else
Done = True
End If
Loop
MsgBox "Found" & " " & Rng.Row & " " & j
Else
MsgBox "Nothing found"
End If
End With
This will discover and clear any blank cells immediately before the first empty cell but will not discover blank cells among the preceding cells.
Is there any way to search for cells containing one or more blanks?
If so I could add a second search.

I need to find the first cell in a column that's either empty or
contains only blanks.
This will go through column A on sheet("Yahoo"). It should work for you:
Sub FindBlankOrEmptyCells()
Dim wbk As Workbook
Set wbk = ThisWorkbook
Dim ws As Worksheet
Set ws = wbk.Sheets(1)
Dim cell As Range
Dim BlankCounter As Integer
Dim i As Integer
Dim OldCellValue As Variant ' just for the heck of it
For Each cell In Sheets("Yahoo").Range("A:A")
OldCellValue = cell.Value
cell.NumberFormat = "#"
cell.Value = "'" & cell.Value
BlankCounter = 0
If cell.Value = "" Then
MsgBox "Found an empty cell in Column A, Row: " & " " & cell.Row
Exit Sub
End If
For i = 1 To Len(cell)
If cell.Characters(i, 1).Text = " " Then
BlankCounter = BlankCounter + 1
End If
If BlankCounter = Len(cell) Then
MsgBox "Found a cell full of blanks in Column A, Row: " & " " & cell.Row
cell.Clear
cell.Value = OldCellValue
cell.Value = cell.Value
Exit Sub
' If you want to delete the contents of the cell or continue looping you can delete this Exit Sub and put in:
' cell.ClearContents
' then it will loop through all the cells and delete blanks and message you each time
End If
Next i
cell.Clear
cell.Value = OldCellValue
cell.Value = cell.Value
Next cell
End Sub
This will find the first cell that is either empty or contains only blanks(spaces). It will stop once it finds a cell that meets that criteria. If you want to continue looping you can enable the code I commented out. Let me know how it works.
EDIT:
If you want to use the .find function to gain some efficiency that is possible - but eventually you are going to need to loop through all the characters in a cell and determine if it contains all spaces. Try this one out(I stopped it at row 30 so it doesn't keep popping up messages for blanks - but you could remove the messages and extend to Loop Until to row 999999):
Sub FindBlankOrEmptyCellsWithFindFunction()
Dim FindString As String
Dim Rng As Range
Set Rng = Sheets("Yahoo").Range("A1")
Dim Done As Boolean
Dim wbk As Workbook
Set wbk = ThisWorkbook
Dim ws As Worksheet
Set ws = wbk.Sheets(1)
Dim cell As Range
Dim BlankCounter As Integer
Dim i As Integer
Dim ii As Integer
Dim LoopStopperRange As Range
Dim OldCellValue As Variant
ii = 0
Do
ii = ii + 1
FindString = " "
With Sheets("Yahoo").Range("A:A")
Set Rng = .Find(What:=FindString, _
After:=.Cells(Rng.Row, 1), _
LookIn:=xlValues, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then ' If Rng Is Something Then
If ii = 1 Then
Set LoopStopperRange = Rng
End If
If LoopStopperRange = Rng And ii > 1 Then
Exit Do
End If
For Each cell In Rng
OldCellValue = cell.Value
cell.NumberFormat = "#"
cell.Value = "'" & cell.Value
BlankCounter = 0
If cell.Value = "" Then
MsgBox "Found an empty cell in Column A, Row: " & " " & cell.Row
'Exit Sub
End If
For i = 1 To Len(cell)
If cell.Characters(i, 1).Text = " " Then
BlankCounter = BlankCounter + 1
End If
If BlankCounter = Len(cell) Then
MsgBox "Found a cell full of blanks in Column A, Row: " & " " & cell.Row
cell.Clear
cell.Value = OldCellValue
cell.Value = cell.Value
'Exit Sub
' If you want to delete the contents of the cell or continue looping you can delete this Exit Sub and put in:
' cell.ClearContents
' then it will loop through all the cells and delete blanks
End If
Next i
cell.Clear
cell.Value = OldCellValue
cell.Value = cell.Value
Next cell
Else
End If
End With
Loop Until Rng Is Nothing
Set Rng = Sheets("Yahoo").Range("A1")
Do
ii = ii + 1
FindString = ""
With Sheets("Yahoo").Range("A:A")
Set Rng = .Find(What:=FindString, _
After:=.Cells(Rng.Row, 1), _
LookIn:=xlValues, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then ' If Rng Is Something Then
For Each cell In Rng
OldCellValue = cell.Value
cell.NumberFormat = "#"
cell.Value = "'" & cell.Value
BlankCounter = 0
If cell.Value = "" Then
MsgBox "This loop will go until Row 30 so you don't have to pause/break out. Found an empty cell in Column A, Row: " & " " & cell.Row
'Exit Sub
End If
Next cell
Else
End If
End With
Loop Until Rng.Row = 30
'Loop Until Rng.Row = 99999
End Sub
Good Luck.

Related

Finding Cells With Only Spaces

I am trying to find any cells with just spaces in. When I run this though it finds cells that are blanks too. Is there anyway to just find cells with spaces?
For i = 1 to lastRow
If len(trim(this workbook.sheets("data").range("a" & i)) = 0 then
Msgbox("a" & i " contains only space")
End if
Next i
Plase, try:
Sub testFindSpaces()
Dim wsD as Worksheet, i As Long, x As String, lastRow As Long
Set wsD = ThisWorkbook.Sheets("data")
lastRow = wsD.Range("A" & wsD.rows.count).End(xlUp).row
For i = 1 To lastRow
x = wsD.Range("a" & i).Value
If UBound(Split(x, " ")) = Len(x) Then
MsgBox "a" & i & " contains only space"
End If
Next i
End Sub
Just exclude blanks by testing for Len(ThisWorkbook.Worksheets("data").Range("A" & i)) <> 0 too.
For i = 1 to lastRow
Dim Untrimmed As String
Untrimmed = ThisWorkbook.Worksheets("data").Range("A" & i).Value
If Len(Trim(Untrimmed) = 0 AND Len(Untrimmed) <> 0 then
Msgbox "a" & i & " contains only space"
End if
Next i
Alternativeley use ThisWorkbook.Worksheets("data").Range("A" & i).Value <> vbNullString to exclude blanks
For i = 1 to lastRow
Dim Untrimmed As String
Untrimmed = ThisWorkbook.Worksheets("data").Range("A" & i).Value
If Len(Trim(Untrimmed) = 0 AND Untrimmed <> vbNullString then
Msgbox "a" & i & " contains only space"
End if
Next i
Just to add alternatives:
With ThisWorkbook.Sheets("data").Range("A" & i)
If .Value Like "?*" And Not .Value Like "*[! ]*" Then
MsgBox ("A" & i & " contains only space")
End If
End With
You may also just create a new regex-object and use pattern ^ +$ to validate the input.
If you don't want to loop the entire range but beforehand would like to exclude the empty cells you could (depending on your data) use xlCellTypeConstants or the numeric equivalent 2 when you decide to use SpecialCells() method and loop the returned cells instead:
Dim rng As Range, cl As Range
Set rng = ThisWorkbook.Worksheets("Data").Range("A:A").SpecialCells(2)
For Each cl In rng
If Not cl.Value Like "*[! ]*" Then
MsgBox ("A" & cl.Row & " contains only spaces")
End If
Next cl
You may also no longer need to find your last used row, but note that this may error out if no data at all is found in column A.
A last option I just thought about is just some concatenation before validation:
For i = 1 To lastRow
If "|" & Trim(ThisWorkbook.Sheets("data").Range("A" & i).value & "|" = "| |" Then
MsgBox ("A" & i & " contains only space")
End If
Next
Macro to get a string of address of cells containing only space using Evaluate VBA function
Edited code below - As suggested by #VBasic2008 and #T.M. in the comments below.
Option Explicit
Sub Cells_with_Space_Only()
Dim ws As Worksheet
Set ws = Sheets("Sheet2")
'Macro to get a string of address of cells containing only space
'https://stackoverflow.com/questions/68891170/finding-cells-with-only-spaces
Dim rngArr, rngStr As String, i As Long, rng As Range
rngArr = Evaluate("IFERROR(ADDRESS((ISBLANK(" & ws.UsedRange.Address(External:=True) & _
")=FALSE)*(" & ws.UsedRange.Address(External:=True) & _
"=REPT("" "",LEN(" & ws.UsedRange.Address(External:=True) & _
")))*ROW(" & ws.UsedRange.Address(External:=True) & _
"),COLUMN(" & ws.UsedRange.Address(External:=True) & ")),""**"")")
rngStr = ""
'If number of columns in usedrange are less then loop with
'For i = 1 To ActiveSheet.UsedRange.Columns.Count
For i = 1 To ws.UsedRange.Rows.Count
'if looped with For i = 1 To ActiveSheet.UsedRange.Columns.Count
'rngStr = Join(Filter(Application.Transpose(Application.Index(rngArr, 0, i)) _
, "**", False, vbBinaryCompare), ",")
rngStr = Join(Filter(Application.Index(rngArr, i, 0) _
, "**", False, vbBinaryCompare), ",")
If rngStr <> "" Then
If rng Is Nothing Then
Set rng = Range(rngStr)
Else
Set rng = Union(rng, Range(rngStr))
End If
End If
Next i
Debug.Print rng.Address
End Sub
The macro returns a string for the sample data in the image below --
$D$1,$A$2,$F$2,$B$3,$E$4,$A$6,$F$6,$E$7,$B$8,$D$9,$C$10,$F$10,$A$11,$D$13,$F$13,$E$14,$A$16,$E$16,$D$17,$F$17:$F$18
Array formula in the worksheet -
=IFERROR(ADDRESS((ISBLANK($A$1:$F$18)=FALSE)*($A$1:$F$18=REPT(" ",LEN($A$1:$F$18)))*ROW($A$1:$F$18),COLUMN($A$1:$F$18)),"**")
Clear Solo Spaces
Couldn't think of any reason for doing this other than for clearing the cells containing only spaces.
Option Explicit
Sub ClearSoloSpaces()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet: Set ws = wb.Worksheets("Data")
Dim srg As Range ' Source Range
Set srg = ws.Range("A1", ws.Cells(ws.Rows.Count, "A").End(xlUp))
Dim crg As Range ' Clear Range
Dim cCell As Range ' Current Cell in Source Range
Dim cString As String ' Current Cell's Value Converted to a String
For Each cCell In srg.Cells
cString = CStr(cCell.Value)
If Len(cString) > 0 Then
If Len(Trim(cString)) = 0 Then
If crg Is Nothing Then
Set crg = cCell
Else
Set crg = Union(crg, cCell)
End If
End If
End If
Next cCell
If crg Is Nothing Then
MsgBox "No cells containing only spaces found.", _
vbInformation, "Clear Solo Spaces"
Else
Dim Msg As Long
Msg = MsgBox("The cells in the rows '" _
& Replace(crg.Address, "$A$", "") _
& "' of column 'A' contain only spaces." & vbLf _
& "Do you want to clear them?", _
vbInformation + vbYesNo, "Clear Solo Spaces")
If Msg = vbYes Then
crg.Clear ' or crg.ClearContents ' to preserve formatting
End If
End If
End Sub
Just for the sake of showing alternatives (#T.M.), please test the next one, too:
Private Sub testFindSpacesBis()
Dim wsD As Worksheet, i As Long, x As String, lastRow As Long
Set wsD = ActiveSheet ' ThisWorkbook.Sheets("data")
lastRow = wsD.Range("A" & wsD.rows.count).End(xlUp).row
For i = 1 To lastRow
x = wsD.Range("a" & i).Value
If StrComp(x, space(Len(x)), vbBinaryCompare) = 0 Then
MsgBox "a" & i & " contains only spaces"
End If
Next i
End Sub

How to copy the contents of two cells dynamically?

Right now my program works. But, I need to copy another cell that's next to the cell being copied when a match is found. I go through myrange1 and when I find a match in myrange2, I copy the contents from Column A in Sheet1 from whichever cell it's at. I want column B, same cell index, to be copied and pasted as well. My copied data is getting pasted in Column(s) R:S. of Sheet2. Column R is the numbers and S is the data.
Sub matchcopy()
Dim i&
Dim myrange1 As Range, myrange2 As Range, myrange3 As Range, cell As Range
' You can use the Codenames instead of Worksheet("Sheet1") etc.
Set myrange1 = Sheet1.Range("A1", Sheet1.Range("A" & Rows.Count).End(xlUp))
Set myrange2 = Sheet2.Range("A1", Sheet2.Range("A" & Rows.Count).End(xlUp))
Set myrange3 = Sheet2.Range("B1", Sheet2.Range("B" & Rows.Count).End(xlUp))
Sheet2.Range("R:S") = "" ' <~~ clear result columns
For Each cell In myrange1 ' presumably unique items
If Not IsError(Application.Match(cell.Value, myrange2, 0)) Then
'Sheet2.Cells(i, 2).Offset(, 1).Resize(1, 1).Copy
cell.Copy
With Sheet2.Range("R50000").End(xlUp)
i = i + 1 ' <~~ counter
.Offset(1, 0) = i ' counter i equals .Row - 1
.Offset(1, 1).PasteSpecial xlPasteFormulasAndNumberFormats
End With
Else
'MsgBox "no match is found in range"
End If
Next cell
Sheet2.Columns("R:S").EntireColumn.AutoFit
Call Set_PrintRnag
End Sub
Sub Set_PrintRnag()
Dim LstRw As Long
Dim Rng As Range
Dim strDesktop As String
Application.ScreenUpdating = True
strDesktop = CreateObject("WScript.Shell").SpecialFolders("Desktop")
LstRw = Sheet2.Cells(Rows.Count, "R").End(xlUp).Row
Set Rng = Sheet2.Range("R1:S" & LstRw)
With Sheet2.PageSetup
.LeftHeader = "&C &B &20 Cohort List Report:" & Format(Now, "mm/dd/yyyy")
.CenterFooter = "Page &P of &N"
.CenterHorizontally = False
.FitToPagesWide = 1
.RightFooter = ""
End With
Rng.ExportAsFixedFormat Type:=xlTypePDF, Filename:=strDesktop & "\CohortList " & " " & Format(Date, "mm-dd-yyyy") & ".pdf", Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=True
End Sub
https://learn.microsoft.com/en-us/office/vba/api/excel.range.offset
You have a cell in column 'A' BUT you want same row in column 'B'.
cell.Offset(0,1).value = cell.value

Select and copy specific cells

I have an excel sheet that I want to select some cells based on their values then copy these cells to another sheet using VBA.
I have a chunk of code that go through all the excel sheetd and search for a specific value then return the total of this cells.
I need to copy right now just the cells in column H that have values "name" & "contact" and copy all these values to the sheet2 in the same workbook.
Then I to copy the cells that are next to the name and contact.
The end result is a new table that contain 2 columns name and contact and under each column the values of each name and contact that belong to it
Sample Data
Scan:
Private Sub CommandButton1_Click()
row_number = 4
count_of_str = 0
Do
DoEvents
row_number = row_number + 1
item_in_review = Sheets("Sheet1").Range("H" & row_number)
If InStr(item_in_review, "name") Then
count_of_str = count_of_str + 1
End If
Loop Until item_in_review = ""
MsgBox "the str occured: " & count_of_str & " times."
End Sub
Utilise the Find / FindNext methods
It's not entirely clear which columns your data is in. I have assumed the labels name and contact are in H, and the actual data in I
Also, I have assumed that every name will have a contact, and have not included any checks for that.
Sub Demo()
Dim row_number As Long, count_of_str As Long
Dim rToSearch As Range, rFound As Range, rng As Range
Dim strSearchTerm As String
Dim FirstAddr As String
Dim ws As Worksheet, rDest As Range
Dim cl As Range, ar As Range
strSearchTerm = "name"
With Sheets("Sheet1")
Set rToSearch = .Range(.Cells(5, 8), .Cells(.Rows.Count, 8).End(xlUp))
End With
Set rng = rToSearch.Find( _
What:=strSearchTerm, _
After:=rToSearch.Cells(rToSearch.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False, _
SearchFormat:=False)
If Not rng Is Nothing Then
FirstAddr = rng.Address
Do
count_of_str = count_of_str + 1
If rFound Is Nothing Then
Set rFound = rng.Offset(0, 1)
Else
Set rFound = Union(rFound, rng.Offset(0, 1))
End If
Set rng = rToSearch.FindNext(rng)
Loop Until rng.Address = FirstAddr
End If
MsgBox "the str occured: " & count_of_str & " times."
' rFound now refers to all found cells
' Copy to somewhere
Set ws = Worksheets("YourDestinationSheet") '<~~Update as required
Set rDest = ws.Range("YourDestinationRange") '<~~Update as required
If Not rFound Is Nothing Then
rFound.Copy rDest '<~~ copy names
rFound.Offset(1, 0).Copy rDest.Offset(0, 1) '<~~ copy contacts
End If
' Process found cells
' eg
If Not rFound Is Nothing Then
For Each ar In rFound.Areas
For Each cl In ar.Cells
Debug.Print cl.Address
Next cl, ar
End If
End Sub
Untested:
Private Sub CommandButton1_Click()
Dim count_of_str As Long
Dim c as Range, d As Range
count_of_str = 0
Set c = Sheets("Sheet1").Range("H4") 'cell to check
Set d = Sheets("Sheet2").Range("A2") 'destination to copy to
Do While Len(c.Value) > 0
If InStr(c.Value, "name") > 0 Then
count_of_str = count_of_str + 1
c.Copy d
Set d = d.Offset(1, 0) 'next destination row
End If
Set c = c.Offset(1, 0) 'next cell to check
Loop
MsgBox "the str occured: " & count_of_str & " times."
End Sub

Store cell in range, and then delete in 1 go

i have created the following code, it aims at delete the empty cell in column R that exists between data, the problem comes to how to store the blank cell in range, any advise?
Sub Macro1()
Dim lastRow_1 As Long
Dim counter_1 As Long
Dim rng_1 As Range, aCell As Range
lastRow_1 = Range("R" & Rows.Count).End(xlUp).Row
MsgBox lastRow_1
counter_1 = 1
For counter_1 = 1 To lastRow_1
If Trim(Range("R" & counter_1).Value) = "" Then
Set aCell = Range("R" & counter_1)
rng_1 = Union(rng_1, aCell)
End If
Next
rng_1.Delete xlUp
End Sub
Assuming R200 is the last cell in the range
range("R1:R200").SpecialCells(xlCellTypeBlanks).Delete

Filter to determain cells to be copied, now copies the last found criteria

I'm having troubles with the output of my code. Im using a macro to search for some criteria which are labeled:
Collection = Trim(Range("lblImportCollection").Value)
System = Trim(Range("lblImportSystem").Value)
Tag = Trim(Range("lblImportTag").Value)
My filter does search the right cell values where the input values are found, but I want to copy the matched values to a new sheet. Now it just copies the last correct value that is found. Can someone help me with it? What I want:
If all three criteria match( I want to copy the 3 criteria in a row on the new worksheet)
If two criteria match( I want to copy the 2 criteria in a row(and not the third one)
If one criteria match( I want to copy the 1 criteria in a row(so not the second and the third)
Also: All resulting matches must fill a new row.
I hope I gave enough information, it's a bit hard to explain. If you have questions, let me know :)
Sub FilterButton()
Dim XUsedRange As Range
Dim SourceRange As Range, DestRange As Range
Dim SrcSheet As Worksheet
Dim DestSheet As Worksheet, Lr As Long
Dim firstAddress As String
Dim c As Range
Dim iLastRow As Integer
Dim zLastRow As Integer
Dim test As String
Dim TempRange As Range
Dim Collection As String
Dim System As String
Dim Tag As String
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
Collection = Trim(Range("lblImportCollection").Value)
System = Trim(Range("lblImportSystem").Value)
Tag = Trim(Range("lblImportTag").Value)
'fill in the Source Sheet and range
Set XUsedRange = Sheets("Imported Data").UsedRange
Set ZUsedRange = Sheets("Test").Range("A:C")
'Fill in the destination sheet and find the last known cell
Set DestSheet = Sheets("Test")
Set SrcSheet = Sheets("Imported Data")
'With the information on the new sheet
iLastRow = XUsedRange.End(xlDown).Row
zLastRow = ZUsedRange.End(xlUp).Row
Set SourceRange = SrcSheet.Range("A2:A" & CStr(iLastRow))
Set DestRange = DestSheet.Range("A2:C" & CStr(zLastRow))
With SourceRange
Set c = SourceRange.Find(What:=Collection, SearchOrder:=xlByColumns)
If Not c Is Nothing Then
firstAddress = c.Address
Do
MsgBox ("Found " & Collection & " on address:" & c.Address)
c.Copy
DestRange.PasteSpecial
If System = SrcSheet.Range("B" & CStr(c.Row) & ":B" & CStr(c.Row)) Then
MsgBox ("The system is " & SrcSheet.Range("B" & CStr(c.Row) & ":B" & CStr(c.Row)))
'DestSheet.Range ("B" & CStr(c.Row) & ":B" & CStr(c.Row))
SrcSheet.Range("B" & CStr(c.Row) & ":B" & CStr(c.Row)).Copy
DestRange.PasteSpecial
If Tag = SrcSheet.Range("C" & CStr(c.Row) & ":C" & CStr(c.Row)) Then
MsgBox ("The tag is" & SrcSheet.Range("C" & CStr(c.Row) & ":C" & CStr(c.Row)))
'DestSheet.Range ("C" & CStr(c.Row) & ":C" & CStr(c.Row))
SrcSheet.Range("C" & CStr(c.Row) & ":C" & CStr(c.Row)).Copy
DestRange.PasteSpecial
End If
End If
Set c = SourceRange.FindNext(c)
Loop While (Not c Is Nothing) And (c.Address <> firstAddress)
Else
MsgBox (Collection & " is NOT Found ")
End If
End With
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
Like I mentioned there are couple of problems with the code
Please use Option Explicit. That will ensure that you define your variables
When you define a variable which is meant to store Excel Row number then instead of Integer, use Long
Avoid the use of UsedRange. Get the Actual range which has "Data". Since you are only concerned with Col A, use that to find the last row. We can always use .Offset() to check for Criteria2 and Criteria3
Comment your code with appropriate "comments". I had a tough time understanding it.
Is this what you are trying?
Code: (UNTESTED)
Option Explicit
Sub FilterButton()
Dim SrcSheet As Worksheet, DestSheet As Worksheet
Dim SourceRange As Range
Dim aCell As Range, bCell As Range
Dim iLastRow As Long, zLastRow As Long
Dim Collection As String, System As String, Tag As String
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
'~~> Set your sheet
Set DestSheet = Sheets("Test")
Set SrcSheet = Sheets("Imported Data")
'~~> Find Last Row in Col A in the source sheet
With SrcSheet
iLastRow = .Range("A" & .Rows.Count).End(xlUp).Row
End With
'~~> Find Last "Available Row for Output" in Col A in the destination sheet
With DestSheet
zLastRow = .Range("A" & .Rows.Count).End(xlUp).Row + 1
End With
'~~> Set your ranges
Set SourceRange = SrcSheet.Range("A2:A" & iLastRow)
'~~> Search values
Collection = Trim(Range("lblImportCollection").Value)
System = Trim(Range("lblImportSystem").Value)
Tag = Trim(Range("lblImportTag").Value)
With SourceRange
'~~> Match 1st Criteria
Set aCell = .Find(What:=Collection, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
'~~> If found
If Not aCell Is Nothing Then
Set bCell = aCell
'~~> Copy A:C. Then match for Crit B and Crit C and remove what is not required
DestSheet.Range("A" & zLastRow & ":" & "C" & zLastRow).Value = _
SrcSheet.Range("A" & aCell.Row & ":" & "C" & aCell.Row).Value
'~~> Match 2nd Criteria
If aCell.Offset(, 1).Value = System Then
'~~> Match 3rd Criteria
If aCell.Offset(, 2).Value <> Tag Then _
DestSheet.Range("C" & zLastRow).ClearContents
Else
DestSheet.Range("B" & zLastRow).ClearContents
End If
'~~> Increase last row by 1 for output
zLastRow = zLastRow + 1
Do
Set aCell = .FindNext(After:=aCell)
If Not aCell Is Nothing Then
If aCell.Address = bCell.Address Then Exit Do
'~~> Copy A:C. Then match for Crit B and Crit C
DestSheet.Range("A" & zLastRow & ":" & "C" & zLastRow).Value = _
SrcSheet.Range("A" & aCell.Row & ":" & "C" & aCell.Row).Value
'~~> Match 2nd Criteria
If aCell.Offset(, 1).Value = System Then
'~~> Match 3rd Criteria
If aCell.Offset(, 2).Value <> Tag Then _
DestSheet.Range("C" & zLastRow).ClearContents
Else
DestSheet.Range("B" & zLastRow).ClearContents
End If
'~~> Increase last row by 1 for output
zLastRow = zLastRow + 1
Else
Exit Do
End If
Loop
Else
MsgBox Collection & " not Found"
End If
End With
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
FOLLOWUP (From Comments)
Option Explicit
Sub FilterButton()
Dim SrcSheet As Worksheet, DestSheet As Worksheet
Dim SourceRange As Range
Dim aCell As Range, bCell As Range
Dim iLastRow As Long, zLastRow As Long
Dim Collection As String, System As String, Tag As String
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
'~~> Set your sheet
Set DestSheet = Sheets("Test")
Set SrcSheet = Sheets("Imported Data")
'~~> Find Last Row in Col A in the source sheet
With SrcSheet
iLastRow = .Range("A" & .Rows.Count).End(xlUp).Row
End With
'~~> Find Last "Available Row for Output" in Col A in the destination sheet
With DestSheet
zLastRow = .Range("A" & .Rows.Count).End(xlUp).Row + 1
End With
'~~> Set your ranges
Set SourceRange = SrcSheet.Range("A2:A" & iLastRow)
'~~> Search values
Collection = Trim(Range("lblImportCollection").Value)
System = Trim(Range("lblImportSystem").Value)
Tag = Trim(Range("lblImportTag").Value)
With SourceRange
'~~> Match 1st Criteria
Set aCell = .Find(What:=Collection, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
'~~> If found
If Not aCell Is Nothing Then
Set bCell = aCell
'~~> Copy A:C. Then match for Crit B and Crit C and remove what is not required
DestSheet.Range("A" & zLastRow & ":" & "C" & zLastRow).Value = _
SrcSheet.Range("A" & aCell.Row & ":" & "C" & aCell.Row).Value
'~~> Match 2nd Criteria
If Len(Trim(System)) = 0 Or _
aCell.Offset(, 1).Value <> System Then _
DestSheet.Range("B" & zLastRow).ClearContents
'~~> Match 3rd Criteria
If Len(Trim(Tag)) = 0 Or _
aCell.Offset(, 2).Value <> Tag Then _
DestSheet.Range("C" & zLastRow).ClearContents
'~~> Increase last row by 1 for output
zLastRow = zLastRow + 1
Do
Set aCell = .FindNext(After:=aCell)
If Not aCell Is Nothing Then
If aCell.Address = bCell.Address Then Exit Do
'~~> Match 2nd Criteria
If Len(Trim(System)) = 0 Or _
aCell.Offset(, 1).Value <> System Then _
DestSheet.Range("B" & zLastRow).ClearContents
'~~> Match 3rd Criteria
If Len(Trim(Tag)) = 0 Or _
aCell.Offset(, 2).Value <> Tag Then _
DestSheet.Range("C" & zLastRow).ClearContents
'~~> Increase last row by 1 for output
zLastRow = zLastRow + 1
Else
Exit Do
End If
Loop
Else
MsgBox Collection & " not Found"
End If
End With
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub

Resources