Excel中的VBA代码随机停止执行。没有出现错误消息

时间:2011-08-24 18:57:46

标签: excel vba

基本上,我有一个Updata按钮,它从两列中获取信息,在两个电子表格中(在一本书中)。此代码的总体目标是从一列中获取所有值,然后从其下面的另一列中追加值。

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

出现在后方。

8 个答案:

答案 0 :(得分:2)

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

有关当前代码的要点:

  • 复制ACTIVE范围时,请检查最后使用的连续单元格。这比循环更快,更有效。
  • 为什么要修剪一个你知道不包含空格的数字?
  • 无需设置i = 1005,只需使用退出即可。这对于读者而言是更有效和清晰的意图。我没有在下面的代码中使用它,因为我完全避免了循环。

这是一种不同的方式,你可以做到这一点,没有任何循环,我认为这是更清晰和有效。试试这个,看看它是否适合你:

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

备注

  • 如果活动工作表中的A2为空白,则完整性检查1。
  • 完整性检查2适用于超出A1002的单元格,其值为“活动工作表”。

答案 1 :(得分:1)

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

对我而言每次运行都很顺利,我在两台不同的计算机上试用过它 - Excel 2003和Excel 2010。

我设置了一个断点,然后使用F8和Shift F8,两者都运行良好。

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

在我的模块中:

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

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

答案 2 :(得分:1)

解决这个问题非常不寻常。

CTRL + BREAK CTRL + BREAK CTRL + BREAK ESC

经过很长一段时间,我发现了一个问题,我正在寻找一个解决方案,然后我来到这里,然后这个序列回到了我的脑海,我试过了。

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

答案 3 :(得分:0)

在晶体管1的答案中已经提到过,但仅作为旁注。

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

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

所以我确认对此问题的回答是:内存已损坏,重新启动Excel

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

答案 4 :(得分:0)

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

我不确定这种行为的一致性,但是,当在条件格式规则中引用自定义VBA函数时,当屏幕更新时,即使使用断点或者使用断点,它也不会逐步执行代码debug.assert方法。以下是发生的事情的细分:

<强>上下文

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

<强>过程

  1. 我在workbook2中调用了一个过程。
  2. Workbook2的程序到达执行autofilter命令的行。
  3. 自动过滤器命令在所有打开的工作簿中触发屏幕更新(触发Worksheet_Change或Worksheet_Calculate事件的任何命令都可以在此处应用)
  4. 屏幕更新处理条件格式设置规则,包括调用workbook1的自定义函数的工作簿1中的规则。
  5. 自定义功能在静音&#39;中运行。状态(即没有与用户交互,忽略断点和&#34; debug.assert&#34;调用;这似乎是设计为条件格式化功能的一部分)
  6. 自定义函数完成执行,停止所有其他活动代码执行。
  7. 我通过在开始时添加Application.ScreenUpdating = False来修复我的问题,以防止屏幕更新,并且通过扩展,进行条件格式处理(但是最好是使自定义函数远离条件格式以开始)。

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

答案 5 :(得分:0)

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

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

我将代码拆分为组件子例程。短暂的snippits运行没有中断或错误。我创建了一个调用每个snippit的子程序。错误重新开始。

他们会单独运行,但不是全部运行。

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

Application.Wait Second(Now)+ 1

然后代码运行没有错误。

感谢曾经写过ThatCleverDevil的人。特别感谢撰写有关Application.Wait的编码人员。

Sub ThatCleverDevil()

On Error GoTo err

MsgBox“即将发生错误” err.Raise 12345 MsgBox“在错误后到达这里”

退出子

错误: 停止:恢复

End Sub

罗伯特

答案 6 :(得分:0)

VBA容易出现此问题。我已经在复杂的工作流中使用了多年,因为它是如此硬编码为很多东西,但是如果可能的话,我只会考虑替代方法。如果这样,一个临时项目R将更快并且提供更大的灵活性。如果这是面向生产的并且打算处理大量产品,那么我将考虑使用informatica。

答案 7 :(得分:0)

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