【问题标题】:VBA error: Why does my code keep jumping back lines?VBA 错误:为什么我的代码不断跳回行?
【发布时间】:2015-01-12 22:24:15
【问题描述】:

我为代码转储道歉,但经过两天的调试,我想我开始失去它了,我越来越绝望了。我已经开发了如下所示的代码

intColumnCount = wsStaff.Cells(1, Columns.Count).End(xlToLeft).Column  
intColumnLoop = 2  
intStaffCount = 0  
wsDisplay.Range("A2").EntireRow.UnMerge  
wsDisplay.Range("A2").EntireRow.Value = ""  
Do  
  intRowCount = wsStaff.Cells(Rows.Count, intColumnLoop).End(xlUp).Row  
  intRowLoop = 2  
  Do  
    If IsEmpty(wsStaff.Cells(intRowLoop, intColumnLoop)) And intRowLoop <> 2 Then  
      wsStaff.Range(wsStaff.Cells(intRowLoop, intColumnLoop).Address).Delete Shift:=xlUp  
      intRowCount = wsStaff.Cells(Rows.Count, intColumnLoop).End(xlUp).Row  
    Else  
      intStaffCount = intStaffCount + 1  
      If wsDisplay.Cells(1, intStaffCount + 2).Value <> wsStaff.Cells(intRowLoop, intColumnLoop).Value And wsDisplay.Cells(1, intStaffCount + 2).Value <> wsStaff.Cells(intRowLoop + 1, intColumnLoop).Value And wsDisplay.Cells(1, intStaffCount + 2).Value <> wsStaff.Cells(2, intColumnLoop + 1).Value And wsDisplay.Cells(1, intStaffCount + 2).Value <> "" Then  
        wsDisplay.Range(wsDisplay.Cells(1, intStaffCount + 2).Address).EntireColumn.Delete Shift:=xlToLeft  
        intRowCount = wsStaff.Cells(Rows.Count, intColumnLoop).End(xlUp).Row  
        intStaffCount = intStaffCount - 1  
      ElseIf wsDisplay.Cells(1, intStaffCount + 2).Value = wsStaff.Cells(intRowLoop + 1, intColumnLoop).Value Or wsDisplay.Cells(1, intStaffCount + 2).Value = wsStaff.Cells(2, intColumnLoop + 1).Value Or wsDisplay.Cells(1, intStaffCount + 2).Value = "" Then  
        wsDisplay.Range(wsDisplay.Cells(1, intStaffCount + 2).Address).EntireColumn.Insert Shift:=xlToRight  
        wsDisplay.Cells(1, intStaffCount + 2).Value = wsStaff.Cells(intRowLoop, intColumnLoop).Value  
        intRowLoop = intRowLoop + 1  
      Else  
        intRowLoop = intRowLoop + 1  
      End If  
      If wsDisplay.Cells(1, intStaffCount + 2).Value = wsDisplay.Cells(1, intStaffCount + 1).Value Then  
        wsDisplay.Range(wsDisplay.Cells(1, intStaffCount + 2).Address).EntireColumn.Delete Shift:=xlToLeft  
        intRowCount = wsStaff.Cells(Rows.Count, intColumnLoop).End(xlUp).Row  
        intStaffCount = intStaffCount - 1  
      End If  
      wsDisplay.Cells(1, intStaffCount + 2).Interior.Color = RGB(255 - (0.1 * (255 - intColourPalette(intColumnLoop Mod 6 + 1, 1))), 255 - (0.1 * (255 - intColourPalette(intColumnLoop Mod 6 + 1, 2))), 255 - (0.1 * (255 - intColourPalette(intColumnLoop Mod 6 + 1, 3))))  
    End If  
  Loop While Not intRowLoop > intRowCount  
  wsDisplay.Range(wsDisplay.Cells(2, 4 + intStaffCount - intRowCount).Address, wsDisplay.Cells(2, 2 + intStaffCount).Address).Merge  
  wsDisplay.Range(wsDisplay.Cells(2, 4 + intStaffCount - intRowCount).Address).Interior.Color = RGB(intColourPalette(intColumnLoop Mod 6 + 1, 1), intColourPalette(intColumnLoop Mod 6 + 1, 2), intColourPalette(intColumnLoop Mod 6 + 1, 3))  
  wsDisplay.Cells(2, 4 + intStaffCount - intRowCount).Value = wsStaff.Cells(1, intColumnLoop).Value  
  wsDisplay.Cells(2, 4 + intStaffCount - intRowCount).Font.Bold = True  
  wsDisplay.Cells(2, 4 + intStaffCount - intRowCount).Font.Color = RGB(255, 255, 255)  
  intColumnLoop = intColumnLoop + 1  
Loop While Not intColumnLoop > intColumnCount  
wsDisplay.Cells(1, 1).EntireRow.Orientation = -45  
wsDisplay.Cells(1, 1).EntireRow.HorizontalAlignment = xlRight  
wsDisplay.Range(wsDisplay.Cells(1, 3), wsDisplay.Cells(2, intStaffCount + 2)).Borders.LineStyle = xlContinuous  
intDisplayRowLength = wsDisplay.Cells(1, Columns.Count).End(xlToLeft).Column  
intEraser = intStaffCount + 3  
wsDisplay.Range(wsDisplay.Cells(1, intEraser), wsDisplay.Cells(1, intDisplayRowLength)).EntireColumn.Delete Shift:=xlToLeft  
End Sub

所以我有两个问题,都涉及代码跳回行和重新执行代码。我通过在不同的变量条件下将几乎所有代码都放在断点上的代码单步执行数百次来弄清楚这一点。

每当重新定义 intRowCount 时,代码经常会跳回到开头,此错误对输出无害,但会显着增加计算时间。我知道这可能内置在 Do 循环中,因此很不方便,但不是最大的问题。

最大的问题是倒数第二行,删除所有不必要的列后,代码会跳回最后一个 end if 语句,它位于嵌套的 do 循环内。我不知道它为什么会跳回来,最重要的是,intRowCount、intRowLoop、intColumnCount 和 intColumnLoop 变量似乎发生了变化,以允许代码的重复循环。

之所以如此灾难性,是因为 intStaffCount 没有改变,这意味着数据被添加了两次。

如果有人能提供任何见解,将不胜感激。

编辑:它跳到代码中添加新项目的位置,并在到达倒数第二行时选择无限这样做。

编辑 2:它实际上到达了 End Sub 行,只是没有结束

编辑 3:在所示代码之外找到解决方案,必须在调用子之前禁用事件并在之后重新启用事件

【问题讨论】:

  • 您是否一直在使用Locals Window和Immediate Window来帮助您调试?
  • 不,我没有,不确定那是什么,但我会查一下,只是一直在使用断点并将鼠标悬停在变量上以查找它们的值。我只使用 vba for excel 大约两个星期。
  • 运行可能删除行或列的循环时的标准建议是向后工作 - 从最底部的行或最右侧的列开始。否则,您会通过尝试跟踪您当前应该查看的行/列来增加复杂性。此外,wsStaff.Range(wsStaff.Cells(intRowLoop, intColumnLoop).Address).Delete Shift:=xlUpwsStaff.Cells(intRowLoop, intColumnLoop).Delete Shift:=xlUp 相同
  • 山姆,这是你的幸运日。因为他们太棒了。转到查看,本地窗口,然后单步执行您的代码。你不需要研究它,因为它是不言自明的。立即窗口非常适合仅输入变量并查看与其关联的立即值。研究如何使用即时窗口。
  • 调用Worksheet_Change 过程是否在调用此Sub 之前禁用事件?如果不是,那么如果Worksheet_Change 过程与wsStaffwsDisplay 相关,您很可能会重复触发该事件。尝试暂停程序的执行并查看调用堆栈(通过 View > Call Stack)

标签: vba excel


【解决方案1】:

问题不在我的模块代码中,而是在事件代码中,通过在调用程序时禁用事件,问题得到解决。感谢 barrowc 的解决方案。

【讨论】:

    猜你喜欢
    • 2013-12-13
    • 1970-01-01
    • 1970-01-01
    • 2020-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-16
    • 1970-01-01
    相关资源
    最近更新 更多