【问题标题】:"Excel has stopped working" when using VBA macro with on change event将 VBA 宏与更改事件一起使用时,“Excel 已停止工作”
【发布时间】:2025-12-01 18:10:01
【问题描述】:

我遇到了一致的“Excel 已停止工作”错误。我有一个用户表单,它根据用户在第一个组合框中选择的内容填充具有相关下拉选项的组合框。

当用户在第二个组合框中键入一个与现有值相对应的字母时,该错误是始终为我的 ANY 我的 on-change 事件 subs 创建的在第二个盒子里。如果用户从下拉列表中选择一个选项,它不会发生——只有当用户键入匹配值的第一个字母时。

示例:如果第一个组合框是“水果”,那么第二个组合选项可能是“Apple”、“Orange”等。如果用户在第二个框中键入“A”或“O”(因为它匹配对应的值),它会使 Excel 崩溃。为什么它不像在第一个组合框中那样简单地“填充”匹配值?

错误处理已经到位,但它从来没有在代码中抛出这个错误,只有“excel已经停止工作”,然后崩溃。

我是否需要在宏中使用启用/禁用工作表事件?如果是这样,请提供有关如何实施的建议并解释其工作原理。我已经通过简单地将它们转换为单击按钮来解决以前的 On Change 问题,但我更愿意学习如何更好地实施 On Change没有错误的事件。

谢谢!下面是一些我认为与 Excel 崩溃相关的示例代码:

Private Sub Option1_Change()

On Error GoTo Option1_Change_Error
'Set cell H4 as value entered in Opt1 (adv. filter criteria)
Sheet6.Range("H4").Value = Me.Option1.Value
'Run macro AdvFilter which sets criteria for dependent drop-down box
AdvFilter
   Me.Option2.Value = ""
'Set row source as output of adv filter
Me.Option2.RowSource = "AdvFilter_Output"
'Set list box content
'If no adv.filter output, then blank listbox
If Sheet2.Range("BZ3").Value = "" Then
    Me.lstOptions.RowSource = ""
Else
    Me.lstOptions.RowSource = "AdvFilter_Output"
End If
Exit Sub

Option1_Change_Error:
MsgBox "An error has occurred.  " _
    & vbCrLf & "" _
    & vbCrLf & "" _
    & "Error " & Err.Number & " (" & Err.Description & ") in procedure Option1_Change_Error of Form frmOptions"
End Sub




Private Sub Option2_Change()

On Error GoTo Option2_Change_Error
If Me.Option1 = "" And Me.Option2 <> "" Then
    MsgBox "Select a the category first to see the corresponding options that exist."
    Exit Sub
    Else
    Me.Option2.RowSource = ""
End If
Exit Sub

Option2_Change_Error:
MsgBox "An error has occurred.  " _
    & vbCrLf & "" _
    & vbCrLf & "" _
    & "Error " & Err.Number & " (" & Err.Description & ") in procedure Option2_Change_Error of Form frmOptions"
End Sub

【问题讨论】:

  • 您是否使用调试器浏览过这段代码?它在哪条线上窒息?如果您还没有,我强烈建议您在函数的第一行设置断点,然后逐行执行代码以了解是什么破坏了它。它还会告诉你是否是这段代码破坏了它——如果你的断点从不跳闸(但 excel 仍然崩溃),它可能完全是另外一回事。
  • 首先想到的是:AdvFilter_Output 是什么?您是否将命名范围分配给这样的行源?我本来希望 RowSource 采用 Range...
  • @tobriand 感谢您的回复。 AdvFilter_Output 是一个动态命名范围,用于保存高级过滤器的输出数据。当用户填写第一个组合框作为视觉辅助时,它会自动填充一个列表框,以向用户显示他们选择的类别的记录中已经存在哪些选项。根据用户在第一个组合框中选择的内容,AdvFilter_Output 也成为第二个组合框的行源。您能否澄清关于命名范围和行源的第二个问题?
  • 通常当我为 RowSources 之类的内容分配字段时(例如在定义名称时),我发现如果我不小心,它最终会分配一个字符串而不是我的实体想要它,这显然是行不通的。我基本上想知道是否正在发生类似的事情。如果是这种情况,将其更改为 "=AdvFilter_Output" 可能会完成这项工作(它会明确意识到您的意思是那个名字)。
  • 其他的想法,现在你说的动态命名范围,就是作用域。可以想象它是一个工作表范围的名称,但它正在寻找工作簿,反之亦然。不过,这会让 Excel 崩溃会很奇怪......

标签: excel onchange vba


【解决方案1】:

想通了,这要归功于能够从 Tobriand 中汲取一些想法并解决一些可能的问题。 由于 Option2 中的 else 子句不合适,问题最终成为两个事件之间的行源冲突。

Private Sub Option2_Change()change 上将第二个组合框的Rowsource 设置为空白,从而无法输入任何内容。 match entry 属性设置为 False,但我认为删除组合框 2 的行源会导致 match entry complete 属性在用户输入某些内容但找不到匹配项时吓坏了。 我从 Option2 事件中删除了 else 部分,现在它似乎可以工作了。

【讨论】:

  • 很高兴听到你把它整理好了!自动完成在 Excel 中总是让我觉得有点轻量级;听起来这是另一个有用的,直到它不是功能。我想,执行顺序必须是 change --> your-event --> 他们的事件。我可以理解为什么这是合乎逻辑的,但确实突出了 VBA 在处理本机错误方面的缺点,不是吗?
最近更新 更多