Как изменить разрядность числового реквизита в расширении 1С при его программном создании?

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

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

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

Анализ проблемы: почему изменения в метаданных не всегда работают

Рассмотрим стандартную ситуацию: у нас есть документ, добавленный в расширение. Мы увеличили точность реквизита в основной конфигурации и в расширении, добились того, чтобы расширение подключалось без ошибок (соответствие типов соблюдено), но в режиме "1С:Предприятие" точность в табличной части осталась прежней. Проанализируем причину: это происходит потому, что реквизиты формы или элементы интерфейса создаются динамически через метод ИзменитьРеквизиты().

Когда реквизит создается программно, в его конструктор передается объект ОписаниеТипов. Если этот объект берется из существующего реквизита объекта (который еще не обновился в памяти или имеет свои особенности заимствования), то он сохраняет старые квалификаторы (например, 1 знак после запятой вместо 3).

Почему нельзя изменить разрядность напрямую в существующем типе?

Типичная ошибка начинающего разработчика — попытка обратиться к свойствам типа напрямую и перезаписать их. Посмотрим на этот пример кода:


Если Реквизит.Имя = "Количество" Или Реквизит.Имя = "КоличествоСклад" Тогда
    // Попытка прямого изменения — вызовет ошибку "Поле объекта не доступно для записи"
    Реквизит.Тип.КвалификаторыЧисла.РазрядностьДробнойЧасти = 3; 
КонецЕсли;

Важно помнить: объекты ОписаниеТипов и КвалификаторыЧисла в 1С являются неизменяемыми после создания. Вы не можете просто зайти в свойство существующего типа и поменять его параметры. Единственный верный способ — создать новый объект ОписаниеТипов с нужными параметрами и заменить им старый при создании реквизита формы.

Пошаговое решение: программное переопределение типа данных

Разберем правильный алгоритм действий. Для того чтобы изменить точность программно создаваемого реквизита, нам нужно выполнить следующие шаги:

  1. Определить нужные квалификаторы числа (общая длина и точность). При внедрении таких изменений в несколько информационных систем упростить обслуживание поможет программа для автоматического архивирования и тестирования баз 1С.
  2. Создать новый объект ОписаниеТипов на основе этих квалификаторов.
  3. Использовать этот объект при создании РеквизитФормы.
  4. При необходимости обновить формат отображения на форме. Для точечного переноса объектов между базами с различающимися реквизитами можно применить обработку для миграции данных между похожими конфигурациями.

Рассмотрим реализацию в коде. Обратите внимание на синтаксис конструктора КвалификаторыЧисла: параметры передаются через запятую, а не через точку.


// 1. Создаем квалификаторы числа: общая длина 15, точность 3, только положительное
НовыеКвалификаторы = Новый КвалификаторыЧисла(15, 3, ДопустимыйЗнак.Неотрицательный);

// 2. Формируем новое описание типов
ТипЧисло = Новый ОписаниеТипов("Число", , , НовыеКвалификаторы);

// 3. Добавляем в массив реквизитов для метода ИзменитьРеквизиты
МассивРеквизитов = Новый Массив;
Если Реквизит.Имя = "Количество" Тогда
    // Используем созданный нами ТипЧисло вместо стандартного Реквизит.Тип
    МассивРеквизитов.Добавить(Новый РеквизитФормы(Реквизит.Имя, ТипЧисло, "ВашПутьКДанным", "Синоним"));
Иначе
    МассивРеквизитов.Добавить(Новый РеквизитФормы(Реквизит.Имя, Реквизит.Тип, "ВашПутьКДанным", "Синоним"));
КонецЕсли;

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

Обеспечение визуального отображения (Формат)

Даже если тип данных в реквизите формы теперь позволяет хранить 3 знака после запятой, само ПолеФормы (визуальный элемент) может быть настроено на отображение только одного знака. Выясним, как это исправить программно при создании элемента формы:


// Создаем элемент формы
НовыйЭлемент = Элементы.Добавить("Количество", Тип("ПолеФормы"), ГруппаРодитель);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.ПутьКДанным = "Объект.Товары.Количество";

// Устанавливаем формат отображения и редактирования
// ЧЦ (Число цифр) = 15, ЧДЦ (Число десятичных цифр) = 3
НовыйЭлемент.Формат = "ЧЦ=15; ЧДЦ=3";
НовыйЭлемент.ФорматРедактирования = "ЧЦ=15; ЧДЦ=3";

Без установки свойств Формат и ФорматРедактирования платформа может использовать настройки по умолчанию из метаданных, что приведет к визуальному округлению значения при вводе, даже если сам реквизит поддерживает большую точность.

Приведение значений и ограничение типа

В некоторых случаях, если вы меняете тип уже существующего на форме реквизита (через удаление и добавление), полезно принудительно привести текущее значение к новому типу, чтобы избежать конфликтов при записи данных в объект.


// Пример приведения значения
ТипЧисло = Новый ОписаниеТипов("Число",,, Новый КвалификаторыЧисла(10, 3));
Элементы.Реквизит1.ОграничениеТипа = ТипЧисло;
Объект.Реквизит1 = ТипЧисло.ПривестиЗначение(Объект.Реквизит1);

Метод ПривестиЗначение() гарантирует, что переменная будет содержать число именно с теми квалификаторами, которые мы задали, отсекая лишние знаки или дополняя их нулями.

Заключение и рекомендации

Проанализировав ситуацию, можно сделать вывод: при работе в расширениях 1С всегда проверяйте, как именно создаются реквизиты. Если они заимствованы визуально — меняйте свойства в дереве метаданных расширения. Если они создаются в коде (особенно в процедурах типа ПриСозданииНаСервере) — используйте создание нового объекта ОписаниеТипов.

Основные правила:

  1. Не пытайтесь менять свойства КвалификаторыЧисла у существующего типа — они только для чтения.
  2. Всегда используйте конструктор Новый КвалификаторыЧисла(Длина, Точность).
  3. Синхронизируйте изменения: тип в метаданных расширения должен совпадать с типом программного реквизита. Для контроля корректности данных после подобных доработок удобно использовать автоматическую сверку бухгалтерских и налоговых проводок между базами.
  4. Не забывайте про свойство Формат у элементов формы, иначе пользователь не увидит введенные сотые и тысячные доли.

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

← На главную