При разработке на управляемых формах 1С программисты часто сталкиваются с необходимостью динамического создания интерфейса. Одной из классических задач является программное формирование колонок в таблице формы на основе данных из таблицы значений (ТЗ). Однако здесь подстерегает неочевидная ловушка: при вводе дробных чисел, начинающихся с нуля (например, "0,5"), платформа может вести себя некорректно — «проглатывать» ноль и запятую, оставляя в ячейке только целое число. Рассмотрим подробнее, почему это происходит и как правильно настроить программное создание реквизитов, чтобы ввод данных работал стабильно.
Представим ситуацию: мы программно создаем колонки в таблице формы. В исходной таблице значений тип колонки определен как Число с точностью 3 знака после запятой. Казалось бы, платформа должна автоматически подхватить эти настройки. Но на практике при попытке ввода значения "0,5" пользователь видит странное поведение: как только вводится цифра после разделителя, строка "0," исчезает, и в ячейке остается просто "5".
Проанализируем визуальные признаки проблемы. Если в поле ввода вместо привычного калькулятора или простого текстового ввода появляется кнопка с «квадратиками» (кнопка выбора типа), это первый сигнал того, что 1С считает тип данных в этой ячейке составным или неопределенным. В этом случае поле ввода работает в режиме «ожидания типа». Когда вы вводите "0", система еще не уверена, что это число. При вводе разделителя она продолжает сомневаться, а когда появляется "5", платформа делает предположение, что это число, но из-за нечетко заданных квалификаторов преобразует ввод в целое число, отбрасывая «незначимый» ноль.
Часто программисты пытаются решить проблему «с конца» — настраивая свойства самого элемента формы (поля ввода). Рассмотрим пример кода, который содержит логические изъяны:
НовыйЭлементФормы = Элементы.Добавить("ТЗ"+Колонка.Имя, Тип("ПолеФормы"), ЭлементТЗ);
НовыйЭлементФормы.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлементФормы.ПутьКДанным = "ТЗ." + Колонка.Имя;
НовыйЭлементФормы.ВыбиратьТип = Ложь; // Попытка скрыть кнопку выбора типа
Установка свойства ВыбиратьТип = Ложь лишь скрывает визуальную кнопку, но не меняет внутреннюю природу данных. Если реквизит формы, к которому привязано это поле, не имеет жесткого ограничения типа Число с заданной точностью, проблема никуда не исчезнет. Разберем по шагам, как сделать правильно.
Ключ к решению задачи лежит в использовании КвалификаторыЧисла. Мы должны явно указать платформе, что реквизит будет содержать число определенной длины и, что самое важное, определенной точности. Выясним причину ошибки: если точность не указана в ОписаниеТипов, система по умолчанию может считать число целым.
Рассмотрим пример создания квалификаторов для числа 15.3:
Квалификаторы = Новый КвалификаторыЧисла(15, 3);
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("Число"));
ОписаниеТипаЧисло = Новый ОписаниеТипов(МассивТипов, , , Квалификаторы);
Такой подход гарантирует, что реквизит формы будет строго типизирован.
Теперь объединим создание описания типов с добавлением реквизитов в структуру управляемой формы. Лучший способ — копировать тип данных напрямую из колонок исходной таблицы значений, так как в ТЗ типы обычно уже определены правильно (например, результатом запроса).
Проанализируем правильный цикл обхода колонок:
МассивРеквизитов = Новый Массив;
Для Каждого КолонкаИсточник Из ТЗ_Результат.Колонки Цикл
// Создаем описание реквизита, полностью копируя тип из колонки ТЗ
НовыйРеквизит = Новый РеквизитФормы(КолонкаИсточник.Имя,
КолонкаИсточник.ТипЗначения,
"ТЗ_НаФорме",
КолонкаИсточник.Заголовок);
МассивРеквизитов.Добавить(НовыйРеквизит);
КонецЦикла;
// Применяем изменения к форме
ЭтаФорма.ИзменитьРеквизиты(МассивРеквизитов);
Важный нюанс: при создании РеквизитФормы вторым параметром мы передаем КолонкаИсточник.ТипЗначения. Если в ТЗ колонка была создана с квалификаторами, то и реквизит формы получит их в полном объеме. Именно это устраняет «квадратики» в поле ввода и восстанавливает корректную работу с нулем в дробной части.
После того как реквизиты (данные) созданы, мы можем приступать к созданию элементов (визуальных полей). Теперь нам не нужно вручную ограничивать типы в свойствах элемента, так как они продиктованы связанным реквизитом.
Для Каждого КолонкаИсточник Из ТЗ_Результат.Колонки Цикл
ИмяЭлемента = "ТЗ_НаФорме" + КолонкаИсточник.Имя;
НовыйЭлемент = Элементы.Добавить(ИмяЭлемента, Тип("ПолеФормы"), ЭлементТаблица);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.ПутьКДанным = "ТЗ_НаФорме." + КолонкаИсточник.Имя;
// Теперь это свойство действительно сработает правильно,
// так как тип реквизита уже однозначно определен
НовыйЭлемент.РежимРедактирования = РежимРедактированияКолонки.ВходПриВводе;
КонецЦикла;
Рассмотрим несколько полезных советов, которые помогут избежать подобных проблем в будущем:
Выгрузить() из результата запроса, убедитесь, что в самом запросе нет неоднозначности типов. Используйте функцию ВЫРАЗИТЬ(Поле КАК ЧИСЛО(15, 3)), чтобы гарантировать передачу квалификаторов в ТЗ.ОписаниеТипов платформа автоматически обрабатывает ввод любого системного разделителя корректно, преобразуя его в числовое значение без потери ведущих нулей.Таким образом, мы выяснили, что проблема «исчезающего нуля» — это не баг платформы, а следствие неявного указания типов данных. Создавая реквизиты формы с четким указанием КвалификаторыЧисла, мы обеспечиваем предсказуемое поведение интерфейса и комфортную работу пользователя с дробными значениями.