Tag Archives: Goto

VBA – A Instrução GoTo

O que é?

É um desvio incondicional para uma linha especificada dentro de uma função VBA.

Estrutura

GoTo [label]

O argumento [label] obrigatório pode ser qualquer rótulo de linha ou número de linha.
rótulo de linha

Utilizado para identificar uma única linha de código. Um rótulo de linha pode ser qualquer combinação de caracteres que inicie com uma letra e termine com dois-pontos (:). Os rótulos de linha não diferenciam maiúsculas de minúsculas e devem iniciar na primeira coluna.
número de linha

Utilizado para identificar uma única linha de código. Um número de linha pode ser qualquer combinação de dígitos que seja exclusiva dentro do módulo no qual é utilizado. Os números de linha devem iniciar na primeira coluna.

Exemplo

Abaixo segue um trecho de código que refleto o uso do Goto:

1
2
3
4
5
6
7
8
9
10
11
12
Public Sub TesteGoto()
    MsgBox "Inicio da função"
    GoTo Rotulo2
Rotulo1:
    MsgBox "Executando Rotulo1"
    GoTo Saida
Rotulo2:
    MsgBox "Executando Rotulo2"
    GoTo Rotulo1
Saida:
    MsgBox "Fim da função"
End Sub

O código acima mostra mensagens em uma sequência definida pela instrução Goto. A instrução não obedece nenhum critério, mesmo sendo executada de dentro uma estrutura condicional (If…Else) ou de repetição (While, For, For Each), fazendo desvio conforme informado. Neste caso, a instrução segue a sequência de execução normalmente até a linha 4, quando é desviada para o Rotulo2 na linha 9, que executa até a linha 11 que desvia a execução para o Rotulo1 na linha 6, que por fim executa até a instrução na linha 8 e quando é desviada para o Saida na linha 12, seguindo a execução até o fim da função.

Veja este outrou exemplo de código:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Public Sub TesteGoto2()
 
    MsgBox "Inicio da função"
    GoTo Saida
 
    MsgBox "Conteúdo da função"
    MsgBox "Conteúdo da função"
    MsgBox "Conteúdo da função"
    MsgBox "Conteúdo da função"
    MsgBox "Conteúdo da função"
    MsgBox "Conteúdo da função"
    MsgBox "Conteúdo da função"
    MsgBox "Conteúdo da função"
 
Saida:
    MsgBox "Fim da função"
End Sub

Neste caso, por conta do desvio na linha 4 para o rotulo Saida na linha 15, todas as instruções das linhas 5 a 14 nunca serão executadas.

Comentários

GoTo pode desviar somente para linhas de dentro da função em que é colocado.

Observação Excesso de instruções GoTo pode tornar difícil a leitura e depuração do código. Sempre que possível, use instruções de controle estruturado (Do…Loop, For…Next, If…Then…Else, Select Case).

Os cuidados em utilizar a instrução GoTo

Sabemos que instrução GoTo do VBA proporciona uma forma de desviar o fluxo execução de uma função para qualquer linha dentro desta.

Apesar de considerar um recurso útil, as boas práticas de programação condenam o uso deste tipo de instrução. É estranho existir a motivação para a não utilização de um recurso, sendo que por algum motivo ele existe, porém, os argumentos para o caso do GoTo são justificáveis.

Vamos assumir que precisássemos construir um algoritmo (entenda algoritmo como uma sequência de passos definidos para executar uma determinada tarefa) para resolver um problema. A sequência correta de passos para construção deste, seguiria uma estrutura sequêncial bem definida, capaz de ser representada por um fluxograma, por exemplo:




O fato de poder ser representada por um fluxograma, significa que não existe ambiguidade em sua estrutura. Todos os passos para execução das tarefas e tomadas de decisão estão bem definidas, detalhadas e cobrem todas as possibilidades dentro de seu contexto.

Dentro do VBA, as instruções de controle de fluxo como If…Then…Else, While…Wend, For…Next e outras, seguem uma estrutura bem definidas, tendo começo, meio e fim bem localizados em suas definições e utilização. Em todas estas, todos os desvios são previstos e controlados pelo programador. Todos os testes são explícitos baseadas nas condições colocadas. Não há ambiguidade em seu funcionamento.

Neste ponto, a própria definição do GoTo nos leva a pensar:

“É um desvio incondicional para uma linha especificada dentro de uma função VBA.”

A palavra incondicional foi evidenciada propositalmente. Um desvio incondicional de código significa que, sem qualquer critério, condição ou mesmo teste, a instrução GoTo efetua o devio da execução do código para outra linha.

Supondo que a instrução GoTo seja utilizada em uma parte do código em que uma variável estiver com um valor inválido, um valor não esperado ou mesmo não tenha nenhum valor configurado, isso trará problemas para a execução do código, podendo gerar erros. Pior ainda, o código pode até não gerar um erro, mas pode executar suas funções com valores indesejados, levando a resultados desastrosos. Não há teste ou condição que avalie este desvio de execução.

O programador pode em alguns casos fazer as verificações necessárias para evitar algumas inconsitências, porém, a lógica de seu algoritmo será completamente quebrada por conta da não condicionalidade do desvio do GoTo. A situação é mais complicada quando o GoTo devia o fluxo de execução para uma linha anterior a qual ele é invocado.

Um teste simples para verificar o “estrago” que o uso indiscriminado do GoTo é tentar construir um fluxograma simples de sua função com sua sequência de execução.

A única excessão do bom uso do GoTo é para o tratamento de erros utilizando a estrutura On Error GoTo, como pode ser visto neste link.

Recomendações

Como o VBA oferece estruturas de controle de fluxo bem definidas e organizadas, tanto voltadas a lógica simples de teste como também de repetição de coleções (For…Each), é aconselhável sempre utilizar estas estruturas na construção de códigos. Raras serão as excessões em que o uso do GoTo torna-se indispensável. Caso esta situação ocorra, utilize-o com critério, certificando que em nenhuma situação o desvio causado pode afetar o funcionamento de seu algoritmo.

A idéia não é impedir ou condenar o uso do GoTo, até porque, se não fosse útil ele sequer existiria. O principal objetivo deste texto é alertar para os cuidados que devem ser tomados com o uso desta instrução, de forma a manter o controle de seu aplicativo e facilitar, ou até mesmo possibilitar futuras manutenções.