P. 1
Apostila Visual Basic

Apostila Visual Basic

4.8

|Views: 21,948|Likes:
Published by RobertoGodoy
VB 6.0
VB 6.0

More info:

Published by: RobertoGodoy on Apr 09, 2008
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as DOC, PDF, TXT or read online from Scribd
See more
See less

08/20/2013

pdf

text

original

Sections

Uma chave primária é útil quando queremos que uma tabela não aceite valores nulos e
nem valores duplicados. Uma chave primária também é útil para se relacionar com outras
tabelas.

Podemos dizer que uma chave primária é um índice ou um conjunto de índices que não
podem ter valores repetidos ou nulos. Por exemplo, digamos que você defina como chave
primária 2 campos. Um referente ao campo Codigo e outro ao campo Nome. Poderíamos
até ter 2 códigos iguais e 2 nomes iguais, mas uma combinação de nome e código igual não
poderia existir. A chave primária nesse caso, seria um índice que definimos com a
propriedade Primary e definimos que o mesmo teria como base o campo Nome e o campo
Código.

Devo admitir que na teoria isso parece um pouco confuso, mas na prática fica bem mais

simples.

Uma tabela pode ter apenas uma chave primária(também chamada de índice primário),
mas pode ter vários índices. Se você tentar atribuir mais de um índice como Primary, irá
receber uma mensagem de erro dizendo que o índice não pode ser criado.
Como a tabela que criamos é bem mais simples e o índice que criamos(Nome), já dá
conta de não permitir valores nulos e repetidos, uma chave primária é no
momento,desnecessária.

Acessando o banco de dados através do Visual Basic

O Visual Basic oferece objetos que nos permitem interagir de forma completa com o
Banco de Dados. Podemos alterar a estrutura das tabelas, criar tabelas, campos, índices,
inserir registros, alterar registros, excluir registros, etc...
No nosso curso veremos como interagir com as tabelas que criamos no Visual Data

Manager.

Primeiramente, crie um novo projeto. Agora, você deve chamar uma biblioteca que
disponha de objetos para manipulação de banco de dados. Temos várias. No nosso curso
iremos usar o Microsoft DAO 3.6 Object Library.

107

Marque essa biblioteca e selecione OK.
Agora já podemos usar os objetos que essa biblioteca nos oferece.

Abrindo um banco de dados

Vamos agora, realizar algumas operações envolvendo bancos de dados. Primeiro crie
uma pasta de trabalho no diretório c:\ com o nome de Trabalho. Depois crie um banco de
dados com o nome DbCurso dentro dessa mesma pasta.
Crie uma tabela nesse banco de dados chamada clientes com os seguintes campos e

atributos:

Campo

Tipo

Tamanho

Codigo

Long(Autoincrementável)

Nome

Text

40

Cpf

Text

15

Rg

Text

11

DataNascimento

DateTime

DataCadastro

DateTime

Endereco

Text

30

Bairro

Text

3

Casado

Boolean
Alguns campos aparecem sem seus respectivos tamanhos por quê não são necessários
devido ao tipo do campo selecionado.
Adicione um índice para o nome chamado IndNome, outro para o Código chamado
IndCodigo e uma chave primária com base no campo Nome e no campo Código e se
chamará Chave.

108

Através do Microsoft Access ou do Visual Data Manager, acrescente 5 registros a essa

tabela e grave-a.

Agora que já temos um banco de dados com uma tabela, vamos aprender como abrimos
o banco de dados e lemos os dados da tabela.
O primeiro objeto de banco de dados que vamos conhecer é objeto Database. Um
objeto Database contém propriedades, funções e métodos relativos á banco de dados. Para
abrir um banco de dados usando o objeto Database, devemos usar a função
OpenDatabase. Essa função só é disponível quando a biblioteca do Microsoft DAO foi
selecionada.

Primeiramente, devemos declarar um objeto Database. Vamos declarar uma variável
chamada Banco como sendo um objeto Database:

Dim Banco as Database

Depois, iremos instanciar o objeto Banco que criamos apontando para a função
OpenDatabase que abrirá o banco de dados que desejarmos. A função OpenDatabase tem
a seguinte sintaxe:

OpenDatabase( dados>,,,)

- Uma string que representa o caminho completo,
incluindo o nome do banco de dados.

(Opcional)- Determina se o banco de dados será aberto em modo exclusivo ou
não. True para exclusivo e False para modo compartilhado. Este recurso é útil quando
iremos criar um sistema que será usado em rede(Multiusuário). Se este argumento for
omitido o padrão será False.

(Opcional)- O tipo de acesso deve informar se o banco de dados será
aberto como somente leitura(True) ou para leitura/gravação(False) .

(Opcional)- Uma string que determina várias opções de configuração,
incluindo senhas.

A pergunta que talvez esteja na sua cabeça é “Onde devo declarar um objeto Database?”.
Bem, na verdade um objeto Database, assim como as variáveis no Visual Basic, podem ser
declaradas em qualquer lugar. No entanto, se declararmos o objeto Database em um
subprocedimento, ele será restrito somente ao subprocedimento em que foi declarado. O
ideal é sempre usarmos declará-lo na seção General-Declarations do formulário ou
módulo que formos usá-lo. Se usarmos em um módulo, esteve objeto será visível em todos
os outros módulos e formulários. No nosso exemplo, usaremos na seção General-
Declarations
do formulário onde ele será usado.
Vamos voltar a declaração do objeto Database que começamos.

109

Declaramos um objeto Database chamado Banco na seção General-Declarations do
nosso formulário.

Agora, para usarmos esse objeto, temos de instanciá-lo apontando para a função
OpenDatabase, como vimos anteriormente. O local ideal para fazer essa instanciação é no
evento Load do formulário. Teremos assim desta forma, o objeto instanciado durante todo
o tempo que o código estiver sendo executado no formulário.
A sintaxe da função OpenDataBase já vimos anteriormente. Veremos agora como
ficaria se usássemos o banco de dados que criamos na nossa pasta de trabalho.

Usamos apenas o primeiro argumento que representa o caminho e o nome do banco de
dados. Como você pode ver, os banco de dados do tipo Access terminam com a extensão
“.mdb”, sendo portanto, necessário que especifiquemos o nome completo do banco de
dados. Os outros argumentos são opcionais.
Agora que já temos o objeto Database instanciado, podemos usar os seus recursos a

qualquer momento.

O primeiro recurso do objeto Database que iremos conhecer é o método
OpenRecordset. Este método serve para abrirmos um RecordSet. Claro que antes de usá-
lo você precisa saber o que é um RecordSet e para o que serve.

O que é um Recordset?

Recordset é um objeto que representa uma tabela. Assim como o objeto Database
representa o banco de dados, o objeto Recordset representa uma tabela. Com ele, podemos
efetuar todas as operações em tabelas que fazíamos via Access ou Visual Data Manager.
Agora que já sabemos pra que serve um Recordset vamos aprender a declará-lo e
instanciá-lo. Primeiro, vá na seção General-Declarations, onde já declaramos um objeto
Database, e declare lá também um objeto Recordset com o nome de Tabela.

110

Depois de declarar o objeto Recordset, será necessário instanciá-lo. É aí que entra o
método OpenRecordset do objeto Database. Veremos agora a sintaxe do método
OpenRecordset:

OpenRecordset(,,,)

- Uma string contendo o nome da tabela que desejamos abrir.Na
verdade, esse argumento não precisa ser necessariamente um nome de tabela. Pode também
ser uma consulta ou uma instrução SQL. No nosso curso usaremos somente atribuí-lo com
o nome da tabela.

- Ao abrirmos um objeto recordset, poderemos escolher entre vários tipos de
aberturas diferentes. Esse argumento pode ser um número ou uma constante interna que
determina o tipo de abertura. Veremos agora os tipos mais usados:

DbOpenTable – Ao usar a contante DbOpenTable, estamos abrindo um objeto
RecordSet do tipo Table como se ele fosse uma tabela normal. Podemos consultar
registros, adicionar registros, excluir registros, atualizar registros e todas as operações que
podemos fazer via Access ou Visual Data Manager.

DbOpenSnapShot – Esta outra contante nos permite abrir um objeto recordset como sendo
do tipo SnapShot. Um recordset do tipo SnapShot pode ser visto como uma cópia virtual
dos dados. Ou seja, é uma cópia da tabela no exato momento em que for criado o objeto
recordset tipo SnapShot. Não podem ser atulizados. Seu uso se restringe a consultas.

DbOpenDynaset – Essa constante cria um objeto RecordSet tipo Dynaset. Um Dynaset é
muito semelhante a um SnapShot. A diferença é que os Dynaset podem ser atualizados.

Devo lembrar que cada um desses tipos de RecordSet contem várias particularidades não
mencionadas aqui, sendo estas que citei, portanto, as mais importantes.
Voltando a abertura do nosso banco de dados, usaremos um objeto recordset do tipo
Table, pelo fato desse tipo de recordset ter as mesmas características de uma tabela. Dessa
forma, poderemos efetuar todas as operações que
precisamos(Inclusão,Alteração,Consulta,Exclusão).
Já que temos o objeto Database instanciado e o objeto RecordSet declarado, vamos
agora instanciar o objeto RecordSet, apontando para o método OpenRecordset do objeto
Database. Ficaria assim:

111

Instanciamos o objeto tipo Recordset apontando para o método OpenRecordset do
objeto DataBase. Como usamos no argumento do método OpenRecordset ,a
contante DbOpenTable, o objeto tipo RecordSet aberto, será do tipo Table. Ou seja, se
comportará como se fosse uma tabela normal.
Pronto! Agora a variável Tabela tem todas as características de um objeto recordset do
tipo Table e têm também todos os registros existentes na tabela Clientes.

Consultando Registros

Desde que já tenhamos um objeto Recordset aberto, poderemos facilmente consultar
seus registros. Há dois tipos de sintaxes que podemos utilizar para retornar valores de
registros:

()

ou

!

Exemplo:

TxtNome.Text = Tabela(“Nome”)

Ou

TxtNome.Text = Tabela!Nome

No projeto que criamos, adicione um TextBox chamado TxtNome e utilize o exemplo
anterior para preencher o TextBox com o valor do campo Nome. Você pode adicionar mais
TextBoxs ao formulário e fazer com que os demais campos sejam exibidos. Rode o
programa.

Você deve ter notado que os dados exibidos no formulário são referentes ao primeiro
registro. Isso por quê quando abrimos um recordset, ele aponta primeiramente para o
primeiro registro. Como se tivéssemos aberto uma tabela no Access ou no Visual Data
Manager.
É como se existisse um ponteiro virtual que sempre está apontando para um
registro X.

Na prática, consultar apenas o primeiro registro não nos adiantaria. È ai que entram os
métodos de navegação que veremos agora.

Navegação através dos registros

MoveNext –Este método moverá o ponteiro para o próximo registro.

MovePrevious – Move o ponteiro para o registro anterior

112

MoveFirst – Move o ponteiro para o primeiro registro.

MoveLast – Move o ponteiro para o último registro.

Move – Move o ponteiro N registros á frente.

Exemplo:

Tabela.Move 3

Moverá o ponteiro 3 registros á frente.

Exemplos:

Tabela.MoveNext
Tabela.MoveLast
Tabela.MovePrevious

Métodos de procura

Um Recordset oferece alguns métodos para realizarmos operações de busca através das
tabelas. Veremos agora os métodos de busca e as suas particularidades.

FindFirst- É o método de procura mais usado. Ele procura um registro com base em uma
condição, a partir do primeiro registro. Sua sintaxe é a seguinte:

Recordset.FindFirst(StringComCondição)

O argumento StringComCondição representa uma string, onde deverá ser informada a
condição. Por exemplo, se você desejar procurar um registro que contenha um campo
Nome igual á “João”, então irá usar uma string assim:”Nome = ‘Joao’”. Vejamos como
ficaria usando o método FindFirst:

Tabela.FindFirst(“Nome = ‘Joao’”)

Note que quando procuramos um campo do tipo Texto(Text), o texto a procurar deve ser
delimitados por aspas simples ‘’. Caso for um campo do tipo numérico(Integer,Long, etc...)
as aspas não são necessárias:

Tabela.FindFirst(“Código = 3”)

FindNext – O método FindNext funciona de forma semelhante ao FindFisrt. A diferença é
que enquanto o método FindFirst procura um registro a partir do primeiro, o FindNext
procura a partir do registro corrente, sendo os anteriores ignorados. A sintaxe usada é a
mesma nos dois métodos.

113

FindPrevious – A partir da atual posição do ponteiro no recordset, localiza o registro
anterior que satisfaça o critério. Segue a mesma sintaxe dos métodos anteriores.

FindLast – A partir do primeiro registro, procura pelo último registro que satisfaça o
critério estabelecido, no caso de termos mais de um registro encontrado. Segue a mesma
sintaxe dos métodos anteriores.

O método Seek

O método Seek oferece um meio de pesquisa mais rápido quando procuramos um
registro com um campo indexado. O método Seek só pode ser usado em um RecordSet do
tipo Table e é necessário que especifiquemos um índice corrente antes de fazermos a
pesquisa. Para especificar um índice corrente, usamos a propriedade Index do RecordSet.
Digamos que vamos usar o Recordset que já criamos q que se chama Tabela. Como você
lembra, quando criamos a tabela “Clientes” adicionamos um índice chamado Nome e é
este índice que iremos usar.

Tabela.Index =”Nome”

Feito isso, já poderemos usar o método Seek que tem a seguinte sintaxe:

.Seek ,,,,Etc...

- Uma string que determina os métodos de comparação pra
quando buscarmos pelo registro especificado em qualquer uma das . Os métodos
de comparação são representados pelos operadores <, <=, =, >= ou >.

,,,Etc... – Um ou mais valores que representam os campos
existentes no índice definido atrabés da propriedade Index. Podemos colocar até 13 chaves.

Exemplo:

Tabela.Index =”Nome”
Tabela.Seek “=”, “João”

Após utilizarmos um método de procura, seja ele Seek ou qualquer um dos que vimos
anteriormente, o ponteiro de moverá para o registro que satisfaça as condições
estabelecidas nas opções de critério. Caso o registro não seja encontrado, o ponteiro
continuará no registro atual.
Quando uma operação de procura não obter sucesso, a propriedade NoMatch do objeto
Recordset passar a ter o valor True. Essa propriedade é útil para sabermos se o registro
que procuramos foi encontrado.

Exemplo:

Dim Banco as Database
Dim Tabela as Recordset

114

Set Banco = Opendatabase(“C:\Trabalho\Dbcurso.mdb”)
Set Tabela = Banco.OpenRecordset(“Clientes”,Dbopentable)
Tabela.FindFirst(“Nome = ‘Maria’”)
If Tabela.Nomatch = True Then
MsgBox “Nome não foi encontrado”

Else

MsgBox “Nome foi encontrado”

Endif

Adidionando Registros

Para adicionarmos registros usamos o método AddNew de um objeto RecordSet.

.AddNew

Depois de usarmos AddNew, devemos atribuir os valores aos campos do Recordset:

() =

Feito isso, ainda precisamos usar o método Update do objeto Recordset para finalizar a
adição do novo registro. Este método trabalha em conjunto com o método AddNew.
Lembre-se de sempre usá-lo quando a adição do registro estiver OK.

.Update

Vamos ao exemplo prático para ilustrar esse processo, partindo do RecordSet que
criamos chamado Tabela
Tabela.AddNew
Tabela(“Nome”) = “Vanessa Martins Vargas”
Tabela(“Endereço”) = “João Borges Fortes, 2000”
Tabela(“DataNasc”) = # 15/09/1980 #
Tabela.Update

Na pratica, estes valores provavelmente viriam de TextBoxs. Mas no exemplo acima
adicionamos os valores diretamente aos campos da tabela para ilustrar o processo. Note que
ao nos referirmos aos campos da tabela usamos, por exemplo Tabela(“Nome”), mas
também poderíamos usar Tabela!Nome. Cabe ao aluno avaliar qual é a sintaxe mais
intuitiva.

115

Atualizando Registros

A atualização de registros é bem semelhante á adição. A diferença é que no lugar de
usarmos o método AddNew, usamos o método Edit. Retomando o exemplo anterior,
digamos que foi gravado o endereço do cliente errado. Usaríamos o seguinte código para
consertar isso:

Tabela.MoveLast ‘ Move o ponteiro para o último registro
Tabela.Edit ‘ Abre a edição do registro
Tabela(“Endereço”)=”José Joaquim Da Mota,211” ‘Atribui o novo endereço
Tabela.Update ‘Grava o novo endereço

Excluindo registros

Esta é a mais simples das operações envolvendo manipulação de registros. Para excluir
um registro, aponte para o registro que deseja excluir e use o método Delete do objeto
RecordSet. Exemplo:

Tabela.MoveLast
Tabela.Delete

Fechando um RecordSet e um Database

É muito importante se atentar para o fato de precisar fechar a conexão dos objetos com a
tabela e o banco de dados quando não estivermos mais usando os dados provenientes deles.
Pois isto evitará que o banco de dados possa estar corrompindo futuramente. Para fechar
um Database, objeto que representa o banco de dados, devemos primeiramente fechar os
RecordSets baseados nesse Database. Se tentarmos fechar o Database primeiro sem
termos fechado o(s) Recordsets bseados nele, teremos um erro em tempo de execução.
Para fechar um RecordSet ou um DataBase, usamos o método Close.

Tabela.Close
Banco.Close

O exemplo acima fecha primeiramente o RecordSet chamado Tabela e depois o
Database chamado Banco.

Conhecendo algumas propriedades úteis

Vamos conhecer agora algumas propriedades úteis do objeto RecordSet :

116

AbsolutePosition : Indica o numero do registro corrente da tabela em uso. Não podemos
consultar essa propriedade em um objeto Recordset do tipo Table. Somente SnapShot ou
Dynaset.

BOF : Retorna True quando foi feita uma tentativa de ir para um registro anterior ao
primeiro. Quando isto aontecer, om ponteiro não apontará para nenhum registro, tendo o
programador ter que fazer com que ele aponte para um registro novamente.

DateCreated : Retorna a data de criação da tabela manipulada pelo Recordset.

EOF : Retorna True quando for feita uma tentativa de ir para um registro superior ao
último.

Index : Especificamos o nome do índice que será associado a tabela.

NoMatch : Retorna True se uma pesquisa efetuada dentro da tabela foi bem-sucedida.

PercentPosition : Retorna um percentual referente a posição que a tabela se encontra com
comparação com o total de registros da tabela.

RecordCount : Retorna a quantidade de registros que uma tabela possui.

Com base nos métodos, propriedades e funções aprendidas, crie um cadastro com base na
tabela Clientes que criamos no banco de dados DbCurso. O cadastro deverá ter botões de
adicionar registros, um botão para ir para o próximo registro, anterior, primeiro e último.
Deverá ter também um botão de excluir registros e um para alterar.

Conhecendo alguns objetos de banco de dados

Iremos conhecer agora alguns objetos que facilitam a nossa vida, quando precisamos
manipular dados de um banco de dados. O primeiro dos objetos que conheceremos é um
controle:

Data – Este objeto automatiza tarefas como a do nosso exemplo anterior,
economizando código. Vejamos como usá-lo.
Crie um formulário e seleciona na caixa de ferramentas um objeto Data. Nomei-o como
Data. Agora insira 5 Labels e 5 Textboxs nesse formulário, como se fosse fazer um
cadastro para a nossa tebela de clientes, como no exemplo anterior. Deixe o formulário
semelhante ao formulário da figura abaixo:

117

Não é nexessário nomear os TextBoxs. Vamos agora configurar o objeto Data. Sem mais
rodeios, vamos diretamente á propriedade que nos interessa e ela é a DatabaseName. Nela
escolheremos o banco de dados que tém a tabela que iremos usar.

Clicando no botão ao lado <...>, uma janela se abrirá para que possamos procurar pelo
banco de dados.

Depois de selecionado o banco de dados, já podemos selecionar uma tabela, através da
propriedade RecordSource do objeto Data.

Note também que na propriedade RecordsetType, podemos escolher entre os 3 tipos de
recordsets que vimos anteriormente.

118

Bem, agora vamos conhecer o que o objeto Data tem a nos oferece. Primeiramente,
configure a opção DataSource dos TextBoxs. Note que quando adicionamos um objeto
Data ao formulário, o mesmo irá aparecer na lista da propriedade RecordSource das
TextBoxs existentes no formulário.

Selecione este objeto para todas as TextBoxs. Agora que já selecionamos o objeto Data
para a propriedade RecordSource de todos os TextBoxs, configure a propriedade DataField
das mesmas, uma por vez.
Note que se tudo estiver configurado de forma adequada, você pode escolher os campos
em uma lista na propriedade DataField de cada TextBox.

Selecione um a um, os respectivos campos para cada TextBox. Depois disso feito, rode o
projeto.

Você vai ver que podemos navegar através dos registros. Como você notou, a economia
de código foi de 100 %.
Tudo o que for digitado ou trocado nas TextBoxs vai ser alterado diretamente no banco
de dados, sem necessidade nenhuma de usar métodos Edit ou Update.
Devo dizer que é um excelente recurso para consultar dados. Na prática, naum se usa
muito esse tipo de controle. Pois na maioria dos aplicativos, temos que fazer validação do
que o usuário digita nas caixas de texto, limitar algumas delas, validar dados, etc. Além
disso, funções como excluir registros, adicionar registros, devem ser feitas manualmente.

O Controle DataGrid(DbGrid)

O controle DbGrid oferece um sofisticado meio de consultarmos dados. Para usar o
DbGrid, você deve marcá-lo na caixa de componentes. Há mais de um tipo de DataGrid, no
entanto o que vamos estudar é o “Microsoft Data Bound Grid Control 5.0(SP3)”.

119

Depois de feito isso e o controle já estar visível na caixa de ferramentas, clique nele e o
arraste-o para o mesmo formulário onde criamos o nosso cadastro de clientes.

Vá na propriedade DataSource da DataGrid. Você verá que aparecerá o nosso objeto Data
na lista. Selecione-o. De fato, para usarmos o objeto DataGrid, temos que ter um objeto
Data já configurado, no mesmo formulário.

Feito isso, já preenchemos o DataGrid com os dados existentes no objeto Data. Rode o
projeto e confira o resultado.

120

Note que ao mudarmos de registro no DataGrid, o registro também troca no objeto Data

e vice-versa.

O Datagrid funciona de forma bem semelehante ao objeto Data. Quando alteramos um
campo via DataGrid, estamos alterando diretamente no banco de dados, sem necessidade de
algum comando adicional. No entanto existem propriedades que nos permitem bloquear
esse tipo de alteração direta. Vejamos algumas propriedades do DataGrid:

AllowAddNew: Habilita a possibilidade de se poder acrescentar registros na tabela.
Quando esta propriedade está habilitada. O DataGrid oferece um registro em branco no
final para que possamos inserir um novo registro.
AllowDelete : Habilita a possibilidade de apagar registros. Quando habilitamos essa
propriedade, podemos excluir registros selecionando toda uma linha e pressionando a tecla

.
AllowUpdate
: Habilita a possibilidade de alterar os registros existentes diretamente.
ColumnHeaders : Determina se o cabeçalho de cada coluna será exibido.
RecordSelectors : Determina se no DBGrid irá aparecer um seletor de registros
AllowRowSizing : Habilita a possibilidade do usuário mudar o tamanho das colunas.
Enabled : Habilita ou não a interação do DBGrid com o usuário.
Columns : Seleciona em qual coluna de dados do DBGrid que terá as propriedades abaixo
disponível para serem configuradas.
Caption : Título da Coluna selecionada.
DataField : Campo da tabela que terá seus dados exibidos na coluna selecionada.
DefaultValue : Valor padrão para um determinado campo.
NumberFormat : Determina o formato com que os dados da coluna serão mostrados no
vídeo. Usa as mesmas regras da função FORMAT.
Locked : Trava os dados contido nas colunas.
AllowSizing : Habilitada a possibilidade de mudar o tamanho da coluna
Visible : Indica se a coluna será visível ou não.

121

Alignment : Alinha dos dados na coluna na forma determinada nesta propriedade.

Impressão

Atualmente existem várias ferramentas para facilitar a impressão de relatórios.

Estudaremos 2 delas:

O objeto Printer, que é um objeto nativo do Visual Basic, e a ferramenta Crystal
Reports,
que é um programa separado, mas que gera relatórios que podem ser acessados
através do Visual Basic. A versão do Crystal Reports que estudaremos é o “Crystal
Reports Report Design Component”, que permite projetarmos relatórios dentro do nosso
próprio projeto do Visual Basic.

O objeto Printer

O objeto Printer nos permite obter um total controle sobre as tarefas de impressão. Tem
propriedades que nos possibilitam alterar a fonte do que será impresso, alterar a impressora
padrão, alternar para fonte em negrito, etc. Tem métodos que nos possibilitam saltar para a
próxima página, terminar a impressão, imprimir na linha x, coluna x,etc. Veremos agora as
principais propriedades do Printer:
ColorMode
: Determina ou mostra a capacidade de impressão colorida do dispositivo.
Copies: Especifica a quantidade de cópias de uma página que deve ser impressa.
CurrentX: Determina a coordenada horizontal que a impressora irá imprimir.
CurrentY: Determina a coordenada vertical que a impressora irá imprimir.
DeviceName: Mostra o nome da impressora padrão suportada pelo dispositivo
FontName: Determina qual fonte de letra a impressora usará para impressão.
FontBold: Determina se a fonte será em negrito.
FontItalic: Determina se a fonte será em itálico.
Fonts: Fornece uma lista de todas as fontes disponíveis para impressão.
FontSize: Determina o tamanho que a fonte de letra escolhida usará.
FontUnderline: Determina se a fonte será sublinhada.
Orientation: Determina a orientação do papel: Retrato ou Paisagem. Usamos as constantes
para definir o tipo escolhido:
vbPRORPortrait

