Melhorando seu código com objetos Type
Dei uma breve explicação sobre objetos type no meu sexto artigo, com um exemplo muito simples e
superficial. Neste vou explicar melhor as aplicações para este objeto tão
subestimado no VBA.
Observe este exemplo real de declaração de variáveis, que
usei em uma ocasião que fiz o código sem fazer um projeto antes de começar:
Private Arquivos As
Variant
Private Resposta As
Integer
Private ContadorArquivo As Integer
Private TotalArquivos As
Integer
Private Quantidade As
Integer
Private Contador As
Integer
Private Inicio As
Long
Private Proximo As
Long
Private Tamanho As
Long
Private Linha As
Long
Private UltimaLinha As
Long
Private ValorEncontrado As Long
Private NomeArquivo As
String
Private Registro As
String
Private TipoRegistro As
String
Private Texto As
String
Private Intervalo As
Range
Private Tabela As
Range
Private Adicionado As
Boolean
Private Encontrado As Boolean
Para deixar mais claro, deixei as variáveis separadas por
tipo. Perceba que mesmo com os nomes de variáveis com a maior clareza possível,
a finalidade de cada uma começa a ficar confusa quando há várias com nomes
similares e tipos distintos. Em alguns casos, acabei reutilizando as variáveis
em mais de uma sub-rotina, pois eram variáveis definidas para o módulo. No
final, a manutenção acabava prejudicada, pois até descobrir a finalidade exata
de cada uma levava algum tempo.
Algo que é muito recorrente nos códigos são as estruturas de
repetição. Em laços do tipo For... Next
costumamos declarar duas variáveis: a iteração (que irá incrementar ou
decrementar conforme o laço é executado) e o limite (o valor que encerra o
laço). No exemplo acima temos ContadorArquivo,
Contador e Linha como iterações e TotalArquivos,
Quantidade e UltimaLinha como limites. Linha
e UltimaLinha foram duas das
variáveis que foram utilizadas em várias sub-rotinas para controlar o
processamento em tabelas distintas. E se eu precisasse de procurar algum valor
em outra tabela? Não daria para usar as mesmas variáveis, pois estavam em uso.
Mais um par de variáveis sendo criado...
Existe alguma maneira de simplificar? Um objeto type pode ajudar. Observe o código
abaixo:
Type tpIteracao
Atual As Integer
Limite As Integer
End Type
Sub Teste()
Dim Contador As
tpIteracao
Contador.Limite = 10
For Contador.Atual = 1
To Contador.Limite
Debug.Print
"Contador = " & Contador.Atual
Next
End Sub
O objeto tpIteracao
está declarado fora das rotinas, sendo assim público. Pode ser utilizada em
qualquer sub-rotina do módulo atual ou mesmo em outros módulos. O objeto foi
criado com duas propriedades Atual e Limite (poderia usar outros nomes, mas
preferi estes).
No exemplo acima foi declarado Contador como sendo do tipo tpIteracao
e assim tendo a mesma estrutura do objeto criado. Na estrutura de repetição, Contador.Atual se refere à iteração
atual e Contador.Limite se refere à
última iteração.
Uma grande vantagem é que o objeto pode ser declarado dentro da
sub-rotina, existindo somente enquanto esta estiver em execução. Se houver
necessidade de um laço dentro do outro, cria-se dois objetos tpIteracao. Outra vantagem é que os
nomes das propriedades ficam padronizadas em todas as vezes que o objeto for
criado, facilitando assim o entendimento e a manutenção do código.
Você pode criar objetos diferentes para cada finalidade. Por
exemplo, pode criar um objeto tpLinha
como contador de linhas da tabela e usar propriedades do tipo long, para suportar todas as linhas da
planilha e um objeto tpContador, com
propriedades do tipo integer, para
quantidades menores, podendo usar até nomes de propriedades diferentes, de
acordo com as necessidades do momento:
Type tpLinha
Atual As Long
Ultima As Long
End Type
Type tpContador
Item As Integer
Total As Integer
End Type
O melhor uso para objetos type é agrupar dados referentes a um objeto específico. Por
exemplo, em vez de criar variáveis individuais para um cliente, podemos criar
uma estrutura type com todas as
propriedades que queremos para o cliente, de preferência na mesma ordem que
colocaremos na planilha:
Type tpCliente
Codigo As Long
Nome As String
DataNascimento As Date
CPF As Long
End Type
Suponha que seu código tenha uma função para pesquisar
cliente que retorna um valor Verdadeiro
ou Falso caso encontre ou não. A
pesquisa poderia ser por código, pelo nome do cliente junto com a data de
nascimento (para prevenir problemas com homônimos) ou pelo CPF. Ao invés de enviar cada
propriedade individualmente como parâmetro da rotina, podemos colocar o objeto type como único parâmetro. Veja o
exemplo da declaração da sub-rotina com parâmetros individuais e com o type como parâmetro:
Function PesquisarCliente(Codigo As Long, Nome As String, DataNascimento As
Date, _
CPF As Long) As Boolean
Function PesquisarCliente(Cliente As tpCliente) As Boolean
A segunda forma é muito mais clara e simples. A primeira
pode até assustar pela quantidade de parâmetros.
Da mesma forma, uma sub-rotina para adicionar o cliente fica
mais simples com um parâmetro apenas:
Sub AdicionarCliente(Cliente As tpCliente)
Veja como a manutenção fica mais fácil: caso você precise
acrescentar campos na planilha de cliente, basta acrescentá-los na declaração
do objeto tpCliente e depois editar
as sub-rotinas que farão uso desses campos, sem necessidade de editar os
parâmetros de cada sub-rotina e função para acrescentar os campos novos.
Desta forma fica mais fácil garantir que não haverá erros de
digitação nos nomes das propriedades e também ajuda a lembrar os nomes das
propriedades, pois aparecerão na lista.
Lembra das enumerações? As propriedades podem ser combinadas
com enumerações, facilitando ainda mais a digitação e a clareza do código. Veja
um exemplo com uma enumeração para o tipo de telefone:
Enum enumTipoTelefone
Celular = 1
Residencial = 2
Comercial = 3
Recado = 4
End Enum
Type tpTelefone
CodigoCliente As Long
Tipo As enumTipoTelefone
DDI As Byte
DDD As Byte
Numero As Long
End Type
Veja como fica na hora de digitar:
São pequenos detalhes que fazem toda a diferença na hora de
fazer manutenção no código. Fica tudo mais organizado, simples e
autodocumentado. A bagunça de variáveis declaradas da forma como está no começo
do artigo passa a não existir, pois em seu lugar ficarão somente as declarações
dos objetos type.
O que achou de conhecer melhor o objeto type? Vai passar a usar? Vai pegar algum projeto existente e fazer alterações
para ver se realmente fica mais simples? Prefere usar classes? Comente, dê sua opinião.
Pedro Martins
Formado em Tecnologia em Eletrônica Digital, já trabalhou como artefinalista, eletrotécnico, programador de CLP (para máquinas industriais) e analista de sistemas em sistema bancário, programando em COBOL.
Mexe com computadores e programação desde a segunda metade dos anos 1980, quando teve um MSX e aprendeu a programar em BASIC. É a favor da disseminação do conhecimento.
Mexe com computadores e programação desde a segunda metade dos anos 1980, quando teve um MSX e aprendeu a programar em BASIC. É a favor da disseminação do conhecimento.
Parabéns, Pedro! Excelente dica. Estou lendo e aprendendo muito sobre VBA com o Trovato, mas esse assunto acho que ele ainda não mostrou em suas Vídeo Aulas.
ResponderExcluirSuas explicações foram 10, acredito que para ilustrar um pouco mais, ainda mais para àqueles que estão iniciando na longa estrada do desenvolvimento de sistemas, um antes e depois, principalmente com o exemplo do telefone.tipo, em meio o clientes.algumcampo, deixaria mais claro ainda.
Mas... com certeza, vou tentar fazer um exemplo aqui!
Valeu por compartilhar isso também!
Grande abraço!