Разработка и Конфигурация · 11 мин
Тип документа как реквизит в 1С: как настроить и использовать
Как использовать тип документа как реквизит в 1С: составной тип, ДокументСсылка, настройка в конфигураторе, запросы, типовые ошибки и проверка результата.
В конфигурациях 1С часто возникает задача: в справочнике, документе или регистре нужно хранить ссылку на какой-либо документ, причём заранее неизвестно, какого именно вида он будет. Например, в задаче указывается документ-основание, в регистре сведений фиксируется источник записи, а в справочнике «Вложения» — объект, к которому прикреплён файл. Для этого реквизиту назначают тип «ДокументСсылка» — либо конкретный, либо составной, охватывающий несколько видов документов или все сразу.
Такой подход отличается от хранения строки с названием документа или его номера. Ссылка — это полноценная связь с объектом базы: по ней можно перейти к документу, получить его реквизиты через точку, использовать в запросах и проверять на заполненность. Платформа контролирует целостность: при попытке удалить документ, на который есть ссылки, сработает контроль ссылочной целостности.
Ниже разобрано, как создать такой реквизит в конфигураторе, как работать с ним в коде и запросах, какие ограничения есть у составных типов и какие ошибки встречаются чаще всего.
Как создать реквизит с типом «ДокументСсылка» в конфигураторе
Откройте конфигуратор, найдите нужный объект (справочник, документ, регистр сведений или план видов характеристик) и перейдите на вкладку «Данные». Добавьте новый реквизит и в поле «Тип» нажмите кнопку выбора. В диалоге редактирования типа разверните ветку «ДокументСсылка» и отметьте флажками те виды документов, которые разрешено хранить.
Если отметить один вид — реквизит будет строго типизированным: пользователь сможет выбрать только документы этого вида, а платформа не даст записать ссылку другого типа. Если отметить несколько видов или все — получится составной тип. Именно составной тип обычно имеют в виду, когда говорят «тип документа как реквизит».
После изменения типа реквизита обновите конфигурацию базы данных (F7 или через меню «Конфигурация — Обновить конфигурацию базы данных»). Если реквизит уже содержал данные другого типа, платформа при реструктуризации попытается их преобразовать, а несовместимые значения очистит — поэтому перед изменением типа в рабочей базе сделайте резервную копию.
- 1Откройте объект в конфигураторе и перейдите на вкладку «Данные»
- 2Добавьте реквизит и откройте диалог редактирования типа
- 3В ветке «ДокументСсылка» отметьте нужные виды документов
- 4Установите признаки: обязательность, индексация, проверка заполнения
- 5Обновите конфигурацию базы данных и проверьте ввод значения в режиме предприятия
Составной тип: когда указывать все документы, а когда — ограниченный список
Соблазн отметить все виды документов понятен: не придётся возвращаться к настройке, когда появится новый сценарий. Но у составного типа есть цена. Поле ввода с составным типом работает медленнее при больших объёмах, список выбора перегружен, а пользователь может указать документ, который по смыслу не подходит — например, выбрать «Реализацию товаров» там, где ожидается «Заказ клиента».
Практическое правило: отмечайте только те виды документов, которые реально могут появиться в реквизите по бизнес-логике. Если заранее известно, что основанием задачи может быть заказ, счёт или реализация — отметьте три вида, а не все сорок. Это упростит интерфейс, ускорит запросы и снизит число ошибок ввода.
Отдельный случай — когда реквизит должен хранить не только документы, но и элементы справочников. Тогда в состав типа добавляют и ветку «СправочникСсылка». Так устроен, например, типовой реквизит «Владелец» у присоединённых файлов.
Сравнение вариантов
Строгий контроль, быстрые запросы и индексы. Не подходит, если источники разнородные
Гибкость при сохранении контроля. Требует проверки фактического типа в коде
Универсально, но перегружает интерфейс и замедляет работу; оправдано для служебных регистров связей
Только для отображения: нет перехода к объекту, нет ссылочной целостности, поиск ненадёжен
Работа с реквизитом в коде: проверка типа и получение данных
Когда реквизит составной, код должен уметь определять, ссылка на какой вид документа в нём записана. Для этого используют функцию ТипЗнч() и сравнение с Тип("ДокументСсылка.ИмяДокумента"):
Если ТипЗнч(Объект.ДокументОснование) = Тип("ДокументСсылка.ЗаказКлиента") Тогда
// логика для заказа
ИначеЕсли ТипЗнч(Объект.ДокументОснование) = Тип("ДокументСсылка.РеализацияТоваровУслуг") Тогда
// логика для реализации
КонецЕсли;
Альтернатива — получить метаданные через ссылку: Объект.ДокументОснование.Метаданные().Имя вернёт имя вида документа строкой. Это удобно, когда ветвлений много и логика выбирается по имени. Для проверки заполненности используйте ЗначениеЗаполнено() — она корректно распознаёт пустые ссылки любого вида документа из состава типа.
Через точку от ссылки доступны реквизиты документа: Объект.ДокументОснование.Номер, Объект.ДокументОснование.Дата. Учтите, что каждое такое обращение к составной ссылке — это обращение к базе; в циклах по многим строкам выгоднее один раз выбрать данные запросом.
Составной реквизит в запросах и отчётах
В запросах ссылку составного типа можно сравнивать с параметром и проверять через ВЫРАЗИТЬ. Оператор ВЫРАЗИТЬ(Поле КАК Документ.ЗаказКлиента) приводит значение к конкретному типу: если фактический тип другой, результат будет NULL. Это стандартный приём для соединений:
ВЫБРАТЬ
Задачи.ДокументОснование КАК Основание,
ВЫРАЗИТЬ(Задачи.ДокументОснование КАК Документ.ЗаказКлиента).СуммаДокумента КАК СуммаЗаказа
ИЗ
Задача.Задачи КАК Задачи
Для отбора по виду документа без приведения используйте функцию ТИПЗНАЧЕНИЯ() в сочетании с ТИП(): ГДЕ ТИПЗНАЧЕНИЯ(Задачи.ДокументОснование) = ТИП(Документ.ЗаказКлиента). В СКД такие условия работают и в отборах, но помните: сравнение по типу не использует индекс эффективно, поэтому на больших таблицах запросы с ТИПЗНАЧЕНИЯ могут выполняться заметно дольше.
ВЫБРАТЬ
Связи.Объект,
Связи.Документ
ИЗ
РегистрСведений.СвязиОбъектов КАК Связи
ГДЕ
ТИПЗНАЧЕНИЯ(Связи.Документ) = ТИП(Документ.ЗаказКлиента)Индексация, производительность и ограничения
Если по реквизиту часто ищут или соединяют таблицы, включите для него индексирование (свойство «Индексировать» в конфигураторе). Для измерений регистров сведений индекс создаётся автоматически. Составной тип хранится в базе как пара «тип + ссылка», поэтому индекс по такому полю менее селективен, чем по однотипному, но всё равно заметно ускоряет типовые выборки.
Есть и ограничения. Составной тип нельзя использовать в некоторых контекстах: например, критерии отбора и планы обмена имеют собственные требования к составу типов, а поле составного типа не всегда корректно работает как измерение плана счетов или вид субконто — там предпочтительнее однотипные ссылки. Также помните, что ввод по строке в поле с составным типом ищет по всем отмеченным видам, что при больших журналах ощутимо нагружает сервер.
Типовые ошибки и как их избежать
Самая частая ошибка — обращение через точку к реквизиту, которого нет у фактического вида документа: код падает с ошибкой «Поле объекта не обнаружено». Лечится проверкой ТипЗнч() или запросом с ВЫРАЗИТЬ. Вторая типичная ситуация — сравнение ссылки со строкой или числом: Если Объект.Основание = "ЗаказКлиента" всегда ложно, потому что сравниваются несовместимые типы.
Третья группа ошибок — прикладная: пользователи выбирают документ не того вида, потому что состав типа слишком широк, а проверки заполнения в модуле объекта не настроены. Добавьте в ОбработкаПроверкиЗаполнения контроль допустимых типов, если бизнес-логика жёстче, чем состав типа реквизита.
Проверка результата после настройки
После обновления конфигурации проверьте реквизит в пользовательском режиме: откройте форму объекта, убедитесь, что в поле выбора доступны ровно те виды документов, которые отмечены в составе типа. Выберите документ, запишите объект, закройте и откройте заново — ссылка должна сохраниться и отображаться корректным представлением.
Затем проверьте программный сценарий: выполните код, который читает реквизит, для записей с разными видами документов и для пустого значения. Если реквизит участвует в отчёте — сформируйте отчёт и убедитесь, что строки с разными типами оснований выводятся без ошибок и с корректными данными.
Как проверить результат
Доступны только отмеченные виды документов
В списке лишние виды или нет нужных
Ссылка сохраняется, представление корректное
Значение очищается или показывает «Объект не найден»
Ветки по ТипЗнч() отрабатывают без ошибок
Ошибка «Поле объекта не обнаружено»
Все типы оснований выводятся, отборы работают
Пустые строки, NULL или долгое формирование
Что важно запомнить
Тип документа как реквизит реализуется через «ДокументСсылка» с нужным составом типов. Отмечайте только необходимые виды, проверяйте фактический тип через ТипЗнч() или ВЫРАЗИТЬ в запросах, индексируйте реквизит при поиске по нему и меняйте тип в рабочей базе только после резервного копирования.
Частые вопросы
Можно ли сделать реквизит, который хранит и документы, и справочники?
Да. В диалоге редактирования типа отметьте нужные виды и в ветке «ДокументСсылка», и в ветке «СправочникСсылка». Такой составной тип типичен для реквизитов вроде «Владелец файла» или «Объект связи». В коде проверяйте фактический тип через ТипЗнч() перед обращением к реквизитам объекта.
Чем отличается ДокументСсылка от ДокументОбъект?
ДокументСсылка — это лёгкая ссылка на запись в базе: по ней доступны номер, дата и другие реквизиты через точку, но изменить документ через ссылку нельзя. ДокументОбъект — это объект для чтения и записи, получаемый методом ПолучитьОбъект(). В реквизитах базы данных всегда хранится именно ссылка.
Почему в поле выбора не виден нужный вид документа?
Проверьте три вещи: отмечен ли этот вид в составе типа реквизита, есть ли у пользователя права на просмотр документов этого вида и не наложен ли на поле ввода дополнительный отбор в коде формы (СвязиПараметровВыбора или Отборы в динамическом списке выбора).
Как найти все записи, где реквизит ссылается на конкретный вид документа?
Используйте запрос с условием ТИПЗНАЧЕНИЯ(Реквизит) = ТИП(Документ.ИмяВида). В консоли запросов это быстрый способ проанализировать фактическое заполнение составного реквизита перед возможным сужением состава типа.
Можно ли сузить состав типа, если реквизит уже заполнен?
Технически можно, но значения исключаемых видов будут очищены при реструктуризации. Перед изменением сделайте копию базы, запросом найдите записи с исключаемыми типами и решите их судьбу: перенести в другой реквизит или оставить как есть.
Влияет ли составной тип на скорость работы?
Да, умеренно. Поля с составным типом медленнее в выборе по строке и дают менее селективные индексы. На небольших объёмах это незаметно; на больших таблицах включайте индексацию реквизита и избегайте отборов по ТИПЗНАЧЕНИЯ без дополнительных индексированных условий.