Você está na página 1de 6

VBA: chamar uma macro em outra

macro
Faça uma pergunta
FRBR
Para chamar uma macro a partir de outra, vamos ter que distinguir vários casos. A
chamada de um Sub ou de uma 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


o Sem configurações
o Com configurações
 Chamada de uma função a partir de um Sub
 Chamada de uma Function a partir de uma Function
 Chamada de um procedimento de evento
o Com a instrução Call
o Como dar acesso ao VBA com a função CallByName
 Chamada de um procedimento em outra pasta de trabalho
o Caso da chamada de um Sub
o Caso de chamada de uma Function
 Conclusão
 Veja também: Função call vba

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, podemos fazer sem a instrução Call:

Sub Macro1()
MsgBox "Hello world!"
End Sub

Sub Macro2()
Macro1
End Sub

No entanto, eu não recomendo. 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
inúteis 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

Note-se aqui 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, mesmo? O que a diferencia de um Sub? Uma função (Function) é
uma instrução que depende de parâmetros e que 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 nossa Function é declarada como As Double (esta 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

Note-se 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.
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, uma pasta de trabalho,
uma 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 isto:

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.

Observação: você me dirá: "basta alterar o valor da A1 a partir da nossa macro, e isso
funcionará. Sim, você tem razão. Mas isso é apenas um exemplo.

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 seu procedimento de chamada no Módulo1, por


exemplo, seja lá o que você fizer, mesmo declarando 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 dar-
lhe este 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), eu quero acionar o
evento ComboBox1_Change de uma lista suspensa situada num UserForm1:

Você também pode gostar