Há diferentes maneiras de realizar esse tipo de chamada no Microsoft Visual Basic. Conheça as principais formas.
Para chamar uma macro a partir de outra, vamos ter que distinguir vários casos. A chamada de um
Sub ou função não é feita exatamente da mesma maneira. Além disso, vamos ter que estudar, separadamente, a chamada de um procedimento de evento e a chamada de um procedimento contida em outra pasta de trabalho.
Chamar um Sub a partir de um Sub
Sem configurações
Quando
os dois Sub estão no mesmo módulo e não têm parâmetros. A Macro2 chama a Macro1:
Sub Macro1()
MsgBox "Hello world!"
End Sub
Sub Macro2()
Call Macro1
End Sub
Eventualmente, pode-se fazer sem a instrução
Call:
Sub Macro1()
MsgBox "Hello world!"
End Sub
Sub Macro2()
Macro1
End Sub
No entanto, essa ação não é recomendada. Na verdade, esta instrução
Call torna o código muito mais legível. Ao lê-lo, o programador vê, imediatamente, que se trata da chamada de um procedimento.
Quando
os dois Sub estão em módulos diferentes e não têm parâmetros, não é preciso especificar o módulo. O exemplo anterior funcionará da mesma forma, porém você deverá pensar na sua manutenção, desde a criação do seu código. O fato de especificar em que módulo fica o procedimento chamado fará com que você não perca tempo com pesquisas durante os possíveis desbloqueios. Então, se a Macro1 estiver no Módulo1 e a Macro2 no Módulo 2:
Sub Macro1()
MsgBox "Hello world!"
End Sub
Sub Macro2()
Call Module1.Macro1
End Sub
Com configurações
O método é o mesmo. Basta adicionar as configurações entre parênteses. No entanto, cuidado ao digitar essas configurações, para evitar a geração de erro (do tipo 13). Se a sua função espera um parâmetro digitado em
string, não envie uma Dupla dobro:
Com a instrução Call:
Sub Macro1(Nb1 As Long, Nb2 As Long)
Range("A1") = Nb1
Range("A2") = Nb2
End Sub
Sub Macro2()
Call Macro1(18254, 654897)
End Sub
Sem a instrução Call:
Sub Macro1(Nb1 As Long, Nb2 As Long)
Range("A1") = Nb1
Range("A2") = Nb2
End Sub
Sub Macro2()
Macro1 18254321, 654897
End Sub
Perceba a ausência de parênteses. Se as macros estiverem em diferentes módulos, mesma sanção:
Sub Macro2()
Call Module1.Macro1(918254321, 654897)
End Sub
Chamada de uma função a partir de um Sub
O que é uma
função e o que a diferencia de um
Sub? Uma
função (Function) é uma instrução que depende de parâmetros e retorna um valor. Um
Sub também é uma instrução dependente de parâmetros (se houver), mas não retorna nada.
Exemplo de
Function:
Function Addition(Nb1 As Double, Nb2 As Double) As Double
Addition = Nb1 + Nb2
End Function
Aqui, vemos que a
Function é declarada como
As Double (essa declaração de tipo é opcional). O valor que ela retorna será do tipo duplo (Double). Como uma função retorna um valor, você deverá, no
Sub que chama, prever o armazenamento desse valor. Isso pode se dar tanto em uma célula do Excel, como em uma variável (pensar em declarar a variável no tipo certo), em um controle etc.
Aqui vamos recebê-la em uma variável do mesmo tipo (Double):
Sub Macro2()
Dim Soma As Double
Soma = Addition(1234.56, 654.32)
MsgBox Soma
End Sub
Function Addition(Nb1 As Double, Nb2 As Double) As Double
Addition = Nb1 + Nb2
End Function
Perceba aqui a obrigação de colocar os parâmetros entre parênteses e separados por vírgulas.
Chamada de uma Function a partir de uma Function
Exatamente o mesmo princípio. Veja o exemplo com armazenamento do resultado em uma variável intermediária:
Sub Macro2()
Dim Soma As Double
Soma = Addition(1234.56, 654.32)
MsgBox Soma
End Sub
Function Addition(Nb1 As Double, Nb2 As Double) As Double
Dim VarNb As Double
VarNb = MultiplicadoPorDois(Nb2)
Addition = Nb1 + VarNb
End Function
Function MultiplicadoPorDois(Nb As Double) As Double
MultiplicadoPorDois = Nb * 2
End Function
Mesmo exemplo sem variável intermediária:
Sub Macro2()
Dim Soma As Double
Soma = Addition(1234.56, 654.32)
MsgBox Soma
End Sub
Function Addition(Nb1 As Double, Nb2 As Double) As Double
Addition = Nb1 + MultiplicadoPorDois(Nb2)
End Function
Function MultiplicadoPorDois(Nb As Double) As Double
MultiplicadoPorDois = Nb * 2
End Function
Chamada de um procedimento de evento
Um procedimento de evento é uma declaração que se ativa automaticamente durante uma ação do usuário em um objeto. O objeto pode ser uma planilha, pasta de trabalho, prova etc. O evento pode ser a abertura ou o fechamento de uma pasta de trabalho, a mudança de planilha, a escolha em uma lista, digitar em uma prova etc. Os procedimentos de evento são usados para interceptar essas ações, para iniciar, automaticamente, os procedimentos que você criou.
Exemplo: gostaríamos que, quando houver uma alteração do valor da célula A1, apareça em B1,
"Nada mal!", se A1 for superior a 10. Para isso, vá no código do
Módulo da planilha em questão e clique direito na guia da planilha >
Ver o Código.
Na janela de código, insira:
Private Sub Worksheet_Change(ByVal Target As Range)
'Se a célula da mudança não tiver o endereço A1 => fechamos
If Target.Address <> "$A$1" Then Exit Sub
'Se a célula (A1) for superior a 10 colocaremos "Nada mal!" na B1
If Target.Value > 10 Then Target.Offset(0, 1) = "Nada mal!" Else Target.Offset(0, 1) = "Insuficiente!"
End Sub
Você já pode testar o efeito, alterando o valor da célula A1 da planilha em questão.
Com a instrução Call
Se o seu procedimento de chamada estiver situado
no mesmo módulo que o seu procedimento de evento, basta chamá-lo, assim:
Private Sub Worksheet_Change(ByVal Target As Range)
'Se a célula da mudança não tiver o endereço A1 => fechamos
If Target.Address <> "$A$1" Then Exit Sub
'Se a célula (A1) for superior a 10 colocaremos "Nada mal!" na B1
If Target.Value > 10 Then Target.Offset(0, 1) = "Nada mal!" Else Target.Offset(0, 1) = "Insuficiente!"
End Sub
Sub MaMacro()
Dim minhaLinha As Range
Set minhaLinha = Sheets("Planilha1").Range("A1")
Call Worksheet_Change(minhaLinha)
End Sub
Em compensação, se você colocar o procedimento de chamada no Módulo1, por exemplo, mesmo que declare como
Public em vez de
Private, você continuará a receber uma mensagem de erro: "Erro de compilação Sub ou Função não definida." Mais claramente, o VBA não tem acesso ao procedimento de evento. Como conceder esse acesso?
Como dar acesso ao VBA com a função CallByName
Sintaxe:
CallByName (Objeto, NomeDoProcedimento, TypeAppel, Args());
Objeto: obrigatório. Do tipo Objeto. Designa o objeto envolvido no procedimento;
NomeDoProcedimento: obrigatório. Do tipo String. Representa o nome do processo de chamada;
TipoDeChamada: obrigatório. Do tipo
CallType. Talvez
Method, Set, Let ou Get;
Args(): opcional. Tabela de parâmetros a serem passados para a função de chamada.
No nosso exemplo, vamos colocar
MinhaMacro no Módulo1 e tentar chamar o
Sub Worksheet_Change. Antes disso, é preciso declarar o nosso procedimento de evento em outro nível. Na verdade, declarada como
Private (Privada), ela só poderá ser usada no módulo da planilha.
Então, tiramos a palavra
Private do módulo da planilha:
Sub Worksheet_Change(ByVal Target As Range)
'Se a célula da mudança não tiver o endereço A1 => fechamos
If Target.Address <> "$A$1" Then Exit Sub
'Se a célula (A1) for superior a 10 colocaremos "Nada mal!" na B1
If Target.Value > 10 Then Target.Offset(0, 1) = "Nada mal!" Else Target.Offset(0, 1) = "Insuficiente!"
End Sub
Agora, vamos colocar o
Sub MinhaMacro no Módulo2:
Sub MinhaMacro()
Dim minhaLinha As Range
Set minhaLinha = Sheets("Planilha1").Range("A1")
CallByName Worksheets("Planilha1"), "Worksheet_Change", VbMethod, minhaLinha
End Sub
Outro exemplo:ao clicar em um botão do formulário de usuário (UserForm2), quero acionar o evento
ComboBox1_Change de uma lista suspensa situada num UserForm1:
Private Sub CommandButton1_Click()
CallByName UserForm1, "ComboBox1_Change", VbMethod
End Sub
Sem esquecer de antes remover o
Private do evento em questão:
Sub ComboBox1_Change().
Chamada de um procedimento em outra pasta de trabalho
Nesse caso, será preciso usar o método
Run. Vamos especificar, principalmente, a pasta de trabalho com o procedimento de chamada e o nome do mesmo.
Caso da chamada de um Sub
Aqui, temos duas opções. Na primeira, o arquivo foi aberto anteriormente. Nesse caso, não há necessidade de especificar o caminho de acesso:
Sub TestRun()
Application.Run "'Pasta1.xlsm'!Módulo2.Macro2"
End Sub
Também é possível que a pasta de trabalho esteja fechada. De qualquer maneira, o caminho de acesso completo deve ser referenciado:
Sub TestRun()
Application.Run "'C:\Users\franck\Desktop\Pasta1.xlsm'!Módulo2.Macro2"
End Sub
Observação: note a presença obrigatória das aspas em torno do nome do arquivo.
Caso de chamada de uma Function
Como no caso da chamada de uma função a partir da mesma pasta de trabalho, você deverá pensar em um lugar de armazenamento. Nesse caso, uma variável. Também vamos ter que comunicar a partir do
Sub de chamada, todos os parâmetros a serem transmitidos para a função de chamada.
Retomemos a
Function Addition situada na ‘Pasta1.xlsm’:
Function Addition(Nb1 As Double, Nb2 As Double) As Double
Addition = Nb1 + Nb2
End Function
Para chamá-la no nosso procedimento
Principal() situado na pasta de trabalho ‘Pasta2.xlsm’, precisamos do seguinte código:
Pasta aberta:
Sub Principal()
Dim Soma As Double
Soma = Run("'Pasta1.xlsm'!Module2.Addition", 1234.56, 654.32)
MsgBox Soma
End Sub
Pasta fechada:
Sub Principal ()
Dim Soma As Double
Soma = Run("'C:\Users\franck\Desktop\Pasta1.xlsm'!Module2.Adição", 1234.56, 654.32)
MsgBox Soma
End Sub
Observação: se a pasta de trabalho foi previamente fechada, ela será aberta depois da execução da macro. Assim sendo, não se esqueça de fechá-la com um código.
Último exemplo: se adicionarmos o encerramento da pasta de trabalho, ficaria assim:
Sub TestRun()
Dim Soma As Double
Soma = Run("'Pasta1.xlsm'!Module2.Addition", 1234.56, 654.32)
Workbooks("Pasta1.xlsm").Close False
MsgBox Soma
End Sub
Conclusão
Não deixe de compartilhar qualquer comentário sobre essas explicações. Qualquer dúvida, poste sua pergunta no fórum adequado.
Foto: © Alejandro Escamilla - Unsplash.