注意标签:VBA,而不是VB6,而不是VB.NET.
这特定于MS Access中的VBA.我在一个名为"Enumerable"的模块中构建了一组方法.它做了许多令人联想到.NET中的Enumerable类和接口的事情.我想要实现的一件事是ForEach方法,与.NET Enumerable.Select方法类似.
我构建了一个使用Application.Run方法为每个元素调用函数的版本,但Application.Run仅适用于用户定义的方法.例如,以下工作:
' User-defined wrapper function:
Public Function MyReplace( _
Expression As String, Find As String, StrReplace As String, _
Optional Start As Long = 1, _
Optional Count As Long = 1, _
Optional Compare As VbCompareMethod = vbBinaryCompare)
MyReplace = Replace(Expression, Find, StrReplace, Start, Count, Compare)
End Function
' Using Application.Run to call a method by name
Public Sub RunTest()
Debug.Print Run("MyReplace", "Input", "In", "Out")
End Sub
Run Code Online (Sandbox Code Playgroud)
RunTest按预期打印"输出".以下不起作用:
Debug.Print Run("Replace", "Input", "In", "Out")
Run Code Online (Sandbox Code Playgroud)
它抛出运行时错误430:"类不支持自动化或不支持预期的接口".这是预期的,因为文档声明Application.Run仅适用于用户定义的方法.
VBA确实有一个AddressOf运算符,但只有在将函数指针传递给外部API函数时才有效; 使用AddressOf创建的函数指针在VBA中不可使用.同样,这在文档中有说明(或者参见例如VBA - CallBacks =少量美元少于几美元?).
那么有没有其他方法来识别和调用使用变量的方法?或者我的回调尝试是否会通过Application.Run方法限制为用户定义的函数?
一周内没有其他答案......为了解决这个问题,我能想到的最好:
CallByName.如果你将ParamArray传递给CallByName它,它会将所有参数混合成一个实际的,Array并将其传递给你试图调用的方法中的第一个参数.ForEach方法:一个调用Application.Run,另一个调用CallByName.如问题中所述,Application.Run仅适用于用户定义的全局(公共模块)方法.反过来,CallByName只适用于实例方法,并需要一个对象参数.这仍然让我无法Trim()通过名称直接调用内置全局方法(例如).我的解决方法是构建只调用内置全局方法的用户定义的包装器方法,例如:
Public Function FLeft( _
str As String, _
Length As Long) As String
FLeft = Left(str, Length)
End Function
Public Function FLTrim( _
str As String) As String
FLTrim = LTrim(str)
End Function
Public Function FRight( _
str As String, _
Length As Long) As String
FRight = Right(str, Length)
End Function
...etc...
Run Code Online (Sandbox Code Playgroud)
我现在可以用这些来做这样的事情:
' Trim all the strings in an array of strings
trimmedArray = ForEachRun(rawArray, "FTrim")
' Use RegExp to replace stuff in all the elements of an array
' --> Remove periods that aren't between numbers
Dim rx As New RegExp
rx.Pattern = "(^|\D)\.(\D|$)"
rx.Global = True
resultArray = ForEachCallByName(inputArray, rx, "Replace", VbMethod, "$1 $2")
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11558 次 |
| 最近记录: |