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.
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()
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
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.
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):
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.
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: