Aplica-se a
Access para Microsoft 365 Access 2021 Access 2019

O conteúdo aqui pode se aplicar a Northwind 2.0 Developer Edition e Starter Edition. 

VBA (Visual Basic for Applications) é a linguagem de programação usada em todos os Produtos do Office. O VBA de aprendizagem permite que você trabalhe com todos os produtos do Office (não apenas o Access).Ao pesquisar por "como fazer", procure exemplos específicos do Access e inclua o Microsoft Access na pesquisa. Muitas vezes, as soluções para os outros produtos do Office funcionarão - mas não há garantia. O Microsoft Access é um produto maduro; isso significa que há muitos exemplos por aí; o que é ótimo para você! 

Isso também significa que os livros mais antigos sobre programação do Access ainda são viáveis para você examinar. Muitos dos livros mais antigos ainda estão disponíveis em sites de livros usados a uma fração de seu custo original. Verifique o site da Microsoft para determinar quais versões do Access ainda estão sendo compatíveis e siga com elas.

Fim dos recursos de suporte para o Office – Implantar o Office | Microsoft Learn  

Veja abaixo alguns links para a documentação do Access na Microsoft.

Os arquivos do Microsoft Access são arquivos do Office. Os arquivos do Office devem estar em um "Local Confiável" ou ter seu "conteúdo habilitado". Esses itens são considerados "seguros" porque você os criou ou eles vieram de uma fonte confiável. Verifique se locais confiáveis ocorrem sempre que você abre qualquer arquivo do office. Vamos nos referir a isso como Confiável/Habilitado daqui em diante. OBSERVAÇÃO: se uma nova versão do aplicativo for lançada e aberta de um local não confiável, o processo de habilitação do conteúdo será repetido.

Saiba mais sobre Locais Confiáveis.: 

Macros, Funções e Subs são como você implementa a lógica de negócios no banco de dados access. É importante que você entenda Escopo e Visibilidade antes do início.

Eventos (como clicar em um controle) em Controles em um formulário (por exemplo, botões, caixas de texto, rótulos etc.) disparam outros processos, como adicionar, excluir registros ou abrir formulários. Esses processos podem ser implementados usando macros ou VBA. Northwind Starter Edition usa principalmente macros e alguns VBA em que as macros não são capazes de executar as funções necessárias. O Northwind Developer Edition usa principalmente o VBA. 

Alguns tipos de controle têm assistentes internos para criar automaticamente uma macro. Por exemplo, adicionar um botão de comando a um formulário abre um assistente que oferece várias opções de funcionalidade para o botão. Adicionar uma caixa de combinação abre um assistente que pode ser configurado para encontrar um registro específico no formulário. 

O Painel de Navegação é a maneira main de exibir e acessar todos os objetos de banco de dados e ele é exibido no lado esquerdo da janela de acesso por padrão. O Painel de Navegação northwind foi personalizado. Criamos uma categoria personalizada chamada Northwind Starter 2.0. Isso nos permite organizar os objetos por área funcional.

Às vezes, você precisa de uma variável para existir após o objeto que o criou sair do escopo. Consulte Escopo e Visibilidade acima. Há três maneiras primárias de fazer isso: Variáveis Públicas, TempVars e Armazenar os valores em uma tabela local. Muitos desenvolvedores usam uma combinação desses. Cada um tem seus prós e contras.  Mais sobre cada um aqui: 

Variável pública do módulo VBA: 

TempVars: 

Armazenando os valores na tabela local

  • Variáveis públicas e TempVars existem para a sessão atual e saem do escopo quando o aplicativo é fechado. Mas e se você quiser manter variáveis específicas do usuário entre sessões? Você pode armazenar esses tipos de valores em uma tabela local. No Northwind 2.0, uma dessas variáveis é salva em uma tabela chamada SystemSettings. O valor na tabela é ShowWelcome. Esse valor informa ao Access se você quiser ver a tela De boas-vindas sempre que fizer logon ou não.

