Académique Documents
Professionnel Documents
Culture Documents
É com muito prazer termos você como nosso aluno virtual em nosso treinamento de
Desenvolvimento de Aplicações Delphi.
Você adquiriu a versão sem suporte a dúvidas. Mas futuramente poderá adquirir o
suporte quando achar necessário pelo e-mail: ramos@mgt.com.br
O conteúdo desta apostila é o conteúdo das vídeo aulas. Caso você tenha alguma dúvida
recorra às vídeo aulas e caso mesmo assim suas dúvidas não tenham sido sanadas pode
enviar para o nosso e-mail.
Todos exemplos desta apostila são progressivos, ou seja, dependem das lições
anteriores.
Este primeiro capítulo é dedicado a uma visão geral do Delphi e sua configuração.
Começamos pelo Main Menu Bar:
Vamos personalizar nossos atalhos para o Delphi. Clique com o botão direito do mouse
sobre esta área da figura a cima e escolha a opção Customize, deverá apresentar a tela
Customize:
Nesta tela encontramos três pastas: Toolbars, Commands e Options. Em nosso exemplo
da apostila temos a opção Custom desmarcada iremos marca-la e observe que o Main
Menu Bar sofrerá alterações, o mesmo ocorrerá se você desmarcar outras opções e
marcar novamente.
Na pasta Commands temos diversos outros atalhos que podem ser adicionados ao
Delphi. Para selecionar vamos escolher em Categories a opção Edit e em Commands
escolheremos a opção Cut:
Existem componentes visuais e não visuais. Os componente visuais são aqueles que
serão vistos pelos usuários quando o programa desenvolvido estiver sendo executado.
Os componentes não visuais são aqueles vistos somente pelo desenvolvedor.
Speed Menus
Object Inspector
Propriedades - Properties
Ainda no Object Inspector, vou aqui falar um pouco de propriedades, como citado
anteriormente, estas propriedades iremos conhecer mais a fundo no decorrer de nosso
treinamento, até porque cada componente que iremos trabalhar possuem suas próprias
propriedades.
Eventos - Events
Eventos são o que ocorrerá a um objeto se por exemplo: Clicar, O mouse estiver por
cima, ou mouse estiver pressionado e diversos outros eventos que cada objeto pode ter –
não obrigatoriamente – e que veremos no decorrer do treinamento.
Esta lição é a mesma lição das vídeo aulas. A partir daqui que iremos começar a
realmente trabalhar com o Delphi e começar a conhecer mais a fundo os componentes,
propriedades e escrever os códigos de programação, que na minha opinião é a melhor
parte.
10
Agora que você já montou a tela como apresentado na figura anterior, iremos agora
criar os eventos no object inspector de cada componente.
11
Este código serve para resetar o componente ProgressBar quando ele estiver sendo
executado, quando o usuário clicar sobre o botão.
12
Primeiramente iremos criar uma nova aplicação indo ao menu do Delphi File | New |
Application, a partir de agora sempre que eu disser “criar uma nova aplicação” fica
entendido que será sempre estes passos.
Em seguida já vamos salvar este projeto criando uma nova pasta chamada
ComponentSampler e salvar como FromComponentSampler1.pás.
15
Iremos utilizar os seguintes componentes: Panel, Splitter e StatusBar que são o caminho
ideal para criarmos uma boa interface gráfica ao nosso sisteminha e possibilitar ao
usuário modificações em tempo real.
Panel servirá para distribuirmos melhor a apresentação do nosso projeto e também para
possibilitar ao usuário a dimensionar os itens expostos no formulário.
Splitter é o objeto que iremos configurar para que possibilite esta movimentação dos
objetos pelo usuário do sistema.
StatusBar é uma barra que contém informações sobre onde o usuário do nosso exemplo
estará.
Você compreenderá melhor o que quero dizer até o final desta lição.
16
Quando você colocou o componente StatusBar em seu formulário ele foi para o final do
Form. Agora vamos criar colunas para nosso StatusBar, na propriedade Panels clique
nos três pontinhos:
17
18
20
Até o momento estávamos preparando como seria o visual da nossa aplicação. A partir
de agora iremos colocar novos componentes que darão a verdadeira função a nossa
aplicação que é um Windows Explorer nosso.
Aproveitando vamos retirar nas propriedades dos Panels seus respectivos captions
deixando vazios.
22
23
24
25
26
Características de Menus
Vamos iniciar uma nova aplicação para melhor ilustrar este exemplo. Na aba de
componentes Standard existe o componente MainMenu é com este componente que
criamos nossos menus.
Colocamos este componente em nosso formulário e com um duplo clique será aberto
uma nova janela que é a janela de edição de menus:
Como todo componente, ele possui sua propriedades no Object Inspector onde temos
em Caption a possibilidade de criar as opções de menu. Vamos criar o menu Opções
escrevendo no Caption.
Agora vamos criar as sub-opções tais como: Custommer, Parts, Vendors e Sair:
27
Você já deve ter percebido que programas Windows possuem navegação por teclado,
como por exemplo Alt+O e assim por diante, podemos fazer isso colocando o símbolo
“&” no Caption de cada opção na letra que acharmos mais conveniente, após fazer isso
observe que a letra onde colocamos o símbolo ficará sublinhado:
28
29
Para selecionarmos os ícones de cada opção de menu, basta clicar duas vezes sobre o
componente ImageList que deverá aparecer a seguinte tela:
Clique sobre o botão Add... em seguida ir a algum diretório onde haja ícones e
selecionar os ícones que irão ser utilizados em seu projeto, como neste exemplo temos 7
opções selecionamos 7 ícones:
30
31
32
O Borland Database Engine ou BDE é utilizado para realizar a conexão do Delphi com
banco de dados (Paradox, Access, Interbase, Oracle, SQLServer e outros) e permite
também distribuir suas aplicações a seus clientes. Neste módulo estaremos dando uma
introdução ao BDE.
Vamos executar o BDE Administrator que foi instalado em seu computador junto com o
Delphi, vá ao menu do Windows Iniciar | Programas | Borland Delphi | BDE
Administrator, deverá ser aberto uma janela como esta:
Vamos iniciar nosso aprendizado sobre o BDE com exemplos práticos e que serão
utilizados pelo nosso treinamento daqui por diante.
Vamos criar aqui um novo Alias1 , para isso vá ao menu Object | New onde deverá ser
apresentado a seguinte tela New Database Alias:
1
Alias é um apelido dado a um caminho onde é localizado os bancos de dados que iremos utilizar no
desenvolvimento de nossas aplicações para que o Delphi possa localizar quando estivermos
desenvolvendo e até mesmo para distribuir nossa aplicação aos nossos clientes.
33
2
Poderíamos criar qualquer nome para o Alias, mas vamos utilizar este nome em todas aplicações que
iremos desenvolver daqui por diante. Caso no futuro você desenvolva um controle de estoque poderia
colocar o nome deste Alias como Estoque.
34
Daqui por diante, para não perdermos tempo criando nossos Bancos de Dados (veremos
como criar banco de dados Paradox no próximo capítulo) iremos trabalhar com bancos
de dados já existentes no próprio Delphi que se localizam em: C:\ Arquivos de
programas\Arquivos comuns\Borland Shared\Data4 em seguida clicar em OK.
3
Caminho de diretórios onde se localiza o diretório onde estão os bancos de dados que o sistema a ser
desenvolvido estão armazenados.
4
Este caminho pode mudar de computador por computador, é aconselhável realizar um procura antes
pelas tabelas: customer.db, Parts.db e colocar o caminho onde se encontram.
35
Para salvar estes processos realizados, vá ao Menu Object | Apply.em seguida irá
perguntar se deseja salvar, confirme clicando em OK:
36
37
Este capítulo é apenas como título de curiosidade, pois nosso objetivo é de apenas
ensinar a desenvolver aplicações Delphi. No treinamento oficial da Borland em nenhum
momento é ensinado a criar um banco de dados Paradox – apesar de ensinar como
desenvolver com – então aqui iremos passar rápido apenas como a título de curiosidade,
tanto que este texto já foi utilizado para outros propósitos para o portal Ramos da
Informática5.
Um banco de dados pode ser definido como um conjunto unificado de informação que
vai ser compartilhado pelas pessoas autorizadas de uma organização. A função de um
Banco de Dados é permitir o armazenamento e a recuperação da informação necessária
para as pessoas da organização tomarem decisões.
Um Banco de Dados é formado por um conjunto de arquivos de dados, também
chamados de tabelas. Em uma tabela temos, linhas e colunas. Onde uma linha contém
informações a respeito de um item em particular, e a coluna possui uma parte das
informações de uma linha. A figura a seguir ilustra uma tabela de Clientes.
Na tabela do exemplo acima, o mais sensato é determinar o campo Código como nossa
chave primária.
Além de determinarmos os campos e a chave primária da nossa tabela, também teremos
que definir o tipo de dado, comprimento, formato e o domínio para cada campo
desta tabela.
Tipo de Dado: refere-se ao conteúdo do dado, podendo ser numérico, alfabético, data,
hora ou cadeia de caracteres longa ou curta.
Comprimento: refere-se ao tamanho ou número máximo de posições que poderá
assumir o valor ou conteúdo de cada dado.
5
Portal Ramos da Informática é um portal de comunidade on-line voltado a desenvolvedores Delphi e
Kylix e todos bancos de dados do mercado. O endereço de acesso é: www.ramosdainformatica.com.br
38
Domínio: especifica se os valores dos dados pertencem a uma lista de valores pré
definidos, podendo estar em uma lista, ou satisfazer uma regra.
Database Desktop
O nosso próximo exemplo, gerenciará duas tabelas. Uma com o cadastro dos clientes e
outra com as vendas realizadas para estes clientes.
39
Digite o nome para o primeiro campo (CODIGO) e mude para tipo de campo (Type)
usando a tecla Tab. Com o campo Type selecionado, de um clique com o botão direito
do mouse em cima dele, para ser exibido o menu pop-up com todos os valores para o
tipo de campo. As letras sublinhadas correspondem à letra de atalho para cada tipo de
dado. O nosso campo CODIGO será definido como tipo Alpha. Apesar de ser um
campo com números nós não iremos realizar nenhum cálculo matemático com ele, por
isso o definimos como Alpha.
40
41
42
Para que a tabela Vendas se relacione com a tabela Clientes, deveremos definir o campo
CODIGO da tabela Vendas como índice secundário.
43
44
O Delphi nos oferece algumas soluções para banco de dados como: Session, Database,
Dataset, DataSource e Data-aware controls ou controles de bancos de dados.
Table é para banco de dados simples como o Paradox e não possui facilidades para
trabalhar com SQL.
45
Este capítulo iremos trabalhar somente com Table pois é necessário que você tenha
conhecimentos deste para podermos prosseguimos com Query e ambos são muito
idênticos mudando poucas coisas.
Componente Table.
Componente DataSource.
Então sempre que pedir para colocar um desses componentes você já sabe onde
localizar. Os componentes de controle, apresentados no diagrama no começo deste
capítulo estão localizados na aba de componentes Data Controls.
Aqui começamos uma nova aplicação. Antes de continuar o assunto sobre criação de
aplicações com banco de dados, crie uma nova aplicação com as seguintes propriedades
do Form:
Name: frmMain
Caption: Nossa Aplicação
46
Vá ao menu File | New | Form com o novo form vamos colocar as seguintes
propriedades para ele:
Name: frmCustomer
Caption: Customers
Name: tblCustomer
DatabaseName: Delphi_Loca_Class_Data (Observe que é aqui que utilizamos o
Alias criado no BDE.)
TableName: customer.db (Observe que aqui encontramos todos bancos de dados
que indicamos ao criar o Alias no BDE, neste exemplo utilizaremos a tabela
customer.db).
47
Name: dtsrcCustomer
DataSet: tblCustomer
Pronto! Já fizemos a ligação do Delphi com nosso banco de dados. Vamos agora inserir
componentes de controle de banco de dados. Por enquanto vamos adicionar somente o
componente DBGrid na palheta de componentes DataControls e setar as seguintes
propriedades para este componente:
Name: dbgrdCustomer
DataSource: dtsrcCustomer
E está quase pronto, mas é preciso mostrar os dados do banco de dados Customer.db no
DBGrid, para isso selecione o componente table (tblCustomer) e coloque a propriedade
Active de False para True e pronto, lá estão os dados do banco de dados Customer.db
visível em nosso DBGrid.
48
Vamos criar aqui uma interface mais agradável ao usuário com várias opções em uma
única tela. Para isso vamos selecionar o DBGrid e clicar no botão Delete de seu teclado,
vamos deletar o componente DBGrid, mas somente ele.
51
52
Agora vamos criar a opção para Detail, onde iremos colocar os detalhes do banco de
dados e conhecer outros componentes de controle de banco de dados.
Componente Propriedades
DBEdit1 Name: dbedtCompany
DataSource: dtsrcCustomer
DataFiels: Company
DBEdit2 Name: dbdtAdress
DataSource: dtsrcCustomer
DataFiels: Addr1
DBEdit3 Name: dbdtCity
DataSource: dtsrcCustomer
DataFiels: City
DBEdit4 Name: dbdtState
DataSource: dtsrcCustomer
DataFiels: State
DBEdit5 Name: dbdtZip
DataSource: dtsrcCustomer
DataFiels: Zip
53
Caption:
Align: alTop
Name: dbnvgtrCustomer
DataSource: dtsrcCustomer
54
Vamos selecionar nosso Page Control que já está no formulário e vamos definir sua
propriedade Align para alClient, sua tela então deverá ficar como esta:
Vamos criar agora mais uma pasta em nosso Page Control que terá seu Caption como
&Orders:
55
DatabaseName: Delphi_Local_Class_Data
TableName: orders.db
Name: tblOrders
Name: dtsrcOrders
DataSet: tblOrders
56
57
O que fizemos faz em Orders mostrar todas as compras realizadas pela empresa
selecionada em Customer.
58
Ainda em nossa aplicação que iniciamos no capítulo anterior aberta vamos criar o
cadastro de Parts.
Vamos ao menu do Delphi File | New | Other e vamos escolher a pasta Business:
59
Em Drive or Alias name vamos selecionar o nosso Alias. Em seguida escolha o banco
de dados Parts.db:
60
61
Clique sobre o botão Finish, será criado nosso formulário do Parts, vamos alterar as
propriedades deste formulário para:
Name: frmParts
Caption: Parts
Name: tblParts
62
6
Mestre Detalhe é quando utilizamos dois ou mais bancos de dados em um formulário.
63
64
65
66
Clique em Finish.
Será montado nosso formulário que liga a tabela Parts.db com Vendors.db:
67
Name: frmPartsVendors
Caption: Parts and Vendors
Componente Propriedades
DataModule2 Name: dtmdlPartsAndVendors
Table1 Name: tbltblParts
Table2 Name: tblVendors
DataSource1 Name: dtsrcParts
DataSource2 Name: dtsrcVendors
68
69
Componentes Correspondência
Field
TAutoIncField Campo de auto-incremento.
TStringField Dados em textos de até 255 caracteres.
TIntergerField Números entre –2147483648... 2147483648
TSmallIntField Números entre –32768...32168
TLargeIntField Campo Integer longo
TWordField Números de zero a 65535
TFloatField Números reais com 15-16 digitos
TCurrencyField O mesmo que TFloatField
TBCDField Números reais com decimais fixas de até 19 digitos
TBooleanField Valores True ou False
TDateTimeField Valores Data e Time
TTimeField Valor Time
TBlobField Campo binário sem limitação de tamanho.
TBytesField Igual ao TBlobField
TVarBytesField Campo binário com limitação de espaço para 65535 caracteres
TArrayField Campo Array
TMemoField Somente textos longos
TADTField Campo abstrato de dados
TGraphicField Campo de imagem (por exemplo, bitmap) sem limitação de tamanho.
Estes componentes apresentados na tabela são os que poderão ser alterados em tempo
de desenvolvimento ou em tempo de execução. Ou alterando suas propriedades no
Object Inspector ou via programação. Conheceremos agora no decorrer do treinamento
os principais e mais utilizados componentes TField.
Este capítulo, apesar de termos as vídeo aulas, vamos refazer os exemplos das vídeo
aulas e vamos explicar itens que não foram explicados nas mesmas.
Se você quiser criar um objeto TField quando estiver desenvolvendo sua aplicação,
clique sobre o componente Table que desejar com o botão direito do mouse e escolha a
opção Fields Editor... :
70
Em seguida clique sobre o botão OK. Todos campos selecionados foram para o nosso
editor de Fields:
71
Existem outras propriedades para cada campo TField no Object Inspector. As que
iremos conhecer em nosso treinamento são:
Propriedade Descrição
DisplayLabel É o nome da coluna de um componente DBGrid, é aqui que corrigimos
o nome de uma coluna do DBGrid.
DisplayWidth Usado para definirmos o tamanho de uma coluna em um componente
DBGrid.
72
Apesar de apresentarmos nas vídeo aulas, vamos tratar também aqui na apostila de
conteúdo o que não foi citado.
Temos algumas mascaras já criadas pelo próprio Delphi que podemos escolher, assim
como também podemos criar nossas próprias mascaras. Por exemplo podemos forçar
que o sistema aceito somente letras maiúsculas colocando o sinal de maior (“>”)antes da
mascara, ou podemos colocar o sinal de menor (“<”) para forçarmos o sistema aceitar
somente letras minúsculas. Podemos colocar o caracter “L” para aceitar somente letras e
o caracter “A” para aceitar letras e números. O caracter “9” permite somente números.
Um exemplo: Se você precisar criar uma mascara que force o usuário a digitar 3 letras
maiúsculas e em seguida 4 números você pode criar a seguinte mascara: >LLL-9999
73
Movendo ponteiros
75
Clique sobre o botão Load e escolha as imagens BMP que melhor se encaixar ao
exemplo no meu caso estas imagens estavam em \Arquivos de
Programas\Borland\Delphi6\Demos\Fotball:
76
77
78
79
81
Assim já estará pronto para rodar a aplicação e ver como funciona este filtro.
Vamos criar um simples sistema de busca, para este exemplo vamos trabalhar um pouco
na no formulário frmParts, deixando um pouco de lado nosso formulário Customer, mas
pode ser feito também em outros formulários futuros.
Name: frmFindPart
Caption: Find Part
No Panel2 colque um componente DBGrid, com sua propriedade Align como alClient:
82
Para BitBtn1:
Name: btbtnCancel
Kind: bkCancel
Para BitBtn2:
Name: btbtnOk
Kind: bkOK
Name: lblFindPartName
Caption: Find Part Name:
Name:edtFind
83
84
Bookmarking Records
Esta rotina faz a ligação com o DataModule e manda o Delphi construir o formulário de
pesquisa.
85
Este capítulo é voltado a migração de aplicações para Cliente Servidor. Você aprenderá
a converter seus bancos de dados Paradox para o Interbase e a configurar sua aplicação
facilmente para esta plataforma.
Escolhemos o banco de dados Interbase não apenas por ser um banco de dados da
Borland, mas também por ser um banco de dados muito mais confiável que muitos
outros como: MS-Access, MySQL, Paradox e outros.
Este capítulo só funciona com o Borland Delphi versão 7, mas pode ser aplicado
perfeitamente ao Delphi 6. Particularmente eu prefiro o Delphi 7 por ter mais recursos e
alguns passos desta lição podem não dar certo com a versão 6 do Delphi.
Num ambiente Cliente/Servidor nós temos um banco de dados central sendo acessado
por vários outros usuários - Clientes. Este banco de dados central deve ser gerenciado
por um programa específico para isto.
Para converter os bancos de dados de Paradox para Interbase vamos utilizar uma
ferramenta que já vem no próprio Borland Delphi 7.
Vamos abrir o DataPump, que irá nos abrir diretamente nesta tela:
86
Mas antes por ser um ambiente Cliente Servidor devemos criar um novo Alias, como já
foi apresentado não irei demonstrar novamente, chamado Delphi_Server_Class_Data,
em seguida escolhido o alias inicial Delphi_Local_Class_Data clique sobre o botão
Next e na próxima tela selecione o Alias Delphi_Server_Class_Data:
Em seguida clique sobre o botão Next, vamos selecionar todos os bancos de dados
clicando sobre o botão >>:
Em seguida clique sobre o botão Next e será apresentado um relatório sobre cada tabela
que irá ser convertida, clique sobre o botão Upsize para iniciarmos a conversão de
87
Este relatório apresenta que tudo ocorreu bem na conversão, clique em Done e pronto,
seus bancos de dados agora são Interbase com todas informações neles contidos
mantidos. Agora vamos às modificações que você deve realizar em sua aplicação para
que rode perfeitamente, agora com banco de dados Interbase e Cliente Servidor.
Modificando Aplicações
Aqui neste exemplo vamos realizar a mudança somente no formulário Parts, quando
você for desenvolver seus aplicativos e converte-lo deve realizar estes processos em
todos formulários.
88
Aqui em meu exemplo deu tudo certo, porém podem ocorrer erros quando você for
realizar. Entre em contato para que possamos resolver e explicar o que aconteceu.
89
Introdução e instrução
Até este momento vimos a utilização de componente TTable para ligação de tabelas. A
partir de agora veremos como utilizar o componente TQuery. O componente TQuery é
parecido com o componente TTable. O componente Query é indicado para outros tipos
de bancos de dados que não seja o Paradox, apesar de funcionar perfeitamente bem com
o Paradox, em especial bancos de dados que trabalhem com instruções SQL como o
Interbase. Então a diferença básica entre componente Table e Query é que este último
necessita conhecimentos de SQL.
Este treinamento não tem como objetivo ensinar SQL, mas vou mostrar aqui algumas
funções básicas de SQL. Você poderá conhecer mais sobre SQL no Portal Ramos da
Informática ( www.ramosdainformatica.com.br ) na seção de artigos. Não ensinarei o
SQL, assim como não ensinei o Paradox, pois sairia do contexto do treinamento que é o
Delphi exclusivamente.
A utilização de SQL é sem dúvidas mais eficiente e rápido que se fizéssemos com
Object Pascal puro e, uma vez que você já tiver conhecimentos de SQL verá como é
muito mais fácil desenvolver suas aplicações, sem contar que o SQL é uma linguagem
universal para banco de dados, muito utilizada pelos principais bancos de dados do
mercado.
Com os objetos (componentes) Query você pode desenvolver aplicações muito mais
rápidas e seguras, além de ser mais indicado no desenvolvimento de aplicações
Client/Server e redes.
Este comando, como já dito, serve para fazer a ligação da tabela Orders ao componente
Query, é sempre este comando mudando apenas o nome do banco de dados sem sua
extensão.
90
91
Agora precisamos fazer a ligação entre as tabelas tblCustomer e qryOrders para que
haja o filtro pelo CustNo, como era antes de realizarmos estas alterações, então de volta
ao editor de SQL do Query acrescente:
92
Observe as propriedades deste parâmetro, o seu exemplo deverá ficar igual. Em seguida
no evento OnDataChange de seu componente dtsrcOrders escreva o seguinte código:
93
Anteriormente vimos como trabalhar com o Database Form Wizard com Table agora
vemos com Query. Vá ao menu do Delphi File | New | Other e na pasta Business
escolha a opção Database Form Wizard:
Em seguida clique em OK. Escolha agora Create Master/Detail Form e Create a Form
using TQuery Objects em seguida clique em Next:
94
Selecione todos os campos com exceção dos campos que comecem por Ship, em
seguida clique sobre o botão Next:
95
97
Select
orders."OrderNo",
orders."CustNo",
orders."SaleDate",
orders."ShipDate",
orders."EmpNo",
orders."PO",
orders."Terms",
orders."PaymentMethod",
orders."ItemsTotal",
orders."TaxRate",
orders."Freight",
orders."AmountPaid"
From "orders.db"
As orders
O de OrderLineItems teremos:
Select
OrderLineitems."LINEITEM_KEY",
OrderLineitems."ORDER_KEY",
OrderLineitems."PART_KEY",
OrderLineitems."SUPPLIER_KEY",
OrderLineitems."LINE_NUMBER",
OrderLineitems."QUANTITY",
OrderLineitems."EXTENDED_PRICE",
OrderLineitems."DISCOUNT",
OrderLineitems."TAX",
OrderLineitems."RETURN_PART",
OrderLineitems."LINE_STATUS",
98
Veja que assim o Wizard já montou os parâmetros SQL de chamada para seus bancos
de dados.
Caption = Orders
Name: frmOrders
Agora basta você chamar este formulário no menu do Formulário principal da aplicação
com o comando:
FrmOrders.Show;
Editando Registros
Este formulário ainda não está aceitando edição porque o Wizard deixa a propriedade
RequestLive dos Querys como False, coloque esta propriedade como True para que
possibilite a edição de registros.
Porém utilizar-se somente deste artifício para edição de registro não é aconselhável por
não ser uma operação segura principalmente se você for trabalhar com aplicações em
rede. Por enquanto isto basta, mas veremos mais adiante como fazer corretamente em
“TDatasets Avançado”.
Neste nosso exemplo vamos colocar um componente Label, Edit e Button devendo ficar
desta forma:
99
end;
O SQL Builder
Eu disse que neste treinamento não irei entrar em detalhes sobre programação em SQL,
porém o Delphi possui um gerador de rotinas em SQL, o SQL Builder que pode ser
acessado diretamente nos componentes Query, clicando sobre o botão direito deles:
100
Vou demonstrar como gerar seus SQLs com este gerador do Delphi. Primeiro vamos
definir nosso Alias em Database:
101
Agora vamos selecionar os campos que iremos utilizar em nossas tabelas, tanto em
Customer quanto em Orders, como mostra a ilustração a baixo:
102
O SQL Builder permite fazer outros tipos de controles além de setar compartilhar
tabelas dos Querys. Podemos fazer outras condições ao código SQL que será gerado.
Por exemplo a próxima figura mostra que posso definir critérios:
103
Na barra de atalhos do SQL Builder possui o Execute Query onde você poderá
visualizar os em um DBGrid o que está sendo montado para que você aprove ou não:
104
Você deverá copiar este código pois o SQL Builder não coloca automaticamente nas
propriedades SQL de seu Query.
105
O dbExpress surgiu a partir da versão 6 do Delphi. Apesar disto é muito importante que
você, mesmo começando a programar a partir da versão 6 do Delphi, conheça e aprenda
o BDE pois a maioria, eu diria uns 95%, da aplicações já desenvolvidas e ainda por
desenvolver trabalha com o BDE e creio que ainda vá demorar bastante para que sejam
convertidos para o dbExpress. Esta nova camada foi reconstruída a partir do zero, não
aproveitando a estrutura da BDE
.
Veja agora as principais diferenças entre a BDE e a DbExpress:
106
Vamos conhecer aqui uma breve descrição sobre cada um destes componentes. Para que
você conheça melhor suas propriedades veja no Help do Delphi.
SQLQuery – Este é um componente DataSet para enviar códigos SQL para o servidor
de banco de dados. Este componente suporta dados enviados pelo comando SELECT.
Modificações de dados com INSERT, UPDATE e DELETE são suportados. Comandos
para criar definições como CREATE TABLE (etc.) enquanto é executado.
107
Vamos imaginar que você precise criar uma aplicação flexível. Mais ainda, suponha que
sua aplicação tenha que trabalhar com diversos tipos de bancos de dados e sistemas
operacionais, e que necessita de ser utilizado em um laptop para em seguida se conectar
a um servidor para transferência de dados para este servidor, quando o usuário chegar
ao escritório. Melhor explicando: Você foi contratado para desenvolver uma aplicação
onde os vendedores de um grande distribuidor atacadista necessitam recolher
informações de seus clientes em seguida enviar estas informações em seus laptops a
central de atacado para poderem processar os pedidos e sua aplicação necessita ser
flexível pois a empresa está com planos futuros de mudar toda sua base de dados e
necessite de algo que não dependa de plataforma ou tipo de banco de dados. Então
como fazer? Quais componentes utilizar?
Crie agora um novo projeto case1.dpr com FormCDS.pas como formulário principal.
Coloque os seguintes componentes com seus respectivos nomes no formulário:
Precisamos agora fazer ligações entre nossos componentes. Observe que ainda não
utilizamos nenhum componente do dbExpress, principalmente o componente
SQLConnection que será envolvido neste exemplo. Coloque a propriedade DataSet do
DataSource para o componente específico ClientDataSet, o DBGrid e o DBNavigator a
propriedade Datasource para dtsrcSales.
108
Selecione a opção Fields Editor. Na janela de Fields Editor não há entradas. Clique com
o botão direito do mouse sobre o Fields Editor e selecione New Field, veja na figura a
seguir. Coloque as informações como mostra a figura:
109
Feche a janela Fields Editor. Agora clique com o botão direito do mouse sobre o
componente ClientDataSet onde você deverá ver as seguintes opções:
110
111
Um elemento XML pode ter dados declarados como sendo preços de venda, taxas de
preço, um título de livro, a quantidade de chuva, ou qualquer outro tipo de elemento de
dado. Como as tags XML são adotadas por intranets de organizações, e também via
Internet, haverá uma correspondente habilidade em manipular e procurar por dados
independentemente das aplicações onde os quais são encontrados. Uma vez que o dado
foi encontrado, ele pode ser distribuído pela rede e apresentado em um browser como o
Internet Explorer 5 de várias formas possíveis, ou então esse dado pode ser transferido
para outras aplicações para processamento futuro e visualização.
Neste treinamento, assim como o SQL, não vamos entrar muito em detalhes sobre XML
porque é voltado exclusivamente ao Delphi.
112
Agora que nossa aplicação já está criando e salvando as informações precisamos agora
fazer com que se conecte ao servidor de banco de dados e mande as informações para
lá.
113
114
115
116
clntdtstSales.ApplyUpdates(-1);
SQLDataSet
117
118
Quando você estiver editando e realizando update no banco de dados poderão surgir
erros que o servidor não permite. Vamos agora criar um formulário que reporte o erro e
possibilite a correção em tempo de execução evitando assim erro ao mudar ou adicionar
os dados na tabela.
implementation
{$R *.dfm}
uses
FormReconcile;
Assim você terá sempre os avisos de erro do servidor e poderá corrigir alterando os
valores, evitando assim erros do sistema.
119
Splash Screen
121
Application.Initialize;
frmSplash := TfrmSplash.Create(Application);
frmSplash.Show;
frmSplash.Refresh;
Application.CreateForm(TfrmMain, frmMain);
Application.CreateForm(TfrmSplash, frmSplash);
frmSplash.Free;
Application.Run;
end.
Assim teremos o Splash Screen sendo apresentado enquanto são carregados os Form e
bancos de dados de nossas aplicações.
O método que vou apresentar, servirá para que o sistema carregue mais rápido e que o
sistema carregue somente o que o usuário irá utilizar gastando assim menos memória e
tempo na máquina do cliente deixando nossas aplicações mais rápidas.
Na lista do DPR inicial, isto em nossa aplicação, vamos deixar somente desta forma:
122
O que vamos fazer agora é, em cada opção do menu para chamada de um novo Form,
realizar a criação dos formulários e dos bancos de dados de cada formulário na hora em
que o usuário abrir. Você poderá estar se perguntando: Mas aí irá demorar sempre para
abrir este formulário. Correto. Mas pense, é melhor o cliente esperar para abrir só o que
ele vai usar do que abrir tudo quando for iniciar o sistema que pode levar muito mais
tempo com o decorrer do uso do sistema.
FrmCustomer.show;
123
Por termos feito isso, e para continuarmos melhorando a velocidade de nosso sistema
em todos os formulários de nossa aplicação devemos destruir a criação do Formulário e
dos bancos de dados para estarmos sempre liberando memória na máquina de nossos
clientes. Até mesmo porque, se não fizermos isto, pode ocorrer o seguinte: sempre que o
usuário fechar o formulário que chamou com nossa aplicação aberta e depois fechar este
formulário ele será fechado na vista de nossos clientes mas não liberará da memória e
quando o usuário for abrir novamente o mesmo formulário estará criando novamente
sempre que for realizando esta operação sendo assim, consumindo sempre mais
memória. Então devemos destruir o formulário com o método caFree para liberar a
memória sempre que os formulários forem sendo fechados.
Por isto em todos formulários de nossa aplicação, no evento OnClose devemos utilizar
do comando: Action := caFree;
124
Para mudarmos o cursor precisamos saber seus nomes. O que a aplicação usa sempre é
o crDefaut. Vamos mudar o cursor de crDefaut para crHourglass sempre que o usuário
125
E assim estará pronto. Talvez você não vá perceber que está funcionando porque talvez
sua aplicação esteja com poucos dados o que torna esta operação muito rápida. Mas
conforme seu banco de dados vá crescendo com certeza isto será muito útil.
126
Vamos precisar colocar imagens nestes botões. Para isto coloque um componente
ImageList, também da palheta de componentes Win32, em nosso formulário e vamos
127
Agora no evento OnClick de cada um destes botões coloque as ligações que deseja para
cada um deles. Aqui eu coloquei as ligações como: Botão 1 para Customers, Botão 2
para Orders, Botão 3 para Parts, Botão 4 para Suppliers e botão 5 ainda não coloquei
nada.
128
Podemos agora colocar Hints em cada um destes botões. Hints são pequenas ajudas que
auxiliam o usuário na navegação de uma aplicação, são mensagens que informam a
utilidade de um botão.
Nas propriedades de todos tipos de botões existem os Hints, basta escrever em cada um
o que quer que seja mostrado ao usuário para o guiar. E definir a propriedade ShowHint
para True.
129
Aplicações MDI
Até o momento aprendemos desenvolver aplicações SDI e MDI. Agora vou ensinar a
deixar sua aplicação somente como MDI. O MDI é legal que dá uma aparência mais
confortável aos usuário que podem abrir várias telas e visualizar todas sem nenhuma ou
pouca dificuldade.
A propriedade FormStyle
fsMDIForm
O estilo fsMDIForm cria janelas MDI pais. É muito importante saber sobre isso.
Primeiro que não são todos formulários que são definidos como fsMDIForm. Devemos
sempre definir o formulário principal como fsMDIForm porque assim as janelas filhas
não irão sobrepor o menu nem os botões da ToolBar criados quand as janelas filhas
forem maximizadas.
fsMDIChild
Fazendo isto podemos até eliminar o método Show para chamarmos nossos formulários.
Veja o exemplo a baixo que eliminamos o método Show e deixamos somente
frmSuppliers := TfrmSuppliers.Create( Application );
130
Agora vamos colocar controles para nossa aplicação MDI que facilitem ao usuário sua
organização automática. O Windows menu possui opções típicas como title, cascate,
minimize all e arrange icons para os formulários filhos. Agora nós vamos utilizar o
componente TactionList.
Action Lists
Action List faz a localização para responder aos comandos do usuário, acionados pelo
clique do mouse, para os objetos do menu. O componente ActionList é usado para
definirmos uma lista de ações (TAction). Então coloque o componente ActionList em
nosso formulário principal e vamos dar um duplo clique sobre ele:
131
Esta é uma caixa de dialog com uma lista de ações para escolhermos ao formulário:
132
133
Depois que você fizer estas ligações todas modificações realizadas serão atualizadas no
formulário:
134
Agora vamos criar uma opção para fechar todos os formulários de uma vez quando o
usuário assim o desejar, crie a opção Close All no menu:
135
136
137
138
139
A partir da versão 7 do Delphi o QuickReport deixa de existir para dar lugar ao Rave
Report.
Com o Rave Report o desenvolvedor pode criar e visualizar relatórios, como era no
QuickReport, mas o rave permite tanto CLX quanto VCL (plataformas Linux e
Windows).
É com este componente que você irá trabalhar para criar o visual do seu relatório.
Podemos criar relatórios de forma visual com sua ferramenta. Assim criamos relatórios
dinâmicos sem utilizar comandos.
Neste exemplo vamos iniciar uma nova aplicação. Em seguida vamos adicionar um
componente ClientDataSet da palheta de componentes Data Access ao formulário, com
a propriedade Name como clntDataLocal e a propriedade FileName como customer.xml
e colocar a propriedade Active para True.
Name = rvDataSetLocal
DataSet = clntDataLocal
Clique com o botão direito sobre este componente e escolha a opção Rave Visual
Designer:
141
Criar relatórios com o Rave é muito fácil. Uma vez dentro do editor do Rave vá ao
menu do Rave em File | New Data Object.
142
Selecione Direct Data View e prossione o botão de Next. Em seguida você deverá
especificar que tipo de conexão deseja realizar, é neste que definimos nosso
componente do tipo rvDataSetLocal.
143
Assim podemos começar a desenvolver nossos relatórios. Vamos utilizar neste exemplo
Wizard para a construção de nosso relatório exemplo. Para isso vá ao menu do Rave
Tools | Report Wizards | Simple Table:
144
145
146
147
Nesta opção você pode imprimir, gerar uma pré-visualização ou gerar um arquivo.
Selecione o Preview pois iremos apenas visualizar nosso relatório, deverá ser
apresentado um preview que você poderá ver como ficou seu relatório.
Quando você gera seu relatório em Rave, são criadas propriedades exclusivas do mesmo
e você precisa salvar todas estas características. Todos relatórios Rave possuem a
extensão .rav. Tanto para alterar futuramente seus projetos de relatórios quanto para
enviar aos clientes você precisa enviar estes arquivos .rav quando for distriubuir suas
aplicações.
Depois que você criou o design de seu relatório e o salvou, a forma de chamar no
Delphi é muito fácil.
148
Processando Transações
Temos agora a seguinte situação. Atualmente quando o usuário faz alguma modificação
ao em algum registro do banco de dados este registro é alterado na hora ou quando se
começa a fazer alguma alteração não tem como voltar atrás. Precisamos permitir ao
usuário poder definir se aquela mudança que ele fez no registro é o que realmente quer e
dar a possibilidade de voltar atrás. Neste tipo de operação é necessário utilizar controles
de transação aos métodos dos objetos de banco de dados. As transações são obrigadas a
iniciar no evento BeforeEdit com o método StartTransaction. É preferível segurar todas
modificações para o banco de dados até que o método Commit seja usado, escrevendo
todas mudanças no banco de dados ou o método Rollback para modificações pendentes.
Devemos agora criar um evento para aceitar a transação quando o usuário quiser salvar
o que foi realizado, utilizando o método Commit. Para isso no evento AfterPost do
mesmo componente iremos colocar o seguinte código:
Cached Updates
O Dataset possui três métodos e uma propriedade para implementar o Cached Updates.
A propriedade CachedUpdate é preciso estar como True para que todos os métodos
tenham efeitos. Então, se o usuário desejar sempre salvar, todas mudanças precisam do
método ApplyUpdate. Se o usuário desejar não salvar todas mudanças, o método
CancelUpdates deve ser executado para voltar ao que era anteriormente. Se o usuário,
no meio de sua edição quiser voltar ao que era anteriormente aquele campo em que ele
estava editando, temos que utilizar o método RevertRecord. Neste caso, todos edits que
o usuário estiver alterando voltara ao que era.
150
No Datamodule, vamos mudar ambos objetos query para usar o cached updates. No
formulário adicione um componente SpeedButton com a propriedade name como
spdbtnAppluUpdates e mude a propriedade VisibleButtons do DBNavigator para que o
botão Post não seja apresentado. No evento OnClick do SpeedButton escreva o seguinte
código:
Neste exemplo, o evento AfterCancel é usado para jogar fora todas mudanças de um
Query. Para cancelarmos mudanças devemos, no evento AfterCancel do componente,
escrever o seguinte código:
151
Vamos ver mais na prática. Usando o formulário Orders, vamos mudar a propriedade
ResquestLive para False dos componentes qryOrders e qryLineItems.
Vamos agora adicionar dois componentes UpdateSQL com nosso DataModule com as
propriedades Name como updtsqlOrders e updtsqlLineItems:
152
153
154
Como este curso não ensina SQL você deverá sempre utilizar o botão Generate SQL
para criar seus ModifySQL, InsertSQL e DeleteSQL.
Observe que clicando sobre o botão Generate SQL você gera seus códigos
automaticamente já para os três items.
155
Mas sempre que você criar packages em tempo de execução é necessário levar estas aos
seus clientes. Um package não acompanha os fontes.
Packages em tempo de design é utilizado somente quando você está desenvolvendo suas
aplicações. Não vou detalhar muito ainda pois veremos com maior clareza com a
criação de exemplos.
Criação de Package
Para criar uma package, vá ao Menu File | New. Em seguida escolha “Package” da pasta
“New Items”, deverá aparecer uma caixa de diálogos como esta:
158
O Delphi pedirá um nome para o arquivo de projeto (.DPK). Este deverá ser o nome do
package que será criado.
Adicionando componentes
Nós vamos ver primeiro como adicionar componentes que já existem no package. Para
adicionar um componente para um package, precisamos então adicionar. Clique no
botão Add no editor de Package.
159
Add Unit – Onde podemos adicionar a unit que será nosso Package.
Import ActiveX – Que podemos importar controles ActiveX para nossas aplicações.
160
Como já dito, um package pode depender de outros packages para que seja executado,
são os Requires. Selecione a pasta requires do nosso editor de Package:
161
Instalando Packages
Podemos instalar packages no menu Component | Install Package que abrirá a janela
Project Option from Package:
162
Na aba “Into existing package” você pode instalar a unit e/ou package do componente
que deseja instalar.
163
Para entender melhor esta questão imagine o seguinte: Você tem um sistema que é
dividido por módulos, estoque, clientes, caixa, bancário e outros. Você pode criar um
package para cada um destes módulos.
Vamos ver por outro aspecto também, suponha-se que você trabalha com uma equipe de
desenvolvedores e cada um é responsável por cada um destes módulos e para distribuir
para que outros desenvolvedores aproveitem estes módulos em suas aplicações você
precisa só criar um package para isto.
Para criar um novo package baseado em nosso exemplo principal, nós vamos precisar
criar uma nova package. Vamos chamar esta package de “pkgDataOrderEntry.dpk”.
Uma vez criado, vamos adicionar a unit DataMain.pas em nosso editor de Package:
Uma vez adicionado, vamos compilar a package. Por padrão, o arquivo DCP é gerado
em um diretório padrão. Este diretório mode ser mudado nas opções do Package na
pasta Directories/Conditionals. Os outros arquivos gerados deverão ficar no diretório
corrente.
Nós vamos agora remover a unit DataMain de nosso projeto. Para isto abra o project
manager e com o botão direito do mouse sobre a unit DataMain escolha a opção
Remove From Project.
164
dtmdlMain := TdtmdlMain.Create(Application);
Devemos também fazer uma referencia a unit DataMain a cláusula Uses do formulário.
E assim nosso sistema volta a funcionar com seu executável menor e com a package em
tempo de execução.
165
Quando você for distribuir sua aplicação é necessário que o Package criado vá junto a
sua aplicação, para isto você deve definir no Delphi a sua package libary (.BLP). Em
“Project Option” (vá ao menu do Delphi Project | Option...) na pasta Packages.
Habilite a opção “Build with runtime packages” para habilitar o botão Add:
166
Clique então no botão Browse para indicar o arquivo .BPL que criamos:
167
168
Introdução
Neste módulo nós vamos discutir como criar e manipular objetos thread em Object
Pascal.
Para entender o que um thread é, nós precisamos primeiro entender como é seu
processo.
O Thread permite que o sistema realize várias tarefas ao mesmo tempo. Por isso
podemos hoje abrir diversos programas no Windows que não há problemas, isso porque
os Threads permitem que a cada milésimo de segundos seja realizado uma operação de
cada vez sem que o usuário perceba e quando mais rápido o computador menos será
visível ao usuário.
Pelo motivo de VCL e outras restições, você é obrigado a ter cuidado ao decidir quais
objetos você precisa criar Thread. Em nossa aplicação nós vamos agora criar um thread
para executar query para atualizar dados em um database. Isso porque dependendo da
quantidade de informações e processos que esta atualização pode realizar pode, com
certeza demorar e precisamos permitir que o usuário realize outras operações enquanto é
realizado estes processos, criando Thread.
Em uma aplicação Delphi, você não deve usar operações thread todo tempo. É preciso
tomar algumas precauções em certas situações. Por exemplo, os VCL não são seguros
para se utilizar thread. O uso de thread em aplicações VCL podem causar diversos erros
de corrupção porque não é seguro sua utilização e pode deixar suas aplicações muito
lentas. A razão para esta lentidão é que VCL não foi desenvolvido pensado-se somente
no Windows mas também no Linux, que não possui as mesmas características do
Windows.
169
Vamos criar um novo objeto thread pelo menu do Delphi File | New... | Threads
Objects. E vamos chamar a “Class Name” de TmonthEndProcThread.
A Classe TThread
170
Em nosso exemplo, nós vamos usar Thread para atualizar a tabela Customer. Para isso,
vamos precisar que no fim do mês nós ajustamos o campo Account_Balance de
Customer uma ajustação mensal na porcentagem para uma especifica nação (país).
Neste exemplo então vamos adicionar um componente SpeedButton ao formulário de
Customer, com a propriedade Name como spdbtnMonth e no evento OnClick do botão
escreva o código a seguir:
171
Bem, devemos agora antes de testar colocar um novo componente querie com o nome
de qryMonthEnd em sua propriedade.
172
A procedure GetNations é usado para pegar uma lista de todas nações em uso para
nossa tabela Customer..
176
Com isto temos a lista de nações, nós vamos atualizar o campo account balance da
tabela Customer. Para isso, nós primeiro temos que criar os códigos para realizar este
update. A procedure GenerateUpdateQuery tem este propósito:
177
Assim quando você executar a aplicação e mandar realizar esta atualização você poderá
facilmente mover ou fazer qualquer outra coisa enquanto é executado esta atualização.
178
O Delphi permite que você crie componentes em tempo de execução, assim como em
tempo de design. Todo componente que você coloca no formulário é criado em tempo
de design, todo o componente que você coloca no formulário que você não tenha
colocado no formulário quando desenvolveu em tempo de design é em run-time (tempo
real). O Delphi permite que você crie componentes dinamicamente se desejar. Neste
capítulo vamos ilustrar com alguns exemplos pequenos sobre como fazer isto e um
exemplo que cria componentes em tempo de execução conforme for a condição.
Para que você entenda melhor este assunto vamos explicar na prática as teorias. Observe
a sintaxe que precisaríamos para criar um componente Timer em tempo de execução:
Onde temos:
Sempre vamos utilizar self quando quisermos criar nossos componentes em tempo de
execução.
Para componentes não visuais (como o componente Timer) você precisa somente
chamar o construtor. Porém para componentes visuais (como um componente de botão)
você precisa definir a propriedade pai7 (Parent).
7
Propriedade pai – Por exemplo, se você colocar um componente Panel em seu formulário ele será o pai
de todos outros componentes que forem anexados a ele, que serão os filhos do Panel. Assim como o pai
do Panel é o formulário.
179
180
Muito bem, criamos o botão, agora precisamos determinar alguma função para ele pois
por enquanto só está sendo apresentado em nosso formulário. Como é um botão que é
181
OnClick := ButtonClick
182
Se rodarmos nossa aplicação, além de ser mostrado o componente se você clicar sobre o
botão será apresentado a mensagem:
Assim você criou sua primeira aplicação com componentes em run-time. Vamos agora
evoluir um pouco mais em nossos estudos e vamos aplicar isto a banco de dados.
Imagine a seguinte situação: Você precisa criar um formulário que mostre somente os
países cadastrados em um banco de dados, sendo estes países botões e você não sabe
183
Para exemplificar, vamos agora criar este exemplo em um novo formulário, com botões
que representem os países cadastrados na tabela de customer. O grid a esquerda lista as
nações achadas na tabela de customer com um total, assim:
Para montar este exemplo você irá adicionar um componente ScrollBox com as
propriedades: Name = scrlbxButtons e Align = alLeft.
Em seguida você deve adicionar dois componentes Query, sendo o primeiro com o
nome de qryNations, a propriedade DatabaseName definir o nosso Alias padrão e na
caixa de edição da propriedade SQL deste componente escrever a seguinte sintaxe:
184
Nesta sintaxe em SQL estou pedindo que faça uma somatória geral do campo
Total_Price de cada nação.
185
Lembro que você deve definir a cláusula uses e a variável publica para habilitar o
evento OnClick de cada componente de botão que será criado:
186
187
188