OLE自动化和与另一个VBE / VBA IDE交互



我熟悉OLE自动化和控制其他应用程序从给定的VBA IDE/VBE(特别是Excel的VBE)。虽然我知道可以使用SendKeys方法来完成我想要做的事情,但我觉得它在某些情况下可能不可靠(更不用说有点草率了)。

简而言之,我试图从Excel内编写一个VBA模块到文本文件(已经弄清楚了这一点),然后有一个目标应用程序的VBA IDE导入模块并执行代码。

我这样做的主要原因是,关于目标应用程序,Excel可用的参考库有局限性(然而,正如人们所期望的那样,目标应用程序的VBA IDE有更多的属性和方法可以使用,因为它的参考库是特定于应用程序本身的,原因很明显)。

关于如何最好地完成这一点,有什么想法吗?

如果只是创建一个自定义的COM引用或调整和现有的一个会更好吗(我认为这是相当困难的,因为我不熟悉c#或Visual Studio)?

(注意:如果你想知道,我正在使用Reflection Sessions (IBM, for Windows),并且对我正在使用的主要COM (EXTRACOM)有相当广泛的接触。)在Reflection Sessions VBE中,有一些方法,如.GetFieldText(无论应用程序游标放在给定字段上的哪个位置,它都会返回整个字段名)。这可能比EXTRACOM的.GetString更有用,后者要求程序员首先指定字段长度和光标位置。另一个属性方法:.GetFieldColor(它将返回字段颜色的数字代码,EXTRACOM (Excel的反射参考文件)缺乏的属性/方法。

我不清楚OP在这里到底想做什么。

当从反射外部调用时,似乎反射类型库不可靠,因此解决方案似乎涉及使用Application.Run或自动化VBE。

有两种方法可以实现:

  1. 在Excel的实例中有反射调用VBA函数(我在这里显示的示例),但是如果您可以获得对反射VBE的引用,您可以将其反转并从Excel中调用反射VBA。

  2. 让Reflection从Excel的vbProject(s)中导出模块,然后将它们导入到Reflection的vbProject(s)中

幸运的是,VBA使这两种方法都成为可能。对于这两种方法,您都需要添加对ExcelVisual Basic for Applications Extensibility的引用

使用Application.Run调用另一个VBA主机中的函数

使用Application.Run,我们可以在Excel项目中调用函数(我们甚至可以在调试时从一个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 我没有反射,所以这里我的代码在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:TempModule1.bas"
  'Import the module into the Access project
  Application.VBE.VBProjects("Database11").VBComponents.Import "C:TempModule1.bas"
End Sub

最新更新