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

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

Составной тип данных в 1С: настройка и практическое применение

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

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

Задача «выразить как составной тип» возникает в трёх типичных ситуациях: при создании нового реквизита в конфигураторе, при работе со значением составного типа в коде (когда нужно определить, что именно лежит в реквизите) и при построении запросов, где платформа требует явного приведения типа через ВЫРАЗИТЬ. Каждая из этих ситуаций решается по-разному, и ошибки в них приводят к разным последствиям — от неудобного интерфейса до падения производительности запросов.

Ниже разобраны практические приёмы: как включить составной тип в свойствах реквизита, как безопасно работать с ним на встроенном языке, как использовать оператор ВЫРАЗИТЬ в запросах и какие ограничения нужно учитывать, чтобы не заложить проблемы в структуру данных.

Что такое составной тип и когда он оправдан

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

Составной тип оправдан, когда бизнес-логика действительно допускает разнородные значения: документ может быть введён на основании пяти разных документов, аналитика затрат может ссылаться на разные справочники, а значение дополнительного свойства может быть числом, строкой или ссылкой. Типовой пример — реквизит «Значение» в механизме дополнительных реквизитов и сведений.

Составной тип не стоит применять «на всякий случай». Каждое лишнее ссылочное значение в составе типа увеличивает количество колонок в таблице СУБД, усложняет запросы и замедляет соединения. Если реквизит всегда хранит один тип — составной тип только навредит.

Настройка составного типа в конфигураторе

Чтобы сделать реквизит составным, откройте его палитру свойств и найдите поле «Тип». По умолчанию там выбран один тип. Нажмите кнопку выбора — откроется окно редактирования типа данных, где можно отметить флажками несколько категорий: примитивные типы (Число, Строка, Дата, Булево) и ссылочные типы (конкретные справочники, документы, перечисления, планы видов характеристик).

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

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

Как включить составной тип реквизита
  1. 1
    Откройте объект конфигурации и выделите нужный реквизит.
  2. 2
    В палитре свойств найдите поле «Тип» и нажмите кнопку выбора.
  3. 3
    В окне редактирования отметьте флажками нужные типы: примитивные и/или конкретные ссылочные объекты.
  4. 4
    Проверьте параметры примитивных типов (длина строки, точность числа).
  5. 5
    Сохраните конфигурацию и выполните обновление конфигурации базы данных.
  6. 6
    Откройте объект в режиме предприятия и убедитесь, что поле принимает значения всех заявленных типов.

Работа с составным типом в коде

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

Если ТипЗнч(Основание) = Тип("ДокументСсылка.ЗаказКлиента") Тогда

// работаем как с заказом

ИначеЕсли ТипЗнч(Основание) = Тип("ДокументСсылка.СчетНаОплату") Тогда

// работаем как со счётом

КонецЕсли;

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

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

Типичные ошибки
01
Обращение к реквизиту как к конкретному типу без проверки ТипЗнч() — при другом типе значения код падает с ошибкой.
02
Включение в состав типа всех справочников «про запас» — таблица в СУБД раздувается, запросы замедляются.
03
Сравнение составного поля со ссылкой напрямую в запросе без ВЫРАЗИТЬ — соединение не срабатывает или выполняется по всем типам медленно.
04
Изменение состава типа в рабочей базе без анализа уже записанных данных — старые значения могут оказаться недопустимого типа.

Составной тип в запросах и оператор ВЫРАЗИТЬ

Именно в запросах составной тип чаще всего требует явной обработки. Если соединить таблицу по составному полю напрямую, платформа построит соединение по всем возможным типам — это замедляет выполнение и может давать лишние строки. Правильный приём — привести поле к конкретному типу оператором ВЫРАЗИТЬ:

ВЫБРАТЬ

ВЫРАЗИТЬ(Регистр.Аналитика КАК Справочник.Номенклатура) КАК Номенклатура

ИЗ

РегистрСведений.Цены КАК Регистр

ГДЕ

Регистр.Аналитика ССЫЛКА Справочник.Номенклатура

Оператор ВЫРАЗИТЬ не преобразует данные, а указывает платформе трактовать поле как заданный тип. Значения других типов в результате дадут NULL. Поэтому ВЫРАЗИТЬ обычно сочетают с проверкой ССЫЛКА или с условием по типу, чтобы отфильтровать нужные записи.

