【问题标题】:VBA Code in Excel randomly stops executing. No error messages occurExcel 中的 VBA 代码随机停止执行。不出现错误消息
【发布时间】:2021-04-23 08:40:26
【问题描述】:

基本上,我有一个更新数据按钮,它从两个电子表格(在一本书内)的两列中获取信息。这段代码的总体目标是从一列中获取所有值,然后将另一列中的值附加到其下方。

Worksheets("Overall Flow").Range("A4:A1004").Value = Worksheets("Active").Range("A2:A1002").Value
Dim i As Integer
For i = 4 To 1004
    If Worksheets("Overall Flow").Range("A" & Trim(str(i))) = "" Then
        Worksheets("Overall Flow").Range("A" & Trim(str(i)) & ":A" & Trim(str(1000 + i))).Value = Worksheets("Inactive").Range("A2:A1002").Value
        i = 1005
    End If
Next

由于某种原因,第一行执行,然后结束。当我设置断点,然后一步一步做,之后没有其他步骤发生。

当我单独运行第一行时,它似乎工作正常,但在以下情况下不行:

Worksheets("Overall Flow").Range("A" & Trim(str(i)) & ":A" & Trim(str(1000 + i))).Value = Worksheets("Inactive").Range("A2:A1002").Value

Worksheets("Overall Flow").Range("A4:A1004").Value = Worksheets("Inactive").Range("A2:A1002").Value

出现在后面。

【问题讨论】:

  • 您实际上有 3 个电子表格:“总体流程”、“活动”和“非活动”。当我运行它时,它工作正常......假设它正在做你认为它应该做的事情。它遍历 A4:A1004 中的每个单元格,当一个单元格为空白时,它将非活动工作表中的值一直复制到“总体流程”工作表的最后一行,然后结束程序。不确定您要做什么,但代码为我运行。如果它在语法上是正确的,你不会得到任何错误。您能否更具体地说明它应该做什么以及您的 3 张床单是什么样的?
  • 这正是它应该做的。它第一次起作用。但在那之后,它就停止了工作。
  • 这可能是因为一旦从“非活动”表中复制它们,“总体流程”表中的 A4:A1004 范围内不再有任何空白单元格(除非您的“非活动”表也有空白单元格)?
  • 你在哪里设置断点,执行到底在哪里停止?它是否通过循环?
  • 大约有 102 条记录处于活动状态,大约 350 条处于非活动状态。我在第一行设置了断点。它触发,按 F8,复制 Active 中的数据,然后什么也没发生

标签: excel vba


【解决方案1】:

对此的解决方案非常不寻常。

CTRL+BREAK CTRL+BREAK CTRL+BREAK ESC

很久以后我又遇到了,我一直在寻找解决方案,然后我来到这里,然后这个序列又回到了我的脑海中,我尝试了。

它对我有用,我希望这会对某人有所帮助。

【讨论】:

    【解决方案2】:

    更新:调整代码(现在有错误检查!)

    关于当前代码的要点:

    • 复制活动范围时,检查最后使用的连续单元格。这比循环更快、更有效。
    • 为什么要修剪一个明知不包含空格的数字?
    • 无需设置 i = 1005,只需使用 Exit For。这对读者来说更有效,更清楚意图是什么。我没有在下面的代码中使用它,因为我完全避免了循环。

    这里有一种不同的方法,您可以在没有任何循环的情况下执行此操作,我认为这种方法更清晰有效。试试这个,看看它是否适合你:

    Sub test()
    
    Dim lastRow As Long, offSet As Long
    lastRow = Worksheets("Active").Range("A2").End(xlDown).row
    
    'Sanity checks
    If IsEmpty(Worksheets("Active").Range("A2")) = True Then offSet = 1: lastRow = 2
    If lastRow > 1001 Then lastRow = 1002
    
    Worksheets("Overall Flow").Range("A4:A" & lastRow + 2).Value = _
    Worksheets("Active").Range("A2:A" & lastRow).Value
    
    If lastRow < 1002 Then
        Worksheets("Overall Flow").Range("A" & lastRow + (3 - offSet) & _
        ":A1004").Value = Worksheets("Inactive").Range("A2:A1002").Value
    End If
    
    End Sub
    

    注意事项

    • 健全性检查 1 用于 A2 在活动工作表中是否为空白。
    • 健全性检查 2 用于检查 A1002 之外的单元格是否在活动工作表中具有值。

    【讨论】:

    • 我通常用 C# 和 C++ 编程,所以当我问朋友 VB 中的中断是什么时,他说没有(我天真地相信他>.
    【解决方案3】:

    这是我用来测试您的代码的。由于我不知道电子表格中的内容,因此我无法准确重现您所看到的内容,因此我首先将虚拟数据放入范围内。

    对我来说,它每次都运行良好,我已经在 2 台不同的计算机上进行了尝试 - Excel 2003 和 Excel 2010。

    我设置了一个断点并按 F8 步进,也按 Shift F8 并且都工作正常。

    您的数据可能有所不同(即,从非活动工作表复制的第一个单元格是空白的,因此在处理第一个单元格后会停止执行 - 检查 A4 列是否为空白),或者可能有一些内存已获得因 Office 被杀而损坏。

    在我拥有的模块中:

    Sub test()
        Worksheets("Active").Range("A2:A1002").Value = "active"
        Worksheets("Active").Range("A5").Value = ""
        Worksheets("Inactive").Range("A2:A1002").Value = "inactive"
    
        Worksheets("Overall Flow").Range("A4:A1004").Value = Worksheets("Active").Range("A2:A1002").Value
        Dim i As Integer
        For i = 4 To 1004
            If Worksheets("Overall Flow").Range("A" & Trim(Str(i))) = "" Then
                Worksheets("Overall Flow").Range("A" & Trim(Str(i)) & ":A" & Trim(Str(1000 + i))).Value = Worksheets("Inactive").Range("A2:A1002").Value
                i = 1005
            End If
        Next
    End Sub
    

    您是否在另一台计算机上尝试过相同的代码?

    【讨论】:

    • 我认为是记忆扭曲了。我在这里尝试了每个人的代码,它没有工作(在 Active -> 整体流程复制后仍然终止)。我最终删除了工作表,然后重新制作。之后一切似乎都正常。
    • 可能是一个损坏的工作簿,如果您删除了工作表并重新制作...很高兴听到它现在可以工作了!
    【解决方案4】:

    我遇到了这个问题,我将其追踪到在 application.screenupdating 仍设置为 True 时处理的条件格式中使用的自定义 VBA 函数。

    我不确定这种行为有多一致,但是,当在条件格式规则中引用自定义 VBA 函数时,当屏幕更新时,即使使用断点或调试,它也不会单步执行代码。断言方法。以下是所发生情况的细分:

    上下文:

    • 2 个打开的工作簿。
    • 有问题的条件格式和自定义函数在 workbook1 中。
    • 我试图执行的代码在 workbook2 中。

    流程

    1. 我在 workbook2 中调用了一个过程。
    2. Workbook2 的过程到达执行自动筛选命令的行。
    3. 自动筛选命令触发屏幕更新在所有打开的工作簿中(任何触发 Worksheet_Change 或 Worksheet_Calculate 事件的命令都可以在此处应用)
    4. 屏幕更新处理条件格式规则,包括 workbook1 中调用 workbook1 的自定义函数的规则。
    5. 自定义函数在“静默”状态下运行(即不与用户交互,忽略断点和“debug.assert”调用;这似乎是设计为条件格式功能的一部分)
    6. 自定义函数完成执行并停止所有其他活动代码执行。

    我通过在开始时添加 Application.ScreenUpdating = False 行来解决我的问题,以防止屏幕更新以及扩展的条件格式处理(但最好一开始就让自定义函数远离条件格式)。

    我不确定这是否与您的情况有关,但我希望它对某人有所帮助。

    【讨论】:

    • 是的...我的“令人讨厌的误导性隐藏”问题也在自动格式中...感谢您的提示!!!
    【解决方案5】:

    transistor1 的回答中已经提到过,但仅作为旁注。

    我遇到了类似的问题,即 VBA 代码只是在函数中间停止执行。就在此之前,它还跳回了几行代码。没有显示错误消息。

    我关闭了所有打开的 Excel 程序,重新打开文件后一切正常。

    所以我对这个问题的确认答案是:内存损坏,重新启动 Excel

    编辑:执行此操作后,我还遇到了当我尝试取消注释特定行时 Visual Basic 编辑器崩溃的问题。所以我创建了一个新的 Excel 文件并复制了我的代码。现在我没有任何问题了。

    【讨论】:

    • 我的解决方案是从宏未运行的文件中强制退出 excel。重新打开时,宏将再次运行。 (当然 - 在强制退出之前保存所有其他文件和此文件中的任何必要更改)
    【解决方案6】:

    我遇到了同样的问题。我有一个子例程,它在整个代码中给出随机错误而不给出错误消息。按 F8,代码将恢复。

    我发现有人发布了一个名为“ThatCleverDevil”的子程序,我不记得资源或发布者。它会警告您即将发生错误。例程贴在下面。

    我将代码拆分为组件子例程。简短的片段运行没有中断或错误。我创建了一个调用每个片段的子例程。错误恢复。

    它们会单独运行,但不会一起运行。

    解决方案:在调用的子例程之间,我运行了以下代码行:

    Application.Wait Second(Now) + 1

    然后代码运行没有错误。

    感谢编写 ThatCleverDevil 的人。特别感谢编写有关 Application.Wait 的编码器。

    Sub ThatCleverDevil()
    

    On Error GoTo err

    MsgBox "即将出错" 错误.Raise 12345 MsgBox "出错后到这里"

    退出子

    错误: 停止:继续

    结束子

    罗伯特

    【讨论】:

      【解决方案7】:

      VBA 很容易出现这个问题。我多年来一直在企业工作流程中使用它,因为它被硬编码成很多东西,但如果可能的话,我会考虑替代方案。如果这是一个临时项目,R 将更快并提供更大的灵活性。如果这更面向生产并且旨在处理大量数据,我会考虑使用 informatica。

      【讨论】:

        【解决方案8】:

        为了提高性能,我在循环内调用了函数 DoEvents。它为我解决了这个问题。

        【讨论】:

          猜你喜欢
          • 2016-08-28
          • 2013-06-09
          • 1970-01-01
          • 2023-03-27
          • 2018-05-16
          • 2019-11-05
          • 1970-01-01
          • 2015-10-19
          • 1970-01-01
          相关资源
          最近更新 更多