Часто в крупных конфигурациях 1С, где реализованы сложные ограничения доступа на уровне записей (RLS), разработчики сталкиваются с ситуацией, когда у одних пользователей список открывается мгновенно, а у других — вызывает критическую ошибку или бесконечное ожидание. Рассмотрим подробнее, почему это происходит и как мы можем исправить эту проблему вместе.
Первое, что важно понять: RLS — это механизм, который принудительно накладывает условия на каждый запрос к базе данных. Когда мы используем ДинамическийСписок, платформа автоматически генерирует SQL-запрос. Если в списке присутствуют поля составного типа (например, поле Предмет в задачах, имеющее тип ЛюбаяСсылка), платформа вынуждена выполнять множественные LEFT JOIN со всеми таблицами, входящими в этот тип данных.
Если на эти таблицы наложены сложные ограничения доступа, итоговый SQL-запрос становится колоссальным. SQL-сервер не справляется с построением плана запроса, что приводит к таймаутам или ошибкам. Именно поэтому попытки завернуть код в УстановитьПривилегированныйРежим(Истина) часто не дают результата: платформа все равно принудительно применяет RLS для динамических списков.
Прежде чем лезть в программный код и переписывать запросы, давайте разберем самый простой и эффективный способ диагностики — сброс пользовательских настроек. Часто пользователи самостоятельно добавляют колонки или настраивают сортировку по «тяжелым» полям, о чем мы можем даже не догадываться.
Предмету), это почти гарантированно приведет к ошибке из-за попытки SQL объединить тысячи записей для вычисления порядка сортировки.Если сброс настроек не помог, необходимо проанализировать запрос, на котором «валится» система. Одной из частых рекомендаций является принудительное определение типов в соединениях. Разберем использование оператора ВЫРАЗИТЬ.
Когда вы строите запрос в ДинамическомСписке, старайтесь избегать неявных соединений с полями типа ЛюбаяСсылка. Используйте конструкцию:
ВЫБРАТЬ
Задачи.Ссылка КАК Ссылка,
ВЫРАЗИТЬ(Задачи.Предмет КАК Справочник.Контрагенты) КАК Предмет
ИЗ
Задача.ЗадачаИсполнителя КАК Задачи
Это позволит платформе четко понимать тип соединения и не пытаться джойнить все возможные таблицы системы.
Если стандартный ДинамическийСписок из-за архитектуры RLS принципиально не может работать быстро, рассмотрим альтернативный подход. Мы можем не использовать ДинамическийСписок, а вывести данные в форму, используя ТаблицуЗначений, которую заполним программно.
Преимущество этого метода в том, что мы можем выполнить получение данных в привилегированном режиме, а затем обработать результат. Рассмотрим пример логики:
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
УстановитьПривилегированныйРежим(Истина);
Запрос = Новый Запрос;
Запрос.Текст = "... наш запрос ...";
Результат = Запрос.Выполнить().Выгрузить();
// Дальнейшая обработка данных для вывода в таблицу
КонецПроцедуры
Важное примечание: При таком подходе, если у пользователя нет прав на некоторые объекты, они будут отображаться как Объект не найден. Чтобы избежать этого, всегда получайте в запросе Представление нужного объекта (через оператор ПРЕДСТАВЛЕНИЕ(Поле)), чтобы пользователь видел читаемый текст вместо ошибки ссылки.
Проанализировав ситуацию, мы выяснили, что ключ к решению большинства «призрачных» ошибок — это очистка пользовательских настроек сортировки и группировки. Если это не приносит результата, переходите к пошаговому упрощению запросов или используйте ТаблицуЗначений. Помните, что архитектура RLS должна быть прозрачной, и если вы столкнулись с «кошмарным лесом» кода, всегда фиксируйте изменения в регламентах, чтобы избежать повторных обращений по одним и тем же вопросам.