【问题标题】:Macro - delete rows based on date宏 - 根据日期删除行
【发布时间】:2017-10-20 03:14:41
【问题描述】:

我对 VBA 和 Excel 中的宏非常陌生。我有一个非常大的 Excel 电子表格,其中 A 列保存日期。我正在尝试删除值小于某个日期的行,这就是我到现在为止的想法..

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
Next i
End Sub

我收到一个没有 For 错误的 Next... 有人可以帮忙吗?

【问题讨论】:

    标签: vba excel


    【解决方案1】:

    这很适合使用Range.AutoFilter 属性。下面的脚本包含对所采取的每个步骤的注释:

    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
    

    在一个简单的示例上运行此代码(在此图片中的“Sheet1”上),如下所示:

    将删除日期早于 2013 年 1 月 1 日的所有行,为您提供以下结果:

    【讨论】:

    • 谢谢!我对代码进行了一些更改,它运行良好!谢谢!
    • 太棒了——很高兴听到它成功了。如果答案适合您,请在方便时接受。以下是截图形式的超快速解释:i.stack.imgur.com/uqJeW.png
    【解决方案2】:

    回答你的问题

    我收到一个没有 For 错误的 Next

    问题是您试图循环i,但您还没有打开For i 循环。当您在调用Loop 或条件(即If)的任何代码下方缩进代码时,它变得很明显

    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
    

    在编写代码时,我尝试:

    • 如果需要,请立即输入结束命令。所以输入If...Then,点击[ENTER],输入End If,点击[HOME],点击[ENTER],点击[UP ARROW]然后[TAB]到正确的地方写条件代码,这样任何人都可以轻松阅读和理解。
    • 始终在每个模块的顶部使用Option Explicit 来强制声明变量。

    关于根据条件删除行的提示 如果您从顶部开始向下工作,则每次删除一行时,您的计数器都会有效地移动到您删除的行下方两行的单元格,因为已删除行下方的行会向上移动(即根本没有经过测试) .

    最有效的方法是从底部或行向上循环:

    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
    

    这样,您要测试的下一行已被保留 - 您只将下面的行向上移动了 1 并且您之前已经测试了该行。

    【讨论】:

      【解决方案3】:

      请试试这个

      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
      

      【讨论】:

        【解决方案4】:

        由于某种原因,您的代码中有一个额外的Next i,正如调试器突出显示的那样。试试下面的:

        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
        

        【讨论】:

        • 我怎么还空着呢?
        • 因为删除行时索引正在移动。你需要iterate backwards
        • vba中的日期格式一般是怎么写的?导致我的类型不匹配
        猜你喜欢
        • 1970-01-01
        • 2021-09-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-22
        • 1970-01-01
        • 1970-01-01
        • 2013-07-30
        相关资源
        最近更新 更多