Excel:错误中断在用户定义函数中不起作用

发布于 2024-11-19 09:49:25 字数 636 浏览 3 评论 0原文

似乎当从单元格公式(即“用户定义函数”或 UDF)调用 VBA 代码时,通常的 VBA Break On Error 不起作用。

我唯一能找到记录此行为的地方是一篇名为 “为 Excel 2007 和 Excel Services 开发用户定义的函数”

错误处理返回 #VALUE 错误。 UDF 代码引发的所有异常都会作为 #VALUE 错误返回到 Excel 工作表中。

即使您将错误捕获设置为“出现所有错误时中断”并单步执行代码**,您也永远不会看到 VBA 运行时错误对话框 - Excel 只是悄悄地放弃执行,而不告诉您出了什么问题。当然,这使得调试变得比实际需要的更加困难。

有一些涉及On Error的潜在解决方法,但我不想为了找出引发错误的位置而弄乱我的代码。

是否有一些我忽略的 Excel/VBA 选项可以使“错误中断”正常工作?我使用的是 Excel 2003。

** 从单元格调用时进入调试器的唯一方法是设置断点或使用 Stop 语句

It seems that when VBA code is called from a cell formula (ie. a "User Defined Function" or UDF), the usual VBA Break On Error doesn't work.

The only place I can find this behavior documented is a couple of lines in an article called "Developing User-Defined Functions for Excel 2007 and Excel Services":

Error handling returns #VALUE errors. All exceptions thrown by the UDF code are returned into the Excel worksheet as #VALUE errors.

Even if you set Error Trapping to "Break on All Errors" and single-step your code**, you will never see the VBA Run-time Error dialog - Excel just quietly abandons execution without telling you what went wrong. Of course this makes debugging more difficult than it needs to be.

There are some potential workarounds involving On Error but I'd rather not clutter up my code just to find out where an error was raised.

Is there some Excel / VBA option I've overlooked which will make Break On Error work normally? I'm using Excel 2003.

** The only way to get into the debugger when called from a cell is to set a breakpoint or use a Stop statement

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

疧_╮線 2024-11-26 09:49:25

最好的方法是使用 On Error GoTo ErrorHandler 以及 Stop 引用,后跟 Resume

需要小心,不要进入 resume 的无限循环,因为 UDF 几乎连续运行(如果发生这种情况,请重复按 Esc),

因此在代码中添加: On错误 GoTo ErrorHandler 靠近函数的开头,然后在 End Function 之前的末尾:

Exit Function
ErrorHandler:
MsgBox Err.Number & vbCrLf & Err.Source & vbCrLf & Err.Description
Stop
Resume

Exit Function 会停止此代码在正常操作中运行。
如果遇到错误,将弹出包含详细信息的消息框,代码将中断(由于 Stop),您可以单步返回代码(通过 resume 跳回) code> 语句)使用调试工具栏上的下一行命令。

当然,当您对 UDF 感到满意时,请不要忘记注释掉 On Error GoTo ErrorHandler 行。

Best method would be to use the On Error GoTo ErrorHandler with a Stop reference followed by Resume.

Need to be careful not to get into an infinite loop with resume as UDFs run almost continually (if this happens hit Esc repeatedly)

So in your code add: On Error GoTo ErrorHandler near the start of your function and then right at the end before End Function:

Exit Function
ErrorHandler:
MsgBox Err.Number & vbCrLf & Err.Source & vbCrLf & Err.Description
Stop
Resume

The Exit Function stops this code running in normal operation.
If an error is encountered a messagebox with the details will pop up, the code will break (due to Stop) and you can step through back into your code (hopping back via the resume statement) using the next line command on the debug toolbar.

Of course don't forget to comment out the On Error GoTo ErrorHandler line when you're happy with your UDF.

尝蛊 2024-11-26 09:49:25

我知道,当您特别要求 On Error 之外的其他内容时,听到这个消息并不有趣,但据我所知,这恐怕是唯一的选择。

您可以在调试时使用 On Error Goto ErrorHandler(并在其他时候将其注释掉以获取默认的 On Error Goto 0)。 ErrorHandler 可以只有几行,这样就不会让您的代码变得过于混乱:

ErrorHandler:
    MsgBox Err.Number & vbCrLf & Err.Source & vbCrLf & Err.Description
    Resume 

始终在 Resume 上设置一个断点,以引导您回到导致错误的地方单步执行时的语句——并避免无限的错误处理循环。

I'm aware that it isn't any fun hearing this when you specifically asked for something else than On Error, but I'm afraid it's the only option to my knowledge.

You could just use On Error Goto ErrorHandler while debugging (and comment it out to get the default On Error Goto 0 at other times). The ErrorHandler could have just a couple of lines so it doesn't clutter up your code too much:

ErrorHandler:
    MsgBox Err.Number & vbCrLf & Err.Source & vbCrLf & Err.Description
    Resume 

always with a breakpoint on Resume to guide you back to the error-causing statement upon stepping -- and to avoid an infinite error-handling loop.

何止钟意 2024-11-26 09:49:25

我最近也遇到了这个。我真的以为有些东西已经改变了,而且并不总是这样 - 但我想我错了。

以下可能是对所建议内容的一个小改进。我添加了一个调试?提示消息框,以便您可以调试或不调试。所以没有无限循环。导致错误的行会突出显示。

假设这是我原来的功能:

Function MyFunction(input_value)
   a = 1
   b = 1 / 0
   MyFunction = 1 + input_value ^ 2
End Function

如果我怀疑有问题,那么我将添加如下三行:

Function MyFunction(input_value)
On Error GoTo DebugError
    a = 1
    b = 1 / 0
    MyFunction = 1 + input_value ^ 2
Exit Function
DebugError: If MsgBox(Err.Description & vbCrLf & "Debug(F8,F8)?", vbYesNo) = vbYes Then Stop: Resume
End Function

然后,当发生错误时:

  1. 会弹出一个包含错误的消息框。
  2. 单击“是”进行调试,或单击“否”继续。
  3. 单击“是”将打开 VBA 代码。
  4. 按 F8 两次以突出显示导致错误的行。

screenshot

这有点麻烦,但也不算太糟糕。如果在调试时发生错误,那没有问题。您只需按 F8、YES、F8、F8 即可返回。

请注意,错误捕获必须设置为“未处理错误时中断”或“类模块中中断”。

I ran into this recently also. I really thought something had changed and it didn't always work like this -but I guess I was wrong.

Below is a perhaps a small improvement on what has been suggested. I added a Debug? prompt to the message box so that you can either debug or not. So no infinite loops. And the line causing the error is highlighted.

Say this is my original function:

Function MyFunction(input_value)
   a = 1
   b = 1 / 0
   MyFunction = 1 + input_value ^ 2
End Function

If I suspect a problem, then I'll add three lines like this:

Function MyFunction(input_value)
On Error GoTo DebugError
    a = 1
    b = 1 / 0
    MyFunction = 1 + input_value ^ 2
Exit Function
DebugError: If MsgBox(Err.Description & vbCrLf & "Debug(F8,F8)?", vbYesNo) = vbYes Then Stop: Resume
End Function

Then when an error happens:

  1. A message box pops up with the error.
  2. You click YES to debug, or NO to continue.
  3. Clicking YES opens the VBA code.
  4. Press F8 twice to highlight the line causing the error.

screenshot

This is some trouble, but not too bad. If an error happens while you're debugging, it's no problem. You just hit F8, YES, F8, F8 to get to back in.

Note that Error Trapping must be set to Break on Unhandled Errors, or Break in Class Module.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文