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