the club - megazine · um forte abraço, av. profº celso ferreira da silva, 190 jd. europa -...

32
julho 2012

Upload: ngobao

Post on 29-Nov-2018

215 views

Category:

Documents


0 download

TRANSCRIPT

julho 2012

julho 2012

julho 2012 03

Desafio The ClubDicas

30

Android Delphi

C#Delphi

Iniciando o uso de Joysticks - Uma abordagem prática

Criando um formulário de pesquisa padrão com o Delphi XE

Delphi

índiceAsp.Net - Criando um formulário para Upload de Arquivos

Editorial

1004Delphi Parte IV

05Android - Criando uma tela de Pesquisa de dados

14

28

20

LegendaInicianteIntermediárioAvançado

Autor: Marcos C. Silva

Autor: Thiago C. Montebugnoli

Autor: Luciano Pimenta

Autor: Victory Fernandes 23Autor: Lucas Vieira

de Oliviera

julho 201204

Bem-vindo

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

pelos seus respectivos proprietários.

Thiago Montebugnoli - Editor [email protected]

“Smoke on the Water”! “Born to be Wild”! Não assustem, pois estão lendo a boa e velha revista “The Club Magazine”.

Isto é apenas uma singela homenagem ao dia 13 de Julho, o dia mundial do “Rock and Roll”. Tão bom quanto um “Rock” são os artigos deste mês, começando com nosso colaborador mensal Luciano Pimenta, que nos traz a quarta parte da seqüência dos artigos do Curso de Delphi para iniciantes.

Este mês, Marcos César Silva, nos ensina a Criar um formulário para Upload de Arquivos, servindo de exemplo para anexá-los em um projeto de site por exemplo. Depois de um tempo fora, nosso colaborador Victory Fernandes volta abordando de uma forma prática o uso de “Joysticks”.

Já o consultor técnico Lucas Vieira de Oliveira, nos mostra como criar um formulário de pesquisa padrão com o Delphi XE. É sempre bom ter em mente este tipo de artigo quando o assunto se trata de reaproveitamento de códigos e telas.

Eu continuo escrevendo sobre o Sistema Android, sendo que desta vez faço uma abordagem de como criar uma tela de pesquisa de dados. Uma dica interessante para quem desenvolve sistemas para esta plataforma.

Lembrando também da seção de “Dicas Delphi”, que como todo mês nos proporciona muitas novidades relacionadas a este assunto.

Vou ficando por aqui, deixando saudações “Roqueiras” a todos os leitores.

Um Forte abraço,

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

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

Internethttp://www.theclub.com.br

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

Skype Suporte: theclub_linha1 theclub_linha2 theclub_linha3

www.twitter.com/theclubbr

Copyright The Club 2012

Diretor TécnicoMarcos César Silva

DiagramaçãoEduardo Massud

ArteVitor M. Rodrigues

RevisãoCíntia Amaral

ColunistasMarcos César Silva

Thiago Cavalheiro MontebugnoliLuciano Pimenta

Victory FernandesLucas Vieira de Oliveira

Impressão e acabamento:GRIL - Gráfica e Editora

Taquarituba-SP - Tel. (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.

julho 2012 05

Delphi

D e l p h i Parte IV

Vimos no artigo anterior, a VCL (Visual Library Component) biblioteca de componentes visuais do Delphi. Claro, não pudemos ver em toda sua extensão, pois isso daria um livro, mas conhecemos os principais componentes e conheceremos outros no decorrer do curso.

Neste artigo conheceremos uma parte muito importante de aplicações Delphi, a conectividade com bando de dados. Atualmente, a quantidade de

servidores de banco de dados é bastante grande, então você pode ficar em dúvida, será que o Delphi pode conectar ao banco de dados da minha aplicação.

A resposta é quase que imediata: Sim.

Caso o servidor do seu banco não possui um

driver para o Delphi, você pode usar outros tipos

de conectividade, como ODBC, ADO etc. Ou seja, as

possibilidades são muitas.

O Delphi inicialmente utilizava o BDE (Borland Figura 1. BDE Admin

julho 201206

Database Engine), um núcleo da própria Borland que

usava banco de dados Paradox e dBase.

O BDE possui vários utilitários para acessar o banco,

manipular objetos e dados.

Veja na Figura 1 o BDE Admin, front-end para criar

conexões, criar objetos e manipular dados dos bancos de

dados suportado pelo BDE.

Com o tempo, devido a vários fatores, o mesmo foi

descontinuado (mas possui componentes até hoje no

Delphi para compatibilidade), entrando no seu lugar o

dbExpress, engine mais leve e que pode usar vários tipos

de servidores de bancos de dados. O dbExpress maximiza

a velocidade, pois seus drivers são pequenos, rápidos e

de fácil distribuição (basta um arquivo DLL).

Além disso, o dbExpress é cross-plataform. Em

conjunto com o ClientDataSet, o dbExpress se torna

uma arquitetura de alta performance e concorrência

para suas aplicações, pois o ClientDataSet usa dados em

memória, ou seja, você pode trabalhar desconectado. No

dbExpress, cada componente tem sua responsabilidade,

diferente do BDE, onde componentes responsáveis por

mostrar dados, também podem conectar ao banco de

dados.

Na Tabela 1, temos os componentes da arquitetura

e suas responsabilidades.

Veja na Figura 2, os componentes da aba dbExpress.

Para criarmos uma conexão para manipular um

cadastro, precisamos do quarteto: SQLConnection +

SQLDataSet + DataSetProvider + ClientDataSet. Vamos

criar um exemplo para entendermos o funcionamento.

Caso você pense que precisa de todos os componentes

para cada cadastro, calma! Mostrarei vários exemplos

para utilizar em aplicações cliente/server usando

dbExpress.

Criando o banco de dados

Primeiramente, vamos criar o banco de dados que

usaremos nos exemplos do artigo. Usarei nesse artigo o

SQL Server 2008 Express, mas fique a vontade de usar

outro banco de dados, pois o Delphi (dbExpress) suporta:

DB2, Firebird, Informix, Interbase, SQL Server, MySQL,

Oracle e conexões ODBC, como já comentado.

Esta bom para você essas possibilidades? Dessas

opções, tem versão gratuita (SQL Server Express, Oracle

Express, MySQL) ou é totalmente gratuito (Firebird).

Abra um front-end para gerenciar seu banco de

dados, nesse caso, vou usar o SQL Server Management

Studio. Veja o script de criação das tabelas do nosso

banco na Listagem 1.

Listagem 1. Script para criação das tabelas do banco

CREATE TABLE CLIENTE( nCdCliente int not null primary key identity, sNmCliente varchar(50) not null, tDtNascimento datetime, --limite de crédito do cliente nVlLimite decimal(9,2) not null )

CREATE TABLE SETOR( nCdSetor int not null primary key identity, sNmSetor varchar(30) not null)

CREATE TABLE EMPREGADO( nCdEmpregado int not null primary key identity, --empregado esta vinculado a um setor nCdSetor int not null, sNmEmpregado varchar(50) not null, tDtAdmissao datetime not null, --percentual de comissão do empregado nPcComissao decimal(2,0) not null )

ALTER TABLE EMPREGADO ADD CONSTRAINT FK_SETOR FOREIGN KEY (nCdSetor) REFERENCES SETOR(nCdSetor)

CREATE TABLE PRODUTO( nCdProduto int not null primary

Tabela 1. Componentes do dbExpress e suas responsabilidades

Figura 2. Aba dbExpress e seus componentes

julho 2012 07

key identity, sNmProduto varchar(50) not null, tDtValidade datetime not null, nQtEstoque decimal(9,2) )

CREATE TABLE VENDA( nCdVenda int not null primary key identity, --a venda deve ter um cliente e um empregado nCdCliente int not null, nCdEmpregado int not null, tDtVenda datetime not null, nVlVenda decimal(9,2) not null )

ALTER TABLE VENDA ADD CONSTRAINT FK_CLIENTE FOREIGN KEY (nCdCliente) REFERENCES CLIENTE(nCdCliente)ALTER TABLE VENDA ADD CONSTRAINT FK_EMPREGADO FOREIGN KEY (nCdEmpregado) REFERENCES EMPREGADO(nCdEmpregado)

CREATE TABLE ITENS( nCdVenda int not null, nCdProduto int not null, nVlItem decimal(9,2) not null, nQtItem decimal(9,2) not null)

ALTER TABLE ITENS ADD CONSTRAINT FK_VENDA FOREIGN KEY (nCdVenda) REFERENCES VENDA(nCdVenda)ALTER TABLE ITENS

ADD CONSTRAINT FK_PRODUTO FOREIGN KEY (nCdProduto) REFERENCES PRODUTO(nCdProduto)

Coloquei comentários para o leitor entender alguns

campos colocados nesse script. Não faz parte desse

artigo ou série, explicar os tipos de campos, chaves etc

do banco de dados. Acredito que o leitor já tenha algum

conhecimento sobre os mesmos.

No decorrer da série vamos modificar ou adicionar

objetos nesse banco de dados. Alguns registros foram

inseridos diretamente no banco, pois não mostrarei

todos os cadastros (como por exemplo SETOR, que é

bastante simples).

Criando o Data Module

Para usarmos os componentes indicados

anteriormente, vamos criar um Data Module. O DM é

um container para adicionar os componentes de acesso

a dados, o que torna a manutenção do projeto, bem

mais fácil.

Ainda no DM, podemos colocar os métodos para as

regras de negócio da nossa aplicação, ou seja, estamos

deixando nosso projeto bem organizado e estruturado.

Você já deve ter criado um novo projeto Delphi, então

acesse File>New>Others e no item Delphi Files escolha

Data Module (Figura 3).

Figura 3. Criando o Data Module

Dê o nome de “DM” e salve o arquivo. Podemos

ter quantos DM quisermos no projeto, mas isso deve ser

analisado com cuidado na hora de implementar para que

aplicação não tenha problemas de performance ou fique

com muitos arquivos desnecessários.

Agora, podemos adicionar um SQLConnection ao

DM e configurar as opções para acesso ao banco de

dados. Outra maneira de fazermos isso é criar uma

conexão com o banco utilizando o Data Explorer.

Vamos com a segunda opção. No Data Explorer

expanda o item MSSQL e veja as conexões que podem

estar criadas. Clique com o botão direito no MSSQL

e escolha Add New Connection. No editor, digite

“DelphiTheClub”. Será criado um item filho do MSSQL

com o nome digitado anteriormente.

Expanda o item, e veja que temos Tables, Views,

Procedures, Functions etc. Ou seja, a maioria dos objetos

do banco de dados para manipularmos diretamente do

Delphi. Clique com o botão direito em DelphiTheClub e

escolha Modify Connection.

Será aberto um editor para configurarmos a

conexão com o banco de dados criado anteriormente.

Veja na Figura 4 as opções que devemos digitar.

Nota: Lembrando apenas que a configuração de Server Name e Database Name podem mudar, de acordo com a configuração da sua máquina.

Caso você tenha um usuário cadastrado para

conexão ao banco de dados, basta usar o User Name

e Password e fazer a conexão. Outra maneira é usar o

próprio Windows para isso. Acesse o botão Advanced

e altere para true a opção os autenthication. Feche o

editor e clique em Test Connection. Se os dados estiverem

corretos, você receberá a mensagem que a conexão foi

realizada com sucesso.

Feche o editor e de volta ao Data Explorer expanda o item Tables. Iremos visualizar as tabelas criadas anteriormente (Figura 5).

Para facilitar, clique sobre o item DelphiTheClub e arraste o mesmo para o DM. O Delphi adiciona um

Figura 4. Configurando a conexão com o banco de dados

julho 201208

SQLConnection com a configuração para acesso ao banco. Para testar, altere para True a propriedade Connected. Pronto! Temos uma conexão com o banco de dados pronta no DM.

Criando o cadastro de clientes

Bom, agora, precisamos configurar os componentes

do dbExpress para criarmos o primeiro cadastro da

aplicação, o de clientes. Adicione no DM um SQLDataSet,

um DataSetProvider e um ClientDataSet. Veja na Figura 6

os componentes dispostos no DM e seus nomes.

Figura 6. Componentes no Data Module

Agora, precisamos configurar os componentes.

No dsCliente, altere a propriedade SQLConnection

para “DelphiTheClub” (ou seja, o SQLConnection). Na

propriedade ComandText, digite: “select nCdCliente,

sNmCliente, tDtNascimento, nVlLimite from CLIENTE”.

Uma dica importante, nunca use o “select * from

CLIENTE”, uso degrada a performance da aplicação.

Outra dica é nunca usar uma consulta sem a cláusula

where, ou seja, nunca trazer todos os dados em memória

no ClientDataSet.

Nesse primeiro momento, vamos fazer isso, retornar

todos os dados, mas adiante, mostrarei como usar

parâmetros. Caso deseja, você pode usar um editor que

o SQLDataSet tem para montar o SQL (Figura 7).

Figura 7. Editor do SQLDataSet para montar a consulta SQL

Basta dar um duplo clique no objeto ou nos campos

para o Delphi adicionar os mesmos no SQL. Para testar,

feche o editor e altere a propriedade Active para True. Se

nenhum erro ocorrer, a consulta esta correta.

No DataSetProvider altere a propriedade DataSet

para “dsCliente”. Essa é a única configuração (por

enquanto) que precisamos fazer nesse componente.

No cdsCliente altere a propriedade ProviderName para

“dspCliente” e Active para True.

Pronto! Já estamos em condições de criar um

cadastro para a tabela de clientes do banco de dados.

Podemos criar um formulário e adicionar os componentes

data-aware conforme visto no artigo anterior. Ou

também podemos mostrar uma maneira rápida e fácil

utilizando o Delphi.

Dê um duplo clique no cdsCliente e use a combinação

de teclas Crtl + F. Note que serão adicionados os campos

usados na consulta SQL, chamados TFields. Podemos,

usando esse editor, fazer as formatações nos campos

utilizando as propriedades EditMask, EditFormat e

Currency.

Para que o dbExpress faça corretamente a

atualizações dos campos, precisamos configurar alguns

Fields. Para o campo nCdCliente, em ProvidersFlags

marque como True as opções pfInWhere e pfInKey,

indicando que o mesmo é o campo chave e será usado

como parâmetro para a atualização.

Para os outros campos, que devem ser atualizados

a única opção deve ser pfInUpdate, ou seja, indicamos

que os campos devem ser atualizados no banco de

dados. Para o campo nCdCliente precisamos configurar

Required como False, para que o ClientDataSet não faça

a validação desse campo que será preenchido no banco,

já que o mesmo é auto-incremento.

Deixe o editor de Fields abertos. Abra o arquivo de

formulário que será nosso cadastro de clientes. Selecione

todos os campos e arraste para o formulário. Será

perguntado se deseja usar a unit do DM. Escolha Sim.

Veja que o Delphi adiciona os componentes

necessários: DataSource, DBEdit e Labels. Agora, basta

adicionar um DBNavigator e vincular ao DataSource.

Troque o DBEdit por um DBText para o campo nCdCliente.

Pronto, execute a aplicação e cadastre os clientes que

desejar (Figura 8).

Você deve, ao tentar salvar, receber a seguinte

mensagem: Field value required. Isso ocorre, por que

o ClientDataSet, mesmo usando dados em memória

(cache), mapeia os campos do banco e o campo

nCdCliente é not null.

Para contornar isso, basta preencher esse campo

com algum valor. Acesse o evento OnNewRecord do

cdsCliente e digite o seguinte código:

cdsClientenCdCliente.AsInteger := 0;

Faça o teste novamente e adicione alguns registros.

Feche a aplicação e abra novamente. Note que os

registros não estão salvos. Por que isso acontece? Por

que o ClientDataSet manipula os dados em memória, ou

seja, ao fechar a aplicação, os dados são descartados.

Mas como eu incluo esses dados no banco? Acesse

o evento AfterPost e adicione o seguinte código:

Figura 8. Cadastro de cliente

Figura 5. Conexão estabelecida com o banco de dados criado anteriormente

julho 2012 09

cdsCliente.ApplyUpdates(0);

O código indica ao ClientDataSet que o mesmo

deve persistir os dados no banco. Após essa alteração,

insira os registros e salve. Verifique que os mesmos serão

incluídos no banco.

Cadastro de empregado

O cadastro de empregado é bastante

semelhante ao de cliente, mas temos a

diferença que precisamos ter uma consulta

para saber qual o setor do empregado

para que o usuário não precise digitar o

código do setor. Agora, adicione um trio de

componentes para cada cadastro: empregado

e setor.

Faça as configurações, semelhante aos do

cadastro anterior. Arraste os campos para um

formulário. Remova o DBEdit para o nCdSetor.

Adicione um DBLookupComboBox.

Adicione também um DataSource e faça

a ligação com o ClientDataSet que foi criado

para trazer os dados da tabela SETOR. No

DBLookupComboBox configure DataSource e

DataField para o campo nCdSetor do cadastro

de empregado.

Para exibir os setores para que o usuário

possa escolher, configure ListSource (com o

DataSource2), ListField (sNmSetor) e KeyField

(nCdSetor). Para mostrar o formulário do

cadastro de empregados ao executar a

aplicação, precisamos configurar isso.

Clique com o botão direito no projeto no

Project Manager e escolha Options. Acesse o

item Forms e configure conforme a Figura 9.

Veja que primeiro criamos o Data Module e depois

os formulários da aplicação. Rode a aplicação

e veja o cadastro de empregado vinculado

com a pesquisa de setor (Figura 10).

Figura 10. Cadastro de empregado e consulta de setor

Nota: Em aplicação “real” não é

interessante criar todos os formulários

na inicialização do programa. O mesmo

ficará muito lento. Para contornar isso,

basta passar os formulários para a

opção Available forms e criar (utilizando

menus ou botão) os mesmos em tempo

de execução.

É Técnico em Processamento de Dados, desenvolvedor Delphi/C# para aplicações Web com ASP.NET e Windows com Win32 e Windows Forms. Palestrante da 4ª edição da Borland Conference (BorCon).

Autor de mais de 60 artigos e de mais de 300 vídeos aulas publicadas em revistas e sites especializados. É consultor da FP2 Tecnologia (www.fp2.com.br) onde ministra cursos de programação e banco de dados. É desenvolvedor da Paradigma Web Bussi-ness em Florianópolis-SC.

Sobre o autor

Luciano Pimenta

www.lucianopimenta.net

Com isso, vimos nessa primeira parte,

dois exemplos de cadastro: um simples, com

apenas alguns campos e outro com associação

com outra tabela, onde precisamos ter uma

consulta para que o usuário possa visualizar

os dados, sem precisar saber o código.

No próximo artigo, vamos nos aprofundar

ainda mais nessa parte de banco de dados,

onde veremos características diferentes do

cadastro, como parametrização, pesquisa

auxiliar, usar apenas um ClientDataSet para

cadastro, ao invés do trio (SQLDataSet +

DataSetprovider + ClientDataSet), além de

aprendermos a usar Stored Procedures.

Conclusões

Iniciamos nessa quarta parte da nossa

série, uma das características do Delphi

mais marcante, o trabalho com banco de

dados. Vimos como usar o dbExpress para

manipular dados oriundos de consultas.

No próximo artigo, vamos nos aprofundar

mais no dbExpress e ClientDataSet para

criar cadastros mais sofisticados para nosso

projeto

Um grande abraço a todos e até a

próxima!

Figura 9. Configurando a criação dos formulários

julho 201210

A s p . N e t Criando um formulário para Upload de Arquivos

No artigo deste mês abordarei como criar um formulário para Upload de arquivos em Asp.Net.

Este tipo de artigo é muito útil para quem deseja implementar em seus projetos a pos-sibilidade de fazer uma área dinâmica para Upload e posteriormente uma implementa-ção de Downloads destes mesmos arquivos. Utilizarei como ferramenta de desenvolvi-mento o Microsoft Visual Studio 2010 e o Microsoft SQL Server 2008 sendo este último responsável por armazenar informações im-portantes referentes a estes arquivos, como: Tipo, Nome, Descrição e Tamanho em Bytes.

Criando a Tabela de Upload

Importante informar que antes de criarmos a tabela é necessário ter uma base de dados criada, que no nosso caso específico deixei como “DB_SITETHECLUB”, mas fique a vontade para criar como quiser.

CREATE TABLE [dbo].[TB_DOWNLOAD]( [COD_ARQ] [int] IDENTITY(1,1) NOT NULL, [NOM_ARQ] [varchar](80) NULL,

[TIP_LIN] [varchar](30) NULL, [DES_ARQ] [varchar](max) NULL, [TAM_ARQ] [int] NULL, CONSTRAINT [PK_TB_DOWNLOAD] PRIMARY KEY CLUSTERED ( [COD_ARQ] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,

julho 2012 11

ALLOW_PAGE_LOCKS = ON) ON [PRIMARY])ON [PRIMARY]

Criando o Modelo de Dados

Para trabalhar com o Linq To Entity é neces-sário adicionar um “ADO.NET Entity Data Model”, para isto siga as etapas abaixo:

1-) Clique com botão direito sobre o projeto escolhendo “Add New Item” e definindo como “TheClubModel.edmx”.

2-) A tela seguinte escolha “Generate From Database”, pois esta tabela irá vir de um Banco de Dados, clique em “Next”.

3-) Escolha uma conexão com o SQL Server já existente um crie uma se necessário, partindo assim para a próxima etapa.

4-)Escolha a tabela criada anteriormente no SQL Server, no caso deverá clicar em TB_DOWNLO-AD para assim finalizarmos este processo.

5-) Foi criado uma camada de Dados chama-da “TheClubModel.edmx”, localizado na pasta “App_Code”.

Dê um duplo clique no mesmo para adicionar-mos a tabela dentro no modelo criado. Poderá fazer isto facilmente clicando com o botão direito e es-colhendo a opção “Update model from Database”.

Ver Imagem 01.

Importante: Esta parte de nosso artigo foi explicada de uma forma rápida e concisa pelo fato de possuirmos outros artigos que abordam estas etapas de uma forma mais detalhada.

Criando o Formulário de Upload

Crie um novo projeto clicando em File/New/WebSite escolhendo a opção “ASP.NET Dynamic Data Enitites Web Site”, ou seja, utilizaremos o “Linq To Entities” para trabalhar com o Bando de Dados.

Devemos criar uma pasta para armazenar nossos arquivos, no meu caso criei uma chamada “Downloads”, para quem não sabe basta clicar com o botão direito sobre o Projeto e escolher “New Folder”,

Ver Imagem 02.

Portanto dentro desta pasta Downloads deverá conter todos os sub-diretórios necessários para uma melhor organização. Foram criadas três Pastas, sendo: Executáveis, Compactados e Documentos. Posteriormente estes sub-diretórios serão carre-gados dinamicamente em um formulário dentro de uma Combobox.

Por padrão o Asp.Net cria uma Página chamada “Default.aspx”, recomendo realizar a exclusão da mesma para a criação do formulário de Uploads. Os passos para realizar esta tarefa serão parecidos com os de criar uma pasta, clicando em “Add New Item” e escolhendo a opção “WebForm.aspx” definindo o nome como “FrmUploads.aspx”. Adicione alguns componentes, como sugere a tabela a seguir:

O Formulário deverá ficar identico ao da Figura 03.

Figura 03: Layout do Formulário de Upload.Codificando o Formulário

No Evento “Page_Init” alimentamos o Dro-pdownlist categoria com o nome das pastas cria-das anteriormente, para isto utilizamos a classe “DirectoryInfo” e o comando “Server.MapPath” nos possibilitará localizar a pasta “Downloads” em nosso servidor.

Nossa tabela irá conter os seguintes campos:

Figura 01: Entidade TB_DOWNLOAD.

Figura 02: Criando uma Pasta para armazena-mento de arquivos.

julho 201212

Os namespaces utilizados:

using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;using System.Configuration;using System.IO;using DB_SITETHECLUBModel;

O código correspondente:

protected void Page_Init(object sender, EventArgs e){DirectoryInfo dir = new DirectoryInfo(Server.MapPath(“~\\Downloads”));

dpTipo.Items.Add(“”);

foreach (var tipos in dir.GetDirectories()) { dpTipo.Items.Add(new ListItem(tipos.Name)); }}

O Evento Page_Init ocorre antes do Page_Load, portanto é nele o lugar certo de alimentar nosso componente DropDownList.

Agora vamos para a função responsável por Limpar nossos componentes após a execução, veja a seguir:

void Limparcampos(){ txtDescricao.Text = string.Empty; dpTipo.SelectedIndex = 0;}

Segue a listagem da implementação do código btUpload_Click.

protected void btUpload_Click(object sender, EventArgs e){ //Testar se ocorreu alguma exceção try { //Testar se escolheu algum arquivo if (fUploadArquivo.PostedFile != null) {//Variáveis para armazenar o Nome, tamanho e Diretório do Arquivostring Nom_Arq = fUploadArquivo.PostedFile.FileName.Substring(fUploadArquivo.PostedFile.FileName.LastIndexOf(“\\”) + 1);

int Tam_Arq = fUploadArquivo.PostedFile.ContentLength;

string Dir_Arq = Server.MapPath(“~\\Downloads\\”);

//Verifica se o tamanho do arquivo em Bytes é válido if (Tam_Arq <= 0) {lbMensagem.Text = “ A tentativa de UpLoad do Arquivo falhou! “; } else {//Comando responsável por salvar o arquivo no ServidorfUploadArquivo.PostedFile.SaveAs(Dir_Arq + dpTipo.Text + “\\” + Nom_Arq);

//Chama a função para Salvar no Banco de Dados

InserirDados(Nom_Arq, Tam_Arq);

//Exibe uma Mensagem ao UsuáriolbMensagem.Text = “O seu arquivo foi gravado com sucesso no seguinte diretório: “ + Dir_Arq + dpTipo.Text + “\\” + Nom_Arq; } }

} catch {lbMensagem.Text = “A tentativa de UpLoad do Arquivo falhou!”; }

Limparcampos(); }

private void InserirDados(string Nom_Arq, int Tam_Arq){ //Instanciar a classe do Modelo de DadosDB_SITETHECLUBEntities db = new DB_SITETHECLUBEntities();

//Inserir dados TB_DOWNLOAD down = new TB_DOWNLOAD { NOM_ARQ = Nom_Arq, TIP_LIN = dpTipo.Text, DES_ARQ = txtDescricao.Text, TAM_ARQ = Tam_Arq };

//Aplicar alterações no Banco de Dados db.AddToTB_DOWNLOAD(down);

julho 2012 13

db.SaveChanges();}

Primeiramente implementamos um Try..Catch para evitar Exceções inesperadas e logo em seguida verifico se o FileUpload está vazio. Crio as variáveis necessárias como: Nome, Tamanho e Diretório do arquivo para ser posteriormente salvo tanto no servidor da aplicação quanto no Banco de Dados utilizando a Função InserirDados().

Ver Imagem 04.

Figura 04: Exemplo em Run-Time.

Conclusão

Procurei neste artigo, demonstrar uma forma bastante simples de realizar Upload de arquivos utilizando o Asp.Net.

Neste caso foi desenvolvida uma tela simples de Upload que no futuro podere-mos programar sem muito esforço uma de Download.

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

Sobre o autor

Marcos César Silva

[email protected]

Caso tenha sugestões a respeito de temas que gostaria ver publicado em nossa revista sinta-se a vontade em nos enviar que iremos fazer o possível para atendê-lo!

Um Forte abraço a todos e até o mês que vem!

julho 201214

Android

Criando uma tela de Pesquisa de dados

Neste mês continuarei a falar do Android junto com o Banco de Dados SQLite. A ideia deste artigo é de aproveitar um pouquinho do que foi aprendido nos meses anteriores, para isto vou criar uma tela para pesquisa de dados. Todo sistema, o ideal, neste caso seria criar uma tela de pesquisa padrão. Este artigo tem o intuito de dar as coordenadas para criação da mesma. Para isto usaremos uma tabela com alguns dados já cadastrados no SQLIte.

Estrutura da Tabela

CREATE TABLE [TB_CLIENTE] ( [COD_CLI] INT NOT NULL, [NOM_CLI] VARCHAR(30), [CID_CLI] VARCHAR(30), CONSTRAINT [] PRIMARY KEY ([COD_CLI] COLLATE NOCASE ASC));

A seguir estão alguns dados necessários, ver Imagem 01.

Figura 01: Dados tabela de Cliente.

julho 2012 15

Criando um projeto de exemplo

Dividiremos o artigo deste mês em três partes, sendo a primeira res-ponsável pela criação do lay-out da aplicação. A segunda definirá uma classe para armazenar nossas principais funções, eu particularmente acho prático e necessário economizando tempo e código ao decorrer do projeto. Esta classe possuirá métodos estáticos essenciais ao decorrer do desenvolvimento. A última parte terá nossa “Activity” principal, com toda a estrutura do projeto.

Para isto abra seu Eclipse e clique em “File/New/Android Project” e crie um projeto em Android, continuamos utilizando a versão 2.2 ou 2.3. Sugiro criar com o nome de “Android_PesquisarDados”.

Lay-Out da Tela de Pesquisa

Para a disposição dos componentes na tela, organizamos por “lay-outs” alternando tipos horizontais e verticais.

Adicionaremos os seguintes componentes:

A Imagem 02 nos disponibiliza a organização dos componentes.

Figura 02: Disposição dos componentes.

Já a Imagem 03 ilustra o resultado final da tela de pesquisa sugerida. A seguir o código XML correspondente.

<?xml version=”1.0” encoding=”utf-8”?><LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android” android:orientation=”vertical” android:layout_width=”fill_parent” android:layout_height=”fill_parent”> <LinearLayout android:orientation=”vertical” android:layout_height=”wrap_content” android:id=”@+id/linearLayout2” android:layout_width=”wrap_content”> <LinearLayout android:layout_height=”wrap_content” android:layout_width=”match_parent” android:id=”@+id/linearLayout5”> <TextView android:id=”@+id/txtPesquisar” android:text=”Pesquisar por:” android:layout_height=”wrap_content”

Figura 03: “Lay-Out” sugerido.

julho 201216

android:textAppearance=”?a

ndroid:attr/textAppearanceMedium” android:layout_gravity=”center” android:layout_width=”142dp” android:typeface=”serif” ></TextView> <RadioGroup android:id=”@+id/rgPesquisar” xmlns:android=”http://schemas.android.com/apk/res/android” android:orientation=”horizontal” android:layout_width=”fill_parent” android:layout_height=”wrap_content”> <RadioButton android:text=”Nome” android:layout_height=”wrap_content” android:id=”@+id/rbNome” android:layout_width=”wrap_content” android:checked=”true” android:typeface=”serif”></RadioButton> <RadioButton android:text=”Cidade” android:layout_height=”wrap_content” android:id=”@+id/rbCidade” android:layout_width=”wrap_content” android:typeface=”serif” ></RadioButton> </RadioGroup> </LinearLayout> </LinearLayout> <LinearLayout android:layout_height=”wrap_content” android:layout_width=”match_parent” android:id=”@+id/linearLayout4” android:weightSum=”1”> <LinearLayout android:orientation=”vertical” android:id=”@+id/linearLayout3” android:layout_width=”235dp” android:layout_height=”wrap_content”> <TextView android:textAppearance=”?android:attr/textAppearanceMedium”

android:id=”@+id/txtPesquisa” android:text=”Texto a Pesquisar: “ android:layout_height=”wrap_content” android:layout_width=”wrap_content” android:typeface=”serif” ></TextView> <EditText android:layout_height=”wrap_content” android:id=”@+id/edtPesquisar” android:layout_width=”match_parent”> <requestFocus></requestFocus> </EditText> </LinearLayout> <LinearLayout android:layout_height=”match_parent” android:id=”@+id/linearLayout1” android:orientation=”vertical” android:layout_width=”match_parent”> <TextView android:textAppearance=”?android:attr/textAppearanceMedium” android:id=”@+id/txt” android:text=” “ android:layout_height=”wrap_content” android:layout_width=”match_parent”></TextView> <Button android:layout_width=”wrap_content” android:text=”Pesquisar” android:id=”@+id/btnPesquisar” android:layout_height=”wrap_content”></Button> </LinearLayout></LinearLayout><TextView android:id=”@+id/txtResultado” android:layout_height=”wrap_content” android:text=”TextView” android:layout_width=”match_parent”android:typeface=”monospace”></TextView></LinearLayout>

Classe de Funções

Para criar uma classe clique com o botão direito em cima do caminho “src” e escolha “New\Class” e defina o nome como “unFuncoes”, Ver Imagem 04.

Utilizaremos neste exemplo três funções principais:

MensagemAlerta: Procedimento responsável por emitir uma mensagem informativa ao usuário.

CaracterDireita: Função para adicionar caracteres à direita de um texto.

julho 2012 17

ZeroEsquerda: Como o próprio nome já diz, insere zero à esquerda de um número.

Quando utilizamos uma classe estática não é necessário instanciá-la, ou seja, não precisamos criar o objeto em si.

Ela já vem criada para utilização apenas fazendo a referência quando neces-sitar e é exatamente deste tipo de classe que usaremos na nossa “unFuncoes”.

O primeiro passo seria importar os seguintes pacotes necessários.

package pct.Android_PesquisarDados;

import android.app.Activity;import android.app.AlertDialog;

public class unFuncoes {public static void MensagemAlerta(String titulo, String corpo, Activity Atividade) { AlertDialog.Builder infoResultado = new AlertDialog.Builder(Atividade); infoResultado.setTitle(titulo); infoResultado.setMessage(corpo); infoResultado.setNeutralButton(“Ok”,null); infoResultado.show();

}

Nesta função foi passado por parâmetro o título, o corpo e a Atividade utilizada em questão.

public static String CaracterDireita(String Campo, int Quantidade, String Caracter) { int tamanho = Quantidade - Campo.length(); StringBuffer sb = new StringBuffer(Campo); if (tamanho > 0) { for (int i=0 ; i<tamanho ; i++) { sb.append(Caracter); } } return sb.toString(); }

Já a função CaracterDireita() tem como parâmetro o campo texto, a quan-tidade e o tipo de caractere.

public static String ZeroEsquerda(int Campo, int Quantidade) { return String.format(“%0”+Quantidade+”d”, Campo); }

}

Temos como parâmetros o campo inteiro e a quantidade de zeros a adicionar.

Codificação da “Activity” principal

Primeiramente importaremos os pacotes:

import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.database.Cursor;import android.database.sqlite.

Figura 04: Classe unFuncoes.

julho 201218

SQLiteDatabase;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.RadioGroup;import android.widget.TextView;

Usaremos também as seguintes variáveis globais.

Cursor ponteiro;SQLiteDatabase bancodados;TextView resultado;

O evento OnCreate() é disparado quando executamos o projeto. Aqui é onde fica o corpo principal onde iremos abrir o Banco de Dados e pesquisar os dados.

@Overridepublic void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); abreoucriaBD(); Button btPesquisar = (Button) findViewById(R.id.btnPesquisar);btPesquisar.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) {resultado = (TextView) findViewById(R.id.txtResultado);

RadioGroup rgPesquisar = (RadioGroup) findViewById(R.id.rgPesquisar); String strPesquisa = “”; switch (rgPesquisar.getCheckedRadioButtonId()) {case R.id.rbNome : strPesquisa = “NOM_CLI LIKE ?”; break; case R.id.rbCidade : strPesquisa = “CID_CLI LIKE ?”; break; }

List<String> dados = PesquisarDados(“TB_CLIENTE”, strPesquisa, “COD_CLI”,“COD_CLI”, “NOM_CLI”, “CID_CLI”); StringBuilder sb = new StringBuilder();sb.append(“Cod.| “+unFuncoes.CaracterDireita(“Nome”, 15,” “) +” | Cidade \n”);sb.append(unFuncoes.CaracterDireita(“-”, 35,”-”)+”\n”); for (String registros : dados) { sb.append(registros + “\n”); } resultado.setText(sb.toString()); } });}

public void abreoucriaBD(){ try {bancodados = openOrCreateDatabase(“DBTHECLUB”, MODE_WORLD_READABLE, null);String sql = “CREATE TABLE IF NOT EXISTS TB_CLIENTE” +”(COD_CLI INTEGER PRIMARY KEY, “ +“NOM_CLI TEXT, CID_CLI TEXT, EST_CLI TEXT, PRO_CLI TEXT)”; bancodados.execSQL(sql); } catch (Exception e) {

unFuncoes.MensagemAlerta(“Erro”, “Ocorreu algum erro ao abrir ou criar o Banco de Dados!”, Android_PesquisarDadosActivity.this); }}

public List<String> PesquisarDados(String NomeTabela, String ClausulaWhere, String OrdemCampo, String...TipoCampos) {

julho 2012 19

EditText edtPesq = (EditText) findViewById(R.id.edtPesquisar);

List<String> list = new ArrayList<String>(); ponteiro = bancodados.query(NomeTabela, TipoCampos, ClausulaWhere,new String[] {“%”+edtPesq.getText().toString() + “%”}, null, null, OrdemCampo); if (ponteiro.moveToFirst()) { do { list.add(unFuncoes.ZeroEsquerda(Integer.parseInt(ponteiro.getString(0)),3) +“ | “ + unFuncoes.CaracterDireita(ponteiro.getString(1),15,” “) + “ | “+ unFuncoes.CaracterDireita(ponteiro.getString(2),10,” “)); } while (ponteiro.moveToNext()); } if (ponteiro != null && !ponteiro.isClosed())

{ ponteiro.close(); }

return list;}

Inicialmente é executado o método “AbreoucriaBD()” que é responsável por criar ou abrir o Database “DBTHECLUB”. No botão pesquisar criamos uma variável do tipo “RadioGroup” para permitir a escolha de pesquisa por Nome ou Cidade e finalmente chamamos o método “PesquisarDados” que tem como parâmetros: o nome da tabela, a cláusula “Where”, o campo onde iremos fazer a ordenação dos registros e um vetor dos campos utilizados. Armazenamos em um StringBuilder para depois lermos usando o comando “For”. Figura 05 e 06.

Figura 06: Exemplo em “Run-Time”.

Conclusão

A intenção deste artigo foi de aprimorar o que foi aprendido nos meses anteriores e criar um “lay-out” para pesquisa de dados. Fiquem a vontade para dar ideias e sugestões para criação de artigos.

Abraços e até o mês que vem!

Figura 05: Exemplo em “Run-Time”.

Thiago Cavalheiro Montebugnoli é tecnólogo, formado pela Faculdade de Tecnologia de Botucatu – SP (FATEC) foi consultor técnico 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 Proces-samento de Dados da Prefeitura Municipal de Itaí-SP. Possui as seguintes certificações: MCP - Microsoft Certified Professional, MCTS - Microsoft Certi-fied Technology Specialist, MCAD - Microsoft Certified Application Developer e MCSD - Microsoft Certified Solution Developer.

Sobre o autor

Thiago Cavalheiro Montebugnoli

[email protected]

julho 201220

Iniciando o uso de Joysticks

Uma abordagem prática

O Delphi possui suporte nativo a joysticks desde a sua versão 2, porém a sua documen-tação não é muito vasta, por isso, neste artigo veremos como fazer a comunicação de um programa criado em Delphi com a interface de joystick do computador, provando que o Delphi se apresenta como uma boa solução de ambiente de programação quando o assunto é a criação de jogos, uma vez que podem ser implementados com relativa facilidade, gráficos, sons, DirectX, Flash, interface com mouse, teclado e por fim joysticks!

Criando o Aplicativo

Veja na Figura 1 a tela do aplicativo demons-trativo que iremos criar:

O Programa Exemplo

Na Figura 1, temos um TGroupbox na parte superior esquerda para indicar os valores das po-sições cartesianas dos eixos do joystick, bem como o estado de pressionamento dos botões.

Logo abaixo, temos os TEdits que determinam

Figura 1.Tela principal do exemplo de comuni-cação com Joystics

julho 2012 21

o nível de sensibilidade para a movimentação do ponteiro. A direita, temos dois TTabsheets, um para calibração, onde são lidos e armazenados os valores máximos e mínimos das posições que o joystick pode assumir e outro para o teste de mo-vimentação do joystick, onde utilizamos um TShape em formato circular para representar graficamente na tela a posição, bem como o estado dos botões.

O Programa de maneira geral funciona com um TTimer que, quando acionado, dispara uma função que faz a leitura da porta do joystick e atualiza as devidas informações de posição e pressionamento de botões. Assim, a propriedade interval do com-ponente TTimer, irá determinar o tempo entre as leituras dos valores, ou seja, a taxa de amostragem, o que terá influência direta na sensibilidade e mo-vimentação do ponteiro na tela.

Montando o Programa

Crie um novo projeto, adicione a unit MMSys-tem à cláusula Uses. Adicione também a seguinte procedure ao mesmo:

//--- Realiza Leitura do Joystick de 3 eixos e 4 botões---procedure LerJoystick(var X, Y, Z:longint;var B1, B2, B3, B4:boolean);var myjoy: TJoyInfo;begin joygetpos(joystickid1,@myjoy);

X := myjoy.wxpos; Y := myjoy.wypos; Z := myjoy.wypos;

B1 := (myjoy.wbuttons and

1) > 0;B2 := (myjoy.wbuttons and 2) > 0; B3 := (myjoy.wbuttons and 3) > 0; B4 := (myjoy.wbuttons and 4) > 0;end;

Esta é a procedure responsável por realizar a leitura propriamente dita do joystick. Nela declara-mos a variável MyJoy do tipo TJoyInfo, que é uma estrutura criada para conter informações do joys-tick. Abaixo vemos como TJoyInfo está declarada:

A variável MyJoy é então usada na função JoyGetPos, que recebe um identificador do Joystick a ser lido, que pode assumir os valores de JOYS-TICKID1 ou JOYSTICKID2, e um pointer para uma variável do tipo TJoyInfo, por onde a função irá retornar os valores lidos. Assim, após a chamada à função JoyGetPos, devemos ler os valores de MyJoy, como mostrados acima.

Agora que já temos a procedure que lê o joystick, criaremos uma função que irá usar estes valores para mostra-los na tela, fazendo um objeto TShape se mover. Para isso, adicionamos a seguinte procedure ao projeto:

//--- Atualiza informações do Joystick na tela ---procedure TForm1.AtualizarJoystick;var X, Y, Z: longint; B1, B2, B3, B4: boolean;beginX := 0;Y := 0;Z := 0;

B1 := true;B2 := true;B3 := true;B4 := true;

LerJoystick(X, Y, Z, B1, B2, B3, B4);

//Atualiza valores de posição do Joystick nos EditseXpos.text := inttostr(X);eYpos.text := inttostr(Y);eZpos.text := inttostr(Z);

//Atualiza valores dos botões do Joystickcheckbox1.Checked := B1;checkbox2.Checked := B2;checkbox3.Checked := B1;checkbox4.Checked := B2;

//Atualiza posição do ponto, quando em modo “testando”try shape1.Left := round(X / escalaX) - round(shape1.Width /2); shape1.Top := round(Y / escalaY) - round(shape1.Height /2);

//Pinta borda do ponto se botão 1 pressionado if B1=true then shape1.Pen.color := clred else shape1.pen.color := clwhite;

//Pinta interior do ponto se botão 2 pressionado if B2=true then shape1.Brush.color := claqua else shape1.Brush.color := clwhite;except showmessage(‘Erro’); end;end;

Pronto, agora basta adicionar uma chamada à procedure AtualizarJoystick ao evento OnTimer de um objeto TTimer para que tenhamos implementa-do a parte básica e inicial de qualquer comunicação com joysticks.

Considerações

Caso o leitor implemente este artigo, irá per-ceber que a leitura dos valores do joystick é, em sua maioria imprecisa; ou seja, apesar do joystick estar parado, seus valores de leitura variam entre + ou - 5%, fazendo com que o ponto na tela esteja sempre realizando pequenos movimentos. Uma solução para este problema é a implementação

julho 2012

de um sistema de sensibilidade, onde ao invés de simplesmente ler e atribuir a nova posição, deve-mos antes testar se a nova posição é maior do que o valor estipulado para a sensibilidade, fazendo com que o objeto na tela se mova somente quando realmente houver o pressionamento do controle.

O demo que acompanha este artigo já imple-menta o esquema de sensibilidade, sendo possível atribuir diferentes sensibilidades percentuais a cada um dos 3 eixos em questão.

O uso do TJoyInfo e JoyGetPos se limita à comunicação com joysticks de no máximo 3 eixos e 4 botões. Para joysticks mais elaborados que utilizem pedais, mais de 4 botões ou um número maior de eixos, deve-se utilizar as declarações de TJoyInfoEx e JoyGetPosEx. Neste caso temos disponíveis até 6 eixos, 32 botões e uma grande variedade de Flags (dwFla-gs) de configuração do joystick.

Podemos ainda testar valores de retorno da função JoyGetPosEx que re-torna JOYERR_NOERROR se não houver nenhum erro, ou:

• MMSYSERR_NODRIVER Se o Driver do joystick não estiver pre-sente

• MMSYSERR_INVALPARAM S e algum parâmetro inválido for passado

• MMSYSERR_BADDEVICEID S e o identificador do joystick passado for inválido

• JOYERR_UNPLUGGED Se o joystick não estiver conectado ao sistema

Conclusão

Agora que você já sabe mais sobre

Professor do Departamento de Engenharia da UNIFACS, Engenheiro Mestrando em Redes de Computadores, e desenvolvedor sócio da TKS Soft-ware - Soluções de Automação e Softwares Dedicados. Pode ser contatado em [email protected], ou através dos sites www.igara.com.br – www.igara.com.br/victory

Sobre o autor

Victory Fernandes

[email protected]

joysticks e sua implementação no Delphi, está pronto para montar sua própria interface, ou até mesmo utilizar com-ponentes de terceiros, porém tendo co-nhecimento de como o componente fun-ciona. Um bom exemplo disso pode ser encontrado em http://www.geocities.com/scottpinkham/delphi/qcjoystick.zip.

O componente QCJoystick é freewa-re, acompanha código fonte e utiliza os comandos descritos neste artigo para implementar uma interface bem com-pleta e simples de usar de joysticks para Delphi.

julho 2012 23

C r i a n d o u m f o r m u l á r i o d e pesquisa padrão com o Delphi XE

Olá pessoal, todos sabemos que qualquer tela de cadastro em qualquer aplicação, deve ter uma área que possibilite ao usuário fazer buscas entre os registros cadastrados. No geral, cria-se uma tela separada da tela de cadastro para fazer essa busca de registros, até mesmo para não sobrecarregar o layout da tela de cadastro.

Até aqui está tudo bem, cada formulário de cadastro terá a sua respectiva tela de consulta certo? Não é errado fazer desta maneira, porém, se pararmos para pensar, os procedimentos utili-zados para realizar uma pesquisa, será sempre os

mesmos.

O que vai alterar mesmo serão apenas o nome da tabela e o campo de busca para poder fazer o acesso aos dados, e para os componentes do formulário, serão alterados o ClientDataSet a ser manipulado e as propriedades captions referentes à pesquisa.

O que se pode tirar disso tudo?

Podemos criar um formulário de pes-quisa que com apenas alguns parâmetros (variáveis públicas) poderá atender a todos os formulários de cadastro da aplicação.

Então, mãos a obra.

Requisitos

Crie um banco de dados com as ta-belas de clientes e produtos com alguns valores incrementados para testes. Segue um exemplo na listagem 1.

CREATE TABLE CLIENTES ( ID_CLIENTE INTEGER NOT NULL,

julho 201224

NOME VARCHAR (60), SEXO CHAR (1), CIDADE VARCHAR (30), PRIMARY KEY (ID_CLIENTE));

INSERT INTO CLIENTES (ID_CLIENTE, NOME, SEXO, CIDADE) VALUES (1, ‘LAURA’, ‘F’, ‘AVARÉ’);INSERT INTO CLIENTES (ID_CLIENTE, NOME, SEXO, CIDADE) VALUES (2, ‘ROBERTO’, ‘M’, ‘ARANDU’);INSERT INTO CLIENTES (ID_CLIENTE, NOME, SEXO, CIDADE) VALUES (3, ‘JOSÉ’, ‘M’, ‘ITAÍ’);

CREATE TABLE PRODUTOS ( ID_PRODUTO INTEGER NOT NULL, DESCRICAO VARCHAR (60), MARCA VARCHAR (30), ESTOQUE INTEGER, PRIMARY KEY (ID_PRODUTO));

INSERT INTO PRODUTOS (ID_PRODUTO, DESCRICAO, MARCA, ESTOQUE) VALUES (1, ‘ARROZ 5KG’, ‘PATÉCO’, 15);INSERT INTO PRODUTOS (ID_PRODUTO, DESCRICAO, MARCA, ESTOQUE) VALUES (2, ‘FEIJÃO 2KG’, ‘SERRITO’, 25);INSERT INTO PRODUTOS (ID_PRODUTO, DESCRICAO, MARCA, ESTOQUE) VALUES (3, ‘REFRIGERANTE 350ML’, ‘COCA COLA’, 20);

Listagem 1 – Criando tabelas no banco de dados para exemplo

Preparando a aplicação

No Delphi XE, crie uma nova aplicação VCL (File/New/VCL Forms Application - Delphi) com os seguintes requisitos:

a) Um formulário principal (Name = fm-Principal), que através de um menu, fará a chamada dos cadastros de produtos e clientes;

b) Um DataModule (Name = DM), com todos os objetos para a conexão ao banco de dados. Observação, neste exemplo foi utilizada a conexão com o banco Firebird 1.5 através da tecnologia DBExpress no Delphi XE. Para criar uma nova conexão siga os seguintes passos:

1. Clique na aba DataExplorer, localizada a direita da tela logo acima da Tool Palette (Paleta de Componentes);

2. Ao fazer isto, listará todas as conexões aos bancos compatíveis ao DBExpress. Com o botão direito do mouse, clique em cima da conexão ao banco Firebird, em seguida clique em Add New Connection;

3. Na janela que aparecer digite um nome para a conexão e clique em ok. Uma nova conexão aparecerá na lista de conexões com o banco Fire-bird com o nome informado. Clique com o botão direito sobre essa conexão e logo em seguida clique em Modify Connection;

4. Irá aparecer uma nova janela, no campo Database Name coloque o nome do computador seguido de “:” mais o caminho do seu banco de da-dos (exemplo, MEUCOMPUTADOR-PC:C:\MEUPRO-JETO\BANCO\BANCO.FDB), os outros campos dessa janela referem-se ao login de acesso ao banco de dados, preencha conforme o seu login. Pronto, com esses passos sua conexão estará pronta para ser adicionada a um componente TSQLConnection. Veja na figura 1 onde são realizados esses passos:

Criando o formulário de pesquisa padrão

Crie um novo formulário (File/New/Form - Delphi), salve a unit com o nome de ‘unPes-quisa’, de o nome de ‘fmPesquisa’ ao formulário, adicione ao formulário os seguintes componentes:

a) 2 GroupBox – Standard (Name = GroupBox1, GroupBox2), serão a descrição dos

componentes para a pesquisa para o usuário;

b) 1 Edit – Standard (Name = edtPesquisa), receberá o texto de pesquisa do usuário;

c) 1 Button – Standard (Name = btnPes-quisa), fará a limpeza da pesquisa e trará todos os registros ao ser clicado;

d) 1 DBGrid – DataControls (Name = dbgPesquisa), listará os registros da pesquisa;

e) 1 DataSource – DataAccess (Name = dsPesquisa), fará a ligação entre os componentes visuais com os componentes de acesso aos dados.

Veja um exemplo do layout da tela de pesquisa na figura 2:

O próximo passo agora é definir nossos parâmetros de pesquisa. Iremos criar variáveis públicas e privadas na unPesquisa. As Variáveis públicas irão receber os valores de um outro formu-lário, são elas: CDS (tipo TClientDataSet) e Tabela, CampoBusca, CampoChave e LegendaGroupBox (tipo String).

Figura 1 – Criando uma conexão “EXEMPLO” no Delphi XE

julho 2012 25

As variáveis públicas irão criar as consultas SQL através dos parâmetros públicos recebidos, são elas: ConsultaSQL, WhereParametro e Whe-reIsNull (tipo String), onde ConsultaSQL trará todos os campos da Tabela passada e as variáveis WhereParametro e WhereIsNull, implementarão a consulta conforme a necessidade.

Exemplo, ao abrir a tela de pesquisa é re-comendado trazer uma consulta sem registros, para melhorar a performance do sistema, ou seja, neste caso utiliza-se WhereIsNull que utiliza o CampoChave.

A Variável WhereParametro será utilizada para fazer a consulta com o parâmetro digitado no edtPesquisa pelo usuário. Veja na listagem 2 a criação dessas variáveis nas diretivas private e public da unPesquisa:

private { Private declarations } ConsultaSQL, WhereIsNull, WhereParametro : string;

public { Public declarations

} CDS : TClientDataSet; Tabela, CampoBusca, CampoChave, LegendaGrouBox : string;

end;

var fmPesquisa: TfmPesquisa;

Listagem 2 – Criando as variáveis públicas e privadas

Temos que ter em vista que as variáveis públicas terão seus valores agregados após criar o formulário de pesquisa em memória pelo formu-lário de cadastro, ou seja, ao exibir o formulário em ShowModal, elas já estarão com seus devidos parâmetros agregados, isso indica que no evento onShow do fmPesquisa iremos montar as variáveis que farão a pesquisa.

Veja na listagem 3 como ocorre esta codifi-cação:

procedure TfmPesquisa.FormShow(Sender: TObject);begin

ConsultaSQL := Format(‘SELECT * FROM %S ‘, [Tabela]); WhereIsNull := Format(‘ WHERE %S IS NULL’, [CampoChave]); WhereParametro := Format(‘ WHERE UPPER(%S) LIKE :P’, [CampoBusca]);

CDS.Close; CDS.CommandText := ConsultaSQL + WhereIsNull; CDS.Open;

dsPesquisa.DataSet := CDS; if (LegendaGrouBox <> ‘’) then GroupBox1.Caption := LegendaGrouBox else GroupBox1.Caption := ‘Pesquisar Registros’;

end;

Listagem 3 – Construindo as consultas no evento OnShow do fmPesquisa

Note que utilizamos a função Format para criarmos as consultas SQL, sua sintaxe é sim-ples, porém não entrarei em detalhes aqui, pois não é o foco do artigo. Na variável ConsultaSQL, atribuímos o nome da tabela, ou seja, será nossa consulta simples, que listará todos os registros.

Já nas variáveis WhereIsNull e WherePara-metro atribuímos as variáveis CampoChave e CampoBusca respectivamente.

Logo em seguida já tem um exemplo de como serão utilizadas as variáveis Where, veja que foi passado uma consulta SQL pela propriedade CommandText do CDS, onde recebeu apenas a Variável ConsultaSQL mais a Variável WhereIsNull, isso significa que ao abrir o fmPesquisa não será listado nenhum registro aumentando assim a performance.

Na sequência do código, vemos que o dsPes-

Figura 2 – Tela de pesquisa padrão

julho 2012

quisa (DataSource) recebe na propriedade DataSet a variável CDS, que indica que o fmPesquisa poderá trabalhar com vários ClientDataSet. Em seguida atribui-se a legenda do GroupBox1 que será dina-mizado pela variável LegendaGroupBox.

Após realizada essa codificação, fica fácil configurar os componentes que realizarão as pesquisas. Veja na listagem 4 a codificação dos componentes visuais de pesquisa:

procedure TfmPesquisa.edtPesquisaKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);Begin

if (Key in [VK_UP, VK_DOWN]) and not(CDS.IsEmpty) then dbgPesquisa.SetFocus;

if (Key = VK_RETURN) and (edtPesquisa.Text <> ‘’) then begin

CDS.Close; CDS.CommandText := ConsultaSQL + WhereParametro; CDS.Params.ParamByName(‘P’).Value := ‘%’ + AnsiUpperCase(edtPesquisa.Text) + ‘%’; CDS.Open;

end;

end;

procedure TfmPesquisa.btnLimparPesquisaClick(Sender: TObject);begin

CDS.Close; CDS.CommandText := ConsultaSQL; CDS.Open; edtPesquisa.Clear;

end;

procedure TfmPesquisa.dbgPesquisaKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);begin

if (Key = VK_RETURN) and not (CDS.IsEmpty)then begin

ModalResult := mrOk; Close;

end;

end;

Listagem 4 – Codificando os componentes visuais de pesquisa

Os componentes edtPesquisa e dbgPes-

quisa ambos utilizarão o evento onKeyDown e o btnPesquisa utilizará o evento onClick para sua codificação.

No edtPesquisa verifica qual a tecla pressionada. Se for uma seta para cima ou para baixo verifica se há registros listados na grid, se houver, seta o foco para a grid.

Se for a tecla Enter e o edtPesquisa não estiver vazio, faz-se uma pesquisa utilizando a propriedade CommandText do CDS, e passa-se o parâmetro digitado no edtPesquisa (O parâmetro SQL definido na variável WhereParametro é a letra “P”, veja na listagem 3), lembrando também que foi utilizado a função SQL Upper que deixa todos os registros em caixa alta, o que explica a utilização da função AnsiUpperCase do Delphi ao se passar o parâmetro.

No btnPesquisa, realiza-se uma consulta que listará todos os registros da tabela, e em segui-da limpa a caixa de texto.

No dbgPesquisa verifica se a tecla pressionada é Enter, se for, atribui-se mrOk ao ModalResult do fmPesquisa fechando logo em seguida o formulário.

Em fim, nossa tela de pesquisa parame-trizada está pronta, o que resta agora é alimentar os parâmetros ao se utilizá-la, ao fazer sua chamada através de um formulário de cadastro.

Chamando a tela de pesquisa através de um formulário de cadastro

Como vimos a princípio, temos duas tabelas no banco de dados (clientes e produtos), deve-se criar uma tela de cadastro para cada tabela denominadas respectivamente de fmClientes e fmProdutos.

Essas telas devem conter os campos de pre-

Figura 3 – Exemplo da tela de cadastro de clientes

julho 2012

enchimento dos registros das tabelas, e uma barra de navegação entre os registros, além de um botão (no exemplo, está vinculado na barra de tarefas, porém, pode ser um botão comum) para efetivar a chamada do formulário de pesquisa.

Veja o exemplo da tela de cadastro de clientes na figura 3:

Neste exemplo, a barra de tarefas é implemen-

tada com ações da ActionList, onde a ação acLo-calizar fará a chamada do fmPesquisa, lembrando que deve-se declarar a unPesquisa na diretiva uses da unClientes, Veja na listagem 5 como é feita a chamada do fmPesquisa e passa-se os parâmetros da pesquisa de clientes pelas variáveis públicas da unPesquisa:

procedure TfmClientes.acLocalizarExecute(Sender: TObject);begin

fmPesquisa := TfmPesquisa.Create(self);

fmPesquisa.CDS := dm.cdsClientes; fmPesquisa.Tabela := ‘CLIENTES’; fmPesquisa.CampoBusca := ‘NOME’; fmPesquisa.CampoChave := ‘ID_CLIENTE’; fmPesquisa.

LegendaGrouBox := ‘Consulta de Clientes por Nome’; fmPesquisa.ShowModal; FreeAndNil(fmPesquisa);

end;

Listagem 5 – Fazendo a chamada do fmPesqui-sa pela tela de clientes

O primeiro procedimento a ser realizado ao clicar no botão Localizar é criar o fmPesquisa em memória.

Em seguida, são passados os parâmetros para se realizar a pesquisa na tabela clientes, veja que todas as variáveis públicas na unPesquisa têm seus valores agregados neste trecho de código, ou seja,

Consultor Técnico The Club.

Sobre o autor

Lucas Vieira de Oliveira

[email protected]

conhecendo os parâmetros a serem passados, pode-se facilmente fazer a mesma coisa com a tela de produtos, apenas passado os parâmetros referentes à tabela de produtos.

Veja que depois de passados os parâmetros, exibe-se o fmpesquisa em ShowModal, ou seja, agora fica por conta da tela de pesquisa realizar todas as tarefas de pesquisa.

Ao fechar a tela de pesquisa, livra da memória o fmPesquisa com o método FreeAndNil.

Veja na figura 4 nosso exemplo em

tempo de execução listando os registros da tela de produtos:

Conclusão

Eu procurei demonstrar neste artigo como pode-se utilizar um único formulário para realizar as pesquisas de registros do banco de dados. Vale lem-brar que fazendo isso, diminui e muito a criação de formulários para a aplicação, além de otimizar e reutilizar os códigos de pesquisa. Pode-se também criar ou-tros parâmetros para uma tela um pouco mais complexa, como por exemplo, colocar um componente combobox que listará os campos para pesquisa, mas isso fica a critério e criatividade de cada um.

Espero ter ajudado com este artigo, até uma próxima.

Figura 4 – Tela de pesquisa em execução listando registros de produtos

julho 201228

Dicas DELPHIComo garantir que o programa seja executado apenas

uma vez

Esta dica tem como função mostrar um exemplo simples de código, que irá assegurar que o aplicativo seja aberto apenas uma vez, e quando clicado novamente, ao invés de abrir outro aplicativo, apenas chamará o foco ao aplicativo que já está em execução.

Geralmente quando o aplicativo exige muito de memória, é interes-sante utilizar esta prática, de garantir que a aplicação seja executada apenas uma vez, pois outra cópia da aplicação sendo executada pode exigir demais do hardware, e até existem casos em que o usuário esquece que o programa já está em execução, e acaba abrindo novamente o aplicativo.

Claro que existem exceções, se o aplicativo tiver de ser executado em rede, onde os terminais acessarão apenas um aplicativo, esta dica deve ser desconsiderada.

Para o exemplo siga os seguintes requisitos:

1. Crie um novo projeto no Delphi;2. Salve a unit principal com o nome unPrincipal; 3. Salve o nome do projeto como ExecutaUmaVez;4. Altere o nome do Form1 para fmrPrincipal.

Com o projeto aberto no Delphi, pressione [Ctrl + F12] e selecione o arquivo ExecutaUmaVez. Na cláusula uses adicione a biblioteca Windows. Antes do bloco Begin e End, crie uma variável Aplicacao do tipo THandle, e dentro do bloco, antes da linha “Application.Initialize;”.

Veja como ficará o código na listagem 1.

var Aplicacao : THandle;begin

Aplicacao := FindWindow(‘TfmrPrincipal’, nil);

if (Aplicacao <> 0) then begin Application.MessageBox(‘Este Programa já está sendo executado’, ‘Programa já em execução’, MB_OK); if not(IsWindowVisible(Aplicacao)) then ShowWindow(Aplicacao, SW_RESTORE); SetForegroundWindow(Aplicacao); Exit; end;

Application.Initialize;

Application.CreateForm(TfmrPrincipal, fmrPrincipal); Application.Run;end.

Listagem 1

Após a variável Aplicacao ter o seu valor incrementado, faz-se uma verificação, onde se o valor da mesma for diferente de zero, significa que ain-da não foi executada nenhuma vez, e caso contrário, exibe uma mensagem indicando que a aplicação já está em execução, e na sequência será verificado se a janela está minimizada para que seja restaurada, e logo após a aplicação será chamada ao foco principal da tela.

Para fazer o teste deste exemplo, execute o projeto, depois finalize a aplicação, salve o projeto e feche o Delphi, e abra a pasta onde o projeto foi salvo e execute quantas vezes quiser o projeto para ver o resultado.

Função para criar subpasta dentro da pasta do execu-tável

Esta função cria em tempo de execução, um subdiretório dentro do dire-tório onde se encontra o arquivo executável do projeto. Antes implementar a função na sua unit, declare na sessão use, as bibliotecas SysUtils e FileCtrl. Veja na listagem 1 a implementação da função.

function TfmrPrincipal.CriaSubDir(const SubDir: string): Boolean;var ExePath: string;begin

ExePath := ExtractFilePath(ParamStr(0)) + SubDir; if DirectoryExists(ExePath) then Result := true else Result := CreateDir(ExePath);

end;

Listagem 1

A função ParamStr(index:integer) quando passado o índice zero, retorna o caminho completo do executável. Já a função ExtractFilePath(FileName:String) retorna o path do arquivo passado, ou seja, a variável ExePath está armazenando o caminho do diretório do executável.

julho 2012 29

A função DirectoryExists(Name:String) retorna o valor True quando o diretório informado já existe e False caso não exista. Neste caso estamos veri-ficando se o diretório que será criado existe, se sim, o result da função receberá True, se não, o result receberá o resultado da função CreateDir(Dir:String), esta função retorna True quando o diretório informado é criado com sucesso, e False caso dê problemas com a criação da pasta.

Veja na listagem 2 um exemplo de utilização desta função. Onde foi criado um Tedit para receber o nome do diretório a ser criado e um botão para criá-lo, ou seja, o código deverá ser implementado no evento onClick do botão.

procedure TfmrPrincipal.Button1Click(Sender: TObject);begin if (Edit1.Text <> ‘’) then begin if not (CriaSubDir(Edit1.Text)) then ShowMessage(‘Não foi possível criar o Diretório’); end;end;

Listagem 2

Como personalizar a janela hint dos componentes no Delphi

Nesta dica será criado um procedimento que irá configurar as propriedades da fonte dos hints dos componentes presentes no formulário, este procedi-mento será chamado a partir do evento onCreate do formulário.

Abra um novo projeto no Delphi, e coloque alguns componentes visuais, e preencha a propriedade hint da cada um com alguma informação, lembre-se de habilitar a exibição do hint marcando True na propriedade ShowHint de cada componente. Até aqui, o exemplo já pode ser executado e visualizado, porém os hints dos componentes ainda estão no padrão do Delphi.

Agora vamos declarar a procedure antes da diretiva private da unit do formulário.

procedure FontHint(var TextoHint:String; var CanShow:Boolean; var HintInfo:THintInfo);

private { Private declarations }

Listagem 1 – Declaração da Procedure

Após declarar a procedure, pressione as teclas [Ctrl + Shift + C] para criar automaticamente o corpo da mesma. Crie uma variável local, “i” do tipo inteiro, para fazer um laço de repetição.

Veja o código na listagem 2.

procedure TForm1.FontHint(var TextoHint: String; var CanShow: Boolean; var HintInfo: THintInfo);var i:Integer;begin

for i:= 0 to Application.ComponentCount - 1 do if Application.Components[i] is THintWindow then with THintWindow(Application.Components[i]).Canvas do begin Font.Name:= ‘Calibri’; Font.Size:= 15; Font.Style:= [fsItalic]; HintInfo.HintColor:= clAqua; end;

end;

Listagem 2 - Corpo

O laço passará por todos os componentes presentes no formulário. Em cada componente faz-se uma verificação, onde visa se o componente é da classe ThintWindow, se for, terá as propriedades da fonte alteradas, para os valores que estão nas linhas de comando da procedure. Note que foram alterados as propriedades Nome, Size (tamanho da fonte), Style (fsBold = Negrito, fsItalic = Itálico, etc...) e HintColor que faz referência à cor de fundo da janela hint.

Esta procedure pode ser chamada no evento onCreate do formu-lário, veja o exemplo na listagem 3.

procedure TForm1.FormCreate(Sender: TObject);begin

Application.OnShowHint:= FontHint;

end;

Listagem 3

Agora é só executar o projeto e ver a diferença dos novos hints. Espero que tenha ajudado com esta dica até mais.

julho 201230

VerticalHorizontal

julho 2012

julho 2012