Tela de Consultas Personalizáveis

Um grande dilema do desenvolvedor de sistemas e a criação de telas de pesquisas. Muitas vezes optamos por pesquisar pelos índices primários das tabelas e na maioria das vezes o cliente opta por pesquisar por outro campo. O pior é que temos que lembrar que o cliente sempre tem razão e se ele escolher, até pesquisar por data, temos que deixar esta opção disponível...

Pense nesta idéia: Ter uma tela onde, o cliente escolhe por qual campo a consulta será ordenada, pesquisada e se necessário filtrada.

Também poderemos oferecer a opção de impressão desta consulta.

Olha só: Se, por exemplo, temos uma tabela chamada “Clientes” e esta tabela possuí 9 campos. Com isto podemos oferecer 9 maneiras diferentes de ordenação da consulta. E se pensarmos no filtro ainda são mais 9 maneiras.

Já pensou: “Um único relatório ligado a esta consulta se transforma em 18”. O que você, desenvolvedor, prefere? Fazer um relatório ou 18?

Neste artigo veremos como criar uma tela de pesquisa para um cadastro de clientes. A estrutura física da tabela de clientes está demonstrada na figura abaixo:


Design de Tela

Bem para montarmos esta tela precisamos dos seguintes componentes:

1- RadioGroup com todas opções de ordenação (Campos da Tabela);

2- Um filtro com 2 Edits e um botão;

3- Uma Pesquisa Incremental com um Edit;

4- Uma Grade para visualizar os Dados

5- Um Botão de Abrir;

6- Um Botão para Imprimir;

7- Componentes para acesso a dados (Query e DataSource);

8- Também podemos ter um botão fechar;

9- Uma DBGrid.


Pegue estes componentes e configure suas propriedades como segue:

1 - Da paleta Standart, pegue o componente RadioGroup.

Altera a propriedade Name para rgpOpcoes e o Caption para Ordenação:

Na propriedade Items escreva os nomes de todos os campos da tabela a qual a pesquisa se refere .Se precisar, altere a propriedade Colums para distribuir melhor os itens.

2 - Da paleta Standart, pegue 2 componentes GroupBox. Altere o Caption do primeiro para Filtro e do segundo para Pesquisa Incremental.

3 - Da paleta Standart, pegue 2 componentes Label e coloque dentro do GroupBox Filtro. Altere o Caption do primeiro para Inicial: e do segundo para Final:.

4 – Da paleta Standart, pegue 2 componentes Edit e coloque dentro do GroupBox Filtro. Altere seus names para edtInicial e edtFinal, respectivamente. Deixe a propriedade Text dois 2 vazio.

5 – Da paleta Additional, pegue o componente SpeedButton e altere a propriedade Glyph colocando um figura de sua preferência. Eu sugiro a Retry.bmp

6 – Da paleta Standart, pegue o componente Edit e coloque dentro do GroupBox Pesquisa Incremental. Altere a propriedade Name para edtPesquisa e apague o Text.

7 – Da paleta Additional, pegue 3 componentes BitBtn. Para o primeiro defina a propriedade Name para btnAbrir e o Caption para &Abrir. No segundo o Name para btnImprimir e o Caption para &Imprimir. No terceiro o Name para btnFechar e o Caption para &Fechar. É interessante mudar a propriedade Hint para esclarecer a função de cada botão. Se fizer isto não esqueça de colocar TRUE na propriedade ShowHint.

8 – Da paleta BDE, pegue o componente Query. Altere a propriedade DataBaseName para o Alias que você usa ou o diretório onde estão as tabelas. Mude a propriedade Name para Consulta. Na propriedade SQL coloque Select * from Clientes. Mude a propriedade Active para True. Este componentes pode ser trocado por outra forma de acesso à dados.

9 – Da paleta DataAccess, pegue o componente DataSource. Altere a propriedade Name para dsConsulta e a propriedade DataSet para Consulta.

10 – Da paleta Data Controls, pegue o componente DBGrid e altere a propriedade DataSource para dsConsulta. Você também pode alterar as propriedades das colunas da grade, para tanto clique 2 vezes sobre a mesma.e no Editor de Colunas clique no botão Add All Fields. Feito isto, você pode agora selecionar a coluna e personalizar, mudando cor, alinhamento, etc.

11 – Para finalizar o design da tela, selecione a Query Consulta e altere a propriedade Active para FALSE. Não precisamos deixar true porque vamos ativar a consulta quando o usuário escolher a forma de ordenação.

Veja como deve ficar o layout:

Após o design da tela podemos começar a dar funcionalidade fazendo sua codificação.

1 – OnClick do RadioGroup (rgpOpcoes):

Consulta.Close;

Consulta.sql.Clear;

Consulta.sql.Add('Select Codigo, Nome, CPF, DataNasci, Fone, Endereco, Cep, Cidade, UF');

Consulta.sql.Add('From Clientes');

If RgpOpcoes.ItemIndex = 0 Then

Consulta.sql.Add('Order by Nome');

If RgpOpcoes.ItemIndex = 1 Then

Consulta.sql.Add('Order by Codigo');

If rgpOpcoes.ItemIndex = 2 Then

Consulta.sql.Add('Order by CPF');

If rgpOpcoes.ItemIndex = 3 Then

Consulta.sql.Add('Order by DataNasci');

If rgpOpcoes.ItemIndex = 4 Then

Consulta.sql.Add('Order by Fone');

If rgpOpcoes.ItemIndex = 5 Then

Consulta.sql.Add('Order by Endereco');

If rgpOpcoes.ItemIndex = 6 Then

Consulta.sql.Add('Order by Cep');

If rgpOpcoes.ItemIndex = 7 Then

Consulta.sql.Add('Order by Cidade');

If rgpOpcoes.ItemIndex = 8 Then

Consulta.sql.Add('Order by UF');

Consulta.Open;

edtPesquisa.Text := '';

edtPesquisa.SetFocus;

Este código serve para, quando o usuário clicar na opção de ordenação, fechar a consulta alterar a instrução SQL ordenando (Order by) pelo campo escolhido.


2 – No Onclick do botão do Filtro (btnFiltro) :

If btnFiltro.Tag = 1 Then

Begin

//Desabilitar o Filtro

Consulta.Filtered := False;

edtInicial.Text := '';

edtFinal.Text := '';

btnFiltro.Hint := 'Filtrar';

btnFiltro.Tag := 0;

Exit;

End;

//Se não foi preenchido nada avisa

If ((edtInicial.Text = '') AND (edtFinal.Text = '')) Then

Begin

MessageDlg('Você deve preencher pelo menos o valor inicial !', mtInformation, [mbOk],0);

Exit;

End;

//Se for preenchido somente o inicial, o final recebe o inicial

If ((edtInicial.Text <> '') AND (edtFinal.Text = '')) Then

edtFinal.Text := EdtInicial.Text;

If RgpOpcoes.ItemIndex = 0 Then

Consulta.Filter := 'Nome>='''+edtInicial.Text+''''+

'and Nome<='''+edtFinal.Text+'''';

If RgpOpcoes.ItemIndex = 1 Then

Consulta.Filter := 'Codigo>='''+edtInicial.Text+''''+

'and Codigo<='''+edtFinal.Text+'''';

If RgpOpcoes.ItemIndex = 2 Then

Consulta.Filter := 'CPF>='''+edtInicial.Text+''''+

'and CPF<='''+edtFinal.Text+'''';

If RgpOpcoes.ItemIndex = 3 Then

Consulta.Filter := 'DataNasci>='''+edtInicial.Text+''''+

'and DataNasci<='''+edtFinal.Text+'''';

If RgpOpcoes.ItemIndex = 4 Then

Consulta.Filter := 'Fone>='''+edtInicial.Text+''''+

'and Fone<='''+edtFinal.Text+'''';

If RgpOpcoes.ItemIndex = 5 Then

Consulta.Filter := 'Endereco>='''+edtInicial.Text+''''+

'and Endereco<='''+edtFinal.Text+'''';

If RgpOpcoes.ItemIndex = 6 Then

Consulta.Filter := 'CEP>='''+edtInicial.Text+''''+

'and CEP<='''+edtFinal.Text+'''';

If RgpOpcoes.ItemIndex = 7 Then

Consulta.Filter := 'Cidade>='''+edtInicial.Text+''''+

'and Cidade<='''+edtFinal.Text+'''';

If RgpOpcoes.ItemIndex = 8 Then

Consulta.Filter := 'UF>='''+edtInicial.Text+''''+

' and UF<='''+edtFinal.Text+'''';

Consulta.Filtered := True;

btnFiltro.Tag := 1;

btnFiltro.Hint := 'Desfiltrar';


Esta parte dá a funcionalidade para o Filtro. Quando o usuário digitar um valor inicial e um valor final ele poderá clicar no botão de filtro que filtrará pelo campo que estiver selecionado na ordenação. Claro que deve-se tomar cuidado com os campos inteiros e data.


3 – No OnChange do Edit (edtPesquisa) :

If rgpOpcoes.ItemIndex = 0 Then

Consulta.Locate('Nome', edtPesquisa.Text, [loCaseInsensitive, loPartialKey]);

//Quando for Código temos que testar para o valor não ser nullo e ser um número

If rgpOpcoes.ItemIndex = 1 Then

If edtPesquisa.Text <> '' Then

Try

Consulta.Locate('Codigo', edtPesquisa.Text, [loCaseInsensitive, loPartialKey]);

Except on EConvertError do

MessageDlg(edtPesquisa.Text+' não é um número válido', mtError, [mbOk],0);

End;

If rgpOpcoes.ItemIndex = 2 Then

Consulta.Locate('CPF', edtPesquisa.Text, [loCaseInsensitive, loPartialKey]);

//Quando for Data temos que testar para o valor não ser nullo e ser uma data válida

If rgpOpcoes.ItemIndex = 3 Then

If Length(edtPesquisa.Text) = 10 Then

Try

Consulta.Locate('DataNasci', StrToDate(edtPesquisa.Text), [loCaseInsensitive, loPartialKey]);

Except On EConvertError Do

MessageDlg(edtPesquisa.Text+' não é uma data válida', mtError, [mbOk],0);

End;

If rgpOpcoes.ItemIndex = 4 Then

Consulta.Locate('Fone', edtPesquisa.Text, [loCaseInsensitive, loPartialKey]);

If rgpOpcoes.ItemIndex = 5 Then

Consulta.Locate('Endereco', edtPesquisa.Text, [loCaseInsensitive, loPartialKey]);

If rgpOpcoes.ItemIndex = 6 Then

Consulta.Locate('CEP', edtPesquisa.Text, [loCaseInsensitive, loPartialKey]);

If rgpOpcoes.ItemIndex = 7 Then

Consulta.Locate('Cidade', StrToDate(edtPesquisa.Text), [loCaseInsensitive, loPartialKey]);

If rgpOpcoes.ItemIndex = 8 Then

Consulta.Locate('UF', StrToDate(edtPesquisa.Text), [loCaseInsensitive, loPartialKey]);

Este código serve para fazer uma pesquisa incremental pelo campo que estiver selecionado na ordenação. È necessário controlar a digitação de números e datas, conforme os comentários.


4 – No Onclick do Botão Abrir : (Abrir Formulário);

frmClientes.tabClientes.Locate('Codigo', Consulta.FieldByName('Codigo').Value, []);

frmClientes.ShowModal;

Com este código você seleciona um registro e chama o formulário para edição do mesmo.


5 – OnClick do Botão Imprimir (btnImprimir) :

Application.CreateForm(TRelClientes, RelClientes);

RelClientes.QuickRep1.Preview;

RelClientes.Free;

Este código cria e chama um relatório que levará em conta a ordenação e filtro da tela de pesquisa, ou seja estará ligado na Consulta. Neste caso o relatório é criado em tempo de execução, por isto não esqueça de tirá-lo da opção de Auto-Create Form do projeto.


6 – OnClick do Botão Fechar (btnFechar) :

Consulta.Close;

Close;


7 – OnShow do Formulário:

//Para selecionar a primeira opção de ordenação e executar o clique

rgpOpcoes.ItemIndex := 0;

rgpOpcoesClick(Sender);


Todo este artigo foi escrito levando em conta que o desenvolvedor já conhece os procedimentos para acesso à dados. No exemplo foi utilizado o Paradox, mas nada impede que ele seja utilizado por qualquer maneira de acesso a dados.

Layout do relatório: