You are on page 1of 9

17 Passos para Melhorar Cdigos VBA por Dan Haught Vice President of Product Development Introduo Codificar fcil.

. Codificar bem difcil. Mas o que um cdigo bem escrito? Geralmente ele deve ter os seguintes atributos: O cdigo funciona (sem bugs) O cdigo est documentado O cdigo de fcil manuteno O cdigo executa com rapidez Alcanar estas metas consome tempo e difcil. Para ajudar neste processo compilamos uma lista de coisas usadas diariamente - dicas e tcnicas que nos ajudam a escrever cdigo que se aproximam da meta gloriosa do cdigo livre de defeitos e de fcil manuteno. Estilos e prticas de codificao um tpico "quente" entre desenvolvedores, chegando quase que a um fervor religioso. O contedo deste artigo no deve ser visto como a palavra final - na verdade uma exposio dos padres que ns da FMS achamos til no trabalho de escrever cdigo. O artigo contm conceitos com os quais voc pode no concordar, o que normal;no os siga. De qualquer forma, importante entender os conceitos envolvidos, assim sendo, vamos mergulhar: #1: Use Option Explicit Isto no uma dica, uma necessidade para se escrever cdigo VBA. Se voc no usar o comando Option Explicit no incio de cada mdulo de seu projeto, vai estar chamando problemas ao depurar seu aplicativo. Ao explicitar Option Explicit voc diz ao VBA que ele deve for-lo a declarar todas as variveis que forem usadas. Isto torna fcil evitar erros de programao por erro ao digitar nomes de variveis. Por exemplo, o procedimento abaixo est em um mdulo que no contm o comando Option Explicit. Voc consegue achar o erro? Sub ShowBugs () Dim intX As Integer Dim intY As Integer Dim intZ As Integer intX = 1 imtY = 2 intZ = 3 Debug.Print intX + intY + intZ End Sub Ao executar este cdigo, seria de se esperar que fossem assinalados os valores 1, 2 e 3 s variveis intX, intY e intZ. e, ao imprimir o resultado da soma teramos 6. Entretanto este procedimento mostra o valor 4 porque existe um erro de digitao. Em vez de setar intY para 2, o cdigo est setando, na verdade, imtY (com "M") em 2. Como Option Explicit no est declarado, a primeira referncia a imtY declara a varivel automaticamente. Isto significa que o cdigo compila sem problemas e no se torna um

problema at que a rotina seja testada na execuo real. Por outro lado se estiver especificado Option Explicit, o cdigo acima iria gerar um erro de compilao, tornando fcil encontrar o erro antes de continuar nos esforos de desenvolvimento. Para terminar, pense nisso: se o bug no exemplo acima foi fcil de encontrar, o que aconteceria se o mesmo bug estivesse enfiado no meio de centenas de linhas de cdigo? O uso de Option Explicit a coisa mais importante de todas para um bom cdigo VBA. partir do Office 95, Option Explicit pode ser inserido automaticamente em todos os mdulos criados. Procure no Help on-line por "Opes" (Options) para ter maiores informaes. #2: Declare Variveis Corretamente Existem vrios pontos a serem considerados na declarao de variveis usando a declarao Dim. Primeiro, organize suas declaraes Dim para mant-las sempre juntas dentro de um procedimento, ou na seo de declaraes de um mdulo. Ao colocar todas as declaraes Dim no incio de um procedimento, podemos fazer um inventrio rpido das variveis que pertencem a ele. Tambm fica mais fcil fazer um controle de qualidade das variveis verificando a lista toda de uma vez, sem ter que procurar declaraes por todo o cdigo. Em segundo lugar, mantenha cada declarao Dim em uma linha. Veja o cdigo abaixo: Dim intX as Integer, intY, intZ As integer Uma olhada rpida ao cdigo pode nos levar a acreditar que esto sendo definidas trs variveis integer. Entretanto, uma olhada mais cuidadosa revela que intY no est sendo declarada como integer (na verdade uma variant). Se cada uma destas variveis estivesse declarada em uma linha, ficaria aparente que intY no estava tipada. Ao aplicar esta regra ao seu cdigo, tambm ser evitada as sndrome do Dim simples. Veja o cdigo abaixo: Dim a, b, c As String A inteno deste cdigo era declarar trs variveis como string. Mas o VBA no trabalha assim: apenas c declarada como uma string - as outras so declaradas como variant. O VBA exige que cada varivel seja declarada explicitamente. Se no, ser criada como variant, o que menos eficiente. Saiba tambm que o VBA permite que se especifique tipos para constantes usando este tipo de sintaxe: Const strCliente As String = "Cliente" #3: Evite Variants Para facilitar a vida de desenvolvedores iniciantes, o VBA oferece o tipo de dados Variant. este tipo de dados muito flexvel pois pode representar quase todo tipo de dado, e o VBA trata todas as converses de um tipo para outro automaticamente. Mas este poder tambm uma fraqueza. Como o tipo Variant pode conter qualquer tipo de dados, o overhead aumenta - sempre mais eficiente armazenar os dados usando o tipo de especfico do que usar o tipo variant. Alm disso, como o VBA faz as converses automaticamente no temos controle - os resultados podem ser bem diferentes do esperado.

#4: No Use Caracteres de Declarao de Tipo A maioria das variantes do Basic da microsoft oferece caracteres de declarao de tipo simples (e arcaicos). Colocando-se um destes caracteres no final do nome da varivel ou funo, definimos o tipo da varivel ou o valor de retorno da funo. Por exemplo, a linha de cdigo abaixo: Dim CName$ Declara uma varivel chamada CName como string. O caractere cifro ($) no final um caractere de declarao de tipo, e o Office sabe que o sinal de cifro significa uma varivel string. O problema que caracteres de declarao de tipo uma coisa antiquada. Eles ainda existem no VBA principalmente para compatibilizao com verses anteriores do Basic. Um bom cdigo VBA deve evitar os caracteres de declarao de tipo pois so considerados obsoletos. Alm disso, existem caracteres de declarao de tipos para apenas um pequeno subconjunto de tipos de dados que o VBA suporta. Deve-se tambm evitar as declaraes Def..., como DefInt A-Z. estas construes tambm so obsoletas e levam a cdigo difcil de depurar e manter. OsmarJr: Nas primeiras verses de Basic as declaraes de variveis eram feitas apenas com uma letra e o caractere de tipagem. A manuteno era "deliciosa": Dim A$, B$, C%, D% e tnhamos que lembrar exatamente o que queria dizer cada uma... 5: Use Variveis em Escopos Pequenos Todas as variveis e procedimentos do VBA esto contidos em escopos para ficarem disponveis a diferentes partes do programa. Por exemplo, uma varvel declarada como Pblica em um mdulo padro do Office pode ser lida ou modificada por qualquer procedimento em qualquer mdulo da base de dados. Este o escopo mais amplo. Por outro lado, variveis declaradas como Private dentro de um procedimento ou passadas como parmetros de procedimentos tm o menor escopo - so vistas apenas pelo procedimento. Entre estes dois extremos, tambm temos o escopo do mdulo. Ao decidir qual o escopo de uma varivel, use o menor escopo possvel. Se a varivel vai ser usada apenas em um procedimento, faa com que seja Private naquele procedimento. Se a varivel vai ser usada por diversos procedimentos dentro de um mdulo, crie-a como uma varivel a nvel de mdulo. Apenas em muito raras ocasies ser necessria a criao de variveis Public. Cdigo com escopo pequeno muito mais fcil de manter e depurar. Tambm so bem mais fceis de mover ou copiar. #6: Converta Tipos de Dados Explicitamente Existem momentos em que necessrio converter dados de um tipo para outro. O VBA faz com que isto seja enganadoramente simples ao fazer automaticamente estas converses. Mas isto no necessariamente uma boa coisa. Isto especialmente verdadeiro ao converter nmeros de integer para double. Alm disso, a semntica e o comportamento da converso automtica de dados normalmente est mal documentada ou no documentada, e pode mudar entre verses da linguagem. Por estas razes use as funes de converso explcitas do VBA no seu cdigo (CInt, CDbl,CStr, etc). Aceitar simplesmente as converses automticas do VBA pode levar a problemas difceis de localizar.

#7: Indicar Explicitamente o Tipo do Retorno de Funo: Uma das dicas mais importantes para variveis declarar explicitamente o seu tipo. A mesma regra se aplica s funes. Quando se cria um procedimento como uma funo, est-se dizendo ao VBA que o procedimento retorna um valor. Se no declaramos explicitamente o tipo do retorno com a palavra chave As, o VBA sempre devolve o valor como Variant. Como com variveis, isto pode levar a converses estranhas e erros de lgica no seu cdigo. Isto tambm faz com que a compilao no consiga identificar a passagem incorreta de valores. Por exemplo, se a funo est definida para devolver um resultado do tipo numrico e recebe uma varivel do tipo string, ocorrer um erro de compilao. Mas isto no ocorre se nada for especificado. Seu aplicativo vai travar ao atingir esta linha de cdigo. Toda funo dever estar explicitamente tipada. #8: Implemente Tratamento de Erro Robusto Quando ocorre um erro no tratado em seu aplicativo VBA, pode ocorrer um monte de coisas interessantes e indesejadas. Em primeiro lugar ser mostrada uma caixa de dilogo, normalmente com os botes Ok, Cancelar e Encerrar. Se o seu usurio conhece o bastante para entender a mensagem apresentada, ele ou ela ser apresentado sem a menor cerimnia ao cdigo VBA, na linha onde ocorreu o erro. Tal comportamento dificilmente pode-se dizer que a marca de um desenvolvimento profissional de um aplicativo. Para piorar as coisas, o cdigo fonte pode estar protegido, fazendo com que mensagens ainda mais estranhas apaream. Por estas razes o tratamento de erros deve ser parte crucial dos esforos de desenvolvimento de um bom aplicativo. Cada procedimento, no importa quo pequeno ou insignificante, deve ter algum tipo de tratamento de erro. No nvel mais rudimentar, deve haver um comando On Error GoTo que encaminha o VBA a um rtulo dentro do procedimento. Este rtulo deve conter cdigo que, pelo menos, apresenta uma mensagem de erro inteligvel. Tambm deve ser considerada a criao de uma pilha (stack) de procedimentos. Uma pilha simplesmente uma lista de procedimentos e a ordem em que esto sendo executados. Esta lista til quando o aplicativo encontra um erro inesperado. Quando tal erro ocorre, a pilha de procedimentos pode ser examinada para saber quais procedimentos estavam sendo executados e em que ordem. Uma pilha normalmente implementada como uma matriz (array). Inicialize a matriz ao iniciar o aplicativo e, no incio de cada procedimento, coloque o nome do procedimento como ltima entrada da matriz, empurrando todos os outros elementos uma casa. Imediatamente antes de sair do procedimento, remova seu nome da matriz. Ainda que esta forma exija um esforo extra de codificao, pode ser bastante til ao tentar depurar um aplicativo instalado em um local remoto. Para terminar, o VBA suporta a funo Erl. Esta funo retorna o nmero da linha onde ocorreu o ltimo erro. Podemos usar esta funo como parte da rotina de tratamento de erros para indicar exatamente onde o erro ocorreu. Infelizmente esta tcnica tem dois problemas: o nmero fsico da linha deve ser digitado no cdigo para que Erl devolva alguma coisa significativa e o Office 97 no suporta Erl corretamente, devolvendo, muitas vezes, resultados errados. #9: Cuidado com o Fluxo do Programa O VBA fornece vrios caminhos para controlar desses caminhos so vestgios dos dias iniciais listas lineares e no modulares que exigiam a principalmente GoTo, GoSub e Return tem

o fluxo dos programas Por azar, alguns do BASIC, quando os programas eram numerao de linhas. Estes caminhos, pouca validade em programas VBA

modernos. Normalmente levam a saltos complicados e de lgica de difcil compreenso. Se voc deseja escrever cdigo bem estruturado, no deve usar os comandos GoSub/Return, e usar o comando GoTo apenas para o tratamento de erros. Igualmente importante: nenhum procedimento deve ter mais de um ponto de sada (comandos Exit Sub ou Exit Function). Se um procedimento oferece mais de uma sada, erros de lgica, objetos no fechados e erros no tratados podem ocorrer. Finalmente: pense na adoo da conveno onde todos os seus procedimentos tem um rtulo de tratamento de erro e um rtulo indicando a sada especficos e padronizados. #10: Use Constantes Valores inseridos no cdigo do programa fazem com que ele se torne difceis de entender e atualizar. Veja o cdigo abaixo: Dim intCusto As Integer Dim intQuantidade As Integer intCusto = intQuantidade * 1.712 O que faz o cdigo? Isto bvio: multiplica uma quantidade por 1,712 para obter o custo. Mas o que 1, 712? Este tipo de nmeros mgicos no oferecem informaes sobre o que est sendo obtido e fazem com que o programa seja difcil de decifrar. Se o nmero necessitar alterao, pode ser difcil encontr-lo. muito melhor declarar uma constante para o nmero. Considere o cdigo: If Err.Number = 2048 Then MsgBox "Ocorreu erro 2048", 16, "Aplicativo ACME" Else MsgBox "No ocorreu erro 2048", 16, "Aplicativo ACMO" Endif Neste exemplo, valores inseridos causam dois problemas. O primeiro causado pelo nmero 16. O que representa 16? Que tipo de cone mostrado pela funo MsgBox? Segundo, como "Aplicativo ACME" est inserido duas vezes fica fcil a ocorrncia de erros de digitao, como mostrado no segundo comando MsgBox. Para terminar, inserindo literais por todo o programa fica difcil fazer alteraes globais no aplicativo todo. estes problemas podem ser evitados substituindo valores inseridos por constantes ou variveis centralizadas ou pela colocao destes valores em uma tabela. No incio do aplicativo, todos estes valores de texto e nmeros mgicos so lidos da tabela para a memria, ficando disponveis para o programa. Ao remover todos os valores inseridos, reduzimos o potencial de erros e tornamos mais fcil a manuteno do programa. Este ltimo ponto pode ser crucial se o aplicativo for internacionalizado. Ao traduzir o aplicativo para outra lngua vemos quanto vale ter cdigo que tenha todos os valores e textos armazenados em um local centralizado. #11: Use Convenes de Nomeao de Variveis Ainda que os mritos relativos de diferentes converses de nomeao de variveis possam causar discusses acaloradas entre desenvolvedores, o uso de convenes de nomeao normalmente aceito como boa prtica de programao. Convenes de nomeao acrescentam informaes a variveis, objetos e nomes de procedimentos, geralmente usando algum tipo de prefixo ou sufixo. Este tipo de notao exige que se

digite alguns caracteres no incio ou fim do nome da varivel para indicar seu tipo. Por exemplo, cada varivel string seria criada com o prefixo "str", indicando que tais variveis so do tipo string. Existem diversas convenes de nomeao para o VBA, divididas entre desenvolvedores Visual Basic e Office. Alm do cdigo, tambm so usadas convenes para nomear objetos do Office (por exemplo: tabelas comeam com "tbl", consultas com "qry", formulrios com "frm", botes de comando com "cmd", etc). A conveno de nomeao usada no to importante quanto seu comprometimento em us-la consistentemente e constantemente. Convenes de nomeao no funcionam se no forem usadas em todo o cdigo. Assim sendo, escolha uma conveno e use-a sempre. #12: Escolha Nomes Significativos para Variveis Pode parecer bvio que um desenvolvedor escolha nomes para procedimentos e variveis que indiquem o propsito de cada objeto. Mas, muitas vezes, no calor da programao, fica muito fcil descambar para nomes de variveis com uma letra, como x ou y. Para facilitar a leitura esta tentao deve ser evitada. Geralmente variveis com uma letra para identificao so usadas para variveis descartveis, como contadores de lao; fora isso, deve-se evitar nomes que no carreguem alguma informao. Muita vezes a nomeao de objetos bate de frente com a meta de manter um cdigo compacto - para documentao. Desejamos nomes que sejam longos o bastante para descrever adequadamente a varivel ou o procedimento, mas no queremos nomes que sejam to longos que tornem nosso cdigo ilegvel ou difcil de digitar. Entre os dois extremos temos uma boa mdia: usar nomes que sejam longos o suficiente para identificar seu propsito, mas no to longos que tornem o cdigo impossvel de se administrar. #13: Comente Se voc j tentou decifrar cdigos escritos por outro programador (ou at seu prprio cdigo), no importando a linguagem, sem dvida voc j sabe o valor do bom comentrio. Muitas vezes o propsito de uma parte qualquer do cdigo no fica aparente ao se ler. Comentrios auxiliam muito fazendo com que o processo de entender, melhorar e depurar se torne muito mais fcil e rpido. Existem vrias nveis de comentrios na codificao VBA. Estes nveis seguem de perto os nveis de escopo: Comentrios do aplicativo (globais) Comentrios a este nvel explicam o fluxo de todo o aplicativo e cobrem a interao entre diferentes mdulos e componentes. Tipicamente, estes comentrios so mantidos fora da base de dados do projeto, mas podem ser includos em um mdulo global como texto de comentrio. Comentrios de Mdulos Comentrios a nvel de mdulo explicam o propsito e contedo de um mdulo,. As informaes normalmente incluem uma lista de procedimentos contidos no mdulo, seu propsito e relacionamentos, e comentrios de reviso do mdulo como um todo. Comentrios de Procedimentos Comentrios para cada procedimento normalmente incluem uma breve descrio do que o procedimento faz, uma definio de seus parmetros e valor de retorno, informaes sobre revises, e qualquer outra situao especial que ocorra dentro dele.

Comentrios de linha Comentrios na ou acima de uma linha especfica explicam o propsito de uma varivel ou de uma seqncia particular de operaes. Tipicamente, melhor incluir um comentrio de linha imediatamente acima dela. Comentrios na mesma linha podem tornar o cdigo difcil de ser visualizado. #14: Use Identificao Padro Estruturas de controle devem ser identificadas para melhorar a legibilidade e reduzir os erros de programao. Estruturas emparelhadas como If...End If, Do...Loop, For...Next, With...End With, While...Wend, Select Case...End Select, Type...End Type, etc., devem ser identificadas para mostrar claramente onde comeam e terminam. Alm disso, procure manter um padro de tabulao - no h nada pior que tentar trabalhar em um aplicativo que tenha diversos padres de tabulao. Por padro, o Office usa quatro espaos, mas se seu cdigo tem muitos aninhamentos, dois espaos podem se mostrar melhor. A identificao tambm pode auxiliar no agrupamento visual de operaes relacionadas, no apenas de estruturas de controle. Por exemplo, imagine fazer a identificao para agrupar operaes AddNew...Update, Set...Close, BeginTrans...CommitTrans. Isto torna mais fcil visualizar quando o cdigo "entra" e "sai" destas operaes "emparelhadas". #15: Evite o Uso de Ifs em uma nica Linha A colocao de uma condio If e sua ao na mesma linha leva a cdigo difcil de ler e manter. Em vez de: If fInitialized Then DoCmd.OpenForm "frmOpen" faa: If fInitialized Then DoCmd.OpenForm "frmOpen" End If #16: Use Select Case Corretamente A construo Select Case torna fcil o programa se ramificar em mltiplos valores possveis para uma varivel ou expresso. Duas coisas devem ser vistas quando se usa Select Case. A primeira uma questo de estilo. Evite colocar uma ao na mesma linha do Case. O cdigo abaixo demonstra isto:

