MaskEdit i __9,9_ wygodne formatowanie

0

Poszukiwania najbardziej optymalnej metody wprowadzania liczb zmiennoprzecinkowych do MaskEdit
doprowadziły do uzyskania takiego efektu? Moje pytanie: czy ktoś posiada jeszcze wygodniejsze rozwiązanie dla
operatora wprowadzającego codziennie bardzo wiele danych.

Przykładowy kod: Na form'e umieszczamy MaskEdit1 i MaskEdit2 w pole "EditMask" obu kontrolek wstawiamy: 9999,999
dodatkowo w kontrolkach ustawiamy zdarzenia: OnClick , OnExit , OnKeyPress tak jak na zamieszczonym listingu

 

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    MaskEdit1: TMaskEdit;
    MaskEdit2: TMaskEdit;
    procedure MaskEdit1KeyPress(Sender: TObject; var Key: Char);
    procedure MaskEdit2KeyPress(Sender: TObject; var Key: Char);
    procedure MaskEdit1Exit(Sender: TObject);
    procedure MaskEdit2Exit(Sender: TObject);
    procedure MaskEdit1Click(Sender: TObject);
    procedure MaskEdit2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function FormatujZapisLiczby(Dane: string): string;
const
ZnakiZabronione: set of char = [' ','_']; //Znaki usuwane
var
i,j:   dword;
begin
     Result:='';
     i:=1;
     j:=Length(Dane);
     while j >= i do
     begin
          if not(Dane[i] in ZnakiZabronione) then Result:=Result+Dane[i];
          i:=i+1;
     end;
end;


//UWAGA: Maska musi miec taki format: 9999,99; Niedozwolony jest format 9999,99;0 bo nie zwraca przecinka.
function FormatowanieMaskEdit(Dana: string): string;
var
Liczba,Reszta: string;
Przecinek,i: integer;
begin
     Result:='';
     Przecinek:=Pos(',',Dana);
     Liczba:=Copy(Dana,0,Przecinek-1);
     Reszta:=Copy(Dana,Przecinek+1,Length(Dana));
     Liczba:=FormatujZapisLiczby(Liczba);
     Reszta:=FormatujZapisLiczby(Reszta);
     for i:=1 to (Przecinek-Length(Liczba))-1 do Result:=Result+' ';
     Result:=Result+Liczba+','+Reszta;
     Form1.Caption:=Result;
end;

//Procedura ustawia kursor na poz.0 MaskEdit jesli jest on pusty formatuje dane po obu stronach przecinka.
//UWAGA: Maska musi miec taki format: 9999,99; Niedozwolony jest format 9999,99;0 bo nie zwraca przecinka.
procedure PozycjaKursoraZmiennoprzecinkowe(Sender: TObject);
begin
     //Ustawienie kursora na pozycji zero przy aktywacji pustego pola edycyjnego...

     if Sender is TMaskEdit then
     begin
           with (Sender as TMaskEdit) do
           begin
                if (FormatujZapisLiczby(Text) = '') or (FormatujZapisLiczby(Text) = ',') then
                begin
                     SelStart:=0;
                     SelLength:=1;
                end;
           end;
     end;
end;




procedure TForm1.MaskEdit1KeyPress(Sender: TObject; var Key: Char);
begin
     //Po enter przechodzimy do kolejnej kontrolki.
     case Key of
          #13: begin
                    Perform(WM_NEXTDLGCTL,0,0);
                    Key:=#0;
               end;
          ',': begin
                    (Sender as TMaskEdit).Text:=FormatowanieMaskEdit((Sender as TMaskEdit).Text);
               end;
     end;

end;

procedure TForm1.MaskEdit2KeyPress(Sender: TObject; var Key: Char);
begin
     //Po enter przechodzimy do kolejnej kontrolki.
     case Key of
          #13: begin
                    Perform(WM_NEXTDLGCTL,0,0);
                    Key:=#0;
               end;
          ',': begin
                    (Sender as TMaskEdit).Text:=FormatowanieMaskEdit((Sender as TMaskEdit).Text);
               end;
     end;

end;

procedure TForm1.MaskEdit1Exit(Sender: TObject);
begin
     (Sender as TMaskEdit).Text:=FormatowanieMaskEdit((Sender as TMaskEdit).Text);

end;

procedure TForm1.MaskEdit2Exit(Sender: TObject);
begin
     (Sender as TMaskEdit).Text:=FormatowanieMaskEdit((Sender as TMaskEdit).Text);

end;

procedure TForm1.MaskEdit1Click(Sender: TObject);
begin
     PozycjaKursoraZmiennoprzecinkowe(Sender);

end;

procedure TForm1.MaskEdit2Click(Sender: TObject);
begin
     PozycjaKursoraZmiennoprzecinkowe(Sender);

end;

end.

0

czy ktoś posiada jeszcze wygodniejsze rozwiązanie dla
operatora wprowadzającego codziennie bardzo wiele danych.

Nie no normalnie mam deja vu! Ktoś tutaj niedawno o to pytał!

MaskEdit i masakra
Ktoś ma bardzo podobny nick i pytania do Ciebie. Odpowiedzi też będą bardzo podobne, więc niepotrzebnie pytasz.

czy da sie temu jakoś zaradzić ?
albo czy da się to tak formatować aby nawet znak _ nie był wstawiany?

Da się. Aż dziwne że nie pytasz jak to zrobić.

0
tester_68k napisał(a)

Poszukiwania najbardziej optymalnej metody wprowadzania liczb zmiennoprzecinkowych do MaskEdit
doprowadziły do uzyskania takiego efektu?

Jakiego efektu...?

tester_68k napisał(a)

Moje pytanie: czy ktoś posiada jeszcze wygodniejsze rozwiązanie dla
operatora wprowadzającego codziennie bardzo wiele danych.

Nie dałeś żadnego źródła, które można by sprawdzić w domku, stąd ciężko powiedzieć co to za efekt i w jaki sposób można zrobić to wygodniej (bo pytanie czy da się nie jest na miejscu);

tester_68k napisał(a)

Przykładowy kod: Na form'e umieszczamy MaskEdit1 i MaskEdit2 w pole "EditMask" obu kontrolek wstawiamy: 9999,999
dodatkowo w kontrolkach ustawiamy zdarzenia: OnClick , OnExit , OnKeyPress tak jak na zamieszczonym listingu

Nic mi to nie mówi i widząc ten kod jakoś nie chce mi się go analizować... Może lepiej napisz jaki efekt Cię interesuje a będzie można łatwiej odpowiedzieć na Twoje pytania;


A tak na marginesie:

function FormatujZapisLiczby(Dane: string): string;
const
ZnakiZabronione: set of char = [' ','_']; //Znaki usuwane
var
i,j:   dword;
begin
     Result:='';
     i:=1;
     j:=Length(Dane);
     while j >= i do
     begin
          if not(Dane[i] in ZnakiZabronione) then Result:=Result+Dane[i];
          i:=i+1;
     end;
end;

pętla for się kłania... A tak poza tym, po co zmienne są typu DWORD? Nie wystarczy Byte?:

function FormatujZapisLiczby(Dane: String): String;
var
  I: Byte;
begin
  Result := '';

  for I := 1 to Length(Dane) do
    if not (Dane[I] in [' ', '_']) then
      Result := Result + Dane[I];
end;

Prawda, że prościej...?


Skoro już tutaj jestem i jednak analizuję ten kod, to postaram Ci podpowiedzieć w jaki sposób można go skrócić;

Zoptymalizowana procedura PozycjaKursoraZmiennoprzecinkowe (naucz się proszę angielskiego i sensownie nazywaj identyfikatory...):

procedure PozycjaKursoraZmiennoprzecinkowe(Sender: TObject);
var
  sResult: String;
begin
  if Sender is TMaskEdit then
    with TMaskEdit(Sender) do
      begin
        sResult := FormatujZapisLiczby(Text);

        if (sResult = ' ') or (sResult = '.') then
          begin
            SelStart := 0;
            SelLength := 1;
          end;
      end;
end;

Dlaczego tak? Bo wywoływałeś ją dwa razy, zamiast dać się jej wykonać raz i przechwycić wartość do zmiennej, po czym ją srawdzić;


Dalej, zdarzenie OnKeyPress kontrolki:

procedure TForm1.MaskEdit1KeyPress(Sender: TObject; var Key: Char);
begin
  case Key of
    #13: begin
           Perform(WM_NEXTDLGCTL, 0, 0);
           Key := #0;
         end;

    #44: TMaskEdit(Sender).Text := FormatowanieMaskEdit(TMaskEdit(Sender).Text);
  end;
end;

nie musisz w kółko wykorzystywać operatora as - stosuj śmiało rzutowanie;


Ostatnie odnosi się do wykorzystywania tych samych procedur/funkcji w ciele zdarzeń obu kontrolek:

procedure TForm1.MaskEdit1Exit(Sender: TObject);
begin
     (Sender as TMaskEdit).Text:=FormatowanieMaskEdit((Sender as TMaskEdit).Text);
end;
 
procedure TForm1.MaskEdit2Exit(Sender: TObject);
begin
     (Sender as TMaskEdit).Text:=FormatowanieMaskEdit((Sender as TMaskEdit).Text);
end;

Po co piszesz to dwa razy? Wystarczy raz:

procedure TForm1.MaskEdit1Exit(Sender: TObject);
begin
  TMaskEdit(Sender).Text := FormatowanieMaskEdit(TMaskEdit(Sender).Text);
end;

a następnie w Inspektorze Obiektów wybrać to samo zdarzenie dla drugiej kontrolki; Poza tym taka konstrukcja jest beznadziejna, lepiej zmień funkcję FormatowanieMaskEdit na procedurę i przekazuj kontrolkę jako argument żeby nie kombinować ze zwracaniem wartości, mógłbyś ją wykorzystać np. tak:

procedure TForm1.MaskEdit1Exit(Sender: TObject);
begin
  FormatowanieMaskEdit(TMaskEdit(Sender));
end;

To samo tyczy się zdarzeń TForm1.MaskEdit1Click i TForm1.MaskEdit2Click oraz TForm1.MaskEdit1KeyPress i TForm1.MaskEdit2KeyPress;

1 użytkowników online, w tym zalogowanych: 0, gości: 1