![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
|
Подскажите пожалуйста как проверить, что некотрое поле содержит именно числовое значение, т.е. что пользователь ввел именно цисло (целое или с плавающей точкой) и вопролнить дальнейшие математические действия только если условие выполнено. На PHP можно проверить регулярным выражением примерно так:
PHP код:
или что-т о около того, возможно ли такое на Delphi? как реализуются подобные проверки? |
|
#2
|
||||
|
||||
|
вот процедура проверки строки:
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
s: string;
i: Integer;
f: Double;
begin
s:= Edit1.Text;
if TryStrToInt(s, i) then
begin
ShowMessage('Целое число');
exit;
end;
if TryStrToFloat(s, f) then
begin
ShowMessage('Дробное число');
exit;
end;
ShowMessage('Ошибка!');
end; |
|
#3
|
|||
|
|||
|
спасибо, работает, НО значения типа 1,35 и т.д. введенные с цифровой клавиатуры воспринимаются как String, если поставить точку через букву ''ю", все работает нормально.... как заставить программу понимать знак вводимый клавишей Del на цифровой клавиатуре как запятую, а не как точку? Заранее огромное спасибо
Последний раз редактировалось Darken, 26.02.2009 в 10:16. |
|
#4
|
||||
|
||||
|
Необходимо проводить проверку непосредственно при нажатии клавиши.
Функция StrToFloat по умолчанию считает разделителем точку(хм, то что она считает по умолчанию вообще-то зависит от региональных настроек), поэтому надо либо при вводе запятую заменять на точку (как это сделано в приведённом ниже коде), либо собственноручно определять, какой символ использовать в качестве разделителя в десятичых дробях(обычно так и делается для пущей безопасности). Также стоит сделать проверку, когда вводит пользователь не цифру или не знак разделителя - при этом просто не помещать этот символ в поле ( для этого надо прировнять Key:=#0 ) Необходимо разрешить и некоторые спец. символы - Backspace( #8 ) и Delete ( #46 ) Код:
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char); begin if Key = ',' then Key := '.' else if not ( Key in [ '0'..'9' , '.' , #8 , #46 ] ) then Key := #0; end; |
|
#5
|
||||
|
||||
|
Rokuell, метод хорош, тут ничего не скажешь (кста, delete можно и не указывать, и так нормально удаляет) я сам его долгое время использовал, но, как говорится, есть одно "но". Данный метод не спасает от copy/paste
![]() |
|
#6
|
|||
|
|||
|
совместив два ранее предложенных пожхода получили нечто
PHP код:
Но, почему-то если ввести число 4, например - выдает ошибку, если 44 - тогда пишет, что целое... И еще хотя это и не нужно в данном проекте, но если ввести число более 12 знаков - выдает, что оно дробное, почему? |
|
#7
|
||||
|
||||
|
Цитата:
Код:
var
s: string;
i: Integer;
f: Double;
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if Key = '.' then Key := ',' //замена точки запятой
else
if not ( Key in [ '0'..'9' , '.' , #8 , #46 ] ) then Key := #0;
end;
procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
s:= Edit1.Text; //проверка ввода
if TryStrToInt(s, i) then
begin
Label5.Caption:= s + ' Целое';
exit;
end;
if TryStrToFloat(s, f) then
begin
Label5.Caption:= s + ' Дробное';
exit;
end;
Label5.Caption:= s + ' Ошибка';
end;Цитата:
Последний раз редактировалось Karsh, 26.02.2009 в 14:51. |
|
#8
|
||||
|
||||
|
Цитата:
Ну что ж, если надо ещё контроль над вставкой, то: 1. В моём варианте комбинация Ctrl+C и так не работает ( т.к. 'C' - это не цифра ) 2. Есть ещё комбинация клавиш для вставки Shift+Ins Для её контроля можно добавить код: Код:
procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if ( ssShift in Shift ) and ( Key = VK_INSERT ) then Key := 0; end; 3. Но! Вставить в Edit можно ещё одним способом - кликнув правой кнопкой мыши и выбрав пункт меню "Вставить". И вот если надо контролировать ещё и это, то надо использовать другой вариант. Общий вариант для всех 3х случаев: 1. В секцию формы private добавляем переменную и новую процедуру: Код:
private
StdEditProc : procedure (var Msg:TMessage) of object;
procedure EditProc(var Msg:TMessage);2. При создании формы заменяем стандартый обработчик сообщения у Edit на самописный, предварительно сохраняя стандартный: Код:
procedure TForm1.FormCreate(Sender: TObject); begin StdEditProc := Edit1.WindowProc; Edit1.WindowProc := EditProc; end; 3. И в нашем обработчике пишем: Код:
procedure TForm1.EditProc(var Msg: TMessage);
begin
Case Msg.Msg of
WM_PASTE: ; // ничего не делаем, поэтому вставка не происходит
WM_KEYDOWN,WM_KEYUP,WM_CHAR: begin
// Если это запятая ( 44 - это её ASCII код )
if Msg.WParam = 44 then
begin
// Заменяем на точку
Msg.WParam := 46;
// И вызываем стандартный обработчик
StdEditProc(Msg);
end
else
if Msg.WParam in [8,37,39,46,48..57]
then StdEditProc(Msg);
// 8 - backspace
// 37 и 39 - VK_LEFT и VK_RIGHT
// 46 - точка
// 48..57 - '0'..'9'
// Для других символов ничего не происходит
end;
Else StdEditProc(Msg);
End;
end; |
|
#9
|
||||
|
||||
|
Класс, только одно замечание:
46 (точка) заменить на ord(DecimalSeparator) и вообще будет гут. |
|
#10
|
|||
|
|||
|
очень интересный и познавательный топ получился, всем спасибо, добавил в избранное
|