仅当 运行 多次时,一段代码才按预期工作

Piece of Code works as expected only when run multiple times

目前正在调试一段代码。目前我的代码按预期工作,它将日期分配给 finaldate 变量,然后在代码中查找以删除高于 finaldate 变量的所有日期。唯一的问题是子程序需要多次 运行 才能生效。例如,当我 运行 通过它,一旦它删除了大约一半的日期, 运行 再次通过它并且它做同样的事情,我通常 F5 它大约 5 次以确认它的完成。虽然这在调试时很好,但我需要知道它每次都能完美运行。

Sub Remove_Unecessary_Data_1()

Dim ALLCs As Worksheet
Dim DS As Worksheet
Dim finaldate As Date




Set DS = Sheets("Data Summary")
Set ALLCs = Sheets("Asset LLC (Input)")



    ALLCs.Select
        For y = 1 To 40
            If InStr(1, Cells(13, y), "Timestamp of Execution") Then
                finaldate = ALLCs.Cells(50, y)
            End If
        Next

    ALLCs.Select
        For u = 1 To 40
            If InStr(1, Cells(13, u), "Start Date") Then
                For p = 2 To 69584
                If Cells(p + 14, u) > finaldate Then
                Cells(p + 14, u).EntireRow.Delete
                End If
                Next
            End If
        Next
  end sub

编辑:示例数据

单元格 (50,y) = 1/12/15 最终日期 = 单元格 (50,Y)

标题为“开始日期”的列包含范围从 1/05/15 到 1/30/15 的日期。

当正常工作时,15 年 12 月之后的所有日期都应该删除整行。

当您使用以下方式删除行时:

Cells(p + 14, u).EntireRow.Delete

已删除行下方的行向上移动以占据 space。如果该行包含应删除的日期,它将被忽略,因为计数器会自动移至下一行。例如,假设我们希望删除 Data 列中带有 CD 的任何行:

Row Number    Data
1             A
2             B
3             C    
4             D
5             E

变成:

Row Number    Data
1             A
2             B
3             D
4             E

行计数器移动到 4 而不检查 3 中的新值,因此 D 不会被删除。

您可以通过将 If...Then 语句更改为 Do...While 循环来解决此问题:

Sub Remove_Unecessary_Data_1()

Dim ALLCs As Worksheet
Dim DS As Worksheet
Dim finaldate As Date




Set DS = Sheets("Data Summary")
Set ALLCs = Sheets("Asset LLC (Input)")



    ALLCs.Select
        For y = 1 To 40
            If InStr(1, Cells(13, y), "Timestamp of Execution") Then
                finaldate = ALLCs.Cells(50, y)
            End If
        Next

    ALLCs.Select
        For u = 1 To 40
            If InStr(1, Cells(13, u), "Start Date") Then
                For p = 2 To 69584
                    Do While (Cells(p + 14, u) > finaldate)
                        Cells(p + 14, u).EntireRow.Delete
                    Loop
                Next
            End If
        Next
End sub

这应该在删除前一行后继续检查该单元格,以确保不应删除替换行。

事实上,当您删除一行的同时行数越来越多时,您将错过分析刚删除的行之后的每一行,因为它 (rows(i+1)) 已成为 rows(i)然而你又增加了下一个。

这是考虑到这一点的代码(并去掉了无用的 Select

Sub Remove_Unecessary_Data_1()

Dim ALLCs As Worksheet, _
    DS As Worksheet, _
    FinalDate As Date

Set DS = Sheets("Data Summary")
Set ALLCs = Sheets("Asset LLC (Input)")

For y = 1 To 40
    If InStr(1, ALLCs.Cells(13, y), "Timestamp of Execution") Then
        FinalDate = ALLCs.Cells(50, y)
    End If
Next


For u = 1 To 40
    If InStr(1, ALLCs.Cells(13, u), "Start Date") Then
        For p = 69584 To 2 Step -1
        If Cells(p + 14, u) > FinalDate Then
            Cells(p + 14, u).EntireRow.Delete
        End If
        Next
    End If
Next
End Sub

删除行时,您必须从下往上操作,否则最终会跳过行。

例如,您有:

 Line 1
>Line 2
 Line 3
 Line 4

当您的代码删除 Line 2 时,"Row" 3 现在变为 "Row "2,但您的代码继续查看 Line 4。您的数据现在如下所示:

 Line 1
 Line 3
 >Line 4

如果您更改代码的这一点:

For p = 2 To 69584
  If Cells(p + 14, u) > finaldate Then
    Cells(p + 14, u).EntireRow.Delete
  End If
Next

对此:

For p = 69598 to 16 step - 1
  If Cells(p, u) > finaldate Then
    Cells(p, u).EntireRow.Delete
  End If
Next

一切都会好起来的。

*注意:我将您的起点和终点向上调整了 14,并从 Cells() 参考中删除了 + 14。在那里做额外的数学运算没有意义...