OLE自动化并与另一个VBE / VBA IDE交互
我熟悉OLE自动化,并从给定的VBA IDE / VBE(特别是Excel的VBE)控制其他应用程序。 虽然我知道可以使用SendKeys方法来实现我想要做的事情,但是我觉得在某些情况下它可能是不可靠的(更不用说有点sl)了)。
简而言之,我试图从Excel内部编写一个VBA模块到文本文件(已经计算出来了),然后让目标应用程序的VBA IDE导入模块并执行代码。
我的主要推论是,针对所述目标应用程序可用于Excel的参考库具有限制(正如人们所期望的那样,目标应用程序的VBA IDE具有更多的属性和方法来处理,因为其参考库特定于应用程序本身,显而易见的原因)。
任何想法如何最好地完成这个?
最好是创build一个自定义的COM引用或调整和现有的(我会认为这是相当困难的,因为我不熟悉C#或Visual Studio)?
(注意:如果您想知道,我正在使用Reflection Sessions(IBM,适用于Windows),并且对我正在使用的主要COM(EXTRACOM)进行了相当广泛的介绍,在Reflection Sessions VBE中有一些方法.GetFieldText
(无论应用程序光标放在给定字段的哪个位置,都会返回整个字段的名称,这比EXTRACOM的.GetString
有用,它需要程序员指定字段长度和光标位置)另一个属性方法: .GetFieldColor
(它将返回字段颜色的数字代码,EXTRACOM(用于reflection的Excel参考文件)缺less的属性/方法。
我不清楚OP究竟在这里做什么。
似乎reflection类库在reflection之外调用时不可靠,所以解决scheme似乎涉及使用Application.Run
或自动化VBE。
有两种方法可以实现这一点:
-
在Excel的实例(我在这里展示的例子)中有reflection调用VBA函数,但是如果您可以获得对Reflection VBE的引用,则可以反转此操作并从Excel调用Reflection VBA。
-
有reflection从Excel的vbProject(s)导出模块,然后将其导入到Refelction vbProject(s)中。
幸运的是,VBA使两种方法成为可能。 对于这两种方法,您都需要添加对Excel
和Visual Basic for Applications Extensibility
引用
使用Application.Run
在另一个VBA主机中调用函数
使用Application.Run
,我们可以调用Excel项目中的函数(我们甚至可以在debugging时从一个VBE跳到另一个VBE,我们可以传递参数,并且可以接收返回值。
Sub CallExcelUDFFromNonExcelHost() 'Get an existing instance of Excel Dim appXL As Excel.Application Set appXL = GetObject(, "Excel.Application") 'Get the already opened Excel workbook Dim wbk As Excel.Workbook Set wbk = appXL.Workbooks("MyExcelFunctions.xlsm") 'Call the function in the Excel workbook Dim result result = appXL.Run(wbk.VBProject.Name & ".MyFunction", "Some Argument") End Sub
自动化外部VBA主机的VBE我没有reflection,所以这里我的代码在Access中运行,并从Excel导入模块。
Sub ImportVBAModuleFromOtherIDE() 'Get an existing instance of Excel Dim appXL As Excel.Application Set appXL = GetObject(, "Excel.Application") 'Get the already opened Excel workbook Dim wbk As Excel.Workbook Set wbk = appXL.Workbooks("MyExcelFunctions.xlsm") 'Export a module from Excel wbk.VBProject.VBComponents("Module1").Export "C:\Temp\Module1.bas" 'Import the module into the Access project Application.VBE.VBProjects("Database11").VBComponents.Import "C:\Temp\Module1.bas" End Sub