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
implementationdesta 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