基于 Matt Hall 的回答,但经过更改以显示您可以如何通过 Access:
- 调用
ThisWorkbook以外的Excel模块;
- 调用 Excel Subs 或从 Excel 函数中检索值;和
- 获取通过引用传递的参数的atlered 值。
在 Excel 中名为 basTextModule 的自定义模块中:
Public Sub ShowCoolMessage()
MsgBox "cool"
End Sub
' Add02 is explictly ByRef (the default in VBA) to show that
' the parameter will be altered and have its value changed even for
' prodedures higher up the call stack.
Public Function GetCoolAmount(Add01 As Variant, _
Optional ByRef Add02 As Integer) As Integer
Add02 = Add02 + 1
GetCoolAmount = 10 + Add01 + Add02
End Function
访问中:
- 设置对 Excel 的引用(VBA IDE > 工具 > 参考 ... Microsoft Excel 16.0 对象库)。
- 然后创建一个(有点)通用的 RunExcelCode ...
对于通过引用传递给工作的参数:
-
Microsoft Docs, Application.Run method (Excel) 请注意,当您将参数传递给 Excel 子程序或函数时,“您不能在此方法中使用命名参数。参数必须按位置传递”。
-
当声明 excelApp 使用Object 而不是Excel.Application 以确保可以检索通过引用传递给excelApp.Run 的任何参数的值。资料来源:Jaafar Tribak "Application.Run .. (Argument Passed ByRef)" at https://www.mrexcel.com/board/threads/application-run-argument-passed-byref.998132/post-4790961
-
在被调用的子函数或函数中,参数(除了第一个ModuleAndSubOrFunctionName)必须具有与调用模块或函数的参数数据类型相匹配的数据类型。它们可以是变体或特定的数据类型。例如,出于说明目的,Arg02 是一个整数,因此在使用 RunExcelCode(WorkbookPathAndFileName, "basTestModule.GetCoolAmount" ...) 时,GetCoolAmount 的第二个参数也必须如此。
但是,为了使您的RunExcelCode 更通用,确保Arg01、Arg02、...Arg30 参数都是变体可能是明智的;因此,您最终调用的子函数或函数的参数也是变体,例如 ...
Public Function GetCoolAmount(Add01 As Variant, _
Optional ByRef Add02 As Variant) As Integer
...
Public Function RunExcelCode(WorkbookPathAndFileName As String, _
ModuleAndSubOrFunctionName As String, _
Optional ByRef Arg01 As Variant, _
Optional ByRef Arg02 As Integer) As Variant
' Must be Object, not Excel.Application, to allow for parameters pass by reference
Dim excelApp As Object
Dim workbook As Excel.workbook
Dim Result As Variant
On Error GoTo HandleErr
' Can be Excel.Application if excelApp previously declared as Object
Set excelApp = New Excel.Application
' excelApp.Visible = True ' For debugging
Set workbook = excelApp.Workbooks.Open(WorkbookPathAndFileName)
' Get a value from a function or,
' if it is a sub a zero length string "" will be returned
Result = excelApp.Run(ModuleAndSubOrFunctionName, Arg01, Arg02)
RunExcelCode = Result
ExitHere:
workbook.Close
excelApp.Quit
Set workbook = Nothing
Set excelApp = Nothing
Exit Function
HandleErr:
Select Case Err.number
Case Else
MsgBox "Error " & Err.number & ": " & Err.Description, _
vbCritical, "RunExcelCode"
End Select
Resume ExitHere
End Function
测试(来自 Access),调用 Sub 和 Function:
Private Sub TestRunExcelCode()
Dim WorkbookPathAndFileName As String
Dim Result As Variant
WorkbookPathAndFileName = "C:\Users\YourName\Documents\MyWorkbook.xlsm"
' Run a sub
Result = RunExcelCode(WorkbookPathAndFileName, "basTestModule.ShowCoolMessage")
If IsNull(Result) Then
Debug.Print "{Null}"
ElseIf Result = "" Then
Debug.Print "{Zero length string}"
Else
Debug.Print Result
End If
' Will output "{Zero length string}"
' Get a value from a function
Dim Arg02 As Integer
Arg02 = 1
Debug.Print "Arg02 Before: " & Arg02
Result = RunExcelCode(WorkbookPathAndFileName, _
"basTestModule.GetCoolAmount", 1, Arg02)
Debug.Print "Arg02 After : " & Arg02 ' Value will have changed, as desired.
Debug.Print "Result : " & Result
End Sub
编辑 01:使代码更通用的重大更改。
编辑 02:处理通过引用传递的参数的重大更改。
编辑 03:在“使您的 RunExcelCode 更通用”的案例中添加了详细信息。