Как исправить ошибку ввода дробных чисел (ноль целых) в динамической таблице управляемой формы

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке на управляемых формах 1С программисты часто сталкиваются с необходимостью динамического создания интерфейса. Одной из классических задач является программное формирование колонок в таблице формы на основе данных из таблицы значений (ТЗ). Однако здесь подстерегает неочевидная ловушка: при вводе дробных чисел, начинающихся с нуля (например, "0,5"), платформа может вести себя некорректно — «проглатывать» ноль и запятую, оставляя в ячейке только целое число. Рассмотрим подробнее, почему это происходит и как правильно настроить программное создание реквизитов, чтобы ввод данных работал стабильно.

Суть проблемы: почему «0,5» превращается в «5»

Представим ситуацию: мы программно создаем колонки в таблице формы. В исходной таблице значений тип колонки определен как Число с точностью 3 знака после запятой. Казалось бы, платформа должна автоматически подхватить эти настройки. Но на практике при попытке ввода значения "0,5" пользователь видит странное поведение: как только вводится цифра после разделителя, строка "0," исчезает, и в ячейке остается просто "5".

Проанализируем визуальные признаки проблемы. Если в поле ввода вместо привычного калькулятора или простого текстового ввода появляется кнопка с «квадратиками» (кнопка выбора типа), это первый сигнал того, что 1С считает тип данных в этой ячейке составным или неопределенным. В этом случае поле ввода работает в режиме «ожидания типа». Когда вы вводите "0", система еще не уверена, что это число. При вводе разделителя она продолжает сомневаться, а когда появляется "5", платформа делает предположение, что это число, но из-за нечетко заданных квалификаторов преобразует ввод в целое число, отбрасывая «незначимый» ноль.

Разбор типичных ошибок в коде

Часто программисты пытаются решить проблему «с конца» — настраивая свойства самого элемента формы (поля ввода). Рассмотрим пример кода, который содержит логические изъяны:


НовыйЭлементФормы = Элементы.Добавить("ТЗ"+Колонка.Имя, Тип("ПолеФормы"), ЭлементТЗ);
НовыйЭлементФормы.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлементФормы.ПутьКДанным = "ТЗ." + Колонка.Имя;
НовыйЭлементФормы.ВыбиратьТип = Ложь; // Попытка скрыть кнопку выбора типа

Установка свойства ВыбиратьТип = Ложь лишь скрывает визуальную кнопку, но не меняет внутреннюю природу данных. Если реквизит формы, к которому привязано это поле, не имеет жесткого ограничения типа Число с заданной точностью, проблема никуда не исчезнет. Разберем по шагам, как сделать правильно.

Шаг 1. Правильное создание Описания Типов

Ключ к решению задачи лежит в использовании КвалификаторыЧисла. Мы должны явно указать платформе, что реквизит будет содержать число определенной длины и, что самое важное, определенной точности. Выясним причину ошибки: если точность не указана в ОписаниеТипов, система по умолчанию может считать число целым.

Рассмотрим пример создания квалификаторов для числа 15.3:


Квалификаторы = Новый КвалификаторыЧисла(15, 3);
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("Число"));
ОписаниеТипаЧисло = Новый ОписаниеТипов(МассивТипов, , , Квалификаторы);

Такой подход гарантирует, что реквизит формы будет строго типизирован.

Шаг 2. Динамическое добавление реквизитов формы

Теперь объединим создание описания типов с добавлением реквизитов в структуру управляемой формы. Лучший способ — копировать тип данных напрямую из колонок исходной таблицы значений, так как в ТЗ типы обычно уже определены правильно (например, результатом запроса).

Проанализируем правильный цикл обхода колонок:


МассивРеквизитов = Новый Массив;
Для Каждого КолонкаИсточник Из ТЗ_Результат.Колонки Цикл
    // Создаем описание реквизита, полностью копируя тип из колонки ТЗ
    НовыйРеквизит = Новый РеквизитФормы(КолонкаИсточник.Имя, 
                                        КолонкаИсточник.ТипЗначения, 
                                        "ТЗ_НаФорме", 
                                        КолонкаИсточник.Заголовок);
    МассивРеквизитов.Добавить(НовыйРеквизит);
КонецЦикла;

// Применяем изменения к форме
ЭтаФорма.ИзменитьРеквизиты(МассивРеквизитов);

Важный нюанс: при создании РеквизитФормы вторым параметром мы передаем КолонкаИсточник.ТипЗначения. Если в ТЗ колонка была создана с квалификаторами, то и реквизит формы получит их в полном объеме. Именно это устраняет «квадратики» в поле ввода и восстанавливает корректную работу с нулем в дробной части.

Шаг 3. Создание элементов интерфейса

После того как реквизиты (данные) созданы, мы можем приступать к созданию элементов (визуальных полей). Теперь нам не нужно вручную ограничивать типы в свойствах элемента, так как они продиктованы связанным реквизитом.


Для Каждого КолонкаИсточник Из ТЗ_Результат.Колонки Цикл
    ИмяЭлемента = "ТЗ_НаФорме" + КолонкаИсточник.Имя;
    НовыйЭлемент = Элементы.Добавить(ИмяЭлемента, Тип("ПолеФормы"), ЭлементТаблица);
    НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
    НовыйЭлемент.ПутьКДанным = "ТЗ_НаФорме." + КолонкаИсточник.Имя;
    
    // Теперь это свойство действительно сработает правильно, 
    // так как тип реквизита уже однозначно определен
    НовыйЭлемент.РежимРедактирования = РежимРедактированияКолонки.ВходПриВводе;
КонецЦикла;

Дополнительные рекомендации

Рассмотрим несколько полезных советов, которые помогут избежать подобных проблем в будущем:

  1. Проверяйте результат запроса: Если таблица значений формируется методом Выгрузить() из результата запроса, убедитесь, что в самом запросе нет неоднозначности типов. Используйте функцию ВЫРАЗИТЬ(Поле КАК ЧИСЛО(15, 3)), чтобы гарантировать передачу квалификаторов в ТЗ.
  2. Используйте ЗначениеВРеквизитФормы: После создания структуры реквизитов не забывайте загружать в них данные из вашей объектной таблицы значений. Это заставит форму обновить состояние элементов.
  3. Региональные настройки: Помните, что поведение разделителя (точка или запятая) зависит от настроек операционной системы. Однако при правильной типизации ОписаниеТипов платформа автоматически обрабатывает ввод любого системного разделителя корректно, преобразуя его в числовое значение без потери ведущих нулей.

Таким образом, мы выяснили, что проблема «исчезающего нуля» — это не баг платформы, а следствие неявного указания типов данных. Создавая реквизиты формы с четким указанием КвалификаторыЧисла, мы обеспечиваем предсказуемое поведение интерфейса и комфортную работу пользователя с дробными значениями.

← На главную