При программной работе с элементами управляемых форм можно столкнуться с неочевидным поведением. Рассмотрим одну из таких ситуаций: вы динамически добавляете на форму колонки с числовым типом данных. Все работает, но при попытке ввести в поле дробное число меньше единицы, например 0,95, ничего не получается — система либо игнорирует ввод, либо ведет себя некорректно. При этом числа больше единицы, например 4,95, вводятся без проблем. Разберемся, почему так происходит и как это исправить.
Проанализируем ситуацию, с которой столкнулся автор. Имеется код, который в цикле создает реквизиты и связанные с ними поля на форме для табличной части Товары.
Вот первоначальный вариант кода:
Для каждого стр из Объект.Клиенты цикл
МассивРеквизитов = Новый Массив;
ТмяКол = "Колонка"+стр.НомерСтроки;
МассивРеквизитов.Добавить(Новый РеквизитФормы(ТмяКол, Новый ОписаниеТипов("Число"), "Объект.Товары", Лев(стр.Контрагент.Наименование,4)+" "+Стр.Договор, Ложь));
ИзменитьРеквизиты( МассивРеквизитов );
Эл = Элементы.Добавить(ТмяКол, Тип("ПолеФормы"), Элементы.Товары);
Эл.Вид = ВидПоляФормы.ПолеВвода;
Эл.ПутьКДанным = "Объект.Товары."+ТмяКол;
КонецЦикла;
На первый взгляд, все выглядит корректно. Мы создаем новый реквизит формы с помощью конструктора Новый РеквизитФормы. В качестве типа данных передаем Новый ОписаниеТипов("Число"). Именно здесь и кроется корень проблемы.
Когда мы указываем тип "Число" без дополнительных уточнений, платформа 1С использует настройки по умолчанию. Эти настройки не содержат явной информации о разрядности и точности (количестве знаков после запятой). В большинстве случаев это работает, но при динамическом создании элементов формы такая неопределенность может приводить к сбоям в работе поля ввода. Система не может корректно интерпретировать ввод пользователя: например, при вводе "0,95" она может "потерять" ноль с запятой и оставить только "95", так как не понимает, что от нее требуется обработка дробной части.
Ключевая причина — отсутствие явных квалификаторов для числового типа данных, что приводит к некорректной работе элемента управления на форме.
Чтобы решить проблему, необходимо предоставить платформе точную информацию о формате числа, который мы ожидаем. Для этого в 1С существует специальный объект — КвалификаторыЧисла.
Этот объект позволяет задать три основных параметра:
Любой), только положительными (Неотрицательный) или только отрицательными (Неположительный).Для исправления нашего кода нужно выполнить два простых шага:
КвалификаторыЧисла с нужными параметрами.ОписаниеТипов при создании реквизита.Посмотрим на исправленный код:
Для каждого стр из Объект.Клиенты цикл
// Шаг 1: Создаем объект квалификаторов
КвалификаторыЧисла = Новый КвалификаторыЧисла(10, 2, ДопустимыйЗнак.Неотрицательный);
МассивРеквизитов = Новый Массив;
ТмяКол = "Колонка"+стр.НомерСтроки;
// Шаг 2: Передаем квалификаторы при создании описания типов
ОписаниеЧисловогоТипа = Новый ОписаниеТипов("Число", , , , КвалификаторыЧисла); // Вариант, который сработал у автора
МассивРеквизитов.Добавить(Новый РеквизитФормы(ТмяКол, ОписаниеЧисловогоТипа, "Объект.Товары", Лев(стр.Контрагент.Наименование,4)+" "+Стр.Договор, Ложь));
ИзменитьРеквизиты( МассивРеквизитов );
Эл = Элементы.Добавить(ТмяКол, Тип("ПолеФормы"), Элементы.Товары);
Эл.Вид = ВидПоляФормы.ПолеВвода;
Эл.ПутьКДанным = "Объект.Товары."+ТмяКол;
КонецЦикла;
В этом примере мы задали число с общей длиной до 10 знаков, из которых 2 знака отводятся под дробную часть, и разрешили ввод только неотрицательных значений. После такого явного указания платформа корректно настраивает поле ввода, и проблема с вводом дробных чисел, начинающихся с нуля, исчезает.
Внимательный разработчик мог заметить в рабочем коде автора необычную конструкцию: Новый ОписаниеТипов("Число", , , , КвалификаторыЧисла). Квалификатор числа передается пятым параметром, хотя в стандартном синтаксисе конструктора он должен быть вторым:
Новый ОписаниеТипов(<Типы>, <КвалификаторыЧисла>, <КвалификаторыСтроки>, <КвалификаторыДаты>, ...)
Платформа 1С имеет несколько перегруженных версий конструктора, и в некоторых случаях она может "простить" такую запись, правильно интерпретировав намерение. Однако для чистоты, читаемости и надежности кода рекомендуется использовать стандартный, документированный синтаксис.
Более правильный и рекомендуемый вариант кода:
// ...
КвалификаторыЧисла = Новый КвалификаторыЧисла(10, 2, ДопустимыйЗнак.Неотрицательный);
// Квалификатор передается вторым параметром
ОписаниеЧисловогоТипа = Новый ОписаниеТипов("Число", КвалификаторыЧисла);
МассивРеквизитов.Добавить(Новый РеквизитФормы(ТмяКол, ОписаниеЧисловогоТипа, "Объект.Товары", ...));
// ...
Или в одну строку для краткости:
// ...
МассивРеквизитов.Добавить(Новый РеквизитФормы(ТмяКол,
Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 2, ДопустимыйЗнак.Неотрицательный)),
"Объект.Товары",
...));
// ...
Вывод: при программном создании реквизитов формы с числовым типом данных всегда явно указывайте КвалификаторыЧисла. Это сделает поведение системы предсказуемым, избавит от неочевидных ошибок при вводе данных и повысит общую надежность вашего кода.