Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Mejorar búsqueda (https://www.clubdelphi.com/foros/showthread.php?t=66051)

dtomeysoto 29-01-2010 19:45:30

Mejorar búsqueda
 
Hola amigos, en una aplicación para el área de Ventas que estoy desarrollando tengo una ventana para crear una factura.

En esta ventana tengo un edit para que el usuario introduzca el código de la empresa, si no se lo sabe puede presionar F2 y le muestro en otra ventana todas las empresas que tengo en el nomenclador usando un DBGrid. Encima de este DBGrid he puesto otro edit para que el usuario teclee parte del nombre de la empresa para así encontrarla más rápido.

Para lograr lo anterior he usado el evento OnChange del edit y he puesto el siguiente código:

Código Delphi [-]
...
QDATOS.Locate('NOMBRE', eBuscarTexto.Text, [loPartialKey]);
...

Hasta aquí todo funciona bien siempre y cuando el usuario vaya poniendo el nombre de la empresa como está escrito en la BD. Por ejemplo si tengo las siguientes empresas en el nomenclador:

EMP. COMERCIALIZADORA ESCAMBRAY
EMP. MAYORIXTA DE PRODUCTOS VERDES
EMPRESA AUTOMOTRIZ S.A
EMPRESA INMOBILIARIA AZUL

y quiero buscar rápidamente la EMPRESA AUTOMOTRIZ S.A hay que escribir necesariamente EMPRESA A y quisiera que al escribir AUT se me posicione en el registro en cuestión.

Hay alguna forma de lograr lo anterior?, estoy usando tablas Paradox.
Gracias.

rgstuamigo 29-01-2010 21:21:38

Cita:

Empezado por dtomeysoto (Mensaje 352293)
...
y quiero buscar rápidamente la EMPRESA AUTOMOTRIZ S.A hay que escribir necesariamente EMPRESA A y quisiera que al escribir AUT se me posicione en el registro en cuestión.

Hay alguna forma de lograr lo anterior?, estoy usando tablas Paradox.
Gracias.

Lo que pasa es que la funcion Locate solo te busca coincidencias desde el principio y no en el medio,o al final;;) Lo que veo mejor que hagas es Filtrar tu DataSet(QDATOS) por medio de Like para que tambien te busque coincidencias entre medios o al final; tu codigo seria mas o menos asi:
Código Delphi [-]
procedure TForm1.eBuscarTextoChange(Sender: TObject);
begin
  QDATOS.Filtered:=False;//Deshabilito el filtro
  QDATOS.Filter:='NOMBRE LIKE ''*'+eBuscarTexto.Text+'*''';
  QDATOS.Filtered:=True; //Habilito el filtro nuevamente
end;
Saludos...:)

Al González 29-01-2010 21:24:54

Me parece que todos los componentes de datos nativos trabajan de esa manera.

Algo que puedes hacer, sin tener que recurrir a componentes de terceros ni escribir mucho código, es crear un campo calculado que contenga los mismos nombres pero a partir de la segunda palabra. Entonces podrías llamar a Locate con el primer campo y, en caso de no encontrarse un registro, llamar a Locate con el campo calculado.

De cualquier manera, considera que Paradox y BDE son tecnologías obsoletas y que presentar en pantalla una lista de n registros para que el usuario selecciona uno solo, puede resultar lento y pesado para el sistema cuando esos n registros sean cientos o miles.

En muchos casos es una mejor práctica lanzar una consulta SQL parametrizada con la parte de texto que quieres encontrar, haciendo que se carguen en memoria solamente los registros que cumplan con el criterio de búsqueda.

Te invito a echar un vistazo a los sistemas cliente-servidor y de n capas. Un buen paso para mí y muchos otros compañeros del foro que solíamos usar Paradox fue comenzar a practicar con Firebird.

Saludos.

Al González. :)

EDITO: Ahora veo el mensaje de rgstuamigo. :)

afunez2007 29-01-2010 23:36:22

Yo para esos casos lo que uso es un componente que se llama JvDBFindEdit, de JEDI, el cual permite cambiar la propiedad de findStyle a AnyPos, o FisrtPos
Otra ventaja de este componente es que tiene una propiedad que se llama findMode, que puede ser filter, y es una busqueda incremental va quitando los que no coinciden, es exelente.

Yo siempre lo hago asi, uso ese componente y le pongo tambien un checkbox, para cambiar el find style a anypos o firstpos si no encuentra al principio.

Si necesitas mas informacion avisame

Saludos

dtomeysoto 01-02-2010 16:19:31

Cita:

Empezado por rgstuamigo (Mensaje 352304)
Lo que pasa es que la funcion Locate solo te busca coincidencias desde el principio y no en el medio,o al final;;) Lo que veo mejor que hagas es Filtrar tu DataSet(QDATOS) por medio de Like para que tambien te busque coincidencias entre medios o al final; tu codigo seria mas o menos asi:
Código Delphi [-]procedure TForm1.eBuscarTextoChange(Sender: TObject); begin QDATOS.Filtered:=False;//Deshabilito el filtro QDATOS.Filter:='NOMBRE LIKE ''*'+eBuscarTexto.Text+'*'''; QDATOS.Filtered:=True; //Habilito el filtro nuevamente end;

Saludos...:)

Hola amigo, resulta que el LIKE no se puede usar, obtengo el siguiente mensaje: Operation not applicable.

Deja ver si instalando las JEDI puedo usar el componente JvDBFindEdit y logro lo que quiero.

Reconozco que Paradox y BDE son tecnologías obsoletas pero esta aplicación que estoy haciendo es para ejecutarse en un PC aislado de la red y es un "cacharrito", por eso tomé la decisión del BDE y Paradox. No obstante si alguien tiene experiencia en el desarrollo de aplicaciones para PC con poca RAM (256 MB), un micro Celeron a 1.X GHZ, etc que me lo diga para tenerlo en cuenta porque siempre es bueno aprender.

Ya tengo descargado el Firebird y 2 documentos que hablan sobre la creación de aplicaciones o sistemas cliente-servidor y de n capas los cuales descargué de este maravilloso Club.

Gracias por sus aportes.

rgstuamigo 01-02-2010 16:32:31

Cita:

Empezado por dtomeysoto (Mensaje 352523)
Hola amigo, resulta que el LIKE no se puede usar, obtengo el siguiente mensaje: Operation not applicable.

Bueno se me olvido decirte que incluyas la opcion foNoPartialCompare en la propiedad FilterOptions de tu DataSet (QDATOS) Lo puedes hacer en tiempo de Diseño para no hacerlo desde codigo;). Hahh y por si las dudas, cuando se esta filtrando con Like en un DataSet no se usa el caracter '%' de porcentage sino el '*' Asterisco.;) Por favor no confundir con las consultas SQL que se hace aun servidor de Base de Dato.
Tu codigo quedaria asi:

Código Delphi [-]
procedure TForm1.eBuscarTextoChange(Sender: TObject);
begin
  QDATOS.Filtered:=False;//Deshabilito el filtro
  QDATOS.FilterOptions:=[foNoPartialCompare];{<--incluyo la opcion 
   foNoPartialCompare, OJO si ya se hizo ésto en tiempo de diseño ésta linea no es necesaria} ;) 
  QDATOS.Filter:='NOMBRE LIKE ''*'+eBuscarTexto.Text+'*''';
  QDATOS.Filtered:=True; //Habilito el filtro nuevamente
end;
.
Pruebalo...:)

dtomeysoto 01-02-2010 16:43:39

Cita:

Empezado por rgstuamigo (Mensaje 352524)
Bueno se me olvido decirte que incluyas la opcion foNoPartialCompare en la propiedad FilterOptions de tu DataSet (QDATOS) Lo puedes hacer en tiempo de Diseño para no hacerlo desde codigo;). Hahh y por si las dudas, cuando se esta filtrando con Like en un DataSet no se usa el caracter '%' de porcentage sino el '*' Asterisco.;) Por favor no confundir con las consultas SQL que se hace aun servidor de Base de Dato.
Tu codigo quedaria asi:

Código Delphi [-]procedure TForm1.eBuscarTextoChange(Sender: TObject); begin QDATOS.Filtered:=False;//Deshabilito el filtro QDATOS.FilterOptions:=[foPartialCompare];{<--incluyo la opcion foPartialCompare, OJO si ya se hizo ésto en tiempo de diseño ésta linea no es necesaria} ;) QDATOS.Filter:='NOMBRE LIKE ''*'+eBuscarTexto.Text+'*'''; QDATOS.Filtered:=True; //Habilito el filtro nuevamente end;

.
Pruebalo...:)

Yo mismo no me había quedado conforme y me puse a leer un poquito más y logré lo que quería con el siguiente código:

Código Delphi [-]
  QDATOS.Close;

  if Length(eBuscarTexto.Text) > 0 then
    QDATOS.SQL[2] := 'WHERE NOMBRE LIKE ''%' + eBuscarTexto.Text + '%'''
  else
    QDATOS.SQL[2] := 'WHERE NOMBRE LIKE ''%%''';

  QDATOS.Open;


Ahora déjame analizar el que escribiste a ver si resulta. Gracias por tu preocupación y dedicación.

dtomeysoto 01-02-2010 16:54:46

Cita:

Empezado por rgstuamigo (Mensaje 352524)
Bueno se me olvido decirte que incluyas la opcion foNoPartialCompare en la propiedad FilterOptions de tu DataSet (QDATOS) Lo puedes hacer en tiempo de Diseño para no hacerlo desde codigo;). Hahh y por si las dudas, cuando se esta filtrando con Like en un DataSet no se usa el caracter '%' de porcentage sino el '*' Asterisco.;) Por favor no confundir con las consultas SQL que se hace aun servidor de Base de Dato.
Tu codigo quedaria asi:

Código Delphi [-]procedure TForm1.eBuscarTextoChange(Sender: TObject); begin QDATOS.Filtered:=False;//Deshabilito el filtro QDATOS.FilterOptions:=[foNoPartialCompare];{<--incluyo la opcion foNoPartialCompare, OJO si ya se hizo ésto en tiempo de diseño ésta linea no es necesaria} ;) QDATOS.Filter:='NOMBRE LIKE ''*'+eBuscarTexto.Text+'*'''; QDATOS.Filtered:=True; //Habilito el filtro nuevamente end;

.
Pruebalo...:)

Ya lo probé y me sigue saltando el mismo error, resolví con el código que puse y añadiéndole a la consulta la siguiente línea:

Código SQL [-]
WHERE  NOMBRE LIKE '%%'

rgstuamigo 01-02-2010 16:57:01

Solo agregar que seria mejor si tambien incluyeras la opcion foCaseInsensitive tambien.;) Si tienes dudas revisa la ayuda de Delphi.
Otra cosa->>Cuando estes escribiendo(Postenado) trata en lo posible no visualizar (Boton de Vista Previa) ya que esto conlleva (cuando envias tu respuesta) a tener un codigo muy feo en el foro. Si se da el caso de que quieres visualizar lo que escribiste no le des Enviar Respuesta desde ahi tan solo presiona el boton de atras en tu navegador y desde alli guardas o envias tu respuesta.
Ésto se debe a que el interprete que muestra los post , tiene un error(bug) internamente que hace que el formateo de codigo no se vea muy estético.;)
Saludos...:)

rgstuamigo 01-02-2010 17:03:35

Cita:

Empezado por dtomeysoto (Mensaje 352528)
Ya lo probé y me sigue saltando el mismo error, resolví con el código que puse y añadiéndole a la consulta la siguiente línea:

Código SQL [-]WHERE NOMBRE LIKE '%%'

Estas confundiendo las cosas;)...una cosa son los filtros de los dataSet y muy distinta son las consulta SQL hacia el servidor.;).
Los filtros no deben tener la Clausula "WHERE";).
Saludos...:)

dtomeysoto 01-02-2010 17:09:14

Cita:

Empezado por rgstuamigo (Mensaje 352529)
Solo agregar que seria mejor si tambien incluyeras la opcion foCaseInsensitive tambien.;) Si tienes dudas revisa la ayuda de Delphi.
Otra cosa->>Cuando estes escribiendo(Postenado) trata en lo posible no visualizar (Boton de Vista Previa) ya que esto conlleva (cuando envias tu respuesta) a tener un codigo muy feo en el foro. Si se da el caso de que quieres visualizar lo que escribiste no le des Enviar Respuesta desde ahi tan solo presiona el boton de atras en tu navegador y desde alli guardas o envias tu respuesta.
Ésto se debe a que el interprete que muestra los post , tiene un error(bug) internamente que hace que el formateo de codigo no se vea muy estético.;)
Saludos...:)

Amigo, al probar tu código me salta el error Operation not applicable no se si sea porque estoy usando Paradox, o porque QDatos es una consulta (TQuery). El error se produce al asignar el valor a la propiedad Filter. Ya he probado cerrando la consulta y con la consulta abierta.

Entonces como dije anteriormente le agregué a la consulta en tiempo de diseño la línea:

Código SQL [-]
WHERE  NOMBRE LIKE '%%'

y modifiqué el código que había escrito inicialmente por:

Código Delphi [-]
  QDATOS.Close;

  if Length(eBuscarTexto.Text) > 0 then
    QDATOS.SQL[2] := 'WHERE NOMBRE LIKE ''%' + eBuscarTexto.Text + '%'''
  else
    QDATOS.SQL[2] := 'WHERE NOMBRE LIKE ''%%''';

  QDATOS.Open;

y así resolví el problema. Ya me había dado cuenta que al visualizar el post para ver como me había quedado y luego al enviarlo todo se desarreglaba.

A quién le toca arreglar ese bug????
Graciasssss


La franja horaria es GMT +2. Ahora son las 07:51:56.

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