32
janeiro 2009

The Club - megazine - The Club - O maior clube de ... · e aplicações - Parte I.NET ... Teste seus conhe-cimentos. ... neste artigo o autor explica o conceito de pacotes e mostras

Embed Size (px)

Citation preview

janeiro 2009

janeiro 2009

janeiro 2009 03

LegendaIniciante

Intermediário

Avançado

Índice

Editorial

04

Ramos de Souza Janone

Delphi

Pacotes: Teoria e PráticaConhecendo seus benefícios

e aplicações - Parte I

.NET

Utilizando ListView e DataPager novos componenetes da framework 3.5

Dicas Delphi

30FORMS – Colorir automati-

camente quando o mouse passa por cima do componente.

Password – Gerar senha randônica

29

07Neste mês também

tenho um artigo na re-vista, onde mostro para vocês as novidades que a Embarcadero incluiu na VCL do Delphi 2009, são novos componentes visuais, que podem dar um “toque” especial na aplicação.

24

Desafio The CLub

Teste seus conhe-cimentos.

Subconsultas - uma abordagem prática 17

05

Como vender seu software mundo afora

Qualquer pessoa ou empresa que desen-volve software pode vender seus produtos para o mundo todo. A internet não possui fronteiras e exportar software hoje é muito fácil. Vamos apresentar aqui uma excelente ferramenta pela qual é possível expor seu produto a um enorme mercado. 19

janeiro 200904

Bem-vindo

Delphi é marca registrada da Borland International, as demais marcas citadas são registradas

pelos seus respectivos proprietários.

Marcos César Silva - Editor [email protected]

Estamos iniciando mais um ano, onde espero que seja muito produ-tivo para todos nós e repleto de sucesso. Para este mês, elaborei o artigo “Lock de Registro em banco de dados Firebird”, que aborda o tratamento de travamento de registros em base de dados Firebird. Como base neste artigo iremos com muita alegria finalmente dar inicio a um projeto que a tempos queríamos disponibilizar para nosso parceiros, que é a criação de vídeo aulas.

O objetivo inicial com destes vídeos é complementar os artigos da revista explicando os exemplos que acompanham os artigos. Assim a partir deste mês na revista irá ter um indicador dos artigos que possuem o vídeo aula, podendo ser baixado através do link que se encontra na página dos artigos referente à edição correspondente.

Neste mês pela primeira vez Ramos de Souza Janones escreve para nossa revista, trazendo em nossa coluna de aberturado o artigo: “Como vender seu software mundo a fora”, que mostra como vender e divulgar um software usando a Internet com uma extensão da empresa.

Temos também nosso amigo, antigo consultor do The Club e hoje nosso colaborador Alessandro Ferreira, que volta este mês com a primeira parte do artigo “Pacotes: Teoria e Prática – Conhecendo seus benefícios e apli-cações”, artigo extremamente útil quando da necessidade de modularizar um aplicação, neste artigo o autor explica o conceito de pacotes e mostras as vantagens de usá-lo, como também com implementar este recurso em sua aplicação.

Para os iniciantes o consultor do Marco Antonio Armando, vem com um artigo bastante útil para iniciantes em consultas SQL, “Subconsultas - Uma Abordagem Prática”.

E por fim, em nossa seção .Net o nosso colunista Fabiano Belmon-te, traz o artigo: “Utilizando ListView e DataPager novos componentes da FrameWork 3.5”, que fala sobre o ListView que nos permitem exibir dados de uma fonte de dados, e o DataPager com o recurso de paginar os dados exibidos no ListView de maneira muito simples, ambos introduzidos no ASP.NET 3.5.

Bom pessoal é isto ai! Espero que gostem e aproveitem a leitura deste mês, e peço que continuem a me escrever dando dicas, sugestões e en-viando reclamações, para que possamos melhorar esta parceria que para muitos de vocês já dura mais que uma década.

Bom inicio de ano a todos!

Av. Profº Celso Ferreira da Silva, 190 Jd. Europa - Avaré - SP - CEP 18.707-150

Informações: (14) 3732-1529 Suporte: (14) 3733-1588

Internethttp://www.theclub.com.br

Cadastro: [email protected]: [email protected] Informações: [email protected] Cadastro: theclub_cadastro

Skype Suporte: theclub_linha1 theclub_linha2

Copyright The Club Megazine 2008

Diretor TécnicoMarcos César Silva

Diagramação e ArteVitor M. Rodrigues

RevisãoMarcos César Silva

ColunistasAntonio Spitaleri Neto

Fabiano BelmonteLuís Alexandre de OliveiraMarco Antonio Armando

Marcos César SilvaRamos de Souza Janones

Impressão e acabamento:GRIL - Gráfica e EditoraRua São Paulo, nº 447

Cep: 18740-00 - Taquarituba-SPTel. (14) 3762-1345

ReproduçãoA utilização, reprodução, apropriação, armazenamento em banco de dados, sob qualquer forma ou meio, de textos, fotos e outras criações intelectuais em cada publicação da revista “The Club Megazine” são terminantemente proibidos sem autorização escrita dos titulares dos direitos autorais.

janeiro 2009 05

Ramos de Souza Janones

Qualquer pessoa ou empresa que desen-volve software pode vender seus produtos para o mundo todo. A internet não possui fronteiras e exportar software hoje é muito fácil. Vamos apresentar aqui uma excelente ferramenta pela qual é possível expor seu produto a um enorme mercado.

Os passos, resumidamente, são:

1. Criar uma versão para demonstração – sha-reware – em no mínimo três idiomas. De preferên-cia português, inglês e espanhol.

2. Criar um website também em três idiomas, pelo menos, para que mais usuários possam co-nhecer melhor o software.

3. Pedir o Swift Code ao seu banco de preferên-cia. Trata-se de um código que identifica seu banco para transferência entre bancos internacionais. Você deverá informar ao cliente o número do seu banco, agência, conta e o Swift Code.

4. Começar a vender seu software para o

mundo todo.

Ok, exageramos, não é tão fácil assim.Existem dois sites que comercializam sharewares no mundo todo: o Share-it e o RegNow. Estes dois são os melhores e mais conhecidos sites do mundo para venda de softwares via internet.

O Share-it é o mais popular. Possui e-commerce em mais de 150 países e uma grande rede de profissionais fornecedores de soluções em TI espalhadas pelo mundo. Tornou-se um excelente canal de vendas e distribuição virtual. Então o quarto passo mais acertado seria de cadastrar-se como "autor de software" nestes dois sites e enfim começar a vender mundialmente.

Caso ainda encontre dificuldades em traba-lhar com dinheiro e bancos internacionais para receber os pagamentos – mesmo tendo o SWIFT Code de seu banco – você pode usar o serviço da SiliconAction para vender e comprar softwares de outros países. Este site pode comercializar seus sharewares em países da América Latina e oferece

parcelamento por cartão de crédito. Há também o PayPal, um serviço internacional de mediação de dinheiro.

Além de criar seu website, abrir conta no Share-it e no RegNow, não esqueça de cadastrar-se nos milhares de sites de busca de todo o mundo (ou pelo menos em alguns deles...). Existem softwares que podem auxiliar neste processo. É possível contratar serviços de empresas especializadas, como a Cadastra. Cadastre também seu shareware, junto com o link de compra e download de de-monstração, nos mais diversos sites de downloads existentes na web. E faça bons negócios.

Como vender seu software

mundo a fora

janeiro 200906

No Brasil, além do SiliconAction, há outros dois grandes sites para comercialização online de softwares, o SofteArena e o ArquivoNacional. O Sof-tArena é uma associação entre o Superdownloads e a Cia do Software e possui hoje 3 mil revendas ativas. Proporciona uma excelente divulgação e a meu ver é o melhor canal de vendas e distribuição online de softwares. Para conhecer todas as vanta-gens oferecidas e publicar seu software neste canal, clique no link "Publique seu Software".

O ArquivoNacional, bastante conhecido no mercado nacional e de língua portuguesa, também é um excelente canal de vendas e distribuição online, com bastante revendas. O número não foi informado, mas é bastante presente na web.

O empresário do software pode e deve adotar todos estes canais apresentados a fim de aumentar as chances de venda e difusão de seus aplicativos. Uma distribuição exclusiva deve ser analisada com cuidado, pois diminui as chances de vendas. Nenhum destes canais apresentados exigem exclu-sividade. Vale lembrar que a internet deve ser uma extensão de seu negócio físico.

As ferramentas aqui demonstradas devem ser vistas como novos canais de venda e distribuição

Sobre o autor

Ramos de Souza Janones é formando em Sistema da Informação e em Publicidade e Propaganda na Faculdade Triângulo Mineiro. Atua com desenvolvimento de software desde 1994. Proprietário da Ramos da Informática (www.ramosdainformatica.com.br), seus sof-twares são comercializados em todo o Brasil e países como: Portugal, Argentina e Bolívia.

Atualmente ministra o curso Sucesso com Software (www.sucessocomsoftware.com.br) voltado a desenvolvedores e Software-houses.

de seus softwares. Uma última dica importante: invista em design. Aproveite esta vantagem que a internet oferece, onde uma empresa pequena pode se apresentar melhor do que concorrentes maiores. Por isso o design e as questões de usabilidade são muito importantes na hora de desenvolver seu site. Vale a pena investir e contar com a colaboração de bons profissionais de design.

Links relacionados:

ShareIt - http://www.shareit.com/

RegNow - http://www.regnow.com/

SilliconAction - www.siliconaction.com.br

PayPal - https://www.paypal.com/br

Cadastra - http://www.cadastra.com.br/

SoftArena - http://www.softarena.com.br/

ArquivoNacional - http://www.arquivonacional.com.br/

Links de sites de download:

* Ultra Download - http://ultradownloads.com.br/

* Superdownloads - http://superdownloads.uol.com.br/

windows/index.html

* Baixaki - http://baixaki.ig.com.br/

* Super Site Web - http://www.supersitesdaweb.com/

* Grátis - http://www.gratis.com.br/

* Baixa Tudo - http://baixatudo.globo.com/

* Baixe - http://www.baixe.net/

* BaixeBem - http://www.baixebem.com/

* Brasil Downloads - http://www.brasildownloads.com.br/

* Download Completo - http://www.downloadcompleto.net/

* iProgramas - http://www.iprogramas.com.br/

* GaruDownloads - http://www.garu.com.br/

* NetDownloads - http://www.netdownloads.com.br/

* Tudo Downloads - http://www.tudodownloads.com.br/

* Zigg Toneladas de Downloads - http://www.ziggi.com.br/

* Terra Downloads - http://terrabrasil.softonic.com/

janeiro 2009 07

Delphi

Introdução

O constante crescimento das transações de-vido a demanda cada vez maior de solicitações e usuários cada vez mais exigentes, aponta para um inevitável crescimento no tamanho e complexidade dos softwares, sejam eles aplicações de automa-ção comercial ou um ERP contemplando todos os processos em uma organização.

Outro aspecto relevante para o aumento no tamanho de um software, é a não adoção de metodologias de desenvolvimento, o que acaba por gerar códigos redundantes, retrabalho e até mesmo “remendos” no software os quais somados, vão acrescentando vários megabytes inchando seu executável final e, com isso dificultando o processo de distribuição e atualização do mesmo.

Como se tudo isso não bastasse, um software mal estruturado e consequentemente “inchado” ou mesmo, um executável grande devido ao ta-manho e complexidade da aplicação, esbarramos em limitações por parte do sistema operacional, onde o mal gerenciamento de memória acaba por impedir que nosso software venha se quer a carregar, problema este freqüente no Windows 98 e com menos freqüência no Windows 2000 e XP,

porém, não estando estes sistemas operacionais livre deste problema.

Dentro deste contexto, o Delphi a partir da versão 3 adicionou suporte a pacotes (packages) que nos possibilitam modularizar aplicações Delphi e C++Builder.

Pacotes ou DLLs?

Pensando apenas na modularização, podería-mos vir a utilizar DLLs as quais são universalmente utilizadas por todas as linguagens de programação e permitem compartilhar código entre elas. Um exemplo clássico são as diversas empresas de impressoras fiscais.

Geralmente, elas desenvolvem e distribuem uma DLL contendo todas as funções necessárias para comunicação com seu periférico, bastando ao programador de automação comercial declarar estas funções em sua aplicação e fazer uso sem necessitar tomar conhecimento em qual linguagem a DLL foi escrita. Assim sendo, particularmente re-comendo a utilização de DLLs somente quando for necessário disponibilizar funções e funcionalidades para outras linguagens de programação, visto que

a criação e manipulação de DLLs exige um bom conhecimento na tipagem e gerenciamento de memória impostos pelo Windows.

Veja algumas das vantagens em utilizar pa-cotes:

• Reduzir o tamanho dos executáveis;• Dividir a aplicação em módulos. Modu-

larizando a aplicação em pacotes, obteremos uma série de vantagens, dentre elas, compartilhar códi-go entre vários projetos, gerenciar funcionalidades do sistema, melhorar a distribuição e a atualização para correção de erros;

• Instalação de componentes facilitada. Se o objetivo for desenvolver um conjunto de componentes para instalar no Delphi, também utilizaremos para fazer a distribuição dos com-ponentes, facilitando a instalação na máquina do desenvolvedor.

Observe que as duas primeiras vantagens também são fornecidas pelas DLLs. Mas, os pa-cotes oferecem maior integração ao ambiente de desenvolvimento do Delphi. Outra importante vantagem é a possibilidade de utilizar orientação a objetos, ou seja, podemos instanciar uma classe

Conhecendo seus benefícios e aplicações

Parte I

janeiro 200908

declarada dentro de um pacote. Assim, quando as aplicações desenvolvidas forem exclusivamente em Delphi (ou C++Builder), há grandes ganhos na utilização de pacotes.

Uma visão geral dos pacotes run-time

Os pacotes run-time são como DLLs, uma cole-ção de dados e códigos que formam uma parte da aplicação, porém não está integrado ao executável da aplicação. Uma vantagem de usar os pacotes run-time é que você pode atualizar os pacotes sem atualizar o arquivo executável. Você pode fornecer aos usuários pequenos pacotes sem enviar a aplicação inteira. O arquivo executável é menor, porque grande parte do código está guardado em pacotes externos.

Outra vantagem dos pacotes run-time é que você pode compartilhá-los com outras aplicações, economizando espaço em disco. Um exemplo de como você pode usar isso, considere o que acontece quando você distribui vários executáveis sem os pacotes externos. Cada arquivo executável contém a VCL. Se você encontrar uma maneira de colocar a VCL em um pacote run-time, os arquivos executáveis serão muito pequenos, porque todo o código da VCL estará compartilhado em um único pacote run-time.

Reconhecendo isto, a Borland vende o Delphi com vários pacotes run-time prontos para a VCL, o que permite que você construa suas aplicações usando-os. Para conferir, acesse o menu Project | Options e selecione a aba Packages (veja figura abaixo). Você verá um checkbox chamado “Build with runtime packages”. Se você selecionar esta opção, poderá selecionar quais os pacotes deseja usar.

Veja Imagem 01.

Você encontrará estes pacotes no diretório \Delphi\Lib, estes são os pacotes run-time forne-cidos pela Borland, cada um dos quais contém uma porção do VCL. Você pode optar por linkar todos estes pacotes run-time, ou apenas escolher alguns deles.

Se você fizer uma aplicação exemplo usando os pacotes run-time contendo a VCL, o tamanho de seu executável deve ficar próximo de 14 Kb, comparado aos 287 Kb se você não usar os paco-tes run-time. É claro, você ainda deve continuar

enviando os pacotes run-time com sua aplicação, o qual tem aproximadamente 2Mb. Então o que você ganhou? Bem, agora você pode efetuar alterações apenas em um pequeno executável e distribuí-lo, sem a necessidade de enviar novamente o pa-cote, pois este não irá mudar e já foi distribuído anteriormente.

Você pode, é claro, criar seus próprios pacotes run-time, mas primeiro vamos conhecer as exten-sões de arquivos usadas quando trabalhamos com pacotes, veja o quadro abaixo.

Extensões de arquivos usadas pelos pacotes.

Imagem 01: A aba Packages do dialog box Project Options.

DPK Código fonte do pacote

DCP Uma imagem binária contendo o cabeçalho do pacote e a concatenação de todos os arquivos DCU do pacote. Um arquivo único DCP é criado para cada pacote. O nome base para o DCP é o nome base do arquivo fonte DPK. Isto é necessário para linkar os pacotes run-time. Fazendo uma analogia, um DCP está para um pacote, assim como um DCU está para uma unit.

Uma imagem binária para um arquivo único contendo um pacote. Um DCU é criado, quando necessário, para cada arquivo (unit).

BPL O pacote run-time. Nada mais é que uma DLL Windows , porém com características especiais do Delphi. O nome base para a BPL é o nome base para o arquivo fonte DPK. Este é o arquivo que você precisa enviar junto com sua aplicação.

janeiro 2009 09

Opções de configuração em pacotes.

Veremos a seguir algumas opções de ajustes disponíveis quando criamos um pacote. A figura a seguir apresenta um pacote recém criado no Delphi.

Veja a imagem 02.

Contains Contém as units que integram o pacote

Requires Indica os pacotes externos requeri-dos para execução

Options Opções de compilação e diretórios. Semelhante a opção Project | Op-tions em um projeto, veja imagem a seguir.

Opções do pacote.

Veja Imagem 03.

Veja Tabela 02.

Imagem 02: Opções do pacote.

Imagem 03: “Options” do pacote.

Description

Apresenta descrição do pacote quando visualizado na aba Packages.

Designtime only Indica que o pacote poderá ser instalado na IDE do Delphi, ou seja, adicio-nado a palheta de componentes.

Runtimeonly Indica que o pacote será utilizado apenas em run-time e seu conteúdo será utilizado para rodar outras aplicações ou pacotes.

Designtime and Runtime Contempla as duas funcionalidades anteriores.

Build control

Rebuild as needed Esta opção indica que o pacote será compilado automaticamente sempre que necessário. Essa opção geralmente é utilizada em pacotes de compo-nentes que são utilizados por outros pacotes, pois sempre que um pacote necessitar que o outro seja recompilado, isso será feito automaticamente sem intervenção do programador.

Explicit Rebuild Esta opção geralmente é utilizada em nossos pacotes de run-time os quais o programador efetuar a compilação no momento que achar necessário.

Tabela 02: “Options” do pacote.

janeiro 200910

testar e depurar a aplicação como se não estivesse utilizando pacotes e, quando for gerar o build para distribuição, compilar/gerar os pacotes, marcar esta opção e gerar o EXE pequeno;

Temos também algumas desvantagens em relação a utilização de pacotes dinâmicos, das quais destaco:

• Todos os pacotes (BPLs) devem obri-gatoriamente disponíveis em uma path acessível pelo EXE, pois do contrário, no momento da carga da aplicação uma exceção será gerada;

• Caso comercialize sua aplicação em módulos separados, deverá distribuir todos os

Outras opções relevantes em relação ao tratamento dos pacotes estão na aba Directories/Conditionals, confira a seguir.

Veja a Imagem 04.

Veja a Tabela 03.

Durante o decorrer deste nosso workshop iremos utilizar estas opções nos exemplos que se-rão implementados para mostrar a funcionalidade dos pacotes.

Tipos de pacotes: Dinâmicos e Está-ticos

O Delphi nos oferece a possibilidade de trabalhar com pacotes estáticos ou dinâmicos. Ambas abordagens oferecem ótimos resultados à sua aplicação e caberá a você decidir qual abor-dagem se encaixará melhor às suas necessidades. Neste tópico, iremos conhecer como funcionam estas duas abordagens e dessa forma facilitar a sua escolha.

Como dito anteriormente, um pacote nada mais é que uma biblioteca especial de link dinâmico usada por aplicações Delphi e C++Builder. Estes pacotes podem conter units com código, compo-nentes, formulários e é claro, tudo que envolve a programação orientada a objetos oferecida pelo Delphi.

Pacotes Estáticos O trabalho com pacotes estáticos é bem mais

simples em relação aos dinâmicos e não requer al-terações significativas em projetos que já estão em produção. Basicamente, quando você quebra sua aplicação em pacotes estáticos, irá separar fisica-mente porções (units, formulários, rotinas) em um pacote a parte de sua aplicação, porém ao informar o nome do referido pacote nas configurações do projeto (Project | Options | Packages | Run-Time Packages) o aplicativo irá automaticamente buscar uma unit ou formulário dentro do referido pacote quando esta não estiver presente na aplicação. Por exemplo, se você possuir na cláusula uses de sua unit principal (MainForm) referência a unit un-CadClientes a qual contém seu cadastro de clientes, no momento que for instanciar tal formulário e o mesmo não for encontrado na aplicação, a carga será feita a partir do pacote estático de forma

totalmente transparente.A primeira vista, a utilização de pacotes estáti-

cos traz muitas vantagens, das quais destaco:

• Facilidade para adequar/quebrar apli-cações já existentes e resolver de forma simples problemas como falta de recursos;

• Facilidade na atualização das aplica-ções, sendo possível distribuir apenas os pacotes referentes aos módulos alterados;

• Redução do tempo de carga da aplica-ção em pelo menos 50%;

• Em ambiente de desenvolvimento, você poderá deixar a opção “Build with runtime packages” desmarcada e dessa forma, compilar,

Imagem 04: Directories/Conditionals

Output directory Indica em qual pasta será gerado o arquivo BPL.

Unit output directory Indica em qual pasta serão gerados os arquivos DCUs referente as units contidas no pacote.

Search Path Path úteis durante a compilação do pacote.

Debug source path Indica onde de depurador do Delphi deverá buscar os arquivos durante uma sessão debug.

DCP output directory Indica em qual pasta será gerado o arquivo DCP referente a compilação do projeto.

Tabela 03.

janeiro 2009 11

pacotes (BPLs) mesmo dos módulos que não es-tarão disponíveis ao usuário e efetuar o controle via programação permitindo ou não acesso aos mesmos;

• O gerenciamento de memória (carregar e descarregar) é feito automaticamente pelo siste-ma (isso pode ser bom ou pode ser ruim, depende da sua experiência em lidar com o assunto);

Laboratório 1

Vamos agora partir para nosso primeiro pro-jeto de exemplo e demonstrar na prática como funcionam os pacotes estáticos. Abra o Delphi, vá ao menu File | New | Application e veja na figura abaixo o layout sugerido.

Veja a Imagem 04.

Nomeie o projeto como fmPrincipal e salve o projeto como UsaPackages e a unit como unPrin-cipal. Depois, dê um duplo clique no ActionList1 e adicione as opções apresentadas na figura a seguinte.

Ver a Imagem 05.

Dentro da pasta onde salvou o projeto, adi-cione três novas pastas sendo: RtmPackClientes, RtmPackDM e RtmPackProdutos, as quais iremos utilizar mais adiante para armazenar os pacotes. Prosseguindo, adicione um DataModule (menu File | New | Data Module), nomeie como DM e salve a unit unDM e nele adicione dois componentes TTable configurando como demonstra o quadro a seguir.

tabCustomer: TTable

DatabaseName DBDemos

TableName Customer

Active True

tabParts: TTable

DatabaseName DBDemos

TableName Parts

Active TrueTabelas no DM.

Adicione dois novos formulários ao nosso projeto nomeando como fmClientes e fmProdutos e salve as units como unClientes e unProdutos respectivamente. Na cláusula uses de ambos,

Imagem 05: Layout sugerido

Imagem 05: Opções do ActionList.

Imagem 06: fmClientes.

adicione referência ao DM declarando a unDM. A figura a seguir apresenta o layout e componentes necessários para estes dois formulários.

Veja a imagem 06.

janeiro 200912

Veja a imgem 07.

Acesse o menu Project | Options e mova o fmClientes e o fmProdutos para a lista Available Forms, como apresenta a Imagem 08.

Veja a Imagem 08.

Volte ao formulário principal (fmPrincipal), dê um duplo clique no ActionList1 e no evento OnExe-cute da acClientes adicione o seguinte código:

procedure TfmPrincipal.acClientesExecute(Sender: TObject);begin if fmClientes = nil then Application.CreateForm(tfmClientes, fmClientes); try fmClientes.ShowModal; finally FreeAndNil(fmClientes); end;end;OnExecute da acClientes.

Faça o mesmo para a acProdutos adicionando o seguinte código:

procedure TfmPrincipal.acProdutosExecute(Sender: TObject);begin if fmProdutos = nil then Application.CreateForm(tfmProdutos, fmProdutos); try fmProdutos.ShowModal; finally FreeAndNil(fmProdutos); end;end;OnExecute da acProdutos.

Imagem 08: Opções do projeto

Imagem 07: fmProdutos.

janeiro 2009 13

Imagem 09: Opções do projeto

Imagem 10: Project Manager.

Obs: Lembre-se de declarar na cláusula uses da unPrincipal as units unClientes e unProdutos.

Feito isso, compile o projeto. Até aqui, nada diferente daquilo que você está acostumado a trabalhar até hoje. Verifique na pasta onde salvou o projeto que o executável gerado deve ter apro-ximadamente 870KB.

Retirando a VCL do projeto

Vamos agora apenas retirar a parafernália em-butida pela VCL em nosso executável e novamente compilar nosso projeto. Para retirar a VCL, acesse o menu Project | Options | Packages e marque a opção “Build with runtime packages” conforme sugere a figura a seguir.

Ver Imagem 09.

Confirme com OK e compile o projeto. Bem, sem nenhum esforço no executável teve uma redução dos aproximados 870KB para aproximada-mente 30KB. Isso em muitos casos resolve aquele velho problema de falta de recursos principalmente no Windows 98 (Out Of Resources), contudo, isso irá depender muito do tamanho e complexidade de sua aplicação.

Obs: Lembre-se que para distribuir uma aplicação que esteja compilada desta forma, será necessários distribuir os pacotes refe-rentes a VCL conforme mencionado no tópico “Uma visão geral dois pacotes run-time”.

Modularizando a aplicação em paco-tes estáticos.

O primeiro passo já foi realizado quando mar-camos a opção “Build with runtime packages”. O próximo será criarmos três pacotes sendo um para abrigar o DM, outro para o fmClientes e finalmente outro para o fbProdutos.

Para facilitar vamos trabalhar com o “Project Manager” do Delphi. Estando com nosso projeto aberto na IDE, acesse o menu View | Project Manager ou simplesmente tecle a combinação CTRL+ALT+F11 e terá o manipulador de projetos conforme apresenta a imagem10.

Veja a imagem 10.

janeiro 200914

Imagem 11: Project Manager.

Imagem 12: Novo pacote.

Imagem 13: Projetos e pacotes.

Clique da direita em Project Group e escolha a opção “Save Project Group”, mantendo o nome padrão e salvando-o na mesma pasta do projeto. Clique em New para criarmos nosso primeiro pacote selecionando a opção “Package” em “New Items”, veja a imagem 11.

Veja a imagem 11.

Após selecionar e confirmar esta opção tere-mos um novo pacote em nosso manipulador de projetos conforme apresenta a próxima figura.

Veja a imagem 12.

Salve este pacote na pasta RtmPackDM com o nome RtmPackDM.dpk. Antes de trabalhar-mos neste pacote, vamos criar os outros dois restantes, sendo RtmPackClientes.dpk (na pasta RtmPackClientes) e RtmPackProdutos.dpk (na pasta RtmPackProdutos). Após adicionar e salvar os três pacotes, nosso manipulador de projetos irá conter o projeto e os três novos pacotes, confira na imagem 13.

Veja a imagem 13.

Algumas literaturas sugerem remover do projeto (Remove file from project) as units que serão adicionadas em pacotes. Particularmente, não acho necessário, pois uma das facilidades em trabalhar com pacotes estáticos é exatamente você continuar dando manutenção ao projeto de forma transparente e somente quando for gerar o build para distribuição, compilar e linkar os pacotes ao projeto.

Obs. Configure nas opções do pacote em Directories/Conditionals os parâmetros “Output directory” e “DCP output directory” para “..\”, com isso, os DCPs e BPLs serão gerados na mesma pasta onde encontra-se o executável de nosso projeto exemplo.

Dando continuidade, vamos adicionar as units a cada pacote respectivamente. Iremos começar pelo RtmPackDM.dpk no qual iremos adicionar nosso DataModule (unDM). Clique no botão “Add” do RtmPackDM.dpk e selecione a unDM e confirme, ficando nosso pacote como apresenta a imagem 14.

janeiro 2009 15

Imagem 14: RtmPackDM.

Veja a imagem 14.

Repita o mesmo procedimento para Rtm-PackClientes.dpk e RtmPackProdutos.dpk. Após adicionar cada unit ao seu respectivo pacote, compile primeiro o RtmPackDM clicando no botão “Compile”. Aqui irá entrar uma regrinha básica quando trabalhamos com pacotes: Analisar a in-terdependência entre os módulos/units. Observe que tanto a unClientes, quando a unProdutos fazem referência ao DataModule (unDM), contudo, não podemos e nem devemos adicionar a unDM em todos os pacotes, primeiro porque isso seria redundante e segundo porque o próprio Delphi irá identificar que uma mesma unit está adicionada em diferentes pacotes e gerará uma exceção a este respeito. Então, o que fazer?

Adicionando dependência entre pacotes

Você deve estar lembrando que o grupo Re-quires indica os pacotes externos requeridos para execução, ou seja, informamos ao pacote atual onde ele deverá buscar as referências que não en-contrar nele próprio. Outro detalhe que você deve estar lembrado é que ao compilar um pacote, além do arquivo BPL geramos também um arquivo DCP que é uma imagem binária contendo o cabeçalho do pacote e a concatenação de todos os arquivos DCU do pacote. Um arquivo único DCP é criado para cada pacote. O nome base para o DCP é o nome base do arquivo fonte DPK. Isto é necessário para linkar os pacotes run-time. Fazendo uma analogia, um DCP está para um pacote, assim como um DCU está para uma unit.

Bem, neste momento você já deve ter iden-tificado qual será o “pulo do gato” para que os pacotes RtmPackClientes e RtmPackProdutos acessem o DataModule. Selecione o item Requires no RtmPackClientes.dpk, clique em “Add” e vá na pasta principal de nosso projeto onde encontrará o arquivo RtmPackDM.dcp, bastando selecioná-lo e adicioná-lo. Repita o mesmo procedimento para o RtmPackProdutos.dpk. Feito isso, compile estes pacotes e com isso teremos seus respectivos DCPs e BPLs gerados na pasta do projeto.

Linkando os pacotes ao projeto

Efetuaremos agora o link estático dos pacotes ao nosso projeto. Para isso, está com o

projeto ativo, acesse o menu Project | Options | Packages, apague todo o conteúdo da caixa de texto referente “Build with runtime packages”, clique em “Add” e selecione os três pacotes anteriormente gerados, lembrando que o link será feito através dos arquivos DCPs, confira a figura a seguir.

Veja a imagem 15.

Confirme em OK e compile o projeto. Por curio-sidade, vá a pasta onde o executável foi gerado e verá que temos um EXE ainda menor, apenas com 22KB! Rode a aplicação, chame os formulários e

Imagem 15: Pacotes adicionados ao projeto.

veja que tudo continua transparente, como se não estivéssemos utilizando pacotes de run-time.

Obs: Quer ter certeza de que os pacotes estão sendo utilizandos? Vá à pasta onde estâo o executável e as BPLs e renomeie a RtmPackDM.bpl para RtmPackDM.old, por exemplo e rode a aplicação. Provavelmente a aplicação não irá carregar e receberá uma exceção semelhante a apresentada na figura a seguir.

janeiro 200916

Veja a imagem 16.

Podemos destacar isso como uma desvanta-gem da linkagem estática de pacotes, pois apesar dos módulos estarem fisicamente separados, existe a dependência e todos os módulos devem estar acessíveis no momento da carga da aplicação. Isso também ocorre quando trabalhamos com DLLs e efetuamos a declaração das funções da mesma em nossa unit e, se a DLL não estiver presente no momento da carga da aplicação o mesmo tipo de exceção será levantada.

Facilidade de manutenção no pro-jeto

Supondo que você necessite efetuar alterações em alguma das units, testar para ver se a alteração ficou satisfatória, depurar para encontrar possíveis erros, trabalhar com pacotes neste contexto seria um inconveniente, pois, você teria que compilar o pacote, compilar o projeto e depois executar seus testes.

Uma vantagem dos pacotes estáticos já citada anteriormente é que a qualquer momento você pode voltar a sua aplicação para um único módu-

Sobre o autor

Alessandro Ferreira

Analista de Sistemas Sênior do Citibank Capital Markets Brazil onde atualmente tra-balha com Microsoft .NET e Oracle. Bacharel em Administração de Sistemas de Informação e Microsoft Certified Professional (MCAD.NET, MCSD.NET, MCTS e MCPD), trabalhou com Delphi por 10 anos sendo 7 anos dedicados ao suporte técnico aqui no The Club, auxiliando centenas de programadores pelo Brasil.

lo, ou seja, sem a dependência dos pacotes. Para isso, bastará acessar o menu Project | Options | Packages e desmarcar a opção “Build with runtime packages” e confirmar em OK. Agora, ao compilar sua aplicação verá que o executável voltou a ter os mesmos aproximados 870KB e, poderá alterar, rodar, depurar, enfim, fazer o que for necessário em seu projeto sem necessitar recompilar seu pa-cote. Quando terminar a manutenção no projeto, marque novamente a opção “Build with runtime packages”, abra somente os pacotes referentes as units alteradas, compile e bastará atualizar os pacotes alterados (BPLs) em seu cliente para que as alterações sejam efetuadas.

Considerações Finais

Com isso encerramos nosso primeiro labora-tório demonstrando como criar uma aplicação e modularizá-la em pacotes estáticos. Na próxima edição estarei abordando a utilização de pacotes dinâmicos e como eles podem ser úteis em sua aplicação.

Abraço à todos e até a próxima.

Imagem 16: Erro quando a aplicação não encontra uma BPL requerida.

janeiro 2009 17

Subconsultas por definição é uma con-sulta embutida dentro da cláusula WHERE de outra consulta, a fim de restringir os dados retornados pela consulta, também conhecida como “consulta aninhada”. Uma subconsulta é utilizada para retorno de dados, os quais serão utilizados na consulta principal, a fim da restrição dos dados a serem recuperados. As subconsultas são utilizadas com as cláusulas SELECT, INSERT, UPDATE E DELETE.

A sintaxe básica de uma subconsulta é a seguinte:

SELECT <NOME DA COLUNA> FROM <TABELA> WHERE <NOME DA COLUNA> = (SELECT <NOME DA COLUNA> FROM <TABELA> WHERE <CONDIÇÕES>)

Quando do uso de uma subconsulta em uma consulta, primeiro processa-se a subconsulta, e posteriormente a consulta principal, de acordo com as condições resolvidas pela subconsulta.

SUBCONSULTASUMA ABORDAGEM PRÁTICA

Os resultados de uma subconsulta são utiliza-dos para processar expressões na cláusula WHERE da consulta principal. As subconsultas podem ser utilizadas na cláusula WHERE ou cláusula HAVING, da consulta principal.

Não podemos nos esquecer que os operado-res: =, >, <, <>, NOT IN, IN, OR, AND, ETC, poderão ser alocados dentro de uma subconsulta.

Para construirmos subconsultas de modo ade-quado, devemos obedecer a alguns importantes critérios, são eles:

• Subconsultas devem ser inseridas entre parênteses.

• Não é possível a utilização de ORDER BY em uma subconsulta, muito embora a consulta principal poderá fazer uso de ORDER BY. A cláusula GROUP BY, neste caso poderá exercer a mesma função que ORDERBY na subconsulta.

• Subconsultas, as quais retornarem mais de uma linha de registros, podem utilizar múltiplos operadores de valor, como IN.

• O operador BETWEEN, não poder ser utilizado com uma subconsulta, mas poderá ser inserido dentro da subconsulta.

• Uma subconsulta por padrão, poderá possuir apenas uma coluna na cláusula SELECT, com exceção que mais de uma coluna, estejam presentes na consulta principal, para que seja efetuada a comparação.

SUBCONSULTAS COM SELECT

Talvez seja a forma mais freqüente na utiliza-ção de subconsultas. Como foi citado anteriormen-te, quando do uso de subconsultas com a instrução SELECT, é executada a recuperação de dados para resolução da consulta principal.

Abaixo um exemplo clássico:

janeiro 200918

SELECT <COLUNA(s)>FROM <TABELA(s)>WHERE <COLUNAS)> <OPERADOR> (SELECT <COLUNA(S)>FROM <TABELA(S)> WHERE <CONDIÇÃO(ÕES)>)SUBCONSULTAS COM INSERT

Os dados retornados por uma subconsulta, são utilizados por uma consulta principal, para serem inseridos em outra tabela.

Abaixo um exemplo clássico:

INSERT INTO <TABELA>SELECT <COLUNA(S)>FROM <TABELA(S)>WHERE <COLUNA> <OPERADOR> (SELECT <COLUNA> FROM <TABELA>WHERE <CONDIÇÃO)>

SUBCONSULTAS COM UPDATE

Utilizaremos uma subconsulta com a instrução UPDATE, a fim de que uma coluna ou mais possam

ser atualizadas.

Abaixo um exemplo clássico:

UPDATE <TABELA>SET <COLUNA> = (SELECT <COLUNA> FROM <TABELA>WHERE <CONDIÇÃO>)

SUBCONSULTAS COM DELETE

Vejamos um exemplo:

DELETE FROM <TABELA>WHERE <COLUNA> <OPERADOR> (SELECT <COLUNA> FROM <TABELA>WHERE <CONDIÇÃO>)

INSERINDO UMA SUBCONSULTA DEN-TRO DE UMA SUBCONSULTA

Uma subconsulta pode ser embutida em outra subconsulta, da mesma forma que podemos em-

butir uma subconsulta em uma consulta comum, sendo que a subconsulta é resolvida antes da consulta principal.

Um exemplo de subconsulta embutida:

SELECT <COLUNA(S)>FROM <TABELA(S)>WHERE <COLUNA> <OPERADOR> (SELECT <COLUNA>FROM <TABELA>WHERE <COLUNA> <OPERADOR>(SELECT <COLUNA> FROM <TABELA> WHERE <CONDIÇÃO>))

Utilizamos nesta breve abordagem acerca de subconsultas, sintaxe em Firebird, podendo variar dependendo da implementação utilizada.

Sobre o autor

Marco Antonio ArmandoConsultor Técnico The club

janeiro 2009 19

1- Introdução

Quando trabalhávamos com tabelas paradox nos acostumamos com o comportamento padrão do BDE de travar um registro quando o mesmo já fosse colocado em edição por outro usuário do sistema ou mesmo outra aplicação. Assim que começamos migrar nossas aplicações de tabelas paradox para um banco relacional, começamos a fazer comparações entre a nossa antiga forma de gerenciar a base de dados e a nova que estaríamos começando a utilizar. Uma das primeiras obser-vações realizadas foi a detecção da falta de um travamento de registro automatizado pelo banco de dados. Embora muitos não tenham o costume ou achem desnecessário o travamento de registro, em alguns casos especiais isto pode ser útil, quando um mesmo registro pode ser concorrido por dois ou mais usuários para sua edição, ou em aplicações Web onde o numero escritas concorrentes seja elevada. Neste artigo vou falar a respeito do tra-vamento de registro ou lock de registro com banco de dados Firebird usando DBExpress.

2- Procedimento Padrão (antes da versão Firebird 1.5)

Logo que o Firebird foi lançado ainda não tínhamos um controle especifico para “travar” um registro, apenas poderíamos travar um deter-

Lock de Registro

em banco de

dados Firebirdminado registro caso fizéssemos um update neste registro dentro de uma transação, onde devido ao nível de isolamento usado nesta transação o regis-tro não ficaria disponível para visualização. Como é esta técnica: faríamos um update, um delete de um registro (optimistic locking) ou conjunto de registro (pessimistic locking) quando não se sabe ao certo qual registro irá ser alterado, sendo que a instrução usada para travar um determinado registro seria:

UPDATE CUSTOMER SET CUST_NO = CUST_NOWHERE CUST_NO = CUST_NO

Observe que neste caso não alteramos o valor do campo código, mas o registro entrou na transação uma vez que foi executado o update sobre ele. Para liberar o registro ou um conjunto de registros basta executar o COMMIT ou ROLLBACK na transação corrente.

3- Com cláusula WITH LOCK

Na versão 1.5 do firebird entre as diversas novi-dades que foram lançadas, uma delas foi a cláusula WITH LOCK, com esta instrução podemos travar um conjunto de registros a partir de um simples select.

Esta cláusula realiza um lock pessimista explicito de registros, assim sugiro que sempre a use em conjunto com a cláusula WHERE a fim de filtrar a seleção de registros.

A seguir veja um exemplo de sua utilização:

SELECT * FROM CUSTOMERWHERE CUST_NO = 1001WITH LOCK

4- Exemplo

Neste exemplo irei exemplificar o travamento de apenas um registro no momento de sua edição, trabalharemos com o banco EMPLOYEE, mais preci-samente com a tabela CUSTOMER, onde na edição do registro dos dados do cliente iremos travar o registro para que nenhum outro usuário consiga editar o mesmo registro simultaneamente.

No Delphi crie uma nova aplicação e chame de LockRegistro.dpr, e um formulário principal que iremos salvar como unPrincipal.pas, alterando o nome do formulário para frmPrincipal, este for-mulário principal terá como objetivo apenas listar os registros da tabela para sua seleção e edição. Neste formulário (Imagem 1) adicione e configure os seguintes componentes:

janeiro 200920

TSQLConnection

Propriedades Valor

Name sqlConexao

ConnectionName ‘LOCKREGISTRO’

DriverName ‘Interbase’

Params.Strings ( ‘DriverName=Interbase’ ‘Database= EMPLOYEE.GDB’ ‘RoleName=RoleName’ ‘User_Name=sysdba’ ‘Password=masterkey’ ‘ServerCharSet=’ ‘SQLDialect=3’ ‘BlobSize=-1’ ‘CommitRetain=False’ ‘WaitOnLocks=False’ ‘ErrorResourceFile=’ ‘LocaleCode=0000’ ‘Interbase TransIsola-tion= ReadCommited’ ‘Trim Char=False’)

Connected True

TSQLDateSet

Propriedades Valor

Name sqlCustomers

CommandText ‘select * from CUSTOMER’

SQLConnection sqlConexao

TDateSetProvider

Propriedades Valor

Name dspCustomers

DataSet sqlCustomers

TClientDateSet

Propriedades Valor

Name cdsCustomers

ProviderName ‘dspCustomers’

Active True

TDataSource

Propriedades Valor

Name dsCustomers

DataSet cdsCustomers

TDBNavigator

Propriedades Valor

DataSource dsCustomers

VisibleButtons [nbFirst, nbPrior, nbNext, nbLast, nbCancel, nbRe-fresh]

TDBGrid

Propriedades Valor

Name dbGridCustomers

DataSource dsCustomers

ReadOnly True

Nas configurações dos componentes listados acima, a mais importante no contexto deste artigo é a alteração do parâmetro WaitOnLocks do TSQL-Connection para False, este parâmetro tem como objetivo controlar a espera ou não da aplicação quando lock de registro for identificado, ou seja com esta propriedade como True, quando um de-terminado registro já locado for ser selecionado a aplicação irá ficar travada aguardando a liberação do registro, para que possa fazer o “fetch” deste re-gistro. Este é um comportamento desagradável que não desejamos em nossa aplicação, assim iremos alterar esta propriedade para False, onde quando lock de registro for identificado, irá ser retornada uma mensagem de erro de deadlock que iremos tratar. Não se esqueça também de adicionar os TFields no ClientDataSet

Veja a Imagem 1.

Agora crie um formulário que iremos usar para edição do registro e salve como unCustomer.pas e altere a propriedade name do formulário para frmCustomer. Adicione nesta unit a referência da

Imagem 1

unit unPrincipal.pas com Alt+F11. Neste formulá-rio (Imagem 1) adicione e configure os seguintes componentes:

TSQLDataSet

Propriedades Valor

Name sdsCustomer

CommandText ‘select * from CUSTOMER’

SQLConnection frmPrincipal.sqlConexao

TDataSetProvider

Propriedades Valor

Name dspCustomer

DataSet sdsCustomer

Options [poAllowCommandText]

UpdateMode upWhereKeyOnly

TDataSource

Propriedades Valor

Name dsCustomer

DataSet ‘dspCustomer’

TDataSource

Propriedades Valor

Name cdsCustomer

ProviderName ‘dspCustomer’

Adicione também os campos (TFields) tanto no SqlDataset quanto no ClientDataset, e configure os ProviderFlags do campo chave primária CUST_NO como: [pfInUpdate, pfInWhere, pfInKey], e para os demais campos: [pfInUpdate]. Também colo-

janeiro 2009 21

que os respectivos DBEdit para cada campo e um DBNavigator.

Veja a Imagem 2.

Como a idéia é no formulário principal ao dar um duplo-clique no DBgrid abrir a janela de edição (frmCustomers), vamos adicionar o evento DblClick no dbGridCustomers, não se esquecendo de adicionar a unit unCustomer.pas no uses da unit principal, coloque a seguinte instrução :

Veja o código fonte 1.

Dica: Observe que na criação do frmCus-tomer criamos um segundo parâmetro para informar para o formulário o valor do campo CUST_NO. Para isto faremos um overload do constructor da classe do formulário, so-brescrevendo o create do constructor, onde neste evento iremos capturar o valor do pa-râmetro e atribuir para uma variável privada na mesma classe, veja código abaixo o código correspondente:

Veja o código fonte 2.

Vamos adicionar o evento OnCreate no form frmCustomer, neste evento iremos iniciar um transação a partir do SqlConnection que esta no form principal, somente após a transação iniciada iremos fazer um select filtrando pelo valor chave da tabela CUSTOMER para que assim apenas um registro seja retornado e travado. Caso o registro já esteja travado por outro usuário irá ser retornado uma exceção no memento da execução de open, isto por termos alterado a propriedade WaitOn-Locks dos parâmetros de conexão para false, caso contrário como já disse anteriormente, o aplicação ficaria travada aguardando o momento em que o registro fosse liberado.

Observe que caso haja a exceção faço um tratamento na mensagem de erro, onde se ela retornar ‘SQL Server Error: lock conflict on no wait transaction deadlock update conflicts with concurrent update’, indicará que o registro está em uso, assim exibo uma mensagem mais amigável, e então executo o método PostMessage(self.handle, WM_CLOSE, 0, 0); para fechar o form frmCustomer antes que o mesmo fosse exibido.

Imagem 2

implementation

uses unCustomer;

{$R *.dfm}

procedure TfrmPrincipal.dbGridCustomersDblClick(Sender: TObject);begin frmCustomer := TfrmCustomer.Create(Self, cdsCustomersCUST_NO.AsInteger); frmCustomer.ShowModal; frmCustomer.Free;end;

end.Código Fonte 1

janeiro 200922

{...} private _CUST_NO: Integer; public constructor Create(AOwner: TComponent; CUST_NO: Integer); overload; end;

var frmCustomer: TfrmCustomer; TD: TTransactionDesc;

implementation

uses unPrincipal;

{$R *.dfm}

constructor TfrmCustomer.Create(AOwner: TComponent; CUST_NO: Integer);begin inherited Create(Owner); _CUST_NO := CUST_NO;end;{...}

Código Fonte 2

Veja o código fonte 3.

Para aplicar as modificações deve ser execu-tado após o post o método Applyupdates, assim adicione o evento OnAfterPost no Clientdataset cdsCustomer, e insira a seguinte instrução:

procedure TfrmCustomer.cdsCustomer AfterPost(DataSet: TDataSet);begin cdsCustomer.ApplyUpdates(0);end;

O mesmo deve ser feito para o caso de deleção, para isto apenas ligue o evento OnAfterDelete ao método cdsCustomerAfterPost através do Object Inspector, para fazer o reaproveitamento do código.

Finalmente iremos adicionar no evento OnClo-se do form as instruções para confirmar a gravação, ou seja executar o commit na transação, e no caso de uma falha no processo realizar o rollback da transação.

Veja o código fonte 5:

5- Conclusão

With lock deve ser usado com bastante cons-ciência, pois serão pouquíssimos os casos em que ele é realmente necessário, o seu uso inadequado pode causar o aumento da mensagem de erro de deadlock, inclusive o nosso exemplo foi feito ape-nas com o objetivo de instruir de como utilizar esta cláusula, mas dependendo da aplicação pode não ser viável a sua utilização para a mesma situação. Considerando o uso apropriado desta cláusula, ele irá facilitar o processo e controle de travamento de registro.

Download do Exemplo:http://www.theclub.com.br/REVISTA/

rev0109/LockRegistro.zip

Download do video aula explicativo:http://www.theclub.com.br/REVISTA/

rev0109/LockRegistroVA.zip

Leia mais sobre a cláusula WITH LOCK no artigo Novidades do FireBird 1.5

http://www.theclub.com.br/REVISTA/NO-VI0504.ASPX

procedure TfrmCustomer.FormCreate(Sender: TObject);const SQLCustomer: string = ‘select * from CUSTOMER where CUST_NO = %d WITH LOCK’;begin Randomize; { Abre uma transação para controlar o processamento todo } TD.TransactionID := Random(65635); TD.IsolationLevel := xilREADCOMMITTED;//xilREPEATABLEREAD; frmPrincipal.sqlConexao.StartTransaction(TD); cdsCustomer.CommandText := Format(SQLCustomer, [_CUST_NO]); try cdsCustomer.Open; except on E: Exception do begin if pos(‘SQL Server Error: lock conflict on no wait transaction’#$A’deadlock’#$A’update conflicts with concurrent update’,E.Message) > 0 then ShowMessage(‘Registro Em Edição, tente mais tarde!’); //Fechar Form antes mesmo que ele seja exibido PostMessage(self.handle, WM_CLOSE, 0, 0); end; end;end;

Código Fonte 3

janeiro 2009 23

procedure TfrmCustomer.FormClose(Sender: TObject; var Action: TCloseAction);begin try if cdsCustomer.State in [dsInsert, dsEdit] then cdsCustomer.Post; frmPrincipal.sqlConexao.Commit(TD); { Em caso de sucesso, confirma a transação } except on E: Exception do {Em caso de erro, aborta todo processamento } if frmPrincipal.sqlConexao.InTransaction then frmPrincipal.sqlConexao.Rollback(TD); end; cdsCustomer.Close;end;

Código Fonte 5

Sobre o autor

Marcos César Silva, Consultor de Sistemas na consultoria de sistemas DataSmart e Consultor Técnico do The Club, Bacharel em Ciência da Computação, MBA em Gestão Empre-sarial, Certificações MCAD (Microsoft Certified Application Developer) e MCSD.NET (Microsoft Certified Solution Developer .NET)

Confira o video deste artigo no site do The Club na edição online da revista.

janeiro 200924

O ASP.NET 3.5 introduziu dois novos controles de manipulação de dados o ListView e o DataPager ListView Server controls que nos permitem exibir dados de uma fonte de dados e com o DataPager podemos paginar os dados exibidos no ListView de maneira muito simples. O listView dá ao usuário total controle sobre o processamento da página. usando modelos e estilos (CSS), o usuário pode gerar HTML interface limpa, de acordo com suas necessidades..

ListView: E um controle de dados parecido com o DataList e o DataRepeater com as funcionalidade de edit, insert, e delete , sort, como o GridView. Uma coisa que ele tem que o GridView não possui e a possibilidade de controlar todo seu HTML de output, utilizar css gerando um output mais limpo e de qualidade.

DataPager: E um controle Web utilizado para paginar um controle de data e exibir os controles de navegação de paginas, ele so pode ser utilizado com controles que implementam a interface IPa-geableItemContainer. O ListView implementa esta interface e portanto pode utilizar o DataPager para fazer o trabalho de paginação de dados, e o que vamos fazer agora em nossa artigo.

Implementando um DataSource no ListView:

Podemos utilizar qualquer controle ASP.NET de DataSource para Bindar os dados no ListView, Colocando o DataSourceID propriedade do Lis-

Utilizando ListView e

DataPager novos componentes

da FrameWork 3.5tView para o nome do DataSource que será utilizado.

Podemos utilizar qualquer controle ASP.NET de DataSource para Bindar os dados no controle ListView, fixando o DataSourceID propriedade do controle ListView para o nome do controle de DataSource.

Neste Exemplo Utilizaremos o LinqData-

Source para recuperar os dados que serão exibidos no ListView

Veja o código fonte 1.

ListView fornece uma espécie de apoio para a funcionalidade de SORT. Tem um evento, que pode ser especificado através da definição da proprieda-de do controle commandName, que faz parte do controle ListView ao efetuar o “Sort”. O evento Sort suporta o command argument que pode ser usado para identificar qual controlo disparou o evento. O evento SORT e registrado no controle atravez da diretiva OnSorting propriedade do ListView para o manipulador nome.

Exemplo de como utilizar o evento SORT no ListView:

Veja o código fonte 2.

Manipulando o evento SORT

Veja o código fonte 3.

Entendendo os templates do Lis-tView:

- LayoutTemplate

<asp:ListView ID=”lvwExemplo” DataSourceID=”LinqDataSource1” runat=”server” OnSorting=”ListView1Sorting” DataKeyNames=”id” OnItemCommand=”ItemUpdate”>

- ItemTemplate- ItemSeparatorTemplate- GroupTemplate- GroupSeparatorTemplate- EmptyItemTemplate- EmptyDataTemplate- SelectedItemTemplate- AlternatingItemTemplate- EditItemTemplate- InsertItemTemplate

Código Fonte 1

janeiro 2009 25

O principal esquema do controle ListView é criada pela definição de um LayoutTemplate. O LayoutTemplate irá incluir controles que funciona como um marcador para os dados, pois dentro dele serão inseridos os outros controles ele será a moldura dos elementos que o ListView irá exibir.

Item template é o principal modelo que irá exibir os dados como um repetidor. Este template geralmente contém itens data-bound, que são vinculados aos dados de cada coluna ou outros ele-mentos de dados individuais. Estes dois templates são obrigatórios.

GroupTemplate serão usados para agrupar os itens. O EditItemtemplate, SelectedItemTemplate, InsertItemTemplate são exibidos em operação como inserir, editar, selecionar. ItemSeparator-Template, GroupSeparatorTemplate são utilizados para separar os itens individuais e separador de grupo de itens.

Vamos utilizar cada modelo para incorporar os necessários controlos HTML como tabela, tr, td, div, span ou Server control pra que a exibição da UI saia de acordo com nossas necessidades.

O exemplo a seguir mostra a estrutura básica de um ListView com os templates obrigatórios modelos ...

Veja o código fonte 4.

Um itemplaceholder deve ser especificado dentro do LayoutTemplate, pois será nele que o ListView irá inserir o itemTemplate quando compilado. Parece confuso mais não é! Vamos La, primeiro definimos o LayoutTemplate que será a moldura de nosso quando como no exemplo acima colocamos uma Tabela como LayoutTemplate, e dentro dele definimos um itemPlaceholder que será utilizado para repetir o itemPlaceholder com os dados do DataSorce.

Lets Rock!!!Agora Vamos colocar a mão na massa! Va-

mos criar um ListView que irá exibir uma lista de clientes.

Preparando o LayoutTemplate

Precisamos criar o LayoutTemplate usando os controles necessários HTML como tabela, tr, td (com estilos) para a formatação e ASP.Net Server Controls (Botões, LinkButtons, DataPager) para exi-bir os cabeçalhos, assim como rodapés. We need to use a itemplaceholder for displaying the items from data source. Temos de usar uma itemplaceholder

<asp:ListView ID=”lvwExemplo” DataSourceID=”LinqDataSource1” runat=”server” OnSorting=”ListView1Sorting” DataKeyNames=”id” OnItemCommand=”ItemUpdate”>

<asp:LinkButton runat=”server” ID=”lnkOrdenarNome” Texto=”Corpo” CommandName=”Ordenar” CommandArgument=”Nome” />

protected void ListView1Sorting(Object sender, ListViewSortEventArgs e) { String strImage; if (e.SortDirection == SortDirection.Ascending) strImage = “asc.gif”; else strImage = “desc.gif”; Image sortSender = (Image)lvwExemplo.FindControl(“Image1”); Image sortSubject = (Image)lvwExemplo.FindControl(“Image2”); Image sortRecdate = (Image)lvwExemplo.FindControl(“Image3”); Image sortBody = (Image)lvwExemplo.FindControl(“Image4”);

if (e.SortExpression == “From”) { sortSender.ImageUrl = strImage; sortSender.Visible = true; sortSubject.Visible = false; sortRecdate.Visible = false; sortBody.Visible = false; } else if (e.SortExpression == “Subject”) { sortSubject.ImageUrl = strImage; sortSender.Visible = false; sortSubject.Visible = true; sortRecdate.Visible = false; sortBody.Visible = false; } else if (e.SortExpression == “recdate”) { sortBody.ImageUrl = strImage; sortSender.Visible = false; sortSubject.Visible = false; sortRecdate.Visible = true; sortBody.Visible = false; } else if (e.SortExpression == “Body”) { sortBody.ImageUrl = strImage; sortSender.Visible = false; sortSubject.Visible = false;

Código Fonte 2

Código Fonte 3

janeiro 200926

para exibir os itens da fonte de dados.

Preparando DataPager

O controle DataPager é usado para exibir a página de dados e controles de navegação de dados vinculada controlos que implementam a interface IPageableItemContainer.

Um controle DataPager pode estar associada ao controle de dados vinculados usando a pro-priedade PagedControlID. Alternativamente, o controle DataPager pode ser colocado no interior do controlo de dados vinculado.

Controle DataPager exibirá a navegação do controle adicionando ao campos para o controlo. DataPager utiliza os seguintes tipos de campos.

NextPreviousPagerField: Permite navegar através das páginas uma página de cada vez, ou para saltar para a primeira ou a última página. Ele mostra os botões primeiro, anterior, próximo e último. O botão pode ser do tipo Button, Imagem, LinkButton.

NumericPagerField: permite navegar por páginas apresentando números de página sobre o datapager.

TemplatePagerField: podemos criar UI perso-nalizado utilizando TemplatePagerField. Podemos usar Label, botões, para criar imagens persona-lizadas IU programáticos, bem como o controlo da DataPager.

Veja a imagem 1.

Para criar o DataPager de acordo com a imagem acima, temos de usar NumericPagerField bem como TemplatePagerField como parte do Da-taPager Fields. Podemos usar propriedades como PageSize do controle DataPager, TotalRowCount, StartRowIndex para criar o TemplatePagerField.

PageSize: qual página esta sendo exibido no DataPager.

TotalRowCount: é o numero de linhas apre-sentados no DataPager.

StartRowIndex: é a primeira linha, o primeiro registro que será exibido.

Veja o código fonte 5.

Preparando ItemTemplate & Alterna-tive ItemTemplate

Precisamos inserir as tags HTML, bem como

Server controls como checkboxes, labels, buttons, a fim de obter o layout dos itens dentro do ItemTem-plates assim como no AlternativeItemTemplates. Os dados serão inseridos nos controles usando o código inline do ASP.Net

sortRecdate.Visible = false; sortBody.Visible = true; } else {

sortSender.Visible = false; sortSubject.Visible = false; sortRecdate.Visible = false; sortBody.Visible = false; } } Continuação do Código Fonte 3

<asp:ListView runat=”server” ID=”lvwExemplo1” DataSourceID=”SqlDataSource1”> <LayoutTemplate> <table runat=”server” id=”table1” runat=”server”> <tr runat=”server” id=”itemPlaceholder”> </tr> </table> </LayoutTemplate> <ItemTemplate> <tr runat=”server”> <td id=”Td1” runat=”server”> <%-- Data-bound content. --%><asp:Label ID=”NameLabel” runat=”server” Text=’<%#Eval(“Name”) %>’ /> </td> </tr> </ItemTemplate> </asp:ListView> Código Fonte 4

<asp:DataPager runat=”server” ID=”ItemDataPager” PageSize=”12” PagedControlID=”ListView1”> <Fields> <asp:NextPreviousPagerField ButtonType=”Link” ShowFirstPageButton=”true” ShowPreviousPageButton=”true” ShowLastPageButton=”true” ShowNextPageButton=”true” /> <asp:TemplatePagerField> <PagerTemplate> <b>showing

Imagem 1.

Código Fonte 5

janeiro 2009 27

Veja o Código fonte 6.

Preparando EditItemTemplate & In-sertItemTemplate

Da mesma forma que vamos criar o EditIte-mTemplate bem como InsertItemTemplate, mas em vez de Label, vamos utilizar como TextBox

<asp:Label runat=”server” ID=”CurrentPageLabel” Text=”<%# Container.StartRowIndex %>” /> to <asp:Label runat=”server” ID=”TotalPagesLabel” Text=”<%# Container.StartRowIndex+Container.PageSize %>” /> ( of <asp:Label runat=”server” ID=”TotalItemsLabel” Text=”<%# Container.TotalRowCount%>” /> records) <br /> </b> </PagerTemplate> </asp:TemplatePagerField> </Fields> </asp:DataPager>

<% # Eval ( “datafieldname”)%>, onde o datafiledname é o nome da coluna no datasoure.

<ItemTemplate> <tr title=”Tooltip text goes here!” onmouseover=”this.style.backgroundColor=’#FFCCFF’” onmouseout=”this.style.backgroundColor=’#FFFFFF’”> <td> <asp:CheckBox ID=”ID” runat=”server” /> </td> <td> <asp:Label ID=”lbFrom” runat=”server”> <%#Eval(“FirstName”)%> </asp:Label> </td> <td> <asp:Label ID=”lbSubject” runat=”server”><%#Eval(“LastName”)%></asp:Label> </td> <td> <asp:Label ID=”lbrecdate” runat=”server”><%#Eval(“BirthDate”)%></asp:Label> </td> <td> <asp:Label ID=”lbBody” runat=”server”><%#Eval(“Country”)%></asp:Label> </td> <td> <asp:Button ID=”EditButton” runat=”Server” Text=”Read” CommandName=”Edit” /> </td> </tr> </ItemTemplate>

Continuação do Código Fonte 5

Código Fonte 6

janeiro 200928

Anuncie

conosco

Solicite um orçamento:

Skype: theclub_cadastro

E-mail: [email protected]

Fone: (14) 3732-1529

Anuncie na revista e ganhe um

banner publicitário no site do The Club

Sobre o autor

Veja o código fonte 7.

Bem pessoal neste artigo pudemos ver como o ListView pode ser bem útil em nossos projetos, ainda mais hoje em dia em que a qualidade dos código HTML gerado levado mais a serio, e com esse controle podemos controlar toda a saída da nossa aplicação. E o mais legal e poder utilizar o controle DataPager para fazer a paginação dos dados de maneira simples e funcional.

Espero ter ajudado.

Bons Códigos...

<EditItemTemplate> <tr> <td> <asp:TextBox ID=”tbFrom” runat=”server” Enabled=”false” Text=’<%#Bind(“FirstName”)%>’ /> </td> <td> <asp:TextBox ID=”tbSubject” runat=”server” Enabled=”false” Text=’<%#Bind(“LastName”)%>’ /> </td> <td> <asp:TextBox ID=”tbrecdate” runat=”server” Enabled=”false” Text=’<%#Bind(“BirthDate”)%>’ /> </td> <td> <asp:TextBox ID=”tbBody” runat=”server” Enabled=”false” Text=’<%#Bind(“Country”)%>’ /> </td> <td> <asp:Button ID=”DeleteButton” runat=”Server” Text=”Delete” CommandName=”Delete” /> </td> </tr> </EditItemTemplate>Insert:<InsertItemTemplate> <tr> <td> <asp:TextBox ID=”tbFrom” runat=”server” Enabled=”true” Text=’<%#Bind(“FirstName”)%>’ /> </td> <td> <asp:TextBox ID=”tbSubject” runat=”server” Enabled=”true” Text=’<%#Bind(“LastName”)%>’ /> </td> <td> <asp:TextBox ID=”tbrecdate” runat=”server” Enabled=”false” Text=’<%#Bind(“BirthDate”)%>’ /> </td> <td> <asp:TextBox ID=”tbBody” runat=”server” Enabled=”true” Text=’<%#Bind(“Country”)%>’ /> </td> <td> <asp:Button ID=”InsertButton” runat=”Server” Text=”Send” CommandName=”Insert” /> </td> </tr> </InsertItemTemplate>

Fabiano BelmonteSenior Architect da InfoMoney.com, es-

pecialista em aplicações e-Business com larga experiência em B2B (Submarino.Com e Saraiva.Com). Trabalha há 5 anos com a tecnologia .Net, aplicando conhecimentos nas diversas áreas: instituições financeiras (sistema SPB), e-Commerce, gerenciamento logístico entre outras. Trabalhando com Visual Studio desde suas primeiras versões, responsável pela implementação de uma Metodologia de tra-balho e melhoras significativas no resultados e na qualidade do time de Desenvolvimento de muitas empresas por onde passou como (Saraiva.Com) e ferramentas como TFS (Team Foundation Server).

Foi palestrante em eventos como Codi-ficando. NET 2008 e outros eventos sobre Tecnologia .NET.

Instrutor da e-TNIAX Group especialista em C#, ASP.NET e Silverlight. www.etniax.com.br

Código Fonte 7

janeiro 2009 29

Dicas DELPHI

FORMS – Colorir automaticamente quando o mouse passa por cima do componente.

Neste exemplo estamos utilizando o componente Label e CheckBox .

procedure ChangeColor(Sender : TObject; Msg : Integer); procedure WndProc(var Msg : TMessage); override; private { Private declarations } public { Public declarations } end;

var Form1: TForm1;implementation{$R *.DFM}

procedure TForm1.WndProc(var Msg : TMessage);var i: Integer;begin for i := 0 to ComponentCount-1 do if Msg.LParam = Longint(Components[i]) then ChangeColor(Components[i], Msg.Msg); inherited WndProc(Msg);end;

procedure TForm1.ChangeColor(Sender : TObject; Msg : Integer);begin if Sender is TLabel Then begin if (Msg = CM_MOUSELEAVE) then

(Sender as TLabel).Font.Color := clWindowText; if (Msg = CM_MOUSEENTER) then (Sender as TLabel).Font.Color := clBlue; end; if Sender is TCheckBox Then begin if (Msg = CM_MOUSELEAVE) then (Sender as TCheckBox).Font.Color := clWindowText; if (Msg = CM_MOUSEENTER) then (Sender as TCheckBox).Font.Color := clRed; end;end;end.

Password – Gerar senha randônica

function RandomPassword(PLen: Integer): string;var str: string;begin Randomize; //possíveis caracteres str := ‘abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ’; Result := ‘’; repeat Result := Result + str[Random(Length(str)) + 1]; until (Length(Result) = PLen)end;

procedure TForm1.BitBtn1Click(Sender: TObject);begin //tamanho da senha Caption := RandomPassword(10);end;

janeiro 200930

janeiro 2009

janeiro 2009