TOP

VBA-Lição 9. Procedimentos e funções

Em qualquer linguagem de programação existem conceitos como procedimentos e funções. Eles também foram incluídos na linguagem de programação integrada VBA para Excel.

  • Uma função é uma rotina que retorna um resultado. Uma chamada de função é uma expressão e pode ser usada em outras expressões ou no lado direito de uma instrução de atribuição (denotada em VBA como "Function");
  • Um procedimento é qualquer rotina que não seja uma função. Marcado em VBA como "Sub" (da palavra "sub-rotina").

  • Procedimentos (Public - Private)

    Neste ponto, todos os procedimentos que criamos são do tipo Public, o que significa que podem ser acessados a partir de qualquer módulo.

     Sub example()
     
     'Idêntico a:
     Public Sub example()
    

    Para disponibilizar o procedimento apenas em um determinado módulo, é utilizada a palavra-chave Private:

    Private Sub example()
    

    Executando um procedimento no meio de outro procedimento

    Para executar um procedimento dentro de outro procedimento, basta digitar seu nome.

    Aqui está um exemplo muito simples disso:

    Private Sub warning()
        MsgBox "Caution !!!" '"AVISO!"
    End Sub
    
    Sub macro_test()
        If Range("A1") = "" Then
            warning '=> execute o procedimento "warning"
        End If
        'etc...
    End Sub
    

    Argumentos

    Os argumentos permitem utilizar valores de um procedimento em um subprocedimento (lembre-se que por padrão as variáveis só estão disponíveis a partir do procedimento em que foram declaradas).

    Private Sub warning(var_text As String)
        MsgBox "Caution : " & var_text & " !"
    End Sub
    
    Sub macro_test()
        If Range("A1") = "" Then
            warning "empty cell"               '"célula vazia"
        ElseIf Not IsNumeric(Range("A1")) Then
            warning "non-numerical value"      '"valor não numérico"
        End If
    End Sub
    

    Foi adicionado um argumento ao procedimento "warning", neste caso é uma variável "var_text" do tipo "String" (fita):

    Private Sub warning(var_text As String)
    

    Esta rotina recebe um argumento, então precisamos colocar um valor depois de "warning" para executá-la:

    warning "empty cell"
    

    Quando quisermos escrever vários argumentos, eles deverão ser separados por vírgulas.

    Argumentos opcionais

    Por padrão, se o procedimento tiver argumentos, eles deverão ser fornecidos e, se não forem fornecidos, o procedimento não será executado.

    Um argumento opcional pode ser adicionado após um argumento obrigatório, usando a palavra-chave Opcional. Exemplo:

    Private Sub dialog_boxes(last_name As String, Optional first_name, Optional age)
    

    Este procedimento agora pode ser executado com ou sem um argumento opcional, como aqui:

     'Exemplo 1: exibir o sobrenome:
     dialog_boxes last_name1
       
     'Exemplo 2: exibimos o sobrenome e o nome:
     dialog_boxes last_name1, first_name1
       
     'Exemplo 3: exiba o sobrenome e a idade:
     dialog_boxes last_name1, , age1
       
     'Exemplo 4: exibir sobrenome, nome e idade:
     dialog_boxes last_name1, first_name1, age1
    

    Os argumentos devem ser inseridos na ordem correta.

    Para testar se um argumento opcional está presente em um procedimento, usamos a função IsMissing. Esta função só é compatível com alguns tipos de função (do tipo Variant) e isso é crítico porque o tipo dos argumentos opcionais não foi declarado (tipo não declarado = Variant).

    Aqui está um exemplo que usa os dois trechos de código discutidos acima:

    Sub macro_test()
    
        Dim last_name1 As String, first_name1 As String, age1 As Integer
       
        last_name1 = Range("A1")
        first_name1 = Range("B1")
        age1 = Range("C1")
    
        'Exemplo 1: exibir o sobrenome:
        dialog_boxes last_name1
       
        'Exemplo 2: exibimos o sobrenome e o nome:
        dialog_boxes last_name1, first_name1
       
        'Exemplo 3: exiba o sobrenome e a idade:
        dialog_boxes last_name1, , age1
       
        'Exemplo 4: exibir sobrenome, nome e idade:
        dialog_boxes last_name1, first_name1, age1
    
    End Sub
    
    Private Sub dialog_boxes(last_name As String, Optional first_name, Optional age)
       
        If IsMissing(age) Then 'Se a variável idade estiver faltando...
           
            If IsMissing(first_name) Then 'Se a variável first_name estiver faltando, então
            							  'apenas o sobrenome será exibido
               MsgBox last_name
            Else 'Caso contrário, o sobrenome e o nome serão exibidos
               MsgBox last_name & " " & first_name
            End If
           
        Else 'Se a variável idade estiver presente...
    
            If IsMissing(first_name) Then 'Se a variável first_name estiver faltando, então
                                          'sobrenome e idade serão exibidos
               MsgBox last_name & ", " & age & " years old"
            Else 'Caso contrário, o sobrenome, nome e idade serão exibidos
               MsgBox last_name & " " & first_name & ", " & age & " years old"
            End If
       
        End If
           
    End Sub
    

    Ver imagem abaixo (exemplo 1):

    ByRef - ByVal

    Por padrão, os argumentos são do tipo ByRef, o que significa que se uma variável for passada como argumento, uma referência a ela também será passada. Em outras palavras, se uma variável foi alterada por outro subprocedimento, ela também será alterada no procedimento externo que chama esse subprocedimento.

    Exemplo:

    Sub macro_test()
        Dim var_number As Integer
        
        var_number = 30
        calcul_square var_number
       
        MsgBox var_number
    End Sub
    
    Private Sub calcul_square(ByRef var_value As Integer) 'ByRef é opcional
                                                          '(é o valor padrão)
        var_value = var_value * var_value
    End Sub
    

    Para deixar claro, abaixo está um exemplo do que acontecerá se a execução da macro for iniciada:

     var_number = 30
     'O valor inicial da variável "var_number" é 30
    
     calcul_square var_number
     'O subprocedimento é executado com "var_number" como argumento
    
     Private Sub calcul_square(ByRef var_value As Integer)
     'A variável "var_value" serve até certo ponto para acesso rápido à variável "var_number",
     'o que significa que se a variável "var_value" for alterada, a variável "var_number" também será alterada
     '(e eles não precisam ter o mesmo nome)
     var_value = var_value * var_value
     'O valor da variável "var_value" é alterado (e portanto "var_number" também é alterado ao mesmo tempo)
    
     End Sub
     'Fim do subprocedimento
    
     MsgBox var_number
     'A variável "var_number" foi alterada para que 900 agora seja exibido na caixa de diálogo
    

    O segundo método é usar ByVal.

    Ao contrário de ByRef, que passa uma referência (rótulo), ByVal passa um valor, o que significa que o valor passado como argumento não foi modificado.

    Abaixo você pode ver como o código anterior e ByVal funcionam:

     var_number = 30
     'O valor inicial da variável "var_number" é 30
    
     calcul_square var_number
     'O subprocedimento é executado com "var_number" como argumento
    
     Private Sub calcul_square(ByVal var_value As Integer)
     'A variável "var_value" copia o valor da variável "var_number" (as 2 variáveis não estão relacionadas)
    
     var_value = var_value * var_value
     'O valor da variável "var_value" mudou
    
     End Sub
     'Fim do subprocedimento (neste exemplo o subprocedimento não tem efeito em nada)
    
     MsgBox var_number
     'A variável "var_number" não foi alterada e portanto 30 será exibido na caixa de diálogo
    

    O que você precisa lembrar: Use ByVal quando a variável não deve ser alterada.

    Funções

    A principal diferença entre um procedimento e uma função é que uma função retorna um valor.

    Aqui está um exemplo simples:

    Function square(var_number)
        square = var_number ^ 2 'A função "quadrado" retorna o valor da "raiz quadrada"
    End Function
    
    Sub macro_test()
        Dim result As Double
        result = square(9.876) 'A variável de resultado recebe o valor que foi calculado pela função
        MsgBox result 'O resultado é exibido (neste caso o quadrado de 9,876)
    End Sub
    

    A função pode ser usada em uma planilha como qualquer outra função em Excel.

    Por exemplo, para obter o quadrado do valor inserido na célula A1: