Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   Búsqueda "incremental" en una base de datos (https://www.clubdelphi.com/foros/showthread.php?t=50049)

loquillo3 07-11-2007 02:48:23

Búsqueda "incremental" en una base de datos
 
Hola,
De antemano le anticipo que si este hilo no va aqui lo muevan al debido lugar donde debe de ir.

Lo que intento hacer es realizar una busqueda que cuando vaya poniendo las letras me vaya apareciendo los resultados.

Ejemplo: Si busco un registro por nombre. Busco el nombre Manuel peo que me aparezcan los demas que empieza con m y a medida que siga poniendo las demas letras se vaya reduciendo la lista hasta quedar el que busco.


Salu2.

dec 07-11-2007 02:51:30

Hola,

Cita:

De antemano le anticipo que si este hilo no va aqui lo muevan al debido lugar donde debe de ir.
Hombre, digo yo, que, antes de publicar el hilo debes mirar en qué subforo cae mejor, apróximadamente. Yo creo que este hilo no va en "Conexión con bases de datos". Tal vez vaya en MySQL, Orable, o la base de datos que uses, pero, como tampoco lo dices... a ver quién ata el cascabel al gato.

De momento quédese el hilo donde está, hasta más ver. Lo que sí he hecho ha sido editar el título del hilo, porque "Búsqueda" sólo quedaba un poco abstracto, por decirlo así. Piensa que en los títulos de los hilos se basan luego las búsquedas que se pueden llevar a cabo en los foros, de ahí la importancia de que tengan un título descriptivo.

Neftali [Germán.Estévez] 07-11-2007 11:36:45

Puedes usar un simple Locate para posicionarte en el registro que necesites.
El problema de las búsquedas incremetales es la velocidad y los recursos que consumen.
Si es una tabla pequeña, puedes utilizar un ClientDataSet para cargarla en memoria y a partir de ahí realizar la búsqueda.
El problema es si no puedes cargar toda la tabla en memoria (esto no siempre es posible) o es muy grande, porque posiblemente tendrás problemas de velocidad.

Coloca un Edit dobde escribes el texto y una tabla apuntando a la tabla employee de DBDemos ordenada por FirstName; Algo así:

Código SQL [-]
  Select * from employee order by FirstName, LastName

Con este código en el OnChange debería valer.

Código Delphi [-]
  // Busqueda incremental
  ClientDataSet1.Locate('FirstName', Edit1.Text, [loCaseInsensitive, loPartialKey]);

Acabo de subir un ejemplo completo a la sección de ejemplos de mi web. Puedes descargarlo y ver el código fuente.

loquillo3 08-11-2007 03:51:37

Hola,
Neftali probe tu ejemplo y es lo que quiero hacer, intente hacerlo por mi mismo pero no pude.
POr cierto mi base de datos esta hecha en access no se si me puedes dar una manito en eso.

Saludos.

tefots 08-11-2007 11:06:27

para busquedas incrementales yo uso like

conforme el usuario va escribiendo en un textbox
en el onkeypres del textbox
hago lo siguiente.

if textbox1.text<>'' then begin
dbbrid1.beginupdate
query1.close
query1.sql.add('select from tabla1 where tabla1.campo like '%dato%')
query1.open
dbgrid.endupdate
end;

con esto , el dbgrid se va posicionando localizando el registro correspondiente conforme vamos escribiendo o borrando.
en acces el like creo que no hay que ponerle % , el codigo es solo como funciona , hay que adaptarlo un poco.

nota : para optimizar ,tambien se puede poner un temporizador (y meter el codigo en el temporizador) , y en el onkeypress dehabilitar y habilitar el temporizador , de unos 200/300ms. asi cuando escriba , no se posiciona cada vez que apretemos una tecla sino que lo hace cuando pase x tiempo despues de apretar la ultima tecla.

saludos.

Neftali [Germán.Estévez] 08-11-2007 11:48:33

Cita:

Empezado por loquillo3 (Mensaje 244364)
...intente hacerlo por mi mismo pero no pude.

¿Exactamente qué pasó?
¿Error?
En principio la Base de Datos no tiene nada que ver, si te fijas en el ejemplo, la búsqueda se hace sobre los datos que ya hay cargados en el DataSet (vía TClientDataSet), por lo tanto es independiente de cómo se carguen los datos.

De todas formas he modificado el ejemplo para permitir cargar los datos desde un XML o desde un MDB.

Lepe 08-11-2007 13:41:00

Cita:

Empezado por tefots (Mensaje 244391)
izar ,tambien se puede poner un temporizador (y meter el codigo en el temporizador) , y en el onkeypress dehabilitar y habilitar el temporizador , de unos 200/300ms. asi cuando escriba , no se posiciona cada vez que apretemos una tecla sino que lo hace cuando pase x tiempo despues de apretar la ultima tecla.

saludos.

Yo prefiero al presionar intro en el edit de búsqueda:
Código Delphi [-]

procedure TForm1.Edit1keyDown(...);
begin
   if key = vk_return then
   begin 
      // abrir y cerrar la consulta
   end;

Saludos

Neftali [Germán.Estévez] 08-11-2007 16:34:55

Cita:

Empezado por Lepe (Mensaje 244414)
Yo prefiero al presionar intro en el edit de búsqueda...

Eso siempre!!! En eso estoy con Lepe.

Aunque te he dado la solución, tengo que decir que si vas a acabar buscando por Manolo, yo también encuentro una tontería buscar por: m, ma, man, mano, manol y finalmente manolo.
Lo que pasa que queda muy bonito y a los clientes les gusta mucho;:p
Básicamente a ellos les da igual que para hacerlo así debas generar más tráfico de red de la cuenta o traerte muchos más registros de los necesarios,... Eso sí luego que funcione, que vaya muy rápido y que consuma poco...:D:D:D

loquillo3 08-11-2007 16:41:29

Estaba viendo este codigo que genero marcsc:

Código Delphi [-]
 
interface

  TBuscador = class(TObject)
  private
    FIndiceCampo: Integer;
    FDataSet: TDataSet;
  public
    constructor Create(DS: TDataSet = nil); 
    property DataSet: TDataSet read FDataSet write FDataSet; //Sobre el que se hace la búsqueda
    function Buscar(Texto: String; BuscarBOF: Boolean = True): Boolean;
  end;

implementation

//Como el valor por omisión del parámetro DS es nil, puedes llamar al constructor
//sin parámetros y asignarle posteriormente el DataSet
constructor TBuscador.Create(DS: TDataSet = nil);
begin
  inherited Create;
  FDataSet:= DS;
  FIndiceCampo:= 0;
end;

//El parámetro BuscarEOF, por defecto True, busca el texto desde el inicio del
//DataSet. En caso que se especifique el valor False, buscará incrementalmente
function TBuscador.Buscar(Texto: String; BuscarBOF: Boolean = True): Boolean;
begin
  Result:= False;
  with FDataSet do
  begin
    if BuscarBOF then
    begin
      First;
      FIndiceCampo:= 0;
    end;

    while (not EOF) and (not Result) do
    begin
      while (FIndiceCampo < Fields.Count) and (not Result) do
      begin
        //Esto seria una busqueda absoluta, si quieres opciones de búsqueda
        //parcial, con opciones de mayúsculas etc te lo dejo como mejora ;)
        Result:= Fields[FIndiceCampo].Text = Texto;
        Inc(FIndiceCampo);
      end;
      FIndiceCampo:= 0;
      Next;
    end;
  end;
end;

Neftali si tu pudieras poner un pequeño ejemplo hecho en access podria guiarme de ahi, ya que vi en el tuyo que usabas un archivo xml.

Saludos

Neftali [Germán.Estévez] 08-11-2007 18:07:02

Cita:

Empezado por loquillo3 (Mensaje 244503)
Neftali si tu pudieras poner un pequeño ejemplo hecho en access podria guiarme de ahi, ya que vi en el tuyo que usabas un archivo xml.

Ya te lo había comentado antes.

Cita:

Empezado por Neftali (Mensaje 244397)
De todas formas he modificado el ejemplo para permitir cargar los datos desde un XML o desde un MDB.

Es el mismo sitio donde estaba el otro; Link.


La franja horaria es GMT +2. Ahora son las 10:34:47.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi