Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Posicionarse en DBGrid según tecla pulsada (https://www.clubdelphi.com/foros/showthread.php?t=80381)

radenf 23-09-2012 14:49:27

Posicionarse en DBGrid según tecla pulsada
 
Hola amigos:

En un DBGrid conectado a una base de datos Access, que posee un primer campo Nombre, necesito posicionarme en el primer registro en que el nombre comienze con la letra de la tecla que se pulsa.

Ejemplo: Si pulso la tecla p que se posicione en Pablo y si pulso la tecla m lo haga en Matías.

Mis escasos conocimientos no me han permitido dar con el código y en las búsquedas no he encontrado nada que relacione los eventos del teclado con esta condición.
Agradezco desde ya cualquier aporte.

Saludos y muchas gracias :)

movorack 23-09-2012 15:03:59

Hola

Podrías ir haciendo un locate parcial o bien podrías colocar una caja de texto donde escribas una condición para filtrar la grid por el campo nombre

radenf 23-09-2012 15:37:18

Gracias movorack

Ya lo intenté con un query que se activa en el evento OnChange de un Edit, pero no me sirve ya que debe ser algo más dinámico, porque debo vaciar el Edit después de pulsar una tecla, para acceder a otra.
El locate parcial no lo he intentado.
Creo que sería más directo y mejor acceder a través de codificar las acciones del teclado, que es lo que busco.

Saludos

radenf 23-09-2012 19:41:29

Logré solucionar el problema utilizando el siguiente código, que dejo por si alguien lo necesita.
Utilizé el locate parcial como sugirió movorack y funcionó.

Código Delphi [-]
procedure Form1.DBGrid1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if key = ord('A') then begin
Tabla1.Locate('nombre', 'a', [loCaseInsensitive, loPartialKey])
end
else
begin
if key = ord('B') then begin
Tabla1.Locate('nombre', 'b', [loCaseInsensitive, loPartialKey])
end
else
begin
.......

y así sucesivamente hasta llegar a la Z

Muchas gracias por tu ayuda movorack

Casimiro Notevi 23-09-2012 20:49:16

Creo que lo puedes acortar un poco. (escribo de memoria):

Código Delphi [-]
procedure TForm1.dbgrid1KeyPress(Sender: TObject; var Key: Char);
begin
  if key in ['a'..'z'] then
    tabla1.locate('nombre', key, [locaseinsensitive,lopartialkey]);
end;

radenf 23-09-2012 21:29:33

Muchas gracias Casimiro Notevi

Cuando me llegó el email indicando tu participación en el hilo, pensé que me ibas a sancionar por el título o me ibas a mandar a leer la guía de estilo.
Hablando en serio: Probé tu código y si bien no da ningún error, no realiza la acción requerida.
Ideal sería poder acortar el código que yo puse, que ocupa 172 líneas.
¿Cúal es la diferencia en usar onKeyPress en vez de onKeyDown?

Salu2

Casimiro Notevi 23-09-2012 22:35:28

Cita:

Empezado por radenf (Mensaje 444048)
Cuando me llegó el email indicando tu participación en el hilo, pensé que me ibas a sancionar por el título o me ibas a mandar a leer la guía de estilo.

Vaya fama :confused::p:D

Cita:

Empezado por radenf (Mensaje 444048)
Hablando en serio: Probé tu código y si bien no da ningún error, no realiza la acción requerida.

Lo mismo has tecleado en mayúsculas, cambia el código:
Código Delphi [-]
procedure TForm1.dbgrid1KeyPress(Sender: TObject; var Key: Char); 
begin   
  if key in ['A'..'Z','a'..'z'] then     
    tabla1.locate('nombre', key, [locaseinsensitive,lopartialkey]); 
end;

Cita:

Empezado por radenf (Mensaje 444048)
¿Cúal es la diferencia en usar onKeyPress en vez de onKeyDown?

Fíjate que en keydown 'key' es un word y en keypress en un char.
Básicamente (muy básicamente :D), en keydown puedes capturar las teclas de flechas, las F1..F12, may, num, etc. y el keypress está más pensado para teclas "normales".

Tiene que funcionarte el código que he puesto antes, revísalo bien, pon un breakpoint para revisar el valor de key y si entra en la condición. Te recuerdo que lo he escrito de memoria, no tengo un delphi para probar.

radenf 23-09-2012 23:23:14

Muchas gracias Casimiro Notevi

Por cierto tu fama te precede y me parece muy bien que exijas que las normas del foro sean cumplidas por todos.

No logré hacer funcionar tu código.
Seguiré intentándolo para lograr reducir dicha acción, ya que mi programa actualmente totaliza más de 5.600 líneas de código.
Te agradezco nuevamente tu aporte y tus enseñanzas.

Salu2

Casimiro Notevi 24-09-2012 00:32:30

¿Has puesto el breakpoint para saber por qué no entra en la condición?

radenf 24-09-2012 00:44:16

Lo hice y los breakpoint aparecen con un check verde y un valor =0, pero no se modifica la posición de la selección de el DBGrid al apretar las teclas.

Salu2

Casimiro Notevi 24-09-2012 01:45:38

¿Pero dónde tecleas?, ese código funcionará si estás tecleando en el propio dbgrid.
Cámbialo al form, por ejemplo:

Código Delphi [-]
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);  // controlar teclas pulsadas a nivel del Form
begin
  if (ActiveControl=dbgrid1) then  // si el dbgrid tiene el control/foco
    if key in ['A'..'Z','a'..'z'] then          
      tabla1.locate('nombre', key, [locaseinsensitive,lopartialkey]);
end;

radenf 24-09-2012 02:35:27

Estimado Casimiro Notevi :

Realizé las modificaciones que sugeriste y no funciona.
Respecto a tu pregunta no tecleo en ninguna parte en especial, el DBGrid siempre tiene el foco porque ocupa gran parte del Form y está configurado para que al entrar el puntero del mouse tome el foco. La idea es que al apretar cualquier tecla alfabética, el DBGRid se posicione en el primer registro que comienze con la letra de la tecla presionada.
Por el momento me quedaré con mi código, mientras encuentro como abreviarlo.
Agradezco toda tu preocupación y desinteresada colaboración.

Saludos y muchas gracias

ecfisa 24-09-2012 07:35:39

Hola radenf.

El código que te sugirió Casimiro hace exáctamente lo que deseas. También coincido con él, que el problema pasa por donde estas realizando la captura del evento de teclado.

Para asegurarte que el evento de teclado es capturado correctamente proba de este modo:
Código Delphi [-]
...
procedure El_Form.FormCreate(Sender: TObject);
begin
  // el formulario recibe el evento de teclado antes que el control activo
  KeyPreview := True;  // asignable desde el Object Inspector
end;

procedure El_Form.FormKeyPress(Sender: TObject; var Key: Char);
begin
  // ¿ El control activo es el DBGrid y se presionó una letra ?
  if (ActiveControl = El_DBGrid) and (Upcase(Key) in['A'..'Z']) then
     Tabla_o_Query.Locate('NOMBRE_DEL_CAMPO', Key, [loPartialKeylo, CaseInSensitive]); // posicionar
end;
...

Saludos.:)

radenf 24-09-2012 12:23:07

Muchas gracias ecfisa.

Tienen toda la razón. El código no funcionaba porque el DBGrid estaba con la propiedad rowselect en True. Al ponerla en falso realiza perfectamente la selección requerida.
Gracias a ti y a Casimiro Notevi por sus aportes.
Poblema resuelto.

Salu2

bulc 27-05-2014 14:16:52

Key en KeyDown Vs. Key en KeyUp/KeyPress
 
Cita:

Empezado por ecfisa (Mensaje 444079)
Hola radenf.

El código que te sugirió Casimiro hace exáctamente lo que deseas. También coincido con él, que el problema pasa por donde estas realizando la captura del evento de teclado.

Para asegurarte que el evento de teclado es capturado correctamente proba de este modo:
Código Delphi [-]
...
procedure El_Form.FormCreate(Sender: TObject);
begin
  // el formulario recibe el evento de teclado antes que el control activo
  KeyPreview := True;  // asignable desde el Object Inspector
end;

procedure El_Form.FormKeyPress(Sender: TObject; var Key: Char);
begin
  // ¿ El control activo es el DBGrid y se presionó una letra ?
  if (ActiveControl = El_DBGrid) and (Upcase(Key) in['A'..'Z']) then
     Tabla_o_Query.Locate('NOMBRE_DEL_CAMPO', Key, [loPartialKeylo, CaseInSensitive]); // posicionar
end;
...

Saludos.:)

Hola. Tal vez deberíais mencionar que no es lo mismo usar el KeyDown que el KeyPress o el KeyUp. el evento onKeyDown gestiona todas las teclas, pero sólo tiene traducción directa para las teclas Virtual Key con prefijo VK. Tales como VK_RETURN, VK_END, etc. Es us valor Word y por tanto requiere más vueltas para obtener el valor de la tecla cuando es letra o número. En cambio el KeyPress o KeyUp dan el valor ASCII de la tecla. Pongo el link, sobre el tema, que he encontrado: http://delphi.about.com/od/adptips2006/qt/vkey2char.htm
No es tan fácil como pensaba. Saludos.


La franja horaria es GMT +2. Ahora son las 01:53:29.

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