Uwaga na tag: VBA, a nie VB6, a nie VB.NET.Niestandardowe wywołania zwrotne w języku VBA
Jest to specyficzne dla VBA w MS Access. Zbudowałem kolekcję metod w module, który nazywam "Enumerable". Ma wiele rzeczy przypominających klasy i interfejsy Enumerable w .NET. Jedną z rzeczy, którą chcę zaimplementować, jest metoda ForEach, analagiczna dla .NET Enumerable.Select method.
Zbudowałem wersję, która używa metody Application.Run do wywołania funkcji dla każdego elementu, ale Application.Run działa tylko z metodami zdefiniowanymi przez użytkownika. Na przykład następujące prace:
' 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
Funkcja RunTest drukuje "Wyjście" zgodnie z oczekiwaniami. Poniższa nie działa:
Debug.Print Run("Replace", "Input", "In", "Out")
To wyrzuca błąd run-time 430: „Klasa nie obsługuje automatyzacji lub nie obsługuje oczekiwanego interfejsu”. Jest to oczekiwane, ponieważ dokumentacja stwierdza, że Application.Run działa tylko dla metod zdefiniowanych przez użytkownika.
VBA ma operatora AddressOf, ale działa to tylko przy przekazywaniu wskaźników funkcji do zewnętrznych funkcji API; wskaźniki funkcyjne utworzone za pomocą AddressOf nie są przydatne w VBA. Ponownie, jest to odnotowane w dokumentacji (lub zobacz na przykład VBA - CallBacks = Few Cents Less Than A Dollar?).
Czy istnieje inny sposób identyfikacji i wywołania metody przy użyciu zmiennej? Czy moje próby wywołania zwrotnego będą ograniczone do funkcji zdefiniowanych przez użytkownika za pomocą metody Application.Run?
wont być w stanie używać adresu, ale VBA obsługuje klasy, więc wywołania zwrotne oparte na interfejsie są w porządku; 'sub coś (arg as string, myCallBack jak IWhatever) ... myCallBack.call (...)' Wypchaj swoje metody do klasy i możesz wywoływać je po nazwie za pomocą "CallByName" - jest to trochę słabe ze względu na obsługę dynamicznej liczby argumentów, alternatywa http://www.devx.com/tips/Tip/15422 –
Jestem trochę zdezorientowany tym, z czym naprawdę potrzebujesz pomocy. Twój pierwszy akapit mówi o implementacji 'For ...Każda z nich, ale reszta twojego pytania mówi o próbie użycia 'Application.Run' na funkcji VBA. – mischab1
@ mischab1 - Spójrz na dowolne metody rozszerzeń .NET IEnumerable. W większości z nich zapewniasz wywołanie zwrotne do wykonania dla każdego członka kolekcji. Próbuję zrobić to samo w VBA. VBA nie ma delegatów ani wskaźników funkcji, ani niczego. Użyłem Application.Run jako substytutu, ale ma ograniczone zastosowanie. –