agosto 2012
agosto 2012
índice
04
Android
15
Android - Lendo e Carregando Arquivo Texto
Autor: Thiago C.
Montebugnoli
Delphi
C#
Editorial
05
Linguagem C# - Criando Classes e Objetos
Autor: Marcos César
Silva
10
Criando aplicações com FireMonkey e acesso a
banco de dados no Delphi
XE2
Autor: Lucas Vieira de
Oliveira
Delphi
Delphi Parte V
Autor: Luciano
Pimenta
21
Desafio The Club
Dicas
28
Legenda
30
Iniciante
Intermediário
Avançado
agosto 2012
03
Bem-vindo
Salve! Salve! Neste mês a revista The Club comemora no dia 5
de Agosto o Dia Internacional da Cerveja, tendo como propósito
principal a possibilidade de unir amigos e familiares para saborear
com responsabilidade esta maravilhosa bebida.
Tão bom quanto uma cerveja gelada em uma sexta-feira agitada
estão os artigos dos colunistas e colaboradores deste mês.
Marcos César Silva nos ensina a Criar Classes e Objetos de uma
forma simples e prática na Linguagem C#, servindo de base para
outros tipos de linguagens.
Av. Profº Celso Ferreira da Silva, 190
Jd. Europa - Avaré - SP - CEP 18.707-150
Informações e Suporte: (14) 3732-1529
Internet
http://www.theclub.com.br
Cadastro: [email protected]
Suporte: [email protected]
Informações: [email protected]
Skype Cadastro: theclub_cadastro
Skype Suporte: theclub_linha1
theclub_linha2
theclub_linha3
www.twitter.com/theclubbr
Nosso colaborador mensal Luciano Pimenta traz a quinta parte
da seqüência dos artigos do Curso de Delphi XE para Iniciantes,
tendo também muitas informações para os que já possuem um
pouco mais de experiência com o Delphi.
Já o consultor técnico Lucas de Oliveira continua firme e forte
abordando assuntos de grande importância e relevância no suporte
técnico, sendo que neste mês ele cria exemplos de aplicações com
FireMonkey junto com acesso a banco de dados.
O FireMonkey é uma VCL turbinada que torna possível criar formulários mais interativos. Eu continuo minha jornada com artigos
relacionados ao Sistema Android criando um exemplo prático de
como se deve ler e carregar arquivos do tipo texto.
A seção de “Dicas Delphi” está sempre nos disponibilizando os
melhores macetes e assuntos abordados neste mês de Agosto.
Um Forte abraço,
Copyright The Club 2012
Diretor Técnico
Marcos César Silva
Diagramação
Eduardo Massud
Arte
Vitor M. Rodrigues
Revisão
Eliziane Valentim
Colunistas
Lucas de Oliveira
Luciano Pimenta
Thiago Cavalheiro Montebugnoli
Marcos César Silva
Impressão e acabamento:
GRIL - Gráfica e Editora
Taquarituba-SP - Tel. (14) 3762-1345
Reprodução
Thiago Montebugnoli - Editor Chefe
[email protected]
04
agosto 2012
A 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.
Delphi é marca registrada da Borland International,
as demais marcas citadas são registradas
pelos seus respectivos proprietários.
C#
Linguagem C#
Criando Classes
e Objetos
Nesta importante etapa abordo um
conceito geral de Classes e Objetos na linguagem C# aproveitando para descrever os
tipos mais importantes ao decorrer do nosso
aprendizado. Na Programação Orientada a
Objetos (POO) tudo é baseado em classes e
objetos, sendo que o conceito é universal e
imprescindível, qualquer que seja a linguagem
em que esta seja aplicada.
A POO procura estabelecer um modelo de
programação que aproxima o desenvolvedor do
mundo real. Seguiremos enfatizando os principais
conceitos e posteriormente um exemplo prático do
uso de Classes e Objetos.
Conceito Geral de Classes e Objetos
Uma classe é uma unidade do sistema e
dentro dela estão definidos atributos e métodos,
que são respectivamente as informações que uma
classe pode armazenar e ações que elas podem
desempenhar.
Para ficar mais fácil o entendimento, um atributo possui as mesmas funcionalidades de uma
variável, assim como um método o mesmo que um
procedimento ou função. A diferença fundamental
entre classe e objeto reside no fato da classe conter
as definições do que essa nova unidade irá fazer
e o objeto ser um caso especial de uma classe. É
importante saber que enquanto exista apenas uma
definição de classe, podem existir diversos objetos
baseados numa classe.
agosto 2012
05
mente. Podemos então encapsular estas propriedades com a ajuda do “Refactor”, clicando com o
botão direito em “nome” escolhendo “Refactor/
Encapsulate Field...”
Ver Figura 02.
Logo após aparecerá uma janela com os seguintes dizeres. Ver Imagem 03.
São as funções e Procedimentos dentro da
classe. Realizam operações sobre as informações
contidas nos atributos de uma classe. Os métodos
podem ser entendidos como mensagens trocadas
entre diferentes objetos. Assim como os atributos,
os métodos também podem ser do tipo público
ou privado.
Exemplo:
Figura 01: Classe e Objeto.
//Declaração do método
Cadastrar(), do tipo
“void” e “public”
A imagem 01 ilustra de uma forma mais didática o que estou descrevendo.
Conceito de Atributos
Na realidade, os denominados atributos nada
mais são do que as variáveis da classe, os locais
que guardarão as informações referentes aquela
classe. Quando um objeto é criado a partir de uma
classe, neste momento os atributos passam a ter
informações específicas assumindo estados especiais, ou seja, de uma forma geral este é o momento
onde são atribuídos os valores. Existem dois tipos
de atributos, os que permitem acesso externo ao
da classe e os que não permitem, são denominados respectivamente de “Públicos” e “Privados”.
Aproveitando este tópico, falaremos de um recurso
importante da POO, o Encapsulamento de dados,
que significa uma proteção às suas propriedades.
De uma forma geral, estes conceitos são melhores
compreendidos seguindo o exemplo a seguir.
Exemplo:
//Declaração do atributo
do tipo “string” e
“private” private string
nome;
A linguagem C#, junto com o Visual Studio
possui inúmeros macetes que nos auxilia diaria-
Figura 02: Refactor/Encapsulate Field.
06
agosto 2012
Figura 03: Encapsulate Field.
Por padrão a Propriedade “nome” virá com
a primeira letra em maiúsculo, isto serve para
diferenciar da propriedade privada criada anteriormente. Clique no botão “Ok” para prosseguir
com o código a seguir.
//Encapsulamento do
atributo Público Nome
public string Nome
{
get
{
return nome;
}
set
{
nome = value;
}
}
Deixamos o atributo “Nome” dinâmico, pois
poderemos retornar e atribuir valores dinamicamente com os operadores “Get” e “Set” respectivamente, permitindo criar regras e lógicas para
acesso a dados e público permitindo uma visibilidade e acessibilidade externa à Classe. Usaremos
este recurso para fins didáticos, sem nenhuma
regra adicional.
Conceito de Métodos
public void Cadastrar()
{
MessageBox.
Show("Cadastrando sócio...
");
}
Métodos do tipo “void” podem ser comparados aos procedimentos, ou seja, não retornam nenhum valor. Já para retornar algum dado veremos
o exemplo a seguir.
Exemplo:
//Declaração do método
ConfirmarCadastro(), do
tipo “bool” e “public”
public bool
ConfirmarCadastro(int
tipo)
{
if (tipo == 1)
return true;
else
return true;
}
O método criado anteriormente está retornando um valor do tipo Booleano utilizando a cláusula
“return”, que significa retorno.
Construtores e Destrutores
Toda classe criada deverá possuir dois métodos: o Construtor (Construct) que é chamado
no momento quando instanciamos a Classe e o
Destrutor (Destruct) quando liberamos o objeto
criado por esta classe da memória.
No C# temos o denominado “Garbage Collector”, trocando em miúdos seria um “Coletor
de Lixos”. Ele é responsável pela destruição de
todo objeto que não é mais utilizado, sendo
um recurso capaz de oferecer uma solução
automatizada ao gerenciamento de memória.
Exemplo:
//Construtor
public Socio()
{
MessageBox.
Show("Objeto Criado com
sucesso!");
}
//Destrutor
~Socio()da classe
{
}
do pelo nível de acesso (public) seguindo pela
palavra chave “class”.
Exemplo:
public class Socio
{
// Códigos da Classe
}
Neste caso temos uma classe pública chamada
“Socio”.
Privada (Private)
Seguindo a mesma lógica dos atributos e
métodos, as classes privadas não permitem
acesso externo.
A sintaxe de criação pode ser conferida
a seguir.
Exemplo:
O método Construtor será invocado quando instanciamos a Classe “Socio” e para fins de
aprendizado achei interessante demonstrar a
sintaxe do Destrutor, que normalmente não
precisamos nos preocupar, pois contamos
com o recurso “Garbage Collector” citado
anteriormente.
Tipos de Classes
Na Programação Orientada a Objetos
contamos com diversos tipos de classes como:
Públicas, Privadas, Protegidas, Estáticas, Abstratas, Seladas, Herdadas entre outras, sendo
que todas possuem recursos que se encaixam
ao decorrer da análise do projetista. Nesta etapa abordarei os principais conceitos referentes
a este assunto
Pública (Public)
As classes públicas, assim como os atributos e métodos, permitem que qualquer pessoa
instancie objetos. O nome da classe é precedi-
private class Socio
{
// Códigos da Classe
}
Ou
class Socio
{
// Códigos da Classe
}
Existem duas maneiras para declaração de
classes privadas, a primeira utilizando a palavra
“private” e a segunda sem nenhuma referência.
Public class Socio
{
//atributos estáticos
private string nome;
public string Nome
{
get { return
nome;}
set { nome =
value;}
}
}
Exemplo de utilização:
Socio soc = new Socio();
soc.Nome = "Thiago
Montebugnoli";
Estáticas
Quando utilizamos estes tipos de classes, deveremos por obrigação, possuir todos os atributos
como estáticos. A principal característica destas
classes é não permitir realizar a instância de um
objeto, ou seja, quando for utilizá-la basta fazer
referência aos membros para poder trabalhar com
os mesmos.
Exemplo de criação:
Public static class Socio
{
//atributos estáticos
private static string nome;
public static string Nome
{
get { return Socio.nome;}
set { Socio.nome = value;}
}
Com o exemplo citado anteriormente fica mais
fácil a visualização.
Instanciáveis
Este tipo de classe é o mais utilizado, ou
seja, toda vez que precisarmos criar um objeto,
é necessário instanciá-lo, podendo assim criar
vários objetos desta mesma classe.
Exemplo de criação:
}
Exemplo de utilização:
Socio.nome = “Thiago
Montebugnoli”
agosto 2012
07
Na sua utilização basta atribuir o valor desejado. Como foi dito anteriormente, a instancia já
é criada automaticamente quando executamos o
programa, podendo ser utilizada em todos os pontos do software. A principal vantagem no uso desta
classe é a automatização na criação da instância.
Criando um Exemplo prático
Crie uma aplicação “Windows Forms” e adicione um botão no formulário. A tela deverá ficar
idêntica a Imagem 04.
//Namespaces utilizados
using System;
using System.Collections.
Generic;
using System.Linq;
using System.Text;
using System.Windows.
Forms;
namespace Classes
{
//Classe pública
public class Socio
{
//Construtor da
classe
public Socio()
{
MessageBox.
Show("Objeto Criado com
sucesso!");
}
//Destrutor da
Figura 04: Tela de Exemplo.
A partir de agora vou detalhar todas as etapas
de como se deve criar uma classe e usá-la logo
em seguida, para isto clique em cima da solução e
com o botão direito escolha “Add/New Item...” e
na região esquerda em “Visual C# Items” escolha
“Code” e em seguida “Class”. Aproveite e clique no
botão “Add”. Ver Imagem 05.
Figura 05: Adicionando uma Classe no projeto.
O Visual Studio por padrão cria apenas o
namespace “Classes”, e a classe “Socio”. Vou
criar uma classe pública e logo em seguida
instanciá-la. A Imagem 01 nos ilustra de uma
forma clara de como irá ficar nossa classe
“Socio” e o código abaixo abrange de uma
forma prática todas as etapas explicadas anteriormente.
08
agosto 2012
classe
~Socio()
{
string Cpf
{
get { return
cpf; }
set { cpf =
value; }
}
public string Rg
{
get { return
rg; }
set { rg =
value; }
}
public DateTime
Nascimento
{
get { return
nascimento; }
set {
nascimento = value; }
}
public string
Telefone
{
}
//Atributos/
Propriedades Privadas
Encapsuladas
private string
nome;
private string
cpf;
private string rg;
private DateTime
nascimento;
private string
telefone;
private string
endereco;
//Atributos/
Propriedades Públicas
Encapsuladas
public string Nome
{
get { return
nome;}
set { nome =
value;}
}
public
get { return
telefone; }
set { telefone
= value; }
}
public string
Endereco
{
get { return
endereco; }
set { endereco
= value; }
}
//Métodos públicos
public void
Cadastrar()
{
MessageBox.Show(string.
Format("Cadastrando
sócio...\r\nNome:
{0}, - Rg: {1}, Cpf:
{2}",nome,rg,cpf));
}
public bool
ConfirmarCadastro(int
tipo)
Parse("15/11/1984");
soc.Telefone = "(14)
{
if (tipo == 1)
return
true;
9999-9999";
soc.Endereco = "Rua
Fulano de Tal, 999";
else
return
//Invocando métodos
soc.Cadastrar();
true;
}
public bool
ValidarSocio(int tipo)
{
if (tipo == 1)
return
true;
else
return
true;
}
if (soc.
ConfirmarCadastro(1))
MessageBox.
Show("Cadastro
Confirmado!");
Figura 07: Passo 02 – Atribuindo Valores e
Executando Métodos.
if (soc.
ValidarSocio(1))
MessageBox.
Show("Sócio Validado!");
soc.Alterar();
public void
Alterar()
{
MessageBox.
Show("Alterando
sócio...");
}
}
O primeiro passo foi criado o objeto “soc”
usando a palavra reservada “new”, logo em seguida
definimos os atributos e invocamos os métodos. A
Figura 06, 07 e 08 nos dá uma boa idéia do funcionamento de uma classe em “Run-Time” .
}
}
//Inserindo atributos
soc.Nome = "Thiago
Montebugnoli";
soc.Rg = "41.999.9999";
soc.Cpf =
"312.999.999-99";
soc.Nascimento
= DateTime.
Neste artigo procurei separar em duas etapas,
a primeira com conceitos básicos de Programação
Orientada a Objetos (POO) e a outra com um exemplo prático e de fácil entendimento.
Vou continuar com conceitos e dicas sobre este
assunto nos próximos artigos.
No formulário criado iremos instanciar um
objeto da classe “Socio” e logo em seguida o código
comentado correspondente.
private void button1_
Click(object sender,
EventArgs e)
{
//Instanciando um
objeto
Socio soc = new
Socio();
Conclusão
Abraços e até o mês que vem!
Figura 06: Passo 01 - Construtor.
Sobre o autor
Marcos César Silva
Consultor de Sistemas na consultoria de sistemas DataSmart e Consultor Técnico do The Club, Bacharel em Ciência
da Computação, MBA em Gestão Empresarial, Certificações
MCAD (Microsoft Certified Application Developer) e MCSD.
NET (Microsoft Certified Solution Developer .NET)
[email protected]
agosto 2012
09
Criando aplicações com
FireMonkey e
acesso a banco de dados
no Delphi XE2
Este artigo tem como foco, criar uma
aplicação de exemplo utilizando a plataforma FireMonkey, a tecnologia LiveBindings, a
tecnologia DBExpress e o Servidor de banco
de dados FireBird. Serão abordados com
mais profundidade os temas FireMonkey e
LiveBindings que são novidade da nova IDE
do Delphi, a XE2. Vamos então conhecer um
pouco sobre essas novas tecnologias que
foram acopladas ao Delphi.
O que é o FireMonkey?
O Delphi XE2 chegou ao mercado repleto de
novidades. E uma das mais cobiçadas pela comu10
agosto 2012
nidade Delphi é o FireMonkey. Este framework
chamou a atenção dos usuários Delphi por suas
excelentes características.
O FireMonkey é uma nova plataforma de desenvolvimento do Delphi XE2, com ela é possível
criar aplicações e distribuí-las para plataformas
Windows 32 bits, Windows 64 bits, Mac OS X e
iOS (iPhone). Além disso, o FireMonkey possibilita
criar uma aplicação mais rica em visual, além é claro
de criar gráficos em 3D, similares as animações
criadas em Flash que são utilizadas em muitas
páginas da web.
O FireMonkey não deixa nada a desejar, nem
se tratando em desempenho de aplicações, pois
utiliza de todo o poder da CPU e também da GPU
(Unidade de Processamento Gráfico) para aplica-
ções em 3D, assim sendo, não precisa se preocupar
com o desempenho de suas aplicações FireMonkey.
São quatro tipos de projetos FireMonkey para
o Delphi XE2, são eles:
1.
2.
3.
4.
FireMonkey 3D Application;
FireMonkey 3D iOS Application;
FireMonkey HD Application;
FireMonkey HD iOS Application.
Tendo em vista estas opções de projetos,
percebe que FireMonkey HD Application dentre
as demais é a que mais coincide com a tradicional
VCL, os projetos para aplicações iPhone se percebe
facilmente, e os projetos para aplicações com gráficos em 3D também fica fácil se perceber. Neste
artigo será exemplificado mais a frente, a forma
que mais se coincide com a VCL.
Conexão a dados através da DBExpress
Na VCL, tradicional plataforma de desenvolvimento mais utilizada pelos usuários Delphi em aplicações com acesso a dados, utiliza-se, entre outras
tecnologias, a DBExpress para acessar um banco de
dados pela aplicação. Dentro de um DataModule
distribui-se os componentes utilizados para este
acesso, que são sequencialmente o TSQLConnection e o TSQLDataSet ou TSQLQuery. Para garantir
melhor desempenho, utiliza-se também a combinação de alguns componentes da palheta DataAccess,
o TDataSetProvider e o TClientDataSet. Com estes
componentes devidamente configurados, já terá
uma conexão persistente com um banco de dados.
Continuando a linha de raciocínio, na VCL,
depois de configurados os componentes de acesso
aos dados, é necessário utilizar um componente
TDataSource dentro do formulário onde será feita
a manipulação dos dados, este que será a origem
dos dados no formulário. Para exibir os dados no
formulário faz-se o uso de componentes DataWares, como DBEdit, EDbText entre outros da palheta
DataControls.
LiveBindings é baseado em expressões relacionais, é um novo recurso de ligação de dados que foi
adicionado a IDE do Delphi XE2 para apoiar tanto a
VCL quanto o FireMonkey, utiliza-se de expressões
para fazer a ligação de um objeto a outro por meio
de suas propriedades.
O conceito principal destas ligações está em
identificar o objeto de origem e o objeto de controle (o destino dos dados), além é claro de configurar
as expressão de origem do objeto de origem e a
expressão de controle. Estas configurações podem
ser feitas no pelo ObjectInspector nas propriedades
do objeto de controle.
Tendo em vista que estas ligações envolvem
um objeto de origem e um objeto de controle,
podemos ter três situações sobre o fluxo dos dados,
sabendo que Source e Control são respectivamente
os objetos de origem e de controle:
1.
2.
3.
dirSouceToControl;
dirControlToSouce;
dirBidirectional.
Estes têm em comum duas propriedades, onde
se configuram o DataSource ao qual estará vinculado e o DatField que é propriamente dito o Campo
da tabela que o componente irá exibir e manipular
no formulário. Estando tudo isso configurado, o
formulário está pronto para exibir e manipular os
dados em tempo de execução.
As opções acima são configuradas na propriedade Direction do componente BindExpression
relacionado ao objeto de controle, não se atente
em entender isso agora, no exemplo será explicado esta ligação com mais detalhes, o importante
agora é saber que o fluxo de dados de uma ligação
LiveBindings pode ser tanto da origem para o
controle quanto do controle para a origem, ou
ainda os dois ao mesmo tempo, marcando a opção
dirBidirectional.
Até aqui não tem nenhuma mudança, como
foi dito esta é uma das formas mais tradicionais
de conexão a banco de dados utilizada em Delphi.
Esta seria uma conexão para uma VCL, mas e se
fosse uma aplicação FireMonkey, o que mudaria?
A resposta é bem simples, não mudaria nada que
se refere à conexão de banco de dados, ou seja,
poderá continuar utilizando forma tradicional.
Ao criar uma expressão de ligação pelo ObjectInspector, é adicionado ao formulário automaticamente um componente BindingList, que armazenará e gerenciará todas as expressões presentes
neste formulário. Outro componente importante
é o BindScope, o qual gera um escopo de ligação
entre os componentes. No caso de ligação a dados,
ou seja, a um TDataSouce, usa-se o BindScopeDB.
O que muda realmente, é que o FireMonkey
não conta com os componentes DataWares da palheta DataControls, o DBEdit, o DBText, etc... Sendo
assim, para exibir os dados num formulários serão
utilizados os componentes da palheta Standard.
Neste ponto surge a necessidade de se utilizar a
outra novidade da versão XE2 do Delphi, a tecnologia LiveBindings (Ligações ao vivo).
Um exemplo simples de LiveBindings seria
passar o texto digitado em um TEdit para ao Caption de um TLabel, neste caso o TEdit é a origem
dos dados, ou seja, a configuração de ligação entre
os componentes será feita toda no TLabel pela
propriedade LiveBindings.
O que é LiveBindings?
Neste ponto se for um projeto montado na
plataforma FireMonkey, listará nesta propriedade
duas opções, ‘New LiveBinding’ e ‘Link To DB Field’,
se for uma projeto em VCL apenas aparecerá a
primeira opção. Seguindo o exemplo, escolha a
opção ‘New LiveBinding’, aparecerá uma janela
para selecionar o tipo de componente que deseja
criar, selecione TBindExpression e clique em ‘Ok’.
Aparecerá mais uma propriedade no ObjectInspector do TLabel, denominada BindExpressionLabel11. Agora será definido a ligação entre os
objetos, marque os seguintes valores nas seguintes
propriedades do Label1:
1. ControlExpression = Text (Na plataforma
FireMonkey não é mais Caption);
2. Direction = dirSourceToControl;
3. SourceComponent = Edit1;
4. SourceExpression = Text.
Até aqui já está configurado a ligação, porém
resta agora apenas notificar o mecanismo de expressão, que irá atualizar os objetos conforme as
alterações em suas propriedades, para isso basta
apenas uma linha de código. No evento onChange
do Edit1, coloque a seguinte codificação:
BindingsList1.
Notify(Edit1, ‘Text’);
O método Notify, irá notificar aos mecanismos
de expressões as mudanças que ocorreram na propriedade Text, o segundo parâmetro do método,
do componente Edit1 que é o Primeiro parâmetro
do método. Pronto este primeiro exemplo já está
funcional, pode executá-lo e ver o que acontece
com acontece com a Label1 depois que digitar
algo na caixa de texto. Veja na figura 1 o exemplo
em execução.
Figura 1 – Exemplo de LiveBindings na plataforma VCL
Com este pequeno exemplo, espero ter esclarecido a funcionalidade do recurso LiveBindings,
agora podemos ter exemplo base do artigo onde
será criado um projeto FireMonkey HD Application
que fará conexão a um banco de dados FireBird
através da tecnologia DBExpress.
agosto 2012
11
Exemplo prático do FireMonkey com
ligação ao banco de dados FireBird
Criação do projeto FireMonkey HD
Application - Delphi
Agora descreverei os passos para a criação do
exemplo prático deste artigo, serão divididos em
etapas para facilitar o entendimento e a possibilidade do leitor pular uma etapa em que já possua
o conhecimento específico como a conexão à base
de dados.
O próximo passo é abrir o Delphi XE2 e criar um
novo projeto FireMonkey HD Application - Delphi.
Salve na pasta ‘Fontes’ que está dentro da pasta
‘Escolar’ o projeto com o nome ESCOLAR.dproj,
e salve a primeira Unit com o nome de unAlunos.
pas. Esta será a Unit que manipulará os dados da
tabela Alunos presente no banco de dados. Altera
a propriedade Name do Form1 para ‘frmAlunos’.
Criação do banco de dados
Por motivo de organização, crie uma pasta
com o nome do projeto ‘Escolar’ e dentro dela
outra pasta onde será salvo o banco de dados,
pode nomeá-la como ‘Banco’, se necessário
pode até criar uma pasta para organizar as fontes do projeto, mas isto fica a critério de cada
um, uma boa organização agiliza e muito na
localização de arquivos pertinentes ao projeto.
Crie um banco de dados firebird com o nome
ESCOLAR, que será usado a fim de exemplificar
este artigo, e uma tabela ALUNOS com os seguintes
campos:
CREATE TABLE ALUNOS (
ID_ALUNO INTEGER NOT
NULL,
NOME VARCHAR (60)
CHARACTER SET NONE COLLATE
NONE,
DATA_NASCIMENTO DATE,
CPF VARCHAR (15)
CHARACTER SET NONE COLLATE
NONE,
CIDADE VARCHAR (60)
CHARACTER SET NONE COLLATE
NONE,
UF CHAR (2) CHARACTER
SET NONE COLLATE NONE,
TELEFONE VARCHAR (15)
CHARACTER SET NONE COLLATE
NONE);
ALTER TABLE ALUNOS ADD
CONSTRAINT PK_ALUNOS
PRIMARY KEY (ID_ALUNO);
CREATE UNIQUE INDEX
PK_ALUNOS ON ALUNOS (ID_
ALUNO);
Listagem 1: Banco de dados Escolar
12
agosto 2012
Conexão da aplicação à base de dados
através de um DataModule
Para fazer a conexão da aplicação criada com
a base de dados, crie um DataModule pelo menu
‘File/New/Other’ e na janela New Itens seleciona
no menu à esquerda ‘Delphi Projects/Delphi Files’,
serão listados à direita os itens a serem adicionados
ao projeto, escolha DataModule e clique em Ok.
Altere a propriedade Name do DataModule1 para
DM e salve a Unit com o nome unDm.
Através do mecanismo DataExplorer, localizado
à direita da tela, crie uma nova conexão FireBird
clicando com o botão direito em seguida New Connection, de o nome de ESCOLAR. Para especificar
o caminho do banco de dados, clique com o botão
direito na conexão que acabou de criar e selecione
a opção Modify Connection, informe a localização
do arquivo do banco de dados, o nome de usuário
e a senha de acesso do mesmo, e teste a conexão.
Caso de algum erro verifique se o caminho está
certo, caso seja necessário antes do caminho especifique o IP ou o nome do computador, exemplo
‘NomedoPC-PC:C:\ESCOLAR\Banco\ESCOLAR.FDB’.
Configurando os componentes DBExpress
Coloque um componente TSQLConnection
da palheta DBExpress e configure a propriedade
ConnectionName para ESCOLAR, marque false
em LoginPrompt e de o nome de CONEXAO. Agora
coloque no DM um componente TSQLDataSet também da palheta DBExpress, altere seu Name para
sdsAlunos, defina em ConnectionName a conexão
Escolar, e coloque em CommandText a SQL ‘SELECT
* FROM ALUNOS’. Carregue os Fields do sdsAlunos
e configure suas propriedades ProvidersFlags.
Adicione mais um componente ao DM, agora um
TDataSetProvider da palheta DataAccess, dê o
nome de dspAlunos, em UpDateMode selecione
upWhereKeyOnly e para finalizar as configurações
deste componente selecione a propriedade opções
e marque True em poAllowCommandText. Agora
para finalizar e possibilitar o acesso dos dados
em memória local, de forma desconectada com o
servidor de banco de dados, coloque um componente TClientDataSet da palheta DataAccess, altere
a propriedade Name para cdsAlunos e selecione
em ProviderName o dspAlunos. Até este ponto,
o mecanismo de acesso e manipulação aos dados
está pronto. O que resta fazer é carregar os Fields
do cdsAlunos e configurá-los da mesma forma
como os Fields do sdsAlunos.
Como o cdsAlunos irá trabalhar com os dados
em memória local, para poder gravar no banco de
dados às atualizações feitas nele é preciso chamar
o método ApplyUpDates passando o parâmetro -1
ou 0 (zero) nos eventos AfterPost e AfterDelete,
veja na listagem 2 um exemplo:
procedure TDM.cdsAlunos
AfterDelete(DataSet:
TDataSet);
begin
cdsAlunos.
ApplyUpdates(-1);
end;
Listagem 2 – Método ApplyUpDates do cdsAlunos
Criando um layout para o frmAlunos
e ligando-o ao DM
Até este ponto do exemplo não tem novidades para quem já trabalha com a tecnologia
DBExpress, pois a conexão com o banco de dados,
como foi dito antes, continua sendo feita da forma
tradicional. Porém, agora temos que vincular os
Fields do cdsAlunos, que se encontra no DM, a um
componente TDataSource, que será adicionado
no frmAlunos, ou seja, o frmAlunos terá que ter
a declaração da unDm em sua cláusula Uses, isto
pode ser feito visualmente pelo menu ‘File/Use
Unit’, depois basta selecionar a unDm e confirmar
clicando em Ok. Logo após adicione um DataSource
ao frmAlunos e altere o Name dele para dsAlunos,
este será a origem dos dados deste formulário, na
propriedade DataSet selecione pelo combo a opção
DM.cdsAlunos. Na VCL isto garantiria que qualquer
componente DataWare, da palheta DataControls,
ligado ao dsAlunos poderia manipular um Field
sem maiores complicações, bastaria apenas configurar no componente o dsAlunos e o Field que ele
representaria. Como estamos criando um projeto
pela plataforma FireMonkey, isso já não é possível
devido ao fato de não contarmos com estes componentes DataWares, por isso teremos que fazer
o uso do novo recurso de ligações LiveBindings,
para podermos configurar os componentes visuais
comuns para estarem gerenciando os dados a partir
de expressões.
Para poder fazer um vinculo das expressões
LiveBindings com o dsAlunos teremos é claro que
definir um escopo para estas ligações, sendo assim
adicione ao formulário um TBindScopeDB, altere
seu Name para BindScopeDB e na propriedade
DataSource selecione o dsAlunos, com isso qualquer componente visual através da propriedade
LiveBinding terá acesso aos Fields do cdsAlunos e
poderá manipulá-los.
Agora vamos definir um layout para o frmAlunos, veja na figura 2 uma sugestão, neste exemplo será utilizado um BindNavigator da palheta
LiveBindings, que tem a mesma funcionalidade
de um DBNavigator, neste componente é necessário apenas configurar a propriedade BindScope
selecionando o recém-criado BindScopeDB. Será
necessário também adicionar os componentes de
edição e visualização dos campos da tabela de alunos, neste caso iremos adicionar seis componentes
TEdit lembrando de alterar a propriedades Name
de cada um seguindo um padrão, por exemplo
edtIdAluno, edtNome, edtDataNascimento, edtCPF,
edtCidade e edtTelefone. Assim ficará mais fácil
fazer a chamada deste componentes nas linhas de
código. Coloque também um componente TComboEdit da palheta Additinonal, este tem a mesma
função do combobox comum, onde se preenche
uma lista de itens, estes que serão os valores a
serem armazenados no banco de dados, altere o
Name deste componente para cbeUF, e adicione as
siglas das UFs na propriedade item separando cada
uma por uma quebra de linha com o botão Enter,
lembrando que o campo UF foi definido com o tipo
Char (2), limitando o armazenamento a apenas 2
caracteres. Para listar os registros cadastrados no
banco, em VCL usa-se um DBGrid, neste exemplo
em Firemonkey será usado um TStringGrid, aletre
seu Name para sgAlunos, mais a frente explicarei
como fazer sua ligação com os dados.
Para finalizar o layout do frmAlunos, restam
apenas distribuir os rótulos (Labels) de cada
componente.
Agora vamos fazer as configurações LiveBin-
dings dos componentes, para que possibilite o
acesso aos dados.
Figura 2 – Sugestão de layout para o frmAlunos
Configurando as ligações dos componentes com o recurso LiveBindings
Tendo todos os componentes visuais ajustados
ao layout do formulário, agora vamos fazer os vínculos com os componentes de acesso aos dados via
LiveBindings. Baseando-se na nomenclatura sugerida dos componentes, selecione o componente
edtIdAluno e na janela ObjectInspector localize a
propriedade LiveBinding, ao clicar na combo serão
listadas duas opções como mostra a figura 3, a
opção NewLiveBinding seria para o caso de fazer
uma ligação manualmente como foi mostrado no
primeiro exemplo onde se informava a ControlExpression, a Direction, o SourceComponent e
a SourceExpression, porém como neste exemplo
as ligações serão feitas aos Fields do cdsAlunos
escolheremos a segunda opção, Link to DB Field,
abrirá uma janela listando os Fields vinculados ao
BindScopeDB, ver figura 4, agora basta selecionar,
neste caso, o Field ID_ALUNO e pressionar Ok.
Faça isso para todos os componentes TEdit, definindo corretamente seus BindLinks para os Fields
correspondentes. No cbeUF (TComboEdit) depois
de inserido as siglas das UFs na lista de itens, basta
criar um BindLink para o campo UF da tabela, da
mesma forma que foi feito com o edtIdAluno.
Figura 3 - Link to DB Field
Ao criar o primeiro DBLink, automaticamente
é criado no formulário um componente TBindingsList, este é responsável por listar todas as
expressões Binding presentes no formulário, pode-se também através deste componente editar as
expressões listadas, alterando suas propriedades
Figura 4 - New DB Link
de forma desvinculadas aos componentes de controle. Entenda que o BindingList utiliza o mesmo
mecanismo de uma ActionList, ele agrupa todos
os controles Bindings facilitando a visualização dos
mesmos, veja na figura 5 a lista dos componentes
do frmAlunos que é aberta logo após dar dois
cliques no componente BindingsList.
Figura 5 - Lista de componentes Bindings
Para configurar a sgAlunos (TStringGrid) muda
um pouco, mas continua seguindo a mesma linha
de raciocínio dos BindLinks, porém a opção será
Link to DB DataSource. Ao selecionar esta opção
será aberta novamente a janela New DB Link para
selecionar em qual o escopo está ligado o dsAlunos,
neste exemplo temos apenas um escopo, mas poderiam ser mais conforme as necessidades forem
surgindo. Ao criar o BindLink para o sgAlunos, já
está praticamente pronto nosso projeto, basta
apenas realizar alguns ajustes para melhorar a
forma de exibição dos dados na grid, logo abaixo da
propriedade LiveBinding do componente sgAlunos,
surgiu uma nova propriedade chamada DBLinksgAlunos1, esta propriedade será criada em todos
os componentes, ela se refere de fato ao BindLink
vinculado ao objeto selecionado, neste caso o
sgAlunos, iremos utilizar a propriedade Columns.
Da mesma forma que no tradicional DBGrid da
VCL, pode-se adicionar os campos do cdsAlunos
na grid de forma manual, podendo assim definir
a largura e o título da coluna de cada Field. Então
agosto 2012
13
clique na propriedade Columns e abrirá a janela
para o gerenciamento das colunas da grid, basta
clicar no botão inserir e selecionar os campos um
a um, definindo suas propriedades, ver tabela 1.
Tabela 1 – Propriedades das colunas da
sgAlunos
Ao preencher todas as propriedades das colunas da sgAlunos, nosso exemplo está quase pronto,
basta alguns ajustes para uma melhor performance. O ideal é que a conexão ao banco de dados
seja aberta apenas uma vez ao abrir o formulário
principal e fecha quando o mesmo seja encerrado.
Como neste exemplo temos apenas uma tela, esta
fará a função de abrir e fechar a conexão e também
abrir e fechar o ClientDataSet utilizado na manipulação dos dados do formulário, o cdsAlunos. Para
que isso seja possível, basta apenas duas linhas
de códigos no evento onCreate e duas no evento
onClose do frmAlunos. Veja a listagem 3.
procedure TfrmAlunos.
FormClose(Sender: TObject;
var Action: TCloseAction);
begin
DM.cdsAlunos.Close;
DM.CONEXAO.Connected :=
False;
Figura 6 - Projeto em tempo de execução
Estes códigos garantem o desempenho do
projeto em execução, mas temos que ter em mente
a ordem de criação formulários na aplicação, acesse
o menu do Delphi ‘Project/Options’ selecione a
opção Forms e veja à direita a ordem em que será
feito o auto-create, se o DM estiver em segundo
lugar no seu projeto, arraste-o para a primeira
posição, para que seja criado antes do frmAlunos
e pressione Ok. Isso é feito para prevenir um futuro
erro de execução. Veja que é feito o uso do DM no
formulário de alunos, para abrir e fechar a conexão
e o cdsAlunos, sendo assim isto não seria possível
se o formulário de alunos fosse criado antes do DM,
por isso o DM deve ser criado antes do formulário. Agora sim, nosso exemplo está funcionando,
pode fazer alguns cadastros de teste, note que a
cada alteração nos componentes a grid vai sendo
atualizada automaticamente como se fosse uma
DBGrid mesmo. Veja na figura 6 a aplicação sendo
executada.
end;
procedure TfrmAlunos.
FormCreate(Sender:
TObject);
begin
DM.CONEXAO.Connected :=
True;
DM.cdsAlunos.Open;
Lucas Vieira de Oliveira
Consultor Técnico The Club.
[email protected]
14
agosto 2012
Procurei mostrar neste artigo, de uma forma
introdutória, um exemplo de como trabalhar com
duas novas tecnologias do Delphi XE2, o FireMonkey e o recurso LiveBindings, para fazer uma
aplicação com acesso à banco de dados. Vimos
que mesmo num projeto FireMonkey a conexão via
DBExpress mantém a mesma forma de trabalhar,
alterando somente a forma de ligar os componentes visuais com os de acesso aos dados.
Além disso, ainda é possível fazer muitas
outras coisas com o Firemonkey, como foi dito na
introdução, é uma tecnologia bastante inovadora e
cheia de recursos para os usuários distribuírem em
suas aplicações. E está abrindo novas portas para
os desenvolvedores adeptos ao Delphi.
Espero que tenham gostado do artigo, um
abraço a todos e até a próxima.
Sobre o autor
end;
Listagem 3 – Códigos de manipulação da conexão e do cdsAlunos na aplicação
Conclusão
Android
Lendo e Carregando
Arquivo Texto
Neste mês abordarei um pouquinho de como podemos criar e carregar arquivos do tipo texto no Android armazenando estas informações
no cartão SD do dispositivo. Montaremos um exemplo prático abordando
recursos como: Criar e utilizar o evento Onclick() do botão, Utilização da
classe “Java.IO” para manipulação de arquivos, entre outros recursos que
poderão ser acompanhados ao decorrer da leitura.
Opções de Armazenamento
O Android nos fornece diversas formas para salvar os dados, sendo que
a solução depende da necessidade, podendo assumir as seguintes formas:
SharedPreferences: Armazenar dados particulares primitivos em pares
chave-valor.
Internal Storage: Armazenar dados privados na memória do dispositivo.
External Storage: Armazenar dados públicos sobre o armazenamento
externo compartilhado.
SQLite DataBases: Armazenar dados estruturados em um banco de dados.
Como foi dito no início do artigo, usaremos a opção “External Storage”,
que significa Armazenamento externo.
External Storage – Armazenamento Externo
agosto 2012
15
Os dispositivos compatíveis com o sistema Android suporta uma memória
externa compartilhada que podemos utilizar para diversas tarefas, como por
exemplo manipular arquivos do tipo texto. Podendo ser um cartão SD ou uma
memória interna não removível. Os arquivos salvos para o armazenamento
externo são de leitura para todos podendo ser modificado pelo usuário.
Comandos úteis:
Environment.getExternalStorageState() : Comando necessário para verificar se a mídia está disponível.
Environment.getExternalStorageDirectory(): comando para abrir um diretório que representa a raiz do armazenamento externo, usando o diretório:
/Android/dados/<nome do pacote>/arquivos
Figura 01: Android Manifest Permissions.
Criando um exemplo prático
O lay-out da aplicação se dividirá em duas partes, a primeira iremos criar
um arquivo do tipo texto e salvá-lo no cartão SD, já a segunda escolheremos
o arquivo para posteriormente carregá-lo em um EditText.
Para isto abra seu Eclipse e clique em “File/New/Android Project” e crie
um projeto em Android, recomendo a criação na versão 2.2 ou 2.3.
Adicionando permissões
Um detalhe importante para esse projeto é que será necessário habilitar
a permissão “WRITE_EXTERNAL_STORAGE” no arquivo manifest, pois graças
a essa permissão que seu aplicativo pode gravar arquivos no SD Card. Dê um
duplo clique no arquivo “AndroidManifest.xml” e na aba “Permissions” clique
no botão “Add” para adicionar o código a seguir. Ver Imagem 01.
<activity android:name=”.
Android_txtActivity”
android:label=”@string/
app_name”>
<intent-filter>
<action
android:name=”android.intent.action.MAIN”
/>
<category android:name=”android.intent.
category.LAUNCHER” />
</intent-filter>
</activity>
</application>
<uses-permission android:name=”android.
permission.WRITE_EXTERNAL_STORAGE”/>
</manifest>
Criando a interface gráfica
android.permission.WRITE_EXTERNAL_STORAGE
Esta permissão indica que podemos salvar dados em um dispositivo
externo, o código deverá ficar parecido com o a seguir.
<?xml version=”1.0” encoding=”utf-8”?>
<manifest xmlns:android=”http://schemas.
android.com/apk/res/android”
package=”pct.Android_txt”
android:versionCode=”1”
android:versionName=”1.0”>
<uses-sdk android:minSdkVersion=”8” />
<application android:icon=”@drawable/icon”
android:label=”@string/app_name”>
16
agosto 2012
Trabalharemos com os componentes padrões do Android, como: TextView,
EditText, Button e Spinner. A imagem 02 nos dá uma noção melhor de como os
componentes deverão estar dispostos em nosso arquivo principal “main.xml”.
Podemos conferir o código XML correspondente logo em seguida.
<?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”
android:weightSum=”1”>
parent”
android:singleLine=”false”
android:gravity=”top”
android:lines=”5”
android:layout_height=”120dp”/>
<Button android:text=”Salvar txt”
android:onClick=”click_Salvar”
android:layout_height=”wrap_
content”
android:layout_width=”115dp”
android:layout_gravity=”center_
horizontal”/>
Figura 02: Disposição dos componentes.
<TextView
android:text=”Diretório:”
android:id=”@+id/txtRoot2”
android:layout_width=”wrap_
content”
android:layout_height=”wrap_
content”/>
<TextView
android:text=”Nome do arquivo
txt:”
android:layout_width=”wrap_
content”
android:layout_height=”wrap_
content”/>
<EditText
android:id=”@+id/edtNomeArq”
android:text=””
android:layout_width=”match_
parent”
android:layout_height=”wrap_
content”/>
<TextView
android:text=”Texto do arquivo a
ser salvo:”
android:layout_width=”wrap_
content”
android:layout_height=”wrap_
content”/>
<EditText
android:id=”@+id/edtSalvar”
android:text=””
android:layout_width=”match_
<TextView android:text=” “
android:id=”@+id/txtPreencher”
android:layout_width=”fill_parent”
android:layout_height=”wrap_
content”/>
<LinearLayout android:layout_
width=”fill_parent”
android:gravity=”center_
vertical”
android:layout_height=”wrap_
content”>
<Spinner android:id=”@+id/
spListarArquivos”
android:layout_
width=”220dp”
android:layout_weight=”10”
android:layout_
height=”50dp”/>
<Button android:layout_
weight=”1.0”
android:text=”Carregar
txt”
android:onClick=”click_
Carregar”
android:layout_
width=”115dp”
android:layout_
height=”wrap_content”/>
</LinearLayout>
<TextView
android:text=”Texto do arquivo a
ser carregado:”
android:layout_width=”wrap_
content”
android:layout_height=”wrap_
content”/>
agosto 2012
17
<EditText
android:id=”@+id/edtLer”
android:text=””
android:layout_width=”match_
parent”
android:singleLine=”false”
android:gravity=”top”
android:lines=”5” android:layout_
height=”120dp”/>
</LinearLayout>
Podemos rodar o exemplo e teremos uma tela parecida com a da Figura 03.
Criaremos também algumas variáveis ao decorrer do desenvolvimento,
confiram a seguir:
private TextView txtRoot;
private TextView txtNomeArq;
private TextView txtSalvar;
private TextView txtLer;
private Spinner SpnListarArquivos;
private ArrayList<String> Arquivos = new
ArrayList<String>();
No evento OnCreate() faremos atribuições às variáveis e invocaremos o
método Listar() seguido de um Try..Catch.
public void onCreate(Bundle
savedInstanceState)
{
super.onCreate(savedInstanceState);
try
{
setContentView(R.layout.main);
Figura 03: Lay-Out da aplicação.
Codificando o Exemplo
Usaremos alguns pacotes adicionais, sendo necessário adicioná-los ao
projeto.
import
import
import
import
import
import
import
import
import
import
import
18
java.io.BufferedReader;
java.io.File;
java.io.FileOutputStream;
java.io.FileReader;
java.util.ArrayList;
android.os.Environment;
android.view.View;
android.widget.ArrayAdapter;
android.widget.Spinner;
android.widget.TextView;
android.widget.Toast;
agosto 2012
txtRoot = (TextView)
findViewById(R.id.txtRoot2);
txtNomeArq = (TextView)
findViewById(R.id.edtNomeArq);
txtSalvar = (TextView)
findViewById(R.id.edtSalvar);
txtLer = (TextView)
findViewById(R.id.edtLer);
SpnListarArquivos = (Spinner)
findViewById(R.id.spListarArquivos);
txtRoot.append(ObterDiretorio());
Listar();
}
catch (Exception e)
{
Mensagem(“Erro : “ +
e.getMessage());
}
}
}
Achei necessário criar uma função Padrão Mensagem (), a qual será
responsável notificar o usuário. Esta classe “Toast” se difere da “AlertDialog.
Builder” pois a mesma apenas informa no rodapé inferior da tela do Android
o ocorrido e logo em seguida desaparece, achei interessante usar este tipo
de recurso para fins de aprendizado, podemos conferir a seguir o método que
recebe como parâmetro uma String.
private void Mensagem(String msg)
{
Toast.makeText(getApplicationContext(),
Ao clicarmos no botão Salvar executaremos o método “Click_Salvar”, usaremos um Try..Catch, onde transformamos o texto digitado em um “Array de
Bytes” e com o método “Write” inserimos os dados seguido de uma notificação
ao usuário. Com o método Listar() atualizaremos o Spinner com o nome dos
arquivos “.txt”. Ver Imagem 04.
msg, Toast.LENGTH_SHORT).show();
}
O próximo método nos retorna o diretório de armazenamento externo.
private String ObterDiretorio()
{
File root = android.os.Environment.
getExternalStorageDirectory();
return root.toString();
}
O método Listar() preencherá o componente Spinner com os arquivos
do tipo “.txt” salvos no diretório externo. Usamos os tipos de variáveis File e
File[], sendo respectivamente responsáveis por obter o diretório e os arquivos
deste diretório. Adicionamos os arquivos em um “Array” para posteriormente
utilizá-los.
public void Listar()
{
File diretorio = new
File(ObterDiretorio());
File[] arquivos = diretorio.
listFiles();
public void click_Salvar(View v)
{
String lstrNomeArq;
File arq;
byte[] dados;
try
{
lstrNomeArq = txtNomeArq.
getText().toString();
arq = new File(Environment.
getExternalStorageDirectory(),
lstrNomeArq);
FileOutputStream fos;
dados = txtSalvar.getText().toString().
getBytes();
fos = new FileOutputStream(arq);
fos.write(dados);
fos.flush();
fos.close();
Mensagem(“Texto Salvo com
sucesso!”);
if(arquivos != null)
{
int length = arquivos.length;
for(int i = 0; i < length; ++i)
{
File f = arquivos[i];
if(f.isFile())
{
Arquivos.add(f.
getName());
}
}
ArrayAdapter<String> arrayAdapter = new Ar
rayAdapter<String>(this,android.R.layout.
simple_dropdown_item_1line, Arquivos);
SpnListarArquivos.
setAdapter(arrayAdapter);
}
}
Criando o método Salvar()
Figura 04: Salvando o Arquivo .txt.
agosto 2012
19
Listar();
}
catch (Exception e)
lstrNomeArq = SpnListarArquivos.
getSelectedItem().toString();
txtLer.setText(“”);
{
Mensagem(“Erro : “ +
e.getMessage());
}
}
Criando o método Carregar()
Já o método carregar, continuaremos a utilizar o Try..Catch, sendo que
de primeiro momento pegamos o item que está selecionado no componente
Spinner, limpamos o campo “txtLer” e logo em seguida efetuamos uma leitura
linha a linha do arquivo carregando para a caixa de texto toda a informação
lida. Ver Imagem 05.
public void click_Carregar(View v)
{
String lstrNomeArq;
File arq;
String lstrlinha;
try
{
arq = new File(Environment.
getExternalStorageDirectory(),
lstrNomeArq);
BufferedReader br = new BufferedReader(new
FileReader(arq));
while ((lstrlinha =
br.readLine()) != null)
{
if (!txtLer.getText().
toString().equals(“”))
{
txtLer.append(“\n”);
}
txtLer.append(lstrlinha);
}
Mensagem(“Texto Carregado com
sucesso!”);
}
catch (Exception e)
{
Mensagem(“Erro : “ +
e.getMessage());
}
}
Conclusão
Este artigo nos demonstrou os conceitos básicos e essenciais para trabalhar com arquivos textos no Sistema Android. Procurei demonstrar alguns
recursos diferentes dos abordados nos meses anteriores a fim de aumentar
nosso leque de aprendizado.
Vou ficando por aqui, um forte abraço e até o mês que vem!
Sobre o autor
Thiago Cavalheiro Montebugnoli
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 Processamento de Dados da Prefeitura Municipal de Itaí-SP. Possui as seguintes
certificações: MCP - Microsoft Certified Professional, MCTS - Microsoft Certified Technology Specialist, MCAD - Microsoft Certified Application Developer
e MCSD - Microsoft Certified Solution Developer.
[email protected]
Figura 05: Carregando o Arquivo .txt.
20
agosto 2012
Delphi
Parte V
Vimos no artigo anterior, o inicio
dos exemplos sobre banco de dados.
Nesse artigo veremos mais dicas
sobre desenvolvimento de aplicações cliente/server com dbExpress
no Delphi, onde a principal será a
parametrização dos cadastros.
Imagine o nosso cadastro de clientes
tenha algo em torno de 500 registros, o
que não é nada de tão absurdo.
Pelo que construímos até agora, teríamos o DBNavigator para navegar entre
os registros, o que não tem nenhuma
facilidade.
Vamos alterar o projeto para que as
consultas sejam parametrizadas e possamos modificar o cadastro. Teremos
assim, performance da aplicação pois
teremos em memória apenas os registros
necessários para a edição dos dados.
Parametrizando as consultas
agosto 2012
21
Figura 1. Configurando o parâmetro
do cadastro de cliente
Para parametrizar as consultas precisamos modificar a consulta SQL adicionando o parâmetro que desejamos. Veja
no código a seguir, como ficará a consulta
para o cliente.
select nCdCliente,
sNmCliente, tDtNascimento,
nVlLimite
from CLIENTE
where nCdCliente =
:nCdCliente
Assim, criamos um parâmetro para
a consulta (basta ter dois pontos antes).
Ao fechar o editor, a propriedade Params
do SQLDataset mapeia os parâmetros
adicionados no SQL (Figura 1).
Configure o parâmetro para o tipo
correto, nesse exemplo, ftInteger. Precisamos “repassar” esse parâmetro para
o ClientDataSet. Para isso, basta clicar
com o botão direito no componente e
escolher a opção Fetch Params. Pronto.
Para conferir, acesse a propriedade Paras do cdsCliente, ela deve ter a mesma
configuração do dsCliente.
Agora, se abrirmos a aplicação você
notará que nenhum registro é mostrado. Obviamente, devido a mudança do
SQL. Como podemos então mostrar os
dados? Precisamos ter uma consulta
auxiliar para buscarmos o registro que
precisamos mudar.
Isso já introduz um conceito importante no nosso projeto, o de performance. Não precisamos retornar todos os
agosto 2012
Figura 2. Usando abas no cadastro de clientes
lário e insira dois TabSheets. Crie uma
aba com o texto: “Dados gerais” e outra
como “Pesquisa”. Na aba Dados gerais
adicione os controles de tela (podemos
remover o DBNavigator). Veja na Figura
2 como ficou o cadastro.
Figura 3. Aba de pesquisa no cadastro
de cliente
registros do cadastro (imagine 5, 10 mil
registros) para modificar um apenas.
Vamos retornar para o cadastro, apenas
o registro que desejamos alterar.
Modificando o cadastro de
cliente
Precisamos mudar o layout do cadastro de clientes. Precisamos adicionar
uma pesquisa para que possamos retornar o registro que o usuário vai alterar.
Vamos criar abas para o cadastro, onde
teremos uma para o cadastro em si e
outra para um grid de pesquisa.
Adicione um PageControl no formu-
Veja que nosso cadastro ficou mais
bonito. Agora, precisamos configurar a
aba de pesquisa. Adicione um Edit, um
Grid e um DataSource. Faça a ligação do
DataSource com o grid. Veja na Figura 3
a aba de pesquisa.
Precisamos configurar uma consulta
para ser usado na pesquisa do cadastro.
Nesse tipo de pesquisa, não precisamos
retornar uma quantidade grande de dados, precisamos apenas o código e um
campo referente a descrição do cadastro
(neste caso, o nome do cliente).
Vamos criar outro Data Module para
conter os componentes para as pesquisas que vamos usar na aplicação. Fica a
seu critério para usar apenas um Data
Module, apenas atente para colocar o
novo Data Module a ser criado na inicialização do projeto.
Pesquisas auxiliares
Crie um novo Data Module e adicione
um SQLDataSet, um DataSetProvider e
um ClientDataSet. Veja os componentes
dispostos na Figura 4.
Figura 4. Data Module para os components
de pesquisa
from CLIENTE
where UPPER(sNmCliente)
like :sNmCliente
Veja que retornamos apenas dois
campos e usamos o like, pois vamos
fazer uma pesquisa parcial pelo nome
do cliente. Configure o parâmetro para
o tipo ftString.
Pesquisa parcial
Aperte Alt + F11 para abrir o editor
Use unit. Escolha DM. Você deve estar
perguntando: “Nos componentes de pesquisa, também preciso ter um trio para
cada pesquisa?”. E a resposta é? Não.
Se vamos utilizar o ClientDataSet para
pesquisar, não precisamos do trio, pois
os outros componentes tem a responsabilidade de incluir dados no banco, como
já comentamos.
Precisamos apenas configurar os
componentes, como fizemos antes (vincular os componentes via propriedades)
e modificar uma propriedade do DataSetProvider para que o ClientDataSet possa
gerenciar a consulta SQL para trazer os
dados para o componente.
Altere para true a propriedade Options > poAllowCommandText do dspPesquisa. Agora, a consulta SQL para
retornar os dados, vamos escrevê-la na
propriedade CommandText do cdsPesquisaCliente. Note que não temos um
editor como o SQLDataSet, mas podemos
digitar o SQL.
Digite o seguinte comando:
select nCdCliente,
sNmCliente
Agora vamos mudar nossa tela de
cadastro. Configure o DataSource para o
cdsPesquisaCliente. No evento OnKeyDown do Edit, digite o código da Listagem 1.
Listagem 1. Executando a consulta
com parâmetros
if (Key = VK_RETURN) then
begin
DMPesquisa.
cdsPesquisaCliente.Close;
DMPesquisa.
cdsPesquisaCliente.
Params[0].AsString :=
UpperCase(‘%’+
edtPesquisa.Text + ‘%’);
DMPesquisa.
cdsPesquisaCliente.Open;
end;
Veja que verificamos se o usuário usou a
tecla ENTER, para executar o código. A seguir,
fechamos o ClientDataSet e preenchemos
o parâmetro configurado. Note que como
usamos o comando Upper no SQL, também
precisamos repassar o valor digitado em
maiúsculo para uma perfeita comparação.
É importante notar, o tipo do parâmetro
(string). Precisamos configurar o tipo correto,
então usamos o AsString. No ClientDataSet do
cadastro, o parâmetro é do tipo inteiro, então,
quando fizermos essa filtragem precisamos
usar a configuração correta (AsInteger).
Por fim, chamamos o Open para mostrar
os dados retornados. Execute a aplicação e
faça pesquisas na aba. Ao entrar na aba e
apertar ENTER, todos os registros são retornados. Poderíamos fazer uma restrição para
que o usuário não possa fazer pesquisa sem
digitar uma quantidade mínima de caracteres.
Isso auxilia, pois caso o cadastro possua
muitos registros, o trafego da rede seria
grande. O código seria:
if (Key = VK_RETURN) then
begin
if Length(edtPesquisa.
Text) < 3 then
ShowMessage(‘Digite
no mínimo 3 caracteres.’)
else
...
Digite algum valor e aperte ENTER e visualize os registros que atendem ao parâmetro
digitado (Figura 5).
Figura 5. Cadastro com pesquisa auxiliar
Agora, precisamos configurar para que
ao usuário dar um duplo clique no grid, ao
escolher um registro, possamos filtrar os
dados para o cadastro e mostrar o mesmo
ao usuário. No evento OnDblClick do grid,
adicione o código da Listagem 2.
Listagem 2. Filtrando o registro escolhido
no grid
if (DMPesquisa.
cdsPesquisaCliente.
RecordCount > 0) then
begin
DM.cdsCliente.Close;
DM.cdsCliente.
Params[0].AsInteger :=
agosto 2012
DMPesquisa.
cdsPesquisaCliente.
FieldByName(‘nCdCliente’).
AsInteger;
DM.cdsCliente.Open;
pgCadastro.ActivePage
:= tabDados;
end;
Primeiro, verificamos se existem registros
no grid para executar a filtragem. Preenchemos o parâmetro do componente de
cadastro, com o valor do código presente no
componente de pesquisa. Por fim, mostramos
a aba de cadastro. Execute e teste a aplicação
(Figura 6).
Figura 6. Pesquisa e filtragem do
cadastro
Modificando o cadastro de empregados
Você pode pensar, as modificações no
cadastro de empregados têm as mesmas
características do cadastro de clientes. Em
parte sim. Precisamos criar a pesquisa, alterar a consulta do cadastro, criar parâmetro e
alterar o layout.
Mas se você recordar, no cadastro de
empregados, temos um relacionamento com
o setor, onde adicionamos um ComboBox
para o usuário escolher o setor. OK, o cadastro de setor é pequeno, não valeria a pena a
modificação, mas nesse caso, vou mostrar a
alteração para fins de conhecimento.
24
agosto 2012
Vamos remover o controle (ComboBox) e
vamos criar uma consulta auxiliar (com uma
nova tela) para o usuário pesquisar o setor
que deseja. Assim, nosso cadastro estará
parametrizado, otimizando a performance
do mesmo.
Precisamos fazer uma modificação na
consulta de empregados, para trazer, o nome
do setor, pois temos que mostrar o nome
(caso o cadastro tenha relacionamento) para
o usuário. A Listagem 3 mostra o novo comando SQL do dsEmpregado no DM.
Listagem 3. Alterando a consulta de empregado para retornar o setor
select
EMPREGADO.
nCdEmpregado,
EMPREGADO.nCdSetor,
EMPREGADO.
nPcComissao,
EMPREGADO.
sNmEmpregado,
EMPREGADO.
tDtAdmissao,
SETOR.sNmSetor
from EMPREGADO
INNER JOIN SETOR ON SETOR.
nCdSetor = EMPREGADO.
nCdSetor
where EMPREGADO.
nCdEmpregado =
:nCdEmpregado
Nota: Qualquer modificação feita no
editor do SQL ou mesmo diretamente
no comando, através da propriedade
CommandText, o parâmetro deve ser
reconfigurado, tanto no SQLDataSet,
quanto no ClientDataSet.
Agora, precisamos configurar corretamente o Field do novo campo (sNmSetor),
para que o dbExpress não tente atualizar o
mesmo quando for salvar o registro. Desmarque todas as opções marcadas para o TField
sNmSetor, assim, o dbExpress não tentará
inserir/atualizar o mesmo.
Na tela de cadastro, adicione um DBText
para mostrar o nome do setor (Figura 7).
Figura 7. Alterando o campo Setor no
cadastro de empregado
Após as alterações, faça testes na aplicação para visualizar o nome do setor na
pesquisa (Figura 8).
Figura 8. Mostrando o nome do setor
no cadastro
Agora, e quando quisermos alterar o
setor? Vamos criar uma tela de pesquisa de
setor. Crie um novo formulário e adicione
os seguintes componentes: RadioGroup,
DBGrid, Edit, Labels. Monte o formulário
conforme a Figura 9.
Crie um componente para pesquisa de
setor, semelhante aos de pesquisa de cliente e empregado. Vincule o componente ao
DataSource da tela, e esse ao DBGrid. No
evento OnKeyDown do Edit, digite o código
da Listagem 4.
Listagem 4. Código para pesquisa de
setores
if Key = VK_RETURN then
begin
Result := true;
except
Result := false;
end;
end;
Qual a lógica da função. Executamos o
comando que transforma uma string em número, dentro de um bloco try...exception, que
caso ocorra erro, o código que será executado
estará dentro do except. Assim, se nenhum
erro ocorrer, o result será verdadeiro, senão,
será falso.
Figura 9. Tela de pesquisa de setor
Agora, no OnDblClick do grid para fecharmos o formulário com o seguinte código:
DMPesquisa.
cdsPesquisaSetor.Close;
DMPesquisa.
cdsPesquisaSetor.
CommandText := ‘’;
if RadioGroup1.ItemIndex
= 0 then
begin
if
IsNumero(edtPesquisa.Text)
then
DMPesquisa.
cdsPesquisaSetor.
CommandText :=
‘select nCdSetor,
sNmSetor from SETOR where
nCdSetor = ‘ +
edtPesquisa.Text
else
ShowMessage(‘Digite
um número para pesquisar
por código’);
end
else
begin
if Length(edtPesquisa.
Text) < 3 then
ShowMessage(‘Digite
no mínimo 3 caracteres.’)
else
DMPesquisa.
cdsPesquisaSetor.
CommandText :=
‘select nCdSetor,
sNmSetor from SETOR where
UPPER(sNmSetor) like ‘ +
UpperCase(QuotedStr(‘%’ +
edtPesquisa.Text + ‘%’));
end;
DMPesquisa.
cdsPesquisaSetor.Open;
end;
if DMPesquisa.
cdsPesquisaSetor.
RecordCount > 0 then
begin
Close;
ModalResult := mrOk;
end;
Note que de acordo com o que for
escolhido no RadioGroup, mudamos o conteúdo do SQL passado para a propriedade
CommandText. Para a pesquisa parcial (pelo
nome do setor), implementamos uma validação como já mostramos anteriormente. O
comando QuotedStr, adiciona aspas simples
(‘’) na consulta SQL, pois estamos trabalhando
com string.
Verificamos se existem registros no componente de pesquisa, e depois o primeiro
código fecha o formulário de pesquisa, já o
segundo, indica o resultado que será verificado no formulário que chamará a tela de
pesquisa.
Para o código, criamos uma function que
retorna se o valor digitado é um número
para que não ocorra erro quando pesquisarmos por código, sendo o que foi digitado é
uma string. Veja na Listagem 5 o código do
IsNumero.
Listagem 6. Código para chamar o formulário de pesquisa
Listagem 5. Função para validar se o valor
é número
function IsNumero(sNumero:
string): boolean;
begin
try
StrToInt(sNumero);
Para entender, adicione um botão no
cadastro de empregados. Adicione o código
da Listagem 6.
Application.CreateForm
(TfrmPesquisarSetor,
frmPesquisarSetor);
try
frmPesquisarSetor.
ShowModal;
if frmPesquisarSetor.
ModalResult = mrOk then
begin
DM.cdsEmpregado.Edit;
agosto 2012
25
ficará o layout dos cadastros.
Na Listagem 7 temos o código dos botões.
Listagem 7. Código dos botões
Novo
DM.cdsEmpregado.Insert;
Figura 10. Alterando o setor com a
pesquisa auxiliar
DM.cdsEmpregadosNmSetor.
AsString :=
DMPesquisa.
cdsPesquisaSetor.
FieldByName(‘sNmSetor’).
AsString;
DM.cdsEmpregadonCdSetor.
AsInteger :=
DMPesquisa.
cdsPesquisaSetor.
FieldByName(‘nCdSetor’).
AsInteger;
end;
finally
frmPesquisarSetor.Free;
end;
Salvar
try
DM.cdsEmpregado.Post;
ShowMessage(‘Registro
salvo com sucesso.’);
except
on E: Exception do
ShowMessage(‘Ocorreu um
erro: ‘ + E.Message);
end;
Excluir
if (MessageDlg(‘Deseja
excluir?’, mtConfirmation,
[mbYes, mbNo], 0) = mrYes)
Após a chamada do formulário (ShowModal) verificamos o retorno do formulário
através da propriedade ModalResult. Se o
usuário não escolher nenhum registro, fechar
o formulário, não precisamos executar o código para alterar o nome do setor.
Caso o mesmo escolha um registro no
grid, vamos chamar o método Edit do ClientDataSet de cadastro e atribuindo os valores
para o nome do setor e o código do setor do
cadastro de empregados. Veja na Figura 10
temos a aplicação em execução.
Finalizando as alterações
Pra finalizar, precisamos implementar os
botões para inserir um novo, salvar ou excluir
os registros da tela. Veja na Figura 11 como
26
agosto 2012
Figura 11. Botões de cadastro
then
DM.cdsEmpregado.Delete;
O botão Novo simplesmente chama o Insert do ClientDataSet. Já no Salvar, colocamos
um bloco try...except para que caso ocorra
algum erro, uma mensagem com a descrição
do erro, seja mostrada ao usuário.
O Excluir pede a confirmação da exclusão
para o usuário e caso afirmativo, exclui o
registro. Para excluir o registro no banco, precisamos chamar o mesmo código que usamos
no evento AfterPost visto no artigo anterior.
No DM, adicione o seguinte código no
evento AfterDelete do cdsEmpregado (faça
o mesmo para o cdsCliente):
cdsEmpregado.
ApplyUpdates(0);
Faça todos os testes na aplicação: novo
registro, salve e exclua. Faça as modificações
no outro cadastro.
Novo cadastro e o que vem pela frente
Agora que já aprendeu como fazer um
cadastro simples parametrizado e como usar
pesquisa auxiliar no cadastro, implemente o
mesmo para a tabela PRODUTO. Adiantando
o que teremos no próximo artigo, vamos criar
um cadastro máster/detail, com o cadastro de
vendas e seus respectivos itens.
Lembrando, para incluir os registros da
tabela ITENS, precisamos ter o código da
venda, presente na tabela VENDA, ou seja,
precisamos incluir uma venda, recuperar
seu código e inserir o mesmo quando salvar
o item.
Como fazer isso? Dados em memória
com o ClientDataSet. Além disso, precisamos
de uma transação nisso, pois não podemos
ter ITENS sem a VENDA e nem a VENDA sem
seus ITENS. Veja que temos muito a aprender
ainda.
Você deve estar perguntando: “Luciano,
você sempre fala que o Delphi é produtivo,
tem facilidades da programação OO, mas pelo
que já vi até agora, tivemos dois cadastros (e
teremos o terceiro), onde precisamos refazer
layout e algumas validações, tipo replicando
Conclusão
código”.
Veremos nos próximos artigos algo
bastante interessante e produtivo para aplicações com Delphi, a facilidade que temos
em criar telas de cadastros: a herança visual.
Apenas para adiantar a ideia: teremos uma
tela de cadastro padrão, com um layout (por
exemplo, as abas e botões) comum para
qualquer cadastro.
Nessa tela padrão, teremos código bastante genérico para ser usado independente
de estarmos no cadastro de cliente, empregado ou qualquer outro. Vale a pena esperar.
Vimos nesse artigo, como utilizar de
maneira correta, a criação de cadastros parametrizados no Delphi para aplicações cliente/
server. No próximo artigo, vamos criar uma
característica muito comum em aplicações, o
cadastro máster/detail.
Um grande abraço a todos e até a próxima!
Sobre o autor
Luciano Pimenta
É 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 Bussiness em Florianópolis-SC.
www.lucianopimenta.net
agosto 2012
27
Dicas DELPHI
DBGrid com o scroll do mouse
Esta dica como o próprio título já propõem, se trata de trazer a funcionalidade do scroll do mouse para o componente DBGrid, facilitando assim a
visualização dos registros, o que se torna um atrativo a mais para a aplicação
aos olhos do usuário final.
Outra boa prática a ser utilizada, é a de criar esta funcionalidade num
formulário base, ou seja, um formulário que servirá de base a outros formulários da aplicação, isto irá garantir que qualquer formulário que descender
do formulário base tenha esta funcionalidade herdada.
Vamos então à codificação, iremos criar um procedimento para manipular
uma mensagem que é enviada da aplicação ao Windows. Vamos partir da
premissa que já tenha no formulário do Delphi um DBGrid conectado a um
DataSource, este que por sua vez está ligado a um ClientDataSet que já esteja
alimentando com os registros de uma tabela.
Então declare na sessão private da unit o procedimento.
private
{ Private declarations }
procedure MsgWmKeyDown(var Msg: TMsg;
var Handled: Boolean);
Após declarar o procedimento MsgWmKeyDown pressione as teclas (Crtl
+ Shift + C) para gerar o corpo do procedimento onde será implementado o
seu código.
Neste procedimento verifica se a mensagem é WM_MOUSEWHEEL e
logo em seguida verifica se o controle ativo é da classe TDBGrid. Depois vem
os comandos para a ação do scroll do mouse.
Faça a chamada deste procedimento no evento onCreate do formulário
da seguinte forma:
procedure TForm1.FormCreate(Sender:
TObject);
begin
Application.OnMessage := MsgWmKeyDown;
end;
Após adicionar o procedimento ao evento OnMessage da aplicação o
exemplo está pronto e basta agora fazer seus testes, execute a aplicação e
clique na DBGrid para ver a funcionalidade do exemplo.
Texto em 3D no Delphi com canvas
Com esta dica você poderá desenhar um texto em 3D no formulário com
o canvas. Declare na sessão Private o seguinte código:
procedure imgPaintCanvas(RefCanvas:
TCanvas; Texto: String;
TamFonte, pHorizontal, pVertical:
Integer);
Depois tecle Ctrl + Shift + C para gerar o corpo da procedure, e digite o
seguinte código dentro do bloco begin e end:
procedure TForm1.MsgWmKeyDown(var Msg:
TMsg; var Handled: Boolean);
var
s: Smallint;
begin
if Msg.message = WM_MOUSEWHEEL then
if (ActiveControl is TDBGrid) then
begin
Msg.message := WM_KEYDOWN;
Msg.lParam := 0;
s:= HiWord(Msg.wParam);
if s > 0 then
Msg.wParam := VK_UP
else
Msg.wParam := VK_DOWN;
end;
end;
28
agosto 2012
procedure TfrmTexto3D.
imgPaintCanvas(RefCanvas: TCanvas; Texto:
String; TamFonte, pHorizontal, pVertical:
Integer);
Begin
RefCanvas.Brush.Style := bsClear;
RefCanvas.Font.Style := [fsBold];
RefCanvas.Font.Name := ‘Courier New’;
RefCanvas.Font.Size := TamFonte;
RefCanvas.Font.Color := clBlack;
RefCanvas.TextOut(pHorizontal,
pVertical, Texto);
RefCanvas.Font.Color := clGray;
RefCanvas.TextOut(pHorizontal - 1,
pVertical - 1, Texto);
RefCanvas.Font.Color := clSilver;
RefCanvas.TextOut(pHorizontal - 2,
pVertical - 2, Texto);
RefCanvas.Font.Color := clBlack;
RefCanvas.TextOut(pHorizontal - 3,
pVertical - 3, Texto);
end;
Como podemos ver os parâmetros são de fácil compreensão, o RefCanvas
se refere a qual propriedade de formulário será preenchida com o desenho,
TamFonte se refere ao tamanho da fonte, pHorizontal e pVertical se referem
sucessivamente ao ponto horizontal e vertical ao qual irá iniciar o desenho.
Para fazer o desenho em 3D, basta agora chamar este procedimento em
algum evento do formulário passando os parâmetros corretamente, neste
exemplo isso foi feito através de um clique de um TButton, veja o como foi
feito a sua chamada na listagem abaixo:
procedure TfrmTexto3D.Button1Click(Sender:
TObject);
begin
Texto3DCanvas(frmTexto3D.Canvas, ‘THE
CLUB O MAIOR CLUBE DE PROGRAMADORES DO
BRASIL’,15, 50, 50);
end;
Ao visualizar com mais atenção o código do procedimento, fica claro que
o mesmo pode ser customizado para atender qualquer cenário, espero que
esta dica ajude de alguma forma até mais.
Converter número inteiro para ordinal por
extenso
Esta dica se resume em uma função que recebe um parâmetro do tipo
inteiro de no máximo três caracteres, para transcrevê-los em números ordinais
por extenso, estes que serão o retorno da função do tipo String. Declare a
função antes da diretiva Private.
function NumOrdinal(Numero: Integer):
String;
private
Tecle Ctrl + Shift + C para gerar o corpo da função. Serão declaradas algumas
variáveis e constantes para poder manipular os dados corretamente, veja na
seguinte listagem a implementação da função.
function TfrmNumerosOrdinais.
NumOrdinal(Numero: Integer): String;
var
Conta : smallint;
StrNumero, Texto : string;
const
Unidades: array[0..9] of string = (‘’,
‘Primeiro ‘, ‘Segundo ‘, ‘Terceiro ‘,
‘Quarto ‘, ‘Quinto ‘, ‘Sexto ‘, ‘Sétimo ‘,
‘Oitavo ‘, ‘Nono ‘);
Dezenas: array[0..9] of string =
(‘’, ‘Décimo ‘, ‘Vigésimo ‘, ‘Trigésimo
‘, ‘Quadragésimo ‘, ‘Quinquagésimo ‘,
‘Sexagésimo ‘, ‘Setuagésimo ‘, ‘Octogésimo
‘, ‘Novagésimo ‘);
Centenas: array[0..9] of string =
(‘’, ‘Centésimo ‘, ‘Ducentésimo ‘,
‘Tricentésimo ‘, ‘Quadringentésimo ‘,
‘Quingentésimo ‘, ‘Sexcentésimo ‘,
‘Septingentésimo ‘, ‘Octingentésimo ‘,
‘Noningentésimo ‘);
begin
StrNumero := trim(IntToStr(Numero));
for Conta:= length(StrNumero) downto 1
do
Begin
if length(StrNumero) - Conta = 0 then
Texto := Unidades[strtoint(copy(StrN
umero, Conta, 1))];
if length(StrNumero) - Conta = 1 then
Texto := Dezenas[strtoint(copy(StrNu
mero, Conta, 1))] + texto;
if length(StrNumero) - Conta = 2 then
Texto := Centenas[strtoint(copy(StrN
umero, Conta, 1))] + texto;
if length(StrNumero) - Conta > 2 then
Texto := ‘Não sabe contar tanto,
ainda. / ‘ + Texto;
end;
result:=texto;
end;
Para exemplificar a utilização desta função será adicionado no formulário um TLabel, um TEdit e um TButton, veja na listagem Abaixo como fica a
chamada da função:
procedure TfrmNumerosOrdinais.Button1Click(Sender: TObject);
begin
if (Edit1.Text = ‘’) then
Abort;
Label1.Caption := NumOrdinal(StrToInt(Edit1.Text));
end;
Esta dica facilita o manuseio de números inteiros convertendo de maneira
bem fácil para uma String de maneira ordinal. Espero ter ajudado com esta
dica, até a próxima.
agosto 2012
29
Horizontal
30
agosto 2012
Vertical
agosto 2012
agosto 2012
Download

agosto 2012