К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как установить тип реквизита в 1С программно

Как программно задать тип реквизита в 1С через ОписаниеТипов и квалификаторы: примеры кода, составные типы, типичные ошибки и проверка результата.

Тип реквизита в 1С задаётся не только в конфигураторе — его можно установить программно из встроенного языка. Это нужно при создании реквизитов формы на лету, настройке таблиц значений, колонок динамических списков, полей компоновки данных и при передаче значений в произвольные структуры. Центральный объект для этой задачи — ОписаниеТипов, который определяет допустимые типы значения и их квалификаторы (длину строки, точность числа, состав даты).

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

Объект ОписаниеТипов: основа программного задания типа

ОписаниеТипов — это объект встроенного языка, который хранит список допустимых типов и ограничения (квалификаторы) для них. Именно его ожидают большинство методов, создающих реквизиты и колонки. Конструктор имеет несколько вариантов параметров, но чаще всего используется форма: первый параметр — типы (строка с именем типа, массив строк или массив объектов Тип), далее — квалификаторы числа, строки и даты.

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

КвалификаторыСтроки = Новый КвалификаторыСтроки(50, ДопустимаяДлина.Переменная);

ОписаниеСтроки = Новый ОписаниеТипов("Строка", , КвалификаторыСтроки);

Обратите внимание на пропущенный второй параметр: порядок квалификаторов в конструкторе — число, строка, дата, двоичные данные. Если нужен только квалификатор строки, параметр квалификаторов числа пропускается, но запятые сохраняются. Пропуск позиций — частая причина ошибки «Несоответствие типов».

Как задать примитивные типы: строка, число, дата, булево

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

Для числа задаются разрядность (общее количество цифр), разрядность дробной части и признак неотрицательности:

КвалификаторыЧисла = Новый КвалификаторыЧисла(15, 2, ДопустимыйЗнак.Неотрицательный);

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

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

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

Ссылочные типы и составные типы реквизита

Ссылочный тип задаётся именем, например "СправочникСсылка.Номенклатура" или "ДокументСсылка.РеализацияТоваровУслуг". Имя должно точно совпадать с именем объекта метаданных — при ошибке в написании конструктор выбросит исключение уже на этапе создания описания, что упрощает диагностику.

Если реквизит должен принимать значения нескольких типов (составной тип), передайте массив строк или перечислите типы через запятую в одной строке:

МассивТипов = Новый Массив;

МассивТипов.Добавить("СправочникСсылка.Контрагенты");

МассивТипов.Добавить("СправочникСсылка.ФизическиеЛица");

ОписаниеКонтрагента = Новый ОписаниеТипов(МассивТипов);

Для составных типов есть полезные методы: ДобавитьТип() расширяет существующее описание, СодержитТип() проверяет, входит ли тип в состав. Это удобно, когда описание собирается поэтапно по условиям алгоритма. Квалификаторы применяются ко всем подходящим типам состава: квалификатор строки подействует на «Строку» в составе и будет проигнорирован для ссылочных типов.

Установка типа реквизита формы программно

Наиболее востребованный сценарий — добавление реквизита на управляемую форму в модуле формы. Сначала формируется массив объектов РеквизитФормы, затем вызывается метод формы ИзменитьРеквизиты():

ДобавляемыеРеквизиты = Новый Массив;

НовыйРеквизит = Новый РеквизитФормы("Комментарий",

Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(200, ДопустимаяДлина.Переменная)),

"", "Комментарий", Ложь);

ДобавляемыеРеквизиты.Добавить(НовыйРеквизит);

ИзменитьРеквизиты(ДобавляемыеРеквизиты);

Параметры конструктора РеквизитФормы: имя, описание типов, путь (для колонок таблиц — имя таблицы-родителя), заголовок, признак сохранения данных. После ИзменитьРеквизиты() реквизит существует в данных формы, но не виден пользователю, пока вы не создадите элемент формы и не свяжете его с реквизитом через свойство ПутьКДанным.

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

Ограничение: ИзменитьРеквизиты() нельзя вызывать до создания формы (в обработчике ПриСозданииНаСервере — можно, это штатное место), а повторный вызов с тем же именем реквизита вызовет ошибку. Если логика допускает повторное выполнение, проверяйте существование реквизита через ЭтаФорма.ПолучитьРеквизиты() или оборачивайте вызов в попытку с осмысленной обработкой.

Тип колонки таблицы значений и полей СКД

Для таблицы значений тип задаётся третьим параметром метода Колонки.Добавить():

ТЗ = Новый ТаблицаЗначений;

ТЗ.Колонки.Добавить("Наименование", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(100)));

ТЗ.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)));

ТЗ.Колонки.Добавить("Товар", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));

Если колонку не типизировать, она примет любое значение, но это ломает сортировку смешанных типов, итоги по Свернуть() и выгрузку в СКД. Типизация колонок — обязательная практика для таблиц, которые передаются в запросы (как временные таблицы), в схему компоновки или на форму.

В СКД тип поля набора данных задаётся свойством ТипЗначения объекта ПолеНабораДанныхСхемыКомпоновкиДанных, а для вычисляемых полей — аналогично через ТипЗначения. Тот же объект ОписаниеТипов используется при программном построении схемы, например когда источником данных служит внешний набор (таблица значений), и платформа должна знать типы полей для фильтрации и группировки.

Сравнение вариантов

Новый ОписаниеТипов("Строка", ...)

Быстро и читаемо для одного типа. Ограничение: имя типа проверяется только в момент создания, опечатка даст исключение.

Массив объектов Тип

Надёжно для составных типов: Тип("СправочникСсылка.Номенклатура") вычисляется явно. Подходит, когда состав типов формируется динамически по метаданным.

ОписаниеТипов из метаданных

Реквизит.Тип возвращает готовое описание существующего реквизита конфигурации. Оптимально, когда нужно повторить тип «как у документа», не дублируя квалификаторы вручную.

Копирование типа из метаданных и проверка результата

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

МетаданныеДокумента = Метаданные.Документы.РеализацияТоваровУслуг;

ОписаниеТипаСуммы = МетаданныеДокумента.Реквизиты.СуммаДокумента.Тип;

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

Контрольные точки

Как проверить результат

Состав типов описания
Норма

ОписаниеТипов.Типы() возвращает массив с ожидаемыми типами

Тревожный признак

Массив пуст или содержит лишние типы — проверьте параметры конструктора

Приведение значения
Норма

ПривестиЗначение() возвращает значение нужного типа, строка обрезана по длине

Тревожный признак

Значение приводится к Неопределено или пустой ссылке — тип не совпадает

Реквизит на форме
Норма

Элемент формы отображает и редактирует значение без ошибок преобразования

Тревожный признак

Поле недоступно или показывает пустое значение — проверьте ПутьКДанным и порядок ИзменитьРеквизиты

Типичные ошибки и ограничения программного задания типов

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

Отдельно стоит предупредить о производительности: конструктор ОписаниеТипов — относительно «тяжёлая» операция. Если описание нужно многократно (в цикле обработки строк, при повторных вызовах серверных процедур), создайте его один раз и кэшируйте в переменной модуля или параметре сеанса обработки, а не пересоздавайте на каждой итерации.

Типичные ошибки
01
Перепутан порядок квалификаторов в конструкторе — квалификатор строки попадает в позицию числа, итог: исключение или неожиданные ограничения типа
02
Попытка изменить тип реквизита справочника или документа из кода режима предприятия — это невозможно, изменение делается в конфигураторе или расширении
03
Колонка таблицы значений без типа — Свернуть() и сортировка работают некорректно при смешанных значениях
04
Создание элемента формы до ИзменитьРеквизиты() — ошибка «Реквизит не найден», элемент не связывается с данными
05
Пересоздание ОписаниеТипов в цикле — лишняя нагрузка, описание нужно создать один раз и переиспользовать

Часто задаваемые вопросы

Можно ли программно изменить тип реквизита документа в режиме 1С:Предприятие?

Нет. Объекты метаданных в режиме предприятия доступны только для чтения. Изменение типа выполняется в конфигураторе с последующей реструктуризацией базы либо через расширение конфигурации, если речь о добавлении нового реквизита. Программно меняются только типы реквизитов форм, таблиц значений и полей СКД.

Как задать реквизит, который может хранить и строку, и ссылку?

Создайте составной тип: передайте в конструктор массив из имён типов, например "Строка" и "СправочникСсылка.Номенклатура". Квалификатор строки при этом применится только к строковой части состава.

Чем отличается ДопустимаяДлина.Фиксированная от Переменная?

Фиксированная длина дополняет строку пробелами справа до указанного размера — значение «АБВ» при длине 10 станет «АБВ» с семью пробелами. Переменная длина лишь ограничивает максимум без дополнения. Для реквизитов форм почти всегда нужна переменная длина.

Как проверить, подходит ли значение под созданное описание типов?

Используйте метод СодержитТип(ТипЗнч(Значение)) для проверки типа и ПривестиЗначение(Значение) для безопасного приведения: метод вернёт значение, приведённое к описанию, либо пустое значение соответствующего типа, если приведение невозможно.

Почему Свернуть() таблицы значений не суммирует мою колонку?

Скорее всего, колонка создана без типа или с типом, отличным от Число. Свернуть() суммирует только числовые колонки. Добавьте колонку с описанием Новый ОписаниеТипов("Число", квалификаторы) и пересоздайте таблицу.

Можно ли получить ОписаниеТипов из существующего реквизита формы?

Да, через ПолучитьРеквизиты() формы: у объекта ОписаниеРеквизитаФормы есть свойство ТипЗначения, содержащее готовое ОписаниеТипов. Его можно переиспользовать при создании других реквизитов или колонок с идентичным типом.

Итог

Что важно запомнить

Программная установка типа реквизита в 1С строится на объекте ОписаниеТипов с квалификаторами строки, числа и даты. Описание передаётся в РеквизитФормы, Колонки.Добавить() или поля СКД. Типы реквизитов объектов конфигурации из кода не меняются — только через конфигуратор. Перед реструктуризацией данных обязательно делайте резервную копию базы.