Comment renvoyer un résultat d'une fonction VBA

Réponses:

430

Pour les types de retour non-objet, vous devez affecter la valeur au nom de votre fonction, comme ceci:

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

Exemple d'utilisation:

Dim i As Integer
i = test()

Si la fonction renvoie un type d'objet, vous devez utiliser le Setmot clé comme ceci:

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

Exemple d'utilisation:

Dim r As Range
Set r = testRange()

Notez que l'attribution d'une valeur de retour au nom de la fonction ne met pas fin à l'exécution de votre fonction. Si vous souhaitez quitter la fonction, vous devez le dire explicitement Exit Function. Par exemple:

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

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

Dan
la source
32
Pour être complet, il convient de noter que lorsque vous retournez un objet (comme un Rangepar exemple), vous devez utiliser Setcomme vous le feriez si vous définissez une variable d'objet dans une méthode régulière. Ainsi, si, par exemple, "test" était une fonction qui renvoyait une plage, l'instruction return ressemblerait à ceci set test = Range("A1").
Jay Carr
Pourquoi est-ce @JayCarr?
PsychoData
4
@PsychoData - Tout simplement parce que c'est ainsi que vous définissez une variable d'objet en général, et le faire sans setpeut entraîner des problèmes. J'ai eu des problèmes pour le faire sans, mais si j'utilise setje ne le fais pas :).
Jay Carr
1
Je pense qu'il convient également de mentionner que le comportement de la fonction diffère lorsque vous l'appelez à partir d'une feuille de calcul, par rapport à l'appel d'une autre fonction VBA ou Sub.
Doug Jenkins
2
Lorsqu'elle est appelée dans VBA, la fonction renvoie un objet de plage, mais lorsqu'elle est appelée à partir d'une feuille de calcul, elle renvoie uniquement la valeur, elle set test = Range("A1")est donc exactement équivalente à test = Range("A1").Value, où "test" est défini comme un variant, plutôt que comme une plage.
Doug Jenkins
86

Les fonctions VBA traitent le nom de la fonction lui-même comme une sorte de variable. Donc, au lieu d'utiliser une returninstruction " ", vous diriez simplement:

test = 1

Notez cependant que cela ne sort pas de la fonction. Tout code après cette instruction sera également exécuté. Ainsi, vous pouvez avoir de nombreuses instructions d'affectation qui affectent des valeurs différentes à test, et quelle que soit la valeur lorsque vous atteignez la fin de la fonction, la valeur sera renvoyée.

froadie
la source
En fait, vous avez répondu plus clairement à la question avec des informations supplémentaires (ce qui pourrait potentiellement conduire à une autre question de nouveau à VBA). Continuez votre bon travail
Adarsha
Désolé, il semble que vous venez de répondre à la même chose que ma réponse, que j'avais d'abord, mais en ajoutant simplement le fait qu'elle ne sort pas de la fonction. C'est un bel ajout, je pensais juste que ce serait plus approprié comme commentaire. Je ne sais pas quelle est la bonne étiquette, je suppose que c'était un peu grossier de voter pour cela, car c'est une bonne réponse, mais cela ne me permettra pas de l'annuler.
Dan
41

Le simple fait de définir la valeur de retour sur le nom de la fonction n'est toujours pas exactement le même que l' returninstruction Java (ou autre) , car en java, returnquitte la fonction, comme ceci:

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

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

Dans VB, l' équivalent exact prend deux lignes si vous ne définissez pas la valeur de retour à la fin de votre fonction . Ainsi, en VB, le corollaire exact ressemblerait à ceci:

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 

Comme c'est le cas, il est également agréable de savoir que vous pouvez utiliser la variable de retour comme n'importe quelle autre variable de la méthode. Comme ça:

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 

Ou, l'extrême exemple de la façon dont la variable de retour des œuvres (mais pas nécessairement un bon exemple de la façon dont vous devriez le code réellement) -Celle qui vous tiendra la nuit:

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
la source
2
"il est également agréable de savoir que vous pouvez utiliser la variable de retour comme n'importe quelle autre variable de la méthode" est généralement vrai - mais par exemple, si le type de retour est Variantet que votre objectif est de renvoyer un tableau, quelque chose comme ReDim test(1 to 100)cela déclenchera une erreur. De plus, même s'il est possible de traiter le type de base Integerscomme ça, il est considéré comme quelque peu unidiomatique. Cela rend le code plus difficile à lire. Les programmeurs VBA recherchent les lignes qui sont affectées au nom de la fonction pour comprendre ce qu'une fonction fait. L'utilisation du nom de la fonction comme variable régulière masque cela inutilement.
John Coleman
@JohnColeman, totalement d'accord sur les deux points. Le dernier exemple ne doit en aucun cas être celui de la méthodologie recommandée. Mais, la question du sujet concerne comment renvoyer une variable, et ce n'est donc qu'une tentative d'explication complète du résultat de retour de VB, et par extension comment ils fonctionnent. Certes, le dernier cas n'est pas une recommandation. (Je ne voudrais certainement pas coder cela comme plus qu'un exemple.) Donc, vos points sont bien pris et de bons ajouts. Je vous remercie.
LimaNightHawk
Il est utile pour les petites fonctions, et c'est quelque chose que tout programmeur VBA devrait connaître, donc je n'ai eu aucun problème à le mentionner. Je pensais juste qu'un avertissement devrait être inclus.
John Coleman
Merci d'expliquer comment se Exit Functionrapporte àreturn
Austin D
@JohnColeman, Évidemment, vous ne pouvez pas ReDim test(1 to 100)sans déclencher une erreur simplement parce que 'test' n'est pas déclaré comme un tableau! et pour aucune autre raison! Vous ne pouvez pas déclarer une fonction en tant que tableau. Déclarez-le en tant que Variant, puis créez simplement votre tableau de sortie (il peut être dynamique ou statique) à l'intérieur de cette fonction test, puis affectez ("=") ce tableau à testcomme valeur de retour. Pour manipuler davantage, comme l' ReDiming, vous devez affecter la valeur retournée à une variable, par exemple Dim x as Variantet appel x = test, après xquoi vous avez fait le testêtre!
Gene
-6

Le code ci-dessous stocke la valeur de retour dans la variable retValet MsgBoxpeut ensuite être utilisé pour afficher la valeur:

Dim retVal As Integer
retVal = test()
Msgbox retVal
Biju John
la source