Ir al contenido


Foto

Duda de primaria o anterior...


  • Por favor identifícate para responder
5 respuestas en este tema

#1 TiammatMX

TiammatMX

    Advanced Member

  • Miembros
  • PipPipPip
  • 1.750 mensajes
  • LocationUniverso Curvo\Vía Láctea\Sistema Solar\Planeta Tierra\América\México\Ciudad de México\Xochimilco\San Gregorio Atlapulco\Home

Escrito 19 agosto 2011 - 03:02

Buena tarde, jóvenes...

Resulta que tenemos una forma con tres o cuatro o muchos TEdits, TMaskEdit o controles así, y quiero tener la posibilidad de "pasar" de un control a otro SIN evaluar el contenido de un OnExit que contienen algunos de ellos para validación..., ejemplo, algo así...



delphi
  1. procedure TfrmIntrfz.mskedtEddExit(Sender: TObject);
  2. begin
  3.   if Trim(mskedtEdd.Text) <> '' then
  4.   begin
  5.     if (StrToInt(Trim(mskedtEdd.Text)) < 90) AND
  6.       (StrToInt(Trim(mskedtEdd.Text)) > 16) then
  7.     begin
  8.       Beep;
  9.       MessageDlg('El contenido de éste campo debe estar en rango.'+#13+#10+'Menor de 16 o mayor de 90.'+#13+#10+''+#13+#10+'Verifique y corrija.', mtError, [mbOK], 0);
  10.       mskedtEdd.Text := '';
  11.       mskedtEdd.SetFocus;
  12.     end;
  13.   end
  14.   else
  15.   begin
  16.     Beep();
  17.     MessageDlg('¡Campo vacío!'+#13+#10+''+#13+#10+'Verificar y corregir.', mtError, [mbOK], 0);
  18.   end;
  19. end;



El punto aquí es que entra al componente, y si malamente al usuario se le olvidó algo que está en el control anterior y desea regresar a él, entra en funcionamiento el OnExit, le manda el mensaje y regresa a él, imposibilitando la tarea que desea realizar el usuario.

Y la duda de niño de primaria (o de adulto embotado en las ideas) es: ¿Cómo puedo "decirle" al componente que en caso que regrese al control anterior NO EJECUTE OnExit? Llevo muchas horas enfrascado en otras partes del código y ya no "veo claro"...
  • 0

#2 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 19 agosto 2011 - 04:29

¿Cómo puedo "decirle" al componente que en caso que regrese al control anterior NO EJECUTE OnExit?



Quizás revisando la propiedad TabOrder del Componente en cuestión.


Saludos.
  • 0

#3 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 19 agosto 2011 - 04:34

Ah vaya, por un momento pensé que este tema debería de ir al Bar-Tolo, el título no dice mucho.

Salud OS
  • 0

#4 Caral

Caral

    Advanced Member

  • Moderador
  • PipPipPip
  • 4.266 mensajes
  • LocationCosta Rica

Escrito 19 agosto 2011 - 06:09

Hola
Lo que entiendo:


delphi
  1. public
  2.   a: integer;




delphi
  1. procedure TfrmIntrfz.verifica;
  2. var
  3. i    :Integer;
  4. comp :TComponent;
  5. begin
  6. for i := 1 to 2 do begin
  7. comp := FindComponent('Edit' + IntToStr(i));
  8. if TEdit(comp).Text = '' then
  9. begin
  10. Beep();
  11. MessageDlg('¡Campo vacío!'+#13+#10+''+#13+#10+'Verificar y corregir.', mtError, [mbOK], 0);
  12. end;
  13. end;
  14. end;




delphi
  1. procedure TfrmIntrfz.mskedtEddExit(Sender: TObject);
  2. begin
  3. a:= 1;
  4.   if Trim(mskedtEdd.Text) <> '' then
  5.   begin
  6.     if (StrToInt(Trim(mskedtEdd.Text)) < 90) AND
  7.       (StrToInt(Trim(mskedtEdd.Text)) > 16) then
  8.     begin
  9.       Beep;
  10.       MessageDlg('El contenido de éste campo debe estar en rango.'+#13+#10+'Menor de 16 o mayor de 90.'+#13+#10+''+#13+#10+'Verifique y corrija.', mtError, [mbOK], 0);
  11.       mskedtEdd.Text := '';
  12.       mskedtEdd.SetFocus;
  13.     end;
  14.   end
  15.   else
  16.   begin
  17.     if a <> 1 then
  18.   verifica;
  19. end;
  20. end;


Saludos
  • 0

#5 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.137 mensajes

Escrito 20 agosto 2011 - 08:29

He elaborado un ejemplo que creo que se aproxima bastante a lo que quieres, esto se basa en  3 arrays (para este ejemplo de 4 elementos), uno de TWinControl, en el que vamos a colocar los controles que necesitan de validación, en donde la  propiedad Tag de cada elemento corresponde al índice en el array (se hubiera podido hacer en la propiedad TabOrder, pero cuando hay controles anidados en grupos, páginas, etc la cosa podría complicarse, por eso he optado por el TAG; un segundo array de Boolean, en el que se colocarán las condiciones a evaluar para cada control del array de controles, en el que, como es lógico, los índices deben corresponder con los dos arrays; y un tercer array de string con los mensajes a mostrar en caso de que que no se cumplan las condiciones del array de Boolean, los índices deben corresponder  con los de los otros  dos arrays. Ademas agregamos un campo privado de tipo entero FTagUltimoControl en el que guardaremos el Tag del último control.


Al crear  el Form inicializamos los array de Controles y  de Mensajes así como el valor del campo FTagUltimoControl.


Compartimos el procedimiento ControlarEntradas en el evento OnEnter de los controles que hacen parte del array de controles. En este procedimiento comparamos el valor del Tag del control que recibe el foco contra el valor del Tag del control anterior almacenado en el campo FTagUltimoControl, solo si el Tag es mayor al anterior se dispara la validación del control anterior almacenada en el array de  Condiciones en el caso contrario no pasa nada (que es lo que tu quieres si el usuario "se devuelve").


Compartimos el procedimiento ControlarSalidas en el evento OnExit de los controles que hacen parte del array de controles. En este procedimiento actualizamos el valor de FTagUltimoControl con el valor del Tag del control que pierde el foco y pasamos el valor booleano de la posible validación, para que sean usados si es necesario en el evento OnEnter del control que recibe el foco.
Debes evitar colocar validaciones individuales en el evento OnExit de los controles, pues estas deben colocarse en el array de condiciones, de lo contrario siempre que salgas del control se ejecutaría.


Finalmente en el evento OnClick del botón, simplemente pasamos los valores a validar, recorremos el array de Condiciones y hacemos todas las validaciones de menor a mayor, devolviendo el foco al control que no cumpla y enviando el respectivo mensaje de error.


He puesto una función complementaria (ESNumero) para evitar el error de tipo al evaluar la condición del Edit3 del ejemplo, esta no es relevante, en caso de que  lo que que estés validadndo campos de un Dataset es más fácil validar en función de los valores del campo en cuestión.


Espero te sirva de guía para implementar lo que quieres.




delphi
  1. unit Unit1;
  2.  
  3.  
  4. interface
  5.  
  6.  
  7. uses
  8.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  9.   Dialogs, StdCtrls;
  10.  
  11.  
  12. type
  13.   TForm1 = class(TForm)
  14.     Edit1: TEdit;
  15.     Edit2: TEdit;
  16.     Edit3: TEdit;
  17.     Edit4: TEdit;
  18.     Button1: TButton;
  19.     procedure FormCreate(Sender: TObject);
  20.     procedure ControlarEntrada(Sender: TObject);
  21.     procedure ControlarSalida(Sender: TObject);
  22.     procedure Button1Click(Sender: TObject);
  23.   private
  24.     FControles: array [1 .. 4] of TWinControl;
  25.     FCondiciones: array [1 .. 4] of Boolean;
  26.     FMensajes: array [1 .. 4] of string;
  27.     FTagControlAnterior: Integer;
  28.  
  29.  
  30.     { Private declarations }
  31.   public
  32.     { Public declarations }
  33.   end;
  34.  
  35.  
  36. var
  37.   Form1: TForm1;
  38.  
  39.  
  40. implementation
  41.  
  42.  
  43. {$R *.dfm}
  44.  
  45.  
  46. procedure TForm1.FormCreate(Sender: TObject);
  47. begin
  48.   // Inicializo controles
  49.   FControles[1] := Edit1;
  50.   FControles[2] := Edit2;
  51.   FControles[3] := Edit3;
  52.   FControles[4] := Edit4;
  53.  
  54.  
  55.   // Inicializo mensajes
  56.   FMensajes[1] := 'Edit1 debe contener un valor';
  57.   FMensajes[2] := 'El número de carcateres de Edit2 debe ser maypor que 3';
  58.   FMensajes[3] := 'El valor de Edit3 debe ser mayor que 7';
  59.   FMensajes[4] := 'El valor de Edtit4 debe ser diferente de hola';
  60.  
  61.  
  62.   // Inicializo Control
  63.   FTagControlAnterior := 1
  64. end;
  65.  
  66.  
  67. procedure TForm1.ControlarEntrada(Sender: TObject);
  68. begin
  69.   if TWinControl(Sender).Tag > FTagControlAnterior then
  70.     if not FCondiciones[FTagControlAnterior] then
  71.     begin
  72.       ShowMessage(FMensajes[FTagControlAnterior]);
  73.       FControles[FTagControlAnterior].SetFocus;
  74.     end;
  75. end;
  76.  
  77.  
  78. function EsNumero(const S: string): Boolean;
  79. var
  80.   k: Integer;
  81. begin
  82.   Result := False;
  83.   if length(Trim(S)) > 0 then
  84.   begin
  85.     for k := 1 to length(Trim(S)) do
  86.       case Trim(S)[k] of
  87.         '0' .. '9':
  88.           ;
  89.       else
  90.         Exit;
  91.       end;
  92.     Result := True;
  93.   end;
  94. end;
  95.  
  96.  
  97. procedure TForm1.ControlarSalida(Sender: TObject);
  98. begin
  99.   FTagControlAnterior := TWinControl(Sender).Tag;
  100.   case TWinControl(Sender).Tag of
  101.     1:
  102.       FCondiciones[1] := Edit1.Text <> '';
  103.     2:
  104.       FCondiciones[2] := length(Edit2.Text) > 3;
  105.     3:
  106.       FCondiciones[3] := EsNumero(Edit3.Text) and (StrToInt(Edit3.Text) > 7);
  107.     4:
  108.       FCondiciones[4] := Edit4.Text <> 'Hola';
  109.   end;
  110. end;
  111.  
  112.  
  113. procedure TForm1.Button1Click(Sender: TObject);
  114. var
  115.   K: Integer;
  116. begin
  117.   FCondiciones[1] := Edit1.Text <> '';
  118.   FCondiciones[2] := length(Edit2.Text) > 3;
  119.   FCondiciones[3] := EsNumero(Edit3.Text) and (StrToInt(Edit3.Text) > 7);
  120.   FCondiciones[4] := Edit4.Text <> 'Hola';
  121.   for K := low(FCondiciones) to High(FCondiciones) do
  122.     if not FCondiciones[K] then
  123.     begin
  124.       ShowMessage(FMensajes[K]);
  125.       FControles[K].SetFocus;
  126.       Exit;
  127.     end;
  128. end;
  129.  
  130.  
  131. end.





  • 0

#6 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 20 agosto 2011 - 10:43

Wilson tu idea podría aligerarse si creamos una estructura con dos elementos, un booleano que indica si está validado y un string con el mensaje. Cada control almacena esa estructura mediante un puntero almacenado en su Tag.


Basta con recorrer los elementos y consultar la estructura para controlar el asunto.


Saludos.
  • 0




IP.Board spam blocked by CleanTalk.