Вы находитесь на странице: 1из 32

maro 2011

maro 2011

ndice
Banco de Dados

Delphi

Editorial

04

Para quem trabalha com desenvolvimento de sistemas


comerciais, o banco
de dados utilizado
no sistema parte
fundamentall...

05

Intraweb no Delphi XE - Primeiros


Passos

Autor: Antonio Spitaleri

Banco de Dados

Delphi
Crie um preeview customizado e
imprima registros selecionados em
um DBGrid

Apresentando o novo Interbase XE parte 2

Autor:Luciano
Pimenta

Autor: Felipe Santos

16

25

10

Instalando e configurando o SQL


Server 2008
Express Edition
with Tools
Autor:Thiago Cavalheiro
Montebugnoli

Dicas
- Dicas Delphi

28

Legenda
Iniciante
Intermedirio
Avanado
maro 2011

03

Bem-vindo

ara quem trabalha com desenvolvimento de sistemas comerciais, o banco de dados utilizado no sistema parte
fundamental do processo. A escolha do banco deve ser feita
levando-se em conta quais recursos o banco oferece em
confronto com as necessidades do sistema.

Para ajuda-los na escolha de um banco de dados e tambm para mantlos atualizados sobre as novidades dessa rea, temos esse ms dois artigos
sobre bancos de dados:
No primeiro, nosso colaborador, Thiago Montebugnoli, nos traz como
instalar, configurar e comear a usar o Sql Server Express 2008 no artigo:
Instalando e configurando o Sql Server Express Edition 2008 with Tools.
No segundo artigo, Felipe Santos prossegue nos mostrando as novidades
do Interbase XE, no artigo: Apresentando o novo Interbase XE parte 2.
Para quem gosta de se aventurar pelo universo da programao Web,
trago esse ms, no artigo: IntraWeb XE Primeiros Passos, as principais
novidades do framework Intraweb no Delphi XE e tambm como podemos
iniciar no desenvolvimento com Intraweb criando uma aplicao simples
com o mesmo.
Para finalizar, Luciano Pimenta nos mostra como podemos personalizar
e agregar recursos aos previews dos principais geradores de relatrio utilizados com o Delphi no artigo: Crie um preview personalizado e imprima
registros selecionados em um DBGrid.

Av. Prof Celso Ferreira da Silva, 190


Jd. Europa - Avar - SP - CEP 18.707-150
Informaes: (14) 3732-1529
Suporte: (14) 3733-1588

Internet

http://www.theclub.com.br
Cadastro: cadastro@theclub.com.br
Suporte: suporte@theclub.com.br
Informaes: info@theclub.com.br
Skype Cadastro: theclub_cadastro
Skype Suporte: theclub_linha1
theclub_linha2
theclub_linha3

www.twitter.com/theclubbr
Copyright The Club Megazine 2009
Diretor Tcnico
Marcos Csar Silva
Diagramao e Arte
Vitor M. Rodrigues
Reviso
Tassiane Fileto
Colunistas
Antonio Spitaleri Neto
Bruno Alcars
Felipe Santos
Luciano Pimenta
Thiago Cavalheiro Montebugnoli
Impresso e acabamento:

isso. Boa leitura a todos e at o prximo ms!

GRIL - Grfica e Editora


Taquarituba-SP - Tel. (14) 3762-1345

Reproduo
A utilizao, reproduo, apropriao, armazenamento em banco
de dados, sob qualquer forma ou meio, de textos, fotos e outras
criaes intelectuais em cada publicao da revista The Club
Megazine so terminantemente proibidos sem autorizao
escrita dos titulares dos direitos autorais.

Antonio Spitaleri Neto - Editor Chefe


antonio@theclub.com.br
04

maro 2011

Delphi marca registrada da Borland International,


as demais marcas citadas so registradas
pelos seus respectivos proprietrios.

Delphi

Int raw e b
Delphi XE

no

Primeiros Passos
Quem trabalha com desenvolvimento
Delphi est quase sempre envolvido em
programas Desktop, que rodam em mquina
local.
O acesso a banco de dados, embora
possa ser feito de forma remota, no torna
a aplicao algo online, ou seja, acessada
comumente pelos usurios de uma rede em
uma interface nica.
O desenvolvedor Delphi, quando v seu
projeto aumentar em termos de recursos, comea a vislumbrar a possibilidade de coloc-lo
para rodar online, seja em rede local ou at
mesmo internet. Nessas situaes, vem a dvida: Como fazer isso? Como converter minha
aplicao para que ela se torne online?

vamente para trabalhar em ambiente Web, como


Java e PHP. Estas linguagens possuem recursos
especficos para o ambiente da internet.
- No caso de um sistema j pronto, utilizar as
linguagens acima descritas seria invivel, j que
a converso seria mais complexa que um projeto
desenvolvido do zero.
- Desenvolver do zero com uma linguagem
para ambiente Web ento a soluo? uma
hiptese, porm para quem trabalha com Delphi
j h alguns anos, o aprendizado de uma nova
linguagem implica em um gasto de tempo que dever ser investido nesse aprendizado. No ambiente
concorrente do mercado de software, nem sempre
o investimento de tempo em uma nova linguagem
pode ser vivel.

- Como proceder ento?


Para a soluo dessa questo, precisamos
atentar inicialmente para alguns tpicos:
- Existem linguagens que foram criadas nati-

Embora pouco divulgado e at mesmo utilizado pela comunidade Delphi, o Delphi possui
um recurso para desenvolvimento de aplicaes

conhecido como Intraweb.


A tecnologia Intraweb existe h bastante
tempo integrado ao Delphi e permite o desenvolvimento de aplicaes para rodar em ambiente Web.
E o melhor: O desenvolvimento de uma aplicao
Intraweb idntico ao de uma aplicao Desktop
Delphi. Nenhum aprendizado extra de linguagem
necessrio.
Com Intraweb desenvolvemos nossa aplicao
utilizando todos os recursos que normalmente
utilizamos em aplicaes Desktop, com a ressalva
que os componentes visuais temos de utilizar os
componentes especficos para Intraweb presentes
no Delphi.
No Delphi XE, a tecnologia IntraWeb segue
presente nos permitindo criar aplicaes para
Web de forma fcil. Veremos algumas questes
relacionadas ao IntraWeb na sequencia:

-Conexo a banco de dados:

maro 2011

05

O Intraweb suporta todas as formas de conexo existentes no Delphi. Ou seja, no precisamos


alterar nossa forma de trabalho em relao a
conexo com bancos de dados para trabalhar em
Intraweb.

-Acesso de mltiplos usurios aplicao:


O Intraweb em Delphi XE possui em seu framework todas as rotinas para realizar o controle
de vrios usurios em ambiente Web. O desenvolvedor no precisa realizar codificao extra para
controlar mltiplos acessos, pois todo o controle
est embutido no Intraweb.

-Estilos e JavaScript:
Com Intraweb podemos utilizar CSS para
aplicar estilos de formatao a nossas pginas, conseguindo um visual mais profissional e ganhando
em agilidade, j que com CSS necessitamos definir
o arquivo com as configuraes de estilo apenas
uma vez. Quaisquer alteraes que precisarem
ser feitas em relao ao visual das pginas quando
fazemos uso de CSS so realizadas no arquivo de
configurao CSS e automaticamente se aplicaro
a todas as pginas que fizerem uso de um mesmo
arquivo CSS.
Alm do CSS para definir estilos, podemos
tambm incorporar funes JavaScript s nossas
aplicaes Intraweb. Com JavaScript, trazemos
parte da codificao da pgina para o lado cliente,
ganhando em agilidade nas requisies e em alguns
eventos disparados pelo usurio.

necessitarmos rodar nossa aplicao em ambiente


Web e no tivermos acesso aos recursos de outras
linguagens.
Nesse artigo estaremos iniciando no desenvolvimento IntraWeb, criando uma aplicao simples
que ir exibir dados provenientes de um banco de
dados Firebird no browser.

Criando a aplicao:
Inicie o Delphi XE.
Selecione o menu File New Other.
Ser exibida a seguinte tela:
Veja a figura 1.
Na TreeView do lado esquerdo selecione VCL
for the Web, no lado direito, selecione VCL for the
Web Application Wizard.
Ser exibida a tela a seguir:

maro 2011

ISAPI Extension: Gera uma DLL no padro ISAPI.


Dessa forma temos uma aplicao que rodar em
espao compartilhado de memria, ocupando
assim menos memria. Porm algumas verses de
servidores no possuem boa compatibilidade com
esse tipo de aplicao.
Para nosso exemplo escolheremos StandAlone
Application.
- Options:
Aqui definimos se queremos que nossa aplicao Intraweb gerencie conexes ao banco de dados
utilizando pooling. Deixaremos marcada essa opo
em nosso exemplo.

Veja a figura 2.
Nessa tela temos as opes principais para a
criao de nossa aplicao Intraweb:
- Application Type:

O Delphi possui um servidor web interno


para a execuo via IDE dos projetos Intraweb.
Ou seja, em ambiente de desenvolvimento, no
necessrio colocar nossa aplicao em um servidor
Web como Apache ou IIS para testar se tudo est
correto. Basta executar a aplicao da mesma forma como fazemos com as aplicaes Desktop e o
servidor Web de teste integrado ser iniciado para
que possamos ver o resultado de nossa aplicao
no browser.

06

StandAlone Application: Essa forma de aplicao gera um executvel (.exe) Delphi. Possui
maior peso em memria, pois roda em espao
prprio de memria, porm a compatibilidade e
posterior configurao em servidores Web como
o IIS e Apache mais tranquila.

Mos obra!

- Ambiente de testes integrado:

Intraweb uma boa alternativa para quando

Aqui escolhemos o tipo de aplicao que


desejamos, temos as opes:

Figura 1

Em Project Name e Project Directory definimos nome e caminho onde a aplicao ser salva
respectivamente.
Clique em OK. Sero criados os formulrios e a

estrutura bsica de nossa aplicao Intraweb.


Trs units com seus respectivos formulrios
foram criadas:
- Unit1: Essa unit igual unit e seu formulrio
correspondente em uma aplicao Desktop. Ser a
pgina principal de nosso projeto. esse formulrio
que ir aparecer no Browser do usurio quando
ele executar o projeto. Claro que iremos alterar o
nome desse formulrio, para que fique clara qual
a funo dele no projeto. No exemplo, irei alterar
seu nome para MainForm.
-DataModuleUnit: Assim como nas aplicaes
Desktop, o Datamodule o formulrio no visual
que contm os componentes de conexo com
o banco de dados. Como ser o nico em nosso
exemplo, no iremos alterar seu nome.
-UserSessionUnit: O UserSession o formulrio e unit onde colocaremos variveis e funes que
sero exclusivas por instncia para cada usurio.
Um exemplo prtico dessa funcionalidade ser a
criao do DataModule, que ser feita no UserSession e ir garantir que cada usurio tenha sua
conexo com o banco independente dos demais.
Com o UserSession, a administrao de usurios
no IntraWeb bastante tranquila e no exige
codificao complexa.

Figura 2

No MainForm faremos o layout da aplicao


como aparecer para o usurio.
Esse layout dever ficar como na figura a
seguir:
Veja a figura 3.
Veja que temos uma IWLabel da aba IWStandard com o caption: Employees List e um
IWDbGrid da aba IWData.

Criando a conexo com o banco de


dados
Acesse no Delphi o menu View DataExplorer.
Clique com o boto direito sobre o driver Firebird e selecione Add New Connection.
Configure a tela que segue:

Figura 3

Com a conexo criada, clique com o boto


direito sobre a mesma no DataExplorer e selecione
Modify Connection.
Ser apresentada a tela a seguir:
Veja a figura 5.
Em DataBase Name coloque o caminho do
arquivo de banco de dados. Para este exemplo,
estou fazendo uso do banco de dados Employee
maro 2011

07

que acompanha a instalao do Firebird.


UserName e Password no necessitam de alteraes salvo os casos em que a senha do SYSDBA
no servidor Firebird houver sido alterada. Clique
em Ok para salvar a conexo.
No DataModule da aplicao, coloque um componente SqlConnection da aba DBExpress e altere
sua propriedade ConnectionName para EMPLOYEE,
que foi a conexo que criamos a pouco.
Insira ainda no DataModule um componente
SqlDataSet e configure sua propriedade SqlConnection para o SqlConnection inserido anteriormente.
Em sua propriedade CommandText coloque: SELECT * FROM EMPLOYEE.
Insira um componente DataSetProvider da aba
DataAccess e sete sua propriedade DataSet para o
SqlDataSet recm-criado.
Para finalizar a construo do DataModule,
insira um componente ClientDataSet e altere sua
propriedade ProviderName para o DataSetProvider
existente no DataModule.

UserSession
Abra a unit do UserSession.
Nessa unit, a principal codificao a fazer a
sobrescrita de seu construtor para que juntamente
com o UserSession seja criada uma instncia do
DataModule.
Como mencionado anteriormente, o UserSession representa objetos, variveis e funes
exclusivas da instncia de usurio. A criao do
DataModule vinculado ao UserSession garante que
teremos a separao da conexo por usurio.
Veja a codificao da unit do UserSession j
com a criao do DataModule:

unit UserSessionUnit;
{

This is a DataModule
where you can add
components or declare
fields that are specific
to
ONE user. Instead of
creating global variables,
it is better to use this

08

maro 2011

Figura 5

datamodule. You can then


access the it using
UserSession.
}
interface
uses
IWUserSessionBase,
SysUtils,
Classes,DataModuleUnit;
type
TIWUserSession =
class(TIWUserSessionBase)
private
{ Private declarations
}
public
{ Public declarations
}
constructor Create(
AOwner:TComponent);overri
de;
end;
var

DM:TDataModule1;

implementation
{$R *.dfm}
{ TIWUserSession }
// Sobrescrita do
construtor do UserSession
constructor

TIWUserSession.
Create(AOwner:
TComponent);
begin
inherited;
DM:=TDataModule1.
Create(Self);
end;
end.

Abra o design do UserSession e insira nele um


componente DataSource. Ligue este DataSource ao
ClientDataSet existente no DataModule.
Volte ao formulrio principal e ligue o IWDBGrid ao DataSource que inserimos no UserSession.
No se esquea de adicionar na uses do formulrio
principal a unit do UserSession.
Pressione F9 para executar o projeto. Ser
exibida a tela do servidor de testes IntraWeb:

Nessa tela pressione novemente F9 para ver


o projeto em execuo no Browser padro da
mquina.
Veja nosso exemplo em execuo:
Veja a imagem 7.

Concluso
Nesse artigo mostrei a criao e configurao
de um projeto Intraweb.
Como pode ser visto, Intraweb oferece ao
desenvolvedor a possibilidade de criao de
aplicativos on-line de forma fcil e com todas as
caractersticas de uma aplicao Desktop.
Em artigos posteriores estarei mostrando
os demais recursos do Intraweb no Delphi XE,
incluindo o uso de JavaScript e a integrao com
DataSnap.

Ento at a prxima e aproveitem os recursos


do Delphi XE!

Figura 7

Sobre o autor
Antonio Spitaleri Neto
Consultor Tcnico The Club.

antonio@theclub.com.br

maro 2011

09

Instalando e Configurando o
SQL Server 2008 Express Edition
With Tools
Uma breve introduo
Estarei utilizando o Windows Seven Ultimate 32 Bits com todas as
atualizaes crticas instaladas para este artigo.
importante ressaltar que esta verso do SQL Server gratuita e
altamente recomendada para aplicaes de pequeno e mdio porte,
abaixo algumas caractersticas do mesmo:
- um sistema de gerenciamento de dados avanado e confivel;
- Oferece um conjunto rico de recursos para desenvolvimento;
- Proteo aos dados e um alto desempenho para clientes de
aplicativos incorporados e aplicativos da Web;

Neste artigo iremos acompanhar sua instalao junto com o seu gerenciador de Banco de Dados.

Realizando o download
Abaixo esto os programas necessrios em caso da utilizao do Windows
Xp Service Pack 3.
Passo 1: Faa o download e instale o Microsoft Net Framework 3.5 SP1.
http://go.microsoft.com/fwlink/?LinkId=120550
Passo 2: Faa o download e instale o Windows Installer 4.5.
http://go.microsoft.com/fwlink/?LinkId=123422
Passo 3: Faa o download e instale o Windows PowerShell 1.0.
http://support.microsoft.com/kb/926139

- Implantao fcil;
- Custo zero e com liberdade de distribu-lo junto com os aplicativos
desenvolvidos;
- Suporta 1 CPU (com suporte a Multi-Core);

Caso utilize o Windows Seven Ultimate com todas as atualizaes crticas


instaladas ignore esta etapa.
Agora faremos o download do Banco de Dados junto com seu gerenciador
SQL Server Management Studio Express, importante ressaltar que em nosso
caso baixaremos a verso 32 Bits, segue abaixo o link:

- 1GB de RAM e com bases de dados at 4GB;


- Com suporte a rede.

10

maro 2011

http://www.microsoft.com/downloads/details.aspx?FamilyID=7522A683-4CB2-454E-B908-E805E9BD4E28&displayLang=pt-br

Requisitos Necessrios
Sistemas Operacionais Suportados: Windows Seven, Windows Server 2003, Windows
Server 2008, Windows Server 2008 R2, Windows
Vista, Windows XP
Os sistemas de 32 bits - Computador com
processador Intel ou compatvel com 1 GHz ou
processador mais rpido.
Os sistemas de 64 bits Computador com
Processador de 1,4 GHz ou mais rpido.
Mnimo de 512 MB de RAM (2 GB ou mais
recomendado).
2,2 GB de espao disponvel em disco
rgido
Figura 01: Central de Instalao do SQL Server.

Realizando a Instalao
Depois de baixado iremos instalar o mesmo, veremos como simples
a instalao junto com sua configurao. Execute o arquivo SQLEXPRWT_
x86_PTB.exe e veremos a tela conforme a Figura 01.
Veja a figura 1.
Nesta tela escolheremos a opo Instalao e em seguida o primeiro
item, como poderemos ver na Figura 02.
Veja a figura 2.
Esta opo indica para uma instalao de uma nova instancia do SQL
Server, sendo a mesma que iremos utilizar em nosso artigo. A prxima
etapa poder ver na Figura 03.
Veja a imagem 3.

Figura 02: Opo Nova Instalao SQL Server.

Verificamos que no encontramos nenhum problema em nosso


Sistema Operacional, portanto continuemos com a instalao. Clique no
boto Ok e prosseguimos com a tela seguinte, Figura 04.
Veja a imagem 4.
Como estamos trabalhando com a verso gratuita do SQL Server,
no precisamos informar nenhuma chave. Em seguida clique em Avanar.
Figura 05.
Veja a imagem 5.
importante dar uma lida nos termos de Licena para uso, em seguida
clique em Aceito os termos de licena e prosseguiremos com a instalao
clicando no boto Avanar.
Em seguida verificaremos os Arquivos de Suporte instalao, no meu
caso apareceram dois alertas, como podemos ver na imagem 06 abaixo:

Figura 03: Regras de Suporte Instalao.


maro 2011

11

Veja a imagem 6.
O primeiro diz respeito segurana de Aplicativo do Microsoft .NET,
que poderemos resolver facilmente clicando em Status no item Aviso e
Baixando o arquivo solicitado, e o outro alerta est dizendo que o Firewall
do Windows est habilitado (Mais tarde iremos criar excees para
permitir sua conexo em rede). Continuando, clique em avanar. Na tela
abaixo iremos selecionar todos os recursos, mas neste artigo estaremos
abordando apenas o Servio do SQL Server e de seu gerenciador de Banco
de Dados. Em artigos futuros poderemos abordar outros recursos do
mesmo. Confiram a Imagem 07 abaixo.
Veja a imagem 7.
Por Padro o SQL Server instalado no diretrio C:\ Arquivos de
Programas, Clique em avanar para continuarmos a instalao.

Figura 04: Instalao do SQL Server.

Na tela seguinte iremos utilizar as configuraes padres, no caso


do SQL Server a instancia ser criada com o mesmo nome SQLExpress,
esta etapa define o nome pelo qual seu servidor SQL ir responder. Veja
a imagem 08 para melhores detalhes.
Veja a imagem 8.
J no prximo passo o instalador faz a anlise do espao em disco,
no nosso caso o teste foi positivo e passamos assim para outra fase da
instalao que seria a parte para configurao do Servidor. Vejamos na
imagem seguinte.
Veja a imagem 9.
Deixemos as configuraes padres, alterando apenas o Nome da
Conta para AUTORIDADE NT\SISTEMA que estaremos apenas utilizando
em uma mquina como exemplo. importante informar que em casos
onde o seu SQL Server utilizar recursos de rede ser necessrio utilizar
uma conta de domnio.

Figura 05: Termos de Licena.

O prximo passo muito importante, seria onde definiremos a senha para acessar o banco de dados, escolha a opo Modo Misto, que
possibilita autenticao do SQL Server e do Windows, em seguida defina
uma senha e especifique os administradores do mesmo. No nosso caso
clicaremos no boto Adicionar usurio Atual para adicionar o usurio
que est sendo utilizado no momento. As abas Diretrio de Dados e
FileStream deixaremos definidas como padres. Em seguida clique em
avanar para darmos continuidade com a instalao, veja Figura 10.
Veja a imagem 10
A prxima tela da instalao diz respeito aos relatrios de Erro e Uso,
eu sempre deixo marcadas estas opes para a fim de aprimorar futuras
verses do SQL Server. No obrigatrio deixar checado estas opes.
Veja a imagem 11.
12

Figura 06: Regras de suporte instalao.


maro 2011

A Figura 11 representa todas as regras para determinar se o processo


de instalao ser executado com sucesso, no nosso caso todas as regras
foram definidas corretamente. Clique em Avanar e na prxima tela aparecer uma rvore com os recursos do SQL Server 2008 a ser instalado,
clique em avanar novamente para procedermos com a instalao.
A instalao concluir em pouco tempo e apresentar uma tela
parecida com a Figura 12. Prontinho, a instalao do SQL Server 2008
com sua Ferramenta Management Studio foi executada facilmente e sem
nenhum segredo.
Veja a imagem 12.

Configurando o SQL Server para Trabalhar em rede

Figura 07: Seleo de Recursos.

Por padro o SQL Server 2008 vem com a opo para se conectar em
rede desabilitada por motivos de segurana de acesso, fazendo com que
no aceite conexes vindas de outras estaes de uma rede, portanto ao
instal-lo conseguiremos criar uma conexo apenas na estao onde o
mesmo foi instalado.
Para habilitar estas opes devemos seguir alguns passos, vejamos
a seguir.
O SQL Server Configuration Manager o utilitrio responsvel por
gerenciar os servios relacionados s instncias locais do SQL Server e
os protocolos de conexes permitidos. Podemos encontr-lo no item do
menu Ferramentas de Configuraes. Em seguida observaremos algumas
configuraes interessantes, conforme ilustra a Figura 13.

Figura 08: Escolhendo a Instncia SQLExpress.

Figura 13: SQL Server Configuration Manager.

O SQL Server Configuration Manager gerencia trs caractersticas.


- Servios do SQL Server: responsvel por todos os servios relacionados ao Banco de Dados, permitindo Iniciar, Pausar ou Reiniciar o
mesmo. Podemos tambm configurar vrias propriedades destes servios.
No nosso exemplo deixaremos o servio SQL Server e o Navegador do
SQL Server iniciado. recomendvel deixar estes servios para iniciar
automaticamente.
Figura 9: Configurao do Servidor.
maro 2011

13

- Configurao de Rede do SQL Server: Esta opo permite ao


Administrador configurar os protocolos de rede que o SQL Server ir
aceitar, no nosso caso habilitaremos o protocolo TCP/IP.
- Configurao do SQL Native Client 10.0: Define a ordem dos protocolos utilizados pelos clientes que acessam o SQL Server e a criao
de Alias de conexes.
O SQL Express suporta os seguintes protocolos de rede:
Veja a tabela 1.
Voltando ao assunto, para habilitar o protocolo TCP/IP, clique em
Configuraes de Rede/ Protocolos para SQL Express e com o boto
direito escolha Propriedades. Na aba Protocolo deixe Sim para a propriedade Habilitado. Veja Figura 14.

Figura 10: Configuraes do Mecanismo de Banco de Dados.

Figura 14: Propriedades TCP/IP.

Na aba endereos IP, no item IPAll altere o mesmo para porta 1433,
isto far com que esta porta servir para todos os IPs configurados em
seu computador. Caso precise configurar uma porta para apenas um
IP especfico, localize o IP desejado (IP1, IP2, IP3 ...) e siga o mesmo
procedimento. Ver Figura 15.

Figura 15: Endereos IP.


14

Figura 11: Regras de Instalao.

Figura 12: Instalao Concluda.


maro 2011

Faa a mesma configurao para Configurao


do SQL Native Client 10.0.
No esquea que sempre quando feita uma
alterao na configurao do Banco de Dados
necessrio reiniciar os servios relacionados.
Importante: Crie excees no Firewall para permitir a conexo remota do SQL Server, para quem
no sabe, basta entrar no Painel de Controle e no
item Firewall do Windows adicione duas portas, a
1433 como TCP e outra como UDP e a 1434 como
TCP e UDP. Veja na Figura 17 o resultado de nossas
configuraes.

Protocolo de rede

Descrio

Padro

Memria
Compartilhada

Permite conectar a uma instncia do SQL Server Express rodando no


mesmo computador.

Habilitado

TCP/IP

Permite que outras estaes se conectem ao SQL Server Express por es- Desabilitado
pecificar o nome do servidor e o nome da instncia (default SQLExpress)
ou o endereo IP e o nome da instncia.

Pipes Nomeados

Permite que outras estaes se conectem ao SQL Server Express por Desabilitado
suportar vrios protocolos de rede, incluindo NetBEUI, TCP/IP e IPX/SPX.
Ele seleciona o protocolo de rede automaticamente baseado na configurao do cliente.

VIA

Protocolo especfico para redes de sistema. Nesta rede, os dados trafegam Desabilitado
em alta velocidade e so utilizadas para a comunicao entre servidores
e/ou clusters.

Tabela 1

Veja a imagem 16

Utilizando o SQL Server Management


Studio
Para realizar os testes abra o SQL Server Management e coloque o IP ou o nome do servidor e em
seguida o nome da instncia do SQL Server, no meu
caso o IP onde o Banco de Dados est instalado
o 192.168.0.157 e o nome da instncia a SQLExpress. Escolha o tipo de Autenticao do SQL Server
seguido de seu usurio e senha cadastrado quando
fizemos a instalao do mesmo. A Figura 18 ilustra
este procedimento. Pronto, estamos trabalhando
com o Banco de Dados em rede.

Figura 16: Configuraes no Firewall do Windows.

poderosos para manipulao e armazenamento de dados de uma forma rpida e segura. Nos prximos
artigos procurarei abordar outros assuntos relacionados ao SQL Server a fim de poder compartilhar meu
conhecimento com os senhores. Vou ficando por aqui e at o ms que vem.

Fonte de Informaes
http://www.microsoft.com/
Figura 17: Conectar ao Servidor.

Concluso
Vimos neste artigo instalao e configurao
deste poderoso Banco de Dados utilizado por
muitas pequenas e mdias empresas. Foram apresentadas algumas caractersticas e funcionalidades
com intuito de trazer uma gama de informaes
teis aos senhores associados. Apesar de ser uma
verso gratuita no deixa de fornecer recursos

Sobre o autor
Thiago Cavalheiro Montebugnoli
Thiago Cavalheiro Montebugnoli tecnlogo, formado pela Faculdade
de Tecnologia de Botucatu SP (FATEC) foi consultor tcnico do The Club, j
desenvolveu softwares utilizando a plataforma .NET, Delphi junto com Banco
de Dados SQL Server e Firebird. Atualmente trabalha no Centro de Processamento de Dados da Prefeitura Municipal de Ita-SP. Possui as seguintes
certificaes: MCP - Microsoft Certified Professional, MCTS - Microsoft Certified Technology Specialist, MCAD - Microsoft Certified Application Developer
e MCSD - Microsoft Certified Solution Developer.

mateuschies@gmail.com

maro 2011

15

