Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Запятая вместо точки


Автор: ivan219 18.12.2005, 09:47
Здравствуйте.

Есть компонент Edit1 мне внего нужно писать только цифры и запятую преобразование из знаков в цифры делаю препомощи (R1:=StrToFloat(Edit1.Text);) так вот если в водить число (12,23) то всё ОК а если (12.23) то вознекает ошибка.

Вопрос: как зделать так чтоб при нажатии на ( . ) в окне Edit1 поевлялась ( , ) и ошибки небыло.

Автор: Albinos_x 18.12.2005, 10:10
Код

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if not (key in ['0'..'9',#8,',','.']) then
   key:=#0
   else
   begin
   if key='.' then
      key:=',';
   end;
end;

Автор: Демо 18.12.2005, 14:27
Albinos_x

Подправлю.

Код

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
    case Key of
      '0'..'9',#8: ;
      ',','.': Key := DecimalSeparator;
      else key := #0;
    end;
end;

Автор: Albinos_x 18.12.2005, 15:23
тот же икс, только вид сбоку smile

Автор: Snowy 18.12.2005, 15:25
Цитата(Albinos_x @ 18.12.2005, 15:23)
тот же икс, только вид сбоку

За исключением
Цитата(Albinos_x @ 18.12.2005, 15:23)
DecimalSeparator;

Это правильнее.

Автор: Albinos_x 18.12.2005, 15:58
Цитата(Snowy @ 18.12.2005, 15:25)
Это правильнее.

единственное.... но результат будет тот же...

Автор: DeadSoul 18.12.2005, 16:11
А если я вставлю эту запятую\точку нажав Ctrl+v? ;) Код будет работать?
По мне наилучший вариант - замена . на , при получение текста данного едита

P.S. Я знаю, что я зануда.

Автор: Демо 18.12.2005, 16:13
Цитата(Albinos_x @ 18.12.2005, 16:58)
единственное.... но результат будет тот же...


Если только в системе разделитель тот же самый. А если нет, то результат будет другой ;)

Вопрос настолько уже избит везде, что даже не знаю, сколько раз можно на него отвечать-))

Автор: Albinos_x 18.12.2005, 16:35
Цитата
А если нет,

ет точно, но если честно, то я с этим не разу не сталкивался...

Автор: Romikgy 19.12.2005, 15:46
Цитата(DeadSoul @ 18.12.2005, 16:11)
А если я вставлю эту запятую\точку нажав Ctrl+v?
Здеся нужен обработчик onChanged (кажется так правильно), а выше приведенный код только для нажитий на батоны клавы!

Автор: Guest 20.12.2005, 18:32
Всем спасибо smile

Автор: TwisT_X 20.12.2005, 18:50
А я вообще не догнал что такое DecimalSeparator подскажите..

Автор: Snowy 20.12.2005, 18:55
Цитата(TwisT_X @ 20.12.2005, 18:50)
что такое DecimalSeparator подскажите..

Это точка, запятая или что угодно, что явняется разделителем целой и дробной части, согласно настроек системы.

Добавлено @ 18:56
Я могу установить в качестве разделителя слово "хвост" и у меня не будет работать ни точка не запятая, а вот DecimalSeparator будет.

Автор: TwisT_X 20.12.2005, 19:01
Snowy спосибо надо будет запомнить..?.

Автор: Alex 20.12.2005, 20:53
Цитата(Snowy @ 20.12.2005, 18:55)
Я могу установить в качестве разделителя слово "хвост" и у меня не будет работать ни точка не запятая, а вот DecimalSeparator будет.

Горячиться не нужно DecimalSeparator - это Char. Так, что можно только 1 символ поставить.

Автор: Guest 20.12.2005, 22:05
ivan219

Работает всем спасибо.

Автор: TwisT_X 20.12.2005, 22:26
все таки а чем не подходить простая замена

Автор: Albinos_x 20.12.2005, 22:55
Цитата(TwisT_X @ 20.12.2005, 22:26)
все таки а чем не подходить простая замена



Цитата(Snowy @ 20.12.2005, 18:55)
Это точка, запятая или что угодно, что явняется разделителем целой и дробной части, согласно настроек системы.


Автор: TwisT_X 21.12.2005, 16:55
Albinos_x а ну да.. все ясно..

Автор: ivan219 15.1.2006, 03:00
Этот процедура делает возможным в компоненте Edit писать только цифры 0...9 ставить только одну запетую и ползоватся клавишей Backspace <---

Код


// Пресвоить всем Edit событие OnKeyPress

procedure TForm1.EditKeyPress(Sender: TObject; var Key: Char);
var  A: String;
begin
 A:=(Sender as TEdit).Text;
 case Key of
  '0'..'9',#8:;
  ',','.':
   begin
    if pos(',',A)=0 then Key := DecimalSeparator;
    if pos(',',A)>0 then Key := #0;
   end;
  else
   Key := #0;
  end;
end;


smile

Автор: ivan219 15.1.2006, 17:46
Так это я его и дописал из несколких которые вы мне дали, сночало был
Код

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);    
begin    
    case Key of    
      '0'..'9',#8: ;    
      ',','.': Key := DecimalSeparator;    
      else key := #0;    
    end;    
end;


Внём было две проблемы первая это возможность ставить больше чем одна запетая а это не правильно так что я перестраховался чтоб проблем небыло что разве это плохо когда код доведён до ума smile
Вторая это много проуедур скажем есть уменя 6 штук Edit и что мне для каждого пришлось писать
Код

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);        
begin    
 case Key of    
  '0'..'9',#8:;    
  ',','.':    
   begin    
    if pos(',',Edit1)=0 then Key := DecimalSeparator;    
    if pos(',',Edit1)>0 then Key := #0;    
   end;    
  else    
   Key := #0;    
  end;    
end;


Это тоже не выход 6 лишних процедур дополнительный код место и.т.д.

Вот я и зделал одну.
Код

// Пресвоить всем Edit событие OnKeyPress    
procedure TForm1.EditKeyPress(Sender: TObject; var Key: Char);    
var  A: String;    
begin    
 A:=(Sender as TEdit).Text;    
 case Key of    
  '0'..'9',#8:;    
  ',','.':    
   begin    
    if pos(',',A)=0 then Key := DecimalSeparator;    
    if pos(',',A)>0 then Key := #0;    
   end;    
  else    
   Key := #0;    
  end;    
end;


А если где встречалась так это хорошо, вот только почемуто мне самому прешось до этого дойти и слова критики в свой адрес я считаю не провомерными так как я для других токихже как я сторался чтоб потом было проше.

Автор: Демо 16.1.2006, 04:34
Цитата(ivan219 @ 15.1.2006, 18:46 Найти цитируемый пост)

Вот я и зделал одну.


Правильно будет работать, только если разделитель - запятая.

Вот тебе еще вариант ;)

Код

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin

    case Key of
        '0'..'9',#8:;
        ',','.':
            begin
                if Pos(DecimalSeparator,TEdit(Sender).Text)>0
                    then Key := #0
                    else Key := DecimalSeparator;
            end;
    else Key := #0;
    end;
end;


Автор: ivan219 16.1.2006, 18:09
Да вобще по уневерсальнее.

Есть ещё вопрос как реализовать копирование т.е. есть 12.12 при такой записи будет ошибка надо автоматически зделать из 12.12 -> 12,12 когда копируеш из другого места smile

Автор: Демо 16.1.2006, 21:06
Цитата(ivan219 @ 16.1.2006, 19:09)
Да вобще по уневерсальнее.

Есть ещё вопрос как реализовать копирование т.е. есть 12.12 при такой записи будет ошибка надо автоматически зделать из  12.12 -> 12,12 когда копируеш из другого места smile

Обработать в OnChange ?

Автор: ivan219 16.1.2006, 22:35
А по конкретнее как smile

Автор: Демо 16.1.2006, 22:45
Код

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
    case Key of
        '0'..'9',#8:;
        ',','.':
            begin
                if Pos(DecimalSeparator,TEdit(Sender).Text)>0
                    then Key := #0
                    else Key := DecimalSeparator;
            end;
    else Key := #0;
    end;
end;

procedure TForm1.Edit1Change(Sender: TObject);
var
  i: integer;
  isSeparator: Boolean;
  s: String;
begin
  isSeparator := False;
  s := TEdit(Sender).Text;
  for i := 1 to Length(s) do
  begin
    case TEdit(Sender).Text[i] of
        '0'..'9',#8: Continue;
        ',','.':
            begin
                if isSeparator then Abort;
                s[i] := DecimalSeparator;
                isSeparator := True;
            end;
    else Abort;
    end;
  end;
  TEdit(Sender).Text := s;
end;

Автор: ivan219 16.1.2006, 23:03
Во спасибо smile

А как реализовать буфер обмена чтоб использовать комбинацию клавиш Ctrl+C Ctrl+V smile smile

Автор: Демо 17.1.2006, 00:09
Цитата(ivan219 @ 17.1.2006, 00:03 Найти цитируемый пост)

А как реализовать буфер обмена


В смысле - как реализовать? Вставка и копирование работают по-умолчанию. Для этого ничего не надо писать дополнительно.

Автор: ivan219 17.1.2006, 01:49
Нет. Это когда меню вызываеш а мне надо Ctrl+C Ctrl+V smile

Вот нашол только как это реализовать чтоб было по нажатию Ctrl+C Ctrl+V

Код

procedure Tform1.CopyStringToClipboard(s: string);
var
  hg: THandle;
  P: PChar;
begin
  hg:=GlobalAlloc(GMEM_DDESHARE or GMEM_MOVEABLE, Length(S)+1);
  P:=GlobalLock(hg);
  StrPCopy(P, s);
  GlobalUnlock(hg);
  OpenClipboard(Application.Handle);
  SetClipboardData(CF_TEXT, hg);
  CloseClipboard;
  GlobalFree(hg);
end; 

Автор: Bog d`An 17.1.2006, 04:55
Цитата(Демо @ 16.1.2006, 22:45 Найти цитируемый пост)

Код

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
    case Key of
        '0'..'9',#8:;
        ',','.':
            begin
                if Pos(DecimalSeparator,TEdit(Sender).Text)>0
                    then Key := #0
                    else Key := DecimalSeparator;
            end;
    else Key := #0;
    end;
end;
procedure TForm1.Edit1Change(Sender: TObject);
var
  i: integer;
  isSeparator: Boolean;
  s: String;
begin
  isSeparator := False;
  s := TEdit(Sender).Text;
  for i := 1 to Length(s) do
  begin
    case TEdit(Sender).Text[i] of
        '0'..'9',#8: Continue;
        ',','.':
            begin
                if isSeparator then Abort;
                s[i] := DecimalSeparator;
                isSeparator := True;
            end;
    else Abort;
    end;
  end;
  TEdit(Sender).Text := s;
end;



Насчёт одной запятой - не будет работать, if not(DecimalSeparator in [',','.']) then думать надо, как DecimalSeparator, который не является константой запихать в case...

вариант: всё что не является буквой или цифрой считать разделителем... Действительно точка и запятая - довольно скудно... например(не претендуя на реальность ситуации) разделителем является '&' а вместо него напечатали(опечаткались) '^'

Автор: Демо 17.1.2006, 10:56
Цитата(Bog d`An @ 17.1.2006, 05:55 Найти цитируемый пост)

Насчёт одной запятой - не будет работать


Конкретнее, что и в каком конкретно месте не будет работать?

За универсализмом не надо гоняться. Нужно исходить из реалии и целесообразности.

например(не претендуя на реальность ситуации) разделителем является '&'

Почему бы тогда не предположить, что разделителем будет знак '-' или '+' (которые как раз тоже надо добавить в набор допустимых символов, и обработка, следовательно, усложнится), которые вляются допустимыми в числах?

Автор: ivan219 17.1.2006, 11:54
Почему не будет уменя 2 вареанта работают и кроме , и . болше ненашто нереагирует некаких +-*/?:%;№"!" нет а если при копировании то это каким же надо быть чтоб пренять @ в качестве , или .

Лучше обесните как выгледит нажатие клавиш Ctrl+C Ctrl+V smile как это реализовать smile

Автор: Alexeis 17.1.2006, 12:15
Цитата

Лучше обесните как выгледит нажатие клавиш Ctrl+C Ctrl+V  как это реализовать

Выделяем любой текст , жмем Ctrl+C
кликаем по Edit у , Жмем Ctrl+V и все smile smile smile

Автор: ivan219 17.1.2006, 14:05
Я незнаю может что нужно вкл. но такой способ непроходит Ctrl+С потм Ctrl+V вот с помощю меню можно вставить и копировать можно вырезазт отменить а комбинация клавиш Ctrl+С Ctrl+V не проходит smile

Автор: Romikgy 17.1.2006, 14:18
Конечно не будет работать smile ведь ты все буквы режешь в кейпрессе , перенеси в кейдаун и разреши необходимые те комбинации клавишь

Автор: Демо 17.1.2006, 16:27
Цитата(Romikgy @ 17.1.2006, 15:18 Найти цитируемый пост)

Конечно не будет работать


У меня работает в том виде, в котором написал. ;)

То, что у автора не работает, явно зависит от его остального кода и настроек форм, hotKey и т.д.

Автор: Bog d`An 17.1.2006, 23:44
Цитата(Bog d`An @ 17.1.2006, 04:55 Найти цитируемый пост)

Код

        ',','.':
            begin
                if Pos(DecimalSeparator,TEdit(Sender).Text)>0
                    then Key := #0
                    else Key := DecimalSeparator;
            end;


вот это. Если DecimalSeparator не является точкой или запятой, он пойдёт не сюда а в else

Но, действительно или целесообразность, или универсальность...
Цитата

Почему бы тогда не предположить, что разделителем будет знак '-' или '+'

тогда зачем вообще использовать DecimalSeparator? писали бы '.'

вот что-то более-менее универсальное
Код

const WrongSepArr : array[0..1] of char =('.',',');

Procedure TForm1.EditChange2(Sender: TObject);
Var
  CurStr: String;
  Counter,
  SelPos,
  SeparatorPos  :Integer;
  isSeparator: Boolean;
begin
  SelPos:= TEdit(Sender).SelStart;
  CurStr:=PChar(TEdit(Sender).Text);

  for counter := low(WrongSepArr) to high(WrongSepArr) do
    if WrongSepArr[counter]<> DecimalSeparator then
      While Pos(WrongSepArr[counter],CurStr)>0 do
        CurStr[Pos(WrongSepArr[counter],CurStr)]:=DecimalSeparator;

  SeparatorPos:=Pos(DecimalSeparator,CurStr);
  for Counter:= Length(CurStr)-1 downto 0 do
  Begin
    if (curStr[Counter] in [DecimalSeparator])and(Counter=SeparatorPos) then
      curStr[Counter] := DecimalSeparator
    else
      if not (curStr[Counter] in ['0'..'9',#8,#42]) then
        Delete(CurStr,counter,1);
  End;
  TEdit(Sender).Text:=CurStr;
  TEdit(Sender).SelStart:=SelPos;
end;



Цитата(Romikgy @ 17.1.2006, 14:18 Найти цитируемый пост)

Конечно не будет работать smile ведь ты все буквы режешь в кейпрессе , перенеси в кейдаун и разреши необходимые те комбинации клавишь

Правильно! там возможностей больше!
и ещё для формы KeyPreview := true

Автор: ivan219 20.1.2006, 03:16
Bog d`An товой код немного фальшивит в Edit можно писать и буквы только каждая последующая заменяет предыдущюю и запетые там можно их 2 штуки ставить.

А поподробнее можно как в KeyDown это реализовать smile smile

Автор: Bog d`An 20.1.2006, 06:16
Упс. Щас посмотрю.
Добавлено @ 06:28
Цитата(ivan219 @ 20.1.2006, 03:16 Найти цитируемый пост)

можно писать и буквы только каждая последующая заменяет предыдущюю и запетые там можно их 2 штуки ставить.

Это потому что в событии onChange


примерно так
Код

procedure TForm1.EditKeyDown1(Sender: TObject; var Key: Word;
  Shift: TShiftState);
Var
  Counter:Integer;
begin
  for counter := low(WrongSepArr) to high(WrongSepArr) do
    if WrongSepArr[counter]<> DecimalSeparator then
      if key = ord(WrongSepArr[counter]) then key:= ord(DecimalSeparator);

  if key in [ord(DecimalSeparator)] then
  Begin
    if Pos(DecimalSeparator,TEdit(Sender).Text)>0 then
      Key := 0;
  End
  else            //ord('0')..ord('9')
    if not (Key in [48..57,8,42]) then
      Key := 0;
end;

Автор: Демо 20.1.2006, 12:08
Цитата(Bog d`An @ 20.1.2006, 07:16 Найти цитируемый пост)

примерно так


Извини, но ты свой код пробовал хотя бы проверить?

Могу даже предложить попроовать вот такой:

Код

procedure TfMain.Edit1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  Key := 0;
end;



Эффект будет аналогичен.

Автор: ivan219 20.1.2006, 14:51
Компилятору чегото ненравится [Ошибка] Unit1.pas(103): Undeclared identifier: 'WrongSepArr'
Код

for counter := low(WrongSepArr) to high(WrongSepArr) do

Автор: Bog d`An 20.1.2006, 14:56
нет не пробовал smile
а надо? smile
Добавлено @ 14:58
Цитата(ivan219 @ 20.1.2006, 14:51 Найти цитируемый пост)

Компилятору чегото ненравится [Ошибка] Unit1.pas(103): Undeclared identifier: 'WrongSepArr'

константа с предидущего примера...
Код

const WrongSepArr : array[0..1] of char =('.',',');

Автор: ivan219 20.1.2006, 16:49
Ошибок нет а всё равно буквы идут когбудто и нет нечего.

Автор: Демо 20.1.2006, 16:50
Цитата(Bog d`An @ 20.1.2006, 15:56 Найти цитируемый пост)

а надо?


Надо, так как твой пример в OnKeyDown не будет работать ни в каком виде.

Автор: Alexeis 20.1.2006, 17:50
Как вам вот это
Код

procedure TForm1.Edit1Change(Sender: TObject);
var
  i : integer;
  fl : boolean;
  s  : ansiString;
  i1 : byte;
begin
  i1 := 1;
  fl := false;
  s := Edit1.Text;
  if length(s) < 1
  then
    exit;

  if s[i1] in ['+','-']
  then
    i1 := 2;

  if s[i1] = '.'
  then
    delete(s, i1, 1);

  for i := i1 to length(s)
  do
    if not fl
    then
      Begin
        if not (s[i] in ['0'..'9',DecimalSeparator])
        then
          delete(s, i, 1)
        else
          if s[i] = DecimalSeparator
          then
            fl := true
      end
    else
      if not (s[i] in ['0'..'9'])
      then
        delete(s, i, 1);

  Edit1.Text := s;
end;

Автор: ivan219 20.1.2006, 19:15
А что он делает smile

Автор: Bog d`An 21.1.2006, 05:06
о, точно там ещё +- надо первым символом разрешить
млин, не всё так просто как казалось...

Код

uses
  ClipBrd;

procedure TForm1.EditKeyDown1(Sender: TObject; var Key: Word;
 Shift: TShiftState);
Var
  Counter:Integer;
  Mgs: TMsg;

   procedure EatKey;
   begin
     PeekMessage(Mgs, 0, WM_CHAR, WM_CHAR, PM_REMOVE);
   end;

Begin
  if ssCtrl in Shift then
    case key of
    // Ctrl + v
    86:
    begin
      if Clipboard.HasFormat(CF_TEXT) then //Если буфер обмена содержит строковый тип
      try
        StrToInt(Clipboard.AsText);        //Если числа
      except
        EatKey                             //При ошибке преобразования типов ничего не вставляем
      end;
      exit;
    end;
    { Ctrl + c }
    67:
      exit;
    else
    Begin
      EatKey;                              //другие клавиши при нажатом контроле
      Exit;
    End;
  end;
  
  if ssShift in Shift then
  Begin
    EatKey;
    Exit;
  End;

  if not (Key in [48..57,8,42])  then
  Begin
    EatKey;
    Exit;
  End;
end;


мда.. вот токо куда проверку на запятую и +- вставить...
вроде они для рус\англ на различном ShiftState ?

Автор: ivan219 21.1.2006, 13:37
Всё почти работает smile запятых нет одни цифры, пречём блок цифровой клавиатуры тоже неотвичает, если из буфера обмена вставить 12.12 или 12,12 то ошибка.

Автор: Romikgy 23.1.2006, 11:19
А так ?
Код

procedure TForm1.Edit1Change(Sender: TObject);
var i: dword;
    sx:string;
begin
sx:=Edit1.Text;
if length(sx)<1 then exit;
if not ((sx[1]) in ['+','-','0'..'9','.',',']) then system.Delete(sx,1,1);
 for i:=2 to length(sx) do
 begin
 if (not ((sx[i]) in ['0'..'9','.',',']))
 then system.Delete(sx,i,1);
  end;
  for i:=1 to length(sx) do
  if (sx[i] in ['.',',']) then sx[i]:=DecimalSeparator;
  Edit1.Text:=sx;
  Edit1.SelStart:=length(sx);
end;

Автор: Bog d`An 24.1.2006, 09:06
С запятыми косяк... и позицией курсора...

Автор: Alexeis 24.1.2006, 09:54
ivan219 Мой алгоритм ведь работает какие еще проблемы??
Разрешает вводить только числа причем только с правельным разделителем, все посторонние символы удаляются, второй и последующие разделители так же удаляются, перед числом можно поставить + или -, сtrl + c и ctrl + V не блокируются, при вставке автоматически удаляются все лишние символы.

Автор: Bog d`An 24.1.2006, 10:23
Код

const WrongSepArr : array[0..1] of char =('.',',');

Procedure TForm1.EditChange2(Sender: TObject);
Var
  CurStr: String;
  Counter,
  SelPos,
  SeparatorPos  :Integer;
  isSeparator: Boolean;
begin
  SelPos:= TEdit(Sender).SelStart;
  CurStr:=PChar(TEdit(Sender).Text);

  if length(curStr)<1 then
    Exit;

  for counter := low(WrongSepArr) to high(WrongSepArr) do
    if WrongSepArr[counter]<> DecimalSeparator then
      While Pos(WrongSepArr[counter],CurStr)>0 do
        CurStr[Pos(WrongSepArr[counter],CurStr)]:=DecimalSeparator;

  SeparatorPos:=Pos(DecimalSeparator,CurStr);
  for Counter:= Length(CurStr) downto 2 do
  Begin
    if (curStr[Counter] in [DecimalSeparator])and(Counter=SeparatorPos) then
      curStr[Counter] := DecimalSeparator
    else
      if not (curStr[Counter] in ['0'..'9',#8,#42]) then
      Begin
        Delete(CurStr,counter,1);
        dec(SelPos);
      End;
  End;

  if (curStr[1] in [DecimalSeparator])and(SeparatorPos=1) then
  Begin
    curStr[1] := DecimalSeparator;
    insert('0',curStr,0);
    inc(SelPos);
  End;

  if length(curStr)>=2 then
    if (curStr[1] in ['+','-'])and(curStr[2] in [DecimalSeparator]) then
      Begin
        insert('0',curStr,2);
        inc(SelPos);
      End;
  if not (curStr[1] in ['0'..'9','+','-',#8,#42]) then
  Begin
    Delete(CurStr,1,1);
  End;

  While (length(curStr)>=2)and(curStr[1]='0')and(curStr[2]<>DecimalSeparator)do
  Begin
    delete(CurStr,1,1);
  End;
  While (length(curStr)>=3)and(curStr[1]in['+','-'])and(curStr[2]='0')and(curStr[3]<>DecimalSeparator)do
  Begin
    delete(CurStr,2,1);
  End;

  TEdit(Sender).Text:=CurStr;
  TEdit(Sender).SelStart:=SelPos;

end;


работает smile

Автор: Romikgy 24.1.2006, 11:04
Цитата(Bog d`An @ 24.1.2006, 08:06 Найти цитируемый пост)

С запятыми косяк... и позицией курсора...

В смысле косяк?, курсор только в конце.
Цитата(Bog d`An @ 24.1.2006, 09:23 Найти цитируемый пост)

 if not (curStr[Counter] in ['0'..'9',#8,#42]) then

Зачем юзать #8 в ченже??? Ведь это бекспейс, а он стирает символ, и в ф-цию передается строка без символа, стертого и символа 8 smile
А че такое 42 smile

Автор: Albinos_x 24.1.2006, 13:55
Цитата(Romikgy @ 24.1.2006, 11:04 Найти цитируемый пост)

А че такое 42

может он хотел написать 46(Del)

Автор: Romikgy 24.1.2006, 14:43
Дык и он зачем этот дел в Change ???

Автор: Alexeis 24.1.2006, 14:49
Код

Дык и он зачем этот дел в Change ???

я думаю это "остатки" EditKeyDown1

Автор: Romikgy 24.1.2006, 14:51
Оттож!!!! В ченже они ненадо!!!

Автор: ivan219 24.1.2006, 18:13
Цитата(alexeis1 @ 24.1.2006, 09:54)
ivan219 Мой алгоритм ведь работает какие еще проблемы??
Разрешает вводить только числа причем только с правельным разделителем, все посторонние символы удаляются, второй и последующие разделители так же удаляются, перед числом можно поставить + или -, сtrl + c и ctrl + V не блокируются, при вставке автоматически удаляются все лишние символы.

Почти когда на запятую два раза жмёш то курсор в ночало уходит.
Добавлено @ 18:15
Цитата(Romikgy @ 23.1.2006, 11:19)
А так ?
Код

procedure TForm1.Edit1Change(Sender: TObject);
var i: dword;
    sx:string;
begin
sx:=Edit1.Text;
if length(sx)<1 then exit;
if not ((sx[1]) in ['+','-','0'..'9','.',',']) then system.Delete(sx,1,1);
 for i:=2 to length(sx) do
 begin
 if (not ((sx[i]) in ['0'..'9','.',',']))
 then system.Delete(sx,i,1);
  end;
  for i:=1 to length(sx) do
  if (sx[i] in ['.',',']) then sx[i]:=DecimalSeparator;
  Edit1.Text:=sx;
  Edit1.SelStart:=length(sx);
end;

Этот код тоже хорош но с запятыми проблема их можно целую кучу ставить а нужна всего одна.

Автор: Alexeis 24.1.2006, 18:20

ошибка исправлена(решение украдено у Bog d`An)

Код

procedure TForm1.Edit1Change(Sender: TObject);
var
  i : integer;
  fl : boolean;
  s  : ansiString;
  i1 : byte;
  SelPos : integer;

begin
  i1 := 1;
  fl := false;
  s := Edit1.Text;

  SelPos:= TEdit(Sender).SelStart;

  if length(s) < 1
  then
    exit;

  if s[i1] in ['+','-']
  then
    i1 := 2;

  if s[i1] = '.'
  then
    delete(s, i1, 1);

  for i := i1 to length(s)
  do
    if not fl
    then
      Begin
        if not (s[i] in ['0'..'9',DecimalSeparator])
        then
          delete(s, i, 1)
        else
          if s[i] = DecimalSeparator
          then
            fl := true
      end
    else
      if not (s[i] in ['0'..'9'])
      then
        delete(s, i, 1);

  Edit1.Text := s;
  TEdit(Sender).SelStart:=SelPos;
end;

Автор: ivan219 24.1.2006, 18:27
Цитата(Bog d`An @ 24.1.2006, 10:23)
Код

const WrongSepArr : array[0..1] of char =('.',',');

Procedure TForm1.EditChange2(Sender: TObject);
Var
  CurStr: String;
  Counter,
  SelPos,
  SeparatorPos  :Integer;
  isSeparator: Boolean;
begin
  SelPos:= TEdit(Sender).SelStart;
  CurStr:=PChar(TEdit(Sender).Text);

  if length(curStr)<1 then
    Exit;

  for counter := low(WrongSepArr) to high(WrongSepArr) do
    if WrongSepArr[counter]<> DecimalSeparator then
      While Pos(WrongSepArr[counter],CurStr)>0 do
        CurStr[Pos(WrongSepArr[counter],CurStr)]:=DecimalSeparator;

  SeparatorPos:=Pos(DecimalSeparator,CurStr);
  for Counter:= Length(CurStr) downto 2 do
  Begin
    if (curStr[Counter] in [DecimalSeparator])and(Counter=SeparatorPos) then
      curStr[Counter] := DecimalSeparator
    else
      if not (curStr[Counter] in ['0'..'9',#8,#42]) then
      Begin
        Delete(CurStr,counter,1);
        dec(SelPos);
      End;
  End;

  if (curStr[1] in [DecimalSeparator])and(SeparatorPos=1) then
  Begin
    curStr[1] := DecimalSeparator;
    insert('0',curStr,0);
    inc(SelPos);
  End;

  if length(curStr)>=2 then
    if (curStr[1] in ['+','-'])and(curStr[2] in [DecimalSeparator]) then
      Begin
        insert('0',curStr,2);
        inc(SelPos);
      End;
  if not (curStr[1] in ['0'..'9','+','-',#8,#42]) then
  Begin
    Delete(CurStr,1,1);
  End;

  While (length(curStr)>=2)and(curStr[1]='0')and(curStr[2]<>DecimalSeparator)do
  Begin
    delete(CurStr,1,1);
  End;
  While (length(curStr)>=3)and(curStr[1]in['+','-'])and(curStr[2]='0')and(curStr[3]<>DecimalSeparator)do
  Begin
    delete(CurStr,2,1);
  End;

  TEdit(Sender).Text:=CurStr;
  TEdit(Sender).SelStart:=SelPos;

end;


работает smile


Работае я немного подправил так что всё ОК smile

Тут даже когда первая стоит запятая то ставит 0, это ещё лучше сам пытался это реализовать но неполучилось вобщем всё работает smile

Код

const WrongSepArr : array[0..1] of char =('.',',');

Procedure TForm1.Edit1Change(Sender: TObject);
Var
  CurStr: String;
  Counter,
  SelPos,
  SeparatorPos  :Integer;
  isSeparator: Boolean;
begin
  SelPos:= TEdit(Sender).SelStart;
  CurStr:=PChar(TEdit(Sender).Text);
  if length(curStr)<1 then
    Exit;
  for counter := low(WrongSepArr) to high(WrongSepArr) do
    if WrongSepArr[counter]<> DecimalSeparator then
      While Pos(WrongSepArr[counter],CurStr)>0 do
        CurStr[Pos(WrongSepArr[counter],CurStr)]:=DecimalSeparator;
  SeparatorPos:=Pos(DecimalSeparator,CurStr);
  for Counter:= Length(CurStr) downto 2 do
  Begin
    if (curStr[Counter] in [DecimalSeparator])and(Counter=SeparatorPos) then
      curStr[Counter] := DecimalSeparator
    else    
      if not (curStr[Counter] in ['0'..'9']) then
      Begin
        Delete(CurStr,counter,1);    
        dec(SelPos);
      End;
  End;    
  if (curStr[1] in [DecimalSeparator])and(SeparatorPos=1) then
  Begin
    curStr[1] := DecimalSeparator;    
    insert('0',curStr,0);
    inc(SelPos);
  End;
  if not (curStr[1] in ['0'..'9']) then
  Begin
    Delete(CurStr,1,1);    
  End;
  While (length(curStr)>=2)and(curStr[1]='0')and(curStr[2]<>DecimalSeparator)do    
  Begin    
    delete(CurStr,1,1);
  End;    
  TEdit(Sender).Text:=CurStr;
  TEdit(Sender).SelStart:=SelPos;
end;


Спасибо!!!!!!! smile
Добавлено @ 18:30
Ещё Bog d`An если можеш распши всё просто мне надо это понять а так я неразберусь хотя попытають.

Автор: Alexeis 24.1.2006, 18:47
в коде Bog d`An есть маленький глюк если установить курсор
в начало строки и жать del то работает как то странно...
Добавлено @ 18:59
если добавить - а перед ним разделитель минус удаляется

Автор: ivan219 24.1.2006, 22:28
Может кто подскажет как этот код в компоненте исползовать я тут попробовал но чтот неполучилось компонент установился а толку мало может кто даст ссылку на литераратуру где можно почитать ка создовать свои компоненты или пожет от куда начать.
Код

unit Edit1;

interface

uses
  SysUtils, Classes, Controls, StdCtrls;

type
  TEdit1 = class(TEdit)
  Procedure EditChange(Sender: TObject);
  private
    { Private declarations }
  protected
    { Protected declarations }
  public
    { Public declarations }
  published
    { Published declarations }
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Ïðèìåðû', [TEdit1]);
end;

Procedure TEdit1.EditChange(Sender: TObject);
const WrongSepArr : array[0..1] of char =('.',',');
Var
  CurStr: String;
  Counter, SelPos, SeparatorPos: Integer;
  isSeparator: Boolean;
begin
  SelPos:=TEdit(Sender).SelStart;
  CurStr:=PChar(TEdit(Sender).Text);
  if length(curStr)<1 then Exit;
  for counter:=low(WrongSepArr) to high(WrongSepArr) do
    if WrongSepArr[counter]<>DecimalSeparator then
      While Pos(WrongSepArr[counter],CurStr)>0 do
        CurStr[Pos(WrongSepArr[counter],CurStr)]:=DecimalSeparator;    
        SeparatorPos:=Pos(DecimalSeparator,CurStr);
  for Counter:=Length(CurStr) downto 2 do
  Begin
    if (curStr[Counter] in [DecimalSeparator])and(Counter=SeparatorPos) then    
      curStr[Counter]:=DecimalSeparator
    else     
      if not (curStr[Counter] in ['0'..'9']) then    
      Begin    
        Delete(CurStr,counter,1);
        dec(SelPos);    
      End;    
  End;     
  if (curStr[1] in [DecimalSeparator])and(SeparatorPos=1) then    
  Begin    
    curStr[1]:=DecimalSeparator;     
    insert('0',curStr,0);    
    inc(SelPos);    
  End;    
  if not (curStr[1] in ['0'..'9']) then Delete(CurStr,1,1);
  While (length(curStr)>=2)and(curStr[1]='0')and(curStr[2]<>DecimalSeparator)do
  Begin     
    delete(CurStr,1,1);    
  End;
  TEdit(Sender).Text:=CurStr;
  TEdit(Sender).SelStart:=SelPos;
end;
end.


smile smile

Автор: Akella 25.1.2006, 10:25
про подмену разделителя целой и дробной части:
давно уже сделано
не забываем про "Арсенал"
http://forum.vingrad.ru/index.php?showtopic=21411&view=findpost&p=409416

Автор: Bog d`An 26.1.2006, 15:14
Цитата(Romikgy @ 24.1.2006, 11:04 Найти цитируемый пост)

В смысле косяк?, курсор только в конце.

а если юзверь станет в середине печатать?

Цитата(alexeis1 @ 24.1.2006, 18:47 Найти цитируемый пост)

если добавить - а перед ним разделитель минус удаляется

??? что бы это значило?

Код

const WrongSepArr : array[0..1] of char =('.',','); //создаём константу - массив для хранения символов, которые надо преобразовать в разделитель

Procedure TForm1.Edit1Change(Sender: TObject);
Var
  CurStr: String;
  Counter,
  SelPos,
  SeparatorPos  :Integer;
  isSeparator: Boolean;
begin
  SelPos:= TEdit(Sender).SelStart;                      //положение курсора
  CurStr:=PChar(TEdit(Sender).Text);                 //Текст из эдита, который изменён
  if length(curStr)<1 then                                    //Проверка длины 
    Exit;
  for counter := low(WrongSepArr) to high(WrongSepArr) do  //Перечисление по массиву
    if WrongSepArr[counter]<> DecimalSeparator then
      While Pos(WrongSepArr[counter],CurStr)>0 do                //ищем данный элемент масива в тексте
        CurStr[Pos(WrongSepArr[counter],CurStr)]:=DecimalSeparator;//Заменяем на сепаратор
  SeparatorPos:=Pos(DecimalSeparator,CurStr);                    //Ищем первый сепаратор
  for Counter:= Length(CurStr) downto 2 do                          //Перечисление по строке от конца до 2 элемента (обратный, т.к. может быть удалены символы и как следствие - уменьшина длина)
  Begin
    if (curStr[Counter] in [DecimalSeparator])and(Counter=SeparatorPos) then //если сепаратор и он не первый
      curStr[Counter] := DecimalSeparator           //удаляем
    else    
      if not (curStr[Counter] in ['0'..'9']) then        //иначе ели не разрешённый символ
      Begin
        Delete(CurStr,counter,1);                          //удаляем
        dec(SelPos);
      End;
  End;    

  if length(curStr)>=2 then                                //Если длина больше 1
    if (curStr[1] in ['+','-'])and(curStr[2] in [DecimalSeparator]) then  //Если первый символ знак
      Begin
        insert('0',curStr,2);                                    //Вставить 0 вторым символом
        inc(SelPos);
      End;
  if not (curStr[1] in ['0'..'9','+','-']) then             //Если первый сивол запрещён
  Begin
    Delete(CurStr,1,1);                                       //Удалить
  End;
  While (length(curStr)>=2)and(curStr[1]='0')and(curStr[2]<>DecimalSeparator)do //удалить нули в начале числа
  Begin
    delete(CurStr,1,1);
  End;
  While (length(curStr)>=3)and(curStr[1]in['+','-'])and(curStr[2]='0')and(curStr[3]<>DecimalSeparator)do //удалить нули в начале числа, если первый символ - знак
  Begin
    delete(CurStr,2,1);
  End;
  
  TEdit(Sender).Text:=CurStr;
  TEdit(Sender).SelStart:=SelPos;
end;

Автор: Kuper 9.2.2006, 09:24
Ниже приведён код, который не позволяет вводить ничего лишнего, кроме символов и всего что их касаеца.
Так же он оставляет знаки "+" и "-" только в начале, и оставляет только один разделитель.
Запехни его просто в обработчик OnChange.
Код

var
  i: Integer;
  sx: string;
  Flag: Boolean;
begin
  Flag := False;
  sx := TDBEdit(Sender).Text;
  if length(sx) < 1 then
    Exit;
  for i := 1 to length(sx) do
    if not (sx[i] in ['+', '-', '0'..'9', '.', ',']) then
      system.Delete(sx,i,1)
      else
      begin
        if (sx[i] in ['+', '-']) and (i <> 1) then
          begin
            system.Delete(sx,i,1);
          end;
        if (sx[i] in ['.', ',']) then
          begin
            if Flag = True then
              begin
                system.Delete(sx,i,1);
              end
              else
              begin
                sx[i] := DecimalSeparator;
                Flag := True;
              end;
          end;
      end;
  TDBEdit(Sender).Text := sx;
  TDBEdit(Sender).SelStart := length(sx);

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)