1

Retrato

vbPRORLandscape2

Paisagem
Page : Retorna o número da página que esta sendo impressa.
PaperSize: Determinamos o tamanho do papel. Podemos usamos as seguintes constantes:
vbPRPSLetter

1

Letter, 8 1/2 x 11 in.

VbPRPSLetterSmall

2

Letter Small, 8 1/2 x 11 in.

VbPRPSTabloid

3

Tabloid, 11 x 17 in.

VbPRPSLedger

4

Ledger, 17 x 11 in.

VbPRPSLegal

5

Legal, 8 1/2 x 14 in.

VbPRPSStatement

6

Statement, 5 1/2 x 8 1/2 in.

VbPRPSExecutive

7

Executive, 7 1/2 x 10 1/2 in.

122

vbPRPSA3

8

A3, 297 x 420 mm

vbPRPSA4

9

A4, 210 x 297 mm

vbPRPSA4Small

10

A4 Small, 210 x 297 mm

vbPRPSA5

11

A5, 148 x 210 mm

vbPRPSB4

12

B4, 250 x 354 mm

vbPRPSB5

13

B5, 182 x 257 mm

vbPRPSFolio

14

Folio, 8 1/2 x 13 in.

VbPRPSQuarto

15

Quarto, 215 x 275 mm

vbPRPS10x14

16

10 x 14 in.

vbPRPS11x17

17

11 x 17 in.

VbPRPSNote

18

Note, 8 1/2 x 11 in.

vbPRPSEnv9

19

Envelope #9, 3 7/8 x 8 7/8 in.

vbPRPSEnv10

20

Envelope #10, 4 1/8 x 9 1/2 in.

vbPRPSEnv11

21

Envelope #11, 4 1/2 x 10 3/8 in.

vbPRPSEnv12

22

Envelope #12, 4 1/2 x 11 in.

vbPRPSEnv14

23

Envelope #14, 5 x 11 1/2 in.

VbPRPSCSheet

24

C size sheet

vbPRPSDSheet

25

D size sheet

vbPRPSESheet

26

E size sheet

vbPRPSEnvDL

27

Envelope DL, 110 x 220 mm

vbPRPSEnvC3

29

Envelope C3, 324 x 458 mm

vbPRPSEnvC4

30

Envelope C4, 229 x 324 mm

vbPRPSEnvC5

28

Envelope C5, 162 x 229 mm

vbPRPSEnvC6

31

Envelope C6, 114 x 162 mm

vbPRPSEnvC65

32

Envelope C65, 114 x 229 mm

vbPRPSEnvB4

33

Envelope B4, 250 x 353 mm

vbPRPSEnvB5

34

Envelope B5, 176 x 250 mm

vbPRPSEnvB6

35

Envelope B6, 176 x 125 mm

vbPRPSEnvItaly

36

Envelope, 110 x 230 mm

vbPRPSEnvMonarch

37

Envelope Monarch, 3 7/8 x 7 1/2 in.

vbPRPSEnvPersonal

38

Envelope, 3 5/8 x 6 1/2 in.

vbPRPSFanfoldUS

39

U.S. Standard Fanfold, 14 7/8 x 11 in.

vbPRPSFanfoldStdGerma
n

40

German Standard Fanfold, 8 1/2 x 12
in.

vbPRPSFanfoldLglGerma
n

41

German Legal Fanfold, 8 1/2 x 13 in.

vbPRPSUser

256User-defined

Port: Retorna o nome da porta de impressão que será usada pela impressora padrão.
PrintQuality: Determina ou seta a resolução que a impressora irá usar.
VbPRPQDraft

-1

Resolução Draft

vbPRPQLow

-2

Baixa Resolução

vbPRPQMediu
m

-3

Média Resolução

vbPRPQHigh

-4

Alta Resolução

123

Vejamos agora, os principais métodos:

EndDoc: Finaliza a impressão de um relatório
KillDoc: Termina imediatamente a impressão
Line: Imprime uma linha horizontal, de acordo com as coordenadas especificadas.
NewPage: Força a impressão passar para a próxima página.
Print : Imprime uma expressão ou variável especificada.

Quando usamos o objeto Printer, será de extrema necessidade o uso de uma função
auxiliar que só pode ser usado com o método Print ou com a instrução Print #. Esta função
é a função Tab e é usada para posicinar a saída. Imagine que estamos imprimindo alguma
coisa com o método Print. Queremos imprimir o título do relatório bem no centro da folha.
Se usássemos o método Print assim:

Printer.Print “Título do Relatório”

O título sairia no início da folha, agora usando a função Tab associada com o método
Print, podemos definir em qual coluna irá começar a impressão feita pelo método Print.

Printer.Print Tab(35); “Título do Relatório”

Deverá existir um ; (ponto e vírgula) entre a função Tab e o que queremos imprimir.
Mas se você não digitar não tem problema, pois o editor do Visual Basic se encarrega de
corrigir esse erro de sintaxe.
Vejamos agora, um exemplo de como poderia ser feito um relatório dos clientes na tabela

que criamos.

Primeiramente, abre o último projeto que criamos. No formulário que criamos, adicione
um botão de Imprimir e nomei-o como “CmdImprimir”.

124

No evento Load do botão, adicione o seguinte código:

Dim Banco As Database
Dim Tabela As Recordset
Dim Linha As Integer

Set Banco = OpenDatabase("C:\trabalho\dbcurso.mdb")
Set Tabela = Banco.OpenRecordset("Clientes", dbOpenTable)

Linha = 1

Do While Not Tabela.EOF
If Linha = 1 Then
Cabecalho

End If
Linha = Linha + 1
Printer.Print Tab(5); Tabela!codigo;
Printer.Print Tab(15); Tabela!nome;
Printer.Print Tab(45); Tabela!endereco;
Printer.Print Tab(65); Tabela!datanasc;
Printer.Print Tab(93); Tabela!rg;
Printer.Print
If Linha = 50 Then
Printer.NewPage
Linha = 1

End If
Tabela.MoveNext

Loop

125

Printer.EndDoc

Agora, crie um subprocedimento denominado Cabeçalho, que terá a funçãop de
imprimir o cabeçalho do relatório toda vez que uma nova página começar a ser impressa.
Neste subprocedimento, insira o seguinte código:

Printer.Font = "Arial"
Printer.FontBold = True
Printer.FontSize = 11

Printer.Print Tab(35); "Relatório de Clientes"
Printer.Print
Printer.Print Tab(5); "Código";
Printer.Print Tab(15); "Nome";
Printer.Print Tab(40); "Endereço";
Printer.Print Tab(60); "Data de Nascimento";
Printer.Print Tab(85); "RG";
Printer.FontBold = False

Bem, vamos começar pelo evento Load do botão CmdImprimir.Primeiramente,
declaramos as variáveris:

Dim Banco As Database
Dim Tabela As Recordset
Dim Linha As Integer

Uma para o banco de dados, outra para a tabela, e outra é referente a um contador de
linhas que criamos para limitarmos o número de linhas impressas por página em 50, quando
exceder, o programa irá passar para uma nova página.
Depois disto, instanciamos as variáveis do banco de dados e da tabela:

Set Banco = OpenDatabase("C:\trabalho\dbcurso.mdb")
Set Tabela = Banco.OpenRecordset("Clientes", dbOpenTable)

E dizemos que a linha inicial será a 1, atribuindo o valor 1 a variável Linha.

Linha = 1

Feito isso, iniciará um ciclio, a qual imprimirá um registro da tabela por vez, enquando a
tabela não chegar no final. Assim que tentarmos nos mover para um registro maior que o
último, o ciclio é interrompido e a impressão encerrará:

Do While Not Tabela.EOF

126

Na linha seguinte, verificamos se a variável Linha tem o valor 1, o que quer dizer que
estamos começando uma nova página, se tiver ela irá chamar o subprocedimento
Cabeçalho:

If Linha = 1 Then
Cabecalho

End If

Vejamos agora o código existente no subprocedimento chamado Cabeçalho.

Printer.Font = "Arial"
Printer.FontBold = True
Printer.FontSize = 11

Printer.Print Tab(35); "Relatório de Clientes"
Printer.Print
Printer.Print Tab(5); "Código";
Printer.Print Tab(15); "Nome";
Printer.Print Tab(40); "Endereço";
Printer.Print Tab(60); "Data de Nascimento";
Printer.Print Tab(85); "RG";
Printer.FontBold = False

As 3 primeiras linhas se referem ao tipo, estilo e tamanho da fonte, Font, FontBold e
FontSize; que se referem nessa ordem á Nome da Fonte, Fonte em negrito e tamanho da
fonte. Sendo assim, escolhemos para o cabeçalho a fonte “Arial”, que será em negrito, já
que estamos escolhendo a propriedade FontBold como True. O tamanho da fonte será
igual a 11, já que definimos a propriedade FontSize com 11.
As próximas linhas se referem a impressão do cabeçalho em si, onde usamos a função
auxiliar Tab para posicionar a impressão na coluna desejada.
Uma observação que tenho que fazer aqui é quanto á linha que tem um Print.Print sem
nada á imprimir. Isto seria um modo de deixar uma linha em branco após o título do
relatório. Outra é o ;(Ponto e Vírgula) no final de todas as linhas de impressão. Colocando
esse ; (Ponto e Vírgula) fazemos com que a impressão continue na mesma linha. Ou seja, a
próxima instrução Print que usarmos após o ; (Ponto e Vírgula) será impressa na mesma
linha. A impressão só passará para a linha seguinte, quando usarmos o método Print sem o
; (Ponto e Vírgula).

Terminamos o subprocedimento do cabeçalho, fazendo com que a fonte passe do negrito
para o normal, já que terminamos a impressão do relatório e precisamos que os registros
não sejam impressos em negrito:

Printer.FontBold = False

Retornando so evento Load do botão CmdImprimir, temos o restante do código:

Linha = Linha + 1
Printer.Print Tab(5); Tabela!codigo;

127

Printer.Print Tab(15); Tabela!nome;
Printer.Print Tab(45); Tabela!endereco;
Printer.Print Tab(65); Tabela!datanasc;
Printer.Print Tab(93); Tabela!rg;
Printer.Print
If Linha = 50 Then
Printer.NewPage
Linha = 1

End If
Tabela.MoveNext

Incrementamos a variável Linha em 1, já que á cada ciclo será impressa uma linha:

Linha = Linha + 1

As próximas linhas se referm á impressão da linha(registro) em si:

Printer.Print Tab(5); Tabela!codigo;
Printer.Print Tab(15); Tabela!nome;
Printer.Print Tab(45); Tabela!endereco;
Printer.Print Tab(65); Tabela!datanasc;
Printer.Print Tab(93); Tabela!rg;
Printer.Print

Depois delas, temos a seguinte verificação:

If Linha = 50 Then
Printer.NewPage
Linha = 1

End If

Se a linha for igual á 50, então usamos o método NewPage para passarmos para uma
nova página, e conseqüentemente, deveremos atribuir o Valor 1 a variável Linha. Pois
começaremos novamente a contar as linhas a partir de 1.
Depois de impresso o registro, passaremos para o próximo registro na tabela:

Tabela.MoveNext

O próximo comando é o Loop e encerra o ciclo Do While:

Loop

Após encerrado o ciclo, e todos os registros serem impressos, precisamos dizer a
impressora que a impressão encerrou. Para isso, usamos o método EndDoc.

Printer.EndDoc

128

É necessário usar esse método para encerrar a impressão, pois se não usássemos o
programa ficaria se comunicando com o Spool da impressora e os dados só seriam
impressos quando o programa fosse encerrado.

Criando relatórios com o Crystal Reports

A ferramenta Crystal Reports, da Seagate, é sem dúvida a ferramenta preferida pelos
desenvolvedores da atualidade para desenvolver relatórios. Isso por quê ele automatiza
várias tarefas que o programador teria de fazer manualmente, caso fosse usar o Printer.
Você pode selecionar um banco de dados de forma interativa e escolher quais campos
devem aparecer no relatório, que ele monta automaticamente o relatório pra você.
Possui ainda um assistente que faz todo o trabalho “pesado” pra você. Você terá apenas
que arrumar alguns detalhes, se necessário, no relatório.

Criando um relatório no Crystal Reports usando o assistente

Existem várias versões do Crystal Reports espalhadas por aí. A versão que iremos usar é o
“Crystal Reports Report Design Component” .
Em outras versões do “Crystal Reports”, ele funciona como um programa separado onde
criamos os relatórios dentro dele mesmo. Esses relatórios, contituem um arquivo separado,
que terá de ser chamado pelo Visual Basic.
Com o “Crystal Reports Report Design Component” , você cria os relatórios dentro do
próprio Visual Basic, e não há necessidade nenhuma de ter um arquivo separado para cada
relatório. Esta é, na minha opinião, a granda vantagem de usar essa versão.
Bem, deixando de rodeios e indo ao que interessa, o que primeiramente precisamos para
criar um relatório usando o Crystal é ter ele instalado. Feito isso, ele já irá aparecer nos
menus do Visual Basic.
Para não termos problemas com o uso do assistente, devemos adicionar um componente
ao projeto. Vá no menu Project, selecione Components e marque o controle “Crystal
Report View Control”. Este controle é requerido pelo assistente quando ele cria o relatório e
se você não adicioná-lo terá problemas sérios ao encerrar o assistente. Esses “problemas
sérios” incluem o Visual Basic fechar e você perder tudo o que não foi salvo. Portanto, não
esqueça de marcar tal componente.

129

Para adicionarmos um novo relatório usando o Crystal Reports, acessamos o menu
Project e escolhemos a opção Add Crystal Reports 8.5.
Abrirá então uma janela perguntando se queremos criar o novo relatório usando o
assintente, se queremos criar um relatório vazio ou criar um relatório a partie de outro
existente.

Além disso, existe uma lista abaixo com vários tipos de relatórios predefinidos para que

possamos escolher.

Como vamos criar nosso relatório usando o assistente, marque a primeira opção e clique

em OK.

Feito isso, o assistente iniciará o processo:

Criar um novo relatório usando o assistente

Criar um novo relatório em branco

Criar um novo relatório a partir de um
relatório já existente

Aqui temos uma lista de tipos de relatórios
predefinidos

Aqui é exibido o LayOut do relatório
predefinido escolhido na lista.

130

Primeiramente, deveremos selecionar um banco de dados, de onde virão os dados do
relatório. Para fazer isso, clicamos no botão Project. Após clicarmos nesse botão, irá abrir
uma janela com várias opções para nos conectarmos com diferentes bancos de dados.

Como estamos utilizando conexão com banco de dados via DAO, marque a opção DAO
e clique no botão Browse para selecionar um banco de dados ou digite o caminho do banco
de dados na caixa de texto.

131

Note ainda que existe uma caixa abaixo, onde podemos selecionar para abrir vários tipos de
banco de dados diferentes. Como o banco de dados que iremos abrir é Access, então não
precisamos alterar.

132

Estando o nome do banco de dados e o tipo selecionado, podemos clicar no botão OK
para proseguirmos. Feito isso, abrirá uma janela onde podemos selecionar o objeto do
banco de dados que desejamos, no nosso caso, a tabela “Clientes”.
Atenção: Neste exemplo selecionamos a tabela “Clientes”. No entanto, podemos
selecionar mais de uma tabela sem problemas. O ato de adicionar mais de uma tabela ao
relatório não obriga o relatório a ser baseado em todas as tabelas. Mas por sua vez, mantém
essas tabelas disponíveis para usarmos no relatório.

Estando esta tabela selecionada, já podemos clicar no botão OK. O assistente retornará
novamente para a primeira tela.
Para proseguir, clicamos no botão Next.

133

O assistente então passará para o guia Fields, onde definimos quais campos aparecerão

no relatório:

Nesta lista estão
todos os campos que
podemos adicionar ao
relatório. Para
adicionar um campo,
basta selecioná-lo
nesta lista e clicar no
botão Add ->

O botão Add All->
coloca todos os
campos no relatório
sem a necessidade de
termos que inserir um
por um.

É nessa lista que
ficam os campos que
escolhemos para
exibir no relatório

O botão Remove <-
remove o campo
selecionado na lista de
campos a exibir no
rerlatório

O botão <- Remove All
remove todos os campos
da lista de campos a
exibir no relatório.

Nesta caixa, podemos
selecionar
individualmente o
cabeçalho que será
exibido para cada
campo.134

Depois de adicionados os campos necessários para o nosso relatório e caso ele seja um
relatório simples, já podemos finalizar, clicando no botão Finish. Veremos mais tarde ao
que se destinam os próximos passos do assintente.
Se você já adicionou os campos que precisa no relatório e não usará nenhum recurso
especial no seu relatório, deverá clicar no botão Finish. Feito isso, aparecerá a seguinte
janela:

Depois que você selecionar as opções que você deseja, clique em OK.

Aqui ele pergunta se
queremos que o assistente
crie um formuilário que
servirá como visualização de
impressão. Caso você queira
visualizar o relatório antes de
imprimir, marque a opção

Yes.

Aqui ele pergunta se você
que o assistente modifique as
propriedades de projeto para
que o formulário de
visualização de impressão
seja o objeto inicial do
projeto(StartUp Object).
Caso você queira, marque
Yes. Geralmente usamos No.

135

Veja que o assistente criou um Relatório(Report) com o nome “CrystalReports1”.
Nomeio-o como “RptClientes”. Caso já tivéssemos um relatório com o nome de
“CrystalReports1”, ele nomearia como “CrystalReports2”, e assim sucessivamente.
Note também que ele criou um formulário como o nome “Form1”. Se já tivéssemos um
formulário com esse nome, ele criaria um com o nome de “Form2” e assim sucessivamente.
Nome-o para “FrmRelCli”. Veja que esse formulário funciona como visualização dos
relatórios. Assim, quando precisarmos imprimir um relatório criado a partir do Crystal,
basta chamar o formulário que o assistente criou para esse relatório através do método
Show. O formulário fará toda a parte de imprimir o relatório para nós.
A janela abaixo mostra uma pré-visualização que foi criada pelo assistente do “Crystal”
em um formulário. Ela oferece recursos de Zoom, mudança de página, pesquisa e ainda
oferece recursos para alternarmos entre os grupos, caso estejamos trabalhando com
relatórios que contenham grupos.

Depois de renomear o nome do relatório e o do formulário que o assistente criou, você
também deve renomear o nome no código do formulário que o assistente criou. Nesse
código ele faz referência ao relatório que o assistente criou. Como modificamos o nome
desse relatório, também temos de fazer o mesmo no código. A única linha que teremos de

Aqui a declaração está apontando
para o objeto CrystalReports1, que
foi criado pelo assistente. Como
modificamos o nome, faça com que
ela aponte para o novo objeto, no
nosso caso, RptCli.(Dim Report as
RptCli).

136

alterar é na declaração, onde é declarado um objeto do tipo Report(relatório). Altere o nome
para o novo nome que você atribuiu ao relatório.

Essa é única linha que teremos de alterar nesse código para que ele funcione
perfeitamente. Essa mudança só é necessária por que alteramos o nome do objeto Report.
Feito essa modificação, talvez você queira fazer alguns ajustes no Layout do relatório.
Um relatório é dividido em várias seções. Veremos agora a função de cada uma delas.

A seção Report Header é o cabeçalho do relatório. Não confunda cabeçalho do relatório
com cabeçalho da página. Pois o cabeçalho da página é impresso sempre antes de uma

137

página ser impressa. Já o cabeçalho do relatório será impresso somente uma vez, antes de
qualquer página ser impressa.

A seção Page Header é o cabeçalho de página e como já falamos anteriormente é impressa
sempre que é iniciada uma nova página. Usamos esta seção para colocar os cabeçalhos para
os campos, além de outras informações.

A seção Details(detalhe) é a mais importante do relatório. É nela que irão os dados que
compõem o relatório. Como por exemplo, os campos nome, endereço, etc.

A seção Report Footer é o rodapé do relatório. Ou seja, é o que será impresso, no final do
relatório, após todas as páginas serem impressas.

A seção Page Footer é o rodapé da pagina. É o que será impresso no fim de cada página.
Usamos esta seção para imprimir, por exemplo, os números de página. Ao criar um
relatório pelo assistente, o Crystal automaticamente insere uma função, para retornar o
número de página nesta seção.

Na caixa de ferramentas a esquerda podemos ver os controles disponíveis para inserir
nos relatórios criados pelo Crystal

Os controles mais importantes são:

Text Objext – Um simples objeto de texto que tem a mesma função do objeto Label

nos formulários.

Line Object – Serve para traçarmos uma linha reta no relatório.

Além desses recursos, o Crystal ainda nos oferece recursos de poder inserir campos
especiais, como hora, data, etc. Vejamos alguns:

138

Trabalhando com filtros no Crystal Reports

É comum as vezes o programador se deparar com um relatório em que a aplicação de um
filtro é necessária. Com o objeto Printer, temos a liberdade de imprimir somente os dados
que nos interessam. Digamos que você precise imprimir um relatório com nomes, em que a
impressão do registro se baseará em um nome que será digitado em um TextBox. Serão
aceitos nomes que iniciem com a string digitada na Textbox. Por exemplo, se você digitar a
string “JO” na TextBox, poderão ser impressos no relatório nomes como “JOAO”, “JOSÉ”,
“JOVANA” e todos outros nomes que comecem com “JO”. Crie um formulário com a
aparência da figura abaixo:

Nomeie a TextBox com o nome de “TxtFiltro”, o botão de impressão com o nome de
“CmdImprimir”. Crie um subprocedimento denominado Cabeçalho e insira o seguinte
código:

Printer.Font = "Arial"
Printer.FontBold = True
Printer.FontSize = 11

Printer.Print Tab(35); "Relatório de Clientes"
Printer.Print
Printer.Print Tab(5); "Código";
Printer.Print Tab(15); "Nome";
Printer.Print Tab(40); "Endereço";
Printer.Print Tab(60); "Data de Nascimento";
Printer.Print Tab(85); "RG";
Printer.FontBold = False

Exibe a data
Exibe a hora
Exibe a data de modificação

Exibe o número de registro
Exibe o número da página

Exibe a hora da modificação

Exibe o numero total de páginas

139

No evento Load do botão “CmdImprimir”, insira o seguinte código:

Dim Banco As Database
Dim Tabela As Recordset
Dim Linha As Integer

Set Banco = OpenDatabase("C:\trabalho\dbcurso.mdb")
Set Tabela = Banco.OpenRecordset("Clientes", dbOpenTable)

Linha = 1

Do While Not Tabela.EOF
If Mid(Tabela!nome, 1, Len(TxtFiltro.Text)) = TxtFiltro.Text Then

If Linha = 1 Then
cabecalho

End If
Linha = Linha + 1
Printer.Print Tab(5); Tabela!codigo;
Printer.Print Tab(15); Tabela!nome;
Printer.Print Tab(45); Tabela!endereco;
Printer.Print Tab(65); Tabela!datanasc;
Printer.Print Tab(93); Tabela!rg;
Printer.Print
If Linha = 50 Then
Printer.NewPage
Linha = 1

End If
End If
Tabela.MoveNext

Loop

Printer.EndDoc

O código acima oferece um modo para filtrarmos alguma string com base no que for
digitado na TextBox.. Antes de o registro ser impresso, verificamos se a string inicial do
campo Nome do registro atual bate com o que foi digitado na Textbox.

If Mid(Tabela!nome, 1, Len(TxtFiltro.Text)) = TxtFiltro.Text Then

Através da função Mid, que retorna uma substring de uma string, pegamos uma substring
inicial do campo Nome, com o tamanho da string que foi digitada em TxtFiltro. Se a
condição for verdadeira, tudo o que estiver no bloco If será executado e o registro será
impresso. Caso contrário, o programa passará ao próximo registro através do método

140

MoveNext do objeto Recordset “Tabela”. Depois disso, é encontrado o comando Loop e o
ciclo é reiniciado, passando o próximo registro agora pela verificação. Desta forma, só os
registros que coincidirem serão impressos. Rode o projeto e veja o resultado.
Como você pode confirmar, com o objeto Printer podemos controlar registro á registro o
que está sendo impresso. A questão então é: Como podemos criar relatórios com filtros no
Cystal?

Bem, na verdade existem muitas maneiras de se fazer isso. Algumas delas são até mesmo

bem complexas.

Ao definir uma tabela para um relatório, quando você o cria, seja pelo assistente ou outro
método, o relatório terá os dados da tabela naquele exato momento. Portanto, modificações
feitas na tabela após termos definido os dados no relatório, não serão refletidas no relatório.
Muitas pessoas usam uma tabela temporária (embora muita gente não aconselhe) para
filtrar somente os dados que se deseja em uma tabela (tabela temporária) e atribuem essa
tabela ao relatório. Alguns problemas com que você vai se deparar, são:

- A tabela deve ser atribuída dinamicamente, ou seja, em tempo de execução.
- Uma vez atribuído a tabela ao relatório, ela deverá ser atribuída novamente cada vez
que o filtro for modificado. Caso contrário, ficará com os dados existentes da primeira vez
que você atribuiu a tabela ao relatório.
3º - O uso de um relatório com uma tabela temporária pode tornar-se lento em relatórios
com muitos registros.

O uso de tabelas temporárias não é aconselhado por oferecer um desempenho baixo
(baixa velocidade) em impressão de relatórios com muitos registros. No entanto, talvez
você se depare com alguma situação em que você não vê outra saída. Por exemplo. Você
quer criar uma planilha sobre o controle de vendas mensal, no Crystal. Uma solução seria
criar uma tabela exatamente como seria a planilha com os dados que você que e jogar essa
tabela para o Crystal. Vejamos como poderíamos fazer isso. Primeiramente, crie a tabela
temporária que você irá usar para imprimir os dados da planilha. Depois, utilize o assistente
do Crystal para adicionar essa tabela ao relatório. Supondo que você criou uma tabela com
o nome TabTemp, e criou um relatório com o nome RptPlan, poderiámos usar o seguinte
código:

Dim Banco as Database
Dim Tabela as RecordSet

Set Banco = OpenDatabase(“C:\Trabalho\Dbcurso.mdb”)
Set Tabela = Banco.OpenRecordset(“TabTemp”,Dbopentable)

<

Aqui poderiam ser utilizados comandos
para efetuar o filtro na tabela. Mas isto
é você quem vai avaliar, e através do método
Delete do objeto RecordSet, deletar os registros
que não devem aparecer no relatório.

141

>

RptPlan.Database.SetDataSource Tabela
RptPlan.PrintOut

Esse código tem dois métodos do objeto Crystal Report que ainda não conhecemos. Um
deles é o método SetDataSource do objeto Database, que é membro do objeto Crystal
Report
, ou seja, do relatório que criamos .
O objeto SetDataSource tem a função de atribuir uma origem de dados ao Crystal
Reports.
Uma origem de dados pode ser uma tabela ou uma instrução SQL. Podemos, por
exemplo, criar um objeto RecordSet, instanciá-lo e atribuir ao relatório. Foi o que fizemos
no exemplo acima. Criamos um objeto Recordset chamado Tabela, instanciamos esse
objeto com a tabela que queremos usar no relatório. Como essa tabela é temporária,
efetuamos as possíveis operações de exclusão para deixar na tabela somente os dados que
nos interessam. Após isso, utilizamos o método SetDataSource, que, como você pode ver,
oferece uma sintaxe muito simples:

RptPlan.Database.SetDataSource Tabela

No nosso caso, Tabela é o objeto RecordSet que representa a tabela “TabTemp”.

Depois disso, entra outro método que ainda não conhecemos, mas que também é muito
simples. É o método PrintOut do objeto Crystal Report. Este método envia diretamente o
relatório para a impressora.
Uma observação a ser feita e um problema bem comum é a de que quando você *chama
um relatório , fica armazenado nele o que foi impresso pela primeira vez. Então se você
voltar a imprimir esse relatório sem decarregá-lo da memória, e aplicar outro filtro, vai ver
que os dados impressos são iguais ao que você imprimiu na primeira vez.
Claro que se você aplicar o filtro, chamar o relatório, imprimir, fechar a aplicação e
voltar a imprimir o relatório, tudo funcionará perfeitamente. Mas, imagine que você tem um
formulário com um TextBox de filtro e um botão de impressão. Então você cria uma rotina
para visualizar a impressão. Provavelmente, você irá dar ao usuário a alternativa de digitar
um filtro e clicar no botão de impressão para ver o resultado, para depois imprimir. Então o
usuário poderia testar várias vezes o filtro selecionado que ele quer. O que acontece aqui é
que assim que ele atribuir uma origem de dados ao relatório pela primeira vez, os dados do
primeiro filtro que ele atribuir ao relatório, serão sempre os exibidos quando ele for acessar
o relatório novamente. Para contornar esse problema, devemos sempre descarregar o
relatório da memória, através do comando Unload, depois que ele foi usado. Exemplo:

Unload RptCli

Isso descarrega imediatamente o relatório da memória. Atenção: Você deve apenas
decarregar o relatório da memória, após o termino de seu uso. Se o relatório estiver sendo
exibido ou um objeto CRViewer, que é o objeto que o assistente cria para podermos

142

visualizar os dados antes de imprimir, estiver exibindo dados do relatório e você
descarregar o relatório da memória, não haverá visualização dos dados. Uma dica: No
formulário de visualização (aquele que o assistente cria pra você e que possibilita visualizar
os dados), descarregue o relatório da memória no evento Unload. Exemplo:

Private Sub Form_Unload(Cancel As Integer)
Unload RptCli
End Sub

*chamar um relatório – O ato de chamar um relatório não está necessariamente ligado ao
comando Load. Podemos também chamar um relatório através do comando Load, mas o
que acontece na verdade é que todos os objetos do projeto são automaticamente carregados,
quando o programa é iniciado. Assim, todo objeto fica na memória para um acesso mais
rápido quando precisarmos desse objeto. No caso do relatório, temos a necessidade de
descarregá-lo da memória para que os dados impressos da última vez sejam substituídos
pelos novos. No entanto, ele é automaticamente carregado quando fizermos qualquer
referência a ele, usando um método ou propriedade.
Continuando, veremos como criar um relatório com filtro sem precisar utilizar uma
tabela temporária. O que se torna mais simples, rápido e organizado. Primeiramente, crie
um novo projeto e adicione um formulário como o que já criamos anteriormente com a
aparência semelhante ao da figura abaixo.

Nomeie a TextBox com o nome de “TxtFiltro”, o botão de impressão com o nome de

“CmdImprimir”.

Depois, adicione o relatório “RptCli”, já criado anteriormente, ao projeto. Feito isso,
codifique o evento Load do botão CmdImprimir da seguinte maneira:

Dim Banco as Database
Dim Tabela as RecordSet

Set Banco = OpenDatabase(“C:\Trabalho\Dbcurso.mdb”)

If TxtFiltro.Text<>”” then
Set Tabela = Banco.OpenRecordset(“Select * from Clientes Where Nome Like ‘ “
& TxtFiltro.Text & “*’” )
Else

Set Tabela = Banco.OpenRecordset(“Clientes”)

End if

RptPlan.Database.SetDataSource Tabela
RptPlan.PrintOut

143

Primeiro, declaramos 2 variáveis. Um objeto Database e outro RecordSet.

Dim Banco as Database
Dim Tabela as RecordSet

Abrimos o banco de dados:

Set Banco = OpenDatabase(“C:\Trabalho\Dbcurso.mdb”)

Depois disso, verificamos de a TextBox “TxtFiltro” não está vazia:

If TxtFiltro.Text<>”” then

Se ela não estiver vazia, abrimos a tabela usando uma instrução SQL(Explicarei logo
após) que abre a tabela já com o filtro aplicado. Este filtro é feito com base nos primeiros
caracteres digitados em “TxtFiltro”:

Set Tabela = Banco.OpenRecordset(“Select * from Clientes Where Nome Like ‘ “
& TxtFiltro.Text & “*’” )

Caso contrário:

Else

Set Tabela = Banco.OpenRecordset(“Clientes”)

Abrirá a tabela normalmente, sem nenhum filtro a aplicar, o que quer dizer que se não
difitarmos nada na TextBox, todos os registros serão exibidos no relatório.
Feito essa verificação, o bloco If é encerrado:

End if

Depois disso, atribuímos a tabela com ou sem o filtro ao nosso relatório e jogamos tudo

para a impressora:

RptPlan.Database.SetDataSource Tabela
RptPlan.PrintOut

Como você pode ver é um código bem simples e a única parte do código desconhecida
pelo aluno é o uso de uma instrução SQL para abrir e filtrar a tabela. Não é propósito do
nosso curso abordar sobre instruções SQL, no entanto, irei abordar ela sobre a questão de
filtros, sendo que é um recurso que não é complexo, mas ao mesmo tempo é um recurso
muito poderoso.

Utilizando instruções SQL para aplicar filtros

144

Para entender como funciona uma instrução SQL, primeiramente olhe para a linha a

seguir:

Select * From Clientes Where Nome = ‘joao’

Veremos o que querem dizer cada uma dessas palavras:

Select – Quer dizer que estamos selecionando campos de uma tabela. O * existente depois
da palavra Select quer dizer que todos os campos foram selecionados. Poderíamos escolher
somente Nome e Código, caso quiséssemos. Neste caso, o farámos demilitando os campos
por vírgula. Exemplo:

Select Código, Nome From Clientes

No nosso curso utilizaremos apenas o *.

From – Especifica a origem de dados. O que virá após From é o nome da tabela de onde
virão os dados.

Where – Esta cláusula é o motivo pela qual fizemos esse superficial estudo sobre
instruções SQL . A cláusula Where nos permite aplicar um filtro à tabela com base no
critério especificado. O que irá após á cláusula Where é o critério de filtro. Olhamos
novamente para esta linha:

Select * From Clientes Where Nome = ‘joao’

O que podemos concluir é que:
Selecionamos todos os campos da tabela “Clientes” e filtramos a tabela, de forma que só o
registro com nome = ’joao’ será exibido.
Quando estamos especificando critérios para um campo do tipo String, o valor deve estar
entre ‘’(aspas simples). No caso de um valor numérico, não são necessárias as
aspas.Exemplo:

Select * From Clientes Where Código = 2

Um recurso muito útil que a linguagem SQL nos oferece é a possibilidade de procurar
registros pelos seus caracteres iniciais ou finais, ou, até mesmo, por uma Substring dentro
de uma string. Esse recurso é muito simples de usar. Utilizando o operador LIKE no lugar
do sinal de igual, com um * no início ou no final da string a procurar, podemos pesquisar
pelos caracteres iniciais ou finais, respectivamente. Podemos também, inserir um * no
início e outro no final da string. Estaremos desta forma, pesquisando qualquer registro que
contenha a string especificada. Para esclarecer um pouco sobre isso, dê uma olhada nos
exemplo á seguir:

Select * From Clientes Where Nome Like ‘Jo*’

145

Irá selecionar todos os registros que tiverem no campo nome nomes que comecem com
“Jô”:”João”, “José”,”Jovana”, etc...
O * no final da string indica que estamos ignorando os últimos caracteres.

Select * From Clientes Where Nome Like ‘*ão’

O exemplo acima irá selecionar todos os registros em que o campo Nome termina com
“ao”. “João”, “Estevão”, etc. Ignorando desta forma, os primeiros caracteres.

Select * from Clientes Where Nome Like ‘*ar*’

O exemplo acima procura um registro em que o campo Nome contenha a string “ar”,
ignorando os primeiros e os últimos caracteres.

Associar a linguagem SQL aos nossos programas para filtrar dados oferece economia de
código e eficência. Nosso curso não se destina á abordar sobre a linguagem SQL, no
entanto achei importante abordar sobre a questão de filtros.
Você também pode, ao usar uma instrução SQL, utilizar todos os outros operadores do
Visual Basic para especificar opções de critério:

Select * from Clientes Where Codigo > 2 And Codigo < 4

O exemplo acima retornará o registro que tenha no campo Codigo um valor igual a 3.

Além disso, Muitas funções do Visual Basic também funcionam dentro de uma instrução
SQL. A única diferença será que o aluno deverá substituir as aspas duplas “” pelas aspas
simples ‘’.

A forma como usamos as instruções SQL dentro do Visual Basic é muito simples. Basta
você a usar aonde colocaria o nome da tabela. Por exemplo:

Set Tabela = Banco.OpenRecordset(“Select * From Clientes Where Nome =

‘Maria’”)

Agora que já temos uma noção sobre instruções SQL, iremos analisar, áquela linha do
código que usamos para filtrar o relatório:

Set Tabela = Banco.OpenRecordset(“Select * from Clientes Where Nome = ‘ “ & TxtFiltro.Text &
“*’” )

É uma instrução SQL simples. O único fato que merece um esclarecimento é a concatenação
g que usamos para a instrução SQL.
Como temos um Textbox e o filtro será com base nesse Textbox, logo teremos que
concatenar a instrução SQL com o conteúdo de “TxtFiltro”, através da propriedade Text.
(“Select * from Clientes Where Nome = ‘ “ & TxtFiltro.Text

Após o sinal de igual(=), usamos uma ‘ (aspas simples), pois o campo a qual estamos
filtrando a tabela é Text, que funciona como se fosse uma variável String, por isso a
necessidade das ‘’(aspas simples). Como ainda iremos concatenar a instrução SQL com o

146

valor contido em “TxtFiltro”, apenas abrimos as aspas simples, deixando para fechar logo
após a concatenação com a Textbox “TxtFiltro”.
Depois da ‘(aspas simples), utilizamos a aspas duplas para fechar a string, e,
concatenamos, através do operador &, com o texto contido em “TxtFiltro”:

“ & TxtFiltro.Text

Para facilitar o entendimento, digamos que o usuário tenha digitado na Textbox, o string
“ma”. Essa string será concatenada com a string á esquerda dela através do operador &.
Isso resultará na seguinte String:

Select * from Clientes Where Nome Like ‘ma

Como você viu, ainda faltam o * e uma aspa simples no final da expressão para que a
instrução SQL funcione. É isto que faz o restante da expressão:

& “*’ ”

Como resultado final, tudo o que for digitado na Textbox será pesquisado no campo
nome da tabela “Clientes”. Se os primeiros caracteres coincidirem, o registro será aceito.

Visualizando os dados antes de imprimir

Em um relatório mais profissional, temos a necessidade de visualizar os dados antes de
imprimi-los. E o Crystal nos primite isso, através do objeto Crviewer. No nosso curso,
iremos aprender a visualizar os dados, através do formulário que o assistente cria para
podermos visualizar os dados. Desta forma, aplicaremos o filtro que precisamos no código
desse formulário e, bastando apenas, a alteração de uma propriedade, conseguimos o
resultado esperado.

Voltando áquele nosso exemplo do filtro anterior. Crie um novo projeto. Crie um novo
relatório no Crystal(não se esqueça de adicionar o controle crviewer na caixa de
componentes). Este formulário deve ter como base a tabela “Clientes”, existente no banco
de dados “bCurso”. Quando o assistente perguntar se você quer criar um formulário de
visualização, selecione a opção Yes.

Nomeie o relatório como “RptCli” e o formulário como “FrmRelCli”. Agora observe o
código criado pelo assistente no formulário “FrmRelCli”:

147

Bem, a primeira coisa que devemos fazer nesse código, é retirar a linha existente na
seção General-Declarations do formulário, já que renomeamos o nome do formulário e
agora essa declaração não aponta para lugar algum.
Analisando o código, onde podemos nesse código aplicar o nosso filtro?
A resposta é: No evento Load.
Claro que colocar Um Textbox nesse formulário para digitar o filtro não seria o correto,
já que esse é um formulário próprio para a visualização. Como esse é um exemplo prático,
façamos o seguinte.

Criamos um novo formulário, como o que já criamos anteriormente para aplicar filtros,
com a seguinte aparência:

Nomeie o formulário como FrmFiltro.O Textbox como “TxtFiltro” e o botão de
visualização de impressão como “CmdVisualizar”.
Usaremos esse formulário apenas para informar o filtro ao relatório. Sendo assim, a
única coisa que teremos de fazer é codificar o evento Click do botão “CmdVisualizar” para
que chame o formulário de visualização(“FrmRelCli”):

Agora que já chamamos o formulário de visualização, vamos aplicar o filtro no evento
Load desse formulário, com base no que foi digitado pelo usuário no objeto “TxtFiltro” do
formulário “FrmFiltro”. Aplicamos o filtro da mesma maneira como já fizemos
anteriormente, quando mandamos os dados direto para a impressora.(Não se esqueça de
marcar a biblioteca do D.A.O., na caixa de referências).

148

Dim Banco as Database
Dim Tabela as RecordSet

Set Banco = OpenDatabase(“C:\Trabalho\Dbcurso.mdb”)

If FrmFiltro.TxtFiltro.Text<>”” then
Set Tabela = Banco.OpenRecordset(“Select * from Clientes Where Nome like ‘ “ &
FrmFiltro.TxtFiltro.Text & “*’” )
Else

Set Tabela = Banco.OpenRecordset(“Clientes”)

End if

RptCli.Database.SetDataSource Tabela

A única diferença está em 2 linhas nesse código, onde fizemos referência ao objeto
“TxtFiltro” do formulário “FrmFiltro”. O Visual Basic trata os objetos de um formulário
como variáveis públicas. Então podemos acessa-los de qualquer parte do projeto, bastando
anteceder seu nome pelo nome do formulário seguido de .(ponto).

FrmFiltro.TxtFiltro.Text

Enfim, com esse código acima, já conseguimos obter o filtro que precisamos. Com isso,
já podemos jogar os dados para a impressora. Mas não é isso que queremos agora. O que
queremos é visualizar os dados antes de imprimir. Olhando para o restante do código do
evento, só temos que alterar uma propriedade:

Screen.MousePointer = vbHourglass
CRViewer1.ReportSource = Report
CRViewer1.ViewReport
Screen.MousePointer = vbDefault

Aqui você troca pelo nome do formulário que irá usar

Alterando, ficará:

Screen.MousePointer = vbHourglass
CRViewer1.ReportSource = RptCli
CRViewer1.ViewReport
Screen.MousePointer = vbDefault

Agora altera a propriedade WindowsState do formulário atual para 2 - Maximized para
dar uma aparência mais profissional á visualização de impressão.
Não podemos nos esquecer de descarregar o relatório da memória. Podemos fazer isso,
no evento Unload do relatório de visualização:

149

Rode o projeto e confira o resultado.

1

1

Autor:Dieimes Viana Corrêa
Email:dieimes_c@yahoo.com.br
Fone: (051) 91538814

150

You're Reading a Free Preview

Download
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->