Você está na página 1de 151

Microsoft© Access Avançado

Microsoft© Access Avançado

INDICE

1. INTRODUÇÃO ....................................................................................................................6
1.1. ARQUITETURA DE UMA APLICAÇÃO MS ACCESS...............................................7
EXERCÍCIOS DE FIXAÇÃO – INTRODUÇÃO ............ERRO! INDICADOR NÃO DEFINIDO.
2. PROGRAMAÇÃO NO MS ACCESS ................................................................................9
2.1. MACRO X MÓDULO ..........................................................................................................9
2.2. MÓDULOS .......................................................................................................................11
2.3. QUANDO USAR PROGRAMAÇÃO ......................................................................................12
2.4. MÓDULO PADRÃO ...........................................................................................................13
2.5. MÓDULO DE CLASSE EM FORMULÁRIOS E RELATÓRIOS ...................................................13
2.6. MÓDULO DE CLASSE .......................................................................................................14
2.7. SEÇÃO DE DECLARAÇÕES ................................................................................................15
2.8. SEÇÃO DE PROCEDIMENTOS ............................................................................................15
2.9. O EDITOR DE CÓDIGO ......................................................................................................16
2.9.1. Cores de código ......................................................................................................17
2.9.2. Opções de codificação............................................................................................17
2.9.3. Configurações da janela.........................................................................................18
2.10. JANELAS DO EDITOR DE CÓDIGO DO ACCESS .................................................................18
2.10.1. Janela de Código ..................................................................................................19
2.10.2. Janela Depurar.....................................................................................................19
2.10.3. Janela Pesquisador de Objetos ............................................................................21
PRÁTICA 2 – PROGRAMAÇÃO NO MS ACCESS ..........................................................23
EXERCÍCIO 1 – Criando um módulo padrão..................................................................23
EXERCÍCIO 2 – Criando um módulo de classe em formulário.......................................23
EXERCÍCIOS DE FIXAÇÃO – PROGRAMAÇÃO NO MS ACCESS .. ERRO! INDICADOR
NÃO DEFINIDO.

3. PROCEDIMENTOS EM MÓDULO PADRÃO .............................................................24


3.1. COMPILAÇÃO DE MÓDULO ..............................................................................................26
3.2. TESTE DE EXECUÇÃO DE PROCEDIMENTO EM MÓDULO PADRÃO ......................................27
3.3. EXECUÇÃO PASSO-A-PASSO ............................................................................................27
3.4. INSPEÇÃO DE VARIÁVEIS .................................................................................................28
3.5. PONTO DE INTERRUPÇÃO ................................................................................................29
3.6. CHAMADA DE PROCEDIMENTOS ......................................................................................30
3.6.1. Passagem de Argumentos.......................................................................................31
3.6.2. Retorno de Valor ....................................................................................................31
3.6.3. Passagem de Argumentos por Valor e por Referência...........................................33
PRÁTICA 3 – CRIAÇÃO DE MÓDULO PADRÃO .......ERRO! INDICADOR NÃO DEFINIDO.
EXERCÍCIO 1 – Criando um procedimento para cálculo de fatorialErro! Indicador não
definido.
EXERCÍCIOS DE FIXAÇÃO – CRIAÇÃO DE MÓDULO PADRÃO.... ERRO! INDICADOR
NÃO DEFINIDO.

4. MÓDULO DE CLASSE EM FORMULÁRIO/RELATÓRIO ......................................35

Reprodução proibida
Microsoft© Access Avançado

INDICE

4.1. COLEÇÕES E OBJETOS DE FORMULÁRIO/RELATÓRIO ......................................................36


4.2. PROPRIEDADES E MÉTODOS ............................................................................................38
4.3. COLEÇÃO PADRÃO E PROPRIEDADE PADRÃO ...................................................................39
4.4. PROPRIEDADES DE COLEÇÃO ..........................................................................................39
4.5. SEÇÕES DE FORMULÁRIO/RELATÓRIO ............................................................................40
4.6. EVENTOS DE FORMULÁRIO .............................................................................................40
EXERCÍCIOS DE FIXAÇÃO – MÓDULO DE CLASSE EM
FORMULÁRIO/RELATÓRIO ........................................ERRO! INDICADOR NÃO DEFINIDO.
5. ELEMENTOS DE PROGRAMAÇÃO ............................................................................42
5.1. VARIÁVEIS..................................................................................................................42
5.1.1. Declaração .............................................................................................................42
5.1.2. Atribuição de valores à variáveis ...........................................................................44
5.2. CONSTANTES .............................................................................................................45
5.2.1. Constantes Simbólicas............................................................................................45
5.2.2. Constantes Intrínsecas............................................................................................45
5.2.3. Constantes Definidas pelo Sistema.........................................................................46
5.3. VETORES E MATRIZES .............................................................................................47
5.4. TIPOS DEFINIDOS PELO USUÁRIO .........................................................................48
5.5. ESTRUTURA DE REPETIÇÃO ...................................................................................48
5.5.1. For..Next.................................................................................................................48
5.5.2. Do..Loop .................................................................................................................49
5.5.3. While..Wend............................................................................................................50
5.5.4. For Each..Next........................................................................................................50
5.6. ESTRUTURA CONDICIONAL ...................................................................................51
5.6.1. If...Then...Else.........................................................................................................51
5.6.2. Select Case..............................................................................................................52
5.7. ENTRADA E SAÍDA DE DADOS ...............................................................................53
5.7.1. Funções do VBA para entrada e saída...................................................................54
5.7.2. Outros dispositivos de entrada e saída...................................................................55
5.8. COMENTÁRIOS...........................................................................................................56
5.9. FUNÇÕES .....................................................................................................................56
5.10. ESCOPO DE IDENTIFICADORES............................................................................57
5.11. OBJETO DOCMD .........................................................................................................58
6. LINGUAGEM SQL............................................................................................................59
6.1. EXPRESSÃO SQL ........................................................................................................60
6.2. INSTRUÇÕES BÁSICAS SQL.....................................................................................61
6.2.1. CONSULTA SELEÇÃO ...................................................................................................61
6.2.1.1. Argumento Predicado..........................................................................................63
6.2.1.2. Expressões na lista de campos ............................................................................65
6.2.1.3. Argumento Expressãodetabela ............................................................................66
6.2.1.4. Tabelas em banco de dados externos ..................................................................68
6.2.1.5. Cláusula Where ...................................................................................................68

Reprodução proibida
Microsoft© Access Avançado

INDICE

7. FORMULÁRIOS AVANÇADOS .....................................................................................74


7.1. FORMULÁRIO DE MANUTENÇÃO DE TABELAS.................................................74
7.1.1. Botões de Navegação Personalizados....................................................................74
7.2. CAIXA DE DIÁLOGO..................................................................................................76
7.2.1. Passagem De Parâmetros Para Procedimento ......................................................77
7.2.2. Passagem De Parâmetros Para Consulta Parametrizada .....................................77
7.2.3. Passagem De Parâmetros Para Relatório .............................................................78
7.2.4. Passagem De Parâmetros Para Formulário..........................................................81
7.3. FORMULÁRIO DE CONSULTA.................................................................................83
7.4. CAIXA DE MENSAGEM .............................................................................................87
8. ACESSO A BANCO DE DADOS .....................................................................................89
8.1. HIERARQUIA DO OBJETOS DAO .....................................................................................89
8.2. SINTAXE PARA REFERENCIAR OBJETOS EM COLEÇÃO ....................................................90
8.3. COLEÇÃO PADRÃO..........................................................................................................91
8.4. REFERÊNCIA A OBJETOS POR MEIO DE VARIÁVEIS ..........................................................91
8.5. PROPRIEDADES E MÉTODOS ............................................................................................91
8.6. ACESSO A BANCO DE DADOS ACCESS ............................................................................93
8.7. ACESSO A BANCOS DE DADOS EXTERNOS ......................................................................96
8.7.1. Vinculação de Tabelas Externas ............................................................................96
8.7.2. Abertura Direta de Tabelas Externas...................................................................100
9. ACESSO A ARQUIVOS E IMPRESSORA ..................................................................103

10. TRATAMENTO DE ERRO ..........................................................................................105


10.1. DESVIO PARA ROTINA DE TRATAMENTO DE ERRO .......................................................106
10.1.1. Tratar o erro e terminar o programa .................................................................106
10.1.2. Tratar o erro e voltar à execução na mesma linha do erro ...............................106
10.1.3. Tratar o erro e voltar à execução na linha seguinte à linha de erro .................107
10.1.4. Tratar o erro e desviar a execução para outro rótulo. ......................................107
10.1.5. Prosseguir o programa após erro ......................................................................108
10.1.6. Evento Erro.........................................................................................................108
10.2. DEPURAÇÃO DO PROGRAMA .......................................................................................109
11. AUTOMAÇÃO ...............................................................................................................111
11.1. AUTOMAÇÃO COM O MICROSOFT WORD ...................................................................112
Hierarquia dos Objetos do Microsoft Word ..................................................................113
11.2. AUTOMAÇÃO COM O MICROSOFT EXCEL ..................................................................113
Hierarquia do Objetos do Microsoft Excel ...................................................................113
Detalhamento do Objeto Worksheets .............................................................................114
Detalhamento do Objeto Charts.....................................................................................115
Detalhamento do Objeto Chartgroups ...........................................................................115
11.3. AUTOMAÇÃO COM MICROSOFT PROJECT ...................................................................121
Hierarquia dos Objetos do Microsoft Project ...............................................................121

Reprodução proibida
Microsoft© Access Avançado

INDICE

11.4. AUTOMAÇÃO COM SCHEDULE+ .................................................................................122


Hierarquia dos Objetos do Schedule..............................................................................123
11.5. REFERÊNCIA À BIBLIOTECA DE OBJETOS ......................................................123
12. CHAMADA À API DO WINDOWS 95 .......................................................................126

13. SEGURANÇA.................................................................................................................132
13.1. SENHA DE BANCO DE DADOS ............................................................................132
13.1.1. DEFININDO UMA SENHA PARA O BANCO DE DADOS .............................132
13.1.2. ABRINDO UM BANCO DE DADOS PROTEGIDO POR SENHA....................133
13.1.3. REMOVENDO SENHA DE BANCO DE DADOS .............................................133
13.1.4. DEFININDO SENHA POR CÓDIGO VBA........................................................133
13.1.5. ABRINDO UM BANCO DE DADOS PROTEGIDO VIA CÓDIGO VBA..........134
13.1.6. ALTERANDO A SENHA VIA CÓDIGO VBA.....................................................134
13.2. CRIAÇÃO DE ARQUIVO MDE ..............................................................................135
13.3. CRIPTOGRAFIA DE BANCO DE DADOS.............................................................137
13.3.1. CRIANDO UM ARQUIVO CRITPTOGRAFADO..............................................138
13.3.2. REVERTENDO A CRITPTOGRAFIA ................................................................138
13.3.2. CRIPTOGRAFIA POR CÓDIGO VBA...............................................................138
13.4. SEGURANÇA EM NÍVEL DE USUÁRIO...............................................................138
13.4.1. PROPRIEDADE SOBRE O BANCO DE DADOS E OBJETOS ........................139
13.4.2. IMPLEMENTANDO SEGURANÇA EM NÍVEL DE USUÁRIO........................139
13.4.2. LOGON POR CÓDIGO VBA .............................................................................144
13.4.3. TROCA DE SENHA VIA CÓDIGO VBA............................................................144
13.4.4. RETIRAR PEMISSÃO DE CRIAR NOVOS BANCOS DE DADOS ...................146
13.4.5. RETIRAR PEMISSÃO DE CRIAR NOVAS TABELAS E CONSULTAS.............146
ANEXO A - CONVENÇÃO DE NOMES PARA DESENVOLVIMENTO DE
APLICAÇÕES COM PRODUTOS MICROSOFT ..........................................................147
MICROSOFT ACCESS .....................................................................................................148
Hierarquia dos objetos do Access ..................................................................................148
Tags para objetos da janela de banco de dados do ACCESS ........................................148
Tags para objetos controles do ACCESS .......................................................................148
Tags para variáveis do ACCESS ....................................................................................149
DATA ACCESS OBJECTS - DAO....................................................................................149
Hierarquia dos objetos DAO para Microsoft Jet Workspaces.......................................149
Hierarquia dos objetos DAO para ODBCDirect Workspaces .......................................150
Tags para Data Access Objects - DAO ..........................................................................150
MICROSOFT VISUAL BASIC 5.0 ...................................................................................151
Tags para controles do Visual Basic..............................................................................151
MICROSOFT VISUAL BASIC FOR APPLICATION - VBA ..........................................151
Tags para variáveis do Visual Basic for Application.....................................................151

Reprodução proibida
Microsoft© Access Avançado

1. INTRODUÇÃO
No MS Access, você armazena dados em tabelas e recupera informações por meio de
consultas, de forma interativa diretamente na janela de Banco de Dados. Esta forma de
trabalhar exige do usuário final um alto nível de conhecimento do MS Access.
Em vez de acessar diretamente as tabelas e consultas, você pode construir uma
interface com formulários e relatórios. No curso básico, você usa inicialmente os Assistentes
e depois pode construir os formulários e relatórios manualmente no modo Estrutura. Esta
forma de criar aplicativos atende a problemas simples de cadastramento e recuperação de
dados e exige que o usuário final tenha apena um conhecimento superficial do MS Access.
Com o tempo, você sente necessidade de o aplicativo dar maior controle no tratamento
dos dados e que a interface seja mais segura e simples de usar, não exigindo que o usuário
final tenha de saber o MS Access para operar o aplicativo. Torna-se necessário então
desenvolver aplicações usando programação dentro do MS Access.
Este curso ensinará a programação do MS Access , utilizando a linguagem Visual
Basic for Application – VBA, para que você desenvolva aplicativos completos no MS Access.
A Microsoft dispõe de três edições da linguagem Visual Basic:
 Visual Basic - VB
 Visual Basic for Application – VBA
 Visual Basic Scripting – VBScript

A primeira é a linguagem completa, feita para desenvolver aplicativos profissionais.


Ela gera um programa executável que pode ser instalado em qualquer PC com Windows, sem
a necessidade de o Visual Basic estar instalado. Alguns dos recursos que só existem no VB é
a possibilidade de desenvolver aplicativos cliente/servidor que acessa bancos de dados
relacionais, como o Microsoft SQL Server ou Oracle, e a criação de componentes ActiveX,
atualmente chamados de componentes COM (Component Object Model). A linguagem
Visual Basic é suportada no software Microsoft Visual Basic.
O VBA possui alguns recursos a menos que o VB, mas a sintaxe é idêntica. O VBA é
uma linguagem embutida nos aplicativos Microsoft Office (exceto o Outlook) e no Microsoft
Project 98. Não é possível gerar um programa executável. Ela é uma linguagem interpretada
que depende do Microsoft Office instalado ou o Microsoft Project 98.
A linguagem Visual Basic é o recurso que integra as melhores características de cada
aplicativo do MS Office. Por meio de programação, VB, VBA ou VBScript, é possível
construir uma interface única em um único aplicativo, como por exemplo o Access, e acessar
todos os recursos especializados dos demais integrantes do pacote Office ou mesmo do Back
Office. Esta técnica é conhecida como Automação, que veremos neste curso.
O VBScript é a versão mais simples do Visual Basic usado principalmente na
confecção de páginas WEB. Ele é suportado nos seguintes produtos:
 MS Outlook
 MS SQL Server
 Windows Scripting Host
 MS Internet Explorer 3 ou superior

6
Microsoft© Access Avançado
Vários softwares não Microsoft também suportam o VBScript para automatizar tarefas.

1.1. ARQUITETURA DE UMA APLICAÇÃO MS ACCESS


Um banco de dados MS Access é um conjunto de componentes do tipo Tabela,
Consulta, Formulário, Relatório, Macro e Módulo. A tendência natural ao se desenvolver uma
aplicação no MS Access é criar todos os componentes em um só banco de dados, ou seja, ter
um único arquivo .MDB.
O fato de ter tudo em um é conveniente, pois você instala apenas um arquivo no
computador e pode transportá-lo facilmente para qualquer outro computador, sem se
preocupar em que disco ou pasta ele será gravado.
Aplicações profissionais, entretanto, não possuem esta arquitetura tudo-em-um. Um
sistema de informação é composto por dois pilares básicos: os dados e os processos.
Mesmo na era do CA-Clipper havia distintamente dois tipos de arquivos: o executável
(.EXE) representanto os processos e os arquivos de dados de extensão .DBF. Neste caso,
ambos fazem parte de um mesmo software e atendem a um mesmo padrão, o xBase.
Com a evolução da informática, processos e dados tiveram softwares e padrões
distintos. Você pode escrever seus processos (programar) em um software e armazenar os
dados em outro formato, gerenciado por outro software. Um exemplo disto é o MS Visual
Basic e o MS SQL Server. O programa é escrito e compilado no MS Visual Basic enquanto os
dados podem ficar armazenados no e ser gerenciados pelo MS SQL Server. Atualmente, você
pode ter vários fornecedores diferentes para criar processos e armazenar dados. Você pode
escrever programas no MS Visual Basic ou Delphi e utilizar gerenciadores de banco de dados
como MS SQL Server, Oracle, Interbase ou MS Access.
Apesar de o MS Access se tudo-em-um, é recomendável separar dados de processos.
Você deve criar a aplicação um arquivo .MDB com consultas, formulários, relatórios, macros
e módulos e ter outro (ou outros) arquivos somente com tabelas. Por que isto?
Os dados são a parte mais estável de uma aplicação. Você pode ter um processo em
que os descontos variem de acordo com a política da empresa ou a época do ano, mas os
dados terão uma estrutura mais perene. Não é difícil encontrar empresas com cadastro de
clientes de anos atrás, mas que já tiveram várias formas de processar faturas, descontos e
promoções. Mudar processos não causa grande impacto na aplicação, mas quando se altera a
estrutura dos dados o trabalho é colossal, porque a alteração na estrutura deve preservar os
dados e há a necessidade de se revisar e alterar os programas que acessam estes dados. Um
bom exemplo é o que aconteceu com o chamado Bug do Ano 2000. O problema,
aparentemente simples, era acrescentar dois dígitos no ano, mas a solução demandou muito
tempo e dinheiro, envolvendo o mundo inteiro e não somente sistemas de computador.
Além do mais, os dados normalmente são corporativos mas ficam agrupados por área
funcional. Há dados da área de pessoal, da área de transporte, da área de engenharia, etc. É
comum estes dados ficarem fisicamente distribuídos vários computadores e em formatos
distintos.
Portanto, uma aplicação em Access deve considerar que os dados estão distribuídos e
em formatos distintos. Mesmo que seja uma aplicação simples, é uma boa prática separar
dados de processos.

7
Microsoft© Access Avançado
O MS Access pode acessar dados em formatos dBase, texto, Excel, Paradox, FoxPro e
HTML via ISAM – Indexed Sequential Access Method e bancos de dados SQL Server,
Oracle e outros via ODBC – Open Database Connectivity. Para tanto, você deve ter instalado
os drivers apropriados no computador onde a aplicação rodará.

Como dados estão separados, o MS Access provê formas de acessá-lo:


 Vinculação de tabela
 Consulta de passagem (pass-through)
 Expressão SQL com a cláusula IN.
 Programação com DAO
 Programação com ODBC-API
 Programação com objetos de acesso a dados, como o RDO e ADO.

No modo interativo você vincula tabelas pelo menu Arquivo|Obter dados


externos|Vincular tabela…. Esta é a forma mais simples de se trabalhar, pois tudo funciona
como se as tabelas estivessem no mesmo banco de dados e você pode acessar qualquer
formato suportado pelos drivers ISAM ou ODBC instalados no seu computador. É possível
abrir tabelas vinculadas normalmente e criar consultas, formulário e relatórios baseados em
tabelas vinculadas. Você verá neste curso como vincular tabelas via programação do DAO.
A consulta de passagem é usada para obter dados provenientes de bancos de dados
como o SQL Server. O Access interage diretamente com o servidor SQL Server, sem utilizar
ODBC nem o mecanismo Jet. Este tipo de consulta não pode ser usada como origem de
registro de formulário e relatório.
Expressões SQL com cláusula IN se aplica criar consultas ou expressões SQL que
acessam tabelas externas em formato Access, dBase, Excel, Parados, e outros formatos
ISAM. Não pode ser usada como origem de registro de formulário e relatório.
O DAO – Data Access Object é um objeto de acesso a dados utilizado na programação
do MS Acccess e suportado também pelo MS Visual Basic. Veremos neste curso a sua
programação.
A programação ODBC-API, como o nome sugere, só é possível acessar dados em
servidor de banco de dados por meio de programação em módulo. Neste tipo de programação,
o Access despreza o seu mecanismo de acesso a dados, o Jet Engine, e interage diretamente
com o gerenciador ODBC. Este assunto não faz parte deste curso.
Programar diretamente via ODBC-API é trabalhoso. O RDO – Remote Data Object é
uma camada entre o Access e o ODBC-API que torna a compreensão dos comandos mais
fácil. Este curso não tratará deste assunto.
ODBC-API e RDO são tecnologias em desuso. A última palavra em acesso a dados é
o ADO- ActiveX Data Object, da Microsoft. Ele pode acessar vários formatos de dados,
desde que você tenha um OLE-DB Provider. O MS Access suporta o ADO via programação
em módulo, desde que você tenha este objeto instalado no seu computador o o OLE-DB
Provider apropriado para o formato desejado. A vantagem é que o ADO acessa diretamente a
fonte de dados, sem passar pelo mecanismo Jet nem por gerenciador ODBC. Não veremos o
ADO neste curso.

8
Microsoft© Access Avançado
2. PROGRAMAÇÃO NO MS ACCESS

2.1. Macro x Módulo


No MS Access, o termo macro designa ações pré-definidas dispostas sequencialmente.
Para não-programadores, as macros podem ser usadas para operações simples, como abrir um
formulário ou relatório, executar uma consulta ou acionar um item de menu.
A chamada de macros por botões de comando em formulários e menus fornece ao
aplicativo uma interface com certo grau de controle de navegação pelas telas e automação.
Isto também restringe o acesso do usuário a recursos críticos do MS Access, tal como alterar
a estrutura de uma tabela, e não exige do usuário um alto nível de conhecimento sobre o MS
Access.
Você pode criar botões de comando em formulários e associar macros que realizam
ações pré-definidas. Por exemplo, o botão de comando cuja legenda é Cadastrar Livros
invoca a macro Macro1. Na Macro1 existe uma ação AbrirFormulário que abre o
formulário chamado frmCadastra_Livros.

A estrutura do formulário mostra que o evento do botão cmdCadastraLivros invoca a


macro Macro1 através do evento Ao clicar.

9
Microsoft© Access Avançado

A manutenção de aplicativos baseados em macros é difícil, pois existem objetos


distintos: o formulário e a macro. Para cada controle que possui evento associado haveria a
necessidade de uma macro. A quantidade de objetos para gerenciar tornaria difícil a
compreensão do fluxo de execução.
Além disso, as macros não oferecem um bom controle de fluxo, pois não possuem
estruturas de controle sofisticados como If..Then..Else e estruturas de repetição como Do
While.
A construção de aplicativos usando programação reduz a complexidade do fluxo
porque a ação é codificada na própria estrutura do formulário. Os eventos de cada controle
apontam para procedimentos escritos em um linguagem de programação poderosa – o Visual
Basic for Application – que permite a criação de rotinas complexas e estruturadas.
No exemplo a seguir, os dois controles invocam os procedimentos de evento
cmdConsultaAutores_Click e cmdCadastraLivros_Click. Estes controles são botões de
comando, cujas propriedades Ao clicar apontam para o código que se encontra na própria
estrutura do formulário.

10
Microsoft© Access Avançado

A programação no MS Access torna o uso de macros obsoleta, pois tudo que as


macros fazem a programação consegue fazer com maior grau de controle sobre o fluxo de
execução. Portanto, não faz sentido neste curso ensinar como se constrói macros.

2.2. Módulos
A programação no MS Access é feita nos módulos.
Um módulo é uma coleção de declarações e procedimentos armazenados
conjuntamente, formando uma unidade. As declarações são instruções que direcionam o
comportamento dos procedimentos em todo um módulo.Um procedimento é uma unidade de
código VBA que realiza uma operação específica. Por exemplo, o cálculo dos dígito
verificador do CPF é um procedimento e o cálculo do fatorial de um número é outro.
Os módulos podem estar alojados em três lugares:
 Na guia Módulos da janela de Banco de Dados do MS Access. Nela existem dois tipos de
módulos: módulo padrão e módulo de classe.
 Embutido em um formulário do Access. Contém módulo de classe.
 Embutido em um relatório do Access. Contém módulo de classe.

Cada módulo na guia Módulos recebe um nome único dentro do aplicativo (no
mesmo arquivo .mdb). O nome deve seguir uma regra de nomenclatura:
 Pode conter até 64 caracteres, entre letras e números
 Aceita espaços e caracteres especiais, exceto ponto, exclamação, acento grave, colchetes e
caracteres de controle (código ASCII de 0 a 31).
 Aceita letras maiúsculas e minúsculas indistintamente.
 Não pode conter espaços no início do nome

11
Microsoft© Access Avançado
É recomendável não usar espaços nem caracteres especiais e evitar nomes muito
longos. O Anexo A sugere uma convenção de nomes a ser adotada no desenvolvimento de
aplicativos com produtos Microsoft.
Os módulos de classe em formulários e relatórios não recebem nomes, pois são
gravados juntamente com o formulário ou relatório aos quais estão relacionados.
O código de um módulo é composto por:
 Instruções, funções e palavras-chave do VBA
 Nomes de variáveis, constantes ou procedimentos fornecidos pelo desenvolvedor
 Instruções e cláusulas da linguagem SQL
 Propriedades e métodos de objetos

As instruções, funções, palavras-chave, cláusulas, propriedades e métodos são


palavras reservadas, ou seja, você não as pode usar como nome de procedimento ou nome de
variável ou constante.

2.3. Quando usar programação


No MS Access, usa-se programação em VBA:
 Para efetuar um processamento complexo, que não pode ser atendido com a utilização de
consultas, nem macros. Exemplo: O cálculo de faturamento exige ler todos os serviços
prestados em um período, computar para, cada fatura, os descontos, multas, juros,
impostos e taxas.

 Para criar funções definidas pelo usuário – UDF (User Defined Functions), por exemplo,
o cálculo dos dígitos verificadores do CGC.

 Para percorrer um registro de cada vez. As consultas de seleção e de refer6encia cruzada


retornam um conjunto de registros de uma vez só, mas ás vezes é necessário processar
cada registro, seja de uma tabela ou de uma consulta.

 Sempre que se necessitar de usar estruturas de repetição e condição complexa (do tipo Do
While e If...Then...Else).

 Para substituir macros por código VBA equivalente. As macros ficam armazenadas em
pastas de macro (a quinta guia da janela Banco de Dados), mas podem ser chamadas de
qualquer parte do Access. Ás vezes pode ficar difícil entender o emaranhado de chamadas
a elas. Os módulos, por formarem uma unidade, são mais compreensíveis, podendo ainda
ser impressas. Assim, o aplicativo pode ser construído de forma modular e concisa,
melhorando assim a sua legibilidade e documentação.

 Para manipular objetos de outros softwares, como o Word e Excel, através da automação.

 Para realizar operações de DDE (troca dinâmica de dados), como por exemplo ler uma
tela do Plenus (um emulador de terminal Unisys TB-27).

 Para efetuar transações com COMMIT e ROLLBACK.

12
Microsoft© Access Avançado
2.4. Módulo padrão
Usa-se código em módulo padrão para criar procedimentos globais, isto é, aqueles que
serão usados por todo o aplicativo. Por exemplo, uma função para transformar um número em
extenso pode ser chamada em qualquer do aplicativo..
Os procedimentos armazenados em Módulo Padrão são do tipo Function (aquele que
retorna um valor, por exemplo o fatorial de um número) ou Sub (aquele que não retorna
valor, por exemplo, uma rotina para tratar e imprimir mensagens de erro na tela).
Uma janela de código em módulo padrão possui as características mostradas abaixo.

2.5. Módulo de classe em formulários e relatórios


Os módulos embutidos em formulário e relatórios são do tipo Módulo de Classe. São
módulos que residem na estrutura dos formulários e relatórios, assim como os objetos de
controle. Por ficarem atrás dos formulários e relatórios, são também chamados de code
behind form. Os módulos de classe em formulário e relatório contêm procedimentos de
evento, que respondem a eventos de formulário, relatório ou controle neles inseridos. Os
procedimentos de evento em módulo de formulário respondem a eventos (tais como o clicar
do mouse) do próprio formulário, de suas seções (cabeçalho, detalhe, rodapé) e dos controles.
Os procedimentos de evento em módulo de relatório respondem a eventos do próprio relatório
e de suas seções somente.
Se se deseja que um evento em um formulário ou relatório acione um procedimento
Function ou Sub de um módulo padrão, é preciso que o procedimento de evento dentro do
módulo de formulário/relatório faça a chamada. O código abaixo é um procedimento de
evento ligado ao controle cmdOkButton que chama um procedimento Sub armazenado em
módulo padrão.

13
Microsoft© Access Avançado

Private Sub cmdOkButton_Click()


CalculaRateio()
End Sub

Uma janela de código em módulo de classe embutido em formulário/relatório tem as


características mostradas abaixo.

O módulo de classe em formulário ou de relatório também pode conter procedimentos


Sub ou Function.

2.6. Módulo de classe


O módulo de classe criado na guia Módulos da janela de Banco de Dados do Access
tem como objetivo implementar as classes de objetos definidas pelo desenvolvedor,
permitindo uma certa reusabilidade de código. Os formulários e relatórios são classes de
objetos pré-definidos, que possuem seus próprios métodos e propriedades. Ao construir um
módulo de classe na janela de módulo, você cria uma nova classe de objetos.
Os procedimentos Sub e Function tornam-se os métodos do novo objeto e os
procedimentos Property Let, Property Get e Property Set tornam-se as propriedades do
objeto.
A programação de classes de objetos é mais efetiva no Visual Basic, pois você pode
construir um objeto totalmente encapsulado em um arquivo DLL, EXE ou OCX e pode usá-lo
em qualquer outra linguagem que suporte a arquitetura COM (Componente Object Model).

14
Microsoft© Access Avançado

2.7. Seção de declarações


A janela de código de módulo, seja padrão ou de classe, possui a seção de
declarações e a seção de procedimentos.
Na seção de declarações encontram-se as instruções de escopo de módulo, ou sejam,
as instruções da seção de declarações afetam todos os procedimentos daquele módulo. As
variáveis declaradas nesta seção também são de nível de módulo, o que quer dizer que todos
os procedimentos do módulo podem acessar e alterar o conteúdo destas variáveis.
Por padrão, a seção de declaração de módulo no Access vem com as instruções
Option Compare Database e Option Explicit.
A instrução Option Compare define a ordem em que os caracteres são comparados.
Se Option Compare não for definido, o padrão é Option Compare Binary, que define a
ordem de classificação de acordo com a página de código utilizado no Windows.
Tipicamente, comparação binária segue a seqüência:
A<B<E<Z<a<b<e<z<À<Ê<Ø<à<ê<ø

Com a opção Database, a comparação segue o que estiver definido nas opções do
Access (menu Ferramentas|Opções..., guia Geral, na caixa Nova Ordem de classificação do
banco de dados).
A instrução Option Explicit obriga que todas as variáveis sejam declaradas
explicitamente, ou seja, usando as instruções de declaração de variáveis (Dim, Redim,
Private, Public ou Static). É altamente recomendável que as variáveis sejam declaradas
explicitamente para que não haja conflitos de nomes de variáveis.

2.8. Seção de procedimentos


Na seção de procedimentos você escreve seus procedimentos. Os procedimentos de
um módulo padrão pode ser do tipo Sub ou Function, ou procedimentos de evento (no caso
de módulo de classe de formulário e relatório) ou procedimentos Property Let, Property Get
e Property Set (no caso de módulo de classe).
15
Microsoft© Access Avançado
Todo procedimento deve ter um nome único em todo aplicativo e seguir as regras de
nomenclatura:
 Podem ter até 255 caracteres.
 Precisam começar com uma letra.
 Podem incluir letras, números ou caracteres sublinhados (_).
 Não podem incluir caracteres de pontuação ou espaços.
 Não podem ser uma palavra reservada do Visual Basic.
 Podem ser escritos com letras maiúsculas ou minúsculas,sem distinção.

Os procedimentos Sub começam com a instrução Sub, seguido do nome do


procedimento, e terminam com End Sub. Entre Sub e End Sub fica o código que realizará a
operação desejada. O procedimento Function começam com a instrução Function, seguida no
nome do procedimento, e termina com End Function.
Os procedimentos de um módulo de classe de formulários e relatórios podem ser do
tipo Sub ou Function, mas o usual é que contenham procedimentos de evento.

