Jak zwrócić wynik z funkcji VBA

Odpowiedzi:

429

W przypadku typów obiektów niebędących obiektami musisz przypisać wartość do nazwy swojej funkcji, tak jak poniżej:

Public Function test() As Integer
    test = 1
End Function

Przykładowe użycie:

Dim i As Integer
i = test()

Jeśli funkcja zwraca typ obiektu, musisz użyć Setsłowa kluczowego w ten sposób:

Public Function testRange() As Range
    Set testRange = Range("A1")
End Function

Przykładowe użycie:

Dim r As Range
Set r = testRange()

Należy pamiętać, że przypisanie wartości zwracanej do nazwy funkcji nie kończy wykonywania funkcji. Jeśli chcesz wyjść z funkcji, musisz wyraźnie powiedzieć Exit Function. Na przykład:

Function test(ByVal justReturnOne As Boolean) As Integer
    If justReturnOne Then
        test = 1
        Exit Function
    End If
    'more code...
    test = 2
End Function

Dokumentacja: http://msdn.microsoft.com/en-us/library/office/gg264233%28v=office.14%29.aspx

Dan
źródło
32
Dla kompletności należy zauważyć, że gdy zwracasz obiekt (jak Rangena przykład), musisz używać tego Setsamego, co robisz, jeśli ustawiasz zmienną obiektu w zwykłej metodzie. Gdyby na przykład „test” był funkcją, która zwróciła zakres, instrukcja return wyglądałaby tak set test = Range("A1").
Jay Carr
Dlaczego to jest @JayCarr?
PsychoData,
4
@PsychoData - Po prostu dlatego, że tak w ogóle ustawiasz zmienną obiektową, a wykonywanie jej bez setmoże prowadzić do problemów. Miałem problemy bez robienia tego, ale jeśli używam, setnie mam :).
Jay Carr
1
Myślę, że warto również wspomnieć, że zachowanie funkcji różni się, gdy wywołujesz ją z arkusza kalkulacyjnego, w porównaniu z wywoływaniem jej z innej funkcji VBA lub Sub.
Doug Jenkins,
2
Gdy zostanie wywołana w VBA, funkcja zwróci obiekt zakresu, ale gdy zostanie wywołana z arkusza, zwróci tylko wartość, więc set test = Range("A1")jest dokładnie równoważna test = Range("A1").Value, gdzie „test” jest zdefiniowany jako wariant, a nie zakres.
Doug Jenkins,
86

Funkcje VBA traktują samą nazwę funkcji jako rodzaj zmiennej. Zamiast używać returnwyrażenia „ ”, wystarczy powiedzieć:

test = 1

Zauważ jednak, że nie wyłamuje się to z funkcji. Kod po tej instrukcji również zostanie wykonany. W ten sposób możesz mieć wiele instrukcji przypisania, które przypisują różne wartości test, i niezależnie od wartości po osiągnięciu końca funkcji będzie zwracana wartość.

froadie
źródło
Właściwie odpowiedziałeś na pytanie jaśniej, dodając dodatkowe informacje (które mogłyby potencjalnie doprowadzić do kolejnego pytania od nowego do VBA). Kontynuujcie dobra prace
Adarsha
Przepraszam, wyglądało na to, że właśnie odpowiedziałeś tak samo jak moja odpowiedź, którą otrzymałem jako pierwszy, ale dodałem tylko fakt, że nie wyłamuje się z funkcji. To miły dodatek, pomyślałem, że będzie bardziej odpowiedni jako komentarz. Nie jestem pewien, jaka jest właściwa etykieta, wydaje mi się, że głosowanie za nią było trochę niegrzeczne, ponieważ jest to dobra odpowiedź, ale nie pozwoli mi jej cofnąć.
Dan
41

Samo ustawienie wartości zwracanej na nazwę funkcji wciąż nie jest dokładnie takie samo jak instrukcja Java (lub inna) return, ponieważ w java returnwychodzi z funkcji, tak jak poniżej:

public int test(int x) {
    if (x == 1) {
        return 1; // exits immediately
    }

    // still here? return 0 as default.
    return 0;
}

W VB dokładny ekwiwalent zajmuje dwa wiersze, jeśli nie ustawiasz wartości zwracanej na końcu funkcji . Tak więc w VB następująca konsekwencja wyglądałaby następująco:

Public Function test(ByVal x As Integer) As Integer
    If x = 1 Then
        test = 1 ' does not exit immediately. You must manually terminate...
        Exit Function ' to exit
    End If

    ' Still here? return 0 as default.
    test = 0
    ' no need for an Exit Function because we're about to exit anyway.
End Function 

Ponieważ tak jest, miło jest wiedzieć, że możesz używać zmiennej zwracanej jak każdej innej zmiennej w metodzie. Lubię to:

Public Function test(ByVal x As Integer) As Integer

    test = x ' <-- set the return value

    If test <> 1 Then ' Test the currently set return value
        test = 0 ' Reset the return value to a *new* value
    End If

End Function 

Lub skrajna przykładem tego, jak zmienne powrót prace (ale niekoniecznie dobrym przykładem tego, w jaki sposób należy właściwie code) -the który będzie Cię w nocy:

Public Function test(ByVal x As Integer) As Integer

    test = x ' <-- set the return value

    If test > 0 Then

        ' RECURSIVE CALL...WITH THE RETURN VALUE AS AN ARGUMENT,
        ' AND THE RESULT RESETTING THE RETURN VALUE.
        test = test(test - 1)

    End If

End Function
LimaNightHawk
źródło
2
„miło jest również wiedzieć, że możesz używać zmiennej zwracanej, jak każdej innej zmiennej w metodzie”, jest to w większości prawda - ale np. jeśli typem zwracanym jest, Varianta Twoim celem jest zwrócenie tablicy, wówczas coś podobnego ReDim test(1 to 100)spowoduje błąd. Ponadto, mimo że jest możliwe, aby traktować podstawowy typ takiego Integersjak to, że jest uważany za nieco unidiomatic. Utrudnia to odczytanie kodu. Programiści VBA szukają linii przypisujących nazwę funkcji, aby zrozumieć, co robi funkcja. Używanie nazwy funkcji jako zwykłej zmiennej niepotrzebnie to zaciemnia.
John Coleman,
@JohnColeman, całkowicie zgadzam się w obu punktach. W żadnym wypadku ostatni przykład nie powinien być zalecaną metodologią. Ale pytanie tematyczne dotyczy tego, jak zwrócić zmienną, więc jest to tylko próba pełnego wyjaśnienia wyniku zwracanego przez VB, a przez to, w jaki sposób działają. Z pewnością ostatni przypadek nie jest zaleceniem. (Z pewnością nie kodowałbym tego jako przykładu.) Zatem twoje punkty są dobrze przyjęte i dobre uzupełnienia. Dziękuję Ci.
LimaNightHawk
Jest to użyteczne dla funkcji niewielkie, a to coś, co każdy programista powinien wiedzieć o VBA, więc nie miałem problemu z wami o tym wspomnieć. Pomyślałem, że należy dołączyć ostrzeżenie.
John Coleman,
Dzięki, wyjaśniając, w jaki sposób Exit Functionodnosi się doreturn
Austin D
@JohnColeman, oczywiście nie można ReDim test(1 to 100)bez wywołania błędu po prostu dlatego, że „test” nie jest zadeklarowany jako tablica! i bez żadnego innego powodu! Nie można zadeklarować funkcji jako tablicy. Zadeklaruj go jako Variant, a następnie po prostu zbuduj tablicę wyjściową (może być dynamiczną lub statyczną) wewnątrz tej funkcji, testa następnie przypisz („=”) tę tablicę testjako wartość zwracaną. Aby dalej manipulować, podobnie jak ReDimgo, musisz przypisać zwróconą wartość do zmiennej, np. Dim x as VariantI wywołać x = test, po czym xto, co stworzyłeś test!
Gene
-6

Poniższy kod przechowuje wartość zwracaną w zmiennej, retVala następnie MsgBoxmożna jej użyć do wyświetlenia wartości:

Dim retVal As Integer
retVal = test()
Msgbox retVal
Biju John
źródło