【发布时间】:2014-04-17 14:24:36
【问题描述】:
我正在开发一个旧的VBA 程序的C# 和VB.NET 端口。它有很多 MSForms/OleObjects 嵌入其中,例如 CommandButton 甚至图像。
我的第一个想法是将所有按钮声明为Microsoft.Vbe.Interop.Forms.CommandButton,但这会导致COM 异常,即System._COM type 无法转换为...Forms.CommandButton。如果我尝试更通用的this solution 版本,我找不到任何项目,如果我尝试遍历所有VBComponets,我注意到它们是workbook 中的所有工作表,但没有一个控制:
foreach (VBComponent xxx in Globals.ThisWorkbook.VBProject.VBComponents) {
Interaction.MsgBox(xxx.Name);
Interaction.MsgBox(xxx.ToString);
}
因此所有这些控件都不在.VBComponets 中,但我可以在thisworkbook.worksheets(n).OLEobjects 中找到它们作为OLEobjects(这对我来说是违反直觉的,但我可能不理解系统开始)。
如何处理来自此类对象的 Click 操作?
我假设我需要使用Excel.OLEObjectEvents_Event 接口,但我似乎无法弄清楚如何使用。如果我尝试使用delegates 制作自定义事件,我似乎无法将它们分配给OleObjects。如果我使用ActionClickEventHandler.CreateDelegate,我会遇到各种各样的错误,这让我觉得这是一条死胡同。
MS 的official documentation 似乎没有多大帮助,尽管它确实向我介绍了Verb 的idea,我正在研究它。到目前为止,这只产生了类似于“应用程序无法启动”的 COM 错误。
即使只是尝试使用两个标准事件之一,.GotFocus,我总是会拉出 0x80040200 错误。
示例:
Excel.OLEObject ButtonCatcher = Globals.ThisWorkbook.Worksheets(1).OLEObjects("CommandButton1");
ButtonCatcher.GotFocus += CommandButton1_Click;
在第二行抛出 COMException Exception from HRESULT: 0x80040200。该按钮已启用,这是我在查找code number from the office dev site.后检查的
在包含控件的工作表的代码中尝试更多 generic approach:
object CommandButtonStart = this.GetType().InvokeMember("CommandButton1", System.Reflection.BindingFlags.GetProperty, null, this, null);
引发缺少方法错误。
非常感谢任何帮助,这似乎应该是显而易见的,我很想念它。
**编辑:我还发现我可以将这些控件转换为Excel.Shape,但这实际上并没有让我更接近从 VSTO 运行函数或子程序。我在玩Excel.Shape.OnAction,但这需要调用 VBA 子程序。据推测,只要 VSTO 是 COM 可见的,我就可以调用从 VSTO 调用子的 VBA 子。这似乎真的很迂回,我只想作为最后的手段。
【问题讨论】:
-
您确定它们是否是工作表上的 ActiveX 控件吗?常规表单控件(非 activeX)不显示事件,只能通过 onAction 方法调用 subs。您可能会遇到哪些问题?
-
帮助我的无知。我发现 VBA 嵌入在 Office 软件程序(或采用它的其他程序之一)中。 VBA 不是独立的。那么
an old VBA program是什么? -
顺便说一句,但根据我的旅行社的说法,所有好的“最后的手段”都是“真正的迂回”。这几乎是一个规则。
-
@Kyle 它们是 ActiveX 控件,例如,可以通过 TructCenter 选项禁用 ActiveX 使其消失。
-
@Smandoli 当然,它不是一个完整的程序,但编程分类法不是我的强项(在 Bio.SE 上向我寻求实际分类法的帮助)。我们应该从 VSTO 中借用并将项目称为插件吗?我不介意任何人编辑该短语以使其更正确。我没有编写原始代码,也从未发现过 VBA。 VBA 解决方案?有组织的宏集合?我认为重点是,不是吗?