Os desenvolvedores geralmente precisam passar parâmetros de um formulário para outro ou de um formulário para um relatório. Esses parâmetros transmitem informações importantes, que a chamada função usará para se configurar. Há várias maneiras de o segundo formulário ou relatório obter informações do primeiro formulário. Aqui estão algumas dessas maneiras: 

  1. O segundo formulário pode "olhar para trás" para o primeiro formulário para pegar alguns valores, possivelmente no controle visível ou invisível.  Por exemplo: lngCustomerID = Forms!FirstForm!cboCustomerID 

  2. O primeiro formulário pode salvar valores em variáveis globais ou em TempVars. Por exemplo: g_lngUserID = Me.cboUserID  TempVars.Add "UserID", Me.cboUserID 

O método que geralmente é usado no Northwind Developer Edition, bem como em nossas vidas profissionais, está usando o argumento OpenArgs de DoCmd.OpenForm ou OpenReport. Por exemplo: DoCmd.OpenForm "frmCompanyDetail", OpenArgs:=StringFormat("CompanyID={0} &CompanyTypeID={1}", Me.VendorID, ctVendor)

Estamos combinando duas técnicas aqui: (1) o uso de OpenArgs para passar o VendorID e o VendorType e (2) o uso da função StringFormat() para criar, por exemplo, esta cadeia de caracteres: 

CompanyID=5&CompanyTypeID=2 

Essa cadeia de caracteres se parece muito com uma cadeia de caracteres de consulta, como é usada em um navegador. Ele contém um ou mais "pares de nome/valor" separados pelo caractere ampersand: 

name1=value1&name2=value2

A vantagem de tal cadeia de caracteres é que cada valor tem um nome. Compare isso com uma abordagem mais simples em que você definiria OpenArgs apenas como "5,2".  Nesse caso, seria necessário esforço para descobrir o que cada valor significa. Nomear cada valor torna a cadeia de caracteres de consulta "autodescrevendo" que é uma boa prática de programação.

No final de recebimento do DoCmd.OpenForm , normalmente estamos no evento Form_Open ou Form_Load e queremos analisar a cadeia de caracteres OpenArgs em seus componentes.

No Northwind, você pode fazer isso com a função StringToDictionary . Ele usa uma função semelhante a querystring e a analisa em seus componentes. Esses componentes são armazenados em um objeto Scripting.Dictionary . Observe que isso exige que você use Ferramentas > Referências e defina uma referência ao Microsoft Scripting Runtime (scrrun.dll).

Os recursos e os benefícios do objeto Dictionary incluem estes:  

  • A ordem dos elementos não é importante

  • Funções simples para adicionar e remover elementos da coleção

  • Funções para repetir o ciclo sobre a coleção, para que possa saber o que está nela

  • Uma função Existe para que possa testar se um determinado elemento está disponível

A utilização do objeto de dicionário é apresentada em Northwind. Por exemplo, o evento Form_Load em frmGenericDialog.

As macros criadas com Assistentes de Controlo no Access raramente incluem processamento de erros; O VBA criado com Assistentes de Controlo pode estar limitado a um MsgBox Err.Description genérico.

Em Northwind 2.0, mostramos-lhe como fazê-lo melhor ao utilizar código VBA. Implementámos o que é chamado de Processador de Erros Global. Os erros que ocorrem em qualquer procedimento chamam uma função ao nível global para mostrar o erro. A grande vantagem aqui é que o processamento de erros é consistente. E se a mensagem precisar de ser alterada (por exemplo, para mostrar o número de erro ou para registar o erro num ficheiro), esta tem de ser feita apenas num único local. 

clsErrorHandler é o Módulo de Classe que implementa o código de processamento de erros. Um módulo de classe mantém todas as suas funções de main e auxiliar juntas numa unidade, encapsulando assim o código.

A macro AutoExec chama a função Arranque no modStartup. No Starter Edition, a função cria uma instância de clsErrorHandler e guarda-a como uma variável global que está disponível para utilização em toda a aplicação. Na edição Dev, é utilizada uma classe estática – veja os comentários na parte superior do módulo de classe.

Na verdade, o código de processamento de erros nos procedimentos é tão consistente que conseguimos criar tudo em menos de cinco minutos com código VBA específico que equipava cada procedimento com o processador de erros adequado. (Código não incluído no modelo). As edições de modelos Northwind 2.0 Starter e Developer foram inicialmente equipadas com esta abordagem de processamento de erros.  '

PROCESSAMENTO DE ERROS MELHORADO

A partir da versão 2.2 da Northwind Developer Edition, o processador de erros foi melhorado, graças ao feedback da comunidade do Access. A edição Starter não mudou. 

Essencialmente, o processador de erros na versão anterior (2.0 – lançada em abril de 2023) é:

Public Sub HandleError(…)     MsgBox Err.DescriptionEnd Sub

Na versão 2.2, é atualizado para:

Public Sub HandleError (…, Optional ByVal IsEventProcedure As Boolean = False)     If Not IsEventProcedure Then         Err.Raise lngError, strErrSource     End If     MsgBox Err.DescriptionEnd Sub

Para compreender por que motivo esta alteração foi efetuada, vamos começar por compreender o que faz com que o código seja executado:

  • A macro AutoExec chama o procedimento de Arranque, que efetua algumas inicializações antes de abrir o primeiro formulário.

  • O utilizador interage com a aplicação, como abrir um formulário ou clicar num botão, fazendo com que os procedimentos de eventos acionem, como Form_Load e cmdPrintInvoice_Click. '

Além dos procedimentos de eventos, as aplicações têm subroutinas e funções, principalmente em módulos, e esse código é chamado a partir dos procedimentos de evento. Estes procedimentos são denominados procedimentos "padrão".

Na versão 2.0 da Northwind, os procedimentos padrão processariam os seus próprios erros com mensagens, mas de alguma forma não notificariam o procedimento de evento de chamada de que tinha ocorrido um erro. Isto pode ser mau se o procedimento do evento tiver código subsequente que deve ser executado independentemente do erro anterior processado pelo procedimento chamado. Claro que podemos substituir a subrreplicação por uma função que devolve êxito ou falha e codificar o procedimento do evento em conformidade, mas isso nem sempre é uma opção.

Na versão 2.2 da Northwind, os procedimentos padrão não processam mensagens de erro, mas sim, através de Err.Raise, reportam-nas ao procedimento de evento de chamada. Em seguida, o procedimento de evento de chamada apresenta o erro gerado e retoma a Exit_Handler. Isto é melhor, porque permite que o procedimento de chamada conclua graciosamente.

Para utilizar o código northwind versão 2.2, os procedimentos de evento têm de passar para HandleError um terceiro argumento que indica que o chamador é um procedimento de evento. A Northwind Dev Edition foi atualizada para o fazer.

Um módulo de processador de erros ainda mais poderoso teria suporte para procedimentos de "emitir e estalar" numa "pilha" (matriz). O primeiro elemento seria sempre o procedimento do evento, pelo que o argumento adicional não é necessário. Esta implementação está para além dos objetivos da Northwind Dev Edition.

MRU ou Utilizado Mais Recentemente é uma lista das Encomendas e Encomendas de Compras utilizadas recentemente. Poderá querer voltar a estes frequentemente para colocá-los no Estado seguinte. As listas de MRU são frequentemente vistas nos produtos do Office como uma lista dos ficheiros utilizados recentemente que poderá querer reabrir.

na edição Northwind Dev, para implementar a funcionalidade MRU (que não existe na edição Starter), primeiro tem de estabelecer os seguintes itens: 

  1. Uma tabela para armazenar informações de MRU.

  2. Código para atualizar a tabela quando uma encomenda ou nota de encomenda (PO) é aberta.

  3. Código para atualizar o menu pendente MRU no friso.

  4. Código para carregar o item quando um item mru é selecionado no friso.

Vamos analisar cada um destes detalhes mais detalhadamente. 

1. Tabela para armazenar informações de MRU.

Vale a pena rever a estrutura da tabela MRU, especialmente os respetivos índices. Tenha em atenção que existe um SortIdx de índice duplicado para ajudar na ordenação rápida dos itens mru na lista pendente do friso, bem como um índice exclusivo para impor a regra de negócio que, para cada utilizador, um item só pode ocorrer uma vez. Por exemplo, abrir a mesma encomenda duas vezes não cria dois registos na tabela MRU.

A tabela tira partido do facto de todos os campos PK (chave primária) relacionados com MRU na base de dados serem Numeração Automática, pelo que o tipo de dados Número Inteiro Longo pode ser utilizado para PKValue.

2. Código para atualizar a tabela quando uma encomenda ou P.O. é aberta.

No NW2, optámos por adicionar à lista de MRU apenas quando foi criado um novo registo, não quando um existente foi atualizado novamente. Podemos certamente mover a chamada AddToMRU de Form_AfterInsert para Form_AfterUpdate para o suportar.

Os procedimentos AddToMRU e DeleteFromMRU são implementados no modGlobal, que é um Módulo Standard cujos procedimentos públicos são visíveis a partir de qualquer formulário.

AddToMRU (como o nome sugere) adiciona o novo item à tabela MRU e, opcionalmente, corta-o novamente, eliminando o registo mais antigo, se tiver crescido para além do tamanho máximo (MAX_MRU_COUNT). O último passo é provavelmente o menos conhecido para os programadores do Access: o menu pendente do friso tem de ser atualizado e isso é conseguido ao chamar InvalidateControl. Este é um sinal para o friso para executar novamente o processo de inicialização. 

3. Código para atualizar o menu pendente MRU no friso. 

No momento do arranque e depois de InvalidateControl ser chamado, é executado um conjunto complexo de funções para preencher o friso.  Estes procedimentos são chamados pelo XML do Friso na tabela uSysRibbons , que diz em parte:

<group id="gCurrentStatus" label="MRU">
    <box id="bxMRU" boxStyle="vertical">
        <dropDown id="ddMRU"
                  getItemCount="ddMRU_GetItemCount"
                  getItemLabel="ddMRU_GetItemLabel"
                  getSelectedItemIndex="ddMRU_GetSelectedItemIndex"
                  getItemID="ddMRU_GetItemID"
                  onAction="ddMRU_OnAction"
                  screentip="Most Recently Used Objects">
        </dropDown>
    </box>
</group>

Estas quatro funções de chamada de retorno povoam o menu pendente. Tenha em atenção que esta é a mesma ideia descrita aqui para caixas de combinação padrão.

Se anular o comentário das linhas Debug.Print no modRibbonCallback e reiniciar a aplicação, a Janela Imediata apresentará uma sequência como esta: 

ddMRU_GetItemCount    ddMRU    6 
ddMRU_GetItemLabel    ddMRU    0      Order 60, Proseware, Inc.
ddMRU_GetItemID       ddMRU    0       2 
ddMRU_GetItemLabel    ddMRU    1      Order 62, Best For You Organics Company
ddMRU_GetItemID       ddMRU    1       4 
ddMRU_GetItemLabel    ddMRU    2      Order 63, Wide World Importers
ddMRU_GetItemID       ddMRU    2       5 
ddMRU_GetItemLabel    ddMRU    3      Order 66, Proseware, Inc.
ddMRU_GetItemID       ddMRU    3       8 
ddMRU_GetItemLabel    ddMRU    4      Order 67, Best For You Organics Company
ddMRU_GetItemID       ddMRU    4       9 
ddMRU_GetItemLabel    ddMRU    5      Order 68, Adatum Corporation
ddMRU_GetItemID       ddMRU    5       10 
ddMRU_GetSelectedItemIndex  ddMRU    0

Podemos ver aqui que o Access está a chamar primeiro um procedimento que devolve o número de itens a carregar no argumento ByRef de ddMRU_GetItemCount. Esta é também a altura em que abrimos a consulta na tabela MRU e a colocamos em cache porque está prestes a ser utilizada várias vezes. 

Em seguida, o friso chama repetidamente dois procedimentos para obter os valores de ID e Etiqueta para o menu pendente de duas colunas. 

Por fim, chama um procedimento para desativar o item que deve ser selecionado. (No nosso caso, é o primeiro.) 

4. Código para carregar um item quando o item MRU está selecionado no friso.

Tal como acontece com qualquer outro item do friso, a propriedade OnAction no XML do Friso especifica uma função de chamada de retorno a ser utilizada para executar a ação:

onAction="ddMRU_OnAction"

Este procedimento é implementado no modRibbonCallback. Utiliza novamente o conjunto de registos já aberto para localizar o registo com o item selecionado e, em seguida, dependendo do TableName necessário, abre o formulário correspondente, transmitindo o valor PK a carregar.

Precisa de mais ajuda?

Quer mais opções

Explore os benefícios da assinatura, procure cursos de treinamento, saiba como proteger seu dispositivo e muito mais.