我创建了一个简单的工具,可以将 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
而不是抛出异常。
有什么方法可以拦截(或阻止)这个消息框吗?
嘿,导出 VBA 代码并将其存储在源代码管理中的好主意。
在自动化过程中,当 VBA 中存在编译错误时,拦截或阻止 Excel 显示的消息框可能具有挑战性。这主要是因为这些对话框由主机应用程序 (Excel) 管理,而不直接暴露给您正在使用的自动化界面(如 .NET 或 VBA)。但是,您可以考虑采取一些策略来处理或绕过这些问题:
拦截这些 MessageBox 的一种方法是使用 Windows API 自动查找并关闭这些对话框。这种方法涉及在应用程序中设置一个挂钩来侦听对话框创建事件,然后在它们符合特定条件(例如窗口标题或类)时关闭它们。
以下是如何实现这一点的粗略概述:
如果您使用 .NET,此方法要求 P/Invoke 使用 Windows API 函数。它可能非常复杂,可能需要仔细处理以确保它不会干扰合法的对话框或其他应用程序。
另一种方法是在尝试编译之前以编程方式检查 VBA 项目是否有错误。这可以通过自己解析 VBA 代码或使用某种形式的静态分析来完成。这是一个基本想法:
如果您正在开发 Excel 加载项,您也许能够直接在 Excel 中处理某些事件。然而,由于环境的限制,直接通过Excel VBA或加载项拦截MessageBox通常是不可能的。
作为最后的手段,您可以考虑使用外部自动化工具,例如 AutoIt 或 AutoHotkey。这些工具可以与 Windows 上的 GUI 元素交互,并且可以编写脚本,通过根据窗口标题或内容检测消息框的存在来关闭消息框。
这是 AutoHotkey 中的一个简单脚本,用于检测并关闭 MessageBox:
Loop
{
WinWait, Microsoft Excel, If there are something that prevents a compilation
{
WinClose ; Closes the active window
}
}
该脚本不断检查具有特定标题的窗口(根据需要调整标题)并立即关闭它们。
每种方法都有其优点和缺点,选择取决于您的具体环境、所需的控制级别以及自动化工作流程的这方面的重要性。 Windows API 和外部工具提供了最多的控制,但需要仔细实施以避免意外的副作用。