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.
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:
usei em uma ocasião que fiz o código sem fazer um projeto
antes de começar:
Private Arquivos
As Variant
As Variant
Private Resposta
As Integer
As Integer
Private ContadorArquivo As Integer
Private TotalArquivos As Integer
Private Quantidade As
Integer
Integer
Private Contador
As Integer
As Integer
Private
Inicio
As Long
Inicio
As Long
Private
Proximo As
Long
Proximo As
Long
Private
Tamanho As
Long
Tamanho As
Long
Private
Linha
As Long
Linha
As Long
Private UltimaLinha As Long
Private ValorEncontrado As Long
Private NomeArquivo As String
Private Registro
As String
As String
Private TipoRegistro As String
Private
Texto
As String
Texto
As String
Private Intervalo As
Range
Range
Private
Tabela
As Range
Tabela
As Range
Private Adicionado As
Boolean
Boolean
Private Encontrado As
Boolean
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.
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…
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 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
Contador.Limite
Debug.Print
“Contador = ” & Contador.Atual
“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).
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.
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.
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:
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:
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:
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, _
String, DataNascimento As Date, _
CPF As Long) As Boolean
Function PesquisarCliente(Cliente As tpCliente) As
Boolean
Boolean
A segunda forma é muito mais clara e simples. A primeira pode
até assustar pela quantidade de parâmetros.
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:
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.
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.
o InteliSense do editor de VBA. Assim que teclar o
ponto para digitar uma propriedade, o menu aparece:
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.
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:
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.
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.
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.
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.
Catálogo de aulas (NOVIDADE)
Criei um catálogo de aulas para ajudar você em seus estudos. Acesse clicando na imagem abaixo ou clique aqui.