PDA

Ver la Versión Completa : Problemas para capturar valor de OnKeyPress


CamiloU
05-04-2006, 02:53:57
Espero me puedan colaborar con el siguiente inconveniente. Trato simular el ReadKey de Pascal con el Evento OnKeyPress de un Edit. Pero la informacion no me pasa a la tabla final.

Presento el codigo para tratar de ser mas especifico con el problema.


procedure TEvaRes.RespKeyPress(Sender: TObject; var Key: Char);
var
res : string[1];
begin
aux := inttostr(i);
if (i < 10) then Result.Text := concat('00',aux);
if (i >= 10) and (i < 100) then Result.Text := concat('0',aux)
else Result.text := aux;
Resp.Clear;
Resp.SetFocus;
if (StrScan('A',Key) <> nil) or (StrScan('B',Key) <> nil) or (StrScan('C',Key) <> nil) or (StrScan('D',Key) <> nil) or
(StrScan('E',Key) <> nil) or (StrScan('F',Key) <> nil) or (StrScan('G',Key) <> nil) or (StrScan('H',Key) <> nil) or
(StrScan('V',Key) <> nil) then
begin
TTemporal.Append;
TTemporal.FieldByName('Pregunta').AsString := inttostr(i);
res := Resp.Text;
TTemporal.FieldByName('Respuesta').AsString := Resp.Text;
TTemporal.Post;
i := i + 1;
Resp.Clear;
end
else Key := #0;

if i > 159 then
begin
tcp := 0;
tda := 0;
tcu := 0;
TRelacion.First;
TTemporal.First;
for j := 1 to (i - 1) do
begin
if TRelacion.FieldByName('Resultado').AsString = TTemporal.FieldByName('Respuesta').AsString then
begin
if TRelacion.FieldByName('Grupo').AsString = 'C' then tcp := tcp + 1;
if TRelacion.FieldByName('Grupo').AsString = 'A' then tda := tda + 1;
if TRelacion.FieldByName('Grupo').AsString = 'D' then tcu := tcu + 1;
end;
TRelacion.Next;
TTemporal.Next;
end;
tot := tcp + tda + tcu;
Resp.Enabled := False;
end;
end;


La idea es que mientras no llegue a 160, pida el valor. A la tabla TTemporal ingresa el numero de la pregunta pero nunca ingresa la respuesta.

Podrian darme una ayuda.

Muchas Gracias.

Lepe
05-04-2006, 10:49:11
La variable "i" no tiene asignada un valor, quizás sea una variable global, pero no puedo adivinarlo si tiene un valor correcto (aunque dices que si).

Desconozco que es "Resp", pero antes del StrScan haces un Resp.Clear, ¿no borra eso el contenido de Resp.Text?

Sugerencia: La condición de strScan se podía haber abreviado como:

if strScan('ABCDEFGHV',key) <> nil


Saludos

CamiloU
05-04-2006, 17:23:33
Lepe. Muchas gracias por la colaboracion. Aclaro un poco mas la situacion. i es un contador de preguntas que se incrementa hasta llegar a 160 porque el total de preguntas del formulario es 159, la cual es inicializada en 1 cada vez que se activa el Formulario. Resp es un Edit donde se ingresa la letra que marcó la persona que lleno el formulario.

Me alargo un poquito para ser mas especifico. La aplicacion busca ingresar y validar las respuestas dadas por n numero de personas en un formulario, donde las preguntas son de seleccion multiple, agrupacion y falso y verdadero.

Respecto a la idea de abreviar. Es cierto pero busco que solo se pueda ingresar una tecla por vez, simulando el ReadKey de Pascal. La idea del Clear es limpiar el Edit para el siguiente ingreso (algo que por cierto no hace).

Después de ingresar el dato, busco que se cambie la posicion de la tabla y el proximo ingreso llegue al registro siguiente.

Pero nunca me recibe el valor dado en el Edit Resp.

roman
05-04-2006, 18:12:33
Tienes un Resp.Clear después del POST que supongo es el que quieres para limpiar el edit para la próxima pregunta; pero tienes otro Resp.Clear antes del Append y es al que Lepe se refiere.

Y haz caso a Lepe y abrevia ese condicional. Al evento OnKeyPress sólo puede llegarle un caracter a la vez.

// Saludos

Lepe
05-04-2006, 18:17:33
Oki doki.

Al Edit le pones MaxLength a 1 y listo, solo permites una letra. Tambien le pones Charcase := ecUppercase y solo escribe en mayúsculas. Ya puedes usar el StrScan como te comenté.

El no responder a Resp.Clear, es precisamente porque lo haces dentro del evento KeyPress. Ten en cuenta que en ese evento puedes modificar por código la tecla pulsada, por tanto, aún no ha sido procesada, y por tanto no está en Resp.Text, solo cuando termine el evento, es cuando el carácter estará en Resp.Text (el carácter que pulsó el usuario, o el que tú has modificado por código).

La solución es bien fácil, en lugar de usar Resp.Text, usamos el parámetro Key.

procedure TEvaRes.RespKeyPress(Sender: TObject; var Key: Char);
var
res : string;
begin
aux := inttostr(i);
if (i < 10) then Result.Text := concat('00',aux);
if (i >= 10) and (i < 100) then Result.Text := concat('0',aux)
else Result.text := aux;
Resp.SetFocus;
if strScan('ABCDEFGHV',key) <> nil begin
TTemporal.Append;
TTemporal.FieldByName('Pregunta').AsString := inttostr(i);
res := key; // <<<<<<<<<<<<<<<< guardamos la tecla
TTemporal.FieldByName('Respuesta').AsString := res;//ahora si se guarda
TTemporal.Post;
i := i + 1;
end
else Key := #0; // esto si debe funcionar de lujo.

if i > 159 then
begin
tcp := 0;
tda := 0;
tcu := 0;
TRelacion.First;
TTemporal.First;
for j := 1 to (i - 1) do
begin
if TRelacion.FieldByName('Resultado').AsString = TTemporal.FieldByName('Respuesta').AsString then
begin
if TRelacion.FieldByName('Grupo').AsString = 'C' then tcp := tcp + 1;
if TRelacion.FieldByName('Grupo').AsString = 'A' then tda := tda + 1;
if TRelacion.FieldByName('Grupo').AsString = 'D' then tcu := tcu + 1;
end;
TRelacion.Next;
TTemporal.Next;
end;
tot := tcp + tda + tcu;
Resp.Enabled := False;
end;
end;
Obviamente queda hacer un Resp.Clear, pero como dije, no puede hacerse en este evento. Podría añadir Key := #0 despues de hacer el i:=i+1, pero el usuario no vería la tecla en el edit, daría la impresión de que no la acepta. Es mejor buscar otro lugar donde Hacer el Resp.Clear.

Saludos

CamiloU
06-04-2006, 02:35:48
Muchas Gracias por la colaboracion. Hay algunos detallitos menores que me fallan pero el resto funciona de lujo.

Quisiera hacer una pregunta extra. La Tabla Temporal me gustaria dejarla vacia al finalizar el ingreso de datos del respectivo usuario. Que instruccion le debo dar y en que momento. He estado utilizando las instrucciones Empty y DeleteTable en el OnClose y me da error.

Lepe
06-04-2006, 10:49:15
Ejemplo de la ayuda de delphi:

with Table1 do

begin
Active := False;
** DatabaseName := 'Delphi_Demos';
** TableName := 'CustInfo';
** TableType := ttParadox;
EmptyTable;

end;

Las instrucciones con ** las tendrás especificadas en tiempo de diseño, por tanto, solo tienes que cerrar la tabla y vaciarla, pero con el TDatabase y Session abiertos.

CamiloU
07-04-2006, 18:57:00
Muchas Gracias por la colaboracion.