2.9. O editor de código


A digitação do código em VBA é feita no próprio MS Access, na janela de código de
um módulo (seja módulo padrão, módulo de classe ou módulo de classe de
formulário/relatório). Para facilitar a edição e visualização do código, o editor de código
possui opções configuráveis, na qual pode-se escolher cores, fontes, tabulação e outros
recursos.

Figura 1: Opções do editor de código do Access

16
Microsoft© Access Avançado
2.9.1. Cores de código
Por padrão, todo o texto do código é escrito usando a fonte Courier New tamanho 10.
A cor depende do tipo do texto. A cor é definida para o primeiro plano, para o segundo plano
e para o indicador de margem. Indicador margem é um ícone que aparece na margem
esquerda (margin indicator) do código, que serve para fornecer dicas visuais durante a
edição ou execução do código.
Os valores padrão para as opções de Caixa de texto, primeiro plano, segundo plano e
indicador são:
Área de texto 1o plano 2º plano Indicador
Texto normal Preta Branca
Texto de seleção Preta Azul
Texto de erro de sintaxe Vermelha Branca
Texto de ponto de execução Preta Amarela Amarela
Texto de ponto de interrupção Branca Marron Marron
Texto de comentário Verde Branca
Texto de palavra-chave Azul Branca
Texto de identificador Preta Branca
Texto de indicador Preta Branca Azul claro
Texto de retorno de chamada Preta Branca Verde claro

Para cada valor de área de texto você pode especificar o tipo de fonte e o tamanho nas
caixas Fonte e Tamanho.
Os ícones de indicadores de margem são:
Ícone Nome do Indicador Descrição
de margem
Ponto de interrupção Indica que você definiu um ponto de interrupção usando o
comando Ativar/desativar ponto de interrupção no menu
Depurar. Você pode ativar/desativar o ponto de interrupção
colocando o ponteiro do mouse na região do indicador de
margem e clicando nele.
Linha de execução Indica a linha de código que será executada a seguir. Você
atual pode arrastar esse indicador de margem para um novo local
dentro de qualquer módulo de código em execução. Caso
arraste o indicador de margem da Linha de execução atual
para uma linha ou região inválida, nada acontecerá e o
indicador retornará para o local original.
Indicador Indica o local de um indicador definido usando o comando
Alternar indicador no menu Editar.
Marcador de Pilha de Indica as linhas que estão atualmente na pilha de chamadas. O
chamadas indicador Marcador de pilha de chamadas aparece apenas no
modo de interrupção.

2.9.2. Opções de codificação


 Autorecuar — Permite que você tabule até a primeira linha de código; todas as linhas
subseqüentes iniciarão nesse local da guia.

17
Microsoft© Access Avançado
 Verificação de sintaxe automática — Determina se o Visual Basic deve verificar
automaticamente a sintaxe correta depois que você inserir uma linha de código.
 Solicitar declaração de variável — Determina se declarações de variável explícitas são
exigidas nos módulos. Esta seleção adiciona a instrução Option Explicit às declarações
gerais de todo módulo novo.
 Compilar ao ser solicitado — Determina se um projeto está totalmente compilado antes
que ele seja iniciado ou se o código está compilado conforme o necessário, permitindo
que o aplicativo inicie logo.
 Listar membros automaticamente — Exibe uma lista que contém informações que
concluiriam logicamente a instrução no ponto de inserção atual. Exemplo.

 Informação rápida automática — Exibe informações sobre funções e seus parâmetros à


medida que você digita. Exemplo:

 Dicas de dados automáticas — Exibe o valor da variável sobre a qual o seu cursor está
posicionado. Disponível somente no modo de interrupção. Exemplo:

 Largura da tabulação — Define a largura da guia, que pode variar de 1 a 32 espaços; o


padrão é 4 espaços.

2.9.3. Configurações da janela


 Visualizar módulo completo — Define o estado padrão dos novos módulos para permitir
que você observe os procedimentos na janela Código como uma lista rolável simples ou
somente um procedimento de cada vez. Não altera o modo de exibição dos módulos
atualmente abertos.
 Separador de procedimento — Permite que você exiba ou oculte as barras separadoras que
aparecem no fim de cada procedimento na janela Código.
 Arrastar-e-soltar edição de texto — Permite que você arraste e solte elementos dentro do
código atual e da janela Código para as janelas Imediata ou Inspeção de variáveis.
 Janela depurar visível — Mantém a janela Depurar aberta.
 Barra do indicador de margem — Exibe a margem de indicador.

2.10. Janelas do editor de código do Access


A parte de programação do MS Access possui apenas três janelas:
 Janela de Código
 Janela Depurar
 Janela do Pesquisador de Objetos.

18
Microsoft© Access Avançado

2.10.1. Janela de Código


A janela de código contém as seções de declaração e a seção de procedimentos e é
onde se digita o código.

A janela de código é aberta nas seguintes situações:


 Na guia Módulos da janela de Banco de Dados clique em Novo para criar um nvo módulo
ou em Estrutura para abrir um módulo existente.
 Na estrutura de formulário ou relatório, acione o menu Exibir|Código, ou clique no ícone
da barra de ferramentas, ou acione o construtor de código nas propriedades do objeto.

2.10.2. Janela Depurar


A janela Depurar consiste de três painéis: Imediato, Locais e Inspecionar. Para
visualizar a janela Depurar, abra um módulo e clique no ícone na barra de ferramentas.
Você também pode abrir a janela Depurar acionando o menu Exibir| Janela Depurar. Você
pode também pressionar Ctrl-G a qualquer momento dentro do Access.

19
Microsoft© Access Avançado

Você pode alternar entre o painel Locais e o painel Inspecionar clicando na guia
Locais ou na guia Inspecionar da janela Depurar. O painel Imediato permanece visível,
independentemente de qual guia é clicada.

2.10.2.1. O Painel Locais


O painel Locais exibe uma lista de variáveis em três colunas: Expressão, Valor e Tipo.
Algumas variáveis, como tipos definidos por usuários, matrizes e objetos, podem conter
informações hierárquicas. Estas variáveis têm um botão para expandir/reduzir à esquerda dos
nomes de variável para controlar a exibição de informações hierárquicas. Quando o painel
Locais está visível, ele é atualizado automaticamente quando o modo de execução muda do
modo de execução para o modo interrupção. Isto acontece quando a execução atinge um
ponto de interrupção ou quando você começa a depurar o código.
A primeira variável da lista é uma variável especial de módulo. Para um módulo
classe, esta é a variável Me definida pelo sistema. Esta é uma referência de objeto à instância
atual da classe definida pelo módulo atual. Já que esta variável é uma referência de objeto, ela
pode ser expandida para mostrar todas as propriedades e os membros de dados da instância de
classe atual. Para módulos padrões, a primeira variável é o nome do módulo atual e também
pode ser expandida para exibir todas as variáveis no nível de módulo no módulo atual. Você
pode alterar o valor de uma variável do painel Locais, mas não pode alterar suas definições de
Expressão ou Tipo.

2.10.2.2. O Painel Inspecionar


O painel Inspecionar permite que você visualize o valor de uma expressão ou uma
variável enquanto o código estiver em execução. Para definir uma expressão de inspeção,
clique no menu Depurar|Adicionar inspeção de variáveis. O painel Inspecionar proporciona
as seguintes capacidades:

20
Microsoft© Access Avançado
 Expandir/reduzir informações hierárquicas.
 Redimensionar cabeçalhos de coluna.
 Editar valores in loco.

2.10.2.3. O Painel Imediato


No painel Imediato, você pode:
 Executar qualquer procedimento Sub ou Function, inclusive procedimentos de evento.
 Executar uma expressão qualquer, inclusive usando variáveis do procedimento em
execução.
 Visualizar a saída de valores enviados pelo método Print do objeto Debug.

Para executar um procedimento definido dentro de um módulo classe a partir do


painel Imediato, você precisa qualificar o procedimento com o nome do módulo classe, a
menos que você esteja no modo de interrupção dentro daquele módulo. Se você estiver no
modo interrupção, não é necessário qualificar o procedimento pois esse módulo está
atualmente no escopo.
O exemplo seguinte, quando digitado no painel Imediato da janela Depurar, executa
um procedimento ListarNomes que está definido no módulo classe associado a um formulário
Funcionários:
Form_Funcionários.ListarNomes

O próximo exemplo executa o procedimento do evento Click para um botão de


comando chamado InformaçõesPessoais em um formulário Funcionários:
Form_Funcionários.InformaçõesPessoais_Click

Para executar uma expressão, use o sinal ? seguido da expressão desejada. Por
exemplo, o comando abaixo irá calcular o número inteiro de uma divisão.
? Int(345/7)

2.10.2.4. Outros Recursos da Janela Depurar


A nova janela Depurar proporciona automaticamente informações de status sobre seu
código. Quando nenhum código está sendo executado, a barra de status no topo da janela
Depurar mostra "<Pronto>". Uma vez iniciada a execução do código, a barra de status mostra
o nome do banco de dados atual, o módulo no qual reside o procedimento em execução, e o
nome do próprio procedimento.
Você também pode visualizar a janela Chamadas a partir da janela Depurar clicando
no botão Construir .

2.10.3. Janela Pesquisador de Objetos

A janela Pesquisador de Objetos é aberta pelo menu Exibir|Pesquisador de Objetos


ou pela tecla F2.
O Pesquisador de Objetos é uma caixa de diálogo que exibe informações sobre
objetos, propriedades, métodos e constantes do banco de dados atual e em bibliotecas de
objetos referenciados. Você pode utilizar o Pesquisador de Objeto para pesquisar um

21
Microsoft© Access Avançado
elemento específico, visualizar suas definições, obter ajuda sobre ele ou colá-lo em um
módulo.

*****

22
Microsoft© Access Avançado

PRÁTICA 2 – PROGRAMAÇÃO NO MS ACCESS

EXERCÍCIO 1 – Criando um módulo padrão

Crie um módulo basDemonstracao contendo o procedimento Welcome.

1. Abra o MS Access .
2. Crie um banco de dados vazio chamado dbWelcome.mdb.
3. Selecione a guia Módulos na janela de Banco de Dados.
4. Clique em Novo.
5. Digite o seguinte procedimento:
Sub Welcome()
MsgBox "Bem-vindo ao curso MS Access Avançado", vbOKOnly, "teste"
End Sub

Perceba como o Access diferencia cores para instruções e texto de usuário e como o editor de
código fornece dicas da sintaxe da instrução MsgBox.

6. Clique no menu Arquivo|Salvar.


7. Informe o nome basDemonstracao e clique OK..
8. Posisione o cursor em qualquer parte do código.
9. Tecle F5. Será mostrada uma caixa de mensagem chamada Teste com o texto "Bem-vindo
ao curso MS Access Avançado"
10. Clique no botão OK da caixa de mensagem.
11. Feche a janela de módulo e veja o nome do módulo basDemonstracao gravado na guia
Módulos da janela de Banco de Dados.

EXERCÍCIO 2 – Criando um módulo de classe em formulário


Crie um formulário chamado frmDemonstracao.

1. Clique na guia Formulários da janela de Banco de Dados.


2. Clique em Novo.
3. Escolha Modo estrutura e clique em OK.
4. Desligue o Assistentes de controle da barra de ferramentas Caixa de ferramentas.
5. Crie um botão de comando.
6. Abra as propriedades do botão de controle e selecione a guia Todas.
7. Atribua as seguintes propriedades:

Nome: cmdOK
Legenda: &Ok
Ao clicar: [Procedimento de Evento]

8. Clique no botão do construtor de código em frente à propriedade Ao clicar. Será


aberta a janela de módulo de classe.
9. Digite o código a seguir:
Private Sub cmdOk_Click()

23
Microsoft© Access Avançado

MsgBox "Isto é um procedimento de evento do controle cmdOk"


End Sub

10. Feche a janela de módulo.


11. Salve o formulário como frmDemonstracao.
12. Alterne para o Modo Formulário.
13. Clique no controle Ok. Surgirá uma caixa de mensagem com o texto "Isto é um
procedimento de evento do controle cmdOk"
14. Feche o formulário.

3. PROCEDIMENTOS EM MÓDULO PADRÃO

Procedimento é uma unidade de código VBA que contém instruções e métodos


sequencia e logicamente ordenados que ao final de algum tempo de execução realizará uma
tarefa específica, previamente planejada no algoritmo.
Por exemplo, podemos querer determinar as raízes de uma equação do segundo grau
por meio de um procedimento. Ao final, podemos ter como resultado um valor, dois valores
ou nenhum.
2
A equação do 2º grau possui a forma geral: ax + bx + c = 0
A resolução do problema consiste em receber três valores da equação do 2º grau,
normalmente chamados de a, b e c e determinar os valores de x. Os valores de x são
determinados pela fórmula de báskara, que consiste em:

b ± b 2 − 4ac
x=
2a
O algorimo para implementar a fórmula de Báskara é:
Algoritmo Baskara
Declare a, b, c, Delta, x1, x2 numérico
Leia a
Leia b
Leia c
{Calcule Delta}
Delta ← b2 – 4 x a x c
Se Delta = 0 então
x1 ← -b ÷ 2 x a
Escreva x1
SenãoSe Delta > 0 então
x1 ← (-b + Delta ) ÷ (2 x a)
x2 ← (-b - Delta ) ÷ (2 x a)
Escreva x1
Escreva x2
Senão
Escreva "Não há solução"
Fim Se
Fim algoritmo

24
Microsoft© Access Avançado

Este algoritmo tem uma finalidade geral e portanto é adequado usar módulo padrão.
Módulos padrão são criados na guia Módulos da janela de Banco de Dados. Selecione a guia
Módulos na janela de Banco de Dados e clique no botão Novo. É aberta uma janela de código
para criação de procedimentos em módulo padrão.
Cada módulo pode conter um ou mais procedimentos do tipo Sub (procedimento sem
retorno de valor, ou simplesmente procedimento) e Function (procedimento com retorno de
valor, ou simplesmente, função).
Abaixo da seção de declarações, digite a palavra reservada Sub ou Function seguido
do nome do procedimento.
Após teclar Enter, uma seção de procedimento será criada, iniciando com a declaração
do procedimento e terminando com a palavra reservada End Sub ou End Function.
Option Compare Database
Option Explicit

Sub MeuProcedimento()
[ instruções ]
End Sub

Function MinhaFuncao()
[ instruções ]
End Function

Na área entre a declaração do procedimento e o seu fim você deve digitar o seu código
VBA. Comece sempre com a declaração das variáveis e constantes que serão utilizados pelo
seu código.
Criemos um primeiro código para implementar o algoritmo de Báskara.
Sub Baskara()
Dim sngA As Single
Dim sngB As Single
Dim sngC As Single
Dim dblDelta As Double
Dim sngX1 As Single
Dim sngX2 As Single

sngA = InputBox("Valor de A")


sngB = InputBox("Valor de B")
sngC = InputBox("Valor de C")
' Cálculo de Delta
dblDelta = sngB ^ 2 - 4 * sngA * sngC
If dblDelta = 0 Then
sngX1 = -sngB / (2 * sngA)
MsgBox sngX1
ElseIf dblDelta > 0 Then
sngX1 = (-sngB + Sqr(dblDelta)) / (2 * sngA)
sngX1 = (-sngB - Sqr(dblDelta)) / (2 * sngA)
MsgBox sngX1
MsgBox sngX2
Else
MsgBox "Não há solução"
End If
End Sub

25
Microsoft© Access Avançado

Os parênteses após o nome do procedimento serve para receber argumentos (também


chamado de parâmetros). Veremos a passagem e recebimento de argumentos mais adiante.
Dentro do mesmo módulo, podemos ter mais de um procedimento Sub ou Function.
Criaremos um procedimento para cálculo de fatorial de um número.
Sub Fatorial()
Dim lngNumero As Long
Dim dblFatorial As Double
Dim lngContador As Long

lngNumero = InputBox("Entre com um número")


dblFatorial = 1
lngContador = 2
If lngNumero = 0 Or lngNumero = 1 Then
MsgBox "O fatorial é 1"
Else
Do While lngContador <= lngNumero
dblFatorial = dblFatorial * lngContador
lngContador = lngContador + 1
Loop
MsgBox "O fatorial é " + str(dblFatorial)
End If
End Sub

3.1. Compilação de módulo


Na maioria da linguagens de programação o termo compilação significa gerar um
arquivo executável a partir do programa fonte. Compilar no MS Access significa verificar a
sintaxe das instruções e a verificação de variáveis e constantes não declaradas (caso Option
Explicit esteja ativado).
Ao terminar a digitação do código, você deve compilar o módulo. A compilação é
feita no menu Depurar|Compilar módulos carregados na janela de módulo. A compilação
abrange todos os módulos abertos (seja padrão, de classe ou de formulário/relatório) e não
somente o módulo que está sendo editado.
Se houve erro de sintaxe ou variável não declarada, uma caixa de mensagem
informará o erro e o texto onde o erro ocorreu será selecionado. Por exemplo, o código abaixo
apresentará erro, pois estamos usando uma variável não declarada.

Option Compare Database


Option Explicit

Sub Teste()
Dim intNumero As Integer
intNumero = intDesconto * 42
MsgBox intNumero
End Sub

Ao compilar, será mostrada uma caixa de diálogo com o erro “Variável não definida”.

26
Microsoft© Access Avançado

Ao clicar OK, a janela do código onde ocorreu o erro será aberta e o local do erro
ficará marcado.
Caso não haja erros de sintaxe, verifique erros de lógica, para que o programa não
trave o computador. Se tudo estiver correto, salve o módulo e forneça um nome. A gravação
do módulo é feita pelo menu Arquivo|Salvar.

3.2. Teste de execução de procedimento em módulo padrão


Os procedimentos em módulos padrão, desde que não recebam argumentos, podem
ser executados, para fins de teste, a partir da janela de código do módulo que está sendo
editado.
Dentro de um mesmo módulo podem ser escritos vários procedimentos. Para executar
um deles, você deve posicionar o cursor em qualquer parte do procedimento desejado e teclar
F5 ou acionar o menu Executar|Ir para/continuar ou ainda teclar o ícone .

3.3. Execução passo-a-passo


Você pode executar o procedimento passo-a-passo, uma linha de cada vez, para
acompanhar o fluxo de execução, depurar eventuais erros de lógica ou visualizar o conteúdo
de variáveis.
A execução passo-a-passo é acionada pela tecla F8 ou pelo ícone na barra de
ferramentas da janela de módulo ou pelo menu Depurar|Depuração total. Durante a
execução passo-a-passo, o texto da linha de código que está sendo executada ficará na cor
definida por “Texto de ponto de execução” definido nas opções do editor de código (menu
Ferramentas|Opções, guia Módulo) e o indicador surgirá na barra Indicador de Margem.
A qualquer momento, você pode decidir pela execução total, teclando-se F5. Durante
a execução passo-a-passo você pode abortar a execução acionando o menu Executar|Fim ou
clicar no ícone na barra de ferramentas. Este ícone só está ativado se algum procedimento
estiver sendo executado. Ao editar o código, preste atenção neste ícone e lembre-se de
terminar a execução antes de fazer qualquer alteração em seu código ou na estrutura de
tabelas, consultas, formulários e relatórios.

27
Microsoft© Access Avançado

3.4. Inspeção de variáveis


Durante a execução passo-a-passo você pode posicionar o mouse sobre uma variável e
verificar o valor nela contida naquele momento da execução.

28
Microsoft© Access Avançado

Lembre-se que este recurso de inspeção de variáveis durante a execução do


procedimento só está disponível se a opção “Dicas de dados automáticas” estiver ativada nas
opções do editor de código.
Você pode inspecionar todas as variáveis no painel Locais da janela Depurar.

3.5. Ponto de interrupção


Para depurar uma aplicação não é necessário executar passo-a-passo todos os códigos.
Normalmente, você quer estudar algumas partes do código mais suceptíveis a falhas. Você
pode estabelecer pontos de interrupção nas linhas em que você quer começar a execução
passo-a-passo.
Para isto, vá até a linha onde se deseja interromper a execução e tecle F9 ou o ícone
na barra de ferramentas ou acione o menu Depurar|Ativar/Desativar pontos de
interrupção. O indicador de margem apresentará o ícone e o texto da linha ficará na cor
marrom em segundo plano.
Ao executar o procedimento com F5, o código será executado completamente e parará
no ponto de interrupção. A partir daí, pode-se prosseguir com F8 para execução passo-a-passo
ou F5 para continuar a execução completa. Um novo F9 na linha do ponto de interrupção
desativará o ponto de interrupção.
Os pontos de interrupção servem para testar o aplicativo. Você deve lembrar de
desativar todos os pontos de interrupção antes de salvar o módulo (ou formulário ou relatório)
para ser distribuído. Pressionando Control+Shift+F9 desativa todos os pontos de interrupção
de todos os módulos, estejam estes salvos ou não.

29
Microsoft© Access Avançado

3.6. Chamada de Procedimentos


Os procedimentos anteriores são duas unidades de código independentes entre si. Cada
um deles é executado ao teclar F5.
Usamos a tecla F5 apenas para testar cada um dos procedimentos. Naturalmente,
quando construir um aplicativo em Access, ele não funcionará à base de tecla F5. Haverá uma
interface gráfica, normalmente um formulário, com opções para executar os procedimentos
que você criou. Veremos em outro capítulo como chamar um procedimento a partir de um
formulário.
Agora, precisamos saber como um procedimento pode chamar outro e como eles se
relacionam.
Suponha que você escreva um procedimento para calcular a combinação de n números
tomados p a p. A fórmula da combinação é:

n!
Cn, p =
p !(n − p)!

Note que para resolver este problema é preciso calcular três fatorias. Ora, já vimos um
procedimento para calcular fatoriais. Não bastaria escrever três vezes o código dentro do
procedimento de combinação?
Não é nada produtivo ter que rescrever o mesmo algoritmo várias vezes. O que
podemos fazer é fazer com que o procedimento de combinação chame o procedimento de
fatorial todas as vezes que for necessário.
Qualquer procedimento pode chamar outro procedimento apenas colocando-se o nome
do procedimento como se fosse uma instrução do VBA.

Sub Combinacao()
.
.
Fatorial
.
End Sub
Esquematicamente, a chamada de um procedimento por outro funciona assim:

Entretanto, o procedimento Fatorial exige que um valor seja informado. No caso,


informamos o valor com a função InputBox do VBA. O procedimento Fatorial também
fornece a resposta por meio da função MsgBox. Da forma como o procedimento foi escrito
ele é um procedimento completo e independente.

30
Microsoft© Access Avançado

Para que o procedimento de combinação possa utilizar o procedimento Fatorial, de


forma a ambos funcionarem em conjunto, devemos modificar o procedimento Fatorial.
A primeira coisa a fazer é retirar a função InputBox do procedimento Fatorial. O
número para o qual se deseja calcular o fatorial deve ser passado como um argumento.

3.6.1. Passagem de Argumentos


Os parênteses à frente do nome do procedimento servem para receber argumentos
vindos de outro procedimento que o chamou. Argumentos são variáveis que receberão
valores, constituindo-se assim a entrada de dados para o procedimento.

Sub Fatorial(lngNumero As Long)


Dim dblFatorial As Double
Dim lngContador As Long

dblFatorial = 1
lngContador = 2
If lngNumero = 0 Or lngNumero = 1 Then
MsgBox "O fatorial é 1"
Else
Do While lngContador <= lngNumero
dblFatorial = dblFatorial * lngContador
lngContador = lngContador + 1
Loop
MsgBox "O fatorial é " + str(dblFatorial)
End If
End Sub

Para um procedimento chamar outro passando argumentos, basta escrever o seu nome
e enviar a variável ou valor à frente do nome. No caso abaixo, o procedimento Combinacao
irá chamar o procedimento Fatorial, passando o valor 4 como argumento.

Sub Combinacao()
.
.
Fatorial(4)
.
End Sub

O outro problema do procedimento Fatorial é que o resultado é escrito na tela e não


pode ser usado pelo procedimento Combinacao. Devemos, portanto, transformar o
procedimento Fatorial de Sub para Function, de forma que ele possa retornar o resultado para
o procedimento que o chamou.

3.6.2. Retorno de Valor


Somente procedimentos do tipo Function podem retornar valor para o procedimento
que o chamou.
Para retornar um valor, usa-se o próprio nome do procedimento para retornar o valor.
Como procedimento do tipo Function retornam valor, eles precisam ter um tipo definido.

31
Microsoft© Access Avançado

Function Fatorial(lngNumero As Long) As Double


Dim dblFatorial As Double
Dim lngContador As Long

dblFatorial = 1
lngContador = 2
If lngNumero = 0 Or lngNumero = 1 Then
Fatorial = 1
Else
Do While lngContador <= lngNumero
dblFatorial = dblFatorial * lngContador
lngContador = lngContador + 1
Loop
Fatorial = dblFatorial
End If
End Sub

Note que em Fatorial = 1, Fatorial não é uma variável e sim o nome do procedimento.
1 é o valor a ser retornado. Note também que o procedimento Fatorial, que agora é do tipo
Function, tem o mesmo tipo de dado que a variável dblFatorial.
Agora, o procedimento Combinacao pode chamar a function Fatorial e armazenar o
valor de retorna em uma de suas variáveis.
Sub Combinacao()
Dim N As Integer
Dim P As Integer
Dim dblFatN As Double
Dim dblFatP As Double
Dim dblFatNP As Double
Dim dblResultado As Double

N = InputBox("Entre com o valor de N")


P = InputBox("Entre com o valor de P")

dblFatN = Fatorial(N)
dblFatP = Fatorial(P)
dblFatNP = Fatorial(N - P)

dblResultado = dblFatN / (dblFatP * dblFatNP)


MsgBox dblResultado
End Sub
O procedimento Combinacao é um código completo, mas dependente da existência do
procedimento Fatorial. O procedimento Combinacao pode ser executado com F5, mas o
procedimento Fatorial não pode mais, por depender da passagem de um argumento.
Como a combinação é um código de uso geral, podemos transformá-lo também em
uma função, para que outro procedimento o chame. Neste caso, são necessários dois
argumentos.
Function Combinacao(intN As Integer, intP As Integer) As Double
Dim dblFatN As Double
Dim dblFatP As Double
Dim dblFatNP As Double

dblFatN = Fatorial(intN)
dblFatP = Fatorial(intP)

32
Microsoft© Access Avançado
dblFatNP = Fatorial(intN - intP)

Combinacao = dblFatN / (dblFatP * dblFatNP)


End Sub

Podemos testar a função Combinacao chamando-a de um outro procedimento, pois,


agora que ela recebe argumentos, ela não pode mais ser executada com F5.
Sub TestaCombinacao()
Dim N As Integer, P As Integer
N = 3
P = 2
MsgBox Combinacao(N,P)
End Sub

3.6.3. Passagem de Argumentos por Valor e por Referência


Os argumentos passados de um procedimento para outro podem ser por valor ou por
referência.
A passagem por valor indica que a variável enviada e a variável definida como
argumento são duas posições de memória distintas. Elas podem até ter os mesmos nomes.
Sub Teste1()
Dim X As Integer
X = 10
MsgBox X ' Será escrito 10
Teste2(X)
MsgBox X ' Ainda será escrito 10
End Sub

Sub Teste2(X As Integer)


MsgBox X ' Será escrito 10
X = 20
MsgBox X ' Será escrito 20
End Sub

No exemplo acima, a variável X do procedimento Teste1 contém o valor 10, e é


passado como argumento para o procedimento Teste2. Em Teste2, o valor é alterado para 20,
mas esta variável não tem nada a ver com o X de Teste1. Apenas o valor de X em Teste1 foi
passado para a variável X de Teste2. Ao retornar para Teste1, a variável X continua a ter o
valor original.
Em suma, a passagem de argumentos por valor equivale a copiar o valor para outra
variável.
Na passagem por referência, as alterações na alteração do argumento afetam o
conteúdo da variável que foi passada como argumento. Na passagem por referência, o
endereço de memória é que é passado para o procedimento. Assim, ambas as variáveis são na
realidade a mesma variável, mesmo que tenham nomes distintos
Sub Teste1()
Dim X As Integer
X = 10
MsgBox X ' Será escrito 10
Teste2 X
MsgBox X ' Será escrito 20
End Sub

33
Microsoft© Access Avançado

Sub Teste2(ByRef G As Integer)


MsgBox G ' Será escrito 10
G = 20
MsgBox G ' Será escrito 20
End Sub

As palavras-chave ByRef e ByVal definem o tipo de passagem de argumento. O


padrão no VBA é ByRef, ou seja, se você não especificar nada, assume a passagem por
referência.
Entretanto, ByVal e ByRef sozinhos não garantem que os argumentos sejam passados
por valor e pro referência, respectivamente. O modo de chamada também define o tipo de
passagem.
Se na chamada do procedimento os argumentos forem passados entre parênteses,
então a passagem é por valor, independentemente de ByRef e ByVal.
Sub Teste1()
Dim X As Integer
X = 10
MsgBox X ' Será escrito 10
Teste2(X) ' Os parênteses definem que a passagem é por valor
MsgBox X ' Será escrito 10
End Sub

Sub Teste2(ByRef G As Integer)


MsgBox G ' Será escrito 10
G = 20
MsgBox G ' Será escrito 20
End Sub

Se na chamada do procedimento os argumentos não forem passados entre parênteses,


então o tipo de passagem será definido por ByRef e ByVal. Lembrando que ByRef é o padrão
do VBA.
Sub Teste1()
Dim X As Integer
X = 10
MsgBox X ' Será escrito 10
Teste2 X ' O tipo de passagem dependerá de ByRef ou ByVal
MsgBox X ' Será escrito 10
End Sub

Sub Teste2(ByVal G As Integer)


MsgBox G ' Será escrito 10
G = 20
MsgBox G ' Será escrito 20
End Sub

*****

34
Microsoft© Access Avançado

4. MÓDULO DE CLASSE EM FORMULÁRIO/RELATÓRIO


Cada formulário e relatório pode conter apenas um módulo. Este módulo é do tipo
módulo de classe. Este módulo não aparece como um objeto na guia de Módulos, pois fica
embutido no formulário/relatório. Por isso, ele era chamado Code Behind Form.
Os procedimentos estão relacionados a eventos do formulário, do relatório ou dos
controles do formulário (controles de relatório não geram evento). Os procedimentos são
criados no modo estrutura do formulário/relatório. No modo estrutura, com um objeto
selecionado, por exemplo o botão de comando cmdOk, na guia Eventos da janela de
propriedades seleciona-se o evento ao qual o procedimento estará associado. O evento pode
chamar uma macro ou um procedimento em código VBA.

Escolhendo [Procedimento de evento] e clicando-se no botão do Construtor de


Código, uma janela de módulo, semelhante a uma janela de módulo padrão, irá se abrir.
O nome do procedimento é gerado automaticamente. Ele é formado pelo nome do
objeto e pelo evento, separado por um sublinhado ( _ ). Por exemplo, para o controle
cmdCancel e evento Clicar o nome do procedimento é cmdCancel_Click.
Um código comum associado ao clicar sobre o botão Cancel é o do fechamento do
formulário corrente.

Private Sub cmdCancel_Click(Cancel As Integer)

35
Microsoft© Access Avançado

DoCmd.Close
End Sub

O procedimento de módulo de formulário ou de relatório só é executado quando o


evento do objeto associado ao procedimento ocorrer.
Como os procedimentos de evento recebem o nome do controle e do evento, é
extremamente recomendável não usar os nomes padrão fornecido pelo Access (Texto1,
Comando2, ect). Deve-se nomear os controles com um nome significativo na guia Outra da
janela de Propriedades.
Algumas das características vistas no módulo padrão se aplicam também no módulo
de classe, dentre elas: Compilação, execução passo-a-passo, ponto de interrupção e inspeção
de variáveis.

4.1. Coleções e Objetos de Formulário/Relatório

Formulários, relatórios e controles são objetos do Access e, portanto, possuem


propriedades, métodos e eventos. As propriedades e os eventos são acessíveis no modo
estrutura do formulário/relatório, na janela de Propriedades. Alterando-se as propriedades no
modo estrutura, os valores tornam-se estáticos. Por exemplo, se se define a Legenda do
formulário como “Menu Principal”, ela só pode ser alterada novamente no modo estrutura

NOTA: Controles de relatórios não possuem eventos.

