vba callback

Devolución de llamada personalizada en VBA



callback (1)

No hay otras respuestas en una semana ... por la resolución, aquí está lo mejor que pude encontrar:

  1. Creé un módulo auxiliar que resuelve un ParamArray a argumentos individuales por llamar a CallByName . Si pasas una ParamArray a CallByName convertirá todos los argumentos en una única Array real y la pasará al primer argumento del método que intentas invocar.
  2. ForEach dos métodos ForEach : uno que invoca Application.Run y otro que invoca CallByName . Como se señala en la pregunta, Application.Run solo funciona para los métodos globales definidos por el usuario (módulo público). A su vez, CallByName solo funciona en métodos de instancia y requiere un argumento de objeto.

Eso todavía me deja sin una forma de invocar directamente métodos globales incorporados (como Trim() ) por nombre. Mi solución para eso es crear métodos de contenedor definidos por el usuario que solo llamen al método global incorporado, por ejemplo:

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...

Ahora puedo usar estos para hacer cosas como:

'' 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")

Tenga en cuenta la etiqueta: VBA , no VB6, no VB.NET.

Esto es específico de VBA en MS Access. Construí una colección de métodos en un módulo que llamo "Enumerable". Hace muchas cosas que recuerdan las clases Enumerable y las interfaces en .NET. Una cosa que quiero implementar es un método ForEach, análogo al método .Enumerable de .NET.

Creé una versión que usa el método Application.Run para llamar a una función para cada elemento, pero Application.Run solo funciona con métodos definidos por el usuario. Por ejemplo, los siguientes trabajos:

'' 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

RunTest imprime "Salida", como se esperaba. Lo siguiente NO funciona:

Debug.Print Run("Replace", "Input", "In", "Out")

Lanza el error 430 en tiempo de ejecución: "La clase no admite automatización o no admite la interfaz esperada". Esto es esperado, porque la documentación indica que Application.Run solo funciona para los métodos definidos por el usuario.

VBA tiene un operador AddressOf, pero eso solo funciona al pasar punteros a las funciones API externas; los punteros de función creados con AddressOf no son consumibles en VBA. De nuevo, esto se observa en la documentación (o ver, por ejemplo, VBA - CallBacks = ¿Hay pocos centavos menos que un dólar? ).

Entonces, ¿hay alguna otra manera de identificar y llamar a un método usando una variable? ¿O mis intentos de devolución de llamada se limitarán a las funciones definidas por el usuario a través del método Application.Run?