So geben Sie ein Ergebnis einer VBA-Funktion zurück

277

Wie gebe ich ein Ergebnis von einer Funktion zurück?

Beispielsweise:

Public Function test() As Integer
    return 1
End Function

Dies führt zu einem Kompilierungsfehler.

Wie kann ich dafür sorgen, dass diese Funktion eine Ganzzahl zurückgibt?

Mike
quelle
10
Dokumentation: msdn.microsoft.com/en-us/library/office/…
Jean-François Corbett

Antworten:

429

Bei Rückgabetypen, die keine Objekte sind, müssen Sie den Wert dem Namen Ihrer Funktion wie folgt zuweisen:

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

Anwendungsbeispiel:

Dim i As Integer
i = test()

Wenn die Funktion einen Objekttyp zurückgibt, müssen Sie das SetSchlüsselwort wie folgt verwenden:

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

Anwendungsbeispiel:

Dim r As Range
Set r = testRange()

Beachten Sie, dass das Zuweisen eines Rückgabewerts zum Funktionsnamen die Ausführung Ihrer Funktion nicht beendet. Wenn Sie die Funktion beenden möchten, müssen Sie dies explizit angeben Exit Function. Zum Beispiel:

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

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

Dan
quelle
32
Der Vollständigkeit halber sollte beachtet werden, dass Sie bei der Rückgabe eines Objekts (wie Rangez. B. eines) Setgenau wie beim Festlegen einer Objektvariablen in einer regulären Methode verwenden müssen. Wenn zum Beispiel "test" eine Funktion wäre, die einen Bereich zurückgibt, würde die return-Anweisung so aussehen set test = Range("A1").
Jay Carr
Warum ist das @JayCarr?
PsychoData
4
@PsychoData - Einfach, weil Sie auf diese Weise im Allgemeinen eine Objektvariable festlegen und auf diese verzichten, setkann dies zu Problemen führen. Ich hatte Probleme damit, aber wenn ich es benutze, settue ich es nicht :).
Jay Carr
1
Ich denke, es ist auch erwähnenswert, dass sich das Verhalten der Funktion unterscheidet, wenn Sie sie aus einer Tabelle aufrufen, im Vergleich zu einer anderen VBA-Funktion oder einem anderen Sub.
Doug Jenkins
2
Beim Aufruf innerhalb von VBA gibt die Funktion ein Bereichsobjekt zurück, beim Aufruf von einem Arbeitsblatt wird jedoch nur der Wert zurückgegeben. set test = Range("A1")Dies entspricht genau dem Wert test = Range("A1").Value, bei dem "Test" als Variante und nicht als Bereich definiert ist.
Doug Jenkins
86

VBA-Funktionen behandeln den Funktionsnamen selbst als eine Art Variable. Anstatt eine " return" -Anweisung zu verwenden, würden Sie einfach sagen:

test = 1

Beachten Sie jedoch, dass dies nicht aus der Funktion ausbricht. Jeder Code nach dieser Anweisung wird ebenfalls ausgeführt. Auf diese Weise können Sie viele Zuweisungsanweisungen haben, denen unterschiedliche Werte zugewiesen werden. testUnabhängig vom Wert, den Sie am Ende der Funktion erreichen, wird der Wert zurückgegeben.

froadie
quelle
Tatsächlich haben Sie die Frage klarer mit zusätzlichen Informationen beantwortet (was möglicherweise zu einer weiteren Frage vom Neu- zum VBA-Typ führen könnte). Machen Sie weiter so
Adarsha
Entschuldigung, es schien, als hätten Sie nur das Gleiche beantwortet wie meine Antwort, die ich zuerst hatte, aber nur die Tatsache hinzugefügt, dass sie nicht aus der Funktion ausbricht. Es ist eine nette Ergänzung, ich dachte nur, dass es als Kommentar angemessener wäre. Ich bin mir nicht sicher, was die richtige Etikette ist. Ich denke, es war ein bisschen unhöflich, dafür zu stimmen, weil es eine gute Antwort ist, aber ich kann es nicht rückgängig machen.
Dan
41

Das Festlegen des Rückgabewerts auf den Funktionsnamen entspricht immer noch nicht genau der Java- returnAnweisung (oder einer anderen Anweisung), da returndie Funktion in Java wie folgt beendet wird:

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

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

In VB dauert das genaue Äquivalent zwei Zeilen, wenn Sie den Rückgabewert nicht am Ende Ihrer Funktion festlegen . In VB würde die genaue Folge also so aussehen:

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 

Da dies der Fall ist, ist es auch schön zu wissen, dass Sie die Rückgabevariable wie jede andere Variable in der Methode verwenden können. So was:

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 

Oder das extreme Beispiel dafür, wie die Rückgabevariable funktioniert (aber nicht unbedingt ein gutes Beispiel dafür, wie Sie tatsächlich codieren sollten) - das, das Sie nachts auf Trab hält:

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
quelle
2
"Es ist auch schön zu wissen, dass Sie die Rückgabevariable wie jede andere Variable in der Methode verwenden können" ist meistens wahr - aber wenn der Rückgabetyp lautet Variantund Ihr Ziel darin besteht, ein Array zurückzugeben, wird so etwas wie ReDim test(1 to 100)einen Fehler auslösen. Auch wenn es möglich ist, den Basistyp so zu behandeln Integers, wird er als etwas unidiomatisch angesehen. Dies erschwert das Lesen des Codes. VBA-Programmierer suchen nach Zeilen, die dem Funktionsnamen zugewiesen sind, um zu verstehen, was eine Funktion tut. Die Verwendung des Funktionsnamens als reguläre Variable verdeckt dies unnötig.
John Coleman
@ JohnColeman, stimme in beiden Punkten voll und ganz zu. Das letzte Beispiel sollte keinesfalls eine der empfohlenen Methoden sein. Die Themenfrage bezieht sich jedoch auf die Rückgabe einer Variablen. Dies ist also nur ein Versuch, das Rückgabeergebnis von VB und dessen Funktionsweise vollständig zu erklären. Der letzte Fall ist sicherlich keine Empfehlung. (Ich würde das sicherlich nicht als mehr als ein Beispiel codieren.) Ihre Punkte sind also gut aufgenommen und gute Ergänzungen. Vielen Dank.
LimaNightHawk
Es ist nützlich für kleinere Funktionen und sollte jedem VBA-Programmierer bekannt sein. Ich hatte also kein Problem damit, dass Sie es erwähnen. Ich dachte nur, dass eine Warnung aufgenommen werden sollte.
John Coleman
Vielen Dank für die Erklärung, wie es sich Exit Functionbeziehtreturn
Austin D
@ JohnColeman, Natürlich können Sie nicht ReDim test(1 to 100)ohne einen Fehler auslösen, nur weil 'Test' nicht als Array deklariert ist! und aus keinem anderen Grund! Sie können eine Funktion nicht als Array deklarieren. Deklarieren Sie es als Variant, erstellen Sie dann einfach Ihr Ausgabearray (es kann dynamisch oder statisch sein) in dieser Funktion testund weisen Sie dieses Array dann testals Rückgabewert zu ("=") . Um weiter zu manipulieren, ReDimmüssen Sie den zurückgegebenen Wert einer Variablen zuweisen, z. B. Dim x as Variantund aufrufen x = test. xDanach haben Sie das gemacht, was Sie sein testsollen!
Gene
-6

Der folgende Code speichert den Rückgabewert in der Variablen retValund MsgBoxkann dann zum Anzeigen des Werts verwendet werden:

Dim retVal As Integer
retVal = test()
Msgbox retVal
Biju John
quelle