Select Case intType Case acTable : strType = "Table" Case acQuery: strType = "Query" End Select

Estilo ruim: difcil de ler e manter: Select Case intType Case acTable strType = "Table" Case acQuery strType = "Query" End Select

Uma forma melhor: fcil leitura e expanso no futuro No primeiro exemplo, difcil ver rapidamente qual a condio e qual a ao. Alm disso, ao voltar ao cdigo para acrescentar algo clusula de ao, ser necessrio format-la corretamente mesmo - mltiplas aes no podem mais ser usadas em uma nica linha! Evite futuros problemas formatando os blocos Select Case j no incio. Outa dica que pode economizar horas de frustrao ao tentar depurar um aplicativo complexo. A menos que voc tenha definido uma clusula Case Else no seu bloco Select Case, valores no antecipados no sero usados. Por exemplo, assuma que seu aplicativo permita ao usurio acrescentar novas categorias de empregados. Seu aplicativo tambm tem um cdigo VBA que d um reajuste a cada funcionrio baseado no tipo de trabalho. O usurio acrescenta "Programador de Computador" como nova categoria e algumas pessoas so contratadas para o trabalho. O seu bloco Select Case para tratar dos reajustes seria mais ou menos assim: Select Case intTipoEmpregado Case EmpTipo_Gerente intReajuste =10 Case EmpTipo_Vendedor intReajuste = 5 Case EmpTipo_Motorista intReajuste = 2 End Select Adivinha quem no vai receber um reajuste? Se voc seguir a prtica de sempre incluir uma clusula Case Else, problemas como o acima se tornam fceis de trabalhar. Por exemplo, o cdigo acima poderia ser reescrito para pedir que o usurio entre com o valor do reajuste no caso de novos tipos de empregados: Select Case intTipoEmpregado Case EmpTipo_Gerente intReajuste =10 Case EmpTipo_Vendedor intReajuste = 5 Case EmpTipo_Motorista intReajuste = 2 Case Else Beep intReajuste = InputBox ("Entre com o valor do reajuste.") End Select

#17: No use comandos STOP para depurar A primeira vista, o comando Stop parece ser a melhor opo para a depurao. Voc insere a palavra chave Stop no seu cdigo, no lugar desejado, executa-o e o VBA para a execuo quando chega quela linha. O problema que voc pode esquecer de excluir todos os comandos Stop antes de colocar seu cdigo para uso na produo. No h nada mais embaraoso que ver seu cdigo abrir em um comando Stop enquanto o usurio est usando seu aplicativo - tudo porque voc esqueceu de remover um comando sem importncia. Uma alternativa melhor a utilizao de pontos de parada (breakpoints). Eles executam a mesma funo do comando Stop mas no so salvos com o cdigo. Ao sair do Access, todos os pontos de parada so descartados, assegurando que seu cdigo no vai parar inesperadamente.

Concluso: Escrever cdigo robusto, de fcil manuteno e sem bugs uma tarefa difcil. As linguagens de desenvolvimento so inerentemente difceis de usar, fazendo com que seja muito fcil o aparecimento de problemas. Entretanto, com uma viso disciplinada e um bom conjunto de normas, seus esforos sero recompensados por programas que funcionam, e funcionam bem.

Crie um sistema que at um idiota pode usar, e s um idiota vai querer us-lo. George Bernard Shaw (1856-1950)