Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Introdução
Uma analogia bastante utilizada é dizermos que se um bolo é um objeto, sua receita é uma
classe. Seguindo o raciocínio, é possível fazer vários bolos a partir de uma receita, ou vários
objetos a partir de uma classe. Uma classe não aloca memória em tempo de execução, e um
objeto sim, já que a classe possui apenas a definição do objeto que cria.
Sub CriarObjeto()
'Declarar:
Dim oCarro As clsCarro
'Instanciar:
Set oCarro = New clsCarro
'Consumir:
'...
'Destruir:
Set oCarro = Nothing
End Sub
oCarro é o objeto e clsCarro é a classe. Repare que quando trabalhamos com objetos, as
atribuições devem ser feitas com o uso da palavra chave Set, ao contrário de tipos de dados
simples como Long, Integer, Date, etc., em que o uso da igualdade dá valor à variável.
Para que o exemplo acima funcione, é necessário que criemos a classe clsCarro no nosso
projeto VBA:
Embora não seja obrigatório, é altamente recomendável destruir todos os objetos criados ao
término da execução do seu programa. O gerenciamento de memória e coletor de lixo do VBE
não são bons, e ao adotar essa prática você minimiza erros inesperados e até crashes no
Excel.
Consumir Objetos
O exemplo a seguir mostra como acessar membros de um objeto de uma classe
chamada clsEmpregado. Pelo código, podemos ver que a classe define três
propriedades: Nome, Endereço e Salário. Cole o num Módulo de Classe
chamado clsEmpregado:
'Propriedade Endereço:
Property Get Endereço() As String
Endereço = aEndereço
End Property
Property Let Endereço(pEndereço As String)
aEndereço = pEndereço
End Property
'Propriedade Salário:
Property Get Salário() As Double
Salário = aSalário
End Property
Property Let Salário(pSalário As Double)
aSalário = pSalário
End Property
Para cada uma das propriedades, há um procedimento Get e outro Let. Get é chamado
quando se deseja ler o valor de uma propriedade e Let é chamado quando se
deseja atribuir um valor a uma propriedade.
Para vermos nosso programa em funcionamento, devemos criar num módulo (comum, e não
de classe) o seguinte código:
Sub UsoBásicoDeClasses()
Dim oEmpregado As clsEmpregado
Set oEmpregado = New clsEmpregado
oEmpregado.Nome = "Felipe"
oEmpregado.Endereço = "Rua Jardim, 20/603"
oEmpregado.Salário = 1000
Ao executar essa rotina, teremos como resultado na janela de verificação imediata (Ctrl+G):
Nome: Felipe
Endereço: Rua A, 12/901
Salário: 1000
Uso do With
Ao trabalhar com suas classes personalizadas, você pode usar o bloco With com os objetos
que você criar:
Sub UsoBásicoDeClassesComWith()
Dim oEmpregado As clsEmpregado
Dentro da classe, podemos observar, por exemplo Endereço, aEndereço e pEndereço. O que
está havendo? Para definir uma simples propriedade, utilizei três membros diferentes com
nomes semelhantes. Eles são necessários. Vamos rever a definição de atribuição de
propriedade Endereço:
aEndereço = pEndereço
End Property
Endereço = aEndereço
End Property
Endereço, nesse contexto, funciona igual uma função, que retorna o valor do
atributo aEndereço ao procedimento que chamou a propriedade Endereço.
Simplificando Declaração de uma Propriedade
Se você não precisar inserir código no procedimento Get e Let de uma variável, você pode
declarar a variável como pública que o VBE irá considera-lo como uma variável. Em outras
palavras, o bloco de código:
É equivalente a simplesmente:
Note que ao utilizar a palavra-chave Public numa variável que está dentro de um módulo de
classe, ela não é pública para todo projeto, como ocorre em declarações em módulos
regulares. Public em módulos de classe significa que a variável declarada pode ser acessada
por procedimentos que não estejam dentro da classe.
Note que poderíamos ter utilizado a variável de módulo (que aqui tem a função de
atributo) aSalário ao invés da propriedade Salário. No entanto, as boas práticas de
programação dizem que quando estamos numa classe, devemos utilizar o valor retornado pela
propriedade, e não a variável que armazena o valor da propriedade. Essa boa prática tem um
custo que é tornar a depuração do código mais trabalhosa, uma vez que todo acesso à
propriedade Salário desvia o código para seu procedimento respectivo. Por outro lado, ao
usar o valor da propriedade, você terá garantido que o valor atribuído já foi processado e
validado por sua classe.
O fato dessa propriedade não possuir a instrução Let é o que a caracteriza somente como
leitura, tornando impossível fazer uma atribuição direta a ela.
Sub ExemploMétodo()
Dim oEmpregado As clsEmpregado
O resultado será:
'Eventos
Private Sub Class_Initialize()
Me.Endereço = "Rua das Flores, 105"
End Sub
Private Sub Class_Terminate()
MsgBox "Um objeto cuja propriedade Endereço é " & Me.Endereço & " foi
destruído.", vbInformation
End Sub
'Propriedades
Property Get Endereço() As String
Endereço = aEndereço
End Property
Property Let Endereço(pEndereço As String)
aEndereço = pEndereço
End Property
Sub ExemploEventos()
Const VALOR_DÓLAR_DO_DIA = 3.03
Sub CriarObjetoFormaNãoRecomendada()
'Declarar e instanciar:
Dim oCarro As New clsCarro
'Consumir
'...
'Destruir
Set oCarro = Nothing
End Sub
Foi feita a declaração e criada uma instância do objeto numa única instrução. O nome dessa
técnica é auto instanciação de variável. No VBA, não é recomendável utilizá-la por dois
motivos:
Aumenta o overhead do código porque cada chamada a um objeto criado dessa classe irá
disparar o evento de inicialização do mesmo. Ao criar um objeto dessa forma e fazer uma
simples atribuição como, por exemplo, oCarro.Cor = "Verde", o
evento Class_Initialize será disparado, e isso é altamente indesejável.
Não há como testar se uma variável criada desse tipo é Nothing porque a própria instrução
de teste irá criar uma instância do objeto, retornando, então, sempre Falsepara o teste.
Nesse exemplo, o teste If oCarro Is Nothing Then... sempre irá passar.
Criar mais de um Objeto com uma Classe
No exemplo a seguir, foram criados três objetos do mesmo tipo, mas com propriedades
diferentes:
Sub VáriosObjetos()
Dim oEmp1 As clsEmpregado
Dim oEmp2 As clsEmpregado
Dim oEmp3 As clsEmpregado
oEmp1.Nome = "Felipe"
oEmp1.Endereço = "Rua Jardim, 20/603"
oEmp1.Salário = 1000
'---
oEmp2.Nome = "Renata"
oEmp2.Endereço = "Praça das Flores, 305"
oEmp2.Salário = 1500
'---
oEmp3.Nome = "Rodrigo"
oEmp3.Endereço = "Av. Castro, 50/101"
oEmp3.Salário = 2000
oEmp1.MostrarFolhaDePagamento
oEmp2.MostrarFolhaDePagamento
oEmp3.MostrarFolhaDePagamento
O VBA não mistura os valores das propriedades (na verdade atributos) dos objetos criados.
Cada objeto aloca espaço na memória para guardar os próprios valores de cada propriedade.
Sub ColeçãoDeObjetos()
Dim tblEmpregados As ListObject
Dim oEmpregado As clsEmpregado
Dim cEmpregados As Collection
Dim iListRow As ListRow
Dim iItem As Long
'Inicializar Coleção?
Set cEmpregados = New Collection
'Mostrar resultados
For Each oEmpregado In cEmpregados
Debug.Print oEmpregado.Nome, oEmpregado.Endereço, oEmpregado.Salário
Next oEmpregado
End Sub
Você pode remover um item da coleção se desejar. A instrução abaixo remove o terceiro item
da coleção do nosso exemplo:
cEmpregados.Remove 3
Gerador de Propriedades
Usando um “código para gerar código”, você pode tornar menos moroso o processo de
escrever declarações de propriedades:
Sub GerarPropriedade()
Dim sAtributo As String
Dim sInstrução As String
Dim sParâmetro As String
Dim sPropriedade As String
Dim sSaída As String
Dim sTipoDeDados As String
Dim vInstruções() As String
vInstruções = Split(sInstrução)
sAtributo = vInstruções(1)
sPropriedade = Mid(sAtributo, 2)
sParâmetro = "p" & sPropriedade
sTipoDeDados = vInstruções(3)
sSaída = ""
sSaída = sSaída & "Property Get " & sPropriedade & "() As " & sTipoDeDados
& vbNewLine
sSaída = sSaída & vbTab & sPropriedade & " = " & sAtributo & vbNewLine
sSaída = sSaída & "End Property" & vbNewLine & vbNewLine
sSaída = sSaída & "Property Let " & sPropriedade & "(" & sParâmetro & " As
" & sTipoDeDados & ")" & vbNewLine
sSaída = sSaída & vbTab & sAtributo & " = " & sParâmetro & vbNewLine
sSaída = sSaída & "End Property" & vbNewLine
Debug.Print sSaída
End Sub
Se você entrar Private aNome As String na janela, obterá as declarações Get e Letna
janela de verificação imediata:
Você pode criar versões mais sofisticadas desse código, como por exemplo: obter o esquema
de uma tabela de um banco de dados e gerar classes no VBE mapeando cada um dos campos
a uma propriedade. Use a criatividade. Não deixe de verificar também o MZ Tools, que possui
um ótimo assistente para criar propriedades em classes.
Fontes: