Como retornar um resultado de uma função VBA

277

Como faço para retornar um resultado de uma função?

Por exemplo:

Public Function test() As Integer
    return 1
End Function

Isso gera um erro de compilação.

Como faço para que essa função retorne um número inteiro?

Mike
fonte
10
Documentação: msdn.microsoft.com/en-us/library/office/…
Jean-François Corbett

Respostas:

430

Para tipos de retorno sem objeto, você deve atribuir o valor ao nome da sua função, assim:

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

Exemplo de uso:

Dim i As Integer
i = test()

Se a função retornar um tipo de objeto, você deverá usar a Setpalavra - chave assim:

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

Exemplo de uso:

Dim r As Range
Set r = testRange()

Observe que atribuir um valor de retorno ao nome da função não encerra a execução da sua função. Se você deseja sair da função, é necessário dizer explicitamente Exit Function. Por exemplo:

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

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

Dan
fonte
32
Para completar, deve-se observar que, ao retornar um objeto (como um Rangepor exemplo), você precisa usar Setcomo faria se definisse uma variável de objeto em um método regular. Portanto, se, por exemplo, "test" fosse uma função que retornasse um Range, a instrução return ficaria assim set test = Range("A1").
Jay Carr
Por que isso é @ JayCarr?
PsychoData
4
@ PsychoData - Simplesmente porque é assim que você define uma variável de objeto em geral, e fazê-lo sem setpode levar a problemas. Eu tive problemas em fazê-lo sem, mas se eu usar set, não :).
Jay Carr
1
Eu acho que também vale a pena mencionar que o comportamento da função difere quando você a chama de uma planilha, em comparação com a chamada de outra função VBA ou Sub.
Doug Jenkins
2
Quando chamada no VBA, a função retornará um objeto de intervalo, mas quando chamada de uma planilha retornará apenas o valor, portanto, set test = Range("A1")é exatamente equivalente a test = Range("A1").Value, onde "teste" é definido como uma Variante, em vez de um Intervalo.
Doug Jenkins
86

As funções do VBA tratam o próprio nome da função como uma espécie de variável. Então, em vez de usar uma returninstrução " ", você apenas diria:

test = 1

Observe, no entanto, que isso não interrompe a função. Qualquer código após esta instrução também será executado. Assim, você pode ter muitas instruções de atribuição que atribuem valores diferentes a test, e seja qual for o valor quando você chegar ao final da função, será o valor retornado.

froadie
fonte
Na verdade, você respondeu à pergunta mais claramente com informações extras (o que potencialmente poderia levar a outra pergunta, de um novato no VBA). Mantenha o bom trabalho
Adarsha
Desculpe, parecia que você acabou de responder a mesma coisa que a minha resposta, que eu havia respondido primeiro, mas apenas adicionando o fato de que ela não sai da função. É uma boa adição, eu apenas pensei que seria mais apropriado como um comentário. Não sei ao certo qual é a etiqueta correta. Acho que foi um pouco rude votar apenas por isso, porque é uma boa resposta, mas não me permite desfazer.
Dan
41

Apenas definir o valor de retorno para o nome da função ainda não é exatamente o mesmo que a returninstrução Java (ou outra) , porque em java returnsai da função, assim:

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

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

No VB, o equivalente exato leva duas linhas se você não estiver definindo o valor de retorno no final de sua função . Assim, no VB, o corolário exato ficaria assim:

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 

Como esse é o caso, também é bom saber que você pode usar a variável de retorno como qualquer outra variável no método. Como isso:

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, o exemplo extremo de como a variável de retorno funciona (mas não necessariamente um bom exemplo de como você realmente deve codificar) - aquele que o manterá acordado à noite:

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
fonte
2
"também é bom saber que você pode usar a variável de retorno como qualquer outra variável no método" é principalmente verdade - mas, por exemplo, se o tipo de retorno é Variante seu objetivo é retornar uma matriz, algo como ReDim test(1 to 100)isso provocará um erro. Além disso, embora seja possível tratar um tipo básico Integerscomo esse, ele é considerado um tanto unidiomatic. Isso torna o código mais difícil de ler. Os programadores do VBA pesquisam as linhas atribuídas ao nome da função para entender o que uma função faz. O uso do nome da função como uma variável regular oculta desnecessariamente isso.
John Coleman #
@ JohnColeman, concordo totalmente em ambos os pontos. De maneira alguma o último exemplo deve ser um dos métodos recomendados. Mas, a questão do tópico é sobre como retornar uma variável e, portanto, isso é apenas uma tentativa de uma explicação completa do resultado do retorno do VB e, por extensão, como eles funcionam. Certamente o último caso não é uma recomendação. (Eu certamente não codificaria isso como mais do que um exemplo.) Portanto, seus pontos são bem aceitos e são boas adições. Obrigado.
LimaNightHawk 04/04
Ele é útil para funções bem pequenos, e é algo que qualquer programador VBA deve saber sobre, então eu não tive nenhum problema com você mencioná-lo. Eu apenas pensei que um aviso deveria ser incluído.
John Coleman
Obrigado explicando como Exit Functionse relaciona comreturn
Austin D
@ JohnColeman, obviamente, você não pode ReDim test(1 to 100)sem desencadear um erro simplesmente porque 'test' não é declarado como uma matriz! e por nenhuma outra razão! Você não pode declarar uma função como uma matriz. Declare-o como a Variant, então apenas construa sua matriz de saída (pode ser Dinâmica ou Estática) dentro dessa função teste atribua ("=") essa matriz testcomo um valor de retorno. Para manipular ainda mais, como ReDimele, é necessário atribuir o valor retornado a uma variável, por exemplo, Dim x as Variante chamar x = test, após o que xvocê criou o testque é!
Gene
-6

O código abaixo armazena o valor de retorno na variável retVale, em seguida, MsgBoxpode ser usado para exibir o valor:

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