Crie um preeview
customizado e imprima
registros selecionados
em um DBGrid
Vou mostrar nesse artigo, algumas dicas
de geradores de relatrios presentes no Delphi. Veremos dicas de Rave Reports, Quick Report e Report Builder. Primeiramente, vamos
customizar um preeview dos geradores de
relatrios, que na sua verso original possui
vrias opes: navegao entre as pginas,
impresso, configurao de pginas, entre
muitas outras.
Mas muitos desenvolvedores sentem
falta de algumas funcionalidades que no
esto presentes em alguns, como exportao
(PDF, HTML, DOC, TXT etc), pesquisa de textos
entre outras. Veremos ainda nesse artigo,
como imprimir somente os itens selecionados em um DBGrid, demanda muito pedida
pelos clientes.

Preparando o ambiente

geradores que possuo esto disponveis apenas


nessa verso. Mas, tenho certeza que voc pode
usar qualquer verso recente do Delphi ou dos
geradores de relatrios.
Algumas opes podem no estar presentes
em todos os previews, como por exemplo, a exportao, onde para o Quick Report temos apenas
para TXT, CSV e HTML, enquanto o Rave Reports
tem as opes para PDF, HTML, RTF e TXT. J no
Report Builder a exportao para TXT e PDF, e
tambm pode ser feita em mais opes usando
componentes de terceiro.

por mostrar as opes de exportao no Salvar


da barra de ferramentas, onde configuramos a
propriedade DropDownMenu apontando para o
PopupMenu. Adicione um QRPreview da paleta
QReport e altere a propriedade Align para alClient
para que o controle ocupe todo o espao do
formulrio.
Na Figura 1 temos os botes com suas respectivas imagens, bem como todo o layout do
formulrio de preview.

Preview no Quick Report


Vamos criar um projeto no Delphi e salvar o
mesmo em um diretrio de sua preferncia. Crie
um novo formulrio e d o nome de frmPreview e
salve como ufrmPreview.pas. No preview adicione uma Toolbar e uma StatusBar. Na barra, adicione
10 botes para as principais funcionalidades.
Figura 1. Layout do preview

Neste artigo vou usar o Delphi 2010, pois os


16

maro 2011

Adicione um PopupMenu que ser responsvel

Fique a vontade para mudar o layout e coloclo de sua preferncia.

Dica: Voc pode, e eu acredito que


deve, usar um ActionList para concentrar seu
cdigo e propriedades em botes e menus,
e trabalhar por exemplo, com permisses,
sendo mais fcil de desabilitar/habilitar botes e menus.

Aps o layout pronto, vamos ao cdigo. Para


os botes de navegao e de zoom temos o cdigo
da Listagem 1.
Listagem 1. Botes de navegao e zoom do
relatrio do Quick Report

Primeiro
QRPreview1.PageNumber :=
1;
Anterior
QRPreview1.PageNumber :=
QRPreview1.PageNumber - 1;
Prximo
QRPreview1.PageNumber :=
QRPreview1.PageNumber + 1;
ltimo
QRPreview1.PageNumber
:= QRPreview1.QRPrinter.
PageCount;
Mais Zoom
QRPreview1.Zoom :=
QRPreview1.Zoom + 10;
Menos Zoom
QRPreview1.Zoom :=
QRPreview1.Zoom - 10;

usamos o cdigo da Listagem 2.

Listagem 2. Exportando
para HTML e TXT
HTML
QRPreview1.QRPrinter.Expor
tToFilter(TQRGHTMLDocument
Filter.Create(
exportacao.html));
TXT
QRPreview1.QRPrinter.Expor
tToFilter(TQRAsciiExportFi
lter.Create(
exportacao.txt));

Veja que bem simples, onde ainda temos a


possibilidade de exportar para CSV (simplesmente
trocando o parmetro para TQRCommaSeparatedFilter). No cdigo, temos a exportao com
o nome do arquivo, para melhorar, coloque um
SaveDialog e d a opo do usurio escolher o local
onde o arquivo ser salvo.

Mostrando o relatrio no preview

QRPrinter :=
TQRPrinter(Sender);
frmPreview.ShowModal;

No OnPreview instanciamos o formulrio e


repassamos para a propriedade QrPrinter do QRPreview, o relatrio. Para chamar o relatrio, use
o seguinte cdigo:

QuickReport2 :=
TQuickReport2.
Create(self);
try
QuickReport2.
PreviewModal;
finally
QuickReport2.Free;
end;

Note que precisamos chamar o mtodo PreviewModal no lugar o Preview. Execute o projeto e
veja como na Figura 2 o preview do Quick Report.
Veja a figura 2.

Para finalizar, precisamos exibir o relatrio do


Quick Report no preview criado. Para isso, abra
o relatrio e no evento OnPreview do mesmo e
adicione o seguinte cdigo:

uses QRPrntr, ufrmPreview;


...
frmPreview := TfrmPreview.
Create(Application);
frmPreview.QRPreview1.

Ainda precisamos coloca o seguinte cdigo


no evento OnClose do formulrio do preview para
liberar o mesmo da memria, assim no teremos
mensagem de erro quando tentar chamar o relatrio pela segunda vez:

Action := caFree;
frmPreview := nil;

Acredito que o cdigo simples e de fcil


entendimento. Para imprimir o relatrio, o cdigo
mais simples ainda, onde precisamos apenas
chamar QRPrinter.Print do QRPreview:

QRPreview1.QRPrinter.
Print;

Agora vamos as opes de exportao, incluindo no formulrio os componentes QRTextFilter


e QRHTMLFilter. Para exportar, simplesmente

Figura 2. Relatrio do Quick Report no preview


maro 2011

17

Nota: a verso do Quick Report que


acompanha o Delphi em verses anteriores
possui poucas funcionalidades no preeview.
Verses profissionais, j possuem funcionalidades a mais em seu preeview, como veremos
mais adiante neste artigo.

Preview no Rave Reports


Para o Rave Reports o formulrio de preview
pode ter os mesmos botes, mas para a exportao
teremos duas opes a mais: PDF e DOC. Ento
crie um novo formulrio, adicione os mesmos
componentes, apenas trocando o QRPreview por
RvRenderPreview e os componentes de exportao: RvRenderPDF, RvRenderHTML, RvRenderRTF
e RvRenderText.
O RvRenderPreview mostra o relatrio, utilizando um ScrollBox, portanto adicione um ao formulrio (altere a propriedade Align para alClient) e
faa a vinculao atravs da propriedade ScrollBox
do RvRenderPreview. Para os botes de navegao
e zoom, use o cdigo da Listagem 3.
Listagem 3. Botes de navegao e zoom do
relatrio do Rave

Primeiro
RvRenderPreview1.
RenderPage(1);
Anterior
RvRenderPreview1.
PrevPage;
Prximo
RvRenderPreview1.
NextPage;
ltimo
RvRenderPreview1.
RenderPage
(RvRenderPreview1.
LastPage);
Mais Zoom
RvRenderPreview1.ZoomIn;
Menos Zoom
RvRenderPreview1.
ZoomOut;

A diferena em relao ao Quick Report esta


nos nomes dos mtodos, pois a funcionalidade a
18

maro 2011

mesma. Para a exportao, adicione um RvNDRWriter ao formulrio e digite o cdigo da Listagem 4


nos respectivos botes, responsvel pela exportao do relatrio.
Listagem 4. Exportando relatrios no Rave
Reports

HTML
RvRenderHTML1.
PrintRender(RvNDRWriter1.
Stream, arquivo.html);
DOC
RvRenderRTF1.
PrintRender(RvNDRWriter1.
Stream, arquivo.rtf);
PDF
RvRenderPDF1.
PrintRender(RvNDRWriter1.
Stream, arquivo.pdf);
TXT
RvRenderText1.
PrintRender(RvNDRWriter1.
Stream, arquivo.txt);

Tambm podemos dar a opo para o usurio escolher o nome do arquivo e diretrio. Para
impresso do relatrio precisamos adicionar um
RvRenderPrinter e um RvNDRWriter ao formulrio e adicionar o seguinte cdigo no boto de
imprimir:

RvRenderPrinter1.
Render(RvNDRWriter1.
Stream);

Para visualizar o relatrio do Rave no preview,


vamos adicionar o cdigo da Listagem 5, que subscreve o construtor do formulrio:

begin
inherited
Create(AOWner);
RvNDRWriter1.Stream :=
Relatorio;
RvRenderPreview1.
Render(RvNDRWriter1.
Stream);
end;

O cdigo, recebe como parmetro um TMemoryStream que ser repassado para a propriedade
Stream do RvNRDWrite. Aps, o RvRenderPreview
mostra o relatrio chamando o Render, passando
como parmetro o stream do RvNDRWriter.
Para finalizar, precisamos criar um relatrio no
Rave Reports. Aps criar o mesmo, no formulrio
para chamar o relatrio, adicione um RvProject
(vinculado ao arquivo de projeto RAV) e um RvNDRWriter, vinculando a propriedade Engine do
RvProject com o RvNDRWriter1.
Aps, use o cdigo da Listagem 6 para abrir o
formulrio de preview com o relatrio.
Listagem 6. Chamando o preview para o Rave
Reports

var
stream: TMemoryStream;
begin
stream := TMemoryStream.
Create;
RvNDRWriter1.StreamMode
:= smUser;
RvNDRWriter1.Stream :=
stream;

Listagem 5. Cdigo para exibir o relatrio

RvProject1.
ExecuteReport(Report1);
frmPreview :=
TfrmPreview.Create(Self,
stream);

constructor Create(AOWner:
TComponent; Relatorio:
TMemoryStream);
reintroduce;
...
constructor TfrmPreview.
Create(AOWner: TComponent;
Relatorio: TMemoryStream);

try
frmPreview.ShowModal;
finally
frmPreview.Release;
frmPreview := nil;
end;
end;

No cdigo anterior, criamos uma varivel do


tipo TMemoryStream que preenche a propriedade
Stream do RvNDRWriter e ser passada como parmetro no construtor do formulrio do preview.
Ao rodar a aplicao, temos o relatrio do Rave
no nosso preview (Figura 3) com as opes de
exportao.
Veja a figura 3.

Preview no Report Builder


Novamente, o formulrio de preview para
o Report Builder pode ter os mesmos botes,
onde modificaremos apenas alguns componentes. Voc pode baixar uma verso trial do Report
Builder no endereo www.digital-metaphors.com/
download.
Neste exemplo, usaremos a verso Enterprise
12.03 para Delphi 2010, mas temos suporte para
praticamente todas as verses do Delphi. Aps baixar, instale e crie um novo projeto no Delphi, onde
podemos verificar os componentes adicionados na
paleta RBuilder (Figura 4).

Figura 3. Exibindo relatrio do Rave no preview

Primeiro
ppViewer1.FirstPage
Anterior
ppViewer1.PriorPage;
Prximo
ppViewer1.NextPage;
ltimo
ppViewer1.LastPage;
Mais Zoom
ppViewer1.ZoomPercentage
:= ppViewer1.
ZoomPercentage + 10;
Menos Zoom
ppViewer1.ZoomPercentage
:= ppViewer1.
ZoomPercentage - 10;

TComponent; aReport; out


appReport: TppReport);
reintroduce;
...
constructor TfrmPreview.
Create(AOWner: TComponent;
out appReport: TppReport);
begin
inherited
Create(AOWner);
aReport := appReport;
ppViewer1.Report :=
appReport;
appReport.
PrintToDevices;
end;

Para imprimir o relatrio, precisamos simplesmente usar o seguinte cdigo:

O cdigo preenche uma varivel declarada


na seo private do formulrio, que ser usada na
exportao, e repassa o ppReport passado como
parmetro, para o ppViewer. A seguir, chamamos
o PrintToDevices para mostrar o relatrio.

ppViewer1.Print;

Figura 4. Componentes do Report Builder instalados


no Delphi

No formulrio de preview, adicione um


ppViewer e um ppDesigner. Altere a propriedade
Align para alClient do ppViewer. Novamente para
os botes de navegao e zoom temos o cdigo
da Listagem 7.
Listagem 7. Botes de navegao e zoom do
relatrio do Report Builder

Para visualizar o relatrio, vamos novamente


subscrever o Create do formulrio, usando o cdigo
da Listagem 8.
Listagem 8. Cdigo para abrir o relatrio no
Report Builder

uses ppReport;
...
constructor Create(AOWner:

Para a exportao, vamos usar o cdigo da


Listagem 9 onde temos a opo para texto e PDF.
Listagem 9. Exportao para o Report Builder

Arquivo Texto
with aReport do
begin
AllowPrintToFile :=
True;
DeviceType :=

maro 2011

19

dtTextFile;
TextFileName :=
arquivo.txt;
Print;
end;
PDF
with aReport do
begin
AllowPrintToFile :=
True;
DeviceType := dtPDF;
TextFileName :=
arquivo.pdf;
Print;
end;

O Report Builder apresenta uma tela de impresso (Figura 5), pois usamos a propriedade AllowPrintToFile configurada como True. Isso facilita a
vida do usurio, pois ele pode configurar nome e
diretrio para o arquivo de exportao.
Veja a figura 5.
Existe um componente de terceiro (TExtraDevice) que exporta relatrios para Excel, HTML, RTF,
entre outras. Para finalizar, precisamos criar um
relatrio no Report Builder. Aps criar o mesmo,
no formulrio para chamar o relatrio, use o cdigo
da Listagem 10.

Figura 5. Tela de impresso do Report Builder

Execute o projeto e veja na Figura 6 como deve


ficar o projeto onde temos o arquivo de exportao
no formato PDF.

jeto necessita do reaproveitamento dos mesmos,


seno teremos uma quantidade muito grande de
arquivos onde os dados apresentados podem ser
os mesmos.

Veja a figura 6.

Imprimindo registros selecionados


A grande utilizao de relatrios em um pro-

Um exemplo: um relatrio onde constam parcelas das vendas do seu cliente. Ele precisa verificar
em situaes diferentes as parcelas pagas, no pagas, vencidas, h vencer etc. se voc imaginou fazer

Listagem 10. Chamando o preview do Report


Builder

frmPreview := TfrmPreview.
Create(Self, ppReport1);
try
frmPreview.ShowModal;
finally
frmPreview.Free;
end;

No cdigo, o formulrio de preview recebe


como parmetro um ppReport, componente
responsvel pela criao do relatrio. Os relatrios do Report Builder podem ser gerados como
arquivos externos (com a extenso RTM), ento
possvel adaptar o preview para carregar os
arquivos externos, passando como parmetro o
nome do mesmo.
Figura 6. Exibindo e exportando relatrios do Report Builder
20

maro 2011

um relatrio apenas e filtrar os dados no banco de


acordo com a necessidade, esta meio certo.
Mas sua consulta vai mudar de acordo com a
opo desejada e assim, ter consultas ao banco
desnecessrias. O que fazer? Simples, vamos fazer
um relatrio apenas, retornando todas as parcelas
(claro, usando outro filtro, como por exemplo, um
perodo de datas) e filtrando os dados de acordo
com a opo.
Ficou curioso como fazer? Ento vamos aprender isso e muito mais neste artigo.

Figura 7. Relatrio no Quick Report

Filtrando parcelas
Primeiramente, faremos o exemplo citado anteriormente, no Quick Report. Usei aqui um banco
de dados criado por mim, que estar disponvel
para download.
Nossa consulta retornar as parcelas de acordo
com o perodo, independente do campo PAGO, que
indica se a mesma esta paga ou no. Nossas opes
de filtragem sero: Pagas (PAGO = T), No Pagas
(PAGO = F), Vencidas (parcelas no pagas at a
data atual), h vencer (parcelas no pagas acima
da data atual).

:DATAFIM

and PA.STATUS
= A
order by PA.DATA_
VENCIMENTO, CO.NR_
CONTRATO, PA.NR_PARCELA

Configure os parmetros no componente.


Nossa consulta esta pronta, ento precisamos criar
o relatrio. Crie um relatrio no Quick Report com
a consulta, usando o layout da Figura 7.
Veja a figura 7.

A consulta pelo perodo vai se basear pelo


campo DATA_LANCAMENTO. No Delphi, crie um
novo projeto (ou utilize o que estamos usando),
e crie a consulta ao banco de dados, que ter o
comando SQL da Listagem 11.

Para testar o relatrio, vamos criar um novo


formulrio e adicionar os controles, conforme a
Figura 8.

Listagem 11. Comando SQL da consulta


select
PA.ID_PARCELA, CO.NR_
CONTRATO, CL.CLIENTE,
PA.NR_PARCELA,
PA.DATA_VENCIMENTO,
PA.VALOR_PARCELA, PA.PAGO
from PARCELAS PA
inner join CLIENTES CL
on (PA.ID_CLIENTE = CL.ID_
CLIENTE)
inner join CONTRATO
CO on (PA.ID_CONTRATO =
CO.ID_CONTRATO)
where
PA.DATA_LANCAMENTO
between :DATAINI and

Figura 8. Formulrio de filtragem de dados

No Data Module, vamos criar uma procedure


que ir filtrar o nosso ClientDataSet que retorna os
dados da consulta. Uso o cdigo da Listagem 12.
Listagem 12. Procedure para filtrar os dados

procedure TDM.
Filtrar(dtInicio, dtFim:
TDateTime);
begin
cdsConsulta.Close;
cdsConsulta.Params[0].
AsDate := dtInicio;
cdsConsulta.Params[1].
AsDate := dtFim;
cdsConsulta.Open;
end;

Voltando ao formulrio de filtros, adicione o


cdigo da Listagem 13 para o boto Relatrio. Adicione no uses a unit do Data Module e relatrio.
Listagem 13. Chamada ao relatrio

//verifica se escolheu um
item
if RadioGroup1.ItemIndex =
-1 then

MessageDlg(Escolha uma
opo de Filtro, mtError,
[mbok], 0)
else
begin

//filtra a
consulta
DM.Filtrar(dtInicial.
Date, dtFinal.Date);
try
frmRelatorioConsulta
:= TfrmRelatorioConsulta.
Create(nil);
frmRelatorioConsulta.
QuickRep1.Preview;

maro 2011

21

finally
frmRelatorioConsulta.
Free;
end;
end;

Nota: dtInicial e dtFinal so controles


DateTimePicker colocados no formulrio.

Caso deseje testar, coloque o Data Module


como primeiro formulrio a ser criado, a seguir o
formulrio de filtragem. At o momento, nossos
dados estaro apenas sendo filtrado pela consulta
principal (Listagem 11).
Para que possamos implementar a filtragem de
acordo com as opes, adicione uma varivel pblica no formulrio do relatrio chamada iIndex, do
tipo integer. Passaremos para esse varivel a opo
escolhida no RadioGroup.

2: PrintBand :=
(QuickRep1.DataSet.
FieldByName(PAGO).
AsString = F) and
(QuickRep1.DataSet.
FieldByName(DATA_
VENCIMENTO).AsDateTime <
Date);
3: PrintBand :=
(QuickRep1.DataSet.
FieldByName(PAGO).
AsString = F) and
(QuickRep1.DataSet.
FieldByName(DATA_
VENCIMENTO).AsDateTime >
Date);
end;

Veja como simples filtrarmos os dados, basta


configurar corretamente o parmetro, usando o valor dos campos que temos vinculados ao relatrio.
Neste exemplo, usei a propriedade DataSource do
relatrio, mas poderamos utilizar diretamente o
controle do Data Module, por exemplo.

Faa os testes para as vrias opes de filtragem (Figura 9).


Veja a figura 9.

Rave Reports
Para o Rave, vamos usar a mesma consulta.
Primeiramente, crie um relatrio no Rave (vamos
colocar os componentes no Data Module). O layout
do mesmo deve se parecer com a Figura 10.
Veja a figura 10.
Para a consulta ser mostrada no relatrio, devemos adicionar um RvDataSetConnection e ligar
sua propriedade DataSet com o cdsConsulta. Faa
a ligao do controle com o relatrio (DataViews)
para exibir os dados.

Nota: Caso exista alguma dvida em


relao a conexo de dados em relatrios
do Rave, sugiro uma pesquisa no site da
Nevrona (fabricante do Rave) ou na internet

Na chamada ao relatrio, modifique o cdigo para repassar o valor do RadioGroup para a


varivel:
frmRelatorioConsulta.
iIndex := RadioGroup1.
ItemIndex;

Agora a parte principal do nosso exemplo,


onde vamos filtrar os dados da consulta, de acordo com a opo escolhida. Toda a mgica esta no
evento BeforedPrint da banda Detail. Nela temos
um parmetro chamado PrintBand do tipo boolean,
que indica se o item que esta sendo impresso,
deve ser impresso.
Assim, com o valor que temos da varivel (iIndex), podemos filtrar os dados. No referido evento,
utilize o cdigo da Listagem 14.
Listagem 14. Filtrando os dados
case iIndex of
0: PrintBand :=
(QuickRep1.DataSet.
FieldByName(PAGO).
AsString = T);
1: PrintBand :=
(QuickRep1.DataSet.
FieldByName(PAGO).
AsString = F);
22

maro 2011

Figura 9. Opes de filtragem do relatrio, sem mudar a consulta ao banco

sobre o assunto.
Aps configurar o relatrio, modifique a
chamada ao relatrio do Quick, no formulrio de
filtragem com o seguinte cdigo:

DM.iIndex := RadioGroup1.
ItemIndex;
DM.Filtrar(dtInicial.Date,
dtFinal.Date);
DM.RvProject1.Execute;

Veja que temos uma varivel pblica no Data


Module que recebe o valor do RadioGroup. Por que
fazemos isso? Por que o responsvel por filtrar os
dados esta no Data Module, o RvDataSetConnection. No evento ValidateRow do controle, vamos
fazer algo semelhante ao exemplo anterior. Veja o
cdigo na Listagem 15.
Listagem 15. Filtrando os dados para o Rave
Reports
case iIndex of
0: ValidRow :=
cdsConsultaPAGO.AsString =
T;
1: ValidRow :=
cdsConsultaPAGO.AsString =
F;
2: ValidRow :=
(cdsConsultaPAGO.AsString
= F) and
(cdsConsultaDATA_
VENCIMENTO.AsDateTime <
Date);
3: ValidRow :=
(cdsConsultaPAGO.AsString
= F) and
(cdsConsultaDATA_
VENCIMENTO.AsDateTime >
Date);
end;

Figura 10. Relatrio no Rave

relatrio os itens selecionados. O exemplo continua


bem simples, usaremos praticamente a mesma
tcnica anterior, com apenas uma modificao
em seu cdigo.
Crie uma consulta (pode se usada a mesma)
e mostre-a em um DBGrid. Altere as seguintes
propriedades do DBGrid:
Options>dgRowSelection =
True
Options>
dgAlwaysRowSelection =
True
Options>dgMultiSelect =
True

Crie um novo relatrio no Quick Report,


usando a consulta anterior. No mesmo evento do
exemplo anterior, vamos repassar para o parmetro PrintBand apenas os registros selecionados no
Grid, usando o seguinte cdigo (adicione no uses
do relatrio a unit do formulrio):

PrintBand :=
frmSelecionar.
DBGrid1.SelectedRows.
CurrentRowSelected;

Estamos indicando assim, que queremos

Cdigo bastante semelhante ao do exemplo do


Quick Report, ficando a diferena que acessamos
diretamente o Field no ClientDataSet. Faa os testes
e verifique as filtragens (Figura 11).
Veja a figura 11.

Imprimindo registros selecionados em


um DBGrid
Esse exemplo bastante interessante. Imagine
que voc possa dar ao seu usurio a possibilidade
de escolher itens em um DBGrid e imprimir em um

Figura 11. Aplicando o exemplo de filtragem no Rave


maro 2011

23

imprimir apenas os registros que esta marcados


no DBGrid. Para o teste, rode a aplicao, marque
alguns itens no DBGrid (utilizando a tecla CRTL) e
chame o relatrio (Figura 12).
Veja a figura 12.
Para o exemplo em Rave, a idia a mesma,
ento crie um novo relatrio e no cdigo para
filtrar os registros selecionados do DBGrid, use o
seguinte cdigo:

ValidRow := frmSelecionar.
DBGrid1.SelectedRows.
CurrentRowSelected;

Neste exemplo didtico, usamos a unit de um


formulrio no Data Module, o que no correto.
Em uma aplicao real, voc pode passar como
parmetro, usar variveis etc. Veja na Figura 13 o
relatrio em execuo no Rave.

Figura 12. Imprimindo apenas os registros selecionados

Veja a figura 13.

Concluso
Vimos neste artigo como criar um preview para
os geradores de relatrios mais usados pelos desenvolvedores Delphi. Algumas funcionalidades a mais
podem ser implementadas para alguns geradores,
como navegar para uma determinada pgina informada pelo usurio, formulrio de impresso, onde
o usurio indica a quantidade de cpias etc.
Lembrando que no usamos o StatusBar onde
podemos colocar o total de pginas, nome do relatrio, entre outras informaes. Fica a motivao
para voc implementar muitas funcionalidades
legais no preview. Se voc quiser disponibilizar
suas alteraes para a comunidade, envie para
mim que publicarei no meu site para que todos
possam aprender.
Vimos tambm como simples de filtrar dados
em relatrios do Rave ou Quick, sem a necessidade
de realizarmos vrias consultas ao banco de dados,
ganhando assim, agilidade e performance a aplicao. Tambm podemos deixar o usurio escolher
os registros de uma consulta e imprimir o mesmo,
adicionando assim valor ao seu projeto.
Um grande abrao a todos e sucesso em seus
projetos!

24

maro 2011

Figura 13. Imprimindo os registros selecionados no Rave

Sobre o autor
Luciano Pimenta
Tcnico em Processamento de Dados, desenvolvedor Delphi/C# para aplicaes
Web com ASP.NET e Windows com Win32 e Windows Forms. Palestrante da 4 edio
da Borland Conference (BorCon).
Autor de mais de 60 artigos e de mais de 300 vdeos aulas publicadas em revistas
e sites especializados. consultor da FP2 Tecnologia (www.fp2.com.br) onde ministra
cursos de programao e banco de dados. desenvolvedor da Paradigma Web Bussiness em Florianpolis-SC.

www.lucianopimenta.net

A P R E S E N TA N D O O
NOVO INTERBASE XE
PARTE 2

Ol pessoal,
Voltamos com a segunda parte da
apresentao do novo InterBase XE. Quero
antes aproveitar essa introduo do artigo
para exaltar o sucesso dessa nova verso do
InterBase. A apresentao durante a Delphi
Conference 2010 foi um sucesso e a procura
pelo produto est fantstica. Isso realmente
mostra que o novo InterBase XE est se tornando um marco na j brilhante histria desse
nosso banco de dados. Em breve o material
da apresentao estar disponvel no site da
Embarcadero (http://edn.embarcadero.com).
Vale a pena conferir.
Pois bem, nessa edio vamos dar continuidade na apresentao do produto. No
artigo anterior ns falamos sobre o suporte
plataforma 64 bits, sobre a ampliao da
capacidade de gerenciamento de memria,
sobre o suporte tecnologia de Cloud Computing e sobre o aperfeioamento na segurana
do produto atravs do Strong Encryption
Password. Agora vamos mostrar em detalhes

outro recurso muito legal do novo InterBase


XE, uma melhoria no suporte linguagem
SQL: o suporte ao comando DML EXECUTE
STATEMENT.
Apesar de j suportado por outros bancos
de dados h um bom tempo, esse comando
disponibilizado no InterBase veio em boa
hora. O EXECUTE STATEMENT permite a ns
desenvolvedores ampliar e explorar mais
ainda os recursos de programao nativa no
banco, incrementando nossas Stored Procedures e facilitando nossa vida em muitas
situaes. Detalhando:

O COMANDO EXECUTE STATEMENT


O comando DML Execute Statement permite a
chamada de outro comando DML ou DDL dentro de
um cdigo de uma Stored Procedure. Esse recurso
muito til, pois podemos condicionar a execuo
de um determinado comando SQL dentro de nossa
programao procedural. Particularmente penso
que sua execuo se faz bem mais interessante,

principalmente pela possibilidade de manipular


estruturas de banco de dados dentro de uma
procedure. Veremos um exemplo dessa situao
mais adiante.
O comando Execute Statement pode ser executado em trs condies distintas:

Quando nenhuma linha de resposta
retornada do comando;

Retornando uma nica linha de resposta
do comando;

Retornando mltiplas linhas de resposta
do comando.
Em cada uma das situaes veremos combinaes e exemplos de aplicao do comando.
Algumas consideraes sobre o uso do Execute
Statement:
1. O comando Execute Statement s pode
ser utilizado dentro de Stored Procedures;
2. preciso que tanto o Servidor quando os Clientes estejam atualizados com o novo
maro 2011

25

InterBase XE. Se o servidor for InterBase XE e os


clientes estiverem utilizando uma verso antiga da
DLL cliente GDS32.DLL, o comando poder retornar
erro;
3. importante ressaltar que para rodar
essa Stored Procedure adequadamente, nossos
bancos de dados devem estar compatveis com
a verso InterBase XE (ODS 15.0). Alm disso, a
interface SQL utilizada, seja o IBConsole, IBExpert
ou qualquer outra, tambm deve estar compatvel
com o InterBase XE. At o momento, a ltima
verso do IBExpert, por exemplo, no estava totalmente compatvel. Ao tentar criar a Stored Procedure acima ocorre um erro: Parsin Error. Porm
o a Stored Procedure criada normalmente e seu
contedo tambm funciona. Utilizando o IBConsole
atualizado com a ltima verso, o problema no
ocorre.

LINHA DE RETORNO
comum a situao onde precisamos enviar
para nossos clientes um script de atualizao da
estrutura do banco de dados. Criamos tabelas, alteramos campos, criamos ndices, enfim. O normal
nessa situao prepararmos um script contendo
todas as alteraes necessrias e enviamos para
nossos clientes. Legal. Mas certamente voc j
deve ter encontrado a situao onde o cliente vai
rodar esse script e retorna erro, pois a estrutura
que desejamos criar j existe no banco de dados
ou queremos dropar algo que no existe mais na
base do cliente. Agora com o Execute Statement
podemos criar uma procedure que verifique antes
a existncia da estrutura que desejamos alterar/
incluir/excluir e ento executamos o comando
desejado.
Vamos ver um exemplo onde queremos incluir
uma nova coluna em determinada tabela, mas
queremos antes verificar se essa coluna j existe
ou no:

Imagem 1 Mensagem de erro quando executamos


o comando Execute Statement via IBExpert.

4. A performance do comando executado


pelo Execute Statement afetar diretamente a
execuo da prpria procedure associada. Assim
devemos ter a ateno para que esse comando no
penalize a execuo do restante da procedure que
venha a ser executado aps o Execute Statement;
5. Quando executvamos comandos
DML, como um Select, Update ou Delete, dentro
da Stored Procedure, o InterBase gravava o plano
de pesquisa e execuo do DML ao compilarmos a
procedure. Assim corramos o risco, por exemplo,
de uma query executada por uma procedure no
ter uma performance to interessante, pois essa
query poderia ter associado um ndice de busca no
adequado quando a procedure foi compilada. Esse
problema no acontece com o comando Execute
Statement. Ele identifica o melhor ndice de busca
cada execuo, tornando o processo mais limpo
e eficiente;
6. Ao compilar uma procedure que contm
um Execute Statement, caso o comando executado
pelo Execute Statement viole alguma Constraint
definida, essa violao no ser validada. A Exception de erro s ser apresentada no momento da
execuo do Execute Statement.

EXECUTE STATEMENT SEM NENHUMA


26

maro 2011

SET TERM ^ ;
CREATE PROCEDURE SP_
VALIDA_DDL (
v_table varchar(67)
character set none,
v_column varchar(67)
character set none,
v_type varchar(16)
character set none)
as
declare variable norows
integer;
declare variable qry
varchar(200);
begin
Select count(*) from
rdb$relation_fields r
where r.rdb$relation_
name= upper(:v_table) and
r.rdb$field_name =
upper(:v_column)
into :norows;
if (norows = 0) then
begin
QRY = ALTER TABLE
|| :V_TABLE || ADD ||
:V_COLUMN ||
|| :V_TYPE
;
EXECUTE STATEMENT QRY;
end
end^
SET TERM ; ^

Nesse exemplo criamos uma Stored Procedure


Chamada SP_VALIDA_DDL com trs parmetros
de entrada:
1.

O nome da tabela que desejamos alte-

rar
2. O nome da coluna que desejamos
acrescentar
3. O tipo da nova coluna que desejamos
acrescentar.
E o texto da procedure bem simples. Primeiramente verificamos se a coluna informada
existe na tabela informada. Para isso executamos
uma query na tabela RDB$RELATION_FIELDS, que
armazena todos os relacionamentos entre campos
e tabelas.
Caso a consulte no retorne qualquer resultado (norows = 0), significa que a coluna no existe
na tabela. Agora podemos montar um comando
DDL para criar a coluna.
Esse passo indicado logo abaixo, quando a
varivel QRY recebe o comando DDL da criao do
campo informado na tabela informada, conforme
o datatype informado.
E por fim, executamos o comando EXECUTE
STATEMENT QRY, fazendo rodar o comando DDL
passado atravs da varivel QRY.
Um exemplo de chamada da Stored Procedure
acima pode ser:

EXECUTE SP_VALIDA_DDL(T_
ESTADO,SIGLA,CHAR(2));

Nesse exemplo estamos tentando criar uma


nova coluna SIGLA na tabela T_ESTADO tipo
CHAR(2). Usando a tcnica do Execute Statement,
essa coluna ser criada somente se a mesma j no
existir na tabela referenciada, no retornando erro
quando ela j existir.

EXECUTE STATEMENT COM UMA NICA LINHA DE RETORNO


Outra situao interessante para o uso do
comando Execute Statement quando precisamos
extrair uma determinada informao, como por
exemplo, o ltimo cdigo sequencial de um campo
chave de uma determinada tabela, mas justamente

no sabemos ao certo o nome da tabela. Essa deciso pode vir no momento de execuo. Vejamos
o exemplo abaixo:

SET TERM ^ ;
CREATE PROCEDURE SP_MAXCOD
(
TABLE_NAME
VARCHAR(50),
FIELD_NAME
VARCHAR(50))
RETURNS (
MAXNO INTEGER)
AS
DECLARE VARIABLE QRY
VARCHAR(200);
BEGIN
QRY = SELECT MAX( ||
:FIELD_NAME || ) FROM ||
:TABLE_NAME ;
EXECUTE STATEMENT QRY INTO
:MAXNO;
SUSPEND;
END^
SET TERM ; ^

No exemplo acima, criamos uma Stored Procedure chamada SP_MAXCOD que recebe como
parmetros de entrada o nome de uma tabela e o
nome de uma coluna, retornando como resultado
o valor mximo encontrado na coluna informada
para a tabela informada. Podemos assim utilizar
essa informao para identificar o prximo valor
para utilizarmos no campo ou como parte de um
clculo de uma validao, enfim, chamar essa
Stored Procedure como parte de outras Stored
Procedures ou Triggers e ter de maneira dinmica
a informao.
Um exemplo de chamada da Stored Procedure
acima pode ser:

EXECUTE SP_MAXCOD(T_
FUNCIONARIO,COD_FUNC);

maior valor do campo COD_CLIENTE encontrado


na tabela T_CLIENTE. E assim por diante.

EXECUTE STATEMENT COM MLTIPLAS LINHAS DE RETORNO


Mais uma possibilidade de uso do comando
Execute Statement. comum encontrarmos bancos
de dados com tabelas distintas para clientes do
tipo Pessoa Fsica e Jurdica. Ou mesmo tabelas
separadas para Clientes e Fornecedores. Pois
bem, utilizando o recurso do Execute Statement,
podemos criar uma procedure que nos retorne informaes relativas a clientes, mas informando em
tempo de execuo, sobre qual tabela queremos
as informaes:

SET TERM ^ ;
CREATE PROCEDURE SP_DADOS_
CLIENTE (
TABLE_NAME VARCHAR(50)
CHARACTER SET NONE)
RETURNS (
COD_CLIENTE INTEGER,
NOME_RAZAO
VARCHAR(50),
CPF_CNPJ VARCHAR(14),
ENDERECO VARCHAR(60),
TELEFONE VARCHAR(12)
)
AS
DECLARE VARIABLE QRY
VARCHAR(200);
BEGIN
QRY = SELECT COD_CLIENTE,
RAZNOME, CPFCNPJ, END, TEL
FROM || :TABLE_NAME ;
FOR EXECUTE STATEMENT QRY
INTO
:COD_CLIENTE,
:NOME_RAZAO, :CPF_CNPJ,
:ENDERECO, :TELEFONE;
DO
SUSPEND;
END^
SET TERM ; ^

Nesse exemplo a procedure retornar o maior


valor do campo COD_FUNC encontrado na tabela
T_FUNCIONARIO.

EXECUTE SP_MAXCOD(T_
CLIENTE,COD_CLIENTE);

J nesse exemplo a procedure retornar o

No exemplo acima criamos uma Stored Procedure chamada SP_DADOS_CLIENTE que nos
retornar alguns campos comuns encontrados
em tabelas de clientes Cdigo do cliente, Razo
Social, CPF ou CNPJ, Endereo, Telefone, enfim.
Poderamos muito bem executar diretamente a
query de Select para obter essas informaes.

Mas utilizando o recurso do Execute Statement,


podemos informar como parmetro de entrada na
Stored Procedure, sobre qual tabela iremos rodar a
query (indicado pelo parmetro TABLE_NAME).
Esse recurso nos da a liberdade de, por exemplo, trabalhar como parte de outra Stored Procedure que, dependendo de determinada situao
encontrada, solicite informaes de uma tabela
ou de outra, da tabela de Clientes ou da tabela de
Fornecedores, baseado em critrios e condies
analisadas.
Exemplos de chamada da Stored Procedure:

EXECUTE SP_DADOS_
CLIENTE(T_CLIENTE);

Nesse exemplo a procedure retornar os dados


(Cdigo do cliente, Razo Social, CPF ou CNPJ, Endereo e Telefone) a partir da tabela T_CLIENTE.

EXECUTE SP_DADOS_
CLIENTE(T_FORNECEDOR);

Nesse outro exemplo a procedure retornar


mesmos campos, mas agora a partir da tabela
T_FORNECEDORES.

()
AS
DECLARE VARIABLE TIPO_
CLIENTE CHAR(1);
BEGIN
()
IF (TIPO_CLIENTE = C)
THEN
FOR SELECT * FROM SP_
DADOS_CLIENTE(T_CLIENTE)
INTO
:COD_CLIENTE, :NOME_
RAZAO, :CPF_CNPJ,
:ENDERECO, :TELEFONE;
DO
SUSPEND;
END
IF (TIPO_CLIENTE = F)
THEN
FOR SELECT * FROM
SP_DADOS_CLIENTE(T_
FORNECEDOR) INTO
:COD_CLIENTE, :NOME_
RAZAO, :CPF_CNPJ,

maro 2011

27

:ENDERECO, :TELEFONE;
DO
SUSPEND;
END
()
END^

No exemplo acima, podemos chamar a Stored


Procedure SP_DADOS_CLIENTE a partir de outra
Stored Procedure qualquer. Quando a varivel
TIPO_CLIENTE for igual C, ento passamos a
tabela T_CLIENTE como parmetro para a chamada do Execute Statement. J quando a varivel
TIPO_CLIENTE for igual F, passamos a tabela
T_FORNECEDOR como parmetro para a chamada
do Execute Statement.

novidade, incrementando o uso e tratamento em


Stored Procedures e Triggers.
O novo comando DML Execute Statement vem
como que coroar o lanamento do InterBase XE.
Mostra a preocupao da Embarcadero em desenvolver o produto e torn-lo cada vez mais atrativo
ao desenvolvedor. Afinal, somos ns desenvolvedores que avaliamos, utilizamos e propagamos o
produto no mercado.
Fica aqui novamente o convite para testarmos
o produto, sempre lembrando que ns desenvolvedores temos direito de uso de uma verso gratuita
do InterBase XE a Developer Edition. Podemos
baixar tanto a verso 62 bits, quanto a 32 bits. Basta
entrar, se cadastrar e baixar o produto atravs do

site da Embarcadero atravs do link abaixo. Essa


edio Developer nos permite utilizar e explorar
todos esses novos: http://www.embarcadero.
com/products/interbase. Fiquem ligados tambm
no canal de notcias do InterBase, atravs da comunidade InterBase no Embarcadero Developer
Network em portugus: http://edn.embarcadero.
com/br/interbase. Em breve com mais novidades
do InterBase aqui na The Club Megazine.

Referncia:
InterBase XE Language Reference Guide
Capitulo 3.

Sobre o autor
CONCLUSO

Felipe Santos

Os exemplos e situaes que passamos so


apenas algumas situaes possveis de se trabalhar
com o recurso do Execute Statement. D-nos uma
ideia do potencial de uso do comando. Para quem
utiliza somente o InterBase ou mesmo outros
bancos de dados que tambm suporte esse recurso padro SQL, agora pode explorar a fundo essa

28

maro 2011

Felipe Santos especialista em InterBase. Trabalha com o InterBase desde


2001. atuando como consultor e instrutor do produto em todo Brasil. Especialista em
ambientes crticos. Atua e trabalha com os maiores clientes do InterBase no Brasil.
Participante ativo na comunidade, com diversos artigos publicados. Participante do
grupo de beta testers mundial do produto. Palestrante em eventos como IB Tour, Borcon
Conference, CodeRage Latin Amrica, Delphi Developers Day, Linux Day, entre outros.
Atualmente trabalhando na rea tcnica do InterBase na Presence Tecnologia agente
oficial especializado do produto no Brasil.

felipe.santos@presence.com.br

Dicas DELPHI

if(EditNames[i]=EditName)then
Result:=EditTexts[i];
end;

Limpar Edits e Retornar valores apagados

Em uma de nossas ltimas edies, publicamos uma dica para limpar todos
os edits de um formulrio e depois retornar os valores apagados.
Os cdigos a seguir so uma nova abordagem dessa dica, utilizando ao
invs de eventos procedures genricas, que no caso estaro contidas em uma
unit parte de qualquer projeto.
Com essa abordagem, as procedures passam a no depender de nenhum
formulrio nem mesmo de quantas edits existem nesse formulrio.

Veja que na funo EditTextByName temos a utilizao dos arrays EditNames e EditTexts. Esses arrays foram declarados na interface e recebero
respectivamente os nomes das edits do formulrio a ser limpo e os textos das
edits do mesmo formulrio.
O preenchimento desses arrays feito pela procedure FillArrays. A procedure FillArrays possui em seu corpo a funo EditsCount, que a responsvel
por retornar para a funo FillArrays a quantidade de edits existentes no
Formulrio.
Segue o cdigo da procedure FillArrays e dentro dela a funo EditsCount:

A unit que iremos criar para esse exemplo recebe o nome de Funcoes.
Na seo interface, que a seo da unit que ser exportada para o projeto
que far uso da mesma, iremos declarar o seguinte:

procedure FillArrays(Form:TForm);
function EditsCount:Integer;
var
i,
iCount:integer;
begin
iCount:=0;

uses
Sysutils,Windows,Forms,StdCtrls;
procedure CleanEdits(Cleaner:Boolean;Form:
TForm);

for i:=0 to Form.ComponentCount-1 do


if(Form.Components[i] is TEdit)
then

var

Inc(iCount);

EditTexts:array of string;
EditNames:array of string;

Na sequncia, na seo implementation colocaremos o cdigo das procedures de apoio a procedure CleanEdits.
Comearemos pela funo EditTextByName. Essa funo ir retornar o
texto que dever ser recolocado em uma determinada edit quando ela for
preenchida com seu valor de antes da limpeza.
Veja o cdigo:

function EditTextByName(EditName:string):s
tring;
var
i:integer;
begin
Result:=;
for i:=0 to
VarArrayHighBound(EditNames,1)do

Result:=iCount;
end;
var
i,
j:integer;
begin
SetLength(EditTexts,EditsCount);
SetLength(EditNames,EditsCount);
j:=0;
for i:=0 to Form.ComponentCount-1 do
if(Form.Components[i] is TEdit)then
begin
EditTexts[j]:=TEdit(Form.
Components[i]).Text;
EditNames[j]:=TEdit(Form.
Components[i]).Name;
Inc(j);
end;
end;

maro 2011

29

Por fim iremos a codificao da procedure que ser vista pelos projetos que
utilizaro essa unit: A procedure CleanEdits, que declaramos na interface.

tipo boolean. Essa varivel ser utilizada para o controle do limpar desfazer
das edits. Essa varivel dever ter o valor True inicial.

A procedure CleanEdits tanto far a limpeza das edits como a posterior


reverso dessa limpeza, que o preenchimento das edits com os valores
que as mesmas continham antes da limpeza. O controle da tarefa, se limpeza
ou reverso feita pelo parmetro Cleaner. Quando esse parmetro est
true, ser realizada a limpeza das edits. Quando estiver false, ser realizada
a reverso da limpeza.

Monte o layout da aplicao de testes com algumas edits e um boto


limpar. Um exemplo de layout pode ser visto na figura a seguir:

Segue o cdigo:

procedure CleanEdits(Cleaner:Boolean;Form:
TForm);
var
i:integer;
begin
case Cleaner of
True:
begin
FillArrays(Form);
for i:=0 to Form.ComponentCount-1
do
if(Form.Components[i] is
TEdit)then
TEdit(Form.Components[i]).
Clear;
end;
False:
for i:=0 to Form.ComponentCount-1
do
if(Form.Components[i] is
TEdit)then
TEdit(Form.Components[i]).
Text:=EditTextByName(TEdit(Form.
Components[i]).Name);
end;
end;

No evento Onclick do boto limpar iremos fazer uso da procedure CleanEdits, alm de um controle do limpar desfazer.
Segue o cdigo:

procedure TForm1.Button1Click(Sender:
TObject);
begin
CleanEdits(Cleaner,Self);
Cleaner:=not Cleaner;
if(Cleaner)then
Button1.Caption:=Limpar
else
Button1.Caption:=Desfazer;
end;

Com a procedure CleanEdits conclumos a codificao da unit Funcoes.


Vamos agora testar sua funcionalidade.
Inicie um novo projeto no Delphi e salve-o em um diretrio de sua preferncia. Coloque a unit Funcoes nesse mesmo diretrio.
Acesse no Delphi o menu Project Add to Project e inclua no projeto a
unit Funcoes.
Na unit do formulrio da aplicao, inclua no uses a unit Funcoes.
Declare na seo var da unit do formulrio principal a varivel Cleaner, do
30

maro 2011

Anuncie
conosco

e um
Anuncie na revista e ganh
site do The Club
banner publicitrio no

to:
Solicite um oramen

Skype: theclub_cadastro
lub.com.br
E-mail: cadastro@thec
Fone: (14) 3732-1529

maro 2011

maro 2011

Вам также может понравиться