自动化过程中如何拦截VBE错误?

问题描述 投票:0回答:1

我创建了一个简单的工具,可以将 Excel 文件提取到文件夹中,相反,获取此文件夹并重新生成 Excel 文件。

此工具还将 VBA 代码提取到文本文件,以便更轻松地将它们存储在源代码管理中。

今天,我添加了一个新功能:VBA 代码“编译”。

这是我用来“编译”VBA 代码的代码:

var btnCompile = proj.VBE.CommandBars.FindControl(Type: 1, Id: 578);
try
{
    if ((btnCompile?.Enabled).HasValue && btnCompile.Enabled)
        btnCompile?.Execute();
}
catch (Exception ex)
{
    throw new VbaCompilationException("An error occurred.", ex);
}

一切都运行良好...当 VBA 代码正确编译时。

但是,如果存在阻止编译的情况,Excel 将显示

MessageBox
而不是抛出异常。

有什么方法可以拦截(或阻止)这个消息框吗?

excel vba vbe excel-automation
1个回答
0
投票

嘿,导出 VBA 代码并将其存储在源代码管理中的好主意。

在自动化过程中,当 VBA 中存在编译错误时,拦截或阻止 Excel 显示的消息框可能具有挑战性。这主要是因为这些对话框由主机应用程序 (Excel) 管理,而不直接暴露给您正在使用的自动化界面(如 .NET 或 VBA)。但是,您可以考虑采取一些策略来处理或绕过这些问题:

1.使用 Windows API 抑制消息框

拦截这些 MessageBox 的一种方法是使用 Windows API 自动查找并关闭这些对话框。这种方法涉及在应用程序中设置一个挂钩来侦听对话框创建事件,然后在它们符合特定条件(例如窗口标题或类)时关闭它们。

以下是如何实现这一点的粗略概述:

  • 设置 CBT 挂钩:使用 Windows SetWindowsHookEx 函数设置基于计算机的训练 (CBT) 挂钩,每当创建新窗口时都会收到通知。
  • 检查 MessageBox 窗口:在挂钩过程中,检查新窗口是否是 MessageBox。您可以通过检查窗口的类名来完成此操作。
  • 发送关闭消息:如果窗口是MessageBox,则发送消息以自动关闭它。

如果您使用 .NET,此方法要求 P/Invoke 使用 Windows API 函数。它可能非常复杂,可能需要仔细处理以确保它不会干扰合法的对话框或其他应用程序。

2.编译前检查 VBA 项目是否有错误

另一种方法是在尝试编译之前以编程方式检查 VBA 项目是否有错误。这可以通过自己解析 VBA 代码或使用某种形式的静态分析来完成。这是一个基本想法:

  • 解析 VBA 代码:使用解析器检查 VBA 代码是否存在语法错误。虽然这不会捕获可能阻止编译的所有类型的错误,但它可以帮助您识别明显的语法问题。
  • 报告错误:如果您的解析器发现任何错误,请将这些错误报告给用户或在尝试编译之前进行相应的处理。

3.通过 Excel 插件进行自定义错误处理

如果您正在开发 Excel 加载项,您也许能够直接在 Excel 中处理某些事件。然而,由于环境的限制,直接通过Excel VBA或加载项拦截MessageBox通常是不可能的。

4.外部自动化工具

作为最后的手段,您可以考虑使用外部自动化工具,例如 AutoIt 或 AutoHotkey。这些工具可以与 Windows 上的 GUI 元素交互,并且可以编写脚本,通过根据窗口标题或内容检测消息框的存在来关闭消息框。

使用 AutoHotkey 的示例:

这是 AutoHotkey 中的一个简单脚本,用于检测并关闭 MessageBox:

Loop
{
    WinWait, Microsoft Excel, If there are something that prevents a compilation
    {
        WinClose ; Closes the active window
    }
}

该脚本不断检查具有特定标题的窗口(根据需要调整标题)并立即关闭它们。

结论

每种方法都有其优点和缺点,选择取决于您的具体环境、所需的控制级别以及自动化工作流程的这方面的重要性。 Windows API 和外部工具提供了最多的控制,但需要仔细实施以避免意外的副作用。

© www.soinside.com 2019 - 2024. All rights reserved.