I have a userform that allows the user to select which rows and columns are relevant to the user to check. I am using this code, but it searches all rows and all columns and therefore doesn’t delete the right rows. Could anyone suggest a solution to fixing this that will work for rows and columns? Thanks.
Dim RowToTest As Long
Dim MySheet As Worksheet
Dim ProjectedDate As Date
Dim ColToTest As Long
Dim TempKeep As Integer
TempKeep = 0
ProjectedDate = Date + 60
For Each MySheet In ThisWorkbook.Sheets
For RowToTest = MySheet.Cells(Rows.Count, 1).End(xlUp).Row To 2 Step -1
For ColToTest = MySheet.Cells(2, Columns.Count).End(xlToLeft).Column To 15 Step -1
With MySheet.Cells(RowToTest, ColToTest)
If IsDate(MySheet.Cells(RowToTest, ColToTest).Value) Then
If .Value < ProjectedDate Then
TempKeep = 1
End If
End If
End With
Next ColToTest
If TempKeep = 0 Then
MySheet.Rows(RowToTest).EntireRow.Delete
End If
TempKeep = 0
Next RowToTest
Next
You can check if a cell is hidden through their .Rows
and .Columns
property like so:
If CelToCheck.Rows.Hidden or CelToCheck.Columns.Hidden Then
'Your code if hidden
Else
'Code if not hidden
End if
In your case CelToCheck would be
MySheet.Cells(RowToTest, ColToTest)
Alternatively you can set a range variable and loop through visible cells only with
For each CL in RangeVariable.SpecialCells(xlCellTypeVisible)
'Your code
Next CL
Answer:
I was about to suggest the same as JvdV, using the .Hidden
property. Can use it in your code something like this:
Dim RowToTest As Long
Dim MySheet As Worksheet
Dim ProjectedDate As Date
Dim ColToTest As Long
Dim TempKeep As Integer
TempKeep = 0
ProjectedDate = Date + 60
For Each MySheet In ThisWorkbook.Sheets
For RowToTest = MySheet.Cells(Rows.Count, 1).End(xlUp).Row To 2 Step -1
For ColToTest = MySheet.Cells(2, Columns.Count).End(xlToLeft).Column To 15 Step -1
With MySheet.Cells(RowToTest, ColToTest)
If IsDate(MySheet.Cells(RowToTest, ColToTest).Value) Then
If .Value < ProjectedDate Then
TempKeep = 1
End If
End If
End With
Next ColToTest
If TempKeep = 0 and Not isHiddenRow(MySheet, RowToTest) Then
MySheet.Rows(RowToTest).EntireRow.Delete
End If
TempKeep = 0
Next RowToTest
Next
don’t necessarily need to have a function to do so, but makes it easier for code reuse.
Function isHiddenRow(sht As Worksheet, rowNr As Long) As Boolean
On Error Resume Next
isHiddenRow = sht.Rows(rowNr).Hidden
End Function
Function isHiddenCol(sht As Worksheet, colNr As Long) As Boolean
On Error Resume Next
isHiddenCol = sht.Columns(colNr).Hidden
End Function
PS: depending how much data you have in your sheet, is not a very good idea to loop directly over the sheet generally. Consider using arrays
if you have thousands of rows.
EDIT: added an alternative using an array to do the same thing.
Option Explicit
Sub delVisibleRows()
Dim MySheet As Worksheet
Dim ProjectedDate As Date: ProjectedDate = Date + 60
Dim R As Long, C As Long, lRow As Long, lCol As Long
Dim arrData As Variant
Dim strRange As String
For Each MySheet In ThisWorkbook.Sheets 'for each sheet
With MySheet
lRow = .Cells(.Rows.Count, 1).End(xlUp).Row 'get last row
lCol = .Cells(2, .Columns.Count).End(xlToLeft).Column 'get last column
arrData = .Range(.Cells(1, 1), .Cells(lRow, lCol)) 'allocate the data to an array
For R = 2 To lRow 'iterate through all rows starting at 2
For C = 15 To lCol 'iterate through all columns, starting at 15 - this could cause a problem if there are less than 15 columns
If IsDate(arrData(R, C)) And arrData(R, C) < ProjectedDate Then 'check if is date, and if is less than projected date
Exit For 'if it is, skip to next row
End If
If C = lCol Then 'If we got to last col without meeting the skip condition
strRange = strRange & R & ":" & R & "," 'build the string for the range to delete
End If
Next C
Next R
strRange = Left(strRange, Len(strRange) - 1) 'get rid of the last comma
.Range(strRange).SpecialCells(xlCellTypeVisible).EntireRow.Delete 'delete only the visible rows
End With
Next MySheet
End Sub
Tags: excelexcel, search