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

OLE Automation and interacting with another VBE / VBA IDE

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

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

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

关于如何最好地完成这项工作有什么想法吗?

创建自定义 COM 参考或调整现有的参考是否更好(我认为这相当困难,因为我不熟悉 C# 或 Visual Studio)?

(注意:如果您想知道,我正在使用 Reflection Sessions(IBM,针对 Windows),并且相当广泛地接触我正在使用的主要 COM (EXTRACOM)。在Reflection Sessions VBE 有诸如 .GetFieldText 之类的方法(它将 return 整个字段名称,而不管应用程序光标放在给定字段上的什么位置。这比 EXTRACOM 的 .GetString 这需要程序员首先指定字段长度和光标位置)。另一种 属性 方法:.GetFieldColor(这将 return 字段颜色的数字代码, property/method EXTRACOM(Excel 的反射参考文件)缺少。

我不清楚 OP 在这里实际想做什么。

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

有两种方法可以实现:

  1. 在 Excel 的实例中调用 VBA 函数(我在此处显示的示例),但如果您可以获得对 Reflection VBE 的引用,你可以反转它并从 Excel.

  2. 调用 Reflection VBA
  3. 让 Reflection 从 Excel 的 vbProject(s) 导出模块,然后将它们导入 Refelction vbProject(s)。

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

的引用

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

使用 Application.Run,我们可以调用 Excel 项目中的函数(我们甚至可以在调试时从一个 VBE step 到另一个。我们可以传递参数,我们可以收到 return 个值。

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:\Temp\Module1.bas"

  'Import the module into the Access project
  Application.VBE.VBProjects("Database11").VBComponents.Import "C:\Temp\Module1.bas"

End Sub