Macro - delete rows based on date

前端 未结 4 1687
北恋
北恋 2020-12-17 07:36

I am very new to VBA and macros in Excel. I have a very large excel spreadsheet in which column A holds dates. I am trying to delete the rows which have a value smaller than

相关标签:
4条回答
  • 2020-12-17 07:47

    To answer your question

    I am receiving a Next without For error

    The problem is you are trying to loop on i but you haven't opened a For i loop. When you indent the code below any code that invokes a Loop or condition (i.e. If) it becomes obvious

    Sub DELETEDATE()
    Dim x As Long
        For x = 1 To Cells.SpecialCells(xlCellTypeLastCell).Row
            Debug.Print Cells(x, "A").Value
            If CDate(Cells(x, "A")) < CDate("01/01/2013") Then
                Cells(i, "A").EntireRow.Delete 'i has no value so Cells(0, "A") is ??
            End If
        Next x
        Next i 'where is the For i = ... in this code?
    End Sub
    

    When writing code I try to:

    • Enter the end command immediately if it's needed. So type If...Then, hit [ENTER], type End If, hit [HOME], hit [ENTER], hit [UP ARROW] then [TAB] to the right place to write the conditional code so that anyone will be able to read and understand it easily.
    • Always use Option Explicit at the top of every module to force variable declarations.

    a tip about deleting rows based on a condition If you start at the top and work down, every time you delete a row your counter will effectively move to the cell two rows below the row you deleted because the row immediately below the deleted row moves up (i.e. it is not tested at all).

    The most efficient way is to loop up from the bottom or your rows:

    Sub DELETEDATE()
    Dim x As Long
        For x = [a1].SpecialCells(xlCellTypeLastCell).Row To 1 Step -1
            Debug.Print Cells(x, "A").Value
            If CDate(Cells(x, "A")) < CDate("01/01/2013") Then
                Cells(x, "A").EntireRow.Delete 'changed i to x
            End If
        Next x
    End Sub
    

    This way, the next row you want to test has been preserved - you've only moved the row below up by 1 and you've tested that row earlier.

    0 讨论(0)
  • 2020-12-17 07:53

    You have an additional Next i for some reason in your code as highlighted by the debugger. Try the below:

    Sub DELETEDATE()
    Dim x As Long
    For x = 1 To Cells.SpecialCells(xlCellTypeLastCell).Row
    Debug.Print Cells(x, "A").Value
    If CDate(Cells(x, "A")) < CDate("01/01/2013") Then
    Cells(i, "A").EntireRow.Delete
    End If
    Next x
    End Sub
    
    0 讨论(0)
  • 2020-12-17 08:02

    This lends itself well to using the .AutoFilter property of a Range. The script below contains a comment for each step taken:

    Option Explicit
    Sub DeleteDateWithAutoFilter()
    
    Dim MySheet As Worksheet, MyRange As Range
    Dim LastRow As Long, LastCol As Long
    
    'turn off alerts
    Application.DisplayAlerts = False
    
    'set references up-front
    Set MySheet = ThisWorkbook.Worksheets("Sheet1")
    
    'identify the last row in column A and the last col in row 1
    'then assign a range to contain the full data "block"
    With MySheet
        LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
        LastCol = .Range("A" & .Columns.Count).End(xlToLeft).Column
        Set MyRange = .Range(.Cells(1, 1), .Cells(LastRow, LastCol))
    End With
    
    'apply autofilter to the range showing only dates
    'older than january 1st, 2013, then deleting
    'all the visible rows except the header
    With MyRange
        .AutoFilter Field:=1, Criteria1:="<1/1/2013"
        .SpecialCells(xlCellTypeVisible).Offset(1, 0).Resize(.Rows.Count).Rows.Delete
    End With
    
    'turn off autofilter safely
    With MySheet
        .AutoFilterMode = False
        If .FilterMode = True Then
            .ShowAllData
        End If
    End With
    
    'turn alerts back on
    Application.DisplayAlerts = True
    
    End Sub
    

    Running this code on a simple example (on "Sheet1" in this picture) that looks like this:

    start

    Will delete all rows with a date older than 1/1/2013, giving you this result:

    end

    0 讨论(0)
  • 2020-12-17 08:03

    Please try with this

    Sub DELETEDATE()
    Dim x As Long
    last = Range("A65536").End(xlUp).Row
    For x = 1 To last
        Debug.Print Cells(x, "A").Value
        check:
        If x <= last Then
            If Trim(CDate(Cells(x, "A"))) <= Trim(CDate("7/29/2013")) Then
                last = last - 1
                Cells(x, "A").EntireRow.Delete
                GoTo check
            End If
        End If
    Next x
    End Sub
    
    0 讨论(0)
提交回复
热议问题