Дополнительное применение ВЫРАЗИТЬ — усечение строк и чисел в запросе. Для составного поля со строкой переменной длины приведение вида ВЫРАЗИТЬ(Поле КАК Строка(100)) позволяет корректно группировать и сравнивать значения, что иначе невозможно для неограниченных строк.

bsl
ВЫБРАТЬ
	ВЫРАЗИТЬ(Док.Основание КАК Документ.ЗаказКлиента).Номер КАК НомерЗаказа
ИЗ
	Документ.РеализацияТоваров КАК Док
ГДЕ
	Док.Основание ССЫЛКА Документ.ЗаказКлиента

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

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

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

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

Альтернативы составному типу

Если составной тип нужен только для хранения «чего угодно», рассмотрите более лёгкие механизмы. План видов характеристик с составным типом значения — стандартный способ хранить разнородные параметры без распухания основных таблиц. Механизм дополнительных реквизитов и сведений в типовых конфигурациях построен именно на этой идее.

Для ссылок «на любой документ-основание» иногда лучше подходит определяемый тип — он позволяет централизованно управлять составом типа сразу для группы объектов и менять его в одном месте. Это снижает риск рассинхронизации составов типов в разных объектах конфигурации.

Наконец, если составной тип появился из-за попытки объединить два разных справочника (например, «Организации» и «Физлица» в одном поле «Контрагент»), подумайте о выделении общего родительского справочника. Единая ссылка упрощает запросы, отчёты и обмены сильнее, чем составной тип.

Варианты решения

Составной тип реквизита

Подходит, когда значений немного и типы строго ограничены. Минус — тяжёлая структура таблицы и сложные запросы.

Определяемый тип

Подходит для единого состава типа, используемого в нескольких объектах. Удобен централизованным изменением.

План видов характеристик

Подходит для разнородных дополнительных свойств. Не заменяет реквизит в основной логике документа.

Общий родительский справочник

Подходит, когда разные типы логически являются одной сущностью. Требует переработки структуры данных.

Проверка результата и типичные проблемы

После настройки составного типа проверьте три вещи. Во-первых, ввод данных: в режиме предприятия поле должно предлагать выбор типа и принимать значения всех заявленных типов. Во-вторых, запросы: все соединения и отборы по составному полю должны использовать ВЫРАЗИТЬ или ССЫЛКА. В-третьих, обмены и печатные формы: убедитесь, что значения всех типов корректно выводятся и передаются.

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

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

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

Ввод значений в режиме предприятия
Норма

Поле предлагает выбор типа и сохраняет значения всех заявленных типов

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

Часть типов недоступна для выбора или значение очищается после записи

Запросы с соединением по составному полю
Норма

Используется ВЫРАЗИТЬ и/или условие ССЫЛКА, результат без лишних строк

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

Соединение по «сырому» полю, дубли строк, медленное выполнение

Данные после изменения состава типа
Норма

Все ранее записанные значения сохранились и читаются

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

Значения исключённых типов очищены реструктуризацией

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

Можно ли сделать составной тип в уже заполненной базе?

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

Чем ВЫРАЗИТЬ отличается от ССЫЛКА в запросе?

ВЫРАЗИТЬ приводит поле к указанному типу и позволяет обращаться к его реквизитам, значения других типов дают NULL. Проверка ССЫЛКА — это логическое условие: она отбирает только записи нужного типа, но не меняет трактовку поля. На практике их обычно комбинируют.

Почему сравнение составного поля со ссылкой в запросе не работает?

Потому что платформа не знает, по какому из типов состава выполнять сравнение, и либо строит тяжёлое условие по всем типам, либо результат отличается от ожидаемого. Приведите поле к конкретному типу через ВЫРАЗИТЬ и сравнивайте уже приведённое значение.

Сколько типов можно включить в состав одного реквизита?

Жёсткого пользовательского лимита нет, но каждый ссылочный тип добавляет колонки в таблицу СУБД и утяжеляет запросы. Практическая рекомендация — включать только реально используемые типы и избегать состава «все справочники» без необходимости.

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

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

Что лучше для «ссылки на любой документ» — составной тип или определяемый тип?

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

Итог

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

Составной тип включается в палитре свойств реквизита выбором нескольких типов. В коде значение проверяют через ТипЗнч(), в запросах приводят через ВЫРАЗИТЬ с отбором по ССЫЛКА. Не расширяйте состав без необходимости и не сокращайте его без проверки данных — при реструктуризации значения исключённых типов удаляются.