Pesquisa através parte de nome em um texto
Olá pessoal, é possível criar uma linha de código onde eu consigo digitar em um campo de pesquisa parte de uma palavra que esteja no meio de um trecho de texto e essa busca ser realizada? Exemplo disso seria mais ou menos o mesmo comportamento da barra de pesquisa do Windows, onde vc digita parte de uma palavra e ele localiza essa palavra com pedaço desse trecho que está no meio de um texto. Isso em Delphi usando ClienteDataSet.
Valdenir Furlanetto
Curtidas 0
Melhor post
Emerson Nascimento
25/04/2019
você pode usar o método locate() pra isso, mas ele não procura em qualquer parte do texto. o conteúdo procurado precisa ser prefixo do conteúdo pesquisado.
por exemplo:
- se o conteúdo do campo for 'RAZAO SOCIAL', e você digitar R na pesquisa, o registro SERÁ encontrado.
- se o conteúdo do campo for 'RAZAO SOCIAL', e você digitar S na pesquisa, o registro NÃO será encontrado.
a sintaxe para o locate() é:
Locate(Campo, ValorProcurado, OpcoesDeBusca);
segue um exemplo:
ClientDatasetCliente.Locate('Nome', 'R', [loPartialKey, loCaseInsensitive]);
você também pode procurar em mais de um campo simultaneamente.
para isso 'Campo' deverá ser uma lista de campos separados por ; (ponto e vírgula) e 'ValorProcurado' precisa ser um array. assim:
ClientDatasetCliente.Locate('Nome;UF', VarArrayOf(['R', 'SP']), [loPartialKey, loCaseInsensitive]);
por exemplo:
- se o conteúdo do campo for 'RAZAO SOCIAL', e você digitar R na pesquisa, o registro SERÁ encontrado.
- se o conteúdo do campo for 'RAZAO SOCIAL', e você digitar S na pesquisa, o registro NÃO será encontrado.
a sintaxe para o locate() é:
Locate(Campo, ValorProcurado, OpcoesDeBusca);
segue um exemplo:
ClientDatasetCliente.Locate('Nome', 'R', [loPartialKey, loCaseInsensitive]);
você também pode procurar em mais de um campo simultaneamente.
para isso 'Campo' deverá ser uma lista de campos separados por ; (ponto e vírgula) e 'ValorProcurado' precisa ser um array. assim:
ClientDatasetCliente.Locate('Nome;UF', VarArrayOf(['R', 'SP']), [loPartialKey, loCaseInsensitive]);
GOSTEI 2
Mais Respostas
Valdenir Furlanetto
24/04/2019
você pode usar o método locate() pra isso, mas ele não procura em qualquer parte do texto. o conteúdo procurado precisa ser prefixo do conteúdo pesquisado.
por exemplo:
- se o conteúdo do campo for 'RAZAO SOCIAL', e você digitar R na pesquisa, o registro SERÁ encontrado.
- se o conteúdo do campo for 'RAZAO SOCIAL', e você digitar S na pesquisa, o registro NÃO será encontrado.
a sintaxe para o locate() é:
Locate(Campo, ValorProcurado, OpcoesDeBusca);
segue um exemplo:
ClientDatasetCliente.Locate('Nome', 'R', [loPartialKey, loCaseInsensitive]);
você também pode procurar em mais de um campo simultaneamente.
para isso 'Campo' deverá ser uma lista de campos separados por ; (ponto e vírgula) e 'ValorProcurado' precisa ser um array. assim:
ClientDatasetCliente.Locate('Nome;UF', VarArrayOf(['R', 'SP']), [loPartialKey, loCaseInsensitive]);
por exemplo:
- se o conteúdo do campo for 'RAZAO SOCIAL', e você digitar R na pesquisa, o registro SERÁ encontrado.
- se o conteúdo do campo for 'RAZAO SOCIAL', e você digitar S na pesquisa, o registro NÃO será encontrado.
a sintaxe para o locate() é:
Locate(Campo, ValorProcurado, OpcoesDeBusca);
segue um exemplo:
ClientDatasetCliente.Locate('Nome', 'R', [loPartialKey, loCaseInsensitive]);
você também pode procurar em mais de um campo simultaneamente.
para isso 'Campo' deverá ser uma lista de campos separados por ; (ponto e vírgula) e 'ValorProcurado' precisa ser um array. assim:
ClientDatasetCliente.Locate('Nome;UF', VarArrayOf(['R', 'SP']), [loPartialKey, loCaseInsensitive]);
Dessa forma eu teria que deixar na própria linha de comando o que eu iria precisar fazer a busca. O que eu preciso é algo similiar ao que o buscador do wuindows explore faz, ali na barra de pesquisa. Ele pesquisar por parte de trecho de um texto, por exemplo, tenho um nome de um serviço em um campo " Bloco de Orçamento / Pedido" ao digitar "pedido" terá que aparecer registro que contenha a palavra pedido, inclusive essa que acabei de citar, "Bloco de Orçamento / Pedido"
GOSTEI 0
Emerson Nascimento
24/04/2019
crie uma procedure pra fazer o que você precisa.
algo assim:
você pode usar no OnChange de um Edit, por exemplo:
Você pode ainda implementar a procedure como um método numa classe derivada de TClientDataset:
E usar assim:
algo assim:
procedure BuscaRegistro(cds: TClientDataset; campo: string; conteudo: string); var numRegistro: integer; bolEncontrou: boolean; strMensagem: string; begin // verifica se o dataset está aberto e se o campo indicado existe if not cds.Active or (cds.FindField(campo) = nil) or cds.IsEmpty then begin if not cds.Active then strMensagem := 'A busca só pode ser realizada num dataset aberto' else if cds.IsEmpty then strMensagem := 'A pesquisa não pode ser realizada num dataset vazio' else strMensagem := 'O campo '''+campo+''' não existe no dataset'; ShowMessage(strMensagem); exit; end; // guarda o registro posicionado antes de iniciar a pesquisa numRegistro := cds.RecNo; // inicializa a variável que indica se o texto foi encontrado bolEncontrou := False; // desabilita o refresh nos controles ligados ao dataset cds.DisableControls; // posiciona no primeiro registro cds.First; //varre o dataset à procura do conteudo desejado while not cds.Eof do begin // procura o valor digitado em qualquer parte do campo bolEncontrou := (Pos(AnsiUpperCase(conteudo), AnsiUpperCase(cds.FieldByName(campo).AsString)) > 0); // se encontrar o conteúdo, sai do loop if bolEncontrou then break; cds.Next; end; // se não encontrou um registro, reposiciona o ponteiro no registro inicial if not bolEncontrou then cds.RecNo := numRegistro; // habilita o refresh nos controles ligados ao dataset cds.EnableControls; end;
você pode usar no OnChange de um Edit, por exemplo:
procedure TForm1.Edit1Change(Sender: TObject); begin BuscaRegistro(ClientDataSet1, 'Nome', Edit1.Text); end;
Você pode ainda implementar a procedure como um método numa classe derivada de TClientDataset:
type TXClientDataset = class(TClientDataset) public procedure BuscaRegistro(campo: string; conteudo: string); end; procedure TXClientDataset.BuscaRegistro(campo, conteudo: string); var numRegistro: integer; bolEncontrou: boolean; strMensagem: string; begin // verifica se o dataset está aberto e se o campo indicado existe if not Self.Active or (Self.FindField(campo) = nil) or Self.IsEmpty then begin if not Self.Active then strMensagem := 'A busca só pode ser realizada num dataset aberto' else if Self.IsEmpty then strMensagem := 'A pesquisa não pode ser realizada num dataset vazio' else strMensagem := 'O campo '''+campo+''' não existe no dataset'; ShowMessage(strMensagem); exit; end; // guarda o registro posicionado antes de iniciar a pesquisa numRegistro := Self.RecNo; // inicializa a variável que indica se o texto foi encontrado bolEncontrou := False; // desabilita o refresh nos controles ligados ao dataset Self.DisableControls; // posiciona no primeiro registro Self.First; //varre o dataset à procura do conteudo desejado while not Self.Eof do begin // procura o valor digitado em qualquer parte do campo bolEncontrou := (Pos(AnsiUpperCase(conteudo), AnsiUpperCase(Self.FieldByName(campo).AsString)) > 0); // se encontrar o conteúdo, sai do loop if bolEncontrou then break; Self.Next; end; // se não encontrou um registro, reposiciona o ponteiro no registro inicial if not bolEncontrou then Self.RecNo := numRegistro; // habilita o refresh nos controles ligados ao dataset Self.EnableControls; end;
E usar assim:
procedure TForm1.Edit1Change(Sender: TObject); begin TXClientDataset(ClientDataSet1).BuscaRegistro('Nome', Edit1.Text); end;
GOSTEI 1
Valdenir Furlanetto
24/04/2019
Pelo que analisei, é possível que atenda o que preciso, vou fazer o teste hj a noite e dou retorno logo em seguida.
GOSTEI 0
Valdenir Furlanetto
24/04/2019
procedure BuscaRegistro(cds: TClientDataset; campo: string; conteudo: string); <----- Essa Procedure, é um componente que eu adiciono? Ela é adicionada na própria Unit do form que será feita a pesquisa? Caso seja uma procedure comum sem adição de componente ali onde está TClienteDataSet seria o Nome do meu ClienteDataSet neh, da forma que está o compilador não reconhece esse tipo.
Ali tbm vc postou duas forma, mas a de baixo seria apenas um complemento da parte de cima. Se puder me passar um pouco mais detalhado, fico muito agradecido.
GOSTEI 0
Emerson Nascimento
24/04/2019
Vamos lá:
A procedure:
Deve ser colocada no seu código. Se você estiver usando um DataModule, implemente a procedure nele. Não é um componente nem nada. É uma procedure simples. Para que o compilador identifique a classe TClientDataset (está assim porque você disse que usa ClientDataset), será necessário adicionar a unit Datasnap.DBClient na cláusula uses.
E, para usar, basta fazer algo assim:
A procedure:
procedure BuscaRegistro(cds: TClientDataset; campo: string; conteudo: string); var numRegistro: integer; bolEncontrou: boolean; strMensagem: string; begin // verifica se o dataset está aberto e se o campo indicado existe if not cds.Active or (cds.FindField(campo) = nil) or cds.IsEmpty then begin if not cds.Active then strMensagem := 'A busca só pode ser realizada num dataset aberto' else if cds.IsEmpty then strMensagem := 'A pesquisa não pode ser realizada num dataset vazio' else strMensagem := 'O campo '''+campo+''' não existe no dataset'; ShowMessage(strMensagem); exit; end; // guarda o registro posicionado antes de iniciar a pesquisa numRegistro := cds.RecNo; // inicializa a variável que indica se o texto foi encontrado bolEncontrou := False; // desabilita o refresh nos controles ligados ao dataset cds.DisableControls; // posiciona no primeiro registro cds.First; //varre o dataset à procura do conteudo desejado while not cds.Eof do begin // procura o valor digitado em qualquer parte do campo bolEncontrou := (Pos(AnsiUpperCase(conteudo), AnsiUpperCase(cds.FieldByName(campo).AsString)) > 0); // se encontrar o conteúdo, sai do loop if bolEncontrou then break; cds.Next; end; // se não encontrou um registro, reposiciona o ponteiro no registro inicial if not bolEncontrou then cds.RecNo := numRegistro; // habilita o refresh nos controles ligados ao dataset cds.EnableControls; end;
Deve ser colocada no seu código. Se você estiver usando um DataModule, implemente a procedure nele. Não é um componente nem nada. É uma procedure simples. Para que o compilador identifique a classe TClientDataset (está assim porque você disse que usa ClientDataset), será necessário adicionar a unit Datasnap.DBClient na cláusula uses.
E, para usar, basta fazer algo assim:
procedure TForm1.Edit1Change(Sender: TObject); begin BuscaRegistro(cdsClientes, 'Nome', Edit1.Text); // aqui você manda teu ClientDataset, o campo que será pesquisado, e o valor a ser procurado end;
GOSTEI 0
Valdenir Furlanetto
24/04/2019
Parece que ta dando resultado, apesar que ele da erro ali no ShowMessage, ai tenho que fazer usn ajuste pra corrigir, não sei pq ele da esse erro, (Undeclared) e o que não entendi bem foi aqui onde tenho que adicionar a unit Datasnap.DBClient na cláusula uses. Esse seria na propria Unit do Data Moduel mesmo neh? mas seria dessa forma mesmo com aquele ponto no meio? pq da erro, ele não reconhece esse comando.
GOSTEI 0
Emerson Nascimento
24/04/2019
Declare na uses do DataModule.
O uso de Datasnap.DBClient ou DBClient vai depender da versão do Delphi.
O uso de Datasnap.DBClient ou DBClient vai depender da versão do Delphi.
GOSTEI 0
Emerson Nascimento
24/04/2019
E, para que o ShowMessage funcione, adicione a unit Dialogs no uses.
GOSTEI 0
Valdenir Furlanetto
24/04/2019
Declare na uses do DataModule.
O uso de Datasnap.DBClient ou DBClient vai depender da versão do Delphi.
O uso de Datasnap.DBClient ou DBClient vai depender da versão do Delphi.
Uso o Delphi 10 e nele jah está declarado esse DBClient na uses do DM. eu adicionei um edit que no caso ficou como edit3 esse código:
procedure TForm1.Edit1Change(Sender: TObject);
begin
BuscaRegistro(ClientDataSet1, 'Nome', Edit1.Text);
end;
Mas ele da como Undeclared Indetifier: BuscaRegistro e no ClienteDataSet1
GOSTEI 0
Emerson Nascimento
24/04/2019
tudo vai depender de como você declarou a procedure no Datamodule:
- como um método (dentro da definição do datamodule)
desta forma, você deve executar assim (indicando o datamodule) :
- como procedure (fora da definição do datamodule)
desta forma, você deve executar assim (chama diretamente a procedure):
Para uma resposta mais precisa, publique o código fonte do teu datamodule.
- como um método (dentro da definição do datamodule)
type TDataModule1 = class(TDataModule) procedure DataModuleCreate(Sender: TObject); private { Private declarations } public { Public declarations } procedure BuscaRegistro(cds: TClientDataset; campo: string; conteudo: string); // declaração da procedure como método do datamodule end;
desta forma, você deve executar assim (indicando o datamodule) :
procedure TForm1.Edit1Change(Sender: TObject); begin DataModule1.BuscaRegistro(TeuClientDataset, CampoASerUtilizado, ConteudoProdurado); // aqui você manda teu ClientDataset, o campo que será pesquisado, e o valor a ser procurado end;
- como procedure (fora da definição do datamodule)
type TDataModule1 = class(TDataModule) private { Private declarations } public { Public declarations } end; var DataModule1: TDataModule1; procedure BuscaRegistro(cds: TClientDataset; campo: string; conteudo: string); // declaração da procedure fora da definição do DataModule implementation
desta forma, você deve executar assim (chama diretamente a procedure):
procedure TForm1.Edit1Change(Sender: TObject); begin BuscaRegistro(TeuClientDataset, CampoASerUtilizado, ConteudoProdurado); // aqui você manda teu ClientDataset, o campo que será pesquisado, e o valor a ser procurado end;
Para uma resposta mais precisa, publique o código fonte do teu datamodule.
GOSTEI 1
Valdenir Furlanetto
24/04/2019
Me passa o seu e-mail, lah te mando as imagem de como tah o meu Data Módule e o código fonte do Data Módule e do Form que to querendo colocar a pesquisa, te explico certinho.
lá no Dta Module ta esse:
se não eu posto aqui mesmo os código fonte do DM e do Form.
lá no Dta Module ta esse:
type TDataModule1 = class(TDataModule) private { Private declarations } public { Public declarations } end; var DM: TDM; implementation
se não eu posto aqui mesmo os código fonte do DM e do Form.
GOSTEI 0
Emerson Nascimento
24/04/2019
Pode mandar para emerson.en@gmail.com
GOSTEI 1
Valdenir Furlanetto
24/04/2019
Tópico Resolvido. Obrigado a todos que participaram dando suas opiniões, conseguir resolver minha dúvida.
GOSTEI 0