Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Como dar formato numerico StringGrid (https://www.clubdelphi.com/foros/showthread.php?t=81677)

JAI_ME 06-12-2012 19:47:20

Como dar formato numerico StringGrid
 
Buenas tardes tengo un TstringGrid y guardo información numérica en sus celdas.

Quiero que el usuario pueda escribir en una celda normalmente pero cuando salga o teclee enter automáticamente en esa celda tome el formato numérico, para dar formato a un texto uso la funcion formatFloat('#0,.00',Numero); pero necesito detectar el momento en que el usuario sale de esa celda para dar el respectivo formato.

He intentado en el evento SetEditText pero no lo he conseguido porque este evento se ejecuta también cada vez que dígito un valor.

En otras palabras, quiero algo parecido a excel cuando el usuario quiere edita la información de una celda numérica y sale de la celda esta toma el formato numérico.

gracias.

movorack 06-12-2012 20:01:50

Hola JAI_ME

Esto lo puedes hallar en la documentación de delphi



O en línea en la wiki de embarcadero
http://docwiki.embarcadero.com/CodeE...tMask_(Delphi)
Código Delphi [-]
procedure TForm1.FormCreate(Sender: TObject);
begin
  StringGrid1.Cells[2, 0]:= 'Phone Number';
end;
 
procedure TForm1.StringGrid1GetEditMask(Sender: TObject; ACol, ARow: Longint; var Value: string);
begin
  if StringGrid1.Cells[ACol, 0] = 'Phone Number' then
    Value :=  '!\(999\)000-0000;1';
end;

JAI_ME 06-12-2012 21:02:44

Gracias por su respuesta, pero quisiera encontrar otra solución sin usar ese evento (GetEditMask), ya que visualmente se ve mal estructurado cuando pongo por ejemplo en una celda pongo un dígito y en la otra 7 dígitos, queda desorganizado. no se le ve orden.

Quizas me puedan ayudar a detectar cuando un usuario sale de una celda ???

ecfisa 06-12-2012 23:40:39

Cita:

Empezado por JAI_ME (Mensaje 451373)
...
Quizas me puedan ayudar a detectar cuando un usuario sale de una celda ???

Hola JAI_ME.

Cuando un usuario sale de una celda de un TStringGrid, existen dos posibilidades. Que lo haga para ingresar en otra, en cuyo caso se dispara el evento OnSelectCell, o para darle el foco a otro control en cuyo caso se dispara el evento OnExit.

Si no entendí mal lo que estas buscando tal vez te sirva de este modo:
Código Delphi [-]
  ...
  private
     FC: TPoint;
  end;
  ...

implementation

procedure TForm1.FormCreate(Sender: TObject);
begin
  FC.X := 0;
  FC.Y := 0;
end;

procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
  var CanSelect: Boolean);
var
  Nro: Double;
begin
  with TStringGrid(Sender) do
   if TryStrToFloat(Cells[FC.X,FC.Y], Nro) then
     Cells[FC.X,FC.Y]:= FormatFloat('#0,.000',Nro);
  FC.X := ACol;
  FC.Y := ARow;
end;

procedure TForm1.StringGrid1Exit(Sender: TObject);
var
  Nro: Double;
begin
  with TStringGrid(Sender) do
   if TryStrToFloat(Cells[FC.X,FC.Y], Nro) then
     Cells[FC.X,FC.Y]:= FormatFloat('#0,.000',Nro);
end;

Saludos.

ozsWizzard 07-12-2012 12:21:48

Yo me creé el evento "OnExitCell" para tratar importes también, a la vez me creé el evento "OnKeyPressCell" no sólo para formatear los importes al salir, sino para que sólo deje meter números y el separador decimal. Aparte, con el "Enter" simula el pulsado del "F2" pero eso se puede quitar.

El evento "OnKeyPressCell", realmente no hace falta pero es por si quieres separarlo del OnKeyPress normal.

Definición
Código Delphi [-]
  TExitCell = procedure(Sender: TObject; const ACol, ARow: Integer) of object;
  TKeyPressCell = procedure(Sender: TObject; const ACol, ARow: Integer; var Key: Char) of object;

  TStringGrid = class(Vcl.Grids.TStringGrid)
      private
         FCol:    Integer;
         FRow:    Integer;
         FEntrar: Boolean;
         EditCel: Boolean;

         FExitCell:    TExitCell;
         FKeyPressCell: TKeyPressCell;
      protected
         function SelectCell(ACol, ARow: LongInt): Boolean; override;

         procedure DoEnter; override;
         procedure DoExit; override;
         procedure KeyDown(var Key: Word; Shift: TShiftState); override;
         procedure KeyPress(var Key: Char); override;
      public
         property ColAux: Integer read FCol    write FCol    default 0;
         property RowAux: Integer read FRow    write FRow    default 0;
         property Entrar: Boolean read FEntrar write FEntrar;

         //Eventos
         property OnExitCell: TExitCell       read FExitCell    write FExitCell; //Este va a ser el evento OnExitCell
         property OnKeyPressCell: TKeyPressCell read FKeyPressCell write FKeyPressCell;
  end;

Implementación
Código Delphi [-]
{ TStringGrid }

procedure TStringGrid.DoEnter;
begin
   inherited;
   ColAux := Col;
   RowAux := Row;
   Entrar := true;
end;

procedure TStringGrid.DoExit;
begin
   if Assigned(OnExitCell) then OnExitCell(Self, ColAux, RowAux);
   inherited;
end;

procedure TStringGrid.KeyDown(var Key: Word; Shift: TShiftState);
begin
   if Key = VK_RETURN then
   begin
      if not EditCel then
      begin
         keybd_event(VK_F2, 0, 0, 0);
         keybd_event(VK_F2, 0, KEYEVENTF_KEYUP, 0);

         Key := 0;

      end;
      EditCel := not EditCel;
   end;
   inherited;
end;

procedure TStringGrid.KeyPress(var key: Char);
begin
   if Assigned(OnKeyPressCell) then OnKeyPressCell(Self, ColAux RowAux, Key);
   inherited;
end;

function TStringGrid.SelectCell(ACol, ARow: LongInt): Boolean;
begin
   //Para no repetir el evento OnExitCell cuando se entra al StringGrid
   if Entrar then
      Entrar := false
   else
      if Assigned(OnExitCell) then OnExitCell(Self, ColAux, RowAux);
   inherited;
   ColAux := ACol;
   RowAux := ARow;

   EditCel := false;
   Result := true;
end;

Programación y asignación de eventos para Float (más bien Currency)
sq1 sería el TStringGrid
Código Delphi [-]
//Evento Keypress para los datos float
procedure sgFloatKeyPress(Sender: TObject; const ARow: Integer;
  var Key: Char);
begin
   if not (Key in [#9, #13]) then
   begin
      if (key = ',') or (key='.') then
         key := DecimalSeparator;
      if not ( ((key >= '0') and (key <= '9')) or (key=#8) or (key=DecimalSeparator) ) then
         key := #0
      else if (key = DecimalSeparator ) and (AnsiPos(DecimalSeparator,text)<>0) then
         key := #0;
   end;
end;

//Se implementa OnExitCell
procedure Form1.sg1ExitCell(Sender: TObject; const ACol,
  ARow: Integer);  
var
  sg: TStringGrid;
begin
   sg := (Sender as TStringGrid);
   //Esto es para formatear, siempre puedes poner más cosas en el evento si lo ves necesario
   //Sólo se formatean los campos que sabemos que son Float o Currency, en este caso son las columnas 1, 2 y 3 y que no sea la fila 0
   if (ARow > 0) and (ACol in [1, 2, 3]) then
      if (sg.Cells[ACol, ARow] <> EmptyStr) then
         sg.Cells[ACol, ARow] := FormatFloat('#,#0.#0', StrToCurr(sg.Cells[ACol, ARow]));
end;

procedure Form1.sg1SelectCell(Sender: TObject; ACol, ARow: Integer;
  var CanSelect: Boolean);
begin
   //Se asigna el evento para los campos tipo importe, como en el evento anterior son las columnas 1, 2 y 3 y que no sea la fila 0
   if (ARow > 0) and (ACol in [1, 2, 3]) then
      TStringGrid(Sender).OnKeyPressCell := sgFloatKeyPress
   else
      TStringGrid(Sender).OnKeyPressCell := nil;
end;

procedure Form1.FormCreate(Sender: TObject);
begin
    sg1.OnExitCell := sg1ExitCell;
end;

Espero que te sirva


La franja horaria es GMT +2. Ahora son las 10:57: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