Via programação, podemos ter acesso às propriedades dos objetos. Os valores das
propriedades podem ser alterados dinamicamente, durante a execução do código. A
programação permite também que os métodos dos objetos sejam invocados, algo que não é
possível no modo estrutura.
Todos os formulários do banco de dados formam a coleção de formulários. Todos os
relatórios do banco de dados formam a coleção de relatórios. Uma coleção é um objeto que
contém objetos de um mesmo tipo. Eis as coleções do Access.
Coleção Descrição
Forms Coleção de formulários abertos
Reports Coleção de relatórios abertos
Controls Coleção de controles em formulários ou relatórios abertos
Modules Coleção de módulos padrão e módulose de classe (inclusive módulos de classe
de formulário e de relatório)

A hierarquia completa dos objetos do Access é mostrada na figura abaixo:

36
Microsoft© Access Avançado

Por ser um objeto, cada coleção possui também propriedades e métodos.


Para referenciar um objeto específico de uma coleção, pode-se usar quatro formas
diferentes:
Coleção(número do item)
Coleção(“Nome do item”)
Coleção![Nome do item]
Coleção.Item(número do item]

A primeira e a última forma têm a desvantagem de ter que saber qual o número do
item dentro da coleção. Se existem vários formulários num banco de dados, cada um deles
recebe um número sequencial, começando do zero (0). Na última forma, Item é uma
propriedade da coleção.
As duas outras formas são mais compreeensíveis e mais fáceis de usar porque já
sabemos o nome do item.
Por exemplo, para referir a um formulário específico chamado frmPedidos, use a
expressão:
Forms![frmPedidos] ou Forms(“frmPedidos”)
Para referir-se a um relatórios chamado rptLista_de_Produtos, use a expressão:
Reports![rptLista_de_Produtos] ou Reports(“rptLista_de_Produtos”)
Para referir-se a um controle chamado txtPreçoUnitário, no formulário frmPedidos,
use a expressão:
Forms![frmPedidos]![txtPreçoUnitário]

37
Microsoft© Access Avançado

Se o código estiver sendo escrito atrás do formulário frmPedidos, não é necessário


referir-se a ele mesmo como Forms![frmPedidos], mas simplesmente como Me!. Assim, a
referência ao controle txtPreçoUnitário pode ser simplificado para Me![txtPreçoUnitário].
NOTA: O objeto Form referencia formulários abertos. Formulários fechados são
referenciados pelo objeto Document da hierarquia de objetos do DAO – Data Access Objects.

4.2. Propriedades e Métodos


Se em vez de querer acessar um controle do formulário você quiser acessar suas
propriedades ou invocar seus métodos, use a expressão:
Forms![frmPedidos].Caption
ou simplesmente
Me.Caption
Para acessar uma propriedade de um controle ou invocar um de seus métodos, use a
expressão:
Forms![frmPedidos]![txtPreçoUnitário].BackColor
ou simplemente
Me![txtPreçoUnitário].BackColor
O caracter ! é usado para indicar que o próximo elemento é um item definido pelo
usuário e o ponto indica que o próximo elemento é uma propriedade ou método. Você pode
usar o ponto para substituir a !, se quiser. Portanto, Forms![frmPedidos] equivale a
Forms.[frmPedidos].
Ao escrever um código VBA, se a opção “Listar membros automaticamente” do editor
de código estivar acionada, será exibida uma lista das propriedades e métodos do objeto e os
controles do objeto.

Propriedade

Método

Controle

Algumas propriedades são somente para leitura, isto é, você não pode alterar o seu
valor, somente recurá-lo. Por exemplo, a propriedade Name é tipicamente uma propriedade
para somente leitura, já que o nome é fornecido ao salvar a estrutura de um objeto.

38
Microsoft© Access Avançado

Todas as propriedades visíveis na janela de propriedades na estrutura de um


formulário são acessíveis via programação. Entretanto, existem várias propriedades que são
acessíveis somente no modo programado e não podem ser acessados no modo estrtutura. Por
exemplo, a propriedade Hwnd de um formulário está disponível somente no modo
programado.

4.3. Coleção padrão e propriedade padrão


Um objeto pode conter coleções. Um objeto formulário, por exemplo, contém a
coleção Controls. À rigor, a referência a um controle de um formulário deveria ser:
Forms![frmPedidos].Controls![txtPreçoUnitário]

Mas como a coleção Controls é a coleção padrão do objeto Form, não é necessário
mencioná-lo.
Os objetos possuem várias propriedades, mas uma delas é a propriedade padrão. Por
exemplo, o controle caixa de texto possui a propriedade Text (o conteúdo da caixa de texto)
como padrão. Assim, pode-se omitir esta propriedade.
Forms![frmPedidos]![txtPreçoUnitário].Text = 3.00
equivale a
Forms![frmPedidos]![txtPreçoUnitário] = 3.00

4.4. Propriedades de Coleção


As coleções Forms, Reports e Controls possuem apenas propriedades, mas não
métodos. As propriedades são:
Application Retorna o objeto Application, no caso, o Microsoft Access. Somente
leitura. Como o retorno é um objeto, deve ser usado como Set obj =
object.Application
Sub ApplicationProperty( )
Dim obj As Object
Set obj = Forms.Application ' Retorna o objeto
Microsoft Access
End Sub

Count Retorna a quantidade de objetos da coleção. Somente leitura.


Sub CountProperty( )
Dim intForms As Integer
IntForms = Forms.Count
End Sub

Item Retorna o objeto em uma determinada posição ou índice dentro da coleção.


Somente leitura.
Sub ItemProperty( )
Dim obj As Object

39
Microsoft© Access Avançado

Set obj = Forms.Item(0) ' Retorna o primeiro objeto


form aberto
End Sub

Parent Retorna o objeto superior. Somente leitura. Como o retorno é um objeto,


deve ser usado como Set obj = object.Parent.
Sub ApplicationProperty( )
Dim obj As Object
Set obj = Me.Controls(”txtCodigo”).Parent ' Retorna o
objeto form atual
End Sub

4.5. Seções de Formulário/Relatório


As seções dos formulários e relatórios são objetos, da mesma forma que controles. As
seções possuem propriedades e eventos, mas não métodos.
Deve-se tomar cuidado, pois, assim como os controles, o nome destes objetos é dado
automaticamente pelo Access, entretanto, não se justifica alterá-los. Na versão em inglês, os
nomes padrão são: FormHeader, FormFooter, Detail, PageHeader e PageFooter.
As propriedades e métodos das seções podem ser acessadas via programação,
entretanto, as seções PageHeader e PageFooter de relatórios não possuem propriedades nem
eventos que possam ser acessados via programação.

4.6. Eventos de Formulário

Eis alguns dos eventos de formulário para os quais pode-se definir código:
Evento Descrição
NoAtual (OnCurrent) O evento NoAtual ocorre quando o foco é movido para um registro,
tornando-o o registro atual, ou quando o formulário é aberto ou atualizado
ou quando sua consulta é repetida.

O Microsoft Access executa a macro ou procedimento de evento Current


antes de o primeiro ou próximo registro ser exibido.
Ao executar uma macro ou procedimento de evento quando ocorre o evento
Current de um formulário, é possível exibir uma mensagem ou sincronizar
registros em um outro formulário relacionado ao registro atual. Por
exemplo, quando o registro de um cliente torna-se o atual, você pode exibir
o pedido anterior do cliente. Quando o registro de um fornecedor torna-se o
atual, é possível exibir os produtos fabricados pelo fornecedor em um
formulário Fornecedores. Você também pode efetuar cálculos com base no
registro atual ou alterar o formulário em resposta aos dados desse registro.

40
Microsoft© Access Avançado

Se a sua macro ou procedimento de evento executar uma ação


IrParaControle ou IrParaRegistro ou o método correspondente do objeto
DoCmd em resposta a um evento Open, ocorrerá o evento Current.
O evento Current também ocorre quando você atualiza um formulário ou
repete a tabela ou consulta base do formulário — por exemplo, quando
você clica em Remover Filtro/Classificação no menu Registros ou utiliza a
ação RepetirConsulta em uma macro ou o método Requery em código do
Visual Basic.

Quando você abre um formulário pela primeira vez, os eventos ocorrem na


ordem a seguir:

Open  Load  Resize  Activate  Current


Antes de Inserir (BeforeInsert) Ocorre quando o usuário digita o primeiro caractere de um novo registro,
mas antes de realmente o registro ser gravado. A ordem dos eventos é:
BeforeInsert  BeforeUpdate  AfterUpdate  AfterInsert
Após Inserir (AfterInsert) Ocorre quando o registro passa a ser um novo registro.
Antes de Atualizar Ocorre quando o usuário atualiza o registro
(BeforeUpdate)
Após Atualizar (AfterUpdate) Ocorre quando o registro é atualizado
Ao Excluir (OnDelete) Ocorre quando o usuário tecla DEL em um ou mais registros.
Confirmar Antes de Excluir Ocorre antes de o registro ser efetivametne excluído, quando o MS Access
(BeforeDelConfirm) apresenta a mensagem de confirmação da exclusão
Após Confirmar Exclusão Ocorre após a confirmação da exclusão do registro.
(AfterDelConfirm)
Ao Abrir (OnOpen) Ocorre ao abrir o formulário. A ordem dos eventos é:
Open  Load  Resize  Activate  Current
Ao Carregar (OnLoad) Ocorre após o formulário ser aberto e carregar os dados para exibição.
Ao Redimensionar (OnResize) Ocorre ao redimensionar a janela do formulário.
Ao Descarregar (OnUnload) Ocorre antes de o formulário ser fechado, mas antes de ele ser removido da
tela. A ordem dos eventos é:
Unload Deactivate Close
Ao Fechar (OnClose) Ocorre ao fechar o formulário.
Ao Ativar (OnActivate) Ocorre quando a janela torna-se ativa, mas antes dela receber foco.
Ao Desativar (OnDeactivate) Ocorre antes de a janela perder o foco.
Ao Receber Foco (OnGotFocus) Ocorre após a janela se tornar ativa.
Ao Perder Foco (OnLostFocus) Ocorre ao perde o foco da janela.
Ao Clicar (OnClick) Ocorre ao clicar o botão esquerdo do mouse sobre o formulário.

41
Microsoft© Access Avançado

5. ELEMENTOS DE PROGRAMAÇÃO

Como qualquer outra linguagem de programação, o VBA implementa:


• Variáveis (simples e compostas)
• Constantes
• Vetores e matrizes
• Comentários
• Instruções de controle de estrutura de repetição
• Instruções de controle de estrutura condicional
• Instruções de entrada
• Instruções de saída
• Funções

O VBA permite ainda utilizar-se de objetos e coleções do próprio MS Access


(Application, Forms/Form, Reports/Report, Controls/Control, Modules/Module, Screen e
DoCmd) ou de outras aplicações que suportem a automação (como os aplicativos do MS
Office) ou de controles ActiveX (atualmente chamados de COM – Component Object
Model).

5.1. VARIÁVEIS
Variável é um local da memória RAM do computador que armazena um valor até que
um novo valor seja armazenado ou até que a rotina se encerre. A posição de memória é
referida por um identificador, que nada mais é que um nome que aponta para o endereço de
memória.

5.1.1. Declaração

Em algoritmo, a declaração das variáveis segue a sintaxe:

Declare nome_da_variável tipo

Onde, declare é uma instrução, nome_da_variável é o nome que referencia a posição


de memória onde será armazenada um dado e tipo é o tipo de dado, podendo ser literal,
numérico ou lógico.
No VBA, a principal instrução para declaração de variáveis é a Dim, seguindo a
sintaxe:

Dim {nome_da_variável} As {tipo}

Os tipos de dados aceitos no VBA são:

42
Microsoft© Access Avançado

Tipo de dados Tamanho de Intervalo


Armazename
nto
Byte 1 byte 0 a 255
Boolean 2 bytes True ou False
Integer 2 bytes -32.768 a 32.767
Long (inteiro longo) 4 bytes -2.147.483.648 a 2.147.483.647
Single (vírgula flutuante de 4 bytes -3,402823E38 a -1,401298E-45 para
precisão simples) valores negativos; 1,401298E-45 a
3,402823E38 para valores positivos
Double (vírgula flutuante 8 bytes -1,769313486232E308 a -
de precisão dupla) 4,94065645841247E-324 para valores
negativos; 4,94065645841247E-324 a
1,769313486232E308 para valores
positivos
Currency (inteiro escalado) 8 bytes -922.337.203.685.477,5808 a
922.337.203.685.477,5807
Decimal 14 bytes +/-
79.228.162.514.264.337.593.543.950.335
sem ponto decimal; +/-
7,9228162514264337593543950335 com
28 casas decimais à direita; o menor
número diferente de zero é +/-
0,0000000000000000000000000001.
Date 8 bytes De 1º de Janeiro de 100 até 31 de
Dezembro de 9999
Object 4 bytes Qualquer referência a Object
String (comprimento da 10 bytes + De 0 até aproximadamente 2 bilhões
variável) comprimento
da seqüência
de caracteres
String (comprimento fixo) Comprimento De 1 até aproximadamente 65.400
da seqüência
de caracteres
Variant (com números) 16 bytes Qualquer valor numérico até o intervalo de
um Double
Variant (com caracteres) 22 bytes + O mesmo intervalo que String de
comprimento comprimento variável
da seqüência
de caracteres
Definido pelo usuário Número O intervalo de cada elemento é o mesmo
(usando Type) requerido por que o intervalo do seu tipo de dados.
elementos

43
Microsoft© Access Avançado

Recomenda-se que os nomes das variáveis sigam o padrão de nomenclatura LNC (ver
Apêndice A). Os nomes de variáveis, assim como o de constantes e procedimentos:
• Podem ter até 255 caracteres.
• Precisam começar com uma letra.
• Podem incluir letras, números ou caracteres sublinhados (_).
• Não podem incluir caracteres de pontuação ou espaços.
• Não podem ser uma palavra reservada do Visual Basic.

Uma palavra reservada é uma palavra que o Visual Basic utiliza como parte de sua
linguagem. Isso inclui instruções (como If e Loop), funções (como Len e Abs), operadores
(como Or e Mod), palavras-chave, cláusulas SQL e propriedades e métodos de objetos.
Exemplos:
Dim strNomeEmpregado As String
Dim intIdade As Integer
Dim dblValorFatura As Double

5.1.2. Atribuição de valores à variáveis

Em algoritmo, a atribuição de valor a uma variável é:


nome_da_variável ← {valor}

No VBA, a atribuição é feita pelo sinal =.


Exemplos:

strNomeEmpregado = “CARLOS KOGA”


intIdade = 25
curPreco = 45.76

Se o tipo da variável for um objeto, a atribuição deve ser precedida pela instrução Set.

Dim dbsBanco As Database ' Objeto Database do DAO


Set dbsBanco = DBEngine.WorkSpaces(0).Databases(0)

O valor atribuído tem que ser coerente com o tipo de dado da variável. Assim, se
intIdade é do tipo inteiro, ocorrerá um erro se for atribuído um valor fracionário ou um valor
fora do intervalo de valores permitidos.

intIdade = 25.5 ' Erro! O tipo é inteiro


intNúmeroNatural = 32768 ' Erro! O valor é maior que 32767

44
Microsoft© Access Avançado

5.2. CONSTANTES

As constantes podem ser de três tipos:


• Constantes simbólicas, que você cria utilizando a instrução Const e utiliza em módulos.
• Constantes intrínsecas, que fazem parte do Microsoft Access ou de uma biblioteca
referenciada.
• Constantes definidas pelo sistema: True, False e Null.

5.2.1. Constantes Simbólicas

Freqüentemente, você terá que utilizar os mesmos valores repetidamente no seu


código ou descobrirá que o código depende de certos números que não têm significado óbvio.
Nesses casos, você pode tornar o código bem mais fácil de ler e de manter utilizando
constantes simbólicas (também chamadas de constantes definidas pelo usuário), que permitem
que você utilize um nome significativo no lugar de um número ou seqüência.
Uma vez que você tenha criado uma constante utilizando a instrução Const, você não
poderá modificá-la ou atribuir um novo valor a ela. Você não pode também criar uma
constante que tenha o mesmo nome que uma constante intrínseca.
Os exemplos a seguir mostram algumas das maneiras pelas quais você pode utilizar a
instrução Const para declarar constantes numéricas e de seqüência:

Const conPI = 3.14159265 ' Pi é igual a este número.


Const conPI2 = conPI * 2 ' Uma constante para criar outra.
Const conVersão = "Versão 7.0" ' Uma constante de seqüência.

5.2.2. Constantes Intrínsecas

Além das constantes que você declara com a instrução Const, o Microsoft Access
declara automaticamente várias constantes intrínsecas e oferece acesso às constantes do VBA
e às constantes de objetos referenciados no código.
Qualquer constante intrínseca pode ser utilizada em uma macro ou no Visual Basic.
Essas constantes estão disponíveis o tempo todo.
As constantes intrínsecas têm um prefixo de duas letras identificando a biblioteca de
objetos que define a constante. As constantes da biblioteca Microsoft Access são iniciadas
com "ac"; as constantes da biblioteca DAO são iniciadas com "db" e as constantes da
biblioteca VBA são iniciadas com "vb". Por exemplo:

acForm
dbAppendOnly
vbCurrency

45
Microsoft© Access Avançado

Observação: Como os valores representados pelas constantes intrínsecas poderão ser


alterados em versões futuras do Microsoft Access, você deve utilizar as constantes em vez de
seus valores reais.
Você pode utilizar constantes intrínsecas sempre que puder utilizar constantes
simbólicas, inclusive em expressões. O exemplo a seguir mostra como você poderia utilizar a
constante intrínseca vbCurrency para determinar se varNúm é do tipo Variant para a qual a
função VarType retorna 6 (tipo Currency):

Dim varNúm As Variant


If VarType(varNúm) = vbCurrency Then
Debug.Print "varNúm contém dados do tipo Currency."
Else
Debug.Print "varNúm não contém dados do tipo Currency."
End If

Existem várias categorias de constantes intrínsecas. Para ver uma lista de constantes
intrínsecas em uma determina categoria. Consulte no Help do Access os tópicos abaixo:

• As constantes de ação (do objeto DoCmd)


• As constantes DAO (Data Access Object)
• As constantes de procedimento de evento
• As constantes de Código de Tecla
• As constantes diversas
• As constantes do método RunCommand (constituem um subconjunto das constantes de
ação)
• As constantes de segurança
• As constantes do Visual Basic
• As constantes da função VarType

5.2.3. Constantes Definidas pelo Sistema

As constantes definidas pelo sistema são os valores lógicos True e False e a ausência
de valor Null. Assim como as constrantes intrínsecas, elas também não precisam ser
declaradas com a instrução Const.
Você pode usar estas constantes em qualquer lugar do Access, tais como em consultas,
macros, variáveis e propriedades de objetos.

46
Microsoft© Access Avançado

5.3. VETORES E MATRIZES

As matrizes suportam de 1 até 60 dimensões. A matriz de apenas uma dimensão é


chamada de vetor.
A declaração das dimensões e dos intervalos de cada dimensão é feita com a instrução
Dim, seguindo a sintaxe:

Dim nomedavariável([ [LimiteInferior To] [LimiteSuperior] [,LimiteInferior To] Limite


Superior] ....] ) As tipo

' Matriz de uma dimensão (vetor) com 5 elementos


Dim intMatriz1( 1 To 5) As Integer

' Matriz de duas dimensões. A primeira com 10 e a segunda com 6 elementos


' O tamanho da string de cada elemento é variável.
Dim strMatriz2( 1 To 10, 1 To 6) as String

' Matriz de 3 dimensões. O número de elementos depende da instrução Option


Base na seção de declarações. O tamanho da string de cada elemento é 50.
Dim strMatriz3( 5, 4 , 3) As String * 50

Se o limite inferior de uma dimensão não for explicitada, assume o valor padrão
declarado pela instrução Option Base. Option Base é colocada na seção de declarações do
módulo. Se Option Base for omitido, o limite inferior é 0. Para iniciar em 1, declara-se Option
Base 1. Para explicitar o início em 0, declara-se Option Base 0.
Uma das características do VBA é a declaração de matrizes dinâmicas, ou seja, o
intervalo dos subscritos e o número de dimensões podem ser alterados conforme a
necessidade que surgir durante o processamento.
Matriz dinâmica é declarada sem especificar as dimensões, nem limites.

Dim intDinamica() As Integer

O redimensionamento é feito instrução Redim.


Redim intDinamica( 1 To 5, 1 To 10)
Redim intDinamica(8, 7, 4)

Você pode também declarar uma matriz dinâmica com Redim, mas neste caso, exige-
se que os subscritos tenham sido definidos. Este tipo de matriz pode ter seus intervalos
alterados (para maior ou menor), mas não se pode alterar o número de dimensões.

Redim A( ) As Integer ' Erro


Redim B(5, 2) As Integer ' OK
Redim B(3, 1) ' Ok
Redim B(5, 6, 10) ' Erro
Redim B(100) ' Erro
Redim B(100, 100) ' Ok

47
Microsoft© Access Avançado

5.4. TIPOS DEFINIDOS PELO USUÁRIO

A instrução Type define um tipo de dado a partir dos tipos básicos. Seu emprego
normalmente se aplica a um registro. Veja o exemplo.

Type RegistroDePessoal
strMatricula As String * 8
strNome As String * 35
strCodOrgao As String * 8
strCodCargo As String * 4
dtaDataNasc As Date
End Type

Dim MeuRegistro As RegistroDePessoal

MeuRegistro.strMatricula = “80106650”
MeuRegistro.strNome = “CARLOS KOGA”
MeuRegistro.dtaDataNasc = #06/10/1964#

5.5. ESTRUTURA DE REPETIÇÃO

O VBA possui as seguintes instruções de repetição:


For...Next
Do...Loop
While...Wend
For Each...Next

5.5.1. For..Next

A estrutura For...Next é suportada por várias linguagens, e não apresenta diferenças. A


sua sintaxe é:

For {contador} = {início}To {fim} [Step {passo}]


[instruções]
[Exit For]
[instruções]
Next [contador]

48
Microsoft© Access Avançado

5.5.2. Do..Loop

A estrutura Do...Loop implementa uma repetição enquanto uma condição for


verdadeira (while) ou até uma condição se tornar verdadeira (until). Também implementa as
saídas tanto de início quanto de final.
Na repetição enquanto uma condição for verdadeira, acrescenta-se a cláusula WHILE
{condição} após o DO (se for saída no início) ou após o LOOP (se for saída no final).

Sub WhileSaídaNoInício()
contador = 0
meuNúmero = 20
Do While meuNúmero > 10
meuNúmero = meuNúmero - 1
contador = contador + 1
Loop
MsgBox "O loop concluiu " & contador & " repetições."
End Sub

Sub WhileSaídaNoFinal()
contador = 0
meuNúmero = 9
Do
meuNúmero = meuNúmero - 1
contador = contador + 1
Loop While meuNúmero > 10
MsgBox "O loop concluiu " & contador & " repetições."
End Sub

Na repetição até que uma condição se torne verdadeira, acrescenta-se o UNTIL


{condição} após o DO (se for saída no início) ou após o LOOP (se for saída no final).

Sub UntilSaídaNoInício()
contador = 0
meuNúmero = 20
Do Until meuNúmero = 10
meuNúmero = meuNúmero - 1
contador = contador + 1
Loop
MsgBox "O loop concluiu " & contador & " repetições."
End Sub

Sub UntilSaídaNoFinal()
contador = 0
meuNúmero = 1
Do
meuNúmero = meuNúmero + 1
contador = contador + 1
Loop Until meuNúmero = 10
MsgBox "O loop concluiu " & contador & " repetições."
End Sub

49
Microsoft© Access Avançado

A saída da repetição pode ser forçada com a instrução Exit Do.

intContador = 0
Do While True
intContador = intContador + 1
if intContador > 10 Then
Exit Do
Endif
Loop

5.5.3. While..Wend

A estrutura While...Wend implementa somente a repetição enquanto uma condição for


verdadeira e não admite saída forçada. Pontanto, é melhor substituí-la pela Do...Loop.

While {condição}
[instruções]
Wend

5.5.4. For Each..Next

A instrução For Each...Next é uma variação do For..Next específica para elementos


dentro de matrizes ou de coleções de objetos.

Dim varNomesMeses As Variant


Dim strMes As String

varNomesMeses = Array("Janeiro", "Fevereiro", "Março", "Abril", _


"Maio", "Junho", "Julho", "Agosto", _
"Setembro", "Outubro", "Novembro", "Dezembro")
For Each strMes In varNomesMeses
Debug.Print strMes
Next

Neste outro exemplo, a coleção TableDefs possui vários objetos do tipo TableDef.
Cada objeto de definição de tabela possui a propriedade Name. A instrução For Each...Next
pode ser usada para listar todas as tabelas do banco de dados corrente.

Dim tdfsTabelas As TableDefs


Dim tdfTabela As TableDef

Set tbfsTabelas = CurrentDb.TableDefs

For Each tdfTabela In tdfsTabelas


Debug.Print tdfTabela.Name
Next

50
Microsoft© Access Avançado

Uma construção similar pode ser obtida com somente a instrução For...Next.

Dim tdfsTabelas As TableDefs


Dim tdfTabela As TableDef
Dim intContador As Integer

Set tbfsTabelas = CurrentDb.TableDefs

For intContador = 0 To tbfsTabelas.Count


Debug.Print tdfTabela(intContador).Name
Next

5.6. ESTRUTURA CONDICIONAL

If...Then...Else
Select Case
On...Goto
On..GoSub

As instruções On..Goto e On..GoSub não serão mostradas porque Select Case pode
substituí-las, gerando um código mais estruturado e flexível.

5.6.1. If...Then...Else

A estrutura condicional mais simples é:

If { condição } Then
[ instruções]
End If

Uma estrutura composta contém a cláusula Else:

If { condição } Then
[ instruções]
Else
[ instruções]
End If

A instrução IF..Then..Else admite ElseIfs aninhados.

If { condição } Then
[ instruções]

51
Microsoft© Access Avançado

Elseif { condição 2} Then


[ instruções]
Elseif { condição 3} Then
[ instruções]
Elseif { condição 4} Then
[ instruções]
Else
[ instruções]
End If

Dim Número, Dígitos, MinhaSeqüência


Número = 53 ' Inicializa a variável.
If Número < 10 Then
Dígitos = 1
ElseIf Número < 100 Then
' A condição avalia como True, então a próxima instrução é executada.
Dígitos = 2
Else
Dígitos = 3
End If

5.6.2. Select Case

O Select Case é semelhante aos ElseIfs aninhados.

Select Case expressãodeteste


[Case listadeexpressões-n
[instruções-n]] ...
[Case Else
[instruçõeselse]]
End Select

Dim Número As Integer


Número = 8 ' Inicializa a variável.
Select Case Número ' Avalia Número.
Case 1 To 5 ' Número entre 1 e 5.
Debug.Print "Entre 1 e 5"
' A seguinte é a única cláusula Case que avalia como True.
Case 6, 7, 8 ' Número entre 6 e 8.
Debug.Print "Entre 6 e 8"
Case Is > 8 And Número < 11 ' Número é 9 ou 10.
Debug.Print "Maior que 8"
Case Else ' Outros valores.
Debug.Print "Não entre 1 e 10"
End Select

52
Microsoft© Access Avançado

5.7. ENTRADA E SAÍDA DE DADOS

Para fazer a leitura de dados via teclado em algoritmo você usa a instrução Leia . Em
Clipper usa-se o comando @..GET para a sua implementação. Para a saída, o algoritmo usa a
instrução Escreva, a qual é implementada no Clipper com @..SAY.
No Clipper, tanto para entrada de dados quanto para a saída, usam-se os dois
comandos para construir uma tela para posicionar os campos na tela, de forma a criar uma
interface agradável e compreensível. No Access, há uma maneira mais fácil de efetuar a
entrada e saída de dados, sem programação: é o objeto formulário.
Tomemos por exemplo a função Extenso( ), cujo código é apresentado mais adiante. A
maioria das funções requer argumentos de entrada, neste caso, um valor monetário. Como
toda função, esta retorna o valor por extenso do valor informado. Tanto o argumento (entrada)
quanto o retorno da função (saída) podem ser colocados em um formulário.
O exemplo a seguir é um formulário simples, sem nenhuma fonte de dados. Por isso,
em suas propriedades estão desativados o seletor de registros, os botões de navegação e as
barras de rolagem.
Há dois controles caixa de texto: txtValor e txtExtenso. O primeiro é um controle não
acoplado, que receberá um valor monetário, e, por isso, está formatado com o tipo Moeda. O
segundo é um controle calculado que contém o dado Extenso([txtValor]). Quando este
receber o foco, chamará a função, levando o argumento txtValor e retornará uma string com o
valor por extenso.

53
Microsoft© Access Avançado

Este exemplo simples mostra claramente que um formulário pode ser usado como
entrada e saída, substituindo com vantagens os tradicionais comando de entrada via teclado e
de saída na tela.

5.7.1. Funções do VBA para entrada e saída

Às vezes você não quer usar um formulário para entrada e saída de dados. Você quer
usar instruções no VBA para receber um único campo e enviar uma mensagem na tela. Para
isto há a função InputBox e a função/instrução MsgBox.

Dim curValor As Currency


curValor = InputBox("Entre com o valor", "Valor monetário")
MsgBox Extenso(curValor), vbOKOnly, "Valor por Extenso"

A execução deste fragmento de código resulta em duas janelas, mostradas abaixo.

54
Microsoft© Access Avançado

Se se quer capturar a resposta do usuário, usa-se a função MsgBox em vez da


instrução. A sintaxe é a mesma, somente acrescenta-se a variável que receberá a resposta.

intResposta = MsgBox(Extenso(curValor), vbOKOnly, "Valor por Extenso")

InputBox e MsgBox não são sofisticados quanto um formulário. InputBox não pode
consistir um dado, usando por exemplo, um código VBA em módulo de formulário, nem
formatar (usando a propriedade Formato do controle Caixa de Texto).

5.7.2. Outros dispositivos de entrada e saída

Nem sempre a entrada de dados é via teclado. Pode ser via leitura de arquivo. A
entrada e gravação de dados em formato de tabela são tratados no tópico Acesso a Dados,
mais adiante. A leitura de dados de arquivos seqüenciais, randômicos e binários será vista
também em outro tópico (Acesso a Arquivos e Impressora).
Da mesma forma, a saída nem sempre é a tela de vídeo. O tópico Acesso a Arquivos e
Impressora mostrará como direcionar a saída para arquivos em disco ou para a impressora
local.
Há um outro local para onde a saída pode ser direcionada: a Janela Depurar. Esta
janela recebe a saída, a qual é visualizada quando a janela é aberta. A janela depurar serve
testar e depurar a lógica de um programa.
A saída para a janela depurar é feita pelo objeto Debug, do VBA, utilizando-se seu
único método: o Print. A janela depurar é aberta com Control-G.

Dim curValor As Currency


curValor = InputBox("Entre com o valor", "Valor monetário")
Debug.Print Extenso(curValor)

55
Microsoft© Access Avançado

5.8. COMENTÁRIOS
Um comentário são textos não executáveis, ou seja, não são entendidos como um
código de programação. Comentários servem para documentar e esclarecer uma rotina
complexas.
Uma linha de código torna-se um comentário se ela vier precedida de uma aspa
simples. Não é necessário que toda a linha seja um comentário; você acrescentar um
comentário após uma instrução.
' Toda esta linha é um comentário.
MsgBox "Teste" ' A partir daqui tudo que for escrito é comentário.

Todo comentário é escrito na cor verde por padrão. Você pode alterar a cor nas opções
do MS Access.

5.9. FUNÇÕES
O MS Access possui um rol muito grande de funções prontas. Como você já deve
saber, uma função é uma rotina que retorna um valor quando é chamada. A função pode
receber nenhum, um ou mais argumentos de entrada. A lista de argumentos é passada entre
parênteses após o nome da função. A função retorna somente um valor de um determinado
tipo, e portanto, toda chamada de função deve ser atribuída a uma variável. Exemplos:
Dim dtaDataDeHoje As Date
Dim intAscii As Integer
dtaData = Date()
intAscii = Char(“A”)
Existem funções do Visual Basic for Applications, do DAO – Data Access Object e
funções agregadas SQL. Apesar de todas poderem ser usadas no código VBA de uma
aplicação em MS Access, é importante saber a origem das funções, pois você não pode usá-
las em qualquer aplicativo. Por exemplo, se a função é do DAO, você só pode chamar a
função de estiver com o objeto DAO carregado. As funções do VBA podem ser usadas em
qualquer aplicação VBA, seja no MS Access, no MS Excel, MS Word, no MS PowerPoint ou
no MS Project.
As funções do VBA são classificadas segundo o finalidade. Os grupamentos são:
• Funções literais
• Funções matemáticas
• Funções financeiras
• Funções de data
• Funções de conversão

Você não deve confundir função com instrução. Normalmente, as instruções são da
cor azul e as funções aparecem na cor preta.
Funções do VBA podem ser usadas na construção de expressões SQL. Por exemplo:

56
Microsoft© Access Avançado

Dim strSql As String


strSql = "SELECT NúmeroDoPedido, DataDoPedido, DataDeEntrega, "
strSql = strSql + "DateDiff('d', [DataDoPedido], [DataDeEntrega] As Prazo "
strSql = strSql + "FROM Pedidos"
Me.RecordSource = strSql

Consulte a ajuda do MS Access para saber mais sobre funções.

5.10. ESCOPO DE IDENTIFICADORES

O escopo refere-se a disponibilidade dos identificadores (variáveis, constantes e


procedimentos) para uso por outros procedimentos. O escopo é definido quando se declara os
identificadores.
Existem dois níveis de escopo e dois de visibilidade que determinam onde e quando
um identificador é reconhecido (visível),

Níveis de escopo
• Nível de procedimento
• Nivel de módulo

Níveis de visibilidade
• Private
• Public

Escopo Private Public


Nível de procedimento Todas as variáveis e Não se aplica.
contantes declaradas em nível
de procedimento são Private,
ou seja, somente podem ser
acessadas dentro do
procedimento em que foram
declaradas. Estas variáveis
são também chamadas
variáveis locais

Sub Teste( )
Dim intK As Integer

Nível de módulo Todas as variáveis e Todas as variáveis e


constantes declaradas na constantes declaradas com a
seção de Declarações podem instrução Public na seção de
ser acessadas por todos os Declarações de um módulo
procedimentos daquele podem ser acessadas por
módulo. qualquer procedimento do
banco de dado.

57
Microsoft© Access Avançado

Option Compare Database


Option Explicit Option Compare Database
Dim intK As Integer Option Explicit
Public intK As Integer

Quanto aos identificadores de procedimento, o escopo é.

Tipo de módulo Escopo


Módulo de formulário/relatório Todos os procedimentos são Private, mesmo
que sejam usadas as instruções Private ou
Public. Isto tem lógica, já que são
procedimentos de evento, os quais devem
responder a somente os eventos dos objetos
formulário, relatório ou controle.
Módulo padrão Todos os procedimentos são Public, a não ser
que seja colocada a instrução Private antes da
declaração do procedimento.

Private Sub Teste()

5.11. OBJETO DoCmd

O objeto DoCmd é exclusivo do MS Access , portanto, você só pode utilizá-lo em


programação VBA dentro do MS Access . Este objeto não possui nenhuma propriedade nem
eventos, somente métodos. Os métodos executam ações do MS Access, tais como abrir um
formulário, executar uma macro, alterar o formato do cursor, etc.
Muitos dos métodos do objeto DoCmd requerem argumentos, alguns obrigatórios,
outros opcionais.
Consulte a ajuda do MS Access para saber os mais sobre o objeto DoCmd.

58
Microsoft© Access Avançado
6. LINGUAGEM SQL
As consultas criadas na guia Consultas da janela de Banco de Dados nada mais são
que instruções em linguagem SQL. A SQL – Structured Query Language (Linguagem
Estruturada de Consulta) foi desenvolvida pela IBM em meados da década de 10 e
padronizada pela ANSI (o padrão SQL ANSI-92). Fornecedores de software de banco de
dados costumam ter variações do padrão ANSI. A SQL do Microsoft SQL Server é o
Transact-SQL e o da Oracle é o PL/SQL. O Access utiliza uma variação da SQL ANSI,
chamada Microsoft Jet Database Engine SQL.
O Microsoft Jet Database Engine SQL é suportado no Microsoft Access e no
Microsoft Visual Basic.
A criação de consultas no MS Access é facilitada pela existência do modo Estrutura,
uma espécie de editor gráfico que torna a tarefa mais intuitiva e fácil.

Você pode criar consultas no modo SQL, escrevendo diretamente as instruções SQL.
Se você não tem conhecimento da linguagem SQL, poderá se familiarizar com ela criando
consultas no modo Estrutura e visualizando-a no modo SQL.

Tendo uma consulta criada na guia Consultas, você pode abrí-la interativamente pelo
botão Abrir da janela de Banco de Dados. O termo executar é mais apropriado que abrir. Via
programação, a consulta pode ser executada pelo método OpenQuery do objeto DoCmd.

59
Microsoft© Access Avançado
A compreensão da linguagem SQL permite desenvolver aplicações sofisticadas. Na
realidade, você pode construir uma aplicação inteira sem nenhuma consulta ter sido criada na
guia Consultas, porque:
• A propriedade Origem do Registro (RecordSource) de formulários e relatórios pode ter
como valor uma tabela ou uma instrução SQL (criada pelo construtor de consultas),
definidos em tempo de desenvolvimento (no modo Estrutura).
• O valor propriedade Origem do Registro de formulários e relatórios pode ser construído
em tempo de execução, passado-o na forma de uma expressão SQL para a propriedade
RecordSource do formulário ou relatório.
• Você pode substituir consultas de ação por expressões SQL criadas em tempo de
execução e executá-las pelo método RunSQL do objeto DoCmd.
• Você pode construir expressões SQL em tempo de execução e visualizar os dados por
meio de um formulário de consulta.
• Você pode construir expressões SQL em tempo de execução e acessar os dados pelo
método OpenRecordset do objeto Database do DAO.

Além do mais, o conhecimento da linguagem SQL é imprescindível para a criação de


consultas específicas SQL (União, Passagem e Definição de dados) e útil para desenvolver
programas para acessar dados em bancos de dados cliente/servidor como o MS SQL Server e
Oracle.

6.1. EXPRESSÃO SQL


Uma expressão SQL é uma cadeia de caracteres (string) contendo instruções SQL.
Sendo uma cadeia de caracteres, você pode construí-la em tempo de desenvolvimento ou de
execução e atribuí-la a uma variável do tipo String. A variável pode ser usada como
argumento ou ser atribuída à propriedade RecordSource de relatório ou formulário. Veja
alguns exemplos de expressão SQL.
Dim strSql As String
strSql = "DELET * FROM [Detalhes do Pedido]"
DoCmd.RunSql strSql

Dim strSql As String


Dim intNumeroPedido As Integer
IntNumeroPedido = InputBox("Qual o número do pedido?")
strSql = "SELECT NúmeroDoPedido, CódigoDoCliente, DataDoPedido, "
strSql = strSql & "DataDeEntrega, DataDeEnvio "
strSql = strSql & "FROM Pedidos WHERE NúmeroDoPedido " & intNumeroPedido
Me.RecordSource = strSql

No primeiro exemplo, a expressão é atribuída à variável strSql e passada como


argumento do método RunSql do objeto DoCmd. Trata-se de uma consulta de ação que
excluirá todos os registros da tabela Detalhes do Pedido. O nome da tabela está entre
colchetes porque possui espaços em seu nome.
No segundo exemplo, uma expressão é construída com o número do pedido sendo
informado em tempo de execução. A expressão é então atribuída à propriedade RecordSource
do formulário/relatório ao qual o módulo de classe pertence. Note os espaços no final de cada
atribuição de valor à variável strSql. Isto é necessário para que a sintaxe da instrução SQL
seja correta, senão ocorreria uma expressão como DataDeEntrega, DataDeEnvioFROM, o que
causaria um erro em tempo de execução.
60
Microsoft© Access Avançado
Apesar de mais trabalhoso, o uso de expressões SQL em programação em vez de criar
consultas na guia Consultas é mais seguro. Suponha que você cie uma consulta de ação que
exclua todos os registros de uma tabela. Qualquer pessoa pode abrir o banco de dados e
executá-la.
É claro que você poderia evitar isto definindo permissão em nível de usuário. De
qualquer forma, usar expressões SQL em programação dará mais flexibilidade e segurança a
sua aplicação.
NOTA: Toda sintaxe das expressões SQL é em inglês, não importa o idioma que você esteja
usando, inclusive nomes de funções e formato de data.

6.2. INSTRUÇÕES BÁSICAS SQL


Não se pretende aqui ensinar a linguagem SQL, mas sim passar noções, restritamente
do Microsoft Jet Database Engine SQL.
NOTA: Se você for programar no MS Visual Basic para acessar banco de dados do MS SQL
Server, deve usar a sintaxe do Transact-SQL.

A maneira mais fácil de se criar expressões SQL é construir a consulta na guia


Consultas, alternar para o modo SQL, selecionar todo o texto, copiar e colar no módulo para
contruir a expressão.
As consultas são agrupadas segundo a sua finalidade. Ao construir uma consulta pelo
modo Estrutura, tem-se 4 tipos básicos: Seleção, Atualização, Exclusão, Acréscimo e Criação
de tabela.
O quadro a seguir mostra quais instruções SQL caracterizam cada tipo de consulta:
Tipo de consulta Instrução SQL característica
Consulta seleção SELECT
Consulta atualização UPDATE
Consulta de exclusão DELETE
Consulta acréscimo INSERT INTO
Consulta criação de tabela SELECT INTO

6.2.1. Consulta Seleção


A consulta seleção é a mais comum de todas. Ela retorna um conjunto de dados vindos
de uma ou mais tabelas relacionadas. Quando se programa, este conjunto não é visível como
no modo Folha de Dados, mas fica na memória do computador para ser acessado. Os dados
também não podem ser alterados como ocorre no modo Folha de Dados, a não ser que você
execute métodos de inserção, atualização ou exclusão do objeto RecordSet.
A consulta seleção possui cláusulas e características específicas deste tipo de consulta
e também outras comuns aos demais tipos. Veremos aqui algumas das cláusulas e
características comuns mais detalhadamente para poupar mais explicações nas consultas
seguintes.
A sintaxe básica da consulta seleção começa com a instrução SELECT. Sua forma
mais simples é:

61
Microsoft© Access Avançado
SELECT {listadecampos |*} FROM {tabela}
Esta instrução retorna os campos selecionados em listadecampos ou todos os campos
se você utilizar o *. Todos os registros da tabela especificada por tabela são recuperados
porque não há uma cláusula de critério. Os campos são recuperados na ordem em que eles
foram escritos na listadecampos. Os campos são separados por vírgulas. Exemplos:
SELECT * FROM Pedidos
Esta instrução retorna todos os campos e todos os registros da tabela Pedidos.

SELECT CódigoDoProduto, NomeDoProduto, CódigoDoFornecedor FROM Produtos


Esta instrução retorna três campos e todos os registros da tabela Produtos.

A sintaxe completa é:

SELECT [predicado] { * | tabela.* | [tabela.]campo1 [AS alias1] [, [tabela.]campo2 [AS alias2] [, ...]]}
FROM expressãodetabela [, ...] [IN bancodedadosexterno]
[WHERE {critérioswhere} ]
[GROUP BY campo1 [, campo2] [,campoN... ] ]
[HAVING {critérioshaving} ]
[ORDER BY campo1 [ASC|DESC] [, campo2 [ASC|DESC] ] [,campoN [ASC|DESC] ... ] ]
[WITH OWNERACCESS OPTION]

A instrução SELECT extrai as colunas (campos) escolhidas, selecionando as linhas


(registros) que atendam aos critérios da cláusula WHERE e classifica (ORDER BY) em orde
crescente (ASC, que é o padrão) ou decrescente (DESC) ou agrupa (GROUP BY) as linhas
resultantes na ordem especificada.
A cláusula WITH OWNERACCS OPTION significa que o usuário que está
executando a consulta possui as mesmas permissões que o criador da consulta. Isto tem
sentido em um ambiente multi-usuário em que se definir segurança em nível de usuário.
Os argumentos da instrução são:
Argumento Descrição
Predicado Um dos predicados a seguir: ALL, DISTINCT, DISTINCTROW
ou TOP. Você utiliza o atributo para restringir o número de
registros retornados. Se nenhum for especificado, o padrão será
ALL.
* Especifica que todos os campos da tabela ou tabelas especificadas
estão selecionados.
Tabela O nome da tabela contendo os campos a partir dos quais os
registros são selecionados. É um argumento opcional. Você só
precisa definí-lo caso suas tabelas possuam o mesmo nome de
campo, como é o caso do campo PreçoUnitário, que consta das
tabelas Produto e Detalhes do Pedido do banco de dados
Northwind. Produto.PreçoUnitário, [Detalhes do
Pedido].PreçoUnitário
campo1, campo2, É a lista de campos a ser recuperada. Se você incluir mais de um
campoN campo, eles serão recuperados na ordem listada.
O campo pode ser uma expressão literal, matemática ou lógica.
Os nomes dos campos são usados nas cláusula ORDER BY para
62
Microsoft© Access Avançado
definir a ordem de classificação e na cláusula GROUP BY para
definir os grupamentos.
alias1, alias2, aliasN Os nomes a serem utilizados como cabeçalhos de coluna em lugar
dos nomes originais de coluna em tabela. Se omitido, assume o
valor da propriedade Legenda na estrutura da tabela. Caso a
propriedade Legenda esteja em branco, assume o nome do campo.
Se um dos campos for uma expressão e não for definido um alias, é
assumido Expr1, Expr2, Expr3 e assim por diante.
Você não pode usar alias nas clausulas ORDER BY nem em
GROUP BY.
Expressãodetabela O nome da tabela ou relacionamento de tabelas contendo os dados
que você deseja recuperar.
Bancodedadosexterno O nome do banco de dados que contém as tabelas em
expressãodetabela se elas não estiverem no banco de dados atual.
Critérioswhere É uma expressão lógica que filtra os registros que atendam ao
critério definido na expressão.
Critérioshaving É uma expressão lógica que filtra os registros após eles terem sidos
agrupados. A cláusula HAVING deve obrigatoriamente vir com a
cláusula GROPU BY.

Nomes de campos ou de tabelas ou de alias que possuam espaços devem vir entre
colchetes. Exemplo:
SELECT CD_Matric AS Matrícula, [Nome do empregado] AS Nome FROM [Cadstro de
Pessoal]

6.2.1.1. Argumento Predicado


O argumento predicado assume valores que são palavras reservadas da linguagem
SQL. Os predicados podem ser as seguintes palavras reservadas:
PREDICADO FINALIDADE
ALL Indica que serão selecionados todos os registros que atendam aos critérios da seleção. É
assumido se nenhum predicado for utilizado.
DISTINCT Omite registros que contêm dados duplicados em campos selecionados.
DISTINCTROW Omite dados com base em registros inteiramente duplicados e não somente campos
duplicados.
TOP n Retorna um número fixo de registros que ficam na parte superior ou inferior de um intervalo
[PERCENT] especificado por uma cláusula ORDER BY.

Para enteder o predicado, considere as tabelas:


CLIENTES
ID_CLIENTE NOME SOBRENOME DT_NASC CARGO
1 JOSE SANTOS 06/07/1956 001
2 PAULO VIANNA 07/09/1952 002
3 SIMONE CASTRO 10/11/1965 001
4 CARLOS SANTOS 21/01/1960 001
5 PENELOPE CHARMOSA 07/09/1952 002

63
Microsoft© Access Avançado
PEDIDOS
NR_PEDIDO ID_CLIENTE DATA VALOR
1 1 01/01/98 500,00
2 4 02/01/98 100,00
3 5 02/01/98 30,00
4 5 03/01/98 15,00
5 3 04/01/98 60,00
6 3 10/01/98 90,00
7 1 01/01/98 120,00

PREDICADO ALL
A consulta a seguir retornará todos os registros da tabela Clientes.
SELECT ALL Clientes.* FROM Clientes

é equivalente a
SELECT Clientes.* FROM Clientes

PREDICADO DISTINCT
A consulta a seguir omitirá um dos registros cujo sobrenome é SANTOS.
SELECT DISTINCT Clientes.SOBRENOME FROM Clientes

A consulta a seguir retornará todos os registros, pois DISTINCT não terá efeito porque há mais
de um campo selecionado.

SELECT DISTINCT Clientes.* FROM Clientes

PREDICADO DISTINCTROW
A consulta a seguir retornará todos os registros da tabela Clientes, exceto o cliente Paulo
Vianna.

SELECT DISTINCTROW Clientes.*


FROM Clientes INNER JOIN Pedidos
ON Clientes.ID_CLIENTE = Pedidos.ID_CLIENTE

Se o predicado DISTINCTROW não fosse usado, apareceriam múltiplas linhas para os clientes
com mais de um pedido.

Esta consulta a seguir não sofre o efeito de DISTINCTROW pois não existem registros repetidos,
já que NR_PEDIDO tem valor distinto em cada valor.

SELECT DISTINCTROW Clientes.*, Pedidos.NR_PEDIDO


FROM Clientes INNER JOIN Pedidos
ON Clientes.ID_CLIENTE = Pedidos.ID_CLIENTE

PREDICADO TOP

A consulta a seguir retornará os nomes dos 2 clientes mais idosos cujos cargos é 001.
SELECT TOP 2 NOME
FROM Clientes
WHERE CARGO ="001"
64
Microsoft© Access Avançado
ORDER BY DT_NASC

A consulta a seguir retornará os nomes de 2% dos clientes mais idosos, cujo cargo é 001.

SELECT TOP 2 NOME


FROM Clientes
WHERE CARGO ="001"
ORDER BY DT_NASC

O predicado TOP não distingue valores iguais. Portanto, a consulta a seguir retornará
dois registros e não somente um.
SELECT TOP 1 NOME
FROM Clientes
WHERE CARGO = "002"
ORDER BY DT_NASC

6.2.1.2. Expressões na lista de campos


Em qualquer dialeto da SQL é possível usar expressões literais, matemáticas ou
lógicas como se fosse um campo de uma tabela. Por exemplo:
SELECT CódigoDoProduto, PreçoUnitário, Quantidade, Desconto,
((PreçoUnitário * Quantidade) – (PreçoUnitário * Quantidade * Desconto)) AS
Subtotal
FROM [Detalhes do Pedido]

Não existe um campo subtotal na tabele Detalhes do Pedido. Ele é o alias da expressão
que calcula o subtotal de um item do pedido. Quando se usa expressão nas lista de campos,
ela se chama campo calculado.
Linguagens SQL como o Microsoft SQL Server possui funções próprias da linguagem
as quais podem ser usadas para criar campos calculados. A diferença do Microsoft Jet
Database Engine SQL é que você pode usar funções do próprio Microsoft Jet Database
Engine SQL, funções do VBA e funções definidas pelo usuário para criar campos calculados.
O Microsoft Jet Database Engine SQL possui a função agregada Avg() para calcular a
média de um valor.
SELECT Avg(PreçoUnitário) AS [Média de preços] FROM Produtos

O Microsoft Jet Database Engine SQL não possui a função WeekDay(), que é do
VBA. Mas você pode usá-la em expressões SQL que serão executadas no MS Access ou no
MS Visual Basic.
SELECT WeekDay(DataDoPedido) AS [Dia da semana] FROM Pedidos

Procedimentos do tipo Function, criadas em módulo padrão e com visibilidade Public,


podem ser usadas na contrução de campos calculados. Veja este exemplo:
SELECT NomeDoProduto, Fatura(Quantidade, PreçoUnitário) AS Valor
FROM [Detalhes do Pedido]

O código do procedimento Fatura fica alojado no módulo padrão.


Function Fatura(Qtd, PreçoUnit) As Currency
65
Microsoft© Access Avançado
If Qtd < 5 Then ' Não tem desconto
Fatura = Qtd * PreçoUnit
Else ' Tem desconto de 10% sobre a fatura
Fatura = (Qtd * PreçoUnit) * 0.90
End If
End Function

6.2.1.3. Argumento Expressãodetabela


O argumento de tabela pode ser apenas o nome de uma tabela, como no exemplo:
SELECT * FROM Produtos
Entretanto, ela pode ser composta por mais de uma tabela, como no exemplo:
SELECT NúmeroDoPedido, NomeDoProduto, [Detalhes do Pedido].PreçoUnitário,
Quantidade
FROM Produtos INNER JOIN [Detalhes do Pedido]
ON Produtos.CódigoDoProduto = [Detalhes do Pedido].CódigoDoProduto

No caso anterior, as tabelas Produtos e Detalhes do Pedido estão relacionadas pelo


campo CódigoDoProduto, que constam nas duas tabelas. Relembrando a modelagem de
dados, a cardinalidade entre Produtos e Detalhes do Pedido é uma-para-muitos.
CódigoDoProduto na tabela Produtos é chave primária (primary key) enquanto
CódigoDoProduto na tabela Detalhes do Pedido é chave estrangeira (foreing key).
A cláusula INNER JOIN especifica que há um relacionamento entre as tabelas, do tipo
de associação 1. No modo estrutura, o tipo de associação é definido na caixa de diálogo
mostrada a seguir.

Os tipos de associações são:


Tipo de Cláusula SQL Descrição Representação
associação do conjunto
1 INNER JOIN Inclui somente os registros
cujos valores dos campos
relacionados são iguais. Isto
quer dizer que retorna
somente os dados da
interseção entre as duas
66
Microsoft© Access Avançado
tabelas
2 LEFT JOIN Inclui todos os registros da
tabela à esquerda e somente
os registros da tabela à
direita quando os valores dos
campos relacionados forem
iguais.
3 RIGHT JOIN Inclui todos os registros da
tabela à direita e somente os
registros da tabela à esquerda
quando os valores dos
campos relacionados forem
iguais.

Dizer qual tabela está à direita e qual está à esquerda depende da ordem em que elas
são escritas na expressão. Se se quiser incluir todos os registros da tabela produtos, pode se
usar tanto LEFT JOIN quanto RIGHT JOIN, dependendo a ordem em que os nomes das
tabelas são escritas.
FROM Produtos LEFT JOIN [Detalhes do Pedido]
Isto equivale a:
FROM [Detalhes do Pedido] RIGHT JOIN Produtos
Naturalmente, a ordem da escrita dos nomes das tabelas não tem efetio quando se usa
INNER JOIN.
INNER JON, LEFT JOIN e RIGHT JOIN simplesmente diz quais tabelas e os tipos de
associações existentes entre elas, mas não define quais os campos relacionados. Após escrever
os nomes das tabelas e o tipo de associação, acrescenta-se a cláusula ON seguido dos campos
relacionados. No exemplo a seguir, as tabelas são relacionados pelo campo CódigoDoProduto
FROM Produtos INNER JOIN [Detalhes do Pedido]
ON Produtos.CódigoDoProduto = [Detalhes do Pedido].CódigoDoProduto

Note que como os nomes dos campos são iguais nas duas tabelas, é necessário colocar
o nome da tabela antes dos nomes dos campos, separados por ponto.
Normalmente o operador de comparação é o =. Mas você pode usar >, >=, <., <= ou
<>. Não é comum usar operadores que não seja o =, mas se você usá-los, o modo Estrutura
não consegue exibir este relacionamento.
Casos os relacionamento seja com dois ou mais campos, você deve usar o operador
lógico AND.
SELECT *
FROM Table1 INNER JOIN Table2
ON (Table1.B = Table2.B) AND (Table1.A = Table2.A)

Você pode mais de duas tabelas relacionadas. O modo de contrução é o mesmo.


SELECT *
FROM Produtos INNER JOIN (Pedidos INNER JOIN [Detalhes do Pedido]
ON Pedidos.NúmeroDoPedido = [Detalhes do Pedido].NúmeroDoPedido)
ON Produtos.CódigoDoProduto = [Detalhes do Pedido].CódigoDoProduto
67
Microsoft© Access Avançado

Note o uso de parênteses na junção entre Pedidos e Detalhes do Pedido. Somente


depois desta junção é feita a junção com Produtos.

6.2.1.4. Tabelas em banco de dados externos


Como você viu na introdução deste cursos, dados e processos residem em arquivos
diferentes. Você pode construir uma consulta ou uma expressão SQL para acessá-los sem ter
que vincular tabelas.
Isto é possível com a cláusula IN do SQL.
SELECT * FROM Clientes INNER JOIN Pedidos
ON Clientes.CódigoDoCliente = Pedidos.CódigoDoCliente
IN "D:\CursosOffice\AccessBasico\NW.mdb"

No caso, as duas tabelas devem estar no mesmo banco de dados. Você não pode
recuperar dados de tabelas em bancos de dados distintos.
Você pode acessar tabelas externas em formatos diferente, como Excel, Paradox ou
dBase. Você coloca duas aspas seguido dos argumentos Especificador e Origem do tipo de
arquivo. No capítulo sobe acesso a banco de dados há a lista completa dos argumentos para a
cláusula IN.
SELECT * from Customers
IN "" [Excel 8.0; DATABASE=C:\Book1.xls]

Para melhor desempenho, use tabelas vinculadas em vez da cláusula IN.

6.2.1.5. Cláusula Where


Enquanto o argumento listadecampos restringe quais campos devem ser recuperados,
a cláusula WHERE restringue quais linhas devem ser recuperadas. A cláuslua WHERE define
uma expressão lógica sob a qual cada registro é validado. Se atender à condição imposta pela
expressão lógica, o registro é recuperado, caso contrário é desprezado.
Operadores lógicos
A expressão lógica pode conter os um ou mais dos seguintes operadores relacionais:
= (igual)
< (menor)
<= (menor ou igual)
> (maior)
>= (maior ou igual)
<> (diferente)

Os operandos podem ser campos, campos calculados ou constantes que, se forem do


mesmo tipo de dados, podem ser comparados com um dos operadores relacionais.
No Microsoft Jet Database Engine SQL não se admite variáveis na expressão lógica.
Se você utilizar uma variável e criar a consulta, esta será assumida como um parâmetro da
consulta. Se tentar usar variável em expressão SQL, tal colocação acarretará em erro em
tempo de execução.

68
Microsoft© Access Avançado
Você pode usar variáveis em expressão SQL por meio de um artifício, como mostrado
abaixo.
Dim strSql As String
Dim intNumeroPedido As Integer
IntNumeroPedido = InputBox("Qual o número do pedido?")
strSql = "SELECT NúmeroDoPedido, CódigoDoCliente, DataDoPedido, "
strSql = strSql & "DataDeEntrega, DataDeEnvio "
strSql = strSql & "FROM Pedidos WHERE NúmeroDoPedido " & intNumeroPedido

A consulta a seguir recuperará todos os campos da tabela Produtos, retornando


somente os registros cujo valor unitário (campo PreçoUnitário) seja maior que 10.
SELECT * FROM Produtos WHERE PreçoUnitário > 10
Note que a comparação é entre um campo e uma constante. Apesar de o campo ser do
tipo moeda (currency) o valor da constante não contém o símbolo da unidade monetária R$.
Operadores lógicos
Se for necessário fazer mais comparações, você pode utilizar-se dos operadores
lógicos AND, OR e NOT. A comparação se faz entre dois operandos de cada vez. Você não
pode ter uma expressão do tipo A > B > C. Ela deve ser escrita da forma A > B AND B > C
SELECT * FROM Produtos WHERE PreçoUnitário > 10 AND NOT Descontinuado

Operadores IN, BETWEEN e LIKE


Além dos operadores relacionais e dos operadores lógicos, você pode operadores IN,
BETWEEN e LIKE
IN significa contido em um conjunto discreto de valores. Por exemplo, In (“A+”,
“B+”, “O+”, “AB+”) especifica um critério que seleciona somente os de tipo sangüíneo RH
positivo. Não confunda o operador IN com a instrução IN.
SELECT * FROM [Detalhes do Pedido]
WHERE CódigoDoProduto IN(14,24,48,55)

Between filtra os valores que estão dentro de um conjunto contínuo de valores. Por
exemplo, Between 1000 AND 5000 seleciona os registros cujo valor de um campo esteja
entre 1000 e 5000, inclusive.
SELECT * FROM Pedidos
WHERE DataDoPedido BETWEEN #01/31/95# AND #05/15/95#

Like permite um comparação parcial de string, conforme a máscara de comparação.


Pode-se usara caracteres especiais na máscara.
Caracter Função Máscara Retorna
* Retorna caracteres o*o ovo, Ocaso, osso, OTELO
múltiplos *ab* abc, Abdomem, cabeça
*ANA Fabiana, cana, CABANA
k* Katana, kibe, kamikaze
? Retorna carater simples o?o Oco, ovo, OMO
# Retorna dígito simples MI# Mi6, mi2, MI0
[] Retorna intervalo de b[a-m] Ba, bb, BC, BJ, bf
valores

69
Microsoft© Access Avançado
[!] Retorna valores fora do b[!a-m] bx, BW, BV
intervalo A[!0-9] AA, A$, ac, A+

SELECT * FROM Clientes


WHERE NomeDoContato LIKE "mar*"

Outras expressões
A expressão lógica da cláusula WHERE pode conter ainda as constantes definidas
pelo sistema True e False, expressões (como Is Null), funções do VBA e funções definidas
pelo usuário.
SELECT * FROM Funcionarios
WHERE False

SELECT * FROM Pedidos


WHERE DateDiff("d”, DataDoPedido, DataDeEntrega) > 5

SELECT NomeDaEmpresa
FROM Clientes LEFT JOIN Pedidos
ON Clientes.CódigoDoCliente = Pedidos.CódigoDoCliente
WHERE NúmeroDoPedido Is Null

6.2.1.6. Funções agregadas SQL


Funcções agregadas SQL efetuam cálculos com um conjunto de registros, retornando
valores sumarizados. Por exemplo, se você quiser saber o valor total dos pedidos, terá de usar
a função agregada SUM. Você não saberá o valor de cada pedido, mas sim a soma de todos os
registros de pedidos.
As funções agregadas são:
FUNÇÃO FINALIDADE
AVG (Média) Calcula a média aritmética de um conjunto de valores contidos em um campo especificado
em uma consulta.
COUNT (Contar) Calcula o número de registros que retornam de uma consulta.
MAX (Máx) Retorna o valor máximo de um conjunto de valores contidos em um campo especificado em
uma consulta
MIN (Mín) Retorna o valor mínimo de um conjunto de valores contidos em um campo especificado em
uma consulta.
STDEV, Retorna a estimativa do desvio padrão de uma população ou de uma amostra de uma
STDEVP (Desv) população representada como um conjunto de valores contidos em um campo especificado
em uma consulta.
SUM (Soma) Retorna a soma de um conjunto de valores contidos em um campo especificado em uma
consulta.
VAR, VARP Retorna as estimativas da variância de uma população ou de uma amostra da população
(Var) representada como um conjunto de valores contidos em um campo especificado em uma
consulta.
FIRST Retorna o primeiro registro de um conjunto de registros retornado por uma consulta.
(Primeiro)
LAST (Último) Retorna o primeiro registro de um conjunto de registros retornado por uma consulta.

Exemplos:
SELECT COUNT(*) AS [Qtd Itens] FROM [Detalhes do Pedido]

70
Microsoft© Access Avançado
SELECT MIN(DateDiff("d”, DataDoPedido, DataDeEntrega)) AS [Prazo mínimo],
AVG(DateDiff("d”, DataDoPedido, DataDeEntrega)) AS [Prazo Médio],
MAX(DateDiff("d”, DataDoPedido, DataDeEntrega)) AS [Prazo Máximo]
FROM Pedidos

6.2.1.7. Cláusulas GROUP BY e HAVING


As cláusulas GROUP BY e HAVING são usadas em conjunto com as funções
agregadas SQL.
GROUP BY agrupa os registros por um ou mais campos. Por exemplo, se você quiser
saber o prazo médio de entrega de cada pedido, deve agrupar pelo campo do
NúmeroDoPedido
SELECT Pedidos.NúmeroDoPedido,
Avg(DateDiff("d",[DataDoPedido],[DataDeEntrega])) AS [Prazo Médio]
FROM Pedidos
GROUP BY Pedidos.NúmeroDoPedido

Todos os campos que aparecerem na lista de campos devem obrigatoriamente ser um


campo de agrupamento ou alvo de uma função SQL. A consulta abaixo falhará porque
DataDoPedido não faz parte de GROUP BY nem de uma função agregada.
SELECT NúmeroDoPedido, DataDoPedido,
Avg(DateDiff("d",[DataDoPedido],[DataDeEntrega])) AS [Prazo Médio]
FROM Pedidos
GROUP BY NúmeroDoPedido

A cláusula HAVING é semelhante ao WHERE, porém atua sobre os registros


retornados. O exemplo abaixo primeiramente calcula a média e depois filtra os registros cujas
médias sejam maior que 20.
SELECT NúmeroDoPedido, DataDoPedido,
Avg(DateDiff("d",[DataDoPedido],[DataDeEntrega])) AS [Prazo Médio]
FROM Pedidos
GROUP BY NúmeroDoPedido
HAVING Avg(DateDiff("d",[DataDoPedido],[DataDeEntrega])) > 20

A cláusula WHERE atua antes da agregação. No exemplo abaixo, a cláusula WHERE


primeiramente filtra somente os pedidos do ano 1996, depois é calculada a média e a cláusula
HAVING filtra os que ultrapassaram a média de 20 dias.
SELECT NúmeroDoPedido,
Avg(DateDiff("d",[DataDoPedido],[DataDeEntrega])) AS [Prazo Médio]
FROM Pedidos
WHERE Year(DataDoPedido) = 1996
GROUP BY NúmeroDoPedido
HAVING Avg(DateDiff("d",[DataDoPedido],[DataDeEntrega])) > 20

6.2.2. Consulta de atualização


A consulta de atualização não retorna nenhum conjunto de registros, mas sim atualiza
um ou mais campos de uma tabela ou mais tabelas.
UPDATE {expressãodetabela}
SET campo1 = valor1 [, campo2 = valor2] [, campoN = valorN]
71
Microsoft© Access Avançado
[WHERE {condiçãoWhere}]

No exemplo abaixo, os campos Via e Quantidade são atulizados. Os campos são de


tabelas distintas. A atualização afeta somente os itens de produtos descontinuados.

UPDATE Produtos INNER JOIN (


Pedidos INNER JOIN [Detalhes do Pedido]
ON Pedidos.NúmeroDoPedido = [Detalhes do Pedido].NúmeroDoPedido )
ON Produtos.CódigoDoProduto = [Detalhes do Pedido].CódigoDoProduto
SET Pedidos.Via = 1, [Detalhes do Pedido].Quantidade = 6
WHERE Descontinuado

6.2.3. Consulta de exclusão


A consulta de exclusão elimina os registros de uma única tabela. Se você não definir
uma condição na cláusula WHERE, todos os registros serão excluídos. A tabela de onde o
registros forem excluídos pode estar relacionada a outras tabelas.
DELETE [tabela.*]
FROM {expressãodetabela}
[WHERE {condiçãoWhere}]

Para excluir registros de uma única tabela, sem relacionamento, a sintaxe é:


DELETE * FROM {tabela}

Caso haja tabelas relacionadas, você deve especificar o nome da tabela de onde osz
registros devem ser excluídos. Exemplo:
DELETE [Detalhes do Pedido].*
FROM Produtos INNER JOIN [Detalhes do Pedido]
ON Produtos.CódigoDoProduto = [Detalhes do Pedido].CódigoDoProduto
WHERE Descontinuado
Se a tabela possuir integridade referencial do tipo resctrict, os registros não serão
excluídos. Se a integridade for do tipo cascade, os registros da tabela relacionada também
serão excluídos.

6.2.4. Consulta acréscimo


Você pode inserir um único registro em uma tabela ou vários registros provenientes de
uma seleção em outra tabela.
Para um único registro, a sintaxe é:
INSERT INTO {tabela} [(campo1, campo2, campoN, ...)]
VALUES (valor1, valor2, valorN, ...)

A identificação da lista de campos é opcional. Se você não a defnir, os valores serão


inseridos na mesma ordem em que os campos foram criados no modo Estrutura da tabela.
INSERT INTO Table1
VALUES ("0033", "PEG SUE", 2, "SP")

72
Microsoft© Access Avançado
Se definir a lista de campos, cada valor estará associado ao campo na ordem em que
foram digitados na instrução INSERT.

INSERT INTO Table1 (EstadoCivil, UF, Nome, Matricula)


VALUES ( 1, "MG", "CARLOS KOGA","0021")

Se você não especificar todos os campos da tabela, o campo omitido assumirá o valor
padrão ou nulo, caso as propriedades Valor padrão e Requerido estejam configurados na
estrutura da tabela. Suponha que os campos EstadoCivil possua a propriedade Requerido=Não
e UF possui a propriedade Valor Padrão = “MG”. As instruções abaixo inserirão dois
registros com o campo EstadoCivil como nulo e UF com “MG”.
INSERT INTO Table1 (Matricula, Nome)
VALUES ("0021", "CARLOS KOGA")

INSERT INTO Table1


VALUES ("0033", "PEG SUE")

Você pode explicitamente inserir nulo usando a constante NULL.


INSERT INTO Table1
VALUES ("0033", "PEG SUE", NULL)

A inserção deve respeitar todas as restrições da tabela, tais como unicidade de chave
primária, integridade referrencial, valor requerido, regra de validação, tamanho do campo e
compatibilidade de tipo de dados.
Você pode inserir registros em uma tabela com registros provenientes de outras
tabelas.
INSERT INTO {tabela} IN bancodedadosexterno
(campo1, campo2, campoN, . . .)
SELECT argumentosSelect

6.2.5. Consulta de criação de tabela

73
Microsoft© Access Avançado

7. FORMULÁRIOS AVANÇADOS
Os formulários podem ser usados como:
 Formulário de manutenção de tabelas
 Caixa de diálogo
 Formulário de consulta
 Caixa de mensagem

Formulários de manutenção de tabelas podem ser criadas facilmente pelo Assistente


de Formulário. Tais formulários, criados por Assistentes, são simples e carecem de
aprimoramento. Via programação, podemos aperfeiçoá-las, incluindo código de validação de
dados, controle de fluxo, botões de navegação personalizados, botões para inclusão de novos
registros, para exclusão de registros, para alteração de dados e para pesquisa.

7.1. FORMULÁRIO DE MANUTENÇÃO DE TABELAS

Um formulário simples, criado pelo Assistente de Formulário ou diretamente pelo


modo estrutura, possui uma fonte de dados - a propriedade Origem do registro
(RecordSource), e controles acoplados que se referem a cada um dos campos da origem do
registro. Controles acoplados possuem o nome do campo na propriedade Origem do controle
(ControlSource).
Os controles podem ser de diversos tipos, dependendo da característica do dado que o
campo contém, como por exemplo caixa de texto, caixa de combinação, caixa de verificação,
caixa de grupo, etc.
Você pode ter também controles calculados, cuja propriedade Origem do controle
contém uma expressão.
A navegação de registros, isto é, o avanço e retrocesso de registros pelo formulário, é
feita pelos Botões de navegação (NavigationButtons). Os botões de navegação incluem a
operação de inclusão de novos registros
As operações de filtragem, exclusão e pesquisa de registros e impressão do formulário
são realizadas pela barra de menus ou pela barra de ferramentas.
Note que todas as operações citadas acontecem a partir de uma única tela. Não há um
formulário específico para consulta, outro inclusão e outro para edição (alteração e exclusão).
Isto leva à pergunta: “Qual a melhor forma de construir formulários de manutenção de
tabelas?”. A resposta é sempre “Depende”.

7.1.1. Botões de Navegação Personalizados


Em vez de usar os botões de navegação do formulário, você pode criar botões
personalizados para navegar pelos registros. Basta criar botões de comando e vincular a
código VBA. A propriedade Botões de navegação do formulário é definida como Não.

74
Microsoft© Access Avançado

Private Sub cmdFirstRecord_Click()


DoCmd.RunCommand acCmdRecordsGoToFirst
End Sub

Private Sub cmdPreviousRecord_Click()


On Error Resume Next
DoCmd.RunCommand acCmdRecordsGoToPrevious
End Sub

Private Sub cmdNextRecord_Click()


On Error Resume Next
DoCmd.RunCommand acCmdRecordsGoToNext
End Sub

Private Sub cmdLastRecord_Click()


DoCmd.RunCommand acCmdRecordsGoToLast
End Sub

O botão de comando cmdPreviousRecord possui a linha On Error Resume Next para


que não ocorra erro ao tentar retroceder um registro quando se está no primeiro registro. O
botão de comando cmdPreviousRecord possui a linha On Error Resume Next para que não
ocorra erro ao tentar avançar um registro quando se está no último registro.
Há um erro de comportamento neste formulário. A navegação deveria ocorrer somente
com os botões personalizados. Entretanto, a tecla Tab, além de mudar de campo, muda de
registro quando se encontra no último campo. Para desabilitar esta caracterísitca, altere a
propriedade de formulário Ciclo (Cycle) para Registro corrente (Current Record).
Outro problema é que cmdNextRecord adiciona um registro ao tentar avançar além do
último registro. Para resolver isto, altere a propriedade de formulário Permitir adição (Allow
Additions) para Não.

75
Microsoft© Access Avançado
7.2. CAIXA DE DIÁLOGO
Uma caixa de diálogo serve para captar dados que serão enviados como parâmetros de
procedimento, consulta, relatório ou outro formulário.
Antes de explicar como enviar parâmetros, você deve definir as propriedades de um
formulário para desempenhar o papel de caixa de diálogo:
Propriedade do formulário Valor
Guia Formato (Format)
 Legenda (Caption) O título da caixa de diálogo
 Modo padrão (Default View) Formulário simples (Single form)
 Modos permitidos (Views Allowed) Formulário (Form)
 Barras de rolagem (Scroll bars) Nenhuma (Neither)
 Seletores de registro(Record Selectors) Não (No)
 Botões de navegação (Navigation Buttons) Não (No)
 Linhas divisórias (Dividing Lines) Não (No)
 AutoCentralizar (Auto Center) Sim (Yes)
 Estilo da vorda (Border Style) Diálogo (Dialog)
 Botões Min Max (Min Max Buttons) Nenhum (None)
Guia Dados (Data)
 Origem do registro (RecordSource) Vazio

Uma caixa de diálogo terá dois botões de comando: Um para prosseguir (Ok) e outro
para fechar a caixa de diálogo (Fechar). Normalmente, as propriedades e eventos dos botões
de comando são:
Propriedade Valor
Legenda (Caption) &Ok
Nome (Name) cmdOk
Padrão (Default) Sim (Yes)
AoClicar (Onclick) Chamada específica (Ver exemplos a seguir)

Propriedade Valor
Legenda (Caption) &Fechar
Nome (Name) cmdFechar
Cancelar (Cancel) Sim (Yes)
AoClicar (OnClick) Private Sub cmdFechar_Click()
DoCmd.Close
End Sub

Normalmente, controles caixas de texto são não acopladas e recebem os valores que
serão passados como parâmetros para proicedimentos, consultas parametrizadas, relatórios e
formulários.

76
Microsoft© Access Avançado
7.2.1. Passagem De Parâmetros Para Procedimento
Esta é a técnica mais simples. O procedimento chamado pelo formulário pode ser Sub
ou Function definido em módulo atrás do formulário (módulo de classe de formulário) ou em
módulo padrão. O evento AoClicar do botão cmdOk fará a chamada do procedimento
enviando o valor do controle como argumento do procedimento.
Private Sub cmdOk_Click()
Dim curValor As Currency
Dim strExtenso As String
curValor = Me.txtValor
strExtenso = Extenso(curValor)
End Sub

7.2.2. Passagem De Parâmetros Para Consulta Parametrizada


As consultas parametrizadas possuem critério dinânico, ou seja, o valor do critério de
filtragem da consulta é informado quando da execução da consulta. Por exemplo, a consulta
seleção, cujo código SQL é mostrado a seguir, pedirá o valor do parâmetro [Qual o número do
pedido] por meio de uma caixa de diálogo simples.
SELECT Pedidos.NúmeroDoPedido, Pedidos.CódigoDoCliente,
Pedidos.DataDoPedido
FROM Pedidos
WHERE Pedidos.NúmeroDoPedido = [Qual o número do pedido];

Esta não é uma forma elegante de passar parâmetros para consulta, pois para cada
parâmetro da consulta será aberta uma caixa de diálogo. Estas caixas de diálogo de consulta
parametrizada não validam nenhum dado informado pelo usuário.
A solução é criar um formulário do tipo caixa de diálogo que receberá todos os
parâmetros de uma só vez e o botão Ok acionará a consulta. Os parâmetros podem ser
formatados e/ou validados pelo formulário antes de ser enviado para a consulta, garantindo
que o usuário informe parâmetros válidos para a consulta.
Para demonstrar a solução da consulta do exemplo acima, construiremos uma caixa de
diálogo chamada frmDlg_Consulta_Pedido. Ela conterá os botões cmdOk e cmdFechar, como
visto anteriormente. A caixa de texto txtNumeroPedido é não acoplada e o seu valor será
passado como parâmetro para a consulta qryConsulta_Pedido.

77
Microsoft© Access Avançado

O botão cmdOk conterá o seguinte código VBA associado ao evento AoClicar


Private Sub cmdOk_Click()
DoCmd.OpenQuery "qryConsulta_Pedido"
End Sub

A consulta qryConsulta_Pedido terá o seguinte código SQL.


SELECT Pedidos.NúmeroDoPedido, Pedidos.CódigoDoCliente,
Pedidos.DataDoPedido
FROM Pedidos
WHERE Pedidos.NúmeroDoPedido =
Forms![frmDlg_Consulta_Pedido].txtNumeroPedido;

A consulta funciona porque o formulário está aberto e seus controles podem ser
acessados por outros objetos do Access.
Esta técnica é útil para aplicativos em que a segurança não é um ponto importante.
Note que a janela folha de dados da consulta, caso seja uma consulta seleção ou referência
cruzada, é aberta, permitindo que o usuário possa alterar a estrutura, modificar os dados ou
excluir registros. A técnica de tela de consulta, como veremos mais adiante, resolve estes
problemas.

7.2.3. Passagem De Parâmetros Para Relatório

Às vezes precisamos de relatórios mais flexíveis, como por exemplo, emitir os pedidos
feitos entre duas datas. Precisamos passar a data inicial e a data final para a origem dos dados
(normalmente uma consulta seleção).
Uma alternativa de solução é criar uma consulta parametrizada, passando parâmetros
pelo formulário. O relatório então se baseará nesta consulta.
Por exemplo, o formulário frmDlg_Relatorio_Pedido contém as caixas de texto não
acopladas txtDataInicial e txtDataFinal. Estes controles são parâmetros para a consulta
qryRelatorio_Pedido.

78
Microsoft© Access Avançado

A consulta qryRelatorio_Pedido possui o código SQL.


SELECT Pedidos.NúmeroDoPedido, Pedidos.CódigoDoCliente,
Pedidos.DataDoPedido
FROM Pedidos
WHERE Pedidos.DataDoPedido BETWEEN
Forms![frmDlg_Relatorio_Pedido].txtDataInicial AND
Forms![frmDlg_Relatorio_Pedido].txtDataFinal;

O relatório rptRelatorio_Pedido é baseado na consulta qryRelatorio_Pedido, ou seja, a


sua propriedade Origem do registro (RecordSource) é qryRelatorio_Pedido.
O botão cmdOk do formulário frmDlg_Relatorio_Pedido contém o código VBA
associado ao evento AoClicar.
Private Sub cmdOk_Click()
DoCmd.OpenReport "rptRelatorio_Pedido", acViewPreview
End Sub

Esta técnica é difícil de ser administrada devido à interação de três objetos do Access
(um formulário, uma consulta e um relatório). Quanto mais objetos o banco de dados possui,
maior a complexidade e mais difícil é sua manutenção. Além disso, esta técnica restringe-se a
filtrar a origem do registro utilizando uma consulta parametrizada.
Uma outra técnica mais elaborada baseia-se na possibilidade de acessar controles de
formulários que estão abertos. Controles de formulários abertos possuem visibilidade public,
ou seja, eles são acessíveis em qualquer parte do Access. É por isso que consultas
parametrizadas funcionam.
Uma caixa de diálogo para abrir relatórios podem construir uma expressão SQL em
tempo de execução, armazená-la em uma caixa de texto oculta e ser usada como parâmetro
para um relatório. Desta forma, elimina-se a necessidade de se construir um objeto consulta,
diminuindo-se a quantidade de objetos no banco de dados e, consequentemente, a
complexidade de manutenção. Além disso, outros parâmetros podem direcionar o
comportamento do relatório, tal como definir a ordem de classificação, incluir mensagem ad-
hoc no relatório, ocultar/exibir seções do relatórios, dentre outras possibilidades.
Para demonstrar esta técnica, usaremos o mesmo exemplo acima.
O formulário frmDlg_Relatorio_Pedido conterá adicionalmente uma caixa de texto
txtSql, com estas propriedades configuradas:
Propriedade Valor
Visivel (Visible) Sim (Yes)
Parada de tabulação (Tab Stop) Não (No)

79
Microsoft© Access Avançado

O botão cmdOk conterá o código VBA associado ao evento AoClicar:


Private Sub cmdOk_Click()
Dim strSql As String
Dim strDataInicial As String
Dim strDataFinal As String

strDataInicial = Me.txtDataInicial
strDataFinal = Me.txtDataFinal

strSql = "SELECT Pedidos.NúmeroDoPedido, Pedidos.CódigoDoCliente, "


strSql = strSql + "Pedidos.DataDoPedido "
strSql = strSql + "FROM Pedidos "
strSql = strSql + "WHERE Pedidos.DataDoPedido BETWEEN #"
strSql = strSql + strDataInicial + "# AND #" + strDataFinal + "#"

Me.txtSql = strSql
DoCmd.OpenReport "rptRelatorio_Pedido", acViewPreview
End Sub

O relatório rptRelatorio_Pedido terá a propriedade Origem do registro


(RecordSource) vazia e o seguinte código associado ao evento AoAbrir.
Private Sub Report_Open(Cancel As Integer)
Me.RecordSource = Forms![frmDlg_Relatorio_Pedido].txtSql
End Sub

Usando esta técnica, podemos modificar outras propriedades do relatório em tempo de


execução, usando parâmetros da caixa de diálogo. O próximo exemplo acrescenta a opção de
ordem de classificação dos dados do relatório. Uma caixa de grupo permite escolher se a
ordem será por Número do pedido ou por Código do cliente. Lembre-se que a cláusula
ORDER BY da origem do registro não afeta a classificação do relatório.

A propriedade que define a ordem de classificação dos dados no relatório é


GroupLevel. Um relatório pode ter até 10 níveis de grupo. Assim, a propriedade GroupLevel
funciona como um vetor de 10 elementos. GroupLevel(0) é o primeiro nível de grupo.
GroupLevel possui as propriedades:
Propriedade Valor
80
Microsoft© Access Avançado
ControlSource Campo ou expressão pelo qual os dados serão classificados
GroupOn Agrupamento dos dados. O padrão é agrupar por cada valor.
GroupInterval O intervalo pelo qual os dados são agrupados. O padrão é 1 (intervalo para cada valor)
KeepTogether Mantém ou não o grupo na mesma página quando é impresso. O padrão é 0 (não
mantém na mesma página)
SortOrder False para ascendente (padrão), True para descendente

O evento AoAbrir do relatório rptRelatorio_Pedido conterá o código:


Private Sub Report_Open(Cancel As Integer)
Dim bytOpcao As Byte

Me.RecordSource = Forms![frmDlg_Relatorio_Pedido].txtSql

bytOpcao = Forms!frmDlg_Relatorio_Pedido.grpClassificacao
If bytOpcao = 1 Then
Me.GroupLevel(0).ControlSource = "NúmeroDoPedido"
Else
Me.GroupLevel(0).ControlSource = "CódigoDoCliente"
End If
End Sub

7.2.4. Passagem De Parâmetros Para Formulário

A passagem de parâmetros de um formulário para outro pode usar a mesma técnica de


passagem de parâmetros para relatório, mostrada acima. Entretanto, formulários podem
receber parâmetros de outra forma.
O objeto DoCmd possui o método OpenForm, cuja sintaxe é:
DoCmd.OpenForm formname[, view][, filtername][, wherecondition][, datamode][, windowmode][, openargs]

Argumento Descrição
formname O nome do formulário a ser aberto.
view Uma das seguintes constantes intrínsecas:
acDesign
acFormDS
acNormal (padrão)
acPreview

acNormal abre o formulário no modo formulário. Se você deixar


em branco, assume o padrão.
filtername Uma expressão que é o nome de uma consulta válida no banco de
dados. Pode ser também uma expressão SQL.
wherecondition Uma expressão de até 32768 caracteres para critério de filtragem.
A sintaxe é a mesma para a cláusula WHERE da linguagem SQL,
exceto que não é preciso colocar a palavra WHERE.
datamode Uma das seguintes constantes intrínsecas:
acFormAdd
acFormEdit
acFormPropertySettings (padrão)
acFormReadOnly
81
Microsoft© Access Avançado

Se você deixar em branco, assume o padrão, que é abrir o


formulário de acordo com o modos atribuído nas propriedades
Permitir edição (AllowEdits), Permitir exclusão (AllowDeletions),
Permitir adição (AllowAdditions) e Entrada de dados
(DataEntry).
windowmode Uma das seguintes constantes intrínsecas:
acDialog
acHidden
acIcon
acWindowNormal (padrão)
Se você deixar em branco, assume o padrão.
openargs Uma expressão literal passada como argumento.

Os argumentos filtername e wherecondition compõem a propriedade Filtro (Filter) do


formulário. Se você especificar ambas, o valor da propriedade Filtro será uma expressão
lógica com as duas condições ligadas pelo operador lógico AND.
Por exemplo, se filtername for definido como:
"SELECT Clientes.* FROM Clientes WHERE Left([CódigoDoCliente],1)='A'"
a propriedade Filtro terá o valor:
(Left([CódigoDoCliente],1)='A')

Se além de filtername for especificado wherecondition como:


"Cidade = 'México D.F.'"
a propriedade Filtro terá o valor:
(Cidade = 'México D.F.') AND (Left([CódigoDoCliente],1)='A')

Você pode construir um filtro em tempo de execução usando os argumentos filtername


e wherecondition. Por exemplo, suponha que o formulário frmClientes apresente todos os
registros da tabela Clientes do banco de dados Northwind. Você deseja consultar/editar
somente os registros dos clientes de uma cidade especificada em uma caixa de diálogo
frmDlg_Formulario_Clientes. O procedimento de evento AoClicar do botão cmdOk da caixa
de diálogo conterá este código:
Private Sub cmdOk_Click()
Dim strCidade As String
Dim strWhereCondition As String

strCidade = Me.txtCidade ' É uma caixa de texto não acoplada


strWhereCondition = "Cidade = '" + strCidade + "'"
DoCmd.OpenForm "frmClientes", , , strWhereCondition
End Sub

Uma outra forma de passar parâmetros de um formulário para outro é usar o


argumento openargs do DoCmd. openargs é um texto que pode ser capturado no formulário
especificado em formname usando a propriedade de formulário OpenArgs. Esta propriedade
deve estar em um código dentro do procedimento de evento AoAbrir do formulário que será
aberto por DoCmd.

82
Microsoft© Access Avançado
Suponha que você tenha que abrir o formulário frmClientes e queira posicionar no
registro referente ao cliente ANTON. Construa um procedimento que abra o formulário
frmClientes, passando “ANTON” como argumento. Aqui, o procedimento chama-se
AbreCliente.
Sub AbreCliente()
DoCmd.OpenForm "frmClientes", , , , , , "ANTON"
End Sub

O procedimento de evento AoAbrir do formulário frmClientes conterá o código:


Private Sub Form_Open(Cancel As Integer)
Dim strCliente As String
Dim rstCopia As Recordset
If Not IsNull(Me.OpenArgs) Then
strCliente = Me.OpenArgs
Set rstCopia = Me.RecordsetClone
rstCopia.FindFirst "CódigoDoCliente= '" + strCliente + "'"
If Not rstCopia.NoMatch Then
Me.Bookmark = rstCopia.Bookmark
End If
End If
End Sub

A propriedade RecordsetClone do formulário cria uma cópia da origem do registro


(propriedade RecordSource do formulário) e armazena na variável rstCopia. É usado o
método FindFirst para localizar o cliente “ANTON”, valor este capturado pela propriedade
OpenArgs do formulário. A propriedade NoMatch do objeto recordset (veja Acesso a Banco
de Dados) indica se o registro foi localizado ou não. Caso seja localizado, a propriedade
Bookmark posiciona o registro correto para ser exibido no formulário frmClientes.

7.3. FORMULÁRIO DE CONSULTA


Abrir uma consulta criada na guia Consulta da janela Banco de Dados é a maneira
mais simples de visualizar dados. Entretanto, o modo Folha de Dados de uma consulta possui
uma apresentação é pobre. Na realidade, o modo Folha de Dados não é só para consulta, pois
permite que o usuário apague ou altere dados.

83
Microsoft© Access Avançado

Usar formulário e sub-formulário é uma boa alternativa para se visualizar dados


somente para leitura.

O primeiro passo é criar um subformulário para a apresentar os detalhes. As principais


propriedades do subformulário são:
Propriedade Valor
Nome SubfrmDetalhes_Pedido
Origem do Registro SELECT [Detalhes do Pedido].NúmeroDoPedido,
Produtos.NomeDoProduto, [Detalhes do
Pedido].PreçoUnitário, [Detalhes do
Pedido].Quantidade, [Detalhes do Pedido].Desconto,
([Detalhes do Pedido].[PreçoUnitário]-[Detalhes do
Pedido].[PreçoUnitário]*[Desconto])*[Quantidade]
AS SubTotal
FROM Produtos INNER JOIN [Detalhes do Pedido]
ON Produtos.CódigoDoProduto = [Detalhes do
Pedido].CódigoDoProduto;
Modo Padrão Formulários contínuos
84
Microsoft© Access Avançado
Barras de Rolagem Somente vertical
Seletor de Registros Não
Botões de Navegação Não
Permitir edições Não
Permitir exclusões Não
Permitir adições Não

O formulário principal conterá o subformulário, entretanto, não haverá vínculo entre


eles, ou seja, não há um campo que relacione os valores do formulário e do subformulário. A
propriedade Origem do Registro (RecordSource) do subformulário será definido via
programação.
Pode haver um ou mais caixas de texto ou caixa de combinação não acoplados, cujos
valores serão o filtro para a apresentação dos registros no subformulário. Por esta razão não é
necessário haver vinculação entre formulário e subformulário. Neste exemplo, o filtro é feito
pela caixa de combinação cboNumeroPedido. Este valor será usado na construção da
expressão SQL que será a Origem do Registro do subformulário. A instrução SQL é criada ao
abrir o formulário, ao clicar no botão Buscar e ao clicar o botão Limpar.
A instrução SQL no evento AoAbrir é a mesma no evento AoClicar. Constrói-se a
instrução tal qual foi feito no subformulário, mas acrescenta-se a cláusula WHERE False
para não apresentar nenhum registro.
Private Sub Form_Open(Cancel As Integer)
Dim strSql As String

strSql = "SELECT [Detalhes do Pedido].NúmeroDoPedido,


Produtos.NomeDoProduto, "
strSql = strSql + "[Detalhes do Pedido].PreçoUnitário , [Detalhes do
Pedido].Quantidade, "
strSql = strSql + "[Detalhes do Pedido].Desconto, "
strSql = strSql + "([Detalhes do Pedido].[PreçoUnitário]-[Detalhes do
Pedido].[PreçoUnitário]*[Desconto])*[Quantidade] AS SubTotal "
strSql = strSql + "FROM Produtos INNER JOIN [Detalhes do Pedido] ON "
strSql = strSql + "Produtos.CódigoDoProduto = [Detalhes do
Pedido].CódigoDoProduto where false"
Me.subfrmDetalhes_Pedido.Form.RecordSource = strSql
Me.subfrmDetalhes_Pedido.Requery
Me.txtTotal = 0
Me.txtRegistros = 0
End Sub

Na linha de instrução Me.subfrmDetalhes_Pedido.Form.RecordSource = strSql é


atribuído o valor da propriedade Origem do Registro do subformulário. Na linha seguinte é
utilizado o método Requery para que o subformulário re-execute a instrução SQL.

O evento AoClicar possui um código semelhante, apenas há o acréscimo da inibição


do botão Exportar XLS e a limpeza do valor na caixa de combinação cboNumeroPedido.

Private Sub cmdLimpar_Click()


Dim strSql As String

85
Microsoft© Access Avançado
strSql = "SELECT [Detalhes do Pedido].NúmeroDoPedido,
Produtos.NomeDoProduto, "
strSql = strSql + "[Detalhes do Pedido].PreçoUnitário , [Detalhes do
Pedido].Quantidade, "
strSql = strSql + "[Detalhes do Pedido].Desconto, "
strSql = strSql + "([Detalhes do Pedido].[PreçoUnitário]-[Detalhes do
Pedido].[PreçoUnitário]*[Desconto])*[Quantidade] AS SubTotal "
strSql = strSql + "FROM Produtos INNER JOIN [Detalhes do Pedido] ON "
strSql = strSql + "Produtos.CódigoDoProduto = [Detalhes do
Pedido].CódigoDoProduto WHERE False"
Me.subfrmDetalhes_Pedido.Form.RecordSource = strSql
Me.subfrmDetalhes_Pedido.Requery
Me.txtTotal = 0
Me.txtRegistros = 0
Me.cboNumeroPedido = ""
Me.cmdExportToExcel.Enabled = False
End Sub

O botão Buscar é que realiza a busca dos registros a serem apresentados no


subformulário. No exemplo, foram incluídas duas funcionalidades opcionais: cálcular o valor
do pedido e a quantidade de itens a serem apresentados nas caixas de texto txtTotal e
txtRegistros e criar uma consulta para que os dados sejam exportados para o MS Excel.
Note que o botão Exportar XLS somente é habilitado (propriedade Enabled) após a
criação da consulta qryExportXLSTemp
Private Sub cmdBuscar_Click()
Dim rst As Recordset
Dim strSql As String
Dim intNumPedido As Variant
Dim curTotal As Currency
Dim dblQtdRegistros As Double
Dim qdf As QueryDef

' Cria a expressão SQL para que o subformulário apresente os dados


intNumPedido = Me.cboNumeroPedido
strSql = "SELECT [Detalhes do Pedido].NúmeroDoPedido,
Produtos.NomeDoProduto, "
strSql = strSql + "[Detalhes do Pedido].PreçoUnitário , [Detalhes do
Pedido].Quantidade, "
strSql = strSql + "[Detalhes do Pedido].Desconto, "
strSql = strSql + "([Detalhes do Pedido].[PreçoUnitário]-[Detalhes do
Pedido].[PreçoUnitário]*[Desconto])*[Quantidade] AS SubTotal "
strSql = strSql + "FROM Produtos INNER JOIN [Detalhes do Pedido] ON "
strSql = strSql + "Produtos.CódigoDoProduto = [Detalhes do
Pedido].CódigoDoProduto "
strSql = strSql + "WHERE [Detalhes do Pedido].NúmeroDoPedido = " &
intNumPedido
Me.subfrmDetalhes_Pedido.Form.RecordSource = strSql

' Totaliza o valor do pedido


curTotal = 0
dblQtdRegistros = 0
Set rst = Me.subfrmDetalhes_Pedido.Form.RecordsetClone
Do While Not rst.EOF
curTotal = curTotal + rst("Subtotal")
dblQtdRegistros = dblQtdRegistros + 1
rst.MoveNext
Loop
86
Microsoft© Access Avançado
rst.Close
Me.txtTotal = curTotal
Me.txtRegistros = dblQtdRegistros

' Cria uma consulta para ser exportada para o MS Excel


On Error Resume Next
CurrentDb.QueryDefs.Delete "qryExportXLSTemp"
Set qdf = CurrentDb.CreateQueryDef("qryExportXLSTemp", strSql)
Me.cmdExportToExcel.Enabled = True
End Sub

Como o botão Buscar cria uma consulta, a qryExportXLSTemp, em tempo de


execução, podemos aproveitá-la para exportar os dados para o Excel pelo método
TransferSpreadsheet do objeto DoCmd.
Existe uma função definida pelo usuário chamada CaixaDialogo_Save que será
explicada mais adiante.
Private Sub cmdExportToExcel_Click()
Dim strFileName As String
strFileName = CaixaDialogo_Save("Salvar dados para MS Excel ", CurDir, _
"Microsoft Excel" + Chr$(0) + "*.xls" + Chr$(0), _
"Pedidos", "*.xls")
If strFileName = "" Then
MsgBox "Informe o nome do arquivo!"
Else
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel, _
"qryExportXLSTemp", strFileName
End If
End Sub

Finalmente, o botão Fechar possui o código mais simples.


Private Sub cmdFechar_Click()
DoCmd.Close
End Sub

7.4. CAIXA DE MENSAGEM


O modo mais simples de se ter caixas de mensagem é usar a intrução MsgBox ou a
função MsgBox( ). O inconveniente disto é estas caixas de mensagem sempre acarreta uma
pausa na execução do programa, pois você deve clicar em pelo menos um dos botões da
caixa.
Você pode usar uma formulário somente com mensagens, sem nenhum botão de
comando. Isto é útil, por exemplo, para exibir uma mensagem AGUARDE enquanto um
processamento longo é executado.
Tipicamente um formulário para ser usado como caixa de mensagem possui as
propriedades:
Propriedade Valor
Modo padrão Formulário simples
Modos permitidos Formulário
Barras de rolagem Nenhum
87
Microsoft© Access Avançado
Seletores de registro Não
Botões de navegação Não
Auto centralizar Sim
Estilo da borda Fino
Caixa de controle Não
Botões Min e Max Ambos desativados
Botão fechar Não

O código para apresentar a caixa de mensagem deve ter as seguintes instruções:


DoCmd.OpenForm "nome_do_formulário"
DoEvents
.
.
DoCmd.Close acForm, "nome_do_formulário"

A primeira linha do código abre o formulário no modo formulário. OpenForm é um


método do objeto DoCmd. A segunda contém a função DoEvents que passa o controle para o
sistema operacional, permitindo que a janela seja exibida. Se não for colocada DoEvents, a
tela ficará congelada e nada será exibido. A última instrução fecha o formulário.

88
Microsoft© Access Avançado
8. ACESSO A BANCO DE DADOS
O acesso a banco de dados no Access usa o modelo DAO – Data Access Object e o
mecanismo Jet (Jet Engine).
O DAO é um conjunto de classes de objetos que modela a estrutura de um sistema de
banco de dado relacional. Eles oferecem propriedades e métodos que lhe permitem realizar
todas as operações necessárias para gerenciar tal sistema, incluindo recursos para criar banco
de dados, definir tabelas, campos e índices, establecer relações entre tabelas, navegar e
consultar o banco de dados, e assim por diante.
O Jet Engine traduz estas operações de objetos de acesso a dados em operações físicas
sobre os próprios arquivos de banco de dados, tratando toda a mecânica da interface com os
diferentes bancos de dados suportados.
O Visual Basic, por meio do DAO e do Jet Engine reconhece três categorias de bancos
de dados:

Bancos de dados nativos


São os bancos que utilizam o formato do Microsoft Access. Eles são criados e manipulados
diretamente pelo Jet Engine, e oferecem a máxima flexibilidade e velocidade.

Bancos de dados externos


São os bancos ISAM (Indexed Sequential Access Method), nos quais estão incluídos os
formatos dBase III, dBase IV, Btrieve, FoxPro, Paradox, arquivos texto, planilhas Excel e
planilhas Lotus 1-2-3.

Bancos de dados ODBC


São bancos de dados cliente/servidor que atendem ao padrão ODBC, tais como o MS SQL
Server e o Oracle.

Existem outros métodos de acesso a banco de dados que não utilizam o Jet Engine.
Somente para citar:
• ODBCDirect
• RDO e RDC
• Chamada à API do OBDC
• ADO (ActiveX Data Objects)

8.1. Hierarquia do Objetos DAO

Para usar os objetos de acesso a dados, é necessário conhecer o modelo DAO.

89
Microsoft© Access Avançado

No topo da hierarquia está o mecanismo de banco de dados do Jet Engine,


representado pelo objeto DBEngine. Ele é o único objeto que não está contido em nada.
Abaixo dele está uma coleção Workspaces (coleções são usadas no plural dos objetos que ela
contém). A única finalidade das coleções é conter outros objetos do mesmo tipo.

8.2. Sintaxe para Referenciar Objetos em Coleção

Os membros de uma coleção, isto é, os objetos, podem ser acessados por um número
índice base-zero. Assim, o primeiro workspace é o Workspaces(0), que é o workspace atual
(aquele que é criado quando você abre o Access). O primeiro database é o Databases(0), que é
o banco de dados atual (o arquivo mdb que está aberto).
Os objetos na hierarquia são identificados por um caminho completo das coleções
acumuladas a que pertencem, usando o ponto (.) para separá-los. Assim, o objeto database que
representa o arquivo mdb no qual você está trabalhando é referido como:

DBEngine.Workspaces(0).Databases(0)

Além do número índice, usa-se uma referência explícita do nome do objeto dentro da
coleção. Por exemplo, um campo CódigoDoLivro é um objeto field dentro de uma coleção
Fields. Se ele for o primeiro campo, ele pode ser referenciado por:

Fields(0)

Ou

Fields(“CódigoDoLivro”)

90
Microsoft© Access Avançado
8.3. Coleção Padrão

A maior parte dos objetos de acesso a dados possui uma coleção padrão. Por exemplo,
a coleção padrão de recordset é Fields. Isto permite omitir a coleção da sintaxe.

intCodigo = rst!CódigoDoLivro ‘ Obtém o valor do campo “CódigoDoLivro”

Que é equivalente a:

intCodigo = rst.Fields!CódigoDoLivro

Ou à:

intCodigo = rst.Fields(“CódigoDoLivro”)

Ou ainda à:

intCodigo = rst.Fields(0)

Note que intCodigo é uma variável do tipo inteiro que armazena o valor do objeto e
não o objeto. Valor é umas das propriedades do objeto.

8.4. Referência a Objetos por meio de Variáveis

Cada objeto pode (e ás vezes deve) ser atribuído à uma variável do mesmo tipo do
objeto.

Dim wks As Workspace


Dim dbs As Database
Set wks = DBEngine.Workspaces(0)
Set dbs = wks.Databases(0)

Se quiser, pode economizar algumas linhas de código com esta sintaxe:


Dim dbs As Database
Set dbs = DBEngine.Workspaces(0).Databases(0)

Neste caso específico, a economia pode ser maior se se usar a função CurrentDb para
retornar o banco de dados atual.
O uso de variáveis simplifica a referência a objetos nas mais baixas níveis da
hierarquia do DAO.

8.5. Propriedades e Métodos

91
Microsoft© Access Avançado
Um dos princípios da orientação a objeto é manter dados e procedimentos de um
objeto dentro do próprio objeto. Os dados dos objetos são chamados de propriedades
enquanto que os procedimentos chamam-se métodos.

Usando variáveis para referenciar os objetos, torna-se prática a programação orientada


a objetos.
Para entender os conceitos acima, vamos usar os objetos recordset e field. Um
Recordset é o conjunto de registros retornado por uma tabela, por uma consulta que retorne
registros (seja esta uma consulta previamente criada na guia de Consultas da janela de Banco
de Dados ou criada em tempo de execução, através de comandos SQL). Um field é o próprio
campo da tabela.
Para obter um objeto recordset, usa-se o método OpenRecordset do objeto database.
O objeto é então atribuído à uma variável, declarada anteriormente como do tipo Recordset.

Dim rst As Recordset


Set rst = CurrentDb.OpenRecordset(“Tabela1”)

Abrir um recordset é semelhante ao comando USE do Clipper.


Como visto, o objeto field é referido por um índice base-zero ou explicitamente pelo
nome do campo. O objeto field pode ser atribuído à uma variável declarada como do tipo
Field.

Dim fldCampo1 As Field


Set fldCampo1 = rst.Fields(“CódigoDoLivro”)

Para obter o valor deste objeto, usa-se a propriedade Value.

intCampo = fldCampo1.Value

intCampo é uma variável do tipo inteiro que armazena o valor do objeto e não o
objeto, o qual já é referenciado por fldCampo1. Em vez de usar a propriedade Value, pode-se
simplesmente referenciar diretamente o objeto, omitindo-se a propriedade.

intCampo = rst.Fields(“CódigoDoLivro”)

Para obter os valores dos campos para os demais registros, usa-se o método MoveNext
do objeto recordset. Pode-se, assim, percorrer sequencialmente todo o recordset.

rst.MoveNext

Este método é semelhante ao SKIP do Clipper.


A leitura sequencial do recordset irá terminar quando se chegar ao seu fim. A
propriedade EOF do objeto recordset.
Para entender os métodos e propriedades vistos até agora, veja uma analogia com o
Clipper

92
Microsoft© Access Avançado

OPERAÇÃO CLIPPER VISUAL BASIC


COLEÇÃO/ PROPRIEDADE/MÉTODO
OBJETO
Abrir arquivo de dados USE Database OpenRecordset( {recordset} )
{arquivo}
Mover ponteiro de SKIP Recordset MoveNext
registro para frente
Mover ponteiro de SKIP –1 Recordset MovePrevious
registro para trás
Ir para o primeiro GoTop() Recordset MoveFirst
registro
Ir para o último registro GoBottom() Recordset MoveLast
Saltar n registros para SKIP [± n] Recordset Move [± n]
frente ou para trás
Testar fim de arquivo Eof() Recordset EOF
Testar início de arquivo Bof() Recordset BOF
Obter o valor de um {nome do Fields Fields({índice}) ou
campo campo} Fields( {nome do campo} ) ou
Fields!{nome do campo})

Field Value
Recordset !{nome do campo}
Fechar arquivo de CLOSE Recordset Close
dados

8.6. Acesso a Banco de Dados Access

Vamos tomar como exemplo os conjuntos de registros abaixo para escrever um código
que percorra todos os registros de um recordset e imprima o valor de seus campos .
O primeiro conjunto de registro refere-se à tabela Livros, o segundo à tabela Tópicos,
o terceiro à consulta seleção qryLivros_versus_Tópicos e o quarto à uma consulta gerada em
tempo de execução, através da expressão SQL:

SELECT Tópicos.Tópico, Count(Livros.CódigoDoLivro) AS


Quantidade FROM Tópicos RIGHT JOIN Livros ON
Tópicos.CódigoDoTópico = Livros.CódigoDoTópico
GROUP BY Tópicos.Tópico;

Tabela: Livros
Código do Livro Título Código do Tópico Nome do Editor Preço de
1 Dirk Luchte 5 GGG&G Editora R$23,50
2 Planejando Sua 1 Jean-Paul Deloria R$22,95
3 Diamantes 6 Editora Ramona R$9,95
4 Técnicas de Tai Chi 4 Editora Ramona R$25,95
93
Microsoft© Access Avançado
5 Minha Família 5 Publicações R$17,95

Os campos da tabela Livros são: CódigoDoLivro, Título, CódigoDoTópico,


NomeDoEditor, e PreçoDoPedido

Tabela: Tópicos
Código do Tópico Tópico
1 Negócios
2 Psicologia
3 Ciência
4 Saúde
5 Ficção
6 Romance
7 Técnico

Os campos da tabela Tópicos são: CódigoDoTópico e Tópico

Consulta seleção: qryLivros_versus_Tópicos


Título Tópico
Planejando Sua Carreira Negócios
Técnicas de Tai Chi Saúde
Dirk Luchte Ficção
Minha Família Ficção
Diamantes Romance

Consulta seleção com função agregada


Tópico Quantidade
Ficção 2
Negócios 1
Romance 1
1

Comecemos por fazer uma leitura sequencial de cada registro da tabela Livros,
listando os conteúdos dos campos Título e NomeDoEditor.
O primeiro passo, é então criar um objeto database que contenha o banco de dados
atual.

' Declara um ojeto database (banco de dados)


Dim dbsBancoAtual As Database
' Atribui o banco atual ao objeto database
Set dbsBancoAtual = DBEngine.Workspaces(0).Databases(0)

O banco de dados atual pode ser referido simplesmente por:

94
Microsoft© Access Avançado
Set dbsBancoAtual = CurrentDb

Um objeto recordset tem que ser aberto no banco de dados atual. Assim, vamos
declarar um objeto recordset e usar o método OpenRecordset do objeto database.

' Declara um ojeto database (banco de dados)


Dim dbsBancoAtual As Database
' Declara um ojeto recordset
Dim rstTabela As Recordset
' Atribui o banco atual ao objeto database
Set dbsBancoAtual = DBEngine.Workspaces(0).Databases(0)
' Abre o recordset e o atribui ao objeto recordset
Set rstTabela = dbsBancoAtual.OpenRecordset(“Livros”)

Para pegar um determinado campo, poderíamos criar um objeto Field para cada o
campo, uma para Título e outro para o campo NomeDoEditor, mas em vez disto vamos pegar
o valor do próprio objeto Field, explicitando o nome do campo dentro da coleção Fields.

rstTabela.Fields(“Título”)
rstTabela.Fields(“NomeDoEditor”)

O nome do objeto Field deve ser o nome do campo e não a sua legenda. Por isso , está
escrito NomeDoEditor e não Nome do Editor.
Falta ainda criar uma estrutura de repetição do VBA que percorra todo o recordset.
Vamos usar o Do...Loop, com a condição While (enquanto) verificando o fim do de arquivo.
O fim de arquivo pode ser obtido pela propriedade EOF do objeto recordset. A navegação
pelos registros é feita pelo método MoveNext do objeto recordset.

' Declara um ojeto database (banco de dados)


Dim dbsBancoAtual As Database
' Declara um ojeto recordset
Dim rstTabela As Recordset
' Atribui o banco atual ao objeto database
Set dbsBancoAtual = DBEngine.Workspaces(0).Databases(0)
' Abre o recordset e o atribui ao objeto recordset
Set rstTabela = dbsBancoAtual.OpenRecordset(“Livros”)

Do While Not rstTabela.EOF


Debug.Print rstTabela.Fields(“Título”) & “ - “ & _
rstTabela.Fields(“NomeDoEditor”)
rstTabela.MoveNext
Loop
rst.Close

A janela depurar conterá os seguintes dados:

95
Microsoft© Access Avançado

8.7. Acesso a Bancos de Dados Externos

No exemplo anterior a origem dos dados é uma tabela (vinculada ou não) do banco de
dados corrente, ou seja, do banco de dados onde o programa está sendo executado. Em certos
casos é necessário obter dados (ou objetos) que estão em outros bancos de dados Access ou de
banco de dados ISAM ou ODBC.

Banco de Dados Corrente


(MDB)

ARQ2.DBF ARQ3.XLS ODBC


ARQ1.MDB
(dBase 3 ) (Excel 95) (SQL Server)

Há duas maneiras de acessar os dados externos: Vinculação e Abertura direta das


tabelas

8.7.1. Vinculação de Tabelas Externas

Para acessar dados de banco de dados externos, via programação, a forma mais fácil é
vincular as tabelas externas (através do Menu Arquivo|Obter Dados Externos|Vincular) e
acessá-las normalmente pelo método OpenRecordset do Database corrente, pois elas fazem
parte do banco de dados corrente.
O problema da vinculação é que o Access não sabe se o arquivo de origem está onde
deveria estar. Portanto, ou se faz a vinculação toda vez que o aplicativo for aberto, ou se
verifica se o vinculo está ativo e o refaz se necessário.

96
Microsoft© Access Avançado
Fazer a vinculação via programação exige o conhecimento de outros objetos,
propriedades e métodos da DAO.

Toda tabela, seja própria do banco de dados ou vinculada, é um objeto TableDef


(definição de tabela). Então, fazer uma vinculação significa criar um objeto TableDef e
configurar suas propriedades (Connect e TableSourceName) para apontar para o arquivo a ser
vinculado. Após criada a TableDef, ela é acrescentada à coleção TableDefs do objeto
Database.

Sub VinculaBancosExternos()
Dim dbs As Database
Dim tdf As TableDef

Set dbs = CurrentDb


‘ Cria o objeto TableDef
Set tdf = dbs.CreateTableDef(“Clientes”)

‘ Define o tipo de banco de dados que está conectando e a localização


(path)
tdf.Connect = “dBASE III; DATABASE=C:\Tabelas”

‘ Define o nome da tabela (sem o sufixo, dbf, no caso)


tdf.SourceTableName = “Clientes”

‘ Acrescenta o objeto TableDef à coleção TableDefs


dbs.TableDefs.Append tdf

End Sub

A propriedade Connect possui dois argumentos: o Especificador e a Origem


(antecedido pela palavra DATABASE=), separadas por um ponto e virgula. Abaixo estão os
valores para este dois argumentos para os tipos de banco de dados:

Tipo de banco de dados Especificador Origem


Banco de dados Access [banco de dados]; Unidade de
disco:\caminho\nome do
arquivo.mdb
dBASE III dBASE III; Unidade de disco:\caminho
dBASE IV dBASE IV; Unidade de disco:\caminho
DBASE 5 dBASE 5.0; Unidade de disco:\caminho
Paradox 3.x Paradox 3.x; Unidade de disco:\caminho
Paradox 4.x Paradox 4.x; Unidade de disco:\caminho
Paradox 5.x Paradox 5.x; Unidade de disco:\caminho
FoxPro 2.0 FoxPro 2.0; Unidade de disco:\caminho
FoxPro 2.5 FoxPro 2.5; Unidade de disco:\caminho
FoxPro 2.6 FoxPro 2.6; Unidade de disco:\caminho
Excel 3.0 Excel 3.0; Unidade de
disco:\caminho\nome do
arquivo.xls
Excel 4.0 Excel 4.0; Unidade de
disco:\caminho\nome do
arquivo.xls
97
Microsoft© Access Avançado
Excel 5.0 ou Excel 95 Excel ; Unidade de
disco:\caminho\nome do
arquivo.xls
Excel Excel 8.0; Unidade de
disco:\caminho\nome do
arquivo.xls
HTML Import HTML Import; Unidade de
disco:\caminho\nome do
arquivo
HTML Export HTML Export; Unidade de disco:\caminho
Text Text; Unidade de disco:\caminho
ODBC ODBC; DATABASE=bancode Nenhum
dados; UID=usuário;
PWD=senha; DSN=
nomedafontededados; [LOGIN
TIMEOUT=segundos;]
Exchange Exchange; Unidade de disco:\caminho.mdb
MAPILEVEL=caminhodapast
a; [TABLETYPE={ 0 | 1
}];[PROFILE=perfil;] [PWD=
senha;] [DATABASE=bancod
edados;]

Quando se usa tabelas vinculadas no aplicativo, é interessante refazer os vínculos no


início da da aplicação. Ora, se as tabelas já estão vinculadas, a criação de um novo TableDef
vai duplicar as tabelas existentes. Além disso, a vinculação pode falhar se as tabelas não
estiverem no local certo. O exemplo abaixo mostra como refazer os vínculos, reportando na
tela se o processo funcionou ou não.

Function VinculaTabelas()
Dim tbfs As TableDefs
Dim tbf As TableDef
Dim strMsg As String
Dim CRLF As String

CRLF = Chr(13) & Chr(10)

Set tbfs = CurrentDb.TableDefs 'Coleção de tabelas

On Error Resume Next

tbfs.Delete "Pessoal"
tbfs.Delete "Cargo"
tbfs.Delete "Funcao"

Err.Clear 'Limpa o erro anterior, se houver

DoCmd.OpenForm "Histórico de Eventos"


Err.Clear

Set tbf = CurrentDb.CreateTableDef("Pessoal")


tbf.Connect = "dBASE III; DATABASE=C:\Tabelas\"
tbf.SourceTableName = "Pessoal"
If Err.Number <> 0 Then
Forms![Histórico de Eventos].txtMsg = _
98
Microsoft© Access Avançado
Forms![Histórico de Eventos].txtMsg & "Erro ao vincular Pessoal" &
CRLF
Else
Forms![Histórico de Eventos].txtMsg = _
Forms![Histórico de Eventos].txtMsg & "Vinculou Pessoal" & CRLF
tbfs.Append tbf
End If
Err.Clear

Set tbf = CurrentDb.CreateTableDef("Cargo")


tbf.Connect = "dBASE III; DATABASE=C:\Tabelas\"
tbf.SourceTableName = "Cargo"
If Err.Number <> 0 Then
Forms![Histórico de Eventos].txtMsg = _
Forms![Histórico de Eventos].txtMsg & "Erro ao vincular Cargo" &
CRLF
Else
Forms![Histórico de Eventos].txtMsg = _
Forms![Histórico de Eventos].txtMsg & "Vinculou Cargo" & CRLF
tbfs.Append tbf
End If
Err.Clear

Set tbf = CurrentDb.CreateTableDef("Funcao")


tbf.Connect = "dBASE III; DATABASE=C:\Tabelas\"
tbf.SourceTableName = "Funcao"
If Err.Number <> 0 Then
Forms![Histórico de Eventos].txtMsg = _
Forms![Histórico de Eventos].txtMsg & "Erro ao vincular Funcao" &
CRLF
Else
Forms![Histórico de Eventos].txtMsg = _
Forms![Histórico de Eventos].txtMsg & "Vinculou Funcao" & CRLF
tbfs.Append tbf
End If
Err.Clear

Forms![Histórico de Eventos].txtMsg = _
Forms![Histórico de Eventos].txtMsg & "--------------------------" & CRLF
Forms![Histórico de Eventos].txtMsg = _
Forms![Histórico de Eventos].txtMsgtrMsg & "Fim da vinculação"

End Function

A execução desta função vinvula as tabelas e mostra o formulário Histórico de


Eventos com o resultado do processamento, como mostra a figura a seguir.

99
Microsoft© Access Avançado

8.7.2. Abertura Direta de Tabelas Externas

Com uma tabela vinculada, além de poder abrir um recordset via programa, você pode
abrí-la normalmente no modo folha de dados ou ainda criar consultas, formulários e
relatórios com base na tabela.
Se o seu caso é simplesmente abrir uma tabela externa via programação, não há
motivo para vinculá-la. Basta abrí-la diretamente.
Para abrir diretamente as tabelas, sem vinculação, lembre-se que cada arquivo externo
é um objeto Database. Portanto, basta declarar as variáveis deste tipo, na quantidade
necessária. Vamos supor que além do banco corrente, queira-se objetos de outros três bancos
Access.

Dim dbsCorrente As Database


Dim dbsArq1 As Database
Dim dbsArq2 As Database
Dim dbsArq3 As Database

Para abrir o banco corrente pode-se usar a função CurrentDb ou toda a referência de
seus objetos pais DBEngine.Workspaces(0).Database(0).
Para abrir bancos de dados externos, usa-se o método OpenDatabase do objeto
Workspace, cuja sintaxe é:

Set bancodedados = [workspace.]OpenDatabase(Banco[, Exclusivo[, ReadOnly[, Origem]]])

Banco é o nome do banco de dados a ser aberto, incluindo o seu path.


Exclusivo é um valor lógico (True ou False que indica se o banco será aberto em modo
exclusivo.
ReadOnly é um valor lógico (True ou False) que indica se o banco será aberto somente
para leitura.
Origem é um string de parâmetros para abrir o banco de dados.

100
Microsoft© Access Avançado

Set dbsCorrente = CurrentDb


Set dbsArq1 = DBEngine.Workspaces(0).OpenDatabase(“C:\Tabelas\Arq1.mdb”)
Set dbsArq2 = DBEngine.Workspaces(0).OpenDatabase(“C:\Sistemas\Arq2.mdb”)
Set dbsArq3 = DBEngine.Workspaces(0).OpenDatabase(“C:\Arq3.mdb”)

Com a abertura de vários objetos Database, você tem acesso a todos os dados destes
bancos de dados (e a objetos, se for banco Access).
Os argumentos Banco e Origem, do método OpenDatabase, e Recordset, do método
OpenRecordset, têm valores específicos para cada tipo de banco de dados. Abaixo estão os
valores para alguns dos mais comuns tipos de banco de dados:

Tipo Banco Origem Recordset


Access Path e nome do banco de Usuário e senha (se Nome da tabela.
dados. necessários). Ex.: “Cidades”
Ex.: Ex.:
“C:\Tabelas\TB_Org.mdb” “UID=Admin;PWD=senha

DBase III Path Tipo do banco de dados. Nome do arquivo,
Ex.: “dBASE III;” sem o sufixo .dbf.
“\\SMG0002\Sistemas” Ex.: “Cliente”
“D:\Dados”
Excel Path e nome do arquivo. Versão do Excel. Intervalo das células
Ex.: “Excel 4.0;” ou nome do intervalo.
“C:\Temp\Clientes.xls” “Excel 5.0;” Ex.:
“Excel 8.0;” “Plan1$A1:B5”
“Custos”
Fox Pro Path Versão do Fox Pro. Nome do arquivo sem
Ex.: “FoxPro 2.0;” o sufixo.
“\\SMG0003\Arqs” “FoxPro 2.6;” Ex.: “Carros”
“FoxPro 3.0;”

1) Exemplo de acesso direto a arquivo dBase III, situado em um recurso de rede.

Set dbsDBase = DBEngine.Workspaces(0).OpenDatabase(“\\SMG0006\Tabelas”, _


False, False, “dBASE III;”)
Set rst = dbsDBase.OpenRecordset(“Orgao”)

2) Exemplo de acesso direto a arquivo FoxPro 2.0


Set dbsFoxPro2 = DBEngine.Workspaces(0).OpenDatabase(“C:\”, _
False, False, “FoxPro 2.0;”)
Set rst = dbsFoxPro2.OpenRecordset(“Clientes”)

3) Exemplo de acesso direto a arquivo Excel

101
Microsoft© Access Avançado
Set dbsExcel = DBEngine.Workspaces(0).OpenDatabase(“C:\Sheets\Venda.xls”, _
False, False, “Excel 8.0;”)
Set rst = dbsExcel.OpenRecordset(“Plan3$A1:F7”)

102
Microsoft© Access Avançado
9. ACESSO A ARQUIVOS E IMPRESSORA
O acesso a banco de dados Access, ISAM ou ODBC, via DAO e Jet Engine, substitui
o tradicional acesso a arquivos seqüenciais e randômicos. Apesar disso, o Access não
eliminou este tipo de acesso.
Não tem muito sentido apresentar o acesso a dados em arquivos, uma vez que a
maioria das necessidades é atendida por banco de dados. Porém pode-se usar o acesso a
arquivos para outros fins, tal como direcionar a saída para disco ou diretamente para a porta
da impressora local.
Uma utilidade para a gravação da saída em disco é a monitoração, através de log em
arquivo texto, de alguns acontecimentos importantes que ocorreu no aplicativo, tal como um
erro fatal. Por exemplo, o aplicativo falhou ao tentar abrir um banco de dados .mdb que não se
encontrava mais no disco. Com certeza, este erro será tratado por uma rotina de erro (ver
tópico Tratamento de Erro) que gerará uma caixa de mensagem na tela. Porém a mensagem é
apresentada ao operador, que esqueceu-se de anotá-la. Se esta mensagem for também gravada
para o disco , o programador pode posteriormente abrir o arquivo e identificar o erro e em que
linha de programa ele ocorreu.
Para mostrar o acesso a arquivo, mostrarei um exemplo que gerará um relatório para
disco, em formato ASCII, para ser impresso em uma impressora matricial em modo texto.

Dim rst As Recordset


Dim strNome As String * 35

Set rst = CurrentDb.OpenRecordset("Pessoal")


Open "C:\SAIDA.TXT" For Output As #1

Do While Not rst.EOF


LSet strNome = rst.Fields("NM_EMPREG")
Print #1, rst.Fields("CD_MATRIC") & " ";
Print #1, strNome;
Print #1, rst.Fields("CD_CARGO") & " ";
Print #1, rst.Fields("CD_ORGAO")
rst.MoveNext
Loop

Close #1
rst.Close

O resultado deste código, o arquivo SAIDA.TXT, pode ser aberto no Notepad. Numa
sessão DOS, este arquivo pode ser enviado para uma impressora matricial em modo texto
(type saida.txt > prn: ). Isto significa que a impressão será rápida, pois não usa as fontes do
Windows.

103
Microsoft© Access Avançado

Em vez de direcionar a saída para um arquivo ASCII, pode-se enviar a saída


diretamente para a porta da impressora local. Isto equivale no Clipper a Set Print On e o
comando ?.

Dim rst As Recordset


Dim strNome As String * 35

Set rst = CurrentDb.OpenRecordset("Pessoal")

Open "Lpt1:" For Output As #1


' Liga o modo condensado em impressoras padrão Epson
Print #1, Chr(15)

Do While Not rst.EOF


LSet strNome = rst.Fields("NM_EMPREG")
Print #1, rst.Fields("CD_MATRIC") & " ";
Print #1, strNome;
Print #1, rst.Fields("CD_CARGO") & " ";
Print #1, rst.Fields("CD_ORGAO")
rst.MoveNext
Loop

Close #1
rst.Close

104
Microsoft© Access Avançado
10. TRATAMENTO DE ERRO
Há três tipos de erros.
• Erro lógico
• Erro em tempo de compilação
• Erro em tempo de execução

Erro lógico é quando o aplicativo não funciona como se esperava. Por exemplo,
esquecer-se de zerar um contador leva a um erro lógico. Este tipo de erro só pode ser
corrigido pelo próprio programador.
Erros em tempo de compilação ocorrem como resultado da construção incorreta de
código. Você pode ter esquecido de balancear pares de instruções (como If e End If ou For e
Next) ou pode ter cometido um erro de programação que viola as regras do Visual Basic
(como um erro de ortografia, omissão de um separador ou um erro de digitação).
Erros em tempo de compilação também incluem erros de sintaxe, que são erros de
gramática ou pontuação. Isso inclui parênteses mal emparelhados ou um número incorreto de
argumentos passados para uma função.
Erro em tempo de compilação ocorre também quando se usam funções definidas pelo
usuário que não existem ou estão fora do escopo, quando se usam objetos de uma biblioteca
não referenciada (ver Referência a Biblioteca de Objetos mais adiante) e quando de usa
variáveis não declaradas (desde que Option Explicit esteja ativada).
O erro por falta de referência a objetos nem sempre pode ser verificado antes de
executar o programa, pois um objeto pode ser criado em tempo de execução (ver Automação
mais adiante) e não há como o Access verificar se as propriedades e métodos são suportados
pelo objeto. Neste caso, é um erro em tempo de execução.
Para verificar a existência de erro de compilação, execute Compilar módulos
carregados no menu Depurar de uma janela de módulo.
Erro em tempo de execução é algo inesperado que ocorre quando o programa está
sendo executado. Por exemplo, tentar abrir um banco de dados em modo exclusivo quando
um outro usuário já o fez ou dividir um número por uma variável que contém zero.
Normalmente, um erro em tempo de execução suspende o programa. Na suspensão, a
janela de módulo é a aberta, a linha onde ocorreu o erro fica iluminada e mensagem de erro
aparece para se optar por depurar o programa ou encerrá-lo.

105
Microsoft© Access Avançado
Esta situação não é boa, não só porque o programa falha, mas porque o usuário tem
acesso ao código fonte do programa (lembre-se que o Access não é um compilador que gera
um programa executável).
O erro em tempo de execução pode ser tratado dentro do próprio programa,
melhorando a forma como o programa seja abortado, ou, conforme a gravidade do erro, até
mesmo corrigindo o erro e impedindo que o programa seja interrompido.
O tratamento de erro em tempo de execução é implementado com a instrução On
Error. Esta instrução permite duas formas de tratamento:
• Desviar o programa para uma rotina de tratamento de erro
• Prosseguir a execução na linha posterior ao do erro

10.1. Desvio para rotina de tratamento de erro

Para o primeiro caso usa-se On Error GoTo rótulo, onde rótulo é uma marca para
fragmento de código dentro do próprio procedimento. Este código pode:
• Tratar o erro e terminar o programa
• Tratar o erro e voltar à execução na mesma linha do erro
• Tratar o erro e voltar à execução na linha seguinte à linha de erro
• Tratar o erro e desviar a execução para outro rótulo.

A rotina de tratamento de erro faz uso do objeto Err, que tem duas propriedades
importantes> o número do erro (Number) e a sua descrição (Description).

10.1.1. Tratar o erro e terminar o programa

Sub MostraErro()
On Error GoTo Trata_Erro
Open “c:\teste.txt” For Input As #1
Close #1
Exit Sub

Trata_Erro:
‘ Erro 53 File not found
MsgBox Err.Number & “- “ & Err.Description

End Sub

Note que foi preciso colocar Exit Sub para que o código de tratamento de erro, no
rótulo Trata_Erro, não seja executado em situação sem erro. Note também, que após reportar
o erro, o programa segue o fluxo normal e pára, já que encontra End Sub.

10.1.2. Tratar o erro e voltar à execução na mesma linha do erro

Sub VoltaNaLinhaDoErro()
On Error GoTo Corrige_Erro
106
Microsoft© Access Avançado
Open “c:\teste.txt” For Output As #1
Kill “c:\teste.txt”
Exit Sub

Corrige_Erro:
If Err.Number = 55 ‘ File alredy open
Close #1
Resume
End If

End Sub

Neste caso o erro ocorre porque tenta-se apagar um arquivo que ainda está aberto. A
rotina de tratamento de erro pode corrigir a situação de erro e retornar o fluxo de programa na
mesma linha onde o erro ocorreu.

10.1.3. Tratar o erro e voltar à execução na linha seguinte à linha de erro

Sub VoltaNaProximaLinha()
Dim blnArquivoExiste As Boolean

On Error GoTo Corrige_Erro


blnArquivoExiste = True

Open “c:\teste.txt” For Input As #1


If blnArquivoExiste
MsgBox “Preparando para ler arquivo C:\teste.txt”
Else
MsgBox “O arquivo C:\teste.txt não existe!”
End If
Exit Sub

Corrige_Erro:
If Err.Number = 53 ‘ File not found
Resume Next
End If

End Sub

10.1.4. Tratar o erro e desviar a execução para outro rótulo.

Sub DesviaParaUmRotulo()
On Error GoTo Corrige_Erro

Open “c:\teste.txt” For Input As #1


Exit Sub

Fim:
MsgBox “O arquivo C:\teste.txt não existe. ” & _
“Irei criá-lo vazio para as próximas execuções!”
Open “c:\teste.txt” For Output As #1
Close #1
Exit Sub

107
Microsoft© Access Avançado

Corrige_Erro:
If Err.Number = 53 ' File not found
Resume Fim
End If

End Sub

10.1.5. Prosseguir o programa após erro

Para prosseguir o programa normalmente após a ocorrência de um erro usa-se On


Error Resume Next. Isto é útil quando o erro não compromete a lógica do programa e pode
ser ignorado. Por exemplo, quando for apagar tabela vinculada (significa desfazer o vínculo),
a falta dela já estiver apagada não é um erro grave e pode ser ignorado.

Sub DesvinculaTabelas()
On Error Resume Next

CurrentDb.TableDefs(“Pessoal”).Delete
CurrentDb.TableDefs(“Cargo”).Delete
CurrentDb.TableDefs(“Funcao”).Delete

End Sub

On Error Resume Next pode ser usado para tratar o erro imediatamente após a sua
ocorrência, sem desviar para um rótulo.

Sub TrataErroImediatamente()
Dim obj As Object

On Error Resume Next


Set obj = CreateObject("Outlook.Application")
If Err.Number <> 0 Then
' Err.Number é 429
' Err.Description é ActiveX component can’t create object
MsgBox "Não foi possível criar o objeto Outlook"
Else
.
.
End If

End Sub

10.1.6. Evento Erro


A instrução On Error pode ser usada em módulo padrão e módulo de classe. Em
módulo de classe há uma outra maneira de interceptar error: é o evento On Error (Ao Ocorrer
Erro, em português) dos objetos formulário e relatório.
O evento On Error detecta somente os erros do Jet Engine e não erros do VBA. Se um
campo que não aceita nulo receber um nulo será gerado um evento de erro, porque é um erro
do Jet Engine. Se o código tentar uma divisão por zero, o erro não é interceptado pelo evento
On Erro, porque é um erro do VBA. Neste caso, tem que se usar a instrução On Error.

108
Microsoft© Access Avançado

10.2. Depuração do Programa

À vezes ocorre um erro persistente, difícil de ser solucionado, para o qual são
necessários executar o programa passo-a-passo, interromper o programa para verificar o
conteúdo das variáveis e prosseguir o programa a partir da interrupção.
Para parar o programa em pontos críticos, podem ser colocados um ou mais Pontos de
Interrupção (tecla F9 põe e tira pontos de interrupção). Nestes pontos o programa é
interrompido e a janela do módulo é aberta. Pode-se então prosseguir com a tecla F8, para
executar o programa passo-a-passo ou F5 para continuar normalmente até outro ponto de
interrupção ou até o fim do programa.
Durante a interrupção, pode-se abrir a janela Depurar (Control G) e verificar o valor
das variáveis ou executar um comando interativamente, inclusive alterando o valor de
algumas variáveis.

Na figura acima, a linha marcada com um círculo é um ponto de interrupção e a linha


marcada com seta é a linha atualmente executada. Na janela Depurar (Debug Windows, em
inglês) foi dado o comando ? xlsSheet.Application, o qual retornou Microsoft Excel (que é o
nome do objeto pai).
Após depurar o programa, não se esqueça de limpar todos os pontos de interrupção.

109
Microsoft© Access Avançado

110
Microsoft© Access Avançado
11. AUTOMAÇÃO
A automação (antigamente chamada de Automação OLE) é um recurso do COM
(Component Object Model), um padrão da indústria de informática utilizado pelos aplicativos
para expor os seus objetos a ferramentas de desenvolvimento, linguagens de macro e a outros
aplicativos que suportam automação. Por exemplo, um aplicativo de planilha pode expor uma
planilha, gráfico, célula ou intervalo de células— como diferentes tipos de objetos. Um
processador de textos pode expor objetos como um aplicativo, um documento, um parágrafo,
uma frase, um indicador ou uma seleção.
Quando um aplicativo suporta automação, os objetos expostos por ele podem ser
acessados pelo Visual Basic. Para manipular esses objetos no Visual Basic, execute métodos
sobre o objeto ou obtenha e defina as propriedades do objeto. Por exemplo, você pode criar
um objeto de automação nomeado MyObj e gravar o código apresentado a seguir para acessá-
lo:

MyObj.Insert "Oi, mundo." ' Insere um texto.


MyObj.Bold = True ' Formata o texto.
MyObj.SaveAs "C:\PROCTXT\DOCS\OBJTEST.DOC" ' Grava o objeto.

Os objetos que que expõem suas funcionalidades é chamado pela Microsoft de


ActiveX. O termo ActiveX engloba também os controles OLE, antigamente chamados de
componentes OCX (isto porque os arquivos têm a terminação .ocx). Atualmente, o termo
ActiveX tem sido substituído por COM – Component Object Model.
Há dois tipos de elementos na automação:
 Os servidores de automação, que podem ser controlados porque suas funcionalidades são
expostas e podem ser acessadas por outras aplicações. Exemplos de servidores de
automação: todos os softwares do Microsoft Office, Schedule+ e o Project.
 Os controladores de automação, que podem controlar servidores de automação através de
código de programação, acessando a funcionalidade exposta pelos servidores de
automação. Exemplos de controladores: MS Visual Basic, MS Visual C++, MS FoxPro e
o VBA (que está embutido no Access, Excel, Word e Project).

A automação permite extrair o que há de melhor dos softwares especialistas e integrá-


los. Por exemplo, pode-se usar o Access, especializado em banco de dados, para processar
dados de vendas e exportá-los para uma planilha do Excel. O Excel, especializado em gráfico,
pode gerar um gráfico de barras, mostrando a evolução das vendas. Este gráfico pode ser
exportado para um relatório trimestral de vendas, que está digitado no Word. Todo este
processo poderia ser manual, usando-se os recursos de copiar e colar. A automação faz tudo
isto com um simples disparo de um código em VBA.
Para usar a automação, no entanto, é necessário conhecer os objetos, propriedades e
métodos de cada um dos aplicativos envolvidos, sem contar com o conhecimento da
linguagem de programação Visual Basic.
No VBA existem duas funções chaves para realizar a automação. GetObject() e
CreateObject().
GetObjetc() obtém um objeto ActiveX de uma determinada classe de objetos. Sua
sintaxe e argumentos são:
111
Microsoft© Access Avançado

GetObject([pathname] [, class])

Pathname Opcional; Variant (String). Indica o caminho completo e nome do arquivo que
contém o objeto a ser recuperado. Se pathname for omitido, class passa a ser
obrigatório.
class Opcional; Variant (String). Uma seqüência de caracteres que representa a classe
do objeto.

O argumento class utiliza a sintaxe nomedoaplic.tipodeobjeto e possui partes a seguir:

Parte Descrição
nomedoaplic Obrigatória; Variant (String). Nome do aplicativo que fornece o objeto.
tipodeobjeto Obrigatória; Variant (String). Tipo ou classe do objeto a ser criado.

O objeto retornado por GetObject é atribuído a uma variável do mesmo tipo,


possibilitando invocar seus métodos e acessar suas propriedades. O exemplo abaixo obtém
um objeto Application do Word. A propriedade Visible é setada para que a janela do
aplicativo aparece na tela. É usado o método Open, da coleção Documents, para abrir um
documento existente.

Dim wrd As Object


Set wrd = GetObject(, "Word.Application")
wrd.Visible = True
wrd.Documents.Open "C:\Meus Documentos\Temp.doc"
Set wrd = Nothing

CreateObject() cria e retorna a referência de um objeto ActiveX da classe especificada


em seu argumento. O argumento é obrigatório e é o mesmo argumento [class] da função
GetObject().

11.1. Automação com o Microsoft Word

112
Microsoft© Access Avançado
Hierarquia dos Objetos do Microsoft Word

O exemplo abaixo cria um novo objeto Application do Word. É usado o método


TypeText, do objeto Selection, para inserir um texto. O documento é salvo e o aplicativo é
encerrado. A referência ao objeto é encerrada atribuindo-se Nothing à variável.

Dim objWord As Object


Set objWord = CreateObject("Word.Application")
objWord.Visible = True
objWord.Documents.Add
objWord.Selection.TypeText Text:="Carlos Koga"
objWord.ActiveDocument.SaveAs FileName:="C:\Koga.doc"
objWord.Quit
Set objWord = Nothing

11.2. Automação com o Microsoft Excel

Hierarquia do Objetos do Microsoft Excel

113
Microsoft© Access Avançado

Detalhamento do Objeto Worksheets

114
Microsoft© Access Avançado

Detalhamento do Objeto Charts

Detalhamento do Objeto Chartgroups

115
Microsoft© Access Avançado

Normalmente, ao abrir o Excel no Windows, abre-se automaticamente um novo


Workbook (Pasta de Trabalho, em português) chamado Book1 (Pasta1, em português) com
três Worksheets (planilhas) denominados Sheet1, Sheet2, Sheet3 (em português, são Plan1,
Plan2 e Plan3, respectivamente). Cada Worksheet possui várias células, referenciadas por
coordenadas de colunas de A a IV e linhas de 1 a 65536.
Este são os principais objetos do Excel. O próprio Excel, o Workbook, o Worksheet e
o Range (que são as células), nesta ordem de hierarquia.
O objeto de mais alto nível é o Application. Ele representa o próprio programa Excel.
No modo programado, o objeto Application não possui de imediato nenhum
Workbook (Pasta de Trabalho, em português) e, consequentemente, nenhum Worksheet
(planilha) e nenhum Range.
O Excel pode abrir um ou mais workbooks. Workbooks (no plural) é uma coleção de
objetos Workbook (no singular). Um objeto workbook é um arquivo .XLS. Note que na
hierarquia de objetos, Workbooks está abaixo do objeto Application. Note também que a
legenda do modelo está errada, pois indica que Workbook é apenas objeto. Na realidade é
coleção e objeto.
Um workbook possui um ou mais Worksheets. Worksheets (no plural) é uma coleção
de objetos Worksheet (no singular). Note que no modelo de objetos Worksheet está abaixo de
Workbook.
Cada worksheet (planilha) contém células, que são os objetos Range (intervalo). A
célula A1 é referenciada por Range(“A1”). As células de A1 a C5 são referenciadas por
Range(“A1:C5”).

116
Microsoft© Access Avançado

Para criar uma instância do objeto Excel, usa-se a função CreateObject() do VBA.
Exemplo:

Sub InstanciaExcel()
Dim xls As Excel.Application

' Cria uma instância do objeto Excel


Set xls = CreateObject(“Excel.Application”)

' Propriedade para tornar o objeto visível


xls.Visible = True

MsgBox “Clique em OK para fechar o Excel”

' Método para fechar o Excel


xls.Quit

Set xls = Nothing ' Libera memória


End Sub

O procedimento acima abre o Excel e o fecha ao clicar OK na caixa de mensagem.


A figura abaixo é a repersentação visual do objeto Excel.Application. Perceba que ele
não contém nenhum objeto Workbook ainda.
117
Microsoft© Access Avançado

Para termos uma janela do Excel com um workbook, temos que acrescentar uma linha
de código, invocando o método Add da coleção Workbooks.

Sub InstanciaExcel()
Dim xls As Excel.Application

' Cria uma instância do objeto Excel


Set xls = CreateObject(“Excel.Application”)

' Propriedade para tornar o objeto visível


xls.Visible = True

' Cria um workbook novo.


' Por default, ele se chama Book1 e possui três worksheets
xls.WorkBooks.Add

MsgBox “Clique em OK para fechar o Excel”

' Método para fechar o Excel


xls.Quit

Set xls = Nothing ' Libera memória


End Sub

O objeto Excel.Application tem agora um objeto Workbook. Logo a sua coleção


Workbooks contém apenas um objeto Workbook, chamado Book1.
Para referenciar um objeto Workbook dentro da coleção, usa-se um índice ou o seu
nome dentro de parênteses.

xls.Workbooks(1) ou

xls.Workbooks(“Book1”)

118
Microsoft© Access Avançado
Note que a referência deve seguir a hierarquia dos objetos. Primeiro Application,
seguida de Workbooks.

Sub InstanciaExcel()
Dim xls As Excel.Application

' Cria uma instância do objeto Excel


Set xls = CreateObject("Excel.Application")

' Propriedade para tornar o objeto visível


xls.Visible = True

' Cria um workbook novo.


' Por default, ele se chama Book1 e possui três worksheets
xls.Workbooks.Add

xls.Workbooks(1).Worksheets(1).Range("A1") = 4
xls.Workbooks(1).Worksheets(1).Range("B1") = 6
xls.Workbooks(1).Worksheets(1).Range("C1") = "=A1 + B1"

MsgBox "Clique em OK para fechar o Excel"

' Salva o workbook como Teste.xls


xls.Workbooks(1).SaveAs "C:\Teste.xls"

' Método para fechar o Excel


xls.Quit

Set xls = Nothing


End Sub

O exemplo a seguir mostra como ler cada registro de um recordset do Access,


gravando cada campo em uma célula.

Dim xlsPlan As Object


Dim rstPessoal As Recordset
Din lngLine As Long

Set xlsPlan = CreateObject("Excel.Sheet")


Set rstPessoal = CurrentDb.OpenRecordset("qryRelacaoDePessoal")

lngLine = 1
Do While Not rstPessoal.EOF
xlsPlan.Application.Cells(lngLine, 1) = rstPessoal.Fields(“Matricula”)
xlsPlan.Application.Cells(lngLine, 2) = rstPessoal.Fields(“Nome”)
xlsPlan.Application.Cells(lngLine, 3) = rstPessoal.Fields(“CodOrgao”)
xlsPlan.Application.Cells(lngLine, 4) = rstPessoal.Fields(“CodCargo”)
xlsPlan.Application.Cells(lngLine, 5) = rstPessoal.Fields(“CodFuncao”)
rstPessoal.MoveNext
lngLine = lngLine + 1
Loop

xlsPlan.SaveAs ("C:\Pessoal.xls")
rstPessoal.Close
Set xlsPlan = Nothing

119
Microsoft© Access Avançado

xlsPlan é um objeto Workbook. A propriedade Application retorna o objeto


Application, que possui a propriedade Cells.

Outro exemplo mais sofisticado é gerar e imprimir um gráfico de barras tridimensional do


Excel a partir de uma consulta referência cruzada do Access.

REGIAO PROD A PROD B PROD C


LESTE 111 54 78
NORTE 245 200 114
OESTE 99 34 48
SUL 210 348 442

Dim xls As Object


Dim rst As Recordset
Dim intLinha As Integer, intColuna As Integer

Set rst = CurrentDb.OpenRecordset(“qryConsumo por Produto e Por Regiao”)


Set xls = CreateObject("Excel.application")
xls.Workbooks.Add

' Insere na linha 1 os cabeçalhos de cada coluna


For intColuna = 1 to rst.Fields.Count
xls.Cells(1, intColuna) = rst.Fields(intColuna – 1).Name
Next

intLinha = 2
Do While Not rst.EOF
' Insere os valores de cada coluna
For intColuna = 1 to rst.Fields.Count
xls.Cells(intLinha,intColuna) = rst.Fields(intColuna – 1)
Next
intLinha = intLinha + 1
rst.MoveNext
Loop

xls.Range("A1:D5").Select
xls.Charts.Add
xls.ActiveChart.ChartType = -4100
xls.ActiveChart.SetSourceData xls.Worksheets("Plan1").range("A1:D5"), 2
xls.ActiveChart.Location 1
With xls.ActiveChart
.HasTitle = True
.ChartTitle.Characters.Text = "Consumo por Regiao"
.Axes(1).HasTitle = True
.Axes(1).AxisTitle.Characters.Text = "Produtos"
.Axes(3).HasTitle = True
.Axes(3).AxisTitle.Characters.Text = "Regiao"
.Axes(2).HasTitle = False
End With
xls.ActiveWindow.SelectedSheets.PrintOut Copies:=1

Neste exemplo, xls é um objeto Application, que possui as propriedades Cells, Range (retorna
o objeto Range), ActiveChart (que retorna o objeto Chart atual) e ActiveWindow (que
retorna o objeto Window atual) e as coleções Workbooks e Charts.

120
Microsoft© Access Avançado

11.3. Automação com Microsoft Project 95

Hierarquia dos Objetos do Microsoft Project 95 (versão 4.1)

A utilidade da automação com o Microsoft Project é mostrada no exemplo a seguir. Uma


tabela do Access contém os eventos de cursos a serem realizados. Cada evento tem as datas de
início e de término, o que não permite uma visualização fácil de todos os eventos
programados num período de tempo. O Project possui o gráfico de Gantt, como mostrado
abaixo, que torna a grade de eventos.

O código a seguir possibilita inserir os dados dos eventos de cursos em um arquivo do Project
e imprimir o gráfico de Gantt, automaticamente.

Dim prjApp As Object


Dim prjProj As Object

121
Microsoft© Access Avançado
Dim rst As Recordset
Dim intI As Integer

Set rst = CurrentDb.OpenRecordset("Cursos")


Set prjApp = CreateObject("MSProject.Application")

prjApp.filenew

Set prjProj = prjApp.projects(1)


intI = 1
Do While Not rst.EOF
prjProj.tasks.Add rst.Fields("Evento")
prjProj.tasks(intI).start = rst.Fields("DataInicio")
prjProj.tasks(intI).finish = rst.Fields("DataTermino")
rst.MoveNext
intI = intI + 1
Loop

prjApp.FileSaveas "C:\Temp\cursos.mpp"
prjApp.fileprint 1, 1, False, False, 1, Null, Null, True, False, False
prjApp.Quit

11.4. Automação com Schedule+ 7.0

122
Microsoft© Access Avançado
Hierarquia dos Objetos do Schedule+ 7.0

O exemplo a seguir mostra como criar um novo compromisso (Almoço), que iniciar-
se-á na data/hora do sistema operacional e durará 1 hora. Este exemplo pode ser aperfeiçoado,
integrando a automação com o Project, para criar compromissos para o instrutor do curso.

Dim objSch As Object


Dim objApontamento As Object

Set objSch = CreateObject(“SchedulePlus.Application”)


objSch.Logon
objSch.ScheduleSelected.Activate

Set objApontamento = objSch.ScheduleSelected.SingleAppointments.New


objApontamento.SetProperties Text:= “Almoço”, _
Start:=Now(), End:= Now() + Format(“01:00”)
objSch.Logoff

11.5. REFERÊNCIA À BIBLIOTECA DE OBJETOS

Para acessar objetos, propriedades, métodos e constantes intrínsecas de outros


softwares, é preciso que as referências aos arquivos de acesso a objetos estejam
estabelecidas.
Uma aplicação Access típica faz referência a três bibliotecas de objetos:

• Arquivo de acesso a objetos do Access (tais como formulários e relatórios) e constantes


do Access (referência obrigatória).
• Arquivo de acesso a objetos (todos os comandos e constantes) do VBA (referência
obrigatória).
• Arquivo de acesso a objetos de dados - DAO (referência necessária apenas se for acessar
dados).

123
Microsoft© Access Avançado

Os arquivos que permitem o acesso a objetos do Access são:


Arquivo Nome Descrição
Msaccess.tlb Microsoft Access for Windows 95 Para o Access 95 (versão 7.0),
em português
Msacc8.olb Microsoft Access 8.0 Object Library Para o Access (versão 8.0) em
inglês
Msacc8.tlb Microsoft Access 8.0 Object Library Para o Access (versão 8.0) em
português

O arquivo que permite o acesso a objetos do VBA é:


Arquivo Nome Descrição
Ven2232.olb Visual Basic for Applications Para a versão 2.2, em inglês

Os arquivos que permitem o acesso a objetos da DAO são:


Arquivo Nome Descrição
Dao350.dll Microsoft DAO 3.5 Object Library Para a versão 3.5
Dao3021.dll Microsoft DAO 3.0 Object Library Para a versão 3.0
Dao2532.tlb Microsoft DAO 2.5/3.0 Compatibility Para compatibilidade das versões
Library 2.5 e 3.0
Dao2535 Microsoft DAO 2.5/3.5 Compatibility Para compatibilidade das versões
Library 2.5 e 3.5

Os arquivos que permitem acesso a objetos dos aplicativos Microsoft são:


Arquivo Nome Descrição
Sp7en32.olb Microsoft Schedule+ 7.0 Object Library Para a versão em inglês
Xl5en32.olb Biblioteca de objetos do Microsoft Excel Para a versão 5.0 em português,
5.0 com sintaxe de comandos em
inglês
Xl5pt32.olb Biblioteca de objetos do Microsoft Excel Para a versão 5.0 em português,
5.0 com sintaxe de comandos em
português
Excel8.olb Microsoft Excel 8.0 Object Library Para a versão em inglês
Pj4en32.olb Microsoft Project 4.1Object Library Para a versão 95 em inglês
Msword8.olb Microsoft Word 8.0 Object Library Para a versão em português, com
sintaxe de comandos em inglês
Graph8.olb Microsoft Graph 8.0 Object Library Para a versão em inglês
Grptb50.olb Biblioteca de objetos do Microsoft Para a versão em português
Graph 5.0

As referências são estabelecidas no menu Ferramentas|Referências..., a partir de


uma janela de módulo aberta.

124
Microsoft© Access Avançado

Se estiver faltando alguma referência na lista de bibliotecas disponíveis, acione o


botão Procurar e localize o arquivo necessário.
É importante saber qual as versões dos objetos você está referenciando, pois em cada
uma há mudanças de sintaxes e até objetos, propriedades e métodos novos ou de
comportamento diferente. Por isto, um aplicativo que funciona perfeitamente em um
computador pode não funcionar em outro.
A referência às bibliotecas de objetos ajuda no tempo de codificação do programa,
pois os objetos, propriedades e métodos ficam visíveis na janela Object Browser (acionada
pela tecla F2). Veja na figura a seguir as propriedades e métodos do objeto ÁreaPlotagem da
biblioteca do Excel 5.0 com a sintaxe em português.

125
Microsoft© Access Avançado
12. CHAMADA À API DO WINDOWS 95
A API (Application Programming Interface) do Windows consiste de um conjunto de
bibliotecas de vínculo dinâmico (DLLs) ou arquivo de recursos (EXEs) contendo
procedimentos relacionados ao sistema operacional que incluem funções, mensagens,
estruturas de dados, tipos de dados e instruções que você pode usar na criação de aplicativos a
serem executados sob o Windows 95. Para chamar esses procedimentos a partir do Visual
Basic, você precisa primeiro declará-los usando uma instrução Declare. Você pode então
chamá-los como faria com qualquer outro procedimento.
A instrução Declare possui a seguinte sintaxe:

[Public | Private ] Declare Function|Sub nome Lib "nomedabibliot" [Alias "nomedoalias" ]


[([listadeargumento])][As tipo]

A sintaxe da instrução Declare tem estas partes:


Parte Descrição
Public Usada para declarar procedimentos que estão disponíveis em todos os
outros procedimentos em todos os módulos.
Private Usada para declarar procedimentos que estão disponíveis apenas
dentro do módulo onde a declaração é feita.
Sub Indica que o procedimento não retorna um valor.
Function Indica que o procedimento retorna um valor que pode ser usado numa
expressão.
nome Qualquer nome de procedimento válido.
Lib Indica que uma DLL ou recurso de código contém o procedimento que
está sendo declarado. A cláusula Lib é obrigatória para todas as
declarações.
nomedabibliot Nome da DLL ou do recurso de código que contém o procedimento
declarado.
Alias Indica que o procedimento que está sendo chamado tem um outro
nome na DLL ou está num recurso de código do Macintosh. É útil
quando o nome do procedimento externo é igual ao da palavra-chave.
Alias também pode ser usado quando um procedimento DLL tem o
mesmo nome de uma variável ou constante pública ou qualquer outro
procedimento no mesmo escopo. Alias também é útil se a convenção
de nomenclatura da DLL não permitir algum caractere no nome do
procedimento.
nomedoalias Nome do procedimento na DLL ou recurso do código.
listadeargumento Lista de variáveis que representam argumentos que são passados ao
procedimento quando ela é chamada.
tipo Tipo de dados do valor retornado por um procedimento Function; pode
ser Byte, Boolean, Integer, Long, Currency, Single, Double, Date,
String (apenas de tamanho flexível), Object, Variant, um tipo definido
pelo usuário ou um tipo de objeto.

O argumento listadeargumento tem a sintaxe e partes abaixo:

126
Microsoft© Access Avançado

[Optional][ByVal | ByRef][ParamArray] nomedavariáv[( )][As tipo]

Parte Descrição
Optional Indica que um argumento não é obrigatório. Se usada, todos os
argumentos subseqüentes na listadeargumento devem ser opcionais e
declarados pelo uso da palavra-chave Optional. Todos os argumentos
Optional devem ser Variant. Optional não poderá ser usada por
nenhum argumento se ParamArray for usada.
ByVal Indica que o argumento é passado por valor.
ByRef Indica que o argumento é passado por referência.
ParamArray Usada apenas pelo último argumento em listadeargumento para indicar
que o argumento final é uma matriz Optional de elementos Variant. A
palavra-chave ParamArray permite fornecer um número arbitrário de
argumentos. Não pode ser usada com ByVal, ByRef ou Optional.
nomedavariáv Nome da variável que representa o argumento que está sendo passado
ao procedimento; segue convenções de nomenclatura padrão de
variável.
tipo Tipo de dados do argumento passado ao procedimento; pode ser Byte,
Boolean, Integer, Long, Currency, Single, Double, Date, String
(apenas de comprimento flexível), Object, Variant, um tipo definido
pelo usuário ou um tipo de objeto.

Para usar a API, simplesmente saber a sintaxe não significa muito. É preciso saber:
• os nomes dos procedimentos embutidos
• em quais arquivos de biblioteca os procedimentos se encontram
• quais os argumentos devem ser passados
• quais os valores que os argumentos devem receber

Quanto aos itens 1 a 3, há uma relação gravada em um banco de dados


(Win32API.mdb) que contém as funções do WinAPI. Eis algumas delas:

Função Declaração
Beep Declare Function Beep Lib "kernel32" Alias "Beep" (ByVal dwFreq As
Long, ByVal dwDuration As Long) As Long
CharLower Declare Function CharLower Lib "user32" Alias "CharLowerA" (ByVal lpsz
As String) As String
GetOpenFileN Declare Function GetOpenFileName Lib "comdlg32.dll" Alias
ame "GetOpenFileNameA" (pOpenfilename As OPENFILENAME) As Long
GetSaveFileN Declare Function GetSaveFileName Lib "comdlg32.dll" Alias
ame "GetSaveFileNameA" (pOpenfilename As OPENFILENAME) As Long

Observação importante: As declarações das funções devem ser escritas seguindo fielmente a
tabela acima. Os nomes são sensíveis à caixa.

127
Microsoft© Access Avançado
As funções Beep e CharLower não apresentam problema para identificar os valores
que os argumentos devem receber. Os exemplos abaixo demonstram isto.

Option Explicit
Declare Function Beep Lib "kernel32" (ByVal dwFreq As Long, _
ByVal dwDuration As Long) As Long

Declare Function CharLower Lib "user32" Alias "CharLowerA" _


(ByVal lpsz As String) As String

Function Som()
Dim lngSom As Long
lngSom = Beep(500, 200)
lngSom = Beep(370, 100)
End Function

Function CaixaBaixa()
Dim str as String
str = CharLower(“CAIXA ALTA”)
MsgBox str
End Function

Entretanto, as funções GetOpenFileName e GetSaveFileName, assim como a maioria


das funções API, necessitam de documentação quanto à estrutura e os valores dos
argumentos. Por exemplo, OPENFILENAME é uma estrutura de dados definida pelo usuário
que contém os seguintes elementos.

lStructSize As Long
hwndOwner As Long
hInstance As Long
lpstrFilter As String
lpstrCustomFilter As
nMaxCustFilter As Long
nFilterIndex As Long
lpstrFile As String
nMaxFile As Long
lpstrFileTitle As String
nMaxFileTitle As Long
lpstrInitialDir As String
lpstrTitle As String
flags As Long
nFileOffset As Integer
nFileExtension As
lpstrDefExt As String
lCustData As Long
lpfnHook As Long
lpTemplateName As

128
Microsoft© Access Avançado
Os exemplos dessas duas funções, apresentados adiante, só foram possíveis graças ao
aplicativo Solutions, que acompanha o Access .

A função GetOpenFileName abre uma caixa de diálogo do tipo “Abrir”, retornando um valor
lógico que indica se o usuário clicou no botão Abrir (true) ou no Cancelar (false). O nome do
arquivo é armazenado no elemento lpstrFile de OPENFILENAME.

Option Compare Database


Option Explicit
Declare Function GetOpenFileName Lib "comdlg32.dll" _
Alias "GetOpenFileNameA" (pOpenfilename As OPENFILENAME) As Boolean
Declare Function GetSaveFileName Lib "comdlg32.dll" _
Alias "GetSaveFileNameA" (pOpenfilename As OPENFILENAME) As Boolean
Type OPENFILENAME
lStructSize As Long
hwndOwner As Long
hInstance As Long
lpstrFilter As String
lpstrCustomFilter As Long
nMaxCustrFilter As Long
nFilterIndex As Long
lpstrFile As String
nMaxFile As Long
lpstrFileTitle As String
nMaxFileTitle As Long
lpstrInitialDir As String
lpstrTitle As String
flags As Long
nFileOffset As Integer
nFileExtension As Integer
lpstrDefExt As String
lCustrData As Long
lpfnHook As Long
lpTemplateName As Long
End Type

Function CaixaDialogo_Open( )
Dim of As OPENFILENAME
Dim blnAbriu As Boolean ' Verifica se o usuário abriu ou cancelou.
' Poderia ser o retorno da função.
Dim strTitulo as String ' Título da caixa de diálog. Poderia ser um
' argumento
Dim strFiltro As String ' Filtro para o tipo de arquivo. Também
' poderia ser um argumento
Dim strDirInicial As String ´Diretório inicial. Idem

strTitulo = “Abrir banco de dados”


strFiltro = “Banco de dados Access” & Chr(0) & _
“*.mdb” & Chr(0) & Chr(0)
strDirInicial = “C:\”

of.hwndOwner = Application.hWndAccessApp
of.hInstance = 0
of.lpstrCustomFilter = 0
of.nMaxCustrFilter = 0
of.lpfnHook = 0
of.lpTemplateName = 0
129
Microsoft© Access Avançado
of.lCustrData = 0
of.lpstrFilter = strFiltro
of.nFilterIndex = 0
of.lpstrFile = String$(512, 0)
of.nMaxFile = 511
of.lpstrFileTitle = String$(512, 0)
of.nMaxFileTitle = 511
of.lpstrTitle = "Teste"
of.lpstrInitialDir = strDirInicial
of.lpstrDefExt = ""
of.flags = 0
of.lStructSize = Len(of)

blnAbriu = GetOpenFileName(of)

MsgBox blnAbriu ´True se clicou em Abrir. False se clicou em Cancelar


If blnAbriu Then
MsgBox of.lpstrFile ´ Nome do arquivo escolhido
End If
End Function

Function CaixaDialogo_Save( )
Dim of As OPENFILENAME
Dim blnSalvou As Boolean ' Verifica se o usuário salvou ou cancelou.
' Poderia ser o retorno da função.
Dim strTitulo As String ' Título da caixa de diálog. Poderia ser um
' argumento
Dim strFiltro As String ' Filtro para o tipo de arquivo. Também
' poderia ser um argumento
Dim strDirInicial As String 'Diretório inicial. Idem
Dim strNomeArq As String 'Nome sugerido para salvar. Idem
Dim strExtensaoDefault As String ' Extensão default. Idem

strTitulo = "Salvar banco de dados"


strFiltro = "Text files " & Chr(0) & "*.txt" & Chr(0) & Chr(0)
strDirInicial = "C:\"
strNomeArq = "Teste2"
strExtensaoDefault = "txt"

of.hwndOwner = Application.hWndAccessApp
of.hInstance = 0
of.lpstrCustomFilter = 0
of.nMaxCustrFilter = 0
of.lpfnHook = 0
of.lpTemplateName = 0
of.lCustrData = 0
of.lpstrFilter = strFiltro
of.nFilterIndex = 0
of.lpstrFile = strNomeArq & String$(512 - Len(strNomeArq), 0)
of.nMaxFile = 511
of.lpstrFileTitle = String$(512, 0)
of.nMaxFileTitle = 511
of.lpstrTitle = strTitulo
of.lpstrInitialDir = strDirInicial
of.lpstrDefExt = "txt"
of.flags = 0
of.lStructSize = Len(of)

blnSalvou = GetSaveFileName(of)
130
Microsoft© Access Avançado

MsgBox blnSalvou 'True se clicou em Salvar. False se clicou em Cancelar


If blnSalvou Then
MsgBox of.lpstrFile ' Nome do arquivo escolhido
End If

End Function

Estas funções não realizam operações de abertura/salvamento de arquivo, mas


simplesmente abrem caixas de diálogo para se selecionar os arquivos.

131
Microsoft© Access Avançado
13. SEGURANÇA

Antes de construir um aplicativo Access, você deve ter em mente que níveis de
segurança que o aplicativo deve atender. É mais construir um aplicativo com a segurança já
definida desde o início que definí-la após o aplicativo estiver pronto.
A segurança visa proteger os dados contra leitura de informações confidenciais,
alteração indevida, inclusão e exclusão de registros por pessoa não autorizada. A segurança
protege também a estrutura dos objetos e o acesso ao código-fonte dos módulos.
Existem várias formas de segurança:
 Senha de banco de dados: É a forma mais simples de proteger um banco de dados. Uma
vez definida a senha, uma caixa de diálogo solicita a entrada da senha. Todos os dados e
estruturas são acessíveis por quem informar a senha correta.
 Criação de arquivo MDE: Cria uma cópia do banco de dados, com extensão .MDE, o que
torna impossível visualizar, criar ou alterar código VBA. Impede também a criação e
alteração de formulários e relatórios.
 Criptografia: Torna a leitura dos dados impossível através de um processador de texto ou
outra ferramenta de acesso a disco. Abrindo o banco de dados no próprio Access, a
criptografia é imperceptível, a não ser a perda de desempenho de 10 a 15%.
 Segurança em nível de usuário: Define permissões de leitura, gravação e alteração de
estrutura por objeto e usuário (ou grupo de usuários). É a forma mais completa de
segurança.

Você pode combinar utilizar todas as formas de segurança em um mesmo aplicativo.

13.1. SENHA DE BANCO DE DADOS

13.1.1. DEFININDO UMA SENHA PARA O BANCO DE DADOS

Para definir uma senha para o banco de dados, o arquivo MDB que você quer proteger
deve estar em uso.

1) Antes de definir uma senha, faça uma cópia de segurança do banco de dados que você
quer proteger.
2) Se você trabalha em rede, assegure-se que ninguém mais esteja com o banco de dados em
uso.
3) Abra o banco de dados no modo exclusivo. Na caixa de diálogo Abrir, acionada pelo
menu Arquivo|Abrir banco de dados…, há uma caixa de verificação Exclusivo.
4) A senha para um banco de dados é feita pelo menu Ferramentas|Segurança|Definir
senha do banco de dados…. Ao acionar o menu, será aberta a seguinte caixa de diálogo.
Digite a senha, confirme e clique Ok

132
Microsoft© Access Avançado

Observações:
 Você pode definir uma senha de até 14 caracteres, entre letras, números e caracteres
especiais. A senha é sensível a letras maiúsculas e minúsculas.
 Guarde a senha e a cópia de segurança do banco de dados em lugar seguro, pois em caso
de esquecimento, é impossível descobrí-la.
 Se você pretende replicar seu banco de dados, não configure senha de banco de dados,
pois a replicação não funciona em banco de dados protegidos por senha.

13.1.2. ABRINDO UM BANCO DE DADOS PROTEGIDO POR SENHA

Ao abrir um banco de dados protegido por senha, uma caixa de diálogo solicitará a
senha.

Caso a senha esteja correta, o banco de dados é aberto normalmente, com acesso a
todos os dados e objetos.

13.1.3. REMOVENDO SENHA DE BANCO DE DADOS

Após ter aberto o banco de dados com a senha correta e no modo exclusivo, você pode
remover a senha e voltar o banco de dados à situação normal.
Num banco de dados protegido por senha, o menu Ferramentas|Segurança|Definir
senha do banco de dados… passa a ser Ferramentas|Segurança|Desproteger senha do
banco de dados…. Ao acionar este menu, será pedida novamente a senha e o banco de dados
é então desprotegido.

13.1.4. DEFININDO SENHA POR CÓDIGO VBA

133
Microsoft© Access Avançado
Você pode definir uma senha do banco de dados por código VBA, utilizando os
objetos do DAO. O método para definir a senha é NewPassword do objeto Database. O
código não pode ser escrito no mesmo banco de dados o qual se deseja proteger.

Sub SetDBPassword()
' Declara a variável do objeto database.
Dim dbs As Database

' Abre o banco de dados em modo exclusivo.


Set dbs = OpenDatabase("C:\bd1.mdb", True)

' Define a senha e fecha o banco de dados.


dbs.NewPassword "","topsecret"
dbs.Close
End Sub

13.1.5. ABRINDO UM BANCO DE DADOS PROTEGIDO VIA CÓDIGO VBA

Para abrir um banco de dados protegido via código VBA, utilize o método
OpenDatabase.

Sub OpenProtectedDB()
' Declara a variável do objeto database.
Dim dbs As Database

' Abre o banco de dados protegido em modo compartilhado.


Set dbs = OpenDatabase("C:\bd1.mdb", False, False, ";pwd=topsecret")

End Sub

13.1.6. ALTERANDO A SENHA VIA CÓDIGO VBA

Você pode também alterar a senha via código usando o método NewPassword do
objeto Database. O código não pode ser escrito no mesmo banco de dados o qual se deseja
trocar a senha.

Sub ChangeDBPassword()
' Declara a variável do objeto database.
Dim dbs As Database

' Abre o banco de dados em modo exclusivo.


Set dbs = OpenDatabase("C:\bd1.mdb", True, False, ";pwd=topsecret"))

' Define a senha e fecha o banco de dados.


dbs.NewPassword "topsecret", "novasenha"
dbs.Close
End Sub

134
Microsoft© Access Avançado

13.2. CRIAÇÃO DE ARQUIVO MDE

Você pode criar um arquivo de extensão .MDE a partir de um arquivo .MDB. Não é
preciso que o banco de dados .MDB esteja em uso.
Num arquivo MDE todas as estruturas de formulários, relatórios e módulos ficam
ocultas e inacessíveis. Você não pode criar novos formulários, relatórios e módulos, nem
exportar estes objetos, nem importar estes objetos de outros banco de dados .MDE.
Entretanto, tabelas, consultas e macros permanecem acessíveis e podem ser importados e
exportados.
Se você alterar seu banco de dados original, deve criar novamente um arquivo .MDE.
Mantenha sempre uma cópia de segurança do banco de dados original, pois não é possível
desfazer um arquivo .MDE.
Arquivos MDE são ideais para a distribuição da sua aplicação front-end, isto é, um
banco de dados de extensão MDE possui as consultas, formulários, relatórios, macros e
módulos que acessam outros bancos de dados que contêm as tabelas.

Arquivos .MDB

Arquivo .MDE Tabelas

Aplicativo Tabelas

Tabelas

Para criar um arquivo MDE, siga os passos:

1) Antes de criar um arquivo .MDE, faça uma cópia de segurança do banco de dados
original.
2) Se você trabalha em rede, assegure-se que ninguém mais esteja com o banco de dados em
uso.
3) Acione o menu Ferramentas|Utilitários de banco de dados|Criar arquivo MDE …
4) Na caixa de diálogo “Salvar banco de dados como MDE”, escolha o banco de dados
original e clique no botão Criar MDE.
5) Na caixa de diálogo “Salvar como MDE”, escolha o nome do novo arquivo e clique no
botão Criar.

Se o banco de dados original fizer referência a outros bancos de dados MDB ou banco
de dados de suplemento (.MDA), estes devem também ser convertidos para MDE, na ordem
em que eles são referenciados. Por exemplo, se o seu banco de dados db3.mdb referencia
db2.mdb que por sua vez referencia db1.mda, a ordem deve ser db1.dba, db2.mdb e db3.mdb.
135
Microsoft© Access Avançado
Para um bom nível de segurança, defina senhas para o banco de dados do aplicativo
(extensão MDE) e para cada banco de dados de tabelas (extensão MDB). Dentro do código do
aplicativo, vincule as tabelas necessárias via código VBA, passando a senha. Como o código
do aplicativo ficará inacessível, a senha ficará a salvo no código. Desta forma, as tabelas
também ficam protegidas contra alteração de estrutura, já que tabelas vinculadas não podem
ter suas estruturas alteradas.
Eis um código VBA para vincular uma tabela de uma banco de dados protegido por
senha.

Sub LinkTable()
Dim dbs As Database
Dim tdfs As TableDefs
Dim tdf As TableDef

Set dbs = CurrentDb


Set tdfs = dbs.TableDefs
Set tdf = dbs.CreateTableDef("Order Linked")
tdf.Connect = ";database=c:\bd1.mdb; pwd=topsecret"
tdf.SourceTableName = "Order"
tdfs.Append tdf

End Sub

Nesta configuração, os dados das tabelas ainda ficam vulneráveis à alteração, assim
como as estruturas das consultas. Os dados somente podem ser protegidos com a segurança
em nível de usuário. Quanto as consultas, você pode minimizar o problema com as seguintes
recomendações:

1) Define a propriedade Origem do Registro de formulários e relatórios como uma tabela ou


uma consulta SQL (chamando o Construtor de Consulta ou passando a expressão SQL
diretamente).
2) Defina consultas de ação em código VBA, construindo consultas com expressões em SQL
e utilizando o método RunSQL objeto DoCmd.
3) Abra consultas que retorna folha de dados em sub-formulários. Defina consultas seleção
ou referência cruzada em código VBA, construindo consultas com expressões em SQL e
passando a expressão como propriedade RecordSource do subformulário.

Eis um exemplo de consulta de ação definida em código VBA.

Sub DeleteCliente()
Dim strSql As String

strSql = "DELETE * FROM Clientes"


DoCmd.RunSQL (strSql)
End Sub

Eis um exemplo de como passar uma consulta de ação para um subformulário.


Private Sub cmdAbrir_Click( )
136
Microsoft© Access Avançado
Dim strSql as String
strSql = "SELECT * FROM [Detalhes do Pedido]"
Me![subfrmDetalhe].Form.RecordSource = strSql
Me![subfrmDetalhe].Requery
End Sub

13.3. CRIPTOGRAFIA DE BANCO DE DADOS

A criptografia protege o banco de dados contra acesso a seus dados via um editor de
texto ou outra ferramenta de acesso a disco. Ela deve ser usada juntamente com a senha de
banco de dados, pois se alguém abrir um banco de dados diretamente pelo Access, a
criptografia não tem efeito nenhum.
Note a ao abrir o banco de dados Northwind.mdb, pelo Wordpad, dados podem ser
lidos.

No arquivo criptografado, todos os dados ficam ilegíveis.

137
Microsoft© Access Avançado
A criptografia é um processo reversível. Você pode criptografar um banco de dados e
depois decriptografá-lo.

13.3.1. CRIANDO UM ARQUIVO CRITPTOGRAFADO


1) Abra o MS Access.
2) Certifique-se que o arquivo a ser criptografado não esteja em uso.
3) No menu Ferramentas|Seguraça escolha Criptografar/decriptografar banco de
dados..
4) Na caixa de diálogo “Criptografar/Decriptografar banco de dados”, selecione um
arquivo não criptografado e clique Ok.
5) Na caixa de diálogo “Criptografar banco de dados”, informe o novo nome do arquivo e
clique Salvar.

13.3.2. REVERTENDO A CRITPTOGRAFIA


1) Abra o MS Access.
2) Certifique-se que o arquivo a ser decriptografado não esteja em uso.
3) No menu Ferramentas|Seguraça escolha Criptografar/decriptografar banco de
dados..
4) Na caixa de diálogo “Criptografar/Decriptografar banco de dados”, selecione um
arquivo criptografado e clique Ok.
5) Na caixa de diálogo “Descriptografar banco de dados”, informe o novo nome do
arquivo e clique Salvar.

13.3.2. CRIPTOGRAFIA POR CÓDIGO VBA


Use o médodo CompactDatabase do objeto DBEngine para criptografar outro banco
de dados.

Sub EncryptDb()
DBEngine.CompactDatabase "C:\bd1.mdb", "C:\db1Cripto.mdb", _
dbLangGeneral, dbEncrypt
End Sub

13.4. SEGURANÇA EM NÍVEL DE USUÁRIO

A segurança em nível de usuário é o modo mais flexível e seguro de proteger um


banco de dados. Com ele, para cada objeto, pode-se definir permissões de:
 abrir/executar (para formulário, relatório e macro)
 leitura de dados (para tabela e consulta),
 inserção de dados (para tabela e consulta),
 exclusão de dados (para tabela e consulta),
 alteração de dados (para tabela e consulta),
 visualização de estrutura,
138
Microsoft© Access Avançado
 alteração de estrutura e
 administração.

Ainda pode-se definir permissões para o banco de dados:


 Abrir/executar,
 Abrir exclusivo e
 Administração

As permissões são definidas para cada usuário (chamada permissão explícita) ou para
grupo de usuários (chamada permissão implícita). Neste último caso, os usuários membros do
grupo herdam as permisssões do grupo. As definições das permissões ficam armazenadas em
um arquivo de informação de grupo de trabalho, de extensão .MDW.
Por padrão, o arquivo de informação de grupo de trabalho é o SYSTEM.MDW e
existem dois grupos pré-definidos:
 Administradores (Admins, na versão em inglês)
 Usuarios (Users, na versão em inglês)

Existe ainda um usuário pré-definido, o Adminsitrador (Admin, na versão em inglês)


que pertence a ambos os grupos pré-definidos.
O arquivo de informação de grupo de trabalho pode ser associado a todos os bancos de
dados ou a apenas um especificamente. O segundo método é o mais adequado, pois você
define segurança por aplicativo.
Ao definir segurança em nível de usuário, ao abrir o banco de dados será apresentada
uma caixa de diálogo de Logon para que seja informado o nome do usuário e a senha. Se o
usuário e a senha estiverem corretos, o banco de dados é aberto e permitirá que o usuário
execute somente as tarefas definidas nas permissões.
As permissões sobre os objetos podem ser alteradas:
 Por membros do grupo Administradores.
 Pelo proprietário do objeto.
 Por usuários que tenha permissão Administração sobre o objeto.

13.4.1. PROPRIEDADE SOBRE O BANCO DE DADOS E OBJETOS

Por padrão, o usuário Administrador é o proprietário do banco de dados e de todos os


objetos nele contidos. Proprietário é o usuário que criou o objeto. Na segurança em nível de
usuário não é possível retirar a permissão de usuários criarem objetos. Criando-se um arquivo
MDE, pode-se evitar que novos formulários, relatórios e módulos sejam criados. Via
programação, pode-se retirar permissões de usuários de criarem novas tabelas e consultas e
novos banco de dados, mas não se pode retirar permissão de criar formulários, relatórios,
macros e módulos.

13.4.2. IMPLEMENTANDO SEGURANÇA EM NÍVEL DE USUÁRIO

139
Microsoft© Access Avançado
 Crie um novo arquivo de informação de grupo de trabalho.
1) Clique no atalho para o “Administrador de grupo de trabalho do MS Access”. Surgirá a
caixa de diálogo a seguir:

2) O arquivo SYSTEM.MDW é o arquivo padrão de informação de grupo de trabalho.


Clique no botão Criar.

3) Surgirá uma caixa de diálogo para definir o proprietário do grupo de trabalho. Guarde
bem as informações, incluindo se as letras estão em maiúsculas ou minúsculas.

4) Ao clicar OK, surgirá uma caixa de diálogo para o nome e localização do novo arquivo de
informação de grupo de trabalho.

140
Microsoft© Access Avançado

5) Ao clicar OK, uma caixa de diálog surgirá confirmando o novo arquivo de informação de
grupo de trabalho. Ao abrir o Access, todos os bancos de dados utilizarão o novo arquivo
para a segurança em nível de usuário.

Observação: Você pode pensar em simplesmente criar um arquivo MDW a partir de uma
cópia do system.mdw. Este método não funciona, pois cada arquivo tem uma identificação
única, formada pelo Nome, Empresa e Código do grupo de trabalho.

 Crie um usuário proprietário e administrador


1) Inicie o Access, sem abrir ou criar nenhum banco de dados. Acione o menu
Ferramentas|Segurança|Contas de usuário e grupo…
2) Na caixa de diálogo Contas de usuário e grupo, crie um novo usuário que será o
proprietário e administrador do banco de dados de seu aplicativo e inclua-o no grupo
Administradores. Usaremos para exemplo o usuário Master.

141
Microsoft© Access Avançado

3) Na caixa de combinação Nome, selecione o usuário Administrador e retire-o do grupo


Administradores.
4) Na guia Alterar senha de logon, informe uma senha para o usuário Administrador. Isto
fará com que uma caixa de diálogo de logon apareça ao abrir o Access.
5) Clique no botão OK e saia do Access.
6) Abra novamente o Access. Surgirá a caixa de logon. Informe o novo usuário, no caso
Master. A senha não foi definida ainda e portanto, pode clicar OK.
7) Acione o menu Ferramentas|Segurança|Contas de usuário e grupo…, selecione a guia
Alterar senha de logon, informe uma senha para o usuário Master. Clique Ok.

Observação: Se você não retirar o usuário Administrador do grupo Administradores, qualquer


um poderá acessar seu banco de dados usando o arquivo padrão system.mdw. O usuário
Administrador permanece no grupo Usuários e não pode ser retirado desde grupo.

 Criar um banco de dados novo sem permissões de usuário


1) Crie um banco de dados novo. O usuário Master será o proprietário do banco de dados. O
grupo Administradores e Usuarios terão todas as permissões sobre todos os objetos e
sobre o banco de dados novo.
2) Acione o menu Ferramentas|Segurança|Permissões para usuário e grupo….

142
Microsoft© Access Avançado
3) Mude para listar Grupos e selecione o grupo Usuários. Na caixa de combinação Tipo de
objeto, altere para “banco de dados”, retire todas as pemissões e clique no botão Aplicar.
4) Na caixa de combinação Tipo de objeto, altere para cada tipo de objeto e retire todas as
pemissões. Clique no botão Aplicar antes de mudar de tipo de objeto.
5) Clique Ok.

Observação: Se você não retirar as permissões do grupo Usuários, qualquer um poderá


acessar seu banco de dados usando o arquivo padrão system.mdw e o usuário Administrador,
pois ele ainda permanece ao grupo Usuários.

 Defina um grupo de usuários para seu aplicativo


1) Acione o menu Ferramentas|Segurança|Contas de usuário e grupo…
2) Na guia Grupos, crie um novo grupo de usuário do seu aplicativo, por exemplo Usuarios
do sistema. Clique Ok.
3) Acione o menu Ferramentas|Segurança|Permissões para usuário e grupo….
4) Mude para listar Grupos e selecione o grupo Usuarios do sistema . Na caixa de
combinação Tipo de objeto, altere para “banco de dados”, marque somente a permissão
Abrir/Executar e clique no botão Aplicar.
5) Na caixa de combinação Tipo de objeto, altere para cada tipo de objeto e escolha as
permissões desejadas. De um modo geral, os usuários não devem ter permissão de
Modificar estrutura e Administrador. Clique no botão Aplicar antes de mudar de tipo de
objeto.
6) Clique Ok.
7) Se alguns usuário tiverem níveis de permissão diferentes, crie novos grupos de usuários e
marque as pemissões desejadas.

 Crie usuários e associe aos grupos


1) Acione o menu Ferramentas|Segurança|Contas de usuário e grupo…
2) Crie novos usuários e adicione ao grupo Usuarios do sistema. Todo novo usuário
automaticamente faz parte do grupo Usuários e não pode ser removido dele. Os usuários
herdarão as permissões do grupo ao qual pertencem.
3) Se outro usuário precisar ter o poder de administrar o banco de dados, inclua-o no grupo
Administradores.
4) Todos os usuários não terão senha. Você deve abrir o Access e efetuar o logon com cada
usuário e definir uma senha. Acione o menu Ferramentas|Segurança|Contas de usuário
e grupo…, selecione a guia Alterar senha de logon, informe uma senha para o usuário
atual.

 Eliminado a caixa de logon


1) Efetue o logon como Administrador.
2) Acione o menu Ferramentas|Segurança|Contas de usuário e grupo…, selecione a guia
Alterar senha de logon, informe a senha atual e mantenha a caixa Nova senha e Confirmar
em branco. Clique OK.

Observação: Ao retirar a senha do usuário Administrador, o Access não mais pedirá senha de
logon, e todos os usuários se logarão como Administrador. Como este usuário não tem

143
Microsoft© Access Avançado
nenhuma permissão, ele nada poderá fazer, a não ser que o grupo Usuários tenha alguma
permissão. Você pode definir algumas permissões básicas para o usuário Administrador.
Não é aconselhável eliminar a senha do usuário Administrador.

 Definindo um arquivo de informação de grupo de trabalho para um aplicativo


1) Acione o Administrador de grupo de trabalho e associe o arquivo original
(SYSTEM.MDW). Isto fará com que o Access use o arquivo original mas não permitirá o
acesso aos bancos de dados protegidos.
2) Crie um atalho que chame o Access e passe os parâmetros de linha de comando.

“C:\Arquivos de programas\Microsoft Office\Office\MSAccess.exe” C:\bd1.mdb /wrkgrp C:\sistemax.mdw

13.4.2. LOGON POR CÓDIGO VBA

Ao definir segurança em nível de usuário, você pode ter uma complicação com
códigos escritos sem levar em conta esta segurança. Uma operação que normalmente
funcionava antes pode não funcionar mais depois de configurada a segurança. Um caso típico
é a abertura De uma tabela pelo método OpenRecordset do objeto Database. Normalmente o
código é:

Sub AbreTabela()
Dim dbs As Database
Dim rst As Recordset
Set dbs = CurrentDb
Set rst = dbs.OpenRecordset("Categorias")
End Sub

Caso o usuário atual não tenha permissão sobre a tabela Categorias, o código falhará.
Se você não quer dar permissão ao usuário para acessar a tabela, é preciso abrir o
banco de dados, via código, com uma conta de um usuário que tenha as permissões
necessárias.

Sub AbreTabela()
Dim wks As Workspace
Dim dbs As Database
Dim rst As Recordset

Set wks = DBEngine.CreateWorkspace("NewWork", "master", "topsecret")


Set dbs = wks.OpenDatabase(CurrentDb.Name)
Set rst = dbs.OpenRecordset("Categorias")
End Sub

Observação: No modo programado, os grupos Administradores e Usuários são referidos como


Admins e Users, respectivamente, e o usuário Administrador é Admin, independentemente se
o Access é em português ou inglês.

144
Microsoft© Access Avançado
13.4.3. TROCA DE SENHA VIA CÓDIGO VBA

Para os usuários mudarem a sua senha, precisam ter acesso ao menu


Ferramentas|Segurança|Contas de usuário e grupo…Entretanto, em uma aplicação não é
interessante que os usuários tenham acesso a menus. Para resolvere esta situação, pode-se
criar um código VBA para eles mesmos alterem suas senhas, sem ter acesso ao menu.

Sub ChangePassword()
Dim wks As Workspace
Set wks = DBEngine.Workspaces(0)

wks.Users("Teste").NewPassword "senhaantiga", "novasenha"


End Sub

O usuário não precisa ser administrador para alterar sua própria senha. Porém, eles
não conseguem alterar senha de usuários do grupo Administradores, nem conseguem alterar
sus própria senha caso esqueçam a senha atual.
No exemplo acima, foi alterada a senha do usuário Teste. Uma melhoria do código
seria criar uma caixa de diálogo que obtivesse o nome do usuário atual. O nome do usuário
atual pode ser obtido pela função CurrentUser().

Private Sub cmdFechar_Click()


DoCmd.Close
End Sub

Private Sub cmdOk_Click()


Dim wks As Workspace

Set wks = DBEngine.Workspaces(0)

If Me.txtNovaSenha <> Me.txtConfirmar Then


MsgBox "Nova senha não confere!"
Exit Sub
End If

On Error Resume Next


wks.Users(CurrentUser()).NewPassword Me.txtSenhaAtual, Me.txtNovaSenha
If Err.Number <> 0 Then
MsgBox "Não foi possível alterar a senha. Confira a sua senha
atual!"
145
Microsoft© Access Avançado
End If
End Sub

Private Sub Form_Open(Cancel As Integer)


Me.txtUsuario = CurrentUser()
Me.txtSenhaAtual.SetFocus
End Sub

13.4.4. RETIRAR PEMISSÃO DE CRIAR NOVOS BANCOS DE DADOS

Quando um usuário efetua o logon no Access, é possível ele fechar o database do


aplicativo e criar um novo banco de dados. Via programação é possível retirar esta permissão.
A permissão de criar banco de dados está no objeto Container, especificamente o
container Databases, do arquivo de informação de grupo de trabalho. Deve-se portanto abrir
este arquivo e configurar a propriedade Permissions do container Databases.
Para acrescentar uma permissão às já existentes, faz-se uma operação Or. Para
remover permissão, faz-se uma operação And Not. As operações são feitas com as
permissões atuais e uma constante intríseca das Constantes de Segurança. No caso de criação
de banco de dados, a constante é a dbSecDBCreate.

Sub Deny_DBCreate()
Dim dbs As Database, ctr As Container, strMDW

' Recupera o caminho e o nome do arquivo de grupo de trabalho


strMDW = DBEngine.SystemDB
Set dbs = DBEngine(0).OpenDatabase(strMDW)
Set ctr = dbs.Containers!Databases
ctr.Username = "Users" ' Grupo Usuários
ctr.Permissions = ctr.Permissions And Not dbSecDbCreate
End Sub

13.4.5. RETIRAR PEMISSÃO DE CRIAR NOVAS TABELAS E CONSULTAS

As permissões para criar tabelas e consultas ficam são definidas no objeto Container,
especificamente no container Tables, do banco de dados protegido (.MDB). A propriedade
Permissions deste container deve sofrer a operação And Not dbSecCreate.

Sub Deny_Create_TableQuery()
Dim dbs As Database, ctr As Container

Set dbs = CurrentDb()


Set ctr = dbs.Containers!Tables
ctr.Username = "Users" ' Grupo Usuários
ctr.Permissions = ctr.Permissions And Not dbSecCreate
End Sub

146
ANEXO A - CONVENÇÃO DE NOMES PARA DESENVOLVIMENTO DE APLICAÇÕES COM
PRODUTOS MICROSOFT
ANEXO A - CONVENÇÃO DE NOMES PARA
DESENVOLVIMENTO DE APLICAÇÕES COM PRODUTOS
MICROSOFT
A Microsoft adota a Leszynski Naming Conventions - LNC, também conhecida como notação
húngara, para nomear objetos dos produtos MS Office (Access, Excel, Word, Outlook e
PowerPoint), MS Project, MS BackOffice (SQL Server, Exchange Server, System
Management Server, Internet Information Server e SNA Server) e MS Visual Studio (Visual
Basic, Visual FoxPro, Visual C++ e Visual InterDev). Estes objetos englobam:
• Class modules (módulos de classe do Visual Basic)
• Constants (constantes)
• Form controls (controles de formulários do Visual Basic e do Access)
• Forms (formulários do VB e do Access)
• Modules (módulos do VB e Access)
• Procedures (procedimentos do VB e Access)
• Queries and views (consultas do Access e SQL)
• Report controls (controles de relatório do Access)
• Reports (relatórios do Access)
• Security objects (objetos de segurança do Access)
• Stored procedures (procedimentos armazenados do SQL)
• Table fields (campos de tabelas do Access)
• Tables (tabelas do Access)
• Triggers (gatilhos do SQL)
• User-defined types (tipos definidos pelo usuário do VB e Access)
• Variables (variáveis)

A estrutura da LNC baseia-se em uma tag (etiqueta) antes do nome do objeto (por
exemplo, frmLogin). A sintaxe é:

[prefixo(s)] {tag} {Nome} [Qualificador] [Sufixo]

Os elementos entre colchetes são opcionais.


O prefixo e a tag são escritos sempre em letras minúsculas. O nome e o qualificador
são escritos em letras maiúsculas e minúsculas. O sufixo pode ser escrito tanto em letras
maiúsculas quanto minúsculas.

Exemplos:

Nome do objeto Prefixo Tag Nome Qualificador Sufixo


qryVendasReopABR qry Vendas Reop ABR
frmSobre frm Sobre
sdtmVigCtr s dtm Vig Ctr
plngAcumulado p lng Acumulado

147
ANEXO A - CONVENÇÃO DE NOMES PARA DESENVOLVIMENTO DE APLICAÇÕES COM
PRODUTOS MICROSOFT

MICROSOFT ACCESS

Hierarquia dos objetos do Access

Tags para objetos da janela de banco de dados do ACCESS

Objeto Tag
Formulário (form) frm
Macro mcr
Módulo (module) bas
Consulta (query) qry
Relatório (report) rpt
Tabela (table) (*) tbl

(*) As tabelas não usarão prefixo nem tags, somente o Nome.

Tags para objetos controles do ACCESS

Controle Tag
Bound object frame (moldura de objeto acoplado) frb
Chart cht
Check box (caixa de verificação) chk
Combo box (caixa de combinação) cbo
Command button (botão de comando) cmd
Custom control (controle personalizado) ocx
Image (imagem) img
Label (rótulo) lbl
Line (linha) lin
List box (caixa de listagem) lst
Option button (botão de opção) opt
Option group (grupo de opção) grp
Page break (quebra de página) brk
Rectangle (retângulo) shp
Section (seção) sec
Subform/Subreport (subformulário/subrelatório) sub
Text box (caixa de texto) txt
Toggle button (botão alternar) tgl
Unbound object frame (moldura de objeto não acoplado) fru

148
ANEXO A - CONVENÇÃO DE NOMES PARA DESENVOLVIMENTO DE APLICAÇÕES COM
PRODUTOS MICROSOFT
Tags para variáveis do ACCESS

Objeto Tag
Application app
Collection col
Control ctl
Controls ctls
CustomControl ocx
CustomControlinReport ocx
Debug n/a
DoCmd doo
Err n/a
Form frm
Forms frms
GroupLevel lvl
Report rpt
Reports rpts
Screen scn
Section sec

DATA ACCESS OBJECTS - DAO

Hierarquia dos objetos DAO para Microsoft Jet Workspaces

149
ANEXO A - CONVENÇÃO DE NOMES PARA DESENVOLVIMENTO DE APLICAÇÕES COM
PRODUTOS MICROSOFT
Hierarquia dos objetos DAO para ODBCDirect Workspaces

Tags para Data Access Objects - DAO


Objeto Tag (ACCESS) Tag (VB)
Connection con
Connections cons
Conteiner ctr
Conteiners ctrs
Database dbs db
Databases dbss
DBEngine dbe
Document doc
Documents docs
Error err
Errors errs
Field fld
Fields flds
Group grp
Groups grps
Index idx
Indexes idxs
Parameter prm
Parameters prms
Properties prps
Property prp
QueryDef qdf qry
QueryDefs qdfs
RecordSet rst rec
RecordSets rsts
Relation rel
Relations rels
TableDef tdf tbd
TableDefs tdfs
User usr
Users usrs
Workspace wrk wsp
Workspaces wrks

150
ANEXO A - CONVENÇÃO DE NOMES PARA DESENVOLVIMENTO DE APLICAÇÕES COM
PRODUTOS MICROSOFT

MICROSOFT VISUAL BASIC 5.0

Tags para controles do Visual Basic


Controle Tag MAPI session mps
3D Panel pnl MCI mci
Animated button ani MDI child form mdi
Check box chk Menu mnu
Combo box, drop-down list box cbo MS Flex grid msg
Command button cmd MS Tab mst
Common dialog dlg OLE ole
Communications com Outline out
Control (usado em procedures ctr Pen BEdit bed
quando o tipo é indefinido) Pen HEdit hed
Data control dat Pen ink ink
Data-bound combo box dbcbo Picture pic
Data-bound grid dbgrd Picture clip clp
Data-bound list box dblst Report rpt
Directory list box dir Shape shp
Drive list box drv Spin spn
File list box fil Text box txt
Form frm Timer tmr
Frame fra UpDown upd
Gauge gau Vertical scroll bar vsb
Graph gra Slider sld
Grid grd ImageList ils
Horizontal scroll bar hsb TreeView tre
Image img Toolbar tlb
Key status key TabStrip tab
Label lbl StatusBar sta
Line lin ListView lvw
List box lst ProgressBar prg
MAPI message mpm RichTextBox rtf

MICROSOFT VISUAL BASIC FOR APPLICATION - VBA

Tags para variáveis do Visual Basic for Application


Tipo de variável Tag Tag
(VBA) (VB)
Boolean (lógico) bln
Byte byt
Collection object - col
Conditional Compilation Constant ccc -
Currency (moeda) cur
Date (data) dtm
Double (dupla precisão) dbl
Error err
Integer (inteiro) int
Long (inteiro longo) lng
Object obj
Single (inteiro simples) sng
String (caracter) str
User-Define Type typ udt
Variant var vnt

151