В процессе развития конфигурации 1С часто возникает ситуация, когда существующий справочник (например, Договоры), который изначально был подчинен только одному объекту (например, Контрагенты), требуется подчинить еще одному справочнику (например, Сотрудники). Технически платформа 1С позволяет сделать стандартный реквизит Владелец составным типом данных. Однако такое простое на первый взгляд изменение может привести к каскаду ошибок в самых неожиданных местах системы. Разберем подробно, как реализовать эту задачу, какие опасности нас подстерегают и как правильно провести аудит конфигурации перед обновлением рабочей базы.
Это прямой путь, который кажется наиболее логичным. Мы заходим в свойства справочника, открываем вкладку «Владельцы» и добавляем еще один справочник в список. С этого момента реквизит Владелец принимает составной тип. Рассмотрим, что происходит «под капотом» и в коде конфигурации.
Главная опасность заключается в разыменовании ссылок через точку. Если в коде конфигурации, в запросах или в формах встречается обращение к реквизитам владельца, система ожидает наличие этих реквизитов у объекта. Проанализируем типичный пример ошибки:
// Пример кода, который может вызвать ошибку
ТекстИнформации = "Договор с " + ОбъектДоговор.Владелец.НаименованиеПолное + " от " + Формат(ОбъектДоговор.Дата, "ДЛФ=D");
Если у первого владельца (например, контрагента) есть реквизит НаименованиеПолное, а у нового (например, сотрудника) его нет — система выдаст ошибку «Поле объекта не обнаружено» в момент выполнения кода. И такие места крайне сложно выловить простым тестированием «на глаз».
Для предотвращения ошибок нам необходимо провести глубокий аудит конфигурации. Воспользуемся глобальным поиском по конфигурации (Ctrl+Shift+F). Проанализируем следующие конструкции:
Владелец. (с точкой на конце). Это позволит найти все прямые обращения к реквизитам владельца через точку. Нам нужно проверить, есть ли такие же реквизиты у нового владельца.Справочник.Договоры.Владелец. Это поможет найти места, где тип владельца проверяется явно или используется в логике отборов.ССЫЛКА в запросах. Ищем конструкции вида Владелец ССЫЛКА Справочник.Контрагенты. После добавления второго типа такие запросы начнут игнорировать записи с новым типом владельца, что приведет к неверным данным в отчетах.Разберем пример проверки типа в запросе, который нужно будет изменить:
// БЫЛО:
"ВЫБРАТЬ * ИЗ Справочник.Договоры ГДЕ Владелец = &Контрагент"
// СТАЛО (нужно убедиться, что тип параметра соответствует):
"ВЫБРАТЬ * ИЗ Справочник.Договоры ГДЕ Владелец ССЫЛКА Справочник.Контрагенты И Владелец = &Контрагент"
Рассмотрим ситуацию на уровне СУБД (SQL). Когда поле Владелец становится составным типом, структура таблицы в базе данных меняется коренным образом. Вместо одного поля с уникальным идентификатором (UUID), создаются дополнительные поля для хранения типа значения. Это приводит к следующим последствиям:
CASE для определения типа владельца при каждом обращении к его реквизитам.Проанализируем крайне важный аспект, о котором часто забывают, — Record Level Security (RLS). Если в вашей конфигурации настроены ограничения доступа (например, менеджер видит договоры только «своих» контрагентов), то логика этих ограничений обычно завязана на владельца. После добавления нового типа владельца шаблоны RLS могут начать работать некорректно или вовсе выдавать ошибку доступа, так как система не будет понимать, как проверять права для нового типа объекта. Нам придется вручную пересматривать все роли, имеющие доступ к этому справочнику.
Во многих случаях добавление второго владельца — это «архитектурное излишество», которого можно избежать. Рассмотрим альтернативный подход: оставить у справочника одного основного владельца, а для связи со вторым справочником создать обычный реквизит.
Преимущества такого подхода:
1. Структура метаданных остается простой и предсказуемой.
2. Не ломаются существующие отчеты и запросы, использующие разыменование через Владелец..
3. Не нужно перенастраивать RLS и обмены данными.
Нюанс реализации: Поскольку справочник обязан иметь владельца при записи (если свойство «Использование подчинения» установлено), нам потребуется выбрать стратегию заполнения стандартного реквизита для «новых» данных. Посмотрим на возможные решения:
Владелец.Проанализируем код при записи в таком случае:
Процедура ПередЗаписью(Отказ)
Если ЗначениеЗаполнено(Объект.НовыйРеквизитВторойВладелец) И НЕ ЗначениеЗаполнено(Объект.Владелец) Тогда
Объект.Владелец = Справочники.Контрагенты.ТехническийВладелец;
КонецЕсли;
КонецПроцедуры
Выясним, как изменение повлияет на удобство работы пользователей. При использовании составного типа Владелец, в каждом поле ввода и при создании нового элемента будет появляться промежуточное окно «Выберите тип данных». Это часто раздражает пользователей, если в 90% случаев создаются договоры для одного типа владельца. Если мы используем «Вариант 2» с отдельным реквизитом, интерфейс остается чистым и понятным.
Если мы все же выбрали путь с составным владельцем, нам необходимо проверить все документы, где используется справочник Договоры. Обычно в документах настроена Связь параметров выбора: поле «Договор» фильтруется по полю «Контрагент» (через отбор по владельцу). После добавления второго типа владельца нам придется зайти в каждый такой документ и убедиться, что связь работает корректно. Если в документе в поле «Контрагент» выбран объект, который не входит в составной тип владельца договора, список выбора будет пустым.
Владелец. в коде и запросах.Подводя итог, можно сказать: добавление второго владельца — процедура допустимая, но требующая предельной внимательности. Если конфигурация большая и типовая, безопаснее и дешевле будет использовать дополнительный реквизит. Если же вы полностью контролируете код и готовы к масштабному аудиту — составной тип Владелец обеспечит более строгую логику подчиненности на уровне платформы.