Почему в программно добавленную колонку формы не вводится дробное число меньше 1?

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

При программной работе с элементами управляемых форм можно столкнуться с неочевидным поведением. Рассмотрим одну из таких ситуаций: вы динамически добавляете на форму колонки с числовым типом данных. Все работает, но при попытке ввести в поле дробное число меньше единицы, например 0,95, ничего не получается — система либо игнорирует ввод, либо ведет себя некорректно. При этом числа больше единицы, например 4,95, вводятся без проблем. Разберемся, почему так происходит и как это исправить.

Анализ исходного кода и причина проблемы

Проанализируем ситуацию, с которой столкнулся автор. Имеется код, который в цикле создает реквизиты и связанные с ними поля на форме для табличной части Товары.

Вот первоначальный вариант кода:


Для каждого стр из Объект.Клиенты цикл        
    МассивРеквизитов = Новый Массив;         
    ТмяКол = "Колонка"+стр.НомерСтроки;
    МассивРеквизитов.Добавить(Новый РеквизитФормы(ТмяКол, Новый ОписаниеТипов("Число"), "Объект.Товары", Лев(стр.Контрагент.Наименование,4)+" "+Стр.Договор, Ложь));
    ИзменитьРеквизиты( МассивРеквизитов );
    
    Эл = Элементы.Добавить(ТмяКол, Тип("ПолеФормы"), Элементы.Товары);
    Эл.Вид = ВидПоляФормы.ПолеВвода;
    Эл.ПутьКДанным = "Объект.Товары."+ТмяКол;         
КонецЦикла;

На первый взгляд, все выглядит корректно. Мы создаем новый реквизит формы с помощью конструктора Новый РеквизитФормы. В качестве типа данных передаем Новый ОписаниеТипов("Число"). Именно здесь и кроется корень проблемы.

Когда мы указываем тип "Число" без дополнительных уточнений, платформа 1С использует настройки по умолчанию. Эти настройки не содержат явной информации о разрядности и точности (количестве знаков после запятой). В большинстве случаев это работает, но при динамическом создании элементов формы такая неопределенность может приводить к сбоям в работе поля ввода. Система не может корректно интерпретировать ввод пользователя: например, при вводе "0,95" она может "потерять" ноль с запятой и оставить только "95", так как не понимает, что от нее требуется обработка дробной части.

Ключевая причина — отсутствие явных квалификаторов для числового типа данных, что приводит к некорректной работе элемента управления на форме.

Решение: Явное указание квалификаторов числа

Чтобы решить проблему, необходимо предоставить платформе точную информацию о формате числа, который мы ожидаем. Для этого в 1С существует специальный объект — КвалификаторыЧисла.

Этот объект позволяет задать три основных параметра:

  1. Разрядность — общее количество цифр в числе.
  2. Точность — количество цифр в дробной части (после запятой).
  3. Допустимый знак — определяет, могут ли числа быть отрицательными (Любой), только положительными (Неотрицательный) или только отрицательными (Неположительный).

Для исправления нашего кода нужно выполнить два простых шага:

  1. Создать экземпляр объекта КвалификаторыЧисла с нужными параметрами.
  2. Передать этот объект в конструктор ОписаниеТипов при создании реквизита.

Посмотрим на исправленный код:


Для каждого стр из Объект.Клиенты цикл
    // Шаг 1: Создаем объект квалификаторов
    КвалификаторыЧисла = Новый КвалификаторыЧисла(10, 2, ДопустимыйЗнак.Неотрицательный);

    МассивРеквизитов = Новый Массив;
    ТмяКол = "Колонка"+стр.НомерСтроки;

    // Шаг 2: Передаем квалификаторы при создании описания типов
    ОписаниеЧисловогоТипа = Новый ОписаниеТипов("Число", , , , КвалификаторыЧисла); // Вариант, который сработал у автора
    
    МассивРеквизитов.Добавить(Новый РеквизитФормы(ТмяКол, ОписаниеЧисловогоТипа, "Объект.Товары", Лев(стр.Контрагент.Наименование,4)+" "+Стр.Договор, Ложь));
    ИзменитьРеквизиты( МассивРеквизитов );
    
    Эл = Элементы.Добавить(ТмяКол, Тип("ПолеФормы"), Элементы.Товары);
    Эл.Вид = ВидПоляФормы.ПолеВвода;
    Эл.ПутьКДанным = "Объект.Товары."+ТмяКол; 
КонецЦикла;

В этом примере мы задали число с общей длиной до 10 знаков, из которых 2 знака отводятся под дробную часть, и разрешили ввод только неотрицательных значений. После такого явного указания платформа корректно настраивает поле ввода, и проблема с вводом дробных чисел, начинающихся с нуля, исчезает.

Нюансы синтаксиса конструктора `ОписаниеТипов`

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

Новый ОписаниеТипов(<Типы>, <КвалификаторыЧисла>, <КвалификаторыСтроки>, <КвалификаторыДаты>, ...)

Платформа 1С имеет несколько перегруженных версий конструктора, и в некоторых случаях она может "простить" такую запись, правильно интерпретировав намерение. Однако для чистоты, читаемости и надежности кода рекомендуется использовать стандартный, документированный синтаксис.

Более правильный и рекомендуемый вариант кода:


// ...
КвалификаторыЧисла = Новый КвалификаторыЧисла(10, 2, ДопустимыйЗнак.Неотрицательный);
    
// Квалификатор передается вторым параметром
ОписаниеЧисловогоТипа = Новый ОписаниеТипов("Число", КвалификаторыЧисла);
    
МассивРеквизитов.Добавить(Новый РеквизитФормы(ТмяКол, ОписаниеЧисловогоТипа, "Объект.Товары", ...));
// ...

Или в одну строку для краткости:


// ...
МассивРеквизитов.Добавить(Новый РеквизитФормы(ТмяКол, 
                          Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 2, ДопустимыйЗнак.Неотрицательный)), 
                          "Объект.Товары", 
                          ...));
// ...

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

← На главную