Solved

Formatting Numeric Values

Posted on 2001-07-05
17
306 Views
Last Modified: 2010-04-06
What will I do to right align numeric values in a textbox.
I want the numbers keyed in to be right aligned and  seperated with commas.

For Example 50000 should appear as 50,000 right aligned.

Please help.
0
Comment
Question by:lgodash_
  • 8
  • 5
  • 2
  • +2
17 Comments
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
for formatting

see about

floattostrf()

in your delphi-helpfile
0
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
stolen from barry(inthe) a component, where the alignmetn could be done

(hopefully barry is not cutting my head from my shoulders)

unit AlignEdit;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls;

type
 TEditAlign = class(TEdit)
 private
   { Private declarations }
 f_alignment: TAlignment;
 protected
   { Protected declarations }
   procedure CreateParams(var params:TCreateParams); override;
 procedure SetAlignment(value: TAlignment);
public
   { Public declarations }
constructor Create(AOwner: TComponent); override;
 published
   { Published declarations }
property Alignment:TAlignment read f_alignment write SetAlignment;

 end;

procedure Register;

implementation
constructor TEditAlign.Create(AOwner: TComponent);
begin
 inherited create(AOwner);
 end;

procedure TEditAlign.SetAlignment(value: TAlignment);
begin
 if value<>f_alignment then begin
   f_alignment:=value;
   recreatewnd;
   end;
 end;

procedure TEditAlign.CreateParams(var params:TCreateParams);
const
   Alignments : array[TAlignment] of Longint = (ES_LEFT, ES_RIGHT, ES_CENTER);
begin
inherited CreateParams(Params);
Params.Style := Params.Style or Alignments[F_Alignment] or ES_MULTILINE;
 end;
procedure Register;
begin
 RegisterComponents('Samples', [TEditAlign]);
end;

end.

meikl ;-)
0
 
LVL 22

Expert Comment

by:mnasman
Comment Utility
showmessage (FormatFloat('#,##',50000));
0
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
mnasman,

should it not be
showmessage (FormatFloat('#,##0',50000));

meikl ;-)
0
 
LVL 22

Expert Comment

by:mnasman
Comment Utility
Edit1.BiDiMode := bdRightToLeft;
Edit1.text := FormatFloat('#,##',50000)
0
 
LVL 1

Expert Comment

by:alx512
Comment Utility
unit NumberEdit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TNAlignment = (naDefault, naLeftJustify, naRightJustify, naCenter);
  TValueType = (vtInteger, vtDouble, vtCurrency);

  TNumberEdit = class(TEdit)
  private
    { Private declarations }
    FDisplayMask: String;
    FAllowText: Boolean;
    FAlignment: TNAlignment;
    FVarValue: Variant;
    FValueType: TValueType;
    FShowZero: Boolean;
    function  GetValue: Variant;
    procedure SetValue(Value: Variant);
    procedure SetValueType(Value: TValueType);
    procedure SetDisplayMask(Value: String);
    procedure SetAllowText(Value: Boolean);
    procedure SetAlignment(Value: TNAlignment);
    procedure SetShowZero(Value: Boolean);
  protected
    { Protected declarations }
    //procedure WMKeyDown(var Message: TWMKey); message WM_KEYDOWN;
    procedure KeyPress(var Key: Char); override;
    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
    procedure CMEnter(var Message: TCMGotFocus); message CM_ENTER;
    procedure CMExit(var Message: TCMLostFocus); message CM_EXIT;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
  published
    { Published declarations }
    property Value: Variant read GetValue write SetValue;
    property ValueType: TValueType read FValueType write SetValueType;
    property DisplayMask: String read FDisplayMask write SetDisplayMask;
    property AllowText: Boolean read FAllowText write SetAllowText;
    property Alignment: TNAlignment read FAlignment write SetAlignment;
    property ShowZero: Boolean read FShowZero write SetShowZero;
  end;

procedure Register;

implementation

constructor TNumberEdit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FValueType := vtDouble;
  FVarValue := 0;
end;

procedure TNumberEdit.SetValueType(Value: TValueType);
begin
  FValueType := Value;
  SetValue(FVarValue);
end;

function TNumberEdit.GetValue: Variant;
var
  S: Variant;
begin
  S := Text;
  try
    if S = '' then
      case FValueType of
        vtInteger : FVarValue := VarAsType(0, varInteger);
        vtDouble  : FVarValue := VarAsType(0, varDouble);
        vtCurrency: FVarValue := VarAsType(0, varCurrency);
      end
    else
      try
        case FValueType of
          vtInteger : VarCast(FVarValue, S, varInteger);
          vtDouble  : VarCast(FVarValue, S, varDouble);
          vtCurrency: VarCast(FVarValue, S, varCurrency);
        end;
      except
        case FValueType of
          vtInteger : FVarValue := VarAsType(0, varInteger);
          vtDouble  : FVarValue := VarAsType(0, varDouble);
          vtCurrency: FVarValue := VarAsType(0, varCurrency);
        end;
      end;
  finally
    Result := FVarValue;
  end;
end;

procedure TNumberEdit.SetValue(Value: Variant);
begin
  case FValueType of
    vtInteger : FVarValue := VarAsType(Value, varInteger);
    vtDouble  : FVarValue := VarAsType(Value, varDouble);
    vtCurrency: FVarValue := VarAsType(Value, varCurrency);
  end;
  Text := VarToStr(FVarValue);
end;

procedure TNumberEdit.SetDisplayMask(Value: String);
begin
  FDisplayMask := Value;
  Invalidate;
end;

procedure TNumberEdit.SetAllowText(Value: Boolean);
begin
  FAllowText := Value;
  Invalidate;
end;

procedure TNumberEdit.SetAlignment(Value: TNAlignment);
begin
  FAlignment := Value;
  Invalidate;
end;

procedure TNumberEdit.SetShowZero(Value: Boolean);
begin
  FShowZero := Value;
  Invalidate;
end;

procedure TNumberEdit.CMEnter(var Message: TCMGotFocus);
begin
  inherited;
  Invalidate;
end;

procedure TNumberEdit.CMExit(var Message: TCMLostFocus);
begin
  inherited;
  Invalidate;
end;


function FormatFloatEx(const Format: string; Value: Extended): string;
var
  i, j: Integer;
  Buffer: array [0..255] of Char;
  Leading: Boolean;
begin
  j:=0;
  Leading := True;
  Result := FormatFloat(Format, Value);
  for i:=1 to Length(Result) do
    if not ((Result[i] in [#32, #160]) and Leading) then
    begin
      if Leading and (Result[i] <> '-') then Leading := False;
      Buffer[j] := Result[i];
      Inc(j);
    end;
  Buffer[j] := #0;
  Result := StrPas(Buffer);
end;

procedure TNumberEdit.KeyPress(var Key: Char);
var
  P: Integer;
begin
  if (Key >= #32) and not FAllowText then
  begin
    if not (Key in ['.', ',' ,'-', '0'..'9']) then
    begin
      Key := #0;
      Exit;
    end;
    if (Key = '-') and ((Pos(Key, Text) <> 0 ) or (GetSelStart <> 0))then
    begin
      Key := #0;
      Exit;
    end;
    if (Key in ['.', ',']) then
    begin
      P := Pos(DecimalSeparator, Text);
      if (P = 0) or ((P >= SelStart) and (P <= SelStart+SelLength)and (SelLength>0)) then
         Key := DecimalSeparator
      else
      begin
        Key := #0;
        Exit;
      end;
    end;
  end;
  inherited;
end;

procedure TNumberEdit.WMPaint(var Message: TWMPaint);
var
  s: String;
  f: Extended;
  DC: HDC;
  Paint: TPAINTSTRUCT;
  Size: TSIZE;
  Brush: HBRUSH;
  A: TNAlignment;
  L: Integer;
  IsNumber: Boolean;
begin
  F := 0;
  if Focused then
  begin
    inherited;
    Exit;
  end;
  DC := BeginPaint(Handle, Paint);
  try
    IsNumber := False;
    Brush := CreateSolidBrush(GetNearestColor(DC, ColorToRGB(Color)));
    SelectObject(DC, Font.Handle);
    SetBkColor(DC, GetNearestColor(DC, ColorToRGB(Color)));
    SetTextColor(DC, GetNearestColor(DC, ColorToRGB(Font.Color)));
    FillRect(DC, ClientRect, Brush);
    if TextToFloat(PChar(Text), f, fvExtended) then
    begin
      IsNumber := True;
      if (f = 0) and not ShowZero then
        s := '' else
        s := FormatFloatEx(FDisplayMask, f);
    end
    else S := Text;
    GetTextExtentPoint32(DC, PChar(S), Length(S), Size);
    if FAlignment <> naDefault then
      A := FAlignment
    else
      if IsNumber then A := naRightJustify  else A := naLeftJustify;
    case A of
      naLeftJustify :  L := 1;
      naRightJustify:  L := ClientWidth - 1 - Size.cx;
      naCenter      :  L := (ClientWidth - Size.cx) shr 1;
      else L := 2;
    end;
    TextOut(DC, L, 1, PChar(s), Length(S));
    DeleteObject(Brush);
  finally
    EndPaint(Handle, Paint);
  end;
end;


procedure Register;
begin
  RegisterComponents('Others', [TNumberEdit]);
end;

end.
0
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
puh alx512,

haust ganz schon auf den putz,

but its perfect

meikl ;-)
0
 
LVL 1

Accepted Solution

by:
h_mohsenian earned 50 total points
Comment Utility
I Think You Want Change Number Format to Comma format Just when User Types His Number ( OnLine Format Change ).

If thats the point . You Can write this Code in OnChange event in TEdit :

procedure TForm1.Edit1Change(Sender: TObject);
var
  Err, TSS : integer;
  L1, L2, DL : integer;
  s : string;
  V : Real;
begin
  S := (Sender as TEdit).Text;
  L1 := Length(S); // Save Length Before Change
  TSS := Edit1.SelStart; // Save SelStart Before Change
  DelComma(S);
  val(S,V,Err);
  if Err = 0 then
    (Sender as TEdit).Text := GetCommaFormat(S);
  L2 := Length((Sender as TEdit).Text); // Length After Change
  DL := L2-L1; // Change in Length
  (Sender as TEdit).SelStart := TSS+DL;
end;

for Making GetCommaFormat function & DelComma Proc , You Can Write The Best Code . But a Code Can be :

// private :
// ---------
procedure TForm1.DelComma(var S : String);
begin
  while pos(',',S) > 0 do
    Delete(S,pos(',',S),1);
end;

function TForm1.GetCommaFormat( S : String ) : String;
var p, c, i : word; NewS : String;
begin
  p := pos('.',S);
  if p <> 0 then
    S := copy(S,1,p-1);
  c := 0;
  for i := length(S) downto 1 do
  begin
    inc(c);
    if (c = 3) then
    begin
      c := 0;
      NewS := ','+copy(S,i,3)+News;
    end;
  end;
  if c = 0 then
    Delete(News,1,1)
  else
    NewS := Copy(S,1,c) + NewS;
  Result := News;
end;


If I Didnt Understand Your Problem Please Tell me.
0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
h_mohsenian,
must that be an answer?

why not use just a comment,
because others have provided solutions/suggestions
before you, even your answer solves the question only partial. what about the alignment?

meikl ;-)
0
 
LVL 1

Expert Comment

by:h_mohsenian
Comment Utility
dear kretzschmar,

you are right I Said Only about ane section of the problem.

but about another issue : < alignment >

There Is One Protected Method In TCustomEdit Class and Its Name Is 'CreateParams'. He(She) must Make a New Component for Example RightEdit and write This Code In That :

// protected method
procedure TRightEdit.CreateParams(var Params: TCreateParams);
  { We add One More behavior :
    < RightJustify >
    That is becuse we like to begine from Right }
Begin;
  inherited CreateParams(Params);
  Params.Style := Params.Style or ES_RIGHT ;
  // This Chanes alignment to right
end;

Ok but about that you wrote :
 1. I dont understand the meaning of <must that be an answer?> that you Said.

 2. You Are Right The Changing Format to CommaFormat as you and mnasman said <FormatFloat> can be good. but I wrode that code only for test my solution and I told lgodash that It is only a sample code.

 3. about Algorithm ! you are right but We Can Clear My COde To Make Good Solution.

 4. Please Tell me do you accept My Code.

Hamed
0
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
hi hamed,

to 1.
more meant: why do you post an answer?
>others have provided solutions/suggestions
>before you, even your answer solves the question only
>partial

well don't know if you aware of that the questioner can grade a comment, which most matches its needs so long as no answer is posted. so that you post now an answer the questioner have first to reject your answer (if your answer not matches its needs) and grade the comment, which matches its need better. but some questioners, do just grade a given answer, even they use a solution of a comment from another expert. this may frustrating the experts, so that they leave the ex-ex community.

so i do a recommendation to all: just post comments,
and i'm sure i go with this in the ex-ex meaning of community.

to 2.
this suggestions may better match the questioners needs as your answer. but this decission obtains only the questioner. see 1.

to 3.
don't know what you mean

to 4.
teh acceptance obtains also the questioner, if your answer is usefull for the questioner, then mostly the questioner let you know this.

hamed,
this is not meant as offense

hopefully you understand my position

meikl ;-)
0
 
LVL 1

Expert Comment

by:h_mohsenian
Comment Utility
hi meikl,

thanks for your recommendations.

I send an e-mail to meikl@spektracom.de(I Didnt know is that your main active email now) and answerd your question ( Like <more meant: why do you post an answer?> ).
becouse I think It was boring for Experts in this community.

by
hamed
0
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
hi hamed,

mail received me, have answered.
and no, you're not boring.

your code seems to be ok,
and does format the text on the fly,
and maybe this is exact that what igodash needs.

meikl ;-)
0
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
igodash, are you here?
0
 

Author Comment

by:lgodash_
Comment Utility
Sorry I was away for sometime.
The Comment from alx512 was just perfect. I have tried it out and it is just what I needed.

All the other comments were helpful. That from Kretzschmar was also good.

You've been very helpful.

Thanks.

0
 
LVL 1

Expert Comment

by:h_mohsenian
Comment Utility
hi lgodash,

I cant understand! ;-) is it your mistake to push accept button!? you accept my comment(h_mohsenian) but you said just alx512 comment was perfect ;-)

any way .if u like ,please tell me your idea about my code.( just for help me. as you see I & Kretzschmar have some discussions about my code.)

best regards
hamed ( h_mohsenian )

0
 
LVL 1

Expert Comment

by:h_mohsenian
Comment Utility
hi lgodash,

you said just alx512 was perfect ( although u accept my comment(h_mohsenian) . maybe it is ur mistake for push accept button )

any way .if u like ,please tell me your idea about my code.( just for help me.as you see I & Kretzschmar had some discussions about my code and your exact need.)

best regards
hamed ( h_mohsenian ) ;-)

0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Suggested Solutions

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now