Auto-Completar Caixa de texto para bancos normalizados

Ao modelar banco de dados,  deparamos com o paradigma da “NORMALIZAÇÃO DO BANCO DE DADOS”, na teoria é tudo muito lindo e na prática, gera bancos mais limpos e menores e mais inteligentes porem, exige grande habilidade do programador durante a criação da interface, já que todo este processo é transparente aos olhos do usuário. O primeiro componente que a gente procura quando iniciamos um projeto delphi baseado um numa estrutura de banco de dados normalizado é algo mágico que possa apontar para uma tabela e uma caixa de texto magicamente auto-complete o texto a media em que digitamos na referida caixa de texo, decepção, este “MagicEdit” não existe, fiz uma pesquisa na net e o que consegui foi: “Acho que TTal.Lib tem mas, é pago”, para resolver minha necessidade e dar uma mãozinha aos colegas que querem se aventura no banco de dados no formato NORMAL (que é uma tendência natural para programação profissional) segue uma função (Que deve se transformar num componente em breve) emula o auto-completar baseado uma tabela para bancos normalizado ou que possuam tabelas auxiliares, o exemplo foi criado em Delphi com banco de dados FireBird usando componentes da paleta Interbase:

Função : NORMAL
Variável Global : NOR_SET
Componente Global :  QDBF : TIBQUERY;

A utilização desta função é muito simples.
Exemplo:
MadkEdit1.Text := NORMAL(´CCID´,´NOME´, MadkEdit1);
CCID = Nome da Tabela;
NOME = Nome do Campo a ser buscado;
MaskEdit1 = Nome do Compontnte que estamos editando;

O Funcionamento:
A função usa o evento OnChange e quando algo é digitado na caixa de texto ele faz uma busca através de um script dinâmico e traz o resultado que encontrou, caso nada encontre ele mantêm aquilo que está sendo digitado, onde o grande macete da função é a manipulação da propriedade SelStart que informa a posição do cursor, que é a base para a consulta e retorno do resultado.

Utilização:
Você pode colocar a função junto da sua unit de funções, não esqueça de criar a variável global NOR_SET e de inicia seu valor quando o form for carregado, (Como no exemplo) e deve declarar também o componente QDBF : TIBQUERY qurry que faz a busca na tabela.

Observação.: Esta função apenas preenche a caixa de texto, não esqueça que antes de gravar o registro que tem que verifica se o campo buscado já está gravado na tabele, é ai onde você devera gravar automaticamente ou informar ao usuário que o texto buscado não consta no arquivo (isso é feito com um simples script antes de gravar o registro).
O objetivo deste artigo não é ensinar o que é, ou como criar um banco de dados na forma normal já que existe centenas de hp´s sobre o assunto.

Caso outro colega queira melhorar esta função, gostaria que compartilhasse com a comunidade, qualquer dúvida pode entrar em contato que terei prazer em tirar sobre esta função, afinal, não estamos sozinho, “A Verdade Está Lá Fora”.

Se alguém tiver qualquer dúvida ou problema para usar esta função pode entrar em contato por e-mail que terei o maior prazer em esclarecer e se possível resolver.

Segue os fontes do Programa e banco de dados para Serem Baixados.

Clique aqui para fazer o download

Antonio Ennio de Jesus

11/08/64

Graduando em Sistemas de Informação (FTC/Jequié-BA) e comecei a programa em 1980 com o TK82c. na era do Bit Lascado.

Ipiaú-Bahia

eia_99@ig.com.br
www.eiainfo.hpg.com.br

unit TESTE;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids, DBGrids, DB, IBDatabase, StdCtrls, Buttons, Mask,
  IBCustomDataSet, IBQuery;
type
  TForm1 = class(TForm)
    MaskEdit1: TMaskEdit;
    BitBtn1: TBitBtn;
    IBDatabase1: TIBDatabase;
    IBTransaction1: TIBTransaction;
    procedure MaskEdit1Change(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
   NOR_SET: integer;
   Function NORMAL(ARQUIVO : ShortString ; CAMPO : ShorTString ; ABUSCA : TMASKEDIT ) : ShortString;
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
  QDBF : TIBQUERY;
Implementation

{$R *.dfm}
Function TFORM1.NORMAL(ARQUIVO : ShortString ; CAMPO : ShorTString ; ABUSCA : TMASKEDIT ) : ShortString;
begin
    IF (Trim(abusca.Text)=´´) OR  (NOR_SET=0) then
    Begin  Result:=´´;exit;
    End;
    QDBF:=TIBQuery.Create(FORM1);
    With TIBQuery(QDBF) do
    Begin
       Name :=´DBX´;
       Database :=IBDatabase1;
       ParamCheck :=True;
       Active:=False;
       Close;
       SQL.Clear;
       Params.Clear;
       SQL.add(´Select ´+CAMPO+´ From ´+ARQUIVO+´ Where ´+CAMPO+´ like ´+#39+´ ´+COPY(ABUSCA.TEXT,1,ABUSCA.SelStart)+´%´+#39);
       open;
       RESULT:=COPY(ABUSCA.TEXT,0,ABUSCA.SelStart)+COPY(Fieldbyname(CAMPO).AsString,ABUSCA.SelStart+1,255);
    End;
    IF NOR_SET=0 THEN NOR_SET:=1 ELSE NOR_SET:=0;
    QDBF.Free;
END;

procedure TForm1.MaskEdit1Change(Sender: TObject);
VAR
INICIO: INTEGER;
begin
      IF ((MadkEdit1.SelStart=0) AND (MadkEdit1.GetTextLen>0)) THEN EXIT;
      INICIO:= MadkEdit1.Selstart ;
      NOR_SET:=1;
      MadkEdit1.text:=NORMAL(´CCID´,´NOME´, MadkEdit1);
      MadkEdit1.SelStart :=INICIO;
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
   CLOSE;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
    nor_set:=0;
end;
end.

Banco de Dados

SET SQL DIALECT 3;
 CREATE DATABASE TESTE.FDB PAGE_SIZE 4096
 DEFAULT CHARACTER SET ISO8859_1

CREATE TABLE CCID
(
  CODIGO CHAR(3) CHARACTER SET ISO8859_1 NOT NULL,
  NOME VARCHAR(25) CHARACTER SET ISO8859_1 COLLATE PT_PT,
  CEP CHAR(10) CHARACTER SET ISO8859_1,
  ESTADO CHAR(2) CHARACTER SET ISO8859_1,
CONSTRAINT PK_CIDCOD PRIMARY KEY (CODIGO)
);

INSERT INTO CCID (CODIGO, NOME, CEP, ESTADO) VALUES (´001´, ´SALVADOR´, NULL, NULL);
INSERT INTO CCID (CODIGO, NOME, CEP, ESTADO) VALUES (´002´, ´AIQUARA´, NULL, NULL);
INSERT INTO CCID ("CODIGO,NOME, CEP, ESTADO) VALUES (´003´, ´BARRA DO ROCHA´, NULL, NULL);
INSERT INTO CCID (CODIGO, NOME, CEP, ESTADO) VALUES (´004´, ´UBATô, NULL, NULL);
INSERT INTO CCID (CODIGO, NOME, CEP, ESTADO) VALUES (´005´, ´ALGODÃO´, NULL, NULL);
INSERT INTO CCID (CODIGO, NOME, CEP, ESTADO) VALUES (´006´, ´IPIAÚ´, NULL, NULL);
INSERT INTO CCID (CODIGO, NOME, CEP, ESTADO) VALUES (´007´, ´PALMEIRINHA´, NULL, NULL);
INSERT INTO CCID (CODIGO, NOME, CEP, ESTADO) VALUES (´008´, ´ITAGÍ´, NULL, NULL);
INSERT INTO CCID (CODIGO, NOME, CEP, ESTADO) VALUES (´009´, ´JEQUIÉ´, NULL, NULL);
INSERT INTO CCID (CODIGO, NOME, CEP, ESTADO) VALUES (´010´, ´MARACAS´, NULL, NULL);
INSERT INTO CCID (CODIGO, NOME, CEP, ESTADO) VALUES (´011´, ´JAGUAQUARA´, NULL, NULL);
INSERT INTO CCID (CODIGO, NOME, CEP, ESTADO) VALUES (´012´, ´LAURO DE FREITAS´, NULL, NULL);
INSERT INTO CCID (CODIGO, NOME, CEP, ESTADO) VALUES (´013´, ´BARRA DA ESTIVA´, NULL, NULL);
INSERT INTO CCID (CODIGO, NOME, CEP, ESTADO) VALUES (´014´, ´BRUMADO´, NULL, NULL);