Access
 sql >> Base de Dados >  >> RDS >> Access

Módulo de classe MS-Access e VBA

Introdução.


Nas últimas semanas, aprendemos a usar o User-Defined Type (UDT) criando uma estrutura de dados complexa e conhecemos a força ou a fraqueza do UDT, mais ou menos agora. Se você não passou por esses artigos, então você pode visitá-los. Utilize os seguintes links:
  • Tipo de dados definido pelo usuário-2
  • Tipo de dados definido pelo usuário-3

No Microsoft Access, existem dois tipos de módulos VBA.
  1. Módulos padrão
  2. Módulos de aula

Trabalhamos com Módulos de Classe em Formulários e Relatórios do Microsoft Access. Os programas do Módulo de classe de formulário/relatório são principalmente pequenas rotinas orientadas a eventos (cliques de botão, antes da atualização, evento atual de formulário/relatório e assim por diante).

Programas de processamento de dados mais sérios serão escritos em Módulos Padrão. Vários programas, não necessariamente relacionados, podem ser escritos em um Módulo Padrão, para realizar diferentes tarefas.

Módulos de classe são diferentes. Eles são usados ​​para construir objetos personalizados e um módulo de classe é usado para apenas um objeto.

Noções básicas do módulo de aula independente.


Vamos criar um módulo de classe simples do zero e aprender o básico.
  1. Inicie o Microsoft Access e abra um banco de dados ou crie um novo. Se for um novo banco de dados, salve-o no local confiável (pasta) existente ou adicione o novo local à lista de locais confiáveis. Clique no Botão Office -> Opções de Acesso -> Central de Confiabilidade -> Configurações da Central de Confiabilidade. Adicione a pasta do banco de dados à lista e clique em OK.
  2. Abra a janela de edição do VBA (Alt+F11).
  3. Clique em Inserir Menu e selecione o Módulo de turma da lista. Um novo módulo de classe é inserido.






  • No painel esquerdo, há um Nome controle com o nome Class1.
  • Alterar o nome Classe1 para ClsArea . Este é o nome do nosso Objeto Personalizado.


  • Observação: O nome da classe:ClsArea se tornar o Nome do Objeto. Isso significa que, onde quer que usemos este objeto, será como uma declaração de variável normal:Dim xyz As ClsArea . Escrevemos uma instrução semelhante para declarações de tipo de dados definido pelo usuário.

    Em seguida, adicionaremos três Propriedades (Variáveis) do Objeto (para Descrição, Comprimento, e Largura ) na parte superior do módulo, abaixo da Option Compare Database e Opção Explícita linhas. Digite as seguintes linhas no módulo de classe.
    Opção Comparar DatabaseOption ExplicitPublic p_Desc as StringPublic p_Length as DoublePublic p_Width as Double

    Essas variáveis ​​são identificadas como Propriedades do Objeto de Classe Personalizada VBA. Salve o módulo de classe.

    Observação: Nosso objeto de módulo de classe e linhas de código não serão tão simples. Ele sofrerá alterações com várias linhas de código. É melhor estar preparado para segui-los passo a passo, sem perder de vista cada etapa das mudanças. Esta é uma classe de cálculo de área simples (área =comprimento * largura ), que simples. Ele sofrerá mudanças gradualmente para que você saiba por que essas mudanças se tornam necessárias.

    Vamos escrever um pequeno programa em um módulo padrão para testar nosso novo módulo de classe. Insira um Módulo Padrão do Menu Inserir. Você pode Digitar ou Copiar e Colar o seguinte Código no Módulo Padrão, substituindo a linha existente no Módulo:
    Opção Comparar DatabaseOption ExplicitPublic Function ClassTest1() Dim oArea As ClsAreaSet oArea =Nova ClsAreaoArea.Set oArea =Função NothingEnd

    O Escurecimento declaração declara uma variável como fazemos para uma variável normal, como Dim Desc como String. Mas, esta não é uma variável comum, estamos definindo uma referência ao nosso objeto de módulo de classe ClsArea . Uma vez que é um objeto, uma simples instrução Dimension por si só não é suficiente porque não alocará nenhum espaço de memória para armazenar valores em nosso objeto definido localmente oArea Propriedades.

    O Conjunto declaração na próxima linha com o Novo palavra-chave necessária, para criar uma instância de um objeto de ClsArea na memória, com o nome da instância do objeto oArea . Podemos abrir várias instâncias do mesmo objeto de classe na memória dessa maneira, se necessário, (aprenderemos sobre elas nas próximas semanas) para que possamos armazenar valores em suas propriedades (p_Desc, p_Length, p_Width). O p_ prefixo para as variáveis ​​é um indicador de que o Escopo das variáveis ​​é Privado, ou seja, as Variáveis ​​não são visíveis fora do Módulo de Classe se a variável for declarada com a palavra-chave Private, mas agora ela é declarada como Pública. O nome da variável pode ser qualquer nome válido.

    Observação: Ainda não o declaramos como Privado. Estamos a caminho dessa mudança.

    Imediatamente após a palavra-chave Definir o nome do objeto local (você pode escolher um nome adequado de sua preferência, mas deve estar de acordo com as regras normais de nome de variável) seguido por um sinal de igual e a palavra-chave Novo e o nome do módulo de classe (ClsArea) para criar uma instância do Objeto clsArea na memória com todas as suas Propriedades (Variáveis).

    Existe um atalho para este código de duas linhas. As ações de ambas as linhas de código podem ser alcançadas com uma instrução conforme mostrado abaixo:
    Dim oArea As ClsAreaSet oArea =New ClsArea'o atalho para as duas instruções acima Dim oArea As New ClsArea

    Quando você digita a próxima linha oArea seguido por um ponto (. ), a tela a seguir aparecerá para mostrar a lista de Propriedades de Objetos Personalizados disponíveis para seleção.

    Se não aparecer, vá para a caixa de diálogo Opções na caixa do menu Ferramentas e marque a opção Listar automaticamente membros na guia Editor.

    Antes de sair da função, a última instrução deve ser Set oArea =Nothing . Essa instrução libera explicitamente a memória ocupada pela instância do Objeto Personalizado, para que mais memória fique disponível para outros programas. Esta é uma operação de limpeza responsável pelo nosso programa.

    O que quer que façamos com o objeto personalizado instanciado deve ser codificado entre o primeiro e o último conjunto declarações.

    O programa de teste de objeto de classe ClsArea.


    O Código do Programa de Teste de Classe preenchido é fornecido abaixo:
    Opção Comparar DatabaseOption ExplicitPublic Function ClassTest1() Dim oArea As ClsAreaSet oArea =Novo ClsAreaoArea.p_Desc ="Tapete"oArea.p_Length =25oArea.p_Width =15Debug.Print "Description", "Length", "Width"Debug.Print oArea.p_Desc, oArea.p_Length, oArea.p_WidthSet oArea =Função NothingEnd

    Clique em algum lugar no meio do Código e pressione F5 para executar o programa. A execução do programa é fornecida abaixo para referência.
    Descrição Comprimento LarguraTapete 25 15 

    Público|Escopo Privado das Propriedades do Objeto.


    Nosso objeto de módulo de classe simples tem algumas desvantagens e vamos corrigi-las.

    A primeira é que declaramos todas as Variáveis ​​(ou Propriedades) com Público Alcance. Por causa disso, eles são visíveis para outros programas VBA e podem ter seu valor alterado diretamente. O segundo problema é que ele aceitará quaisquer valores inválidos, como valores negativos ou zero, o que não é adequado para nosso objeto de classe. Temos que incorporar algumas verificações de validação antes de aceitar os valores nas variáveis.

    O primeiro problema podemos resolver facilmente alterando as declarações de variáveis ​​de Public para Private . Quando fizermos isso, devemos ter algum método indireto para armazenar e recuperar valores das Variáveis ​​Privadas. Esse é o propósito do Obter e Deixe Procedimentos de Propriedade, para cada Propriedade do Objeto. Vamos fazer essas alterações no módulo de classe.

    Abra o módulo de classe ClsArea. Altere a palavra Público para Privado para todas as três variáveis.

    Criação de procedimentos de propriedade


    Selecione Procedimento de Inserir Menu, digite strDesc no Nome controle de texto, selecione Propriedade no Tipo Grupo de opções e Público no Escopo grupo de opções. Clique em OK para inserir os procedimentos de propriedade para o p_Desc privado Variável (Propriedade).
    Opção Comparar DatabaseOption ExplicitPrivate p_Desc As StringPrivate p_Length As DoublePrivate p_Width As DoublePublic Property Get strDesc() As String strDesc =p_Desc 'retorna o valor de p_DescEnd PropertyPublic Property Let strDesc(ByVal strNewValue As String) p_Desc =strNewValue 'armazena o valor em propriedade p_DescEnd

    Tanto o Obter Procedimento e Deixe Os procedimentos são declarados como Públicos . Ambos os nomes de procedimento são os mesmos strDesc. Por padrão, o retornou o tipo de dados é Variante no Obter O procedimento e o tipo de dados Parameter também são inseridos como Variant no Let Procedimento. Podemos alterar para tipos específicos conforme necessário, o que fizemos e alteramos para String tipo. As três primeiras letras str em strDesc dá ao usuário uma dica de que a propriedade espera um valor de tipo de dados String. Altere o Deixe Procedimento de propriedade Parâmetro Nome da variável vNewValue para strNewValue

    Quando inserimos o Property Procedure eles sempre são inseridos com Get e Deixe Pares de procedimentos para uma variável.

    Agora, observe atentamente a expressão que escrevemos no Get Procedimento. O lado esquerdo do = Assine o nome do procedimento de obtenção strDesc atua como uma variável para retornar o valor copiado da variável privada p_Desc para o programa de chamada.

    O Deixe Procedimento strDesc aceita o valor String no parâmetro Variável strNewValue . O valor de entrada é transferido para nossa variável privada p_Desc.

    O ponto a ser observado aqui é que não há acesso direto à nossa variável privada p_Desc para o mundo exterior. Transporte de valores De/Para a variável (propriedade) p_Desc é sempre roteado pelo Get/Let Apenas procedimentos de propriedade e sujeitos a verificações de validação (ainda não implementado), vamos introduzir verificações de validação na entrada de valores (Let Procedure) na propriedade mais tarde.

    O Obter/Deixar Os procedimentos são executados automaticamente dependendo do que fazemos com a propriedade Object em uma expressão em Programas VBA.

    O Obter O procedimento é executado quando usamos o Nome da Propriedade em uma expressão da seguinte maneira:
    ‘ Lê o valor de p_Desc para PrintDebug.Print oArea.strDescOR‘ Lê o valor de p_Desc e o atribui à variável XX =oArea.strDesc

    O Deixe O Property Procedure é executado quando tentamos atribuir um valor ao Property Name. Verifique a expressão de exemplo em nosso Programa de Teste abaixo:
    oArea.strDesc =“Tapete”

    Em livros anteriores da linguagem BASIC você pode ver o uso da palavra-chave LET.
    LET X =25 ‘ LET é opcional

    Como era opcional, a instrução funciona sem ele e parou de usá-lo.

    Aqui, se você estiver apenas lendo algum valor de uma variável e não armazenando nada nela diretamente, você pode omitir o procedimento Let e ​​usar apenas o Get Procedimento.

    Esta regra também se aplica ao procedimento Let. Você pode usar apenas o Let Procedimento, se você estiver atribuindo algum valor em uma variável privada, mas não lendo nada de volta da mesma variável, omita o procedimento Get.

    O Obter e Deixe Os procedimentos serão executados um após o outro se nossa expressão for algo como o seguinte:
    oArea.strDesc =oArea.strDesc &“ – Tamanho King.”

    Na expressão acima, vamos Obter o valor existente da variável privada p_Desc e modifique a descrição e armazene-a de volta na mesma variável. Resumindo em uma expressão se você usar o nome da propriedade à direita do sinal de igual (= ) o Obter O procedimento é chamado e Let O procedimento é executado quando o nome do procedimento da propriedade do objeto aparece à esquerda do igual (= ) sinal.

    Insira dois conjuntos de procedimentos de propriedade para as variáveis ​​p_Length e p_Width. Quando você fornece os nomes do procedimento no Nome controle dê o nome dblLength e dblWidth para dar uma dica ao usuário de que essas propriedades esperam números de precisão dupla como entrada.

    Objeto de classe ClsArea com seus procedimentos de propriedade.


    O código completo até agora com os procedimentos de propriedade dblLength e dblWidth é fornecido abaixo para referência e para atualizar seu código.
    Opção Comparar DatabaseOption ExplicitPrivate p_Desc As StringPrivate p_Length As DoublePrivate p_Width As DoublePublic Property Get strDesc() As String strDesc =p_Desc 'copia o valor de p_DescEnd PropertyPublic Property Let strDesc(ByVal strNewValue As String) p_Desc =strNewValueEnd PropertyPublic Property Get dblLength( ) As Double dblLength =p_LengthEnd PropertyPublic Property Let dblLength(ByVal dblNewValue As Double) p_Length =dblNewValueEnd PropertyPublic Property Obtenha dblWidth() As Double dblWidth =p_WidthEnd PropertyPublic Property Let dblWidth(ByVal dblNewValue Double> 

    O Programa de Teste com Mudanças.


    Se você terminou de completar o código acima, deixe-nos fazer alterações em nosso programa de teste, para refletir as alterações que fizemos aqui. O código de amostra modificado é fornecido abaixo.
    Opção Comparar DatabaseOption ExplicitPublic Function ClassTest1() Dim oArea As ClsAreaSet oArea =Nova ClsArea'Property Deixe os procedimentos chamados hereoArea.strDesc ="Carpet"oArea.dblLength =25oArea.dblWidth =15Debug.Print "Description", "Length", "Width"'Property Get Procedures chamado aqui para printDebug.Print oArea.strDesc, oArea.dblLength, oArea.dblWidthSet oArea =Função NothingEnd

    Quando você insere um ponto (.) imediatamente após o nome do objeto oArea (oArea.), a lista de nomes de Procedimentos de Propriedade é exibida pelo VBA IntelliSense e você pode selecionar o desejado na lista sem digitá-lo manualmente.

    O objetivo deste Objeto de Classe é calcular a área de algo, como Área de Sala, Tapete, Piso, ou qualquer outro material, que tenha valores de Comprimento e Largura. Isso significa que precisamos de uma função pública para calcular a área de qualquer valor de comprimento, largura e descrição do item inserido no objeto de classe.

    Método de objeto ClsArea:Area()


    Aqui está o Código para a Função Pública:
    Public Function Area() As Double Area =Me.dblLength * Me.dblWidthEnd Function

    Você pode inserir esta Função a partir do Inserir Menu inserindo Área no Nome Controle, selecionando Função do Tipo grupo de opções e Público como Escopo no módulo de classe ClsArea. Complete a função inserindo a linha no meio.

    Podemos endereçar diretamente as variáveis ​​p_Length e p_Width (porque a função Area() faz parte do Módulo Classe) na expressão para cálculo da Área. Mas, estamos tomando a rota correta e chamamos os procedimentos Get dblLength e dblWidth para cálculo. Você deve ter notado a referência Eu. usado para qualificar os dblLength, dblWidth Get Procedures, como costumávamos escrever em Form/Report Class Modules, para se referir ao objeto atual na memória e suas propriedades. Como afirmei anteriormente, nosso objeto de classe personalizado pode ter várias instâncias de objeto abertas na memória ao mesmo tempo e o Me palavra-chave refere-se à instância atual à qual a Function Area() pertence.

    A função de teste com modificação.


    Modifique nossa função de teste ClassTest1() para incorporar a saída da função Area() conforme abaixo:
    Opção Comparar DatabaseOption ExplicitPublic Function ClassTest1() Dim oArea As ClsAreaSet oArea =New ClsAreaoArea.strDesc ="Carpet"oArea.dblLength =25oArea.dblWidth =15Debug.Print "Description", "Length", "Width", "Area "Debug.Print oArea.strDesc, oArea.dblLength, oArea.dblWidth, oArea.AreaSet oArea =função NothingEnd

    A alteração é apenas nas instruções Debug.Print. Execute o código e verifique o resultado na janela de depuração.

    Há dois procedimentos de evento necessários nos módulos de classe personalizada:Class_Initialize() e Class_Terminate() .

    Métodos de execução automática.


    A Class_Initialize() programa é executado automaticamente quando instanciamos um objeto com o Novo Palavra Chave. Este programa pode ser usado para definir valores padrão em variáveis ​​ou instanciar outros objetos na memória. Um objeto de classe pode usar outras classes como objeto(s) filho(s) e precisa ser instanciado. Este aspecto vamos explorar mais e aprender como fazê-lo mais tarde.

    O Class_Terminate() programa é executado quando tentamos limpar o objeto da memória quando o Nada palavra-chave é executada na instrução Set oArea =Nothing . Quando o programa que usa o objeto de classe termina, a instância do objeto na memória é removida por padrão. Mas é uma boa prática de programação que usamos Set oArea =Nothing como a última instrução executável em nossos programas para limpar o objeto da memória.

    Vamos adicionar os programas acima em nosso módulo de classe. Adicione o seguinte código no final do seu módulo de classe:
    Private Sub Class_Initialize() p_Length =0 p_Width =0 'MsgBox "Initialize.", vbInformation, "Class_Initialize()"End SubPrivate Sub Class_Terminate() 'MsgBox "Terminate.", vbInformation, "Class_Initialize()"End Sub 

    Se você quiser testar essas duas sub-rotinas, remova o símbolo Comment e ative a MsgBox. Execute seu programa de teste mais uma vez. Você encontrará o Inicializar mensagem aparece no início (Clique em OK para continuar) e o Terminar mensagem aparece no final do programa de teste.

    Eu sei o que você está pensando agora, como “tanto código para multiplicar duas variáveis”. É verdade nessa perspectiva, mas é muito provável que tenhamos escrito código para problemas semelhantes de solução de problemas repetidamente todas as vezes, duplicando código para verificações de validação e para outras proteções de erros lógicos.

    Aqui, não estamos escrevendo um Programa comum, mas desenvolvendo um Objeto Personalizado que pode ser usado muitas vezes ou pode fazer parte de outros Objetos, onde quer que precisemos sem nos preocupar com o funcionamento, do ponto de vista do usuário. O Microsoft Access possui muitos Objetos/Funções internos que usamos o tempo todo sem nos preocuparmos com o funcionamento, definindo suas Propriedades ou Parâmetros e fazendo o trabalho.

    Temos mais um problema para resolver, as verificações de validação nos valores inseridos no dblNewValue Parâmetro no Let Procedimentos de propriedade de dblLength() e dblWidth(), para garantir que valores válidos são atribuídos a Propriedades do objeto p_Length e p_Width .

    Valores negativos ou zero inseridos são considerados inválidos e temos que tomar precauções para que o valor correto seja inserido pelo usuário.

    Realizando verificações de validação.


    O Let modificado Os segmentos do Código de Procedimento de Propriedade são fornecidos abaixo. Faça alterações em seu código de acordo.
    Propriedade Pública Let dblLength(ByVal dblNewValue As Double) Faça Enquanto dblNewValue <=0 dblNewValue =InputBox("Negative/0 Values ​​Invalid:", "dblLength()", 0) Loop p_Length =dblNewValueEnd PropertyPublic Property Let dblWidth(ByVal dblNewValue As Double) Faça While dblNewValue <=0 dblNewValue =InputBox("Negative/0 Values ​​Invalid:", "dblwidth()", 0) Loop p_Width =dblNewValueEnd Property

    O Faça Enquanto. . . Ciclo é executado repetidamente até que um valor válido (maior que 0) seja inserido em dblNewValue pelo usuário

    Verificações de validação no método público:Area()


    Precisamos de mais uma verificação de validação na Area() Função. Se o usuário chamar a função Area() sem inserir valores válidos para Comprimento e Largura primeiro, o usuário deve ser informado sobre isso. Vamos verificar se as variáveis ​​p_Length e p_Width possuem valores válidos antes de executar a expressão para cálculo de área. Aqui está o Código:
    Public Function Area() As Double If (Me.dblLength> 0) And (Me.dblWidth> 0) Then Area =Me.dblLength * Me.dblWidth Else Area =0 MsgBox "Erro:Comprimento/Largura Valor(es) ) Inválido., Programa abortado." Fim da função IfEnd

    O Código Completo do Objeto ClsArea.


    O código totalmente preenchido do nosso módulo de classe ClsArea é fornecido abaixo:
    Opção Comparar DatabaseOption ExplicitPrivate p_Desc As StringPrivate p_Length As DoublePrivate p_Width As DoublePublic Property Get strDesc() As String strDesc =p_Desc 'copia o valor de p_DescEnd PropertyPublic Property Let strDesc(ByVal strNewValue As String) p_Desc =strNewValueEnd PropertyPublic Property Get dblLength( ) As Double dblLength =p_LengthEnd PropertyPublic Property Let dblLength(ByVal dblNewValue As Double) Faça While dblNewValue <=0 dblNewValue =InputBox("Negative/0 Values ​​Invalid:", "dblLength()", 0) Loop p_Length =dblNewValueEnd PropertyPublic Property Get dblWidth() As Double dblWidth =p_WidthEnd PropertyPublic Property Deixe dblWidth(ByVal dblNewValue As Double) Faça enquanto dblNewValue <=0 dblNewValue =InputBox("Negative/0 Values ​​Invalid:", "dblwidth()", 0) Loop p_Width =dblNewValueEnd PropertyPublic Função Area() como Double If (Me.dblLength> 0) E (Me.dblWidth> 0) Then Area =Me.dblLength * Me.dblWidth Else Area =0 MsgBox "Erro:Valor(es) de Comprimento/Largura inválidos., Programa abortado." End IfEnd FunctionPrivate Sub Class_Initialize() p_Length =0 p_Width =0 'MsgBox "Initialize.", vbInformation, "Class_Initialize()"End SubPrivate Sub Class_Terminate() 'MsgBox "Terminate.", vbInformation, "Class_Terminate()"End Sub 

    Procedimentos e métodos de propriedade de teste.


    Você pode testar nosso objeto de classe personalizado inserindo valores negativos ou 0 como entrada para dblLength, dblWidth Properties.

    No Programa de Teste Comente as linhas (oArea.dblLength=25 e oArea.dblWidth=15) para testar a função Area(). Ele deve exibir a mensagem de erro que escrevemos dentro da função.

    Nosso módulo de classe de cálculo de área agora é considerado completo e testamos e descobrimos que está funcionando corretamente. Você pode testá-lo ainda mais para quaisquer erros lógicos que eu tenha esquecido. Se você se deparar com algo que eu não previ, por favor, compartilhe comigo.

    Plano futuro para testes.


    Testamos o objeto de classe para apenas um item. Precisamos calcular a área de vários itens (digamos a área de 5 quartos ou 10 Tapetes de tamanhos diferentes e assim por diante. Dizem-nos que uma vez desenvolvido um objeto podemos instanciá-lo várias vezes na memória atribuindo um conjunto diferente de valores em cada instância do Object e pode trabalhar com eles.

    Além disso, este objeto pode ser usado como parte de outros objetos que desenvolvemos com menos código, pois parte do nosso novo objeto de classe já está desenvolvido no módulo de classe ClsArea.

    Na próxima semana vamos aprender a criar um Array de Objetos Personalizados para calcular a área de vários itens.
    1. Módulo de classe MS-Access e VBA
    2. Matrizes de objetos de classe VBA do MS-Access
    3. Classe base do MS-Access e objetos derivados
    4. Classe básica do VBA e objetos derivados-2
    5. Classe base e variantes de objetos derivados
    6. Ms-Access Recordset and Class Module
    7. Módulo de classe de acesso e classes wrapper
    8. Transformação da funcionalidade da classe wrapper
    9. Noções básicas de Ms-Access e objetos de coleção
    10. Módulo de classe Ms-Access e objeto de coleção
    11. Registros de tabela no objeto e formulário de coleção
    12. Noções básicas de objetos do dicionário
    13. Noções básicas de objetos do dicionário-2
    14. Classificação de chaves e itens de objetos de dicionário
    15. Exibir registros do dicionário para o formulário
    16. Adicionar objetos de classe como itens de dicionário
    17. Atualizar item do dicionário de objetos de classe no formulário