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

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

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

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

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

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

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

Объект ОписаниеТипов — основа программной типизации

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

Конструктор объекта принимает несколько вариантов параметров. Самый распространённый — строка с именами типов через запятую и квалификаторы:

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

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

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

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

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

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

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

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

Квалификаторы: длина строки, точность числа, состав даты

Квалификаторы часто становятся источником скрытых ошибок. Если создать описание типа "Строка" без квалификаторов, платформа трактует длину как неограниченную. Для реквизита формы это допустимо, но при выгрузке в СУБД-подобные структуры или при сравнении значений неограниченная строка может вести себя иначе, чем ожидалось.

Для чисел порядок параметров в КвалификаторыЧисла — сначала общая длина (разрядность), затем число знаков после запятой, затем допустимость знака (ДопустимыйЗнак.Любой или Неотрицательный). Частая ошибка — перепутать разрядность и точность: Новый КвалификаторыЧисла(2, 15) даст число всего из двух разрядов, а не «пятнадцать с двумя знаками».

Для даты квалификатор определяет, хранится ли только дата, только время или оба компонента. Если реквизит создаётся для отбора по периоду, обычно достаточно ЧастиДаты.Дата; для меток времени документов нужен ЧастиДаты.ДатаВремя.

Типичные ошибки с квалификаторами
01
Перепутан порядок параметров КвалификаторыЧисла — вместо (15, 2) указано (2, 15), значения обрезаются до двух разрядов
02
Строка создана без квалификатора длины — при выгрузке или индексации неограниченная строка вызывает ограничения и ошибки
03
Для даты указан состав Дата, а прикладной код записывает дату со временем — время теряется без предупреждения

Как задать тип колонки таблицы значений и дерева значений

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

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

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

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

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

Если тип не указать, колонка получит произвольный тип — в неё можно записать что угодно. Это удобно на этапе прототипирования, но замедляет работу на больших объёмах и мешает контролю данных: опечатка в логике заполнения останется незамеченной, пока значение не попадёт в отчёт или проведение документа.

Для дерева значений синтаксис идентичен — колонки добавляются через Дерево.Колонки.Добавить() с тем же параметром типа. Обратите внимание: если колонка должна содержать ссылки на разные виды справочников, перечислите все нужные типы в одной строке через запятую, например "СправочникСсылка.Номенклатура,СправочникСсылка.Контрагенты".

Как программно добавить реквизит формы с нужным типом

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

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

НовыйРеквизит = Новый РеквизитФормы("АдресДоставки",

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

"", "Адрес доставки", Ложь);

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

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

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

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

Составной тип и тип «произвольный»

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

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

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

Ограничения: что нельзя сделать в режиме предприятия

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

Если требуется «добавить» реквизит без изменения конфигурации, используются штатные механизмы: дополнительные реквизиты и сведения (в конфигурациях на БСП), значения свойств, хранение произвольных данных в реквизитах типа ХранилищеЗначения. Тип значения дополнительного реквизита в этом случае задаётся интерактивно в настройках, а программно — через соответствующие объекты библиотеки.

Также помните о безопасности: динамическое конструирование типа по строке, полученной извне (например, из пользовательской настройки), требует проверки. Вызов Тип() с несуществующим именем вызовет исключение, поэтому оборачивайте получение типа в попытку/исключение и задавайте поведение по умолчанию.

Проверка результата и контроль типов в коде

После установки типа полезно убедиться, что платформа применила его так, как задумано. Для таблиц значений тип колонки читается обратно: Таблица.Колонки["Количество"].ТипЗначения вернёт объект ОписаниеТипов, у которого можно проверить метод СодержитТип().

Для проверки конкретного значения на соответствие типу нет отдельной «валидации реквизита» — контроль выполняется в момент присваивания. Если записать в типизированную колонку значение несовместимого типа, платформа либо приведёт его (например, число в строку — нет, не приведёт), либо запишет Неопределено/пустое значение, либо вызовет ошибку — поведение зависит от контекста. Поэтому перед записью используйте явную проверку:

Если НЕ ОписаниеТипа.СодержитТип(ТипЗнч(НовоеЗначение)) Тогда

ВызватьИсключение "Недопустимый тип значения для реквизита";

КонецЕсли;

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

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

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

Тип колонки после добавления
Норма

Свойство ТипЗначения содержит нужный ОписаниеТипов

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

ТипЗначения пуст или содержит лишние типы

Запись тестового значения
Норма

Значение записывается без потерь и приведений

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

Значение обрезается, обнуляется или возникает исключение

Реквизит формы после ИзменитьРеквизиты
Норма

Реквизит виден в отладчике и связан с элементом формы

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

Реквизит создан, но элемент формы не отображает данные

Частые вопросы

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

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

Как задать реквизиту тип «ссылка на любой справочник»?

Передайте в конструктор ОписаниеТипов строку «СправочникСсылка» без указания вида — это включит все существующие виды справочников. Аналогично работают «ДокументСсылка», «ПеречислениеСсылка», «ПланВидовХарактеристикСсылка». Учтите, что такой широкий тип снижает контроль ввода и усложняет отладку.

Почему строка обрезается, хотя тип указан как «Строка»?

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

Как получить ОписаниеТипов из уже существующего реквизита объекта?

Через метаданные: например, Метаданные.Справочники.Номенклатура.Реквизиты["ЕдиницаИзмерения"].Тип вернёт готовый объект ОписаниеТипов, который можно переиспользовать при создании колонок таблицы значений или реквизитов формы. Это удобный способ гарантировать совместимость типов.

Что быстрее: создавать ОписаниеТипов каждый раз или хранить готовый?

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

Можно ли сузить тип колонки таблицы значений после её заполнения?

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

Итог

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

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