Beruflich Dokumente
Kultur Dokumente
1
FICHA CATALOGRÁFICA
1. Informática
2
EDUARDO V MACHADO (GOOD GUY)
1ª Edição
Rio de Janeiro
Editora Livrorama
Ano 2018
3
4
DEDICATÓRIA
5
6
AGRADECIMENTOS
7
8
PREFÁCIO
9
informática. Meu Deus, pensei, preciso crescer como
profissional, sair da rotina. A princípio, procurei fazer uma
faculdade de Ciência da Computação, mas desisti para
valorizar o meu casamento recente.
Na época quando fiz Letras não havia informática
como hoje existe, só o estudo da linguagem de programação
Fortran. Só tinha uma coisa a fazer, ou resolvia estudar por
conta própria e através de cursos caros, mas de bom conteúdo
e ser bom em Programação ou ser bom em Técnica de
Reparos em Computadores. Bem, vamos devagar, pensei,
investindo em estudo de hardware. Comecei, fazendo cursos
de manutenção e trabalhei algum tempo como técnico de
computadores. Mas com o tempo percebi que estava gastando
mais dinheiro em livros e cursos do que conseguia com
reparos. Foi quando resolvi atacar a programação, mas quando
vi os códigos em sites e livros me desesperei e comecei a
chorar de medo daquela linguagem indecifrável dos códigos
que se repetiam a cada capítulo dos livros. Decidi fazer então
cursos de Lógica de Programação e com a ajuda de
profissionais amigos dos fórums, fui perdendo o medo e
sentindo satisfação com meus resultados.
Desde então, tenho estudado com dedicação a
linguagem VBA para o Access há muitos anos, fazendo cursos
com grandes mestres da programação e participando
ativamente de fórums como Máximo Access, Expert Access,
It Lab Forum, The Code Cage Forum e Access World
Forums. Cheguei a ser premiado internacionalmente com
meus aplicativos na comunidade lusófona de programadores e
convidado para ser moderador de fórum. Hoje tenho um site de
informática, chamado Good Guy Sistemas, Aplicativos e
Jogos cujo endereço é www.goodguyaccessvba.com.br. Tenho
10
também uma página no Facebook e um blog com assuntos
variados de tecnologia. Sou também o autor de dois outros
livros sobre Access, Técnicas Especiais de Access VBA e
Engenharia de Software com Access VBA.
Há alguns anos vinha sonhando em preparar um
livro que esmiuçasse certos rudimentos da linguagem VBA
para Access como fruto de minha experiência profissional
adquirida nesses grandes fórums, a fim de preparar futuros
programadores no domínio dessa ferramenta tão necessária
para capacitar o profissional de TI no desenvolvimento de
poderosos sistemas de informação. Sabia que não seria fácil
escrever um livro sobre este assunto em face de já existir
muitos bons livros já escritos por excelentes mestres. Mestres
como Flávio Morgado, autor da coleção Programando em
Access VBA de quem comprei toda a sua coleção e com quem
aprendi muito, Bernardo Leite, autor do livro VBA para
Microsoft Access, André Bernardes autor de diversos artigos
em sites sobre VBA e José Carlos Macoratti também. Aprendi
muito com João Paulo um dos grandes moderadores do fórum
Máximo Access; Avelino Sampaio criador do site Usando
Access que me proporcionou com sua grande capacidade e
didática, muito conhecimento; Alexandre Neves outro excelente
programador, moderador do fórum Máximo Access com sua
agilidade e inteligência ao codificar e, me cobrando atenção e
dedicação; Alexandro de Andrade (Mc Feba) inteligente
programador que também me abriu os olhos para boas
técnicas de programação, amigos programadores geniais
assim como Dilson Marcos criador do Blog Access do
Programador, meu maior incentivador e grande amigo; o
habilidoso Plínio Mabesi, criador do site Mabesi.com que muito
me incentivou; Harysohn Pina, inteligente e inovador, criador de
11
um sistema de biometria no Access e,finalmente, o Valdino
Campos, mais conhecido como Criquio, também fera em
programação.
A nenhum desses trato como concorrentes, mas
como irmãos e amigos, porque somos uma grande família nos
fórums. Com isto em mente, este livro se propõe a ensinar a
arte de desenvolver aplicativos para solucionar problemas do
dia-a-dia. Você aprenderá a ser um excelente Desenvolvedor
de Soluções em TI. Esta é uma carreira promissora e vantajosa
e que lhe abrirá as portas não só da realização pessoal bem
como da realização financeira.
Ao longo deste livro alguns leitores poderão já se
sentir mais familiarizados com certos tópicos como o uso da
Janela Verificação Imediata na IDE onde você poderá
depurar seus códigos e corrigir os erros antes mesmo de rodar
o aplicativo. Estudaremos também a janela Pesquisador de
Objeto onde o leitor poderá obter, ao estudar essas janelas,
um bom domínio de programação ao utilizar métodos e
propriedades dos objetos de forma mais eficaz. Ao longo de
cada capítulo, o leitor poderá avaliar os seus conhecimentos
com exercícios práticos e assim começar a dominar a arte da
programação.
12
desenvolvendo soluções práticas, e assim sobressair-se em
qualquer situação conflitante da vida real. Para isso, no
entanto, vai depender de você com sua perseverança, alcançar
este nível de profissionalismo. Planejar e corrigir um bom
programa ou sistema aliado à Lógica de Programação, sua
análise de que a que fim se propõe é o passo número um a
dominar e imprescindível em todo e qualquer bom profissional
de programação.
13
ÍNDICE
Pág.
Introdução .................................................................... 18
Avaliação ...................................................................... 29
CAPÍTULO 1 – O FUNDAMENTO
14
7. Criando Consultas com Referência Cruzada.... 144
8. Criando Consultas com Duplicação de Dados........ 146
9. O Uso de SEIMED para Criar Consultas com
Campo Calculado ................................................................ 146
10. Otimizando Consultas .............................................. 148
15
18. Os Controles Principais Usados em
Formulários com Suas Propriedades e Métodos ............. 240
18.1 Combobox ............................................ 241
18.2 Listbox ............................................. .... 247
18.2.1 Calculando Totais com Listbox 255
18.3 TextBox .................................................. 257
18.4 CheckBoxes ............................................ 261
18.5 Option Buttons ...................................... 262
18.6 Subforms .............................................. 262
18.6.1 Calculando Totais com Subforms 262
19. Principais Eventos de Um Controle …........... 267
19. 1 O Evento NotInList...................................... 269
20. Controles-guias …………………………........ 275
21. Formatação Condicional em Formulários..... 278
22. Inserindo Dados em Uma Tabela a Partir de
Outra .................................................................. 281
23. Alterando Dados em Uma Tabela a Partir de
Outra ............................................................... 282
24. Função Aleatório (Randomize)........................ 283
25. Trabalhando com o Form_Timer .................. 291
25.1 Time........................................................ 293
26. Tratamentos de Erros ..................................... 293
27. Módulos ............................................................ 300
28. Aplicativos em Rede ........................................ 303
Avaliação............................................................................... 306
16
17
INTRODUÇÃO
18
3.º Passo: Clique no modo Design e selecione um botão
na barra de ferramentas.
19
4.º Passo: Clique em Cancelar e renomeie o botão pela
aba Outra, ao clicar com o botão direito do mouse em
cima do botão.
20
Insira agora o seguinte código pela aba Evento, Clicar do
botão:
21
Pronto, o primeiro programa está criado. Mas é preciso ir
mais além na codificação para melhorar a apresentação
dessa simples mensagem. Que tal colocarmos um ícone
de informação nesta caixa de mensagem e uma
referência ao programa como título desta mensagem?
End Sub
22
eventos Ao Abrir (Form_Open), Ao
Carregar(Form_Load) e Ao Ativar(Form_Activate).
Alguns fundamentos de desenvolvimento são necessários
você dominar para tornar a codificação mais fácil e
dinâmica.
Configurações Importantes
Vamos examinar as opções de configurações de seu
aplicativo em Access. Antes de criar ou concluir um
23
aplicativo, você precisa aprender a configurá-lo de modo
que possa ser prático o manuseio dele para realizar as
alterações necessárias para o seu pleno funcionamento e
análise. Quando você abre o Access ele exibe a seguinte
janela:
24
Clique com o botão direito a Tabela1 à sua esquerda.
Selecione o Modo Design. Salve a sua tabela como um
nome também sugestivo (Ex. tblMeusDados) .
25
Adicione novos campos à sua tabela, logo abaixo de
código.
26
Para que seu aplicativo rode sem segurança de macros, o
que impede que o seu código VBA funcione, faça o
seguinte: Siga para a Central de Confiabilidade logo
abaixo e clique no botão Configurações da Central de
Confiabilidade, Configurações de Macro e selecione à sua
direita “Habilitar todas as macros”. ATENÇÃO: Não faça
isso se você receber um aplicativo de terceiros que você
não tenha certeza que é uma fonte confiável.
27
Pronto, clique em OK, em seguida OK de novo. Você
agora está pronto para trabalhar com Access VBA.
28
AVALIAÇÃO:
29
CAPÍTULO 1 – O FUNDAMENTO
30
Isso é lógica de programação. Todo ser humano segue
um programa diário de atividades. Um programa de
computador também obedece esta lógica como veremos
ao longo deste livro. Chamamos a este tipo de sequencia
lógica de algoritmo.
ALGORITMOS
1- Sentar-se na cama,
2- calçar os chinelos,
3- ir ao banheiro,
4- abrir o armário,
5- pegar as escovas de dentes,
6- pegar a pasta,
7- passar a pasta na escova,
8- escovar os dentes,
9- lavar a boca, lavar a escova,
10- guardar a escova e a pasta no armário.
11- Posso agora tomar o meu café.
31
início, o corpo do texto e a conclusão ou mesmo, para
ser mais exato, semelhante a receita de um bolo ou de
um prato qualquer. Assim como há diferentes tipos de
bolos assim temos diferentes tipos de receitas para o
seu preparo, seguindo esta regra geral:
Faça assim
Caso seja B
Faça assado
Fim da seleção
CONCLUSÃO - Pronto para ser servido Fim do
Programa
32
variável que recebesse nomes de pessoas, ou de
telefones, ou de bairros, ou de cidades, etc.
ASP
ActionScript
33
C/C++
C#
Pascal/Object Pascal
Euphoria
Java
Lua
MATLAB
PHP
Python
R
Ruby
Tcl
Basic/Visual Basic
34
Primeira geração: A linguagem de primeira geração, ou
1GL, é o código de máquina. É a única linguagem que um
microprocessador pode entender nativamente. O código
de máquina não pode ser escrito ou lido por um editor de
texto, e portanto é raramente usado por uma pessoa
diretamente.
35
serve como um bit de paridade, utilizado para detecção de
erro. Os códigos ASCII representam texto em
computadores, equipamentos de comunicação, entre
outros dispositivos que trabalham com texto.
Desenvolvida a partir de 1960, grande parte das
codificações de caracteres modernas a herdaram como
base.
Exemplo 1:
Algoritmo Calcular_Idade
36
Programa Calcular_Idade()
sAno1
Tipo: longo
sAno2
Tipo: longo
sIdade
Tipo: inteiro
Senão
Sair do programa
Fim
37
uma função (por quê?) porque retorna um valor (ou traz
um valor de retorno), no caso, a idade de uma pessoa.
Function Calcular_Idade()
Else
Exit Sub
End If
38
Chame esta função através de um botão no formulário.
Sub cmdCalcular()
End Sub
a- Compreender o problema
b- Identificar os dados de entrada
c-Identificar os dados de saída
d- Determinar o que é preciso para transformar dados
de entrada em dados de saída:
39
1- usar a estratégia do dividir-para-conquistar
2- observar regras e limitações
3- identificar todas as ações a realizar
4- eliminar ambiguidades
e- Construir o algoritmo
f- Testar o algoritmo
g- Executar o algoritmo
REPRESENTAÇÕES DE ALGORITMOS
Linguagem Natural
Fluxograma
Pseudo-linguagem
FLUXOGRAMAS
Exemplo de fluxogramas:
(A)
40
(B)
41
Para criarmos um fluxograma convencionalmente correto
em programaçãoe planejar o desenvolvimento de um
programa, as etapas seriam assim distribuídas nos blocos
e estes também dever seguir uma padronização como
esta no exemplo abaixo:
(A)
42
Observe que após o cálculo o programa recomeça a
tomada de decisão ou o início da condição proposta,
chamamos isso de looping.
(B)
43
Início
Ler o primeiro
número – N1
Ler o segundo
Número – N2
Mostrar em video
O valor da DIVISÃO FIM
44
DECLARAÇÃO DE VARIÁVEIS
45
nada mais é que criar um receptador dos dados digitados
ou inputados no seu programa(do inglês Input, que
significa introduzir) . As variáveis armazenam os valores
temporariamente na memória do computador. Uma
variável pode, por assim dizer, armazenar diversos
valores para serem manipulados um de cada vez. É
imprescindível para que um bom programa funcione a
contento que haja variáveis declaradas no seu escopo de
códigos.
Option Explicit
46
No ambiente de código, deixe sempre declarada esta
linha pela barra de ferramentas Opções, pois é
extremamente necessária para forçar a declaração de
variáveis, tornando o código bem estruturado e
aumentando o bom desempenho do programa evitando
'bugs' indesejados.
47
Dim é uma palavra reservada da biblioteca Access VBA
usada para reservar espaço para uma variável na
memória.
48
2º Caso: Quando o valor da nossa variável do tipo String
NÃO vem encorpada por duas aspas. Nesse caso
estamos trabalhando ou com o valor da caixa de texto ou
combo a que ela se refere ou com o valor inserido em
uma InputBox*.
49
REGRAS PARA DECLARAÇÃO DE VARIÁVEIS(*)
50
Declaração por Sufixos(*)
Alternativa de sufixo
Sufixo Tipo de dado
& Long
! Single
# Double
% Integer
$ String
Sub Exemplo1()
Dim strNome As String
Dim lngIdade As Long
Dim dblPosicao As Double
Dim intn As Integer
EndSub
Sub Exemplo2()
Dim strNome$
Dim lngIdade&
Dim dblPosição#
Dim intn%
End Sub
51
TABELA DE TIPOS DE VARIÁVEIS MAIS COMUMENTE
USADAS
52
922.337.203.685.477,5807
53
MODELAGEM DE DADOS DE UMA TABELA:
54
Número Valores numéricos, como as distâncias. Observe
que há um tipo de dados separado para moeda.
Objeto OLE como documentos do Word, imagens.
Texto Curto, valores alfanuméricos, como um sobrenome
ou um endereço.
Sim/Não Valores booleanos.
Tipos de dados
55
incluem anotações, descrições bytes por caractere),
longas e parágrafos que usam dos quais você pode
formatação de texto, como exibir 65.535
negrito ou itálico. caracteres em um
Use a propriedade Formato do único controle.
Texto de um campo OBSERVAÇÃO O
Memorando para especificar se tamanho máximo de
o campo oferece suporte a um arquivo de
texto formatado. banco de dados do
Defina a propriedade Office Access 2007
Acrescentar Somente de um é de 2 gigabytes.
campo Memorando como Sim
para manter versões anteriores
do valor do campo quando o
valor for alterado.
Número Use para armazenar valores 1, 2, 4, 8 ou 12
numéricos (inteiros ou bytes (16 bytes
fracionados) que serão usadosquando usado para
em cálculos, exceto para uma ID de
valores monetários. replicação)
OBSERVAÇÃO Use o tipo de Para obter mais
dados Moeda para valores informações,
monetários. consulte a entrada
Número Tamanho
do Campo da
tabela de
referências das
propriedades do
campo.
Data/Hora Use para armazenar valores de 8 bytes
data e hora. Observe que cada
valor armazenado inclui um
componente de data e um
componente de hora.
Moeda Use para armazenar valores 8 bytes
monetários (Moeda).
AutoNumeração Use para gerar valores 4 bytes (16 bytes
exclusivos que podem ser quando usada para
56
usados como uma chave ID de replicação)
primária, inserida pelo Access
quando um registro é
adicionado. Observe que
campos AutoNumeração
podem ser incrementados
seqüencialmente, por um
incremento especificado ou
atribuídos aleatoriamente.
Sim/Não Use para valores booleanos: 1 bit (0,125 bytes)
Sim/Não, Verdadeiro/Falso ou
Ativado/Desativado.
Objeto OLE Use para armazenar Objetos Até 1 gigabyte
OLE de outros programas do
Microsoft Windows.
Anexo Use para armazenar arquivos Para anexos
binários (ou seja, arquivos que compactados, 2
você não pode ler usando um gigabytes. Para
editor de texto), como imagens anexos
digitais (fotos e elementos descompactados,
gráficos) ou arquivos criados aproximadamente
usando outros produtos 700KB, dependendo
Microsoft Office. do grau de
Você pode anexar mais de um compactação do
arquivo por registro para um anexo.
campo Anexo. OBSERVAÇÃO O
tamanho máximo de
um arquivo de
banco de dados do
Office Access 2007
é de 2 gigabytes.
Hiperlink Use para armazenar hiperlinks, Até 1 gigabyte de
que fornecem acesso de clique caracteres ou 2
único para páginas da Web por gigabytes de
meio de uma URL (Uniform armazenamento (2
Resource Locator) ou para bytes por caractere),
arquivos por meio de um nome dos quais você pode
em UNC (Uniform Resource exibir 65.535
57
Locator). Você também pode caracteres em um
criar links para objetos do único controle.
Access que estão armazenados OBSERVAÇÃO O
em um banco de dados. tamanho máximo de
um arquivo de
banco de dados do
Office Access 2007
é de 2 gigabytes.
Assistente de Use para iniciar o Assistente de Se o campo de
Pesquisa Pesquisa para que você possa pesquisa estiver
criar um campo que usa uma associado a uma
caixa de combinação para tabela ou uma
pesquisar um valor em outra consulta, terá o
tabela, consulta ou lista de tamanho da coluna
valores. Observe que o associada.
Assistente de Pesquisa, na Se o campo de
realidade, não é um tipo de pesquisa não estiver
dados. associado a outra
coluna (e armazenar
uma lista de
valores), terá o
tamanho do campo
Texto usado para
armazenar a lista.
58
O que você observa de importante sobre o que
estudamos?
59
Qual é a diferença entre Formato e Máscara de
entrada?
60
um campo de data). Além disso, ajudam a garantir que
usuários digitem dados de maneira consistente. Essa
consistência facilita a localização dos dados, bem como a
manutenção de seu banco de dados.
61
você selecionar dependerá das configurações
regionais do Microsoft Windows.
> Converte todos os caracteres seguintes em
letras maiúsculas.
< Converte todos os caracteres seguintes em
letras minúsculas.
! Faz com que a máscara de entrada seja
preenchida da esquerda para a direita, e não
da direita para a esquerda.
\ Os caracteres seguintes serão exibidos
literalmente.
"" Os caracteres entre aspas duplas serão
exibidos literalmente.
62
Observe que para cada campo de sua tabela corresponde
a um tipo de dados. Quando tratamos de campos do tipo
Texto, estaremos lidando com variáveis do tipo String em
VBA que referenciarão a este campo específico do tipo
Texto. Por exemplo, no campo Nome poderão ser
inseridos a cada registro um nome diferente, certo? Logo,
podemos dizer que o campo Nome poderá ter valores que
variarão ao longo do tempo. Para ocorrerem modificações
neste campo via programação será necessário que
trabalhemos com certos termos referentes a estes
campos que damos o nome de variáveis.
63
Por exemplo, para o campo Nome temos uma variável
com determinado termo que chamaremos de
sNome(termo criado pelo programador seguindo as
regras para sua declaração, isto é, respeitando as
palavras reservadas do Access ao NÃO utilizá-las)
64
Debug.Print intn
End Sub
REGRAS PARA PREFIXOS DE NOMES DE OBJETOS
CAIXA
DE RÓTULO COMBOBOX LISTBOX CHECKBOX OPTION BUTTON
TEXTO
byt Byte
f Boleano (Lógico)
65
int Integer
lng Long
sng Single
dbl Double
cur Currency
dat Date
obj Object
str,s String
stf String (comprimento fixo)
var Variant
Alguns exemplos:
Dim lngCount As Integer
Dim intValue As Long
Dim strInput As String
DESCRIÇÃO DO CÓDIGO
66
ao lado da linha de código ou acima deste dentro do
evento de algum controle, função ou sub-rotina. Em
conjunto com o nome dado aos objetos acima,
podemos dizer que assim será possível que diferentes
programadores possam entender o seu código e assim
operar as modificações que se fizerem necessário em
caso da manutenção de uma linha de código.
Ex:
Função que retorna a soma dos valores de uma
determinada coluna de uma listbox.
67
„3ª coluna percorrendo do índice 0 até o
último índice menos 1, pega os valores da
coluna Quantidade
Next
SomarTotal = lngsoma
End Function
68
Vendas(um-para-muitos), vincunlando-se os campos
CodigoCliente. Se surgir o erro: Nenhum índice exclusivo
foi encontrado para o campo referido da tabela
primária.Faltava o índice exclusivo. No modo Design da
tabela Funcionários, clique em Índices e modifique para
Sim o campo com índice exclusivo que é a sua chave
primária.
69
Assim, teremos a seguinte visualização dos dados (ou
registros). Em VBA chamamos de Recordset:
70
Verificamos que na tabela Grupos que seria a tabela
principal da cadeia, existe ramificações identificadas pelo
sinal (+) de outras tabelas sujeitas a ela. Quais seriam? A
segunda tabela sujeita ao campo Grupo é a tabela
Categorias. Assim, cada grupo especificado em cada
registro da tabela Grupos possui um conjunto de outros
registros da tabela Categorias, subordinados a cada um
desses grupos. Visualize a segunda cadeia de registros
abaixo:
71
Note que o grupo de registro número 1 possui
subordinado a ele, um conjunto de categorias no total de
29, isto é, um recordset com 29 registros. Você verá
agora que cada categoria desse conjunto possui outro
conjunto de registros(recordset) a ele subordinado que
agora será de Produtos. Atente para a figura abaixo:
72
Como isso foi possível? Vinculando na área de
relacionamentos o código do produto ao código de
categoria e este por sua vez ao código do grupo. Vamos
ver isso na prática. Observe as figuras:
73
(2) Clique com o botão direito dentro desta área e
insira as tabelas Grupos, Categorias e Produtos.
74
Agora, clique duas vezes em cima de CodGrupo e
vincule as tabelas Grupos e Categorias e campos
CodGrupo de cada tabela respectivamente. Isso também
é possível ao clicar e arrastar para o outro campo em
comum da outra tabela. Faça a mesma coisa com as
tabelas Categorias e Produtos com os campos
CodCategoria de cada tabela. Teremos aqui um
relacionamento do tipo Um-para-muitos, isto é, para cada
registro de Grupos muitas Categorias e, por sua vez na
tabela Categorias, para cada registro de Categorias
muitos Produtos.
Do site da Microsoft:
75
conectados devem ter os tipos de dados iguais ou
compatíveis. Por exemplo, você não pode criar uma
associação entre um campo Número e um campo Texto,
mesmo que os valores desses campos coincidam.
76
O objetivo do relacionamento é tornar possível no
formulário principal a criação de sub-formulários
relacionados aos registros do formulário principal
baseados em um único código de mesmo nome presente
entre as tabelas que se relacionam entre si. Assim,
teríamos uma forma estruturada de visualização vinculada
aos campos indexados(códigos) ou campos com chave
primária(Não permite duplicação de registro com o
mesmo nome) de cada tabela. Outro aproveitamento é
organizar ou encadear os registros das tabelas que tem
algum vínculo associativo. Vejamos um exemplo desta
finalidade:
77
Observe neste formulário o campo Produto, o campo
Categoria e o campo Grupo. Com base nos
relacionamentos existentes entre essas tabelas foi
possível correlacioná-las na forma que você vê acima:
78
Campo Produto(Não Acoplado) e seu Valor
respectivamente na fonte do controle:
=DPesquisa("[Produto]";"[Produtos]";"[CodigoProd]=[
cboCodProduto]")
=DPesquisa("[ValordeVenda]";"[Produtos]";"[CodigoPr
od]=[cboCodProduto]")
79
A resposta é que preciso nesse caso que a tabela
Produtos venha associada a tabela Categorias, isto é,
relacionando-se entre si. Para que isso ocorra, preciso
criar uma consulta(qryProdutos). Como as tabelas já
estão relacionadas, basta incluí-las que imediatamente o
relacionamento surgirá. Veja a figura abaixo:
80
E que também a tabela Categorias venha relacionada
com a tabela Grupo. É só criar outra
consulta(GrProdutos)e incluir as tabelas.
Semelhantemente como na consulta qryProdutos é só
incluí-las que o relacionamento surgirá imediatamente.:
81
Há mais dois outros tipos de relacionamentos que
convém estudar. A partir do mesmo raciocínio
82
poderemos ter relacionamentos do tipo muitos-para-
muitos e um-para-um.
Relacionamento um-para-um:
83
do Banco de Dados, podemos criar uma Segunda
Tabela "Alunos da Banda", a qual se relaciona com a
tabela Alunos através de um relacionamento do tipo
Um para Um. Cada aluno somente é cadastrada uma
vez na Tabela Alunos e uma única vez na tabela Alunos
da Banda. Poderíamos utilizar o Campo Matrícula do
Aluno como o Campo que relaciona as duas Tabelas.*
Relacionamento muitos-para-muitos:
84
teríamos que repetir o Número do Pedido, Nome do
Cliente, Nome do Funcionário, Data do Pedido, etc,
para cada item do pedido. Concluímos que não
poderíamos indexar qualquer campo das tabelas se os
campos tivessem que se repetir, isto é, com um
relacionamento muitos-para-muitos. Como identificar
os produtos diferentes para um único cliente, ou
melhor, como selecionar vários produtos entre vários
pedidos para um único cliente?
85
Vamos fazer um teste:
86
porque reúne vários atletas de diversos clubes. (3) Na
terceira e última tabela(tblClubes) os campos
CodigodoClube e NomedoClube. Neste caso, para
cada clube só existe um código.
87
(1) A tabela tblClubesfica assim:
88
(3) Finalmente, a tabela (DetalhesdoAtleta) ficaria
assim:
89
Agora vamos fazer os testes dos relacionamentos:
Observe que o jogador Neymar, neste exemplo, joga
somente futebol em um único clube, o Santos (Código
8)
90
E quais são os atletas dos clubes?
91
Analise bem. Quem joga no Santos é o Neymar(Código
1), na modalidade Futebol, com 21 anos de idade. Quem
joga no São Paulo é o Ganso(Código 3) na modalidade
Futebol com 22 anos de idade.
Vou deixar pra você entender o por quê. No final, você vai
perceber que é muito fácil criar relacionamentos. Tem que
ter os sinais gráficos 1 para oo (infinito) . Crie uma
integridade referencial, isto é, permitir atualizações em
todas as tabelas a partir da tabela-Pai e se preferir
exclusões dos nomes dos clientes em todas as tabelas.
Cuidado com esta última opção.
92
Na mesma janela para criar o relacionamento leia com
atenção qual é o nível de relacionamento, se é 1, 2 ou 3
que se baseia na paridade ou semelhança entre os
campos existentes entre as tabelas.
93
Criei um relacionamento um-para-muitosde nível 2
entre a tabela OBRA e a tabela ASO e entre os campos
codigo de cada tabela OBRA e ASO de nível 1 para que
as informações se repitam em outros registros do sub-
formulário e também entre os campos
ID_FUNCIONARIO e ID_FUNCIONARIO entre as tabelas
tbFuncionario e OBRA. Pronto !!! Esta consulta servirá
de fonte de controle.
94
R: Somente unir as linhas quando os campos unidos
de ambas as tabelas forem iguais.
95
Um fato a considerar em relacionamentos entre
tabelas:
ANALISADOR DE DESEMPENHO
A Microsoft disponibiliza um recurso muito
importante que muitos programadores desconhecem.
É o Analisador de Desempenho. O que ele faz? Analisa
todos os objetos de seu banco como tabelas,
consultas, formulários e relatórios, verificando falhas
na modelagem da tabela, excesso de campos, erros no
relacionamento de tabelas, excesso de objetos do
formulário que poluem o seu visual, etc. Abra a aba
Ferramentas de Banco de Dados e selecione Analisar
desempenho.
(1)
96
(2)
97
(3)
ANALISADOR DE TABELAS
Você tem dúvidas sobre a funcionalidade de sua
tabela? Estaria muito inflada e gostaria de torná-la
mais prática e com menos campos? Utilize também
este recurso da Microsoft. O assistente vai explicando
o que será feito e só completará a fragmentação de
sua tabela se você concordar no final. Criará um
98
relacionamento entre as novas tabelas, facilitando a
sua vida.
99
100
CÁLCULO EM TABELAS
Você pode usar expressões nas propriedades Fonte do
Controle e Valor Padrão para um controle. Além disso, é
possível usá-las na propriedade Regras de Validação de
um campo da tabela
Coluna(1) de um campo vazio
Exemplo(1)*:
101
Exemplo(2): (Regras de Validação)
(1)
[Quantidade] * [Preço Unitário]
(2)
[Peso]+[Pontos]
AVALIAÇÃO:
102
que faça este cálculo e que aponte também quantos
alunos eram meninos e quantos eram meninas em cada
faixa de aprovados e reprovados.
tblModalidades
tblDetalhesAdic
103
Acrescente dados às tabelas tblClubes, tblAtletas,
tblModalidades, tblDetalhesAdic(Posição do Jogador)
e DetalhesdoAtleta ao criar um formulário com um
sub-formulário que esteja baseado neste tipo de
relacionamento.
104
Para melhor entender os relacionamentos, estude o
aplicativo Clubes contido no cd incluso.
105
(Veja um exemplo dentro do cd chamado CEEME
V.15 que se baseia em uma dúvida atendida por
mim no fórum Maximo Access.)
106
CAPÍTULO 2 – SQL EM AÇÃO (CONSULTAS)
107
108
Criamos então uma consulta que tenha o registro de
maior quantidade em ordem decrescente:
109
Vamos, agora, visualizar esta mesma consulta no modo
SQL:
110
A sintaxe criada foi:
111
COMANDO SELECT (SELECIONAR)
112
O resultado de uma consulta de SQL com o comando
SELECT é sempre uma tabela;
Relacionais
= igual a
> maior que
>= maior ou igual a
< menor que
113
<= menor ou igual a
<> (mais vulgar) ou != diferente
Lógicos
cond1 AND cond2 conjunção
cond1 OR cond2 disjunção
NOT condição negação
Especiais
campoN [NOT]BETWEEN valor1 verifica intervalos de
AND valor2 valores
campoN [NOT]IN (valor1, ..., verifica conjuntos de
valorN) valores
campoN IS [NOT] NULL trata valores NULL
campoN LIKE '.......' compara strings
tabela1 [NOT] CONTAINS tabela2 compara tabelas
[NOT] EXISTS tabela verifica tabelas vazias
114
WHERE cidade IN (SELECT DISTINCT cidade
FROM vendedores)
SELECT nome
FROM clientes
WHERE cidade = “NITERÓI”
↓
Ordem ( ) Parêntesis
decrescente *,/ multiplicação, divisão
+,- soma, subtracção
NOT negação lógica
AND conjunção lógica
OR disjunção lógica
Cláusula AS (COMO)
115
Esta cláusula renomeia um campo de saída;
Uma constante.
116
ou seja, pergunta pelos resultados das funções de grupo,
o qual WHERE não pode fazer.
117
O conjunto de resultados se parecerá com isto:
Cliente SUM(ValordoPedido)
Eduardo 2000,00
Lucas 1700,00
Mateus 2000,00
Cliente SUM(ValordoPedido)
Eduardo 5700,00
Lucas 5700,00
Eduardo 5700,00
Eduardo 5700,00
Mateus 5700,00
118
Lucas 5700,00
SELECT Cliente,DatadoPedido,SUM(ValordoPedido)
FROM Pedidos
GROUP BY Cliente,DatadoPedido
Cláusula HAVING
119
A cláusula HAVING vem adicionada a SQL porque a
palavra-chave (ou cláusula)WHERE não se pode usar
com funções agregadas.
120
5 2008/08/30 2000,00 Fernando
Cliente SUM(PrecodoPedido)
Lucas 1700,00
121
GROUP BY Cliente
HAVING SUM(PrecodoPedido)>1500
Cliente SUM(PrecodoPedido)
Eduardo 2000,00
Fernando 2000,00
A sua sintaxe é:
ORDER BY campo1[ASC|DESC],
campo2[ASC|DESC],...
Problema dado:
122
Selecionar na tabela Comissão o valor a receber, o
montante do imposto (17%) e o valor líquido, para os
indivíduos cujo Id é 14 ou 25, apresentando a
ordenação por Id e Imposto:
FROM comissão
WHERE Id IN (14,25)
ORDER BY Id, Valor*0,17
FROM comissão
WHERE Id IN (14,25)
ORDER BY Id, 3 (posição do
campo no comando SELECT)
123
SQL NO MSACCESS: 2ª PARTE
124
Temos a seguinte tabela “Pessoas”:
125
1 Machado Eduardo Rua Artur Campo
Rios, 1474 Grande
126
Codigo UltimoNome PrimeiroNome Endereco Cidade
1 Machado Eduardo Rua Artur Campo
Rios, 1474 Grande
5 Borges Luccas
CLÁUSULA UPDATE
Emprega-se a cláusula UPDATE para atualizar registros
emuma tabela.
A tabela “Pessoas”:
127
Codigo UltimoNome PrimeiroNome Endereco Cidade
5 Borges Luccas
UPDATE Pessoas
SET Endereco='Rua Ferreira Borges, 67', Cidade='Campo
Grande'
128
WHERE UltimoNome='Borges' AND
PrimeiroNome='Luccas'
129
UPDATE Pessoas
SET Endereco='Rua Ferreira Borges, 67', Cidade='Campo
Grande'
130
5 Borges Luccas Rua Campo
Ferreira Grande
Borges, 67
131
UNION
A cláusula UNION se aplica para selecionar informação
relacionada a partir de duas tabelas, parecido com a
cláusula JOIN. No entanto, quando se aplica a cláusula
UNION todas as colunas selecionadas precisam ser do
mesmo tipo de dados. Além disso, com UNION, apenas
valores únicos ou distintos são selecionados.
UNION ALL
Exemplos:
132
SELECT Nome FROM tbClientes UNION SELECT
Nome FROM tbFornecedores ORDER BY Nome
Nome
Fernando César
Gustavo Tannure
Luccas Borges
Paulo Sérgio
Marcelo Machado
UNION ALL
Nome
Luccas Borges
Fernando César
Paulo Sérgio
Gustavo Tannure
Marcelo Machado
Marcelo Machado
133
O Access dispõe de assistente para este tipo de consulta,
mas prefiro criar as minhas próprias.
134
registros inseridos.
Set db = rs.OpenRecordset("SuaTabela1",
dbOpenTable)
sNome = Forms!SeuForm!Nome
„Ou Me!Nome
sEndereco = Forms!SeuForm!Endereco
„Ou Me!Endereco
sBairro = Forms!SeuForm!Bairro
„Ou Me!Bairro
135
CurrentDb.Execute " INSERT INTO
SuaTabela1 (nome, endereco, bairro) VALUES
(„” & sNome & “‟,‟” & sEndereco & “‟,
„” & sBairro & “‟)
db.Close
Set db = Nothing
DoCmd.SetWarnings False
End Sub
Set db = OpenRecordset("SuaTabela",
dbOpenTable)
136
nCod = InputBox("Digite o código: ",
"Inserindo Dados")
db.Close
Set db = Nothing
DoCmd.SetWarnings False
End Sub
(3) Consulta inserção para inserir dados em uma tabela
vazia a partir de um campo código do tipo numérico com
contador. Esse modo é um pouco mais complexo. Criou-
se uma função que faz a contagem progressiva. É de
autoria de um amigo chamado Wagner McFeba que
disponibilizou para uso livre.
137
Set rkt =
DBEngine(0)(0).OpenRecordset(strSQL,
dbOpenForwardOnly)
Contador = Nz(rkt("MaxValor")) + 1
138
E no evento Form_BeforeInsert:
139
DoCmd.RunSQL strSQL „Ou Currentdb.Execute
strSQL
End Sub
140
Exemplo:
141
praticidade no emprego deste tipo de consulta quando,
por exemplo, segundo alguns colegas do fórum ItLab,
precisamos unir as tabelas de Clientes, Fornecedores e
Funcionários para mandarmos cartões de Natal, por
exemplo, então preparamos uma consulta união e
colocamos os campos que necessitamos: nome,
endereço, etc. Os campos a serem unidos não precisam
ter o mesmo nome.
Exemplo:
SELECT MATRICULA,
DATADAENTRADA,ORGAO,ENDERECO,BAIRRO,MOTIVOVISTO
RIA FROM ListadeFR2011 UNION ALL SELECT
MATRICULA,
DATADAENTRADA,ORGAO,ENDERECO,BAIRRO,MOTIVOVISTO
RIA FROM ListadeFR2012 UNION ALL SELECT
MATRICULA,
DATADAENTRADA,ORGAO,ENDERECO,BAIRRO,MOTIVOVISTO
RIA FROM ListadeFR2013 UNION ALL SELECT
MATRICULA,
DATADAENTRADA,ORGAO,ENDERECO,BAIRRO,MOTIVOVISTO
RIA FROM ListadeFR2014;
142
Observe que as tabelas(em azul) formam um recordset de
4(quatro) anos que foram sendo armazenados no bd.
Começamos com SELECT (em vermelho) e selecionamos
os campos discriminados da primeira tabela e em
seguida, temos a UNION ALL (unir tudo sem repetir
registros) mais a SELECT com dados da tabela seguinte
e repetimos o processo para as demais tabelas tantas
quanto necessárias para fundamentarmos nossa
pesquisa. Veja como fica:
143
formulário. Ao clicar no botão de filtro, obtemos então o
resultado pretendido ou pelo evento After_Update da
combobox:
Private Sub cboMatricula_AfterUpdate()
On Error Resume Next
Dim sMatr As String
sMatr = Me.cboMatricula.Column(0)
Me.RecordSource = "SELECT * FROM cnsInclusao
WHERE MATRICULA = '" & sMatr & "'"
End Sub
TRANSFORM Count(Órgãos.Loja) AS
ContarDeLoja
144
SELECT Órgãos.Órgão, Count(Órgãos.Loja) AS
[Total de Lojas]
FROM Órgãos
WHERE (((Órgãos.Órgão) Is Not Null))
GROUP BY Órgãos.Órgão
PIVOT Órgãos.Código;
145
Máximo), Méd(Média), Mínimo, Primeiro, Soma,
Último e Var. Sabe qual o campo que utilizo para
criar uma planilha com total de valores? Em geral,
um campo que não existe na proposta inicial, este
campo dou o nome de Total na tabela principal,
você deve criá-lo na tabela e selecioná-lo como
título de coluna que receberá o cálculo desejado,
Contagem, Soma, Média, etc.
146
Podemos realizar cálculos em consultas utilizando uma
coluna vazia.
Exemplo(1)
Total 1: ([Peso]+[Pontos])
Total 2: DSoma("[Peso]";"tblTeste")
Total 3: DSoma("[Pontos]";"tblTeste")
Exemplo(2)
Exemplo(3)
Exemplo(4)
Resultado=SeImed([uf]="m3";[comprimento]*Fo
rmulario![Largura]*[espessura];SeImed([uf]=
147
"m2";[comprimento]*Formulario![Largura];[co
mprimento]))*
OTIMIZANDO CONSULTAS
(4) “*” & [Digite uma palavra chave:] & “*” – Pesquisa
registros que contenham a palavra digitada ou que
iniciam com partes da palavra.
148
(5) Como R*–Retorna registros para todos as palavras que
comecem com R.
http://office.microsoft.com/pt-br/access-help/exemplos-de-
criterios-de-consulta-HA010066611.aspx
*O uso de vários seimed‟s só é possível com a devida referência ao
campo(Forms!NomedoFormulário!NomedoCampo) tanto na consulta
quanto no formulário. Este exemplo é de uma dúvida de um colega do
fórum Máximo Access.
AVALIAÇÃO
149
Selecione o modo SQL de sua consulta e faça as
seguintes pesquisas em SQL:
150
(1) Com base no estudo de relacionamento muitos-para-
muitos estudado no capítulo anterior, abra as consultas
criadas na última avaliação no modo SQL. Estude a sintaxe
SQL criada pelo Access. Aprenda como é feito os vínculos entre
as tabelas através da cláusula INNER JOIN.
(2) Crie um formulário que faça as consultas utilizando a
técnica estudada no tópico Otimizando Consultas pelo
evento BeforeUpdate de uma combo.
151
CAPÍTULO 3 – DOMINANDO O ACCESS VBA I
(FORMULÁRIOS)
A BARRA DE FERRAMENTAS
152
Os principais controles que podemos “arrastar e
largar”(drag-and-drop) para o nosso formulário
são:
a Caixa de Texto (TextBox)
a Caixa de Combinação (ComboBox)
o Botão (Button)
a Caixa de Listagem (ListBox)
o Subformulário/Sub-relatório (SubForm/SubReport)
o Rótulo (Label)
o Grupo de Opções (Option Group) – Permite uma
só seleção de cada vez
a Caixa de Seleção (CheckBox) – Permite várias
seleções
o Botão de Opção (Option Button or Toggle Button)
o Controle Guia (Page Control)
153
mouse clicado sobre cada um deles e assim, entrando na
caixa de propriedades. Cada um desses controles
possuem cinco abas com os seguintes nomes: Formato,
Dados, Evento, Outra e Todas.
154
de controle na aba Dados, com o cursor do mouse dentro
dessa propriedade, pressione a tecla SHIFT junto com a
tecla F2 e depois solte. Você terá um Zoom desta
propriedade.
155
156
Principais propriedades do formulário que devem ser
configuradas para uma melhor visualização pelo usuário.
157
Com o tempo você irá se acostumar a fazer estas
configurações para tornar seu aplicativo bem simpático
em seu impacto visual para o seu cliente ou usuário.
158
trabalhar com dados. Podemos fazer paralelo com um
cozinheiro na cozinha. O que ele faz? Ele trabalha com os
itens da receita, mas precisa de certos utensílios para
prepará-la, certo? A função InputBox nada mais é que
um utensílio que pelo nome já diz é de extrema
funcionalidade na criação de programas (pratos da
receita). Enquanto as InputBox recebem e inserem
dados, as MsgBox exibem os dados que podem ser
qualquer coisa como resultado dos cálculos com estes
dados, por exemplo, fornecidos ao final do programa.
Uso de InputBox
Sintaxe:
159
title(Título):"CIDASA - Consulta Instantânea de Dados do SASB"
160
Observação: Para especificar mais que o primeiro argumento
nomeado, você deve utilizar InputBox em uma expressão. Para
omitir alguns argumentos posicionais, você deve incluir o
delimitador de vírgula correspondente.
Exemplo 2:
161
Logicamente, neste exemplo se o usuário não souber o
que inserirá, ao simplesmente pressionar OK para atender
ao default "Regras Básicas", o programa deverá fornecer
esta informação desejada através de uma ...(você já sabe
o quê?) uma MsgBox.
162
A sintaxe inicial pode ser simplificada sem qualquer
problema para a seguinte:
Dim Perguntas As String
163
http://www.tomasvasquez.com.br/blog/microsoft-
office/vba-a-diferencas-entre-inputbox-e-application-
inputbox
164
valor =
([valorDolar]*[TaxaDolar])'valorDolar e
TaxaDolar são variáveis fornecidos pelo
usuário e inseridas em caixas de texto
valorLucro = [valorDolar]*NumDado/100
valorTotal = [valor]+[valorLucro]
End Function
End Sub
165
Uso de MsgBox
Sintaxe:
Exemplo 1:
MsgBox ("Você precisa precisa preencher este
campo !"), vbInformation, "Cadastro de Reserva"
ou sem os parênteses:
MsgBox "Você precisa precisa preencher este
campo !", vbInformation, "Cadastro de Reserva"
Exemplo 2*:
166
String. Certas pesquisas que fazemos utilizando uma
função de cálculo, (função DCount*), por exemplo,
intercala-se o apóstrofo antes e depois das aspas:
End Sub
Ou
167
MesA = InputBox("Digite o Mês(JAN,FEV,etc...)
de Consulta: ", "Controle de Ordem de Serviço")
End Sub
Exemplo 3:
Exemplo 4:
168
sNum = InputBox("Digite o valor pago: ",
"Cadastro de Reserva")
Exemplo 5:
169
decimais independente do número de casas
decimais.
Exemplo 6:
Call IniciarPesquisa
End Sub
SUB-ROTINA X FUNÇÃO
Em se tratando de procedimentos, sub-rotinas retornam
uma ou mais informações; são partes de uma solução
final; podem ser reutilizadas em outros programas e
funções retornam valores que em geral, são resultantes
de cálculos em função dos seus argumentos em sua
elaboração e que funcionam na chamada da função com
seus parâmetros correlatos.
170
para que você programador possa ir já aprendendo a
desenvolvê-las e utilizá-las em seus aplicativos. Vamos
ver então primeiramente funções sem parâmetros.
FUNÇÕES PRÁTICAS
(1)
Private Function Tabuada()
Dim i As Integer
„Bloco For...Next
„**********************************************
For i = 1 To 10
Tabuada = Valor * i
MsgBox "O valor " & Valor & " vezes " & i & " é
" & Tabuada, vbInformation, "Tabuada"
Next i
„**********************************************
End Function
171
Replace(Substitui por esta nova string)
Endereco = sEtr sAvn = Replace(Endereco,
"Avenida", "Avn")'Expression(ou nome do campo),
Find(procura a string antiga),
Replace(Substitui por esta nova string)
Endereco = sAvn
Substituir= Endereco„Aqui a função recebe o
valor Resultante
Else
Exit Function
End If
End Function
172
nTexto = Resposta 'Resposta é o nome da caixa de texto do tipo
Texto ou do tipo Memorando
EncontreErrosOrtográficos = nTexto
End function
173
If sLogin <> "" Then MsgBox "Nome OK",
vbInformation, "Testa Login" End If
If sSenha = nSenha Then
MsgBox "Senha válida !!!", vbInformation,
"Testa Login"
DoCmd.OpenForm "frmteste", acNormal'Se a senha
for válida abre o formulário principal
MsgBox "Senha inválida !!!", vbInformation,
"Testa Login"
End If
End Function
174
& " '@" & "Pesquisa Especial CIDASA @
',0,'Ajuda')")
175
Case vbNo
DoCmd.OpenForm "Form_Ufir",
acNormal
End Select
Case vbNo
strTitle = "Dúvida"
strMsg = "Deseja encerrar a pesquisa ou iniciar
uma nova? Selecione 'Sim' para a primeira opção
e 'Não' para a segunda opção."
intRetVal = MsgBox(strMsg, vbYesNo +
vbQuestion, strTitle)
Select Case intRetVal
Case vbYes
DoCmd.CancelEvent
Case vbNo
Perguntas =
InputBox(Prompt:="Digite abaixo a sua dúvida:",
Title:="CIDASA - Consulta Instantânea de Dados
do SASB", Default:="Por favor, repita a
operação !!!")
End Select
End Select
Case Is = "Abastecimento Predial"
Eval ("MsgBox ('Abastecimento de prédio ou de
parte de prédio dotado de instalação autônoma!'
" & "& chr(13)&chr(10)&" & " '@" & "Pesquisa
Especial CIDASA @ ',0,'Ajuda')")
..........
End Sub
176
Exemplo 6
177
Private Sub cmdConsulta_Click()
Dim strConsulta As String
strConsulta = InputBox("Selecione o tipo de
consulta desejada: " & vbCrLf & _
"1 - Total de funcionários cadastrados " &
vbCrLf & _
"2 - Total de funcionários ativos " & vbCrLf &
_
"3 - Total de funcionários inativos ",
"Consulta Geral")
178
Primeiro declaramos as variáveis:
Dim strTitle As String
Dim strMsg As String
Dim IntRetVal As Integer
179
Nota: intRetVal é uma variável do tipo Integer que
significa valor de retorno do tipo inteiro porque trabalha
com constantes representadas por vbYesNo, vbOkOnly,
vbInformation, vbCritical, vbExclamation, vbQuestion, etc.
No programa ela recebe o valor destas constantes em
forma de MsgBox:
180
Obs: Algumas formas são aceitáveis nesta elaboração
como o uso de "+" entre os parâmetros nesta sintaxe
quando se quer acrescentar um ícone à MsgBox que
identifica que tipo de MsgBox se trata. Exemplos:
intRetVal = MsgBox(strMsg,vbYesNo+
vbInformation,strTitle)
OU
intRetVal = MsgBox(strMsg,vbYesNo+
vbCritical,strTitle)
OU
intRetVal = MsgBox(strMsg,vbYesNo +
16,strTitle)
181
Constantes para função MsgBox() extraídas do livro
Programando Microsoft Access VBA do Prof Flávio
Morgado, volume 1:
182
Poderíamos também desejar fragmentar na forma de um
parágrafo a nossa MsgBox. Para isso, precisamos inserir
um quebra-linhas com a instrução vbCrLf. Estude este
exemplo:
Exemplo 1:
Private Sub cmdMessageBox_Click()
MsgBox "Suas credenciais de logon foram
checadas." & vbCrLf & "Antes de dar início ao
seu aplicativo, por favor " & _
"preencha a seguinte pesquisa", vbExclamation,
"Pesquisa"
End Sub
183
Finalmente, estude estas formas de uso de InputBox e
MsgBox respectivamente, em meus aplicativos.
184
"de +8,0%.!@" & "Identificação do
Aparelho.@',0,'Informação')")„O uso de Eval ao
lado de uma MsgBox deixa em negrito esta linha.
Acompanha o arroba na forma como é colocado
seguido de zero entre vírgulas
Case Is = 2
Eval ("MsgBox('Quando acarreta folga nos
roletes da relojoaria ou " & vbCrLf & _
"permite que o eixo da mesma caia de seus
mancais quando submetido " & vbCrLf & _
............................
"@" & "Identificação do
Aparelho.@',0,'Informação')")
Case Is = 3
Eval ("MsgBox('Quando se trata de perda da
capacidade de magnetização " & vbCrLf & _
"dos imãs do sistema de transmissão o medidor
tende a parar, ou apresentar " & vbCrLf & _
„.............................................
"@" & "Identificação do
Aparelho.@',0,'Informação')")
Case Is = 4
185
"1 - Furar a cúpula da relojoaria e utilizar
uma agulha para trancar " & vbCrLf & _
"os roletes, retirando-a quando na época de
leitura. " & vbCrLf & _
"2 - Retirar o aparelho, retirar o filtro e
injetar no " & vbCrLf & _
"mesmo impurezas(como cola, pedrinhas,
barbante, etc.) " & vbCrLf & _
"ou furar a câmara de medida com o objetivo de
parar a turbina. " & vbCrLf & _
"3 - Inverter o aparelho no quadro, deixando-o
funcionar apenas " & vbCrLf & _
"metade do tempo no sentido correto. " & vbCrLf
& _
"4 - Romper o lacre, abrir o aparelho e frear
os roletes com calços " & vbCrLf & _
"(palitos, pregos, etc.). " & vbCrLf & _
"5 - Golpear ou queimar a cúpula do aparelho
com a intenção " & vbCrLf & _
"de danificá-lo." & vbCrLf & _
"@" & "Identificação do
Aparelho.@',0,'Informação')")
Case Is = 5
Eval ("MsgBox('Vazamento na cúpula do aparelho,
a água sai por cima do medidor.: " & vbCrLf & _
"* O aperto dado no anel da cúpula quando da
montagem não foi suficiente " & vbCrLf & _
„.............................................
186
"** É bastante comum o usuário confundir os
vazamentos no quadro ou cavalete, " & vbCrLf &
_
"informando que é o aparelho que está vazando.
Sem dúvida, a troca de um " & vbCrLf & _
„.............................................
"@" & "Identificação do
Aparelho.@',0,'Informação')")
End Select
End Sub
187
188
Na janela que se abre você tem uma combo no lado
superior à esquerda que informa as bibliotecas contidas.
Para facilitar o estudo, escolha a biblioteca Access.
189
A “mão” segurando um folha de papel refere-se
àpropriedade do controle (caixa de texto, combo, caixa de
listagem) ou como no exemplo abaixo:
190
O ícone de raio que não visualizado aqui mais em outras
classes significa um evento. A classe de métodos é a
mais utilizada no ambiente de código. É formada por
diversos que se tornam membros da família DoCmd.
Vamos selecionar o método Maximize e, em seguida,
clicar no ponto de interrogação na parte superior à direita.
Este ao ser clicado nos fornece a informação pertinente a
este método. O que ele faz em termos de código e como
deve ser usado.
191
Alguns métodos exigem uma exemplo demonstrativo e o
Ajuda do Access vai exibi-los para maior clareza e ajudá-
lo a codificar o seu programa. Observe grifado em azul
um exemplo demonstrativo do método CopyObject da
família(Classe) DoCmd.
192
DoCmd.CopyObject, "Employees Copy", acTable,
"Employees"
193
lista de métodos desta família encontrei o método
FindRecord(Ache o registro). Não perdi tempo com a
explicação dos parâmetros ou argumentos do método e
procurei por um exemplo de aplicação.
194
como Requerido : Sim. Isto obrigava o usuário a digitar
um valor no campo. Para evitar uma codificação que
cobrasse do usuário a sua digitação, criei uma código no
evento de um botão que adicionasse um novo registro
com a inclusão da String 1111111-1. E funcionou muito
bem !!! Ao abrir o formulário, o registro com esta String
1111111-1 era localizado com o método FindRecord.
A FAMÍLIA DOCMD
195
Para saber a que biblioteca pertence para ser utilizada na
codificação, clique em Access nesta mesma janela(Class
DoCmd).
196
*Os métodos referentes a família DoCmd assim como os referentes aos
objetos no formulário tem a forma de uma pastilha verde em movimento.
197
exemplos de códigopara melhor clareza e portanto foram
adicionados.
Comandos Descrição
198
Abaixo temos uma tabela sumário
mostrando que eventos são passíveis de
cancelamento utilizando o método Cancel
Event.
199
acNormal
200
Glass ícone de ampulheta (ou um outro ícone
de sua escolha) enquanto o programa
está correndo. Aplica-se este método
quando estiver rodando um procedimento
de VBA que demora para rodar.
201
Ex: DoCmd Open Form,”NomedoFormulário”,...
202
email que pode ser visualizado e enviado.
USO DO RECORDSET
203
4. Close - Fecha um objeto recordset
5. Delete - Exclui o registro atual de um objeto
recordse aberto.
6. GetRows - Retorna múltiplos registros de um
recordset em um vetor.
7. Move - Muda a posição do registro atual.
8. MoveFirst - Muda a posição do registro para o
primeiro registro do recordset e o torna o registro
atual.
9. MoveLast - Muda a posição do registro para o
último registro do recordset e o torna o registro
atual.
10. MoveNext - Muda a posição do registro para o
próximo registro.
11. MovePrevious - Muda a posiçãodo registro para
o registro anterior.
12. MoveNextRecordset - Retorna o próximo objeto
recordset.
13. Open - Abre um Cursor.
14. Requery - Atualiza os dados de um recordset
executando novamente a consulta que o gerou.
15. Resync - Atualiza os dados de um objeto
recordset.
16. Supports - Informa a funcionalidade que o
objeto recordset suporta.
17. Update - Salva as alterações feitas no registro
atual.
18. UpdateBatch - Escreve todas as atualizações
pendentes em lote para o disco.
204
1. AbsolutePage - Informa o número da 'página' de
localização do registro atual.
2. AbsolutePosition - Determina a posição do
registro atual.
3. ActiveConnection - Informa a qual conexão o
objeto recordset pertence.
4. BOF - Informa que o registro atual está antes do
primeiro registro.(Início do Arquivo)
5. Bookmark - Retorna o bookmark que identifica
o registro atual ou atribui ao registro atual o
bookmark de um outro registro do recordset.
6. CacheSize - Informa o número de registros do
recordset que estão na memória.
7. CursorType - Informa o tipo de cursor usado em
u recordset.
8. EditMode - Mostra o status da edição que esta
sendo realizada no registro atual.
9. EOF - Informa que o registro atual está
posicionado depois do último registro.(Fim de
Arquivo)
10. Filter - Informa um filtro para os dados em um
recordset.
11. LockType - Informa o tipo de bloqueio dos
registros durante a edição.
12. MaxRecords - Informa o número máximo de
registros que serão retornados de uma consulta.
13. PageCount - Informa o número de páginas de
dados que um recordset contém.
14. PageSize - Mostra quantos registros constituem
uma página no recordset.
15. RecordCount - Informa o número de registros
em um recordset.
205
16. Source - Informa a fonte de dados em um objeto
recordset ou o nome do objeto ou aplicação que
gerou um erro.
17. Status - Informa o status do registro atual.
BIBLIOTECA DAO
206
Antes de seguirmos adiante, adicione a biblioteca DAO
em Ferramentas, Referências* no ambiente de código:
_________
207
Quando você precisar trabalhar com os objetos database
e recordset com os membros de suas coleções, digite
assim no cabeçalho do módulo da IDE ou de um
procedimento:
Dim db As DAO.Database
Dim rs As DAO.Recordset
208
Em seguida, vamos selecionar um objeto do formulário,
por exemplo, uma caixa de texto e voltar para a janela de
propriedades.
209
A caixa de texto selecionada apresenta suas propriedades
tais como cor, altura, largura, etc desta caixa de texto
específica.
210
estudar estas propriedades de forma prática para
desenvolvermos nossos aplicativos com profissionalismo.
211
Veja um exemplo do uso da biblioteca DAO em um
programa:
Exemplo (1)
212
rs.Close „Fecha o recordset
db.Close „Encerra o banco de dados
213
!Nome = “JOÃO BATISTA”
!Fone = 2332-4812
End With
If MsgBox("Salvar alterações?", vbYesNo) =
vbYes Then
r.Update 'Salva
MsgBox "Registro adicionado com
sucesso",vbInformation, “Adicionar”
Else
r.CancelUpdate 'Cancela cadastramento
End If
r.Close
Set d = Nothing
End Sub
Exemplo 1:
Dim ws As DAO.Workspace*
214
Dim db As DAO.Database
Dim rs As DAO.Recordset
„*Um Workspace é um objeto não-persistente que
define como seu aplicativo interage com os
dados ao utilizar o motor de banco de dados do
Ms Access. Use o objeto Workspace para
trabalhar a sessão corrente ou para iniciar uma
sessão adicional. Em uma sessão, você pode
abrir múltiplos bancos de dados ou conecções e,
trabalhar transações.
Trans = False
Set ws = DBEngine.Workspaces(0) 'Referir-se ao
Workspace padrão
Set db = CurrentDb 'Banco de Dados corrente
Set rs = db.OpenRecordset("Funcionarios",
dbOpenTable)
ws.BeginTrans
Trans = True
215
If rs!FuNome = "EDUARDO VIEIRA MACHADO" Then
„Considere que haja um registro com o seguinte
nome
Me!FuNome = rs!FuNome „Ou rs.Fields("FuNome")
sMens = MsgBox("Confirma alteração?", vbYesNo,
"Confirmação")
Sair:
rs.Close
Set db = Nothing
Set ws = Nothing
Exit Sub
216
Erro:
MsgBox "Erro"
If Trans Then „Ou Trans = True
ws.Rollback
End If
Resume Sair
End Sub
Exemplo 2:
Dim ws As DAO.Workspace
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim Trans As Boolean
Dim sMens As String
Dim sNome As String
Dim tNome As String
Trans = False
Set ws = DBEngine.Workspaces(0) 'Referir-se ao
Workspace padrão
Set db = CurrentDb 'Banco de Dados corrente
Set rs = db.OpenRecordset("Funcionarios",
dbOpenTable)
ws.BeginTrans
217
Trans = True
218
End If
Sair:
rs.Close
Set db = Nothing
Set ws = Nothing
Exit Sub
Erro:
MsgBox "Erro"
If Trans = True Then
Exit Sub
End If
Resume Sair
End Sub
Exemplo (3.a)
219
With r
.Edit „Utilizando o método Edit. Abre a
possibilidade de alteração do campo
!Bairro = sBairro
.Update „Atualiza pelo novo nome do campo
.FindNext Criterio
End With
Loop „Fim do laço
r.Close
Set d = Nothing
End Sub
Exemplo (3.b)
Sub DAO_MoveAndEdit()
Dim db as DAO.Database
Dim rs As DAO.Recordset
220
End Sub
Exemplo (4)
221
Clique em Procedimento...
222
Descreva o seu procedimento se será uma sub-rotina,
uma função ou uma propriedade e se seu escopo será de
natureza Pública ou Privada no seu projeto. Dê um nome
ao seu procedimento e clique em OK.
Normalmente, ao criarmos uma função, declaramos os
argumentos da função que entram dentro do parênteses.
Quando chamamos a função, podemos utilizá-la como
origem de um controle de uma caixa de texto ou dentro de
uma linha de código dentro de um evento qualquer de
algum controle(caixa de texto, combobox, etc), como Exit,
Ao Clicar, AfterUpdate, etc. Neste controle o valor
inserido em cada objeto como caixa de texto, combobox,
etc servirão de parâmetro da função, isto é, ocuparão o
223
lugar dos argumentos da função e servirão de elementos
do cálculo que porventura existir na função criada pelo
programador.
224
conteúdos das variáveis enquanto você codifica no modo
de Interrupção. O modo de Interrupção é o estado do VBA
quando a execução do código é pausada no ponto de
interrupção. Para exibir a Janela Imediata, pressione
CTRL+G ou selecione-a no menu Exibir.
225
Aprovado o código após a verificação na Janela
„Verificação Imediata‟, coloque-o no evento Click de um
botão de um formulário, com os seguintes acréscimos
grifados:
„Ou
„MsgBox “Este nome “ & sNome & “ contém “ & n
& “ caracteres
End Sub
226
do Access em procedimentos que requerem uma
atualização de dados, por exemplo, e colocar a nossa
própria mensagem personalizada.
227
Mas se incluirmos o seguinte código de desativação
acima e abaixo da instrução SQL com sua MsgBox
personalizada ficará assim:
228
„Seu código personalizado
„*********************************************
strMsg = "Deseja realmente efetuar a
alteração?"
intRetVal = MsgBox(strMsg, vbQuestion +
vbYesNo, "Alterar?")
Select Case intRetVal
Case vbYes
DoCmd.RunCommand acCmdRefresh „Atualiza a
ListBox
MsgBox "Alteração realizada com sucesso !!!",
vbInformation, "Sistema PDV"
Case vbNo
MsgBox "Nenhuma alteração foi feita !!!",
vbInformation, "Sistema PDV"
End Select
End Sub
229
230
A ESTRUTURA DE CONTROLE If Then...Else...End If
E Select Case…End Select
IF THEN…ELSE…END IF
Em VBA:
231
„Lembrando que P, M, G e GG são variáveis à minha
proposição, isto é, escolhidas aleatoriamente e inseridas
em uma caixa de texto do meu formulário
MinhaCamisa=Camisa„Camisa é o nome da caixa
de texto que recebe a variável MinhaCamisa
232
ANINHAMENTO DE IF‟s
Ex.:
If Not IsNull(Campo1) Or Campo1 = “”
Then„Testa „se o campo está nulo ou vazio
(1)
If IsNumeric(Campo1) Then„Testa se o campo
é numérico (2)
If Campo1 > 0 Then„Testa se o valor do
campo é maior que 0 (3)
MsgBox “Valor Positivo !!!”,
vbInformation, “Teste de IF‟s”
Else
MsgBox “Valor Negativo !!!”,
vbInformation, “Teste de IF‟s”
End If (3)
Else
MsgBox “Valor Não É Numérico !!!”,
vbInformation, “Teste de IF‟s”
End If (2)
Else
233
MsgBox “O Campo Está Vazio
!!!”,vbInformation, “Teste de IF‟s”
End If (1)
234
„Lembrando que P, M, G e GG são variáveis à minha
proposição, isto é, escolhidas aleatoriamente e inseridas
em uma caixa de texto do meu formulário
MinhaCamisa=Camisa„Camisa é o nome da caixa
de texto que recebe a variável MinhaCamisa
Select Case MinhaCamisa
Case Is = “P”
MsgBox “Este tamanho não cabe em mim!!!”
Case Is = “M”
MsgBox “Este tamanho não cabe em mim!!!”
Case Is = “G”
MsgBox “Este tamanho não cabe em mim!!!”
Case Is = “GG”
MsgBox “Este tamanho cabe em mim. Obrigado
!!!”
End Select
No caso de usarmos SELECT CASE ... END SELECT,
estabelecemos condições onde só será satisfeita uma
delas também, mas o programa não dará uma resposta
automática de negação às proposições apresentadas que
rejeite qualquer uma que não satisfaça as condições
fornecidas pelo programador, só rejeitará apenas as que
você como programador estabelecer.
235
Podemos inserir o primeiro dentro do segundo, isto é, o
select case dentro de if’s e também ao contrário:
Exemplo:
Case acComboBox
strPrefix = "cbo"
i = ControlCS(ctl, strPrefix, fTag)
Case acCheckBox
strPrefix = "chk"
strControlSource = ctl.ControlSource
If fUnbound = False Then
i = ControlCS(ctl, strPrefix, fTag)
Else
i = ControlNA(ctl, strPrefix, fTag)
End If
„.................................................
CONSTANTES E ENUMERADORES
CONSTANTES
236
Usamos constantes para fixar um valor que estará
presente ao longo do código sem alterações ou para
estabelecer uma regra de cálculo para conversões de
dados. Na verdade ela difere da variável porque ao se
atribuir um valor, o programa ao ser compilado, esse valor
permanece inalterável.
Exemplo de constantes:
237
'e também no Access VBA quando no modo "Fontes
„pequenas" do Windows, 15 twips são iguais a um
pixel,
'e 567 twips equivale a 1 cm para efeito de
definição de „largura e altura de um objeto no
formulário.
sValor1 = Nz(Forms!frmConstantes!txtLargura)
sValor2 = Nz(Forms!frmConstantes!txtAltura)
If Forms!frmConstantes!txtLargura = sValor1
Then
Forms("frmConstantes").Controls("MinhaFig
ura").Width = sValor1 * TW
End If
Forms("frmConstantes").Controls("MinhaFig
ura").Height = sValor2 * TW
End If
End Function
Private Sub cmdMostrar_Click()
Call Redimensionar(txtLargura, txtAltura)
End Sub
ENUMERADORES
238
programador para representar os membros de uma
classe.
Exemplo de enumeradores:
Segunda = 2
Terca = 3
Quarta = 4
Quinta = 5
Sexta = 6
Sabado = 7
End Enum
Private Function
ObterDiadaSemana(ValordeEntrada As Dias
deTrabalho) As String
239
Case Is = 6
MsgBox "Sexta-Feira", vbInformation, "Dia
da Semana"
Case Is = 7
MsgBox "Sábado", vbInformation, "Dia da
Semana"
End Select
End Function
expression.Column(Index, Row)
240
Index (Índice) exige Long. Um inteiro longo que pode variar do
0 ao valor ajustado da propriedade ColumnCount menos
um(ColumnCount-1).
EXEMPLO :
241
OBS: Para exibir este nome digamos em uma MsgBox ou
fazermos qualquer referência a ele ao longo de seu
código temos que organizar a nossa caixa de
propriedades. Na aba Formato, o número de colunas
será 2(dois) ou mais, dependendo da posição do campo
Nome na tabela.
Número de Colunas: 2
Coluna acoplada: 2
242
O índice zero neste caso é porque não temos o campo
Código por não se tratar de referência a uma tabela e sim
a uma lista de valores, isto é, neste caso, nomes em
série.
243
No exemplo acima observamos que EDUARDO VIEIRA
MACHADO é o primeiro nome de uma lista. Mas de onde
vem esta lista? Vamos mudar para o modo Design
(Estrutura) do formulário.
244
A fonte de controle do objeto, no caso uma ComboBox de
nome FuNome, é a tabela Funcionários. Veja porém que
o campo Nome segue logo após RG. Conclui-se que é a
segunda coluna da tabela Funcionários.
Para efeito de ComboBox é a segunda coluna (column)
que estamos analisando, por isso a ordem dela na tabela
como segunda coluna é importante saber para que
possamos exibir a lista de nomes em nossa ComboBox.
245
Observe que o campo Nome é a segunda coluna da
tabela. Ok? Vamos então fazer algumas alterações na
propriedade de nossa ComboBox (ou controle) que é
também, por assim dizer, um objeto do formulário
Funcionários.
246
Alteramos o Número de colunas a exibir na
ComboBox(cboNome) para 2, isto é, RG(FuRG) e
Nome(FuNome), mas ocultamos o primeiro campo,
colocando o valor (0cm) como primeiro valor da linha
Larguras das colunas e x cm(x=1 ou 2 cm, etc) separados
por ponto e vírgula. Colocaremos tantos 0cm quanto
necessários separados por ponto e vírgula(;) quando
quisermos exibir a coluna desejada.
LISTBOX
247
atribuir diversos métodos para contar e informar total de
registros implantados, somar valores de uma determinada
coluna, selecionar registros, etc.
Exemplo(1)
Contagem de registros:
(1) Propriedade ListCount.
248
total, porque senão teríamos no total da contagem o valor
6 contados do total de registros.
249
Exemplo 2:
Propriedade Column.
Técnica N.º 1:
250
MsgBox "O valor existente na 2a coluna é "
& Me.Lista9.Column(1) & ".", vbInformation,
"Registro procurado"
End Sub
Técnica N.º 2:
251
para exibir a informação completa desta coluna e de todas
as outras no formato matriz de dados, em um só clique.
252
"3.ª coluna é : " & Me.Lista9.Column(2) &
vbCrLf & _
"4.ª coluna é : " & Me.Lista9.Column(3) & "",
vbInformation, "Registro procurado"
End Sub
Técnica N.º 3:
For i = 1 To Me.Lista.ListCount - 1
If Lista.ItemsSelected(i) = True Then
If Lista.Column(i) =
Forms![NomedoSeuFormulário]!NomedoSeuCampo Then
253
Next i
End Function
Exemplo 3:
Set rs = Me.RecordsetClone
rs.FindFirst "[IDCodigo] = """ & Me.SuaListBox
& """"
If rs.NoMatch Then
MsgBox "Registro Não
Encontrado.",vbInformation,"Localizar ..."
Else
'Exibe o registro no formulário
Me.Bookmark = rs.Bookmark
End If
Set rs = Nothing
End If
End Sub
254
CALCULANDO TOTAIS COM LISTBOX
255
Me.Total = SomarTotal „SomarTotal é a função
que realiza o cálculo e nos retorna um valor.
End Sub
End Function
O resultado será:
256
TEXTBOX (CAIXAS DE TEXTO)
Propriedades:
TextAlign (Alinhamento de texto)
RightMargin (Margem à direita)
LeftMargin (Margem à esquerda)
TopMargin (Margem superior)
257
BottomMargin (Margem inferior)
If CurrentProject.AllForms("Logos").IsLoaded
Then„Se o formulário Logos estiver aberto faça
assim
If Forms!Catálogo!cboPosicao.Column(0) = "À
Direita" Then
Forms("MeuFormulário").Controls("MinhaCaixadeTe
xto").TextAlign = 3 „Alinha o texto à
direita
ElseIf Forms!Catálogo!cboPosicao.Column(0) = "À
Esquerda" Then
Forms("MeuFormulário").Controls("MinhaCaixadeTe
xto").TextAlign = 1 „Alinha o texto à
esquerda
ElseIf Forms!Catálogo!cboPosicao.Column(0) =
"Centro" Then
Forms("MeuFormulário").Controls("MinhaCaixadeTe
xto").TextAlign = 2 „Alinha o texto no
centro
ElseIf Forms!Catálogo!cboPosicao.Column(0) =
"Justificado" Then
258
Forms("MeuFormulário").Controls("MinhaCaixadeTe
xto").TextAlign = 4 „Alinha o texto
justificado
Else
Exit Sub
End If
End Function
sValor1 = Nz(Forms!Catálogo!cboMargDireita)
„Valor na combo em cm.
sValor2 = Nz(Forms!Catálogo!cboMargEsq)
sValor3 = Nz(Forms!Catálogo!cboMargSuperior)
sValor4 = Nz(Forms!Catálogo!cboMargInferior)
259
If Forms!Catálogo!cboMargDireita = sValor1 Then
Forms("MeuFormulário").Controls("MinhaCaixadeTe
xto").RightMargin = sValor1 * TW
Forms("MeuFormulário").Controls("MinhaCaixadeTe
xto").LeftMargin = sValor2 * TW
Forms("MeuFormulário").Controls("MinhaCaixadeTe
xto").TopMargin = sValor3 * TW
Forms("MeuFormulário").Controls("MinhaCaixadeTe
xto").BottomMargin = sValor4 * TW
260
Else
Exit Sub
End If
End Sub
261
OBTION BUTTONS (Ou Botões de Opção)
SUBFORMS(Subformulários)
262
No campo TOTAL PAGO temos a soma de todos os
valores em Reais dos produtos comprados pelo cliente
José Maria de Azevedo, filtrados no sub-formulário. Como
fizemos essa soma? Observe o modo Design deste
formulário.
263
Na fonte do controle do campo txtTotal(Total) do sub-
formulário, temos:
=[Produtos subformulário]![txtTotal]
264
O resultado será este.
265
Public Sub AtualizarSaldo()
On Error Resume Next
Dim strSQL As String
266
PRINCIPAIS EVENTOS DE UM CONTROLE
267
BeforeUpdate Antes De Atualizar
Change Ao Alterar
Click Ao Clicar
Close Ao Fechar
Current No Atual
DblClick Ao Clicar Duas Vezes
Deactivate Ao Desativar
Delete Ao Excluir
Enter Ao Entrar
Error Ao Ocorrer Erro
Exit Ao Sair
Filter Ao Filtrar
Format Ao Formatar
GotFocus Ao ReceberFoco
Initialize nenhuma
ItemAdded nenhuma
ItemRemoved nenhuma
KeyDown Ao Apertar Tecla
KeyPress Ao Pressionar
TeclaKeyUp Ao Liberar Tecla
Load Ao Carregar
LostFocus Ao Perder Foco
MouseDown Ao Apertar Mouse
MouseMove Ao Mover Mouse
MouseUp Ao Liberar Mouse
NoData Se Nenhum Dado
NotInList Se Não Estiver Na Lista
Open Ao Abrir
Page Na Página
Print Ao Imprimir
Resize Ao Redimensionar
268
Os eventos principais dos controles mais usados são (Not
In List, AfterUpdate, BeforeUpdate, Change, Current,
Enter, Click, Double-Click, GetGocus, LostFocus e Exit)
Exemplo 1:
269
Msg = "'" & NewData & "' NÃO ESTÁ NA LISTA DE
COMODOS." & vbCr & vbCr
Msg = Msg & "VOCÊ DESEJA ADICIONÁ-LO?"
End Sub
_________
* É uma constante do Access. Devolve as atualizações se
ocorrer um erro (apenas espaços de trabalho do Microsoft
Access). Fonte: Ajuda do Access
** Definindo o valor do argumento Response para esta
constante, você indica ao Access que o valor digitado na lista
foi adicionado à tabela definida na propriedade Origem da linha
da caixa de combinação(combobox). Isso fará com que a lista
seja automaticamente reconsultada, passando a exibir entre
seus itens o valor digitado (como ocorre com a caixa de diálogo
Executar do Windows) Fonte: Programando Microsoft Access
com VBA, Vol. 3, pág. 13, Flávio Morgado)
270
*** Definindo o argumento Response para esse valor, indica-se
ao Access para não reconsultar a lista e não exibir uma
mensagem de erro para o item inexistente. Neste caso, o item
digitado será aceito como o novo valor da caixa de
combinação, apesar da propriedade Limitar a Uma Lista estar
definida para Sim;
Fonte: Programando Microsoft Access com VBA, Vol. 3, pág.
13, Flávio Morgado)
CodComodo
Comodo
271
criada para receber os valores referentes aos
comodos.
Crie uma consulta referente a esta tabela como o seguinte
nome cnsComodos com dois campos apenas. No modo
Design, Propriedade, Valores Exclusivos configurado
como Sim.
272
O que acontece se essas propriedades não estiverem
configuradas corretamente? Logicamente, você não
poderá inserir nenhuma informação. O contrário acontece
se estiver com informação.
273
Vamos tentar inserir um comodo que não está na lista e
ver o que acontece.
274
Como sua resposta deverá ser Sim, o novo comodo é
adicionado à lista.
CONTROLES-GUIAS
275
formular um código para diferenciar a sua pesquisa de
dados de uma página para a outra.
276
Exemplo:
Me.lblStatus.Caption = "EXIBINDO
VENDAS..."
Case 1
Me.lstCodigo.visible = False
Me.tbl_Produtos.visible = True
Me.Gráfico62.visible = False
Me.RecordSource = "SELECT * FROM
tbl_Produtos"
Me.lblStatus.Caption = "EXIBINDO
ESTOQUE..."
Case 2
Me.lstCodigo.visible = False
277
Me.tbl_Produtos.visible = False
Me.Gráfico62.visible = True
Me.Gráfico62.Requery
Me.lblStatus.Caption = "EXIBINDO
GRÁFICO..."
End Select
End Sub
278
Naturalmente, você notou que na linha 4 o nome AMAURI
DAMIÃO XAVIER DE ANDRADE aparece em destaque
na cor vermelha. Ao selecionar com o mouse aquela linha
este efeito acontece. Como se faz isso?
Primeiramente, o seu formulário deve ser criado no
formato tabular ou modificado pelo modo
Design(Estrutura) e em propriedades do formulário, na
aba Formato, o modo Padrão dever ser Formulário
Contínuo.
279
Selecione no espaço Condição 1 o item „A Expressão‟ e
no campo ao lado digite [STATUS]=-1 e a cor da fonte
desejada.
280
Private Sub PREPOSTO_GotFocus()
Me!PREPOSTO.SelStart = Len(Me!PREPOSTO &
"") „Propriedade SelStart ajusta o ponto
inicial do texto selecionado
End Sub
Exemplo
281
& "FROM SuaTabela2 WHERE Código = " & nCod
db.Close
Set db = Nothing
DoCmd.SetWarnings False
End Sub
Exemplo:
Set db = OpenRecordset("SuaTabela",
dbOpenTable)
282
CurrentDb.Execute " UPDATE SuaTabela1 SET
Campo1 = „Rio de Janeiro‟ WHERE Código = " &
nCod „Campo1 poderia ser Cidade
db.Close
Set db = Nothing
DoCmd.SetWarnings False
End Sub
Exemplo (1):
283
ExibirValor = Int((6 * Rnd) + 1)„Serão
exibidos seis números que podem se repetir
aleatoriamente
MsgBox ExibirValor, vbExclamation, "Função
Round(Rnd)"
Next i
End Sub
Set rs =
CurrentDb.OpenRecordset("tblClientes",
dbOpenTable)
k = rs.RecordCount
284
MsgBox "Registro: " & LRandomNumber,
vbExclamation, "Aleatorio"
End Sub
285
Tipo(10) = "Não disse que você iria tirar
de letra?"
Hora = Time
Call Randomize„Chamada da função do tipo Rnd de
„valores inteiros que exibirá o total de 10
„mensagens(vetores) aleatoriamente
„Tipo(Int(10*Rnd)+1)
286
(3) Exibindo sinais gráficos como a letra O e X em jogos
como Jogo da Velha
Exemplo:
287
alternados ou aleatórios sorteados pela função
Randomize definida a quantidade de vezes
especificada entre parênteses em conjunto com a
função Rnd(Random). Random significa Aleatório.
End If
ElseIf Chave = pal(2) Then
If IsNull(Casa4) Or Casa4 = "" Then
Casa4 = Replace(Chave, "'", "")„No segundo
vetor precisarei retirar o apóstrofo com a
função Replace. Por que isto? Porque não é
possível trabalhar vetores com elementos
iguais. Farei isto com todos os outros vetores.
Cada casa com exceção da Casa1 poderá receber o
valor de cada vetor aleatório, isto é, o seu
elemento modificado.
End If
ElseIf Chave = pal(3) Then
If IsNull(Casa5) Or Casa5 = "" Then
Casa5 = Replace(Chave, "*", "")
End If
ElseIf Chave = pal(4) Then
If IsNull(Casa6) Or Casa6 = "" Then
288
Casa6 = Replace(Chave, "!", "")
End If
ElseIf Chave = pal(5) Then
If IsNull(Casa7) Or Casa7 = "" Then
Casa7 = Replace(Chave, "@", "")
End If
ElseIf Chave = pal(6) Then
If IsNull(Casa9) Or Casa9 = "" Then
Casa9 = Replace(Chave, "%", "")
End If
ElseIf Chave = pal(7) Then
If IsNull(Casa8) Or Casa8 = "" Then
Casa8 = Replace(Chave, "$", "")
End If
ElseIf Chave = pal(8) Then
If IsNull(Casa3) Or Casa3 = "" Then
Casa3 = Replace(Chave, "&", "")
End If
Else
Exit Function
End If
End If
289
pal(4) = "X!"
pal(5) = "X@"
pal(6) = "X%"
pal(7) = "X$"
pal(8) = "X&"
290
If IsNull(Casa9) Or Casa9 = "" Then
Casa9 = Replace(Chave, "%", "")
End If
ElseIf Chave = pal(7) Then
If IsNull(Casa8) Or Casa8 = "" Then
Casa8 = Replace(Chave, "$", "")
End If
ElseIf Chave = pal(8) Then
If IsNull(Casa6) Or Casa6 = "" Then
Casa6 = Replace(Chave, "&", "")
End If
Else
Exit Function
End If
End If
End Function
291
modo propriedades do formulário, clique na aba Eventos,
selecione intervalo de cronômetro. Geralmente para
relógios, o intervalo de cronômetro é 1000, ou se você
desejar poderá alterá-lo via código como no exemplo
abaixo.
Exemplo de um relógio:
xSegundo = Second(txtTime)„txtTime é a
caixa de texto que exibe a hora, minuto e
segundos
xMinuto = Minute(txtTime)
xHora = Hour(txtTime)
Me.TimerInterval = 1000 „Altera o
intervalo de cronômetro influindo na
velocidade da animação
If xSegundo < 60 Then
xSegundo = xSegundo + 1
Else
xSegundo = 0
If xMinuto < 60 Then
xMinuto = xMinuto + 1
Else
xMinuto = 0
xHora = xHora + 1
End If
292
End If
Me.txtTime = Format(TimeSerial(xHora,
xMinuto, xSegundo), "hh:mm:ss")
End Sub
A FUNÇÃO TIME
TRATAMENTOS DE ERROS
293
Geralmente quando queremos assegurar que o aplicativo
rodará sem avisar sobre erros de depuração de código,
incluímos a seguinte linha de código antes do código
principal de nossa sub-rotina:
1.º CASO
Exemplo (1)
Private Sub cmdAbrir_Click()
Dim A As Integer
End Sub
294
O que acontecerá após eu dar OK?
295
variável A recebeu, ser do tipo String, mas foi declarada
como do tipo Integer. Este é o erro.
1.º CASO
Option Compare Database
Option Explicit
Dim A As Integer
296
297
Geralmente, os erros obedecem um padrão em uma
escala tabular já pré-estabelecida pela Microsoft.
2.º CASO
Private Sub cmdAbrir_Click()
On Error GoTo TrataErro„Ao ocorrer um erro vá para
TrataErro
Dim A As Integer
End Sub
298
Nota: Observe que a mensagem “Seu Nome é ...” será
ignorada e ao invés esta mensagem personalizada
surgirá, evitando que o aplicativo seja interrompido com
uma mensagem inconveniente de depuração de código e
deixe vulnerável seu aplicativo para alterações indevidas
de seus usuários.
299
Finalizando a Sub-Rotina
MÓDULOS
Podemos ter módulos padrão e módulos de classe. Neste
livro, porém, vamos abordar somente módulos padrão.
Módulos Padrão:
300
“Um módulo é essencialmente uma coleção de
declarações, instruções e procedimentos armazenados
conjuntamente como uma unidade chamada para
organizar seu código do Microsoft Visual Basic. O
Microsoft Access possui dois tipos básicos de módulos:
módulos padrão e módulos classe.”
Módulos classe – contém procedimentos para formulários
e relatórios.
Módulos – contém procedimentos para uso geral.
301
On Error GoTo Err_Handler
For Each doc In
Db.Containers("Forms").Documents
DoCmd.OpenForm doc.Name, acDesign, , , ,
acHidden
For Each ctl In Forms(doc.Name)
If TypeOf ctl Is Label Then
ctl.FontName = "Arial"
ctl.FontSize = 7
ElseIf TypeOf ctl Is TextBox Then
„Alterações dos controles
ctl.FontName = "TimesNewRoman" „Define
todas os tipos de „fontes
ctl.FontSize = 10 „Define o tamanho
das fontes
ctl.BorderColor = 14727292 „Define a
cor de todas as bordas „dos controles
ctl.BackColor = 16769734 „Define a cor
de fundo de todos os controle
ctl.BackStyle = 1 „Define
se o controle será transparente ou não
ctl.BorderWidth = 2 „Define a
largura da borda de todos os controles
ctl.ForeColor = 6697728 „Define a cor
dos caracteres
ctl.SpecialEffect = 4 „Define o
efeito especial do controle, por exemplo, com
alto relevo ou baixo relevo.
ctl.BorderStyle = 1 „Define o
estilo de borda se é do tipo fino(com bordas
não acentuadas), ou caixa de diálogo etc
End If
302
Next
DoCmd.Close acForm, doc.Name, acSaveYes
Next
Exit_MudaPropriedades:
Set Db = Nothing
Exit Sub
Err_Handler:
MsgBox "Error #: " & Err.Number & vbNewLine
& Err.Description
Resume Exit_MudaPropriedades
End Function
APLICATIVOS EM REDE
303
Os Comandos e adicioná-los à sua barra de ferramentas,
Guias Principais. Após a replicação, isto é, a geração de
cópias de seu bd na rede, a cada alteração ou inclusão de
registros, clique em Sincronizar Agora.
304
3. Para cada conflito mostrado no Visualizador de
conflitos, escolha uma destas opções:
4. Clique em Resolver.
5. Repita as etapas 3 e 4 quantas vezes forem
necessárias para resolver cada conflito da tabela.
305
Você não consegue editar o mesmo arquivo, mas
consegue fazer isso em dois locais diferentes da rede, e o
Source Safe comita as alterações em ambos os arquivos
quando você solicitar.
AVALIAÇÃO:
306
Private Sub cmdPotencial_Click()
Dim x As Integer
Dim y As Integer
Call CalculaPotenciacao(x, y)
End Sub
307
7 - Estude o seguinte código de um botão. Faça em
seguida um código semelhante que informe através
de uma MsgBox algumas informações de registros de
uma tabela Clientes, por exemplo:
Set db = CurrentDb()
Set rs = db.OpenRecordset("SELECT * FROM tbl_OS
WHERE NOME = '" & NomeU & "' ORDER BY
DIASSATUALIZAÇÃO DESC")
308
For i = 1 To rs.RecordCount „Método para
contagem total de registros. Retorna o número
máximo de registros da tabela ou recordset
DIFER = Abs(DateDiff("d",
rs.Fields("DATASOLICITACAO"),
rs.Fields("DATAEXECUCAO")))
diferenca = Abs(DateDiff("d",
rs.Fields("DIASSATUALIZAÇÃO"),
rs.Fields("PRAZO")))
309
& "" & vbCrLf & "O.S." &
rs.Fields("ORDEMDESERVICO") & vbCrLf & _
"DATA DA SOLICITAÇÃO: " &
rs.Fields("DATASOLICITACAO") & vbCrLf & "DATA
DA EXECUÇÃO: " & rs.Fields("DATAEXECUCAO") & _
vbCrLf & "TIPO DE SERVIÇO: " &
rs.Fields("TIPODESERVICO") & vbCrLf & "OBS: " &
rs.Fields("OBS") & vbCrLf & "PRAZO(DIAS): " &
rs.Fields("PRAZO") & vbCrLf & _
"DIAS DECORRIDOS: " & DIFER & vbCrLf & "PRAZO
EXTRAPOLADO? " & IIf(rs.Fields("PRAZO") >=
DIFER, "NÃO", "SIM") & _
vbCrLf & vbCrLf &
"**********************************************
" & vbCrLf & IIf(rs.Fields("PRAZO") >= DIFER,
"PARABÉNS, ", "ATENÇÃO, RISCO DE MULTA ") &
rs.Fields("NOME") & " !!!" & vbCrLf & _
"**********************************************
" & vbCrLf & "RELATÓRIO GERAL: " & vbCrLf &
vbCrLf & _
"O.S. NÃO EXECUTADAS: " & dif & vbCrLf & _
"O.S. EXECUTADAS: " & totalCump & vbCrLf &
"TOTAL DE O.S.: " & totalOS & vbCrLf & _
"**********************************************
intRetVal = MsgBox(strMsg, vbOKCancel +
IIf(rs.Fields("PRAZO") >= DIFER, vbInformation,
vbCritical), strTitle)
Select Case intRetVal
Case vbOK
Case vbCancel
Exit Sub
310
End Select
Else
strTitle = "CONTROLE DE ORDENS DE SERVIÇO -
ANÁLISE CRÍTICA"
count = count + 1
diferenca = Abs(DateDiff("d",
rs.Fields("DIASSATUALIZAÇÃO"),
rs.Fields("PRAZO")))
dif = DCount("[ORDEMDESERVICO]", "tbl_OS",
"[EXECUTADA] = 0")
'dif = DCount("*", "cnsExecutada") ' Também é
válida
totalOS = DCount("*", "tbl_OS")
totalCump = totalOS - dif
strMsg = "O.S DE No: " & count & vbCrLf &
vbCrLf & _
"O.S.: " & rs.Fields("ORDEMDESERVICO") & "" &
vbCrLf & "MATRÍCULA: " & rs.Fields("MATRÍCULA")
& " " & vbCrLf & _
"DATA DA SOLICITAÇÃO: " &
rs.Fields("DATASOLICITACAO") & vbCrLf & "DATA
DA EXECUÇÃO: " & rs.Fields("DATAEXECUCAO") &
vbCrLf & _
"TIPO DE SERVIÇO: " &
rs.Fields("TIPODESERVICO") & vbCrLf &
"DAE/ÓRGÃO: " & rs.Fields("DAEORGAO") & vbCrLf
& "DIAS SEM ATUALIZAÇÃO: " &
rs.Fields("DIASSATUALIZAÇÃO") & vbCrLf & _
311
"**********************************************
" & vbCrLf & "PRAZO(DIAS): " &
rs.Fields("PRAZO") & vbCrLf & _
"DIAS ATÉ/EXCEDENTES O/AO PRAZO: " & diferenca
& vbCrLf & "PRAZO EXTRAPOLADO? " &
IIf(diferenca > rs.Fields("PRAZO"), "SIM",
"NÃO") & vbCrLf & _
IIf(diferenca > rs.Fields("PRAZO"), "ATENÇÃO,
RISCO DE MULTA ", "MUITO BEM ATÉ AGORA, FAVOR
ACOMPANHAR ") & rs.Fields("NOME") & vbCrLf & _
"**********************************************
" & vbCrLf & "RELATÓRIO GERAL: " & vbCrLf &
vbCrLf & _
"O.S. NÃO EXECUTADAS: " & dif & vbCrLf & _
"O.S. EXECUTADAS: " & totalCump & vbCrLf &
"TOTAL DE O.S.: " & totalOS & vbCrLf & _
"**********************************************
" & vbCrLf & "AVISO !!! " & vbCrLf & "USUÁRIO:
" & rs.Fields("NOME") & vbCrLf & _
"CASO ESTA O.S. AINDA NÃO TENHA SIDO EXECUTADA
" & vbCrLf & "OU JÁ TENHA SIDO BAIXADA,CONTATE
O DAE/ÓRGÃO, " & vbCrLf & _
"VERIFIQUE AS CAUSAS, ANALISE-AS COM CUIDADO "
& vbCrLf & "EM BUSCA DE UMA SOLUÇÃO E ABRA UMA
NOVA O.S. !!! " & vbCrLf & _
"ESTA O.S. PRECISA SER EXECUTADA !!!"
intRetVal = MsgBox(strMsg, vbOKCancel +
IIf(diferenca > rs.Fields("PRAZO"), vbCritical,
vbInformation), strTitle)
312
Case vbOK
Case vbCancel
Exit Sub
End Select
End If
rs.MoveNext
Next i
End Sub
313
CAPÍTULO 4 – DOMINANDO O ACCESS VBA II
(RELATÓRIOS)
314
(1) Na barra de ferramentas, clique na aba Criar,
Assistente de Relatório. Selecione a tabela tblAtletas e
clique no botão >>. Em seguida, clique no botão Avançar.
315
(3) Em resposta à pergunta Deseja adicionar algum
nível de agrupamento?, selecione o campo
CódigodoAtleta e clique no botão com o sinal gráfico (>).
316
A partir daí você pode determinar se seu relatório será
visualizado com destaque no código do atleta ou nome
do clube, etc.
317
Como isso foi feito?
318
Observe que as caixas de texto para os sub-totais foram
colocadas abaixo do Cabeçalho do código(MasterID)
correspondente a cada competidor que por sua vez está
um nível acima de todos os outros campos do relatório.
Como isto foi feito?
319
CRIANDO RELATÓRIOS COM NÍVEIS E
AGRUPADOS
320
Siga o passo-a-passo do assistente selecione o nome da
escola com um nível acima. Pronto, agora vamos contar o
número de servidores da escola. Observe o modo
Estrutura do formulário acima. Coloque uma caixa de
texto no cabeçalho referente ao campo que está um nível
acima e na fonte de controle =Contar(*) , para obtermos a
contagem do número de PROFESSORES por NOME DA
ESCOLA, isto é, por grupos.
321
Simples, não? Para somar valores por grupos, coloque :
=Soma([NomedoCampo])
322
CRIANDO RELATÓRIOS COM CAMPO
CALCULADO
Já a caixa de texto(Total) está no cabeçalho do relatório.
Como é feito o cálculo dos sub-totais? Como é feito o
cálculo do total? Isso você vai aprender após estudar as
funções DLookup(DPesquisa) e DSum(DSoma).
323
No campo txtTotalIndividual correspondente à coluna
Pontos ficou assim:
=DSoma("Pontos";"CalculaPontos";"MasterID =
Reports!CalculaPontos!MasterID")
324
No campo txtTotal ficou assim:
=DSoma("Pontos";"CalculaPontos")
325
IMPRESSÃO DE RELATÓRIOS VIA ACCESS
VBA*
326
Ou então como colocado por Alex Dybenko, o seguinte
método que não exige que o relatório seja aberto no modo
Preview.
DoCmd.PrintOut , , , , 2
DoCmd.PrintOut , , , , 1
327
Finalmente se o relatório que você deseja imprimir venha
a diferir dependendo das circunstâncias, você pode
substituir o nome do relatório com uma simples variável
como está demonstrado no código abaixo:
Private Sub btnImprimeDoc_Click()
Dim strNomeDoc as String
End Sub
328
________
http://www.creativeconnections.co.uk/index.php/microsoft-access/192-
how-to-automatically-print-out-an-access-report-using-vba
329
Utilize o assistente do relatório e classifique os campos
com as fotos por categoria, pela divisão por nível; em
seguida, layout por Estrutura de Tópicos e, por último,
orientação paisagem. O Access só aceita figuras com
extensão (.bmp). Daí você teria que converter todas as
fotos(.jpg, png, etc.) para esta extensão(.bmp) primeiro
antes de continuar.
330
AVALIAÇÃO:
331
______
* Os dados naturalmente podem ser diferentes
332
Assim, estamos concluindo este livro de fundamentos do
Access VBA para que você passe agora para o meu outro
livro Técnicas Especiais de Access VBA que abordam ou
aplicam com mais profundidade tudo o que foi estudado
neste livro e com fins mais profissionais. Para quem
deseja estudar Ciência da Computação sugiro adquirir
meu mais recente livro Engenharia de Software com
Access VBA.
333