首页 > 解决方案 > 为什么我的 Excel VBA 代码在第一次尝试时没有完全执行?

问题描述

首先,我在 Windows 10 上使用 Excel 2016。

我在 Excel 中有一个电子表格,它利用两个宏来插入基于用户表单的数据,或者在有人想要清除电子表格时从电子表格中删除所有数据。这个问题的重点是清除数据的程序(见下文),尽管我也会讨论另一个问题。

Sub ClearData()

ToDelete = MsgBox("Are you sure you want to delete all data?", vbYesNo, "Are you sure?")

if ToDelete = vbYes Then
   ActiveSheet.Unprotect "Password"
   Do While Range("A2").Value <> ""
      Range("A2:J2").Delete Shift:=xlUp
   Loop

   ActiveSheet.Protect "Password"
End If

End Sub

代码非常简单。它要求用户确认他们是否要删除所有数据,如果这样做,它会解锁工作表,不断删除第二行直到没有更多行,然后将工作表锁定回来。

问题:假设我的电子表格中有 10 行数据,然后点击指向 ClearData() 子的按钮。在这种情况下,第一行删除,然后宏完全停止,留下 9 行数据。现在,如果我再次点击 ClearData() 按钮,宏将完美执行并删除剩余的 9 行。

我认为问题可能出在锁定和解锁代码的电子表格部分。所以我手动解锁了工作表并单击了按钮,并且发生了同样的错误。

“插入数据”宏偶尔会出现的另一个类似问题是它只会将数据添加到一个单元格(甚至不是整行,只是第一个单元格)。然后,如果我再次运行该程序并在用户表单中输入相同的确切信息,所有这些信息都会正确填写。在这两种情况下,宏都会运行几行代码,直到它执行实际更新电子表格的第一行代码,然后完全退出代码而不执行任何其他行。另请注意,也不会出现错误消息。

需要注意的一点是,这个问题似乎是间歇性的。我刚刚又试了一次,数据正在正确填写和清除。我可以做的一件事会导致“插入数据”宏出现问题。如果我更改代码并再次保存,即使我更改的代码无关紧要(例如在注释中添加空格),那么下次执行时也会出现插入数据错误。

标签: excelvba

解决方案


不是您问题的实际答案,而是帮助调试它的建议。

添加一个陷阱来检测错误情况,并进入调试模式,这样您就可以检查事物的状态。

Sub ClearData()
    Dim ToDelete As VbMsgBoxResult
    Dim RowCount As Long

    ToDelete = MsgBox("Are you sure you want to delete all data?", vbYesNo, "Are you sure?")

    If ToDelete = vbYes Then
       ActiveSheet.Unprotect "Password"
       Do While Range("A2").Value <> ""
          Range("A2:J2").Delete Shift:=xlUp
          RowCount = RowCount + 1
       Loop
       If RowCount = 1 Then Stop
       ActiveSheet.Protect "Password"
    End If

End Sub

如果循环在一次删除后结束,代码将在Stop命令上中断。然后,您可以检查工作表的状态和单元格 A2 的值,这可能会(也可能不会!)揭示一些信息。


同样不是答案,而是另一种方法:

这假设了两件事

-在 A 列的第一个空白行下方没有您想要保留的其他数据

- 在J 列的右侧没有您想要保留的其他数据

如果这些假设中的任何一个是错误的,则可以轻松调整代码以适应

Sub ClearData()
    Dim rng As Range
    If MsgBox("Are you sure you want to delete all data?", vbYesNo, "Are you sure?") <> vbYes Then Exit Sub

    With ActiveSheet
        Set rng = .Range(.Cells(.Rows.Count, 1).End(xlUp), .Cells(2, 1))

        ' account for possibility there are no data rows
        If rng.Row = 1 Then Exit Sub

       .Unprotect "Password"
       rng.EntireRow.Delete
       .Protect "Password"
    End With
End Sub

推荐阅读