Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Validar un memo por linea (https://www.clubdelphi.com/foros/showthread.php?t=61741)

deprimera 20-11-2008 14:08:10

Validar un memo por linea
 
Hola a todos

Me gustaria saber como puedo hacer para que un memo m permita ingresar nada mas 3 caracteres por linea y luego que pase al renglon de abajo...espero alguna respuesta muchas graciass

Caro 20-11-2008 14:34:20

Hola deprimera, se me ocurre que hagas algo así:

Código Delphi [-]
procedure TForm1.Memo1KeyPress(Sender: TObject; var Key: Char);
begin
 if Length(Memo1.Lines[Memo1.Lines.Count-1]) > 2 then
  key := #13;
end;

Saluditos

deprimera 20-11-2008 15:07:52

caro q suerte encontrarte nuevamente...

cuando ejecuto el codigo q m pasast m hace 2 enter, deja un renglon entre medio en blanco y si borro todo desp no lo vuelve a validar

Caro 21-11-2008 15:09:24

Cita:

Empezado por deprimera (Mensaje 326979)
cuando ejecuto el codigo q m pasast m hace 2 enter, deja un renglon entre medio en blanco y si borro todo desp no lo vuelve a validar

Hola de nuevo, ayer te respondi a la rapida sin ver los problemas que podía tener ese codigo, ademas que estoy con poco tiempo, acabo de hacer una prueba y si, no funciona bien, nada bien, aún arreglandolo no funciona bien en esos eventos (OnKeyDown, OnKeyUp).

Lo que puedes hacer es utilizar el evento OnMessage del ApplicationEvent que se encuentra en la paleta Additional.

Código Delphi [-]
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
  var Handled: Boolean);
var
 FilaActual : Integer;
begin
 //Capturamos cuando se ha presionado una tecla
 if (Msg.message=WM_KEYDOWN) then
  if ActiveControl = Memo1 then //Verificamos si ha sido en el Memo
   begin
     //Obtenemos la fila actual
     FilaActual := Memo1.Perform(EM_LINEFROMCHAR, Memo1.SelStart, 0);
 
     if (Memo1.Lines[FilaActual+1]<>'') AND Not(Msg.wParam in [vk_delete,8,vk_left,vk_right,vk_down,vk_up]) then
        Msg.wParam := 0;
 
     if Length(Memo1.Lines[FilaActual])=2 then
      begin
       if (FilaActual=Memo1.Lines.Count-1) AND (Msg.wParam<>VK_RETURN) then
        //Envíamos el Enter al Memo
        PostMessage(Memo1.Handle, WM_KEYDOWN, VK_RETURN, 0);
      end;
   end;
end;

Conste que no esta bien controlado, pero puedes aumentar codigo sobre eso, espero que alguien mas pueda ayudarte a controlar para que todo funcione bien. Por ahora recibe solo 3 caracteres y se presiona el enter, una vez que ya tienes lleno, te puedes mover entre las lineas borrar pero no aumentar mas texto, como te digo falta controlar.

Saluditos

deprimera 21-11-2008 17:34:07

te agradezco mucho ,aun no funciona bien pero tampoco quiero abusar de tus tiempos...besoss

roman 21-11-2008 18:10:52

Creo que deberías especificar con más detalle lo que quieres lograr. Por ejemplo, con este código

Código Delphi [-]
procedure TForm1.Memo1KeyPress(Sender: TObject; var Key: Char);
var
  C, I: Integer;

begin
  I := Memo1.Perform(EM_LINEFROMCHAR, Memo1.SelStart, 0);
  C := Length(Memo1.Lines[i]);

  if Key = #13 then
    Key := #0;

  if (C >= 3) and (Key <> #8) then
    Memo1.Lines.Insert(I + 1, '');
end;

logras más o menos lo que quieres: al escribir el cuarto caracter en una linea, automáticamente se coloca en la siguiente; la tecla de retroceso funciona como se espera, y al oprimir ENTER se pasa a la siguiente línea sólo si ya se completaron los tres caracteres.

Pero no has definido si esto es realmente lo que deseas del ENTER, ni tampoco qué debe pasar si te cambias a una línea anterior. En resumen, especificar qué debe suceder en cada caso posible.

Por otra parte, habría que ver si no te conviene más usar otro tipo de control, como un StringGrid, por ejemplo.

// Saludos

deprimera 22-11-2008 00:04:58

roman gracias por tu respuesta

El codigo no funciona para lo q yo quiero pq como vos decis "al oprimir ENTER se pasa a la siguiente línea sólo si ya se completaron los tres caracteres" pero yo necesito q tambien m permita ingresar uno, dos o tres caracteres.

Te explico un poco lo q necesito:
Yo utilizo el memo para ingresar una cantidad de productos que vendo (estoy haciendo una factura de venta), por cada linea yo necesito entrar la cantidad de productos que estoy vendiendo que puede tener una, dos o tres cifras, por lo tanto cuando ingreso la cantidad que nesecito 1, 10 o 100 por ejemplo, con un enter poder pasar a la linea siguiente para cargar la proxima cantidad.

roman 22-11-2008 01:28:14

Lo de impedir el cambio de línea sólo si se completaban los tres caracteres lo había puesto justamente por no saber con exactitud cuáles eran las necesidades, pero puedes modificarlo fácilmente:

Código Delphi [-]
procedure TForm1.Memo1KeyPress(Sender: TObject; var Key: Char);
var
  C, I: Integer;

begin
  I := Memo1.Perform(EM_LINEFROMCHAR, Memo1.SelStart, 0);
  C := Length(Memo1.Lines[i]);

  if (Key = #13) and (C >= 3) then
    Key := #0;

  if (C >= 3) and (Key <> #8) then
    Memo1.Lines.Insert(I + 1, '');
end;

Pero, por lo que comentas, te reitero que no creo que el Memo sea el componente adecuado. Podrías, por ejemplo, usar un StringGrid con una sola columna editable y una sóla fila editable:

ColCount = 2
RowCount = 2
FixedCols = 1
FixedRows = 1

y el siguiente código en su evento KeyPress:

Código Delphi [-]
procedure TForm1.StringGrid1KeyPress(Sender: TObject; var Key: Char);
var
  C: Integer;

begin
  C := Length(StringGrid1.Cells[StringGrid1.Col, StringGrid1.Row]);

  if (Key = #13) then
  begin
    if StringGrid1.Row = StringGrid1.RowCount - 1 then
      StringGrid1.RowCount := StringGrid1.RowCount + 1;

    StringGrid1.Row := StringGrid1.Row + 1;
  end
  else if (C >= 3) and (Key <> #8) then
    Key := #0;
end;

Con esto, partes de una sóla celda y conforme el usuario oprime ENTER -sin importar si hay uno, dos o tres caracteres- se pasa a la fila siguiente (si era la última fila, se crea una nueva). Tienes mucha más libertad para moverte por entre las celdas si hay que editar algo, sin el riesgo de descuadrar cosas.

La fila y columna fija puedes usarla para poner rótulos, o bien te olvidas de ellas poniendo:

ColCount = 1
RowCount = 1
FixedCols = 0
FixedRows = 0

// Saludos

deprimera 22-11-2008 01:56:36

gracias roman por lo q m enviast hasta ahora

queda algun problemita x resolver

si voy cargando los numeros y hago enter no hay problema
pero si voy con el cursor del mouse a alguna linea q ya tiene datos ingresados, lo borro y vuelvo a escribir m deja renglones entre medio d una linea y otra, y en algunos casos entran cuatro numeros, fijate si podes resolverlo por favor...desde ya graciass

deprimera 22-11-2008 01:57:56

m olvide de decirte q sigo utilizando el memo pq m llevaria mucho tiempo pasar todo a un stringgrid


La franja horaria es GMT +2. Ahora son las 16:17:18.

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