При разработке в среде 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда после добавления нового объекта метаданных (например, копированием существующего документа) начинают «отваливаться» стандартные отчеты или возникают ошибки прав доступа у рядовых пользователей. Ситуация выглядит парадоксально: новый Документ2 не является регистратором, не упоминается в текстах запросов отчета и вообще не используется в бизнес-логике, но без полных прав на него отчет СКД либо выдает ошибку, либо просто возвращает пустой результат.
В этой статье мы подробно разберем, как работает механизм платформы «под капотом», почему возникают такие «невидимые» связи и как правильно настраивать конфигурацию, чтобы избежать подобных проблем.
Рассмотрим ситуацию, когда в системе есть регистр (сведений или накопления), который используется в отчете. Часто в таких регистрах присутствуют измерения или реквизиты с составным типом данных. В типовых конфигурациях (УНФ, ERP, КА) это чаще всего реализуется через Определяемые типы.
Например, регистр ДополнительныеСведения имеет измерение Объект. Тип этого измерения — ОпределяемыйТип.ВладелецДополнительныхСведений. Когда вы копируете Документ1 для создания Документ2, платформа часто автоматически включает новый объект в состав этого определяемого типа (особенно если в свойствах документа стоит галочка участия в соответствующих функциональных опциях или подсистемах).
Выясним, что происходит на уровне СУБД (SQL). Когда система компоновки данных (СКД) строит запрос к такому регистру, платформа 1С обязана обработать все возможные типы данных в составном поле. Для СУБД это превращается в серию соединений LEFT JOIN со всеми таблицами документов, входящих в составной тип. Платформа делает это по следующим причинам:
WHERE, проверяющие права для каждого входящего в состав типа.Объект, системе нужно знать, из какой таблицы брать представление (номер, дата) для конкретной ссылки.Таким образом, даже если в базе нет ни одной записи, где в поле Объект записана ссылка на Документ2, физически запрос к базе данных будет пытаться «зацепить» таблицу этого документа. И если у пользователя нет прав на Чтение или Просмотр этого типа, платформа может заблокировать выполнение всего запроса.
Проанализируем ситуацию, почему при добавлении минимальных прав отчет открывается, но данные исчезают. Это связано с особенностью работы механизма Record Level Security (RLS). Когда СКД выполняет запрос, она учитывает ограничения доступа. Если в запросе участвует составное поле, и на один из типов этого поля права настроены не полностью или содержат сложные условия, платформа может добавить такие предикаты в ГДЕ, которые отсекут все остальные записи.
Рассмотрим пример того, как может выглядеть логика запроса с точки зрения платформы (упрощенно):
ВЫБРАТЬ
Рег.Номенклатура,
Рег.Количество
ИЗ
РегистрНакопления.Запасы КАК Рег
ГДЕ
(ВЫРАЗИТЬ(Рег.ДокументОснование КАК Документ.Документ1) В (&СписокРазрешенных1)
ИЛИ ВЫРАЗИТЬ(Рег.ДокументОснование КАК Документ.Документ2) В (&СписокРазрешенных2))
Если в схему прав добавлен Документ2, но условия RLS для него некорректны или база данных еще не обновила кэш прав, результирующий фильтр может стать ложным для всех записей. Это объясняет, почему полные права решают проблему — в этом случае платформа просто не добавляет условия RLS в запрос.
Чтобы решить проблему «фантомной» зависимости, выполним следующие действия:
Общие -> Определяемые типы. Нас интересуют типы, связанные с владельцами свойств, файлов, заметок или бизнес-процессов. Чаще всего это ВладелецДополнительныхСведений. Проверим, стоит ли галочка напротив нашего Документа2. Если документ не должен иметь доп. сведений — снимем ее.ЛюбаяСсылка. Как было отмечено в решении проблемы на форуме, именно регистр ДополнительныеСведения часто становится «виновником» из-за своего измерения Объект./C ЗапуститьОбновлениеИнформационнойБазы или воспользуемся обработкой «Обновление вспомогательных данных» из состава БСП.Разберем, как минимизировать риски при создании новых документов копированием:
Во-первых, всегда проверяйте вкладку «Права» в конфигураторе. Копирование документа не копирует права доступа в ролях. Если вы создали Документ2, вам нужно вручную пройтись по всем ролям, где был разрешен Документ1, и добавить соответствующие права, если пользователи должны с ним работать.
Во-вторых, обратите внимание на составные типы в запросах СКД. Если вы используете в отчете поле, которое может содержать ссылку на новый документ, СКД будет проверять права. Чтобы этого избежать, можно использовать функцию ВЫРАЗИТЬ(Поле КАК Тип) в тексте запроса. Это жестко ограничит типы, к которым обращается система, и исключит лишние соединения таблиц на уровне SQL.
Посмотрим на пример оптимизации запроса в СКД:
ВЫБРАТЬ
ДопСведения.Значение
ИЗ
РегистрСведений.ДополнительныеСведения КАК ДопСведения
ГДЕ
ВЫРАЗИТЬ(ДопСведения.Объект КАК Документ.Документ1) <> ЗНАЧЕНИЕ(Документ.Документ1.ПустаяСсылка)
Такой подход явно указывает платформе, что нас интересует только Документ1, и она не будет пытаться проверять права на Документ2, даже если он входит в определяемый тип владельца сведений.
Если проблему не удается локализовать визуально, можно воспользоваться технологическим журналом (ТЖ). Настроим сбор событий EXCP (исключения) и DBMSSQL (запросы к базе данных). В логах ТЖ при попытке формирования отчета мы увидим реальный SQL-запрос. Если в нем присутствует JOIN к таблице нашего нового документа (например, _Document200), значит, поле с составным типом где-то активно используется.
Проанализируем фрагмент лога, указывающий на проблему прав:
...SRVR=...Context='Отчет.Продажи.Сформировать' ... SQL='SELECT ... FROM _InfoRg123 T1 LEFT OUTER JOIN _Document200 T2 ON ...' ... Error='Доступ запрещен'
Это прямое подтверждение того, что СКД «затягивает» таблицу нового документа в выборку из-за механизма обработки ссылок.
Ситуация, описанная в теме, не является ошибкой платформы, а является следствием архитектуры работы с метаданными и безопасностью. Ключевой вывод: любое добавление объекта в конфигурацию — это не просто создание новой таблицы, это изменение графа связей через составные и определяемые типы. Всегда проверяйте вхождение новых объектов в системные определяемые типы БСП и своевременно настраивайте роли доступа, даже если объект кажется изолированным.