the club - megazine · um forte abraço, av. profº celso ferreira da silva, 190 jd. europa -...
TRANSCRIPT
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
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
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
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
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.