Delphi. Обработка полей ввода на форме.
22.05.2017Для ввода данных пользователем, программист создает определенный набор элементов формы.
Каждый элемент предназначен для ввода определенной информации и если этот элемент не является типом MEMO или обычным EDIT — обработка введенных значений очень проста, и совсем другая история, если эти поля могут содержать только определенный формат значений.
Как правило для этих целей используют элемент типа MASKEDIT и оперируют его свойствами. Про него я писать не буду — информации в сети более чем достаточно.
Рассмотрим обработку на примере обычного EDIT и элемента DateEdit (или DateTimePicker).
Итак, задача:
1. Используя обычный TEdit ограничить ввод символов, недопустить ввода пользователем некорректных значений (пусть это будет дробное число вносимое в поле БД типа FLOAT).
2. Используя на форме два элемента выбора даты выставить зависимость одного от другого и от текущей даты.
Поехали.
Задача 1.
Поставим на форму TEdit.
Большинство его свойств нас не интересуют, делайте так как Вам удобно — это просто визуальное оформление, но некоторым уделим внимание.
Поскольку по условию задачи поле должно содержать дробное число, ну или целое — не важно, то примем как шаблон, число может содержать значение равное или меньше 25 с точностью до сотых долей.
Тогда максимальная длина нашего Edit1 будет равна 5 символов (например число 24,98), что мы и сообщим элементу задав свойство Edit1.MaxLength:=5 и это пожалуй единственное ограничение, которое наложим свойством элемента.
Поскольку по умолчанию поле ввода позволяет вводить любые симоволы, необходимо наложить некоторые ограничения. Это будет ограничене на ввод только цифт и знака-разделителя (запятая или точка), выполняется это следующим образом:
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char); begin case Key of //здесь проверка ввода символа (допустимый набор) #8, '0'..'9':; //разрешаем только цифры и нажатие клавиши backspace '.',',': // разрешение на ввод разделителя дробной части begin // я использую как хранилище БД MySQL поэтому: DecimalSeparator:='.'; // обозначаю разделитель дробного от целого if key = ',' then key:= '.'; // выполняю замену на точку если введена запятая if Pos(DecimalSeparator, Edit1.Text) <> 0 then Key := Chr(0); //запрещаю ставить два разделителя подрят end else Key := Chr(0); //игнорирую ввод любого символа кроме разрешенных end; end;
Таким образом элемент Edit1 обучен получать нужный формат вводимых данных.
Конечно, сразу же возникнет вопрос: какие данные лягут в базу, если последним символом окажется точка? Ведь необходимо в последствии обрабатывать информацию минимальным набором операций.
Для исключения сохранения информации с точкой на конце, применяю следующий ход:
procedure TForm1.Edit1Exit(Sender: TObject); begin // если полседний символ строки точка - избавляемся от нее trim(Edit1.Text); // хотя этого в данном случае можно и не делать if Edit1.Text <>'' then begin // если элемент формы содержит текст,- выполняю проверку // и удаляю последний символ, если он является точкой. if Edit1.Text[Length(Edit1.Text)]='.' then edit1.text:=copy(edit1.text,1,length(edit1.text)-1) ; end; end;
Процедура OnExit выполнятся при переходе из этого поля ввода формы в любой другой элемент или по щелчку мыши по форме.
Осталось только проверить соответствие введенного значения допустимому диапазону. Я это делаю при нажатии кнопки сохранения,- можно и иначе.
if strtofloat(edit1.Text)<=25 then .... выполняю какие-то действия ....... else showmessage('Проверьте правильность ввода данных:'+#13+'Значение не может быть больше 25');
Внедрение +#13+ позволяет переносить строку внутри сообщения выводимого методом showmessage. Вот собственно и все решение первой части поставленной задачи.
Задача 2.
Эта задача многим проще и не займет много времени на реализацию.
Поскольку в поставновке задачи озвучены два элемента выбора даты, то для начала зададим им максимальную дату для выбора не более текущей даты:
procedure TForm1.FormShow(Sender: TObject); begin DVZ.MaxDate:= Date (); DUZ.MaxDate:= Date (); end;
DVZ и DUZ здесь имена копмонентов типа DateEdit.
Поскольку нужна зависимость второго от первого, дабы во втором элементе невозможно было выбрать дату менее выбранной в первом, делаем:
procedure TForm1.DVZChange(Sender: TObject); begin DUZ.MinDate:=DVZ.Date; DUZ.Clear; end;
Зависимость реализована, теперь проверяем ввод данных.
Поскольку маска ввода у меня такова !99/99/9999;1; а изначальный текст отображаемый пользователю выглядит так: «__.__.____» (только вместо символов подчеркивания стоят пробелы), то в моем случае проверка ввода выгляди так:
if (StringReplace(DVZ.Text, ' ', '',[rfReplaceAll])<>'..') // убираю все пробелы и сравниваю and (StringReplace(DUZ.Text, ' ', '',[rfReplaceAll])<>'..') then showmessage('Все введено!');
Все! Проверка выполнена!