При автоматизации бизнес-процессов часто возникает задача выполнять какие-либо действия в фоновом режиме по расписанию. Для этого в платформе 1С существует механизм регламентных заданий. Программное управление регламентными заданиями в 1С 8.3 позволяет гибко настраивать их создание и работу (поможет инструмент управления и отладки регламентных заданий) непосредственно из встроенного языка, а для более сложных сценариев можно использовать конвейер обработки задач, который упрощает построение мощных цепочек фоновых операций. Стандартная ситуация: мы программно создаем регламентное задание и хотим, чтобы оно выполнялось от имени конкретного пользователя, например, для корректного применения его прав и настроек. Однако, установив свойство ИмяПользователя, мы с удивлением обнаруживаем, что задание все равно выполняется от имени предопределенного системного пользователя. Разберемся, почему так происходит и как правильно решать эту задачу.
Корень проблемы кроется в понимании контекста выполнения регламентного задания. Платформа 1С может выполнять фоновые задания в двух принципиально разных средах: на клиенте и на сервере. Именно от этого зависит, как будет интерпретировано свойство ИмяПользователя, а также какие особенности выполнения фоновых заданий в клиент-серверной архитектуре стоит учитывать при разработке, включая отслеживание результата выполнения и индикацию прогресса без использования БСП — для этого есть контроль и уведомление о сбоях регламентных заданий.
ИмяПользователя сработает корректно. Задание будет выполнено в контексте указанного пользователя 1С.rmngr) в специальных рабочих процессах (rphost). Эти процессы запущены от имени системной учетной записи операционной системы, под которой работает служба «Агент сервера 1С:Предприятия» (например, USR1CV8). В этом режиме свойство ИмяПользователя регламентного задания полностью игнорируется.Таким образом, если ваше регламентное задание настроено на выполнение на сервере, оно всегда будет выполняться в сеансе, инициализированном от имени предопределенного пользователя, указанного в настройках кластера серверов 1С. Попытка задать другого пользователя через свойство объекта РегламентноеЗадание не даст ожидаемого эффекта.
Поскольку мы не можем напрямую указать пользователя для выполнения серверного регламентного задания, необходимо изменить подход к разработке самого кода, который это задание выполняет. Рассмотрим несколько рабочих стратегий.
Это самый правильный и гибкий способ. Идея заключается в том, чтобы сделать код процедуры, выполняемой заданием, независимым от "текущего пользователя" сеанса. Правильная передача параметров в регламентные задания позволяет явно передать нужного нам пользователя в качестве входного значения.
Разберем по шагам:
Посмотрим на пример кода:
Предположим, у нас есть общедоступная экспортная процедура ВыполнитьФоновуюОперацию в общем модуле МоиФоновыеЗадания.
Код создания регламентного задания:
Процедура СоздатьРегламентноеЗаданиеДляПользователя(ПользовательДляВыполнения)
// Находим метаданные нашего задания
МетаданныеЗадания = Метаданные.РегламентныеЗадания.МояФоноваяОперация;
// Создаем новое задание
НовоеЗадание = РегламентныеЗадания.СоздатьРегламентноеЗадание(МетаданныеЗадания);
// Задаем основные свойства
НовоеЗадание.Наименование = "Фоновая операция для " + ПользовательДляВыполнения.Наименование;
НовоеЗадание.Использование = Истина;
НовоеЗадание.Ключ = "Ключ" + XMLСтрока(ПользовательДляВыполнения.УникальныйИдентификатор());
// САМОЕ ВАЖНОЕ: Сохраняем пользователя в параметрах
НовоеЗадание.Параметры.Вставить("ПользовательКонтекста", ПользовательДляВыполнения);
// Настраиваем расписание (например, каждый день в 3 часа ночи)
Расписание = Новый РасписаниеРегламентногоЗадания;
Расписание.ДневноеПовторение.ПовторятьЧерез = 86400; // раз в сутки
НовоеЗадание.Расписание = Расписание;
// Записываем задание
Попытка
НовоеЗадание.Записать();
Исключение
Сообщить("Не удалось создать регламентное задание: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Код в модуле, который выполняет задание:
// Общий модуль МоиФоновыеЗадания
Процедура МояФоноваяОперация(ПараметрыЗадания) Экспорт
// Проверяем, был ли передан наш параметр
Если ПараметрыЗадания = Неопределено ИЛИ НЕ ПараметрыЗадания.Свойство("ПользовательКонтекста") Тогда
// Записать в журнал регистрации ошибку, так как задание настроено неверно
ЗаписьЖурналаРегистрации("РегламентныеЗадания", УровеньЖурналаРегистрации.Ошибка, , ,
"В регламентном задании не указан обязательный параметр 'ПользовательКонтекста'");
Возврат;
КонецЕсли;
// Получаем пользователя из параметров
ПользовательДляРаботы = ПараметрыЗадания.ПользовательКонтекста;
// Теперь используем переменную ПользовательДляРаботы для всех дальнейших действий
НастройкиОтчета = ПолучитьНастройкиПользователя(ПользовательДляРаботы, "ОтчетПоПродажам");
// Или для создания документа от его имени (программно, не через сеанс)
НовыйДокумент = Документы.ЗаказКлиента.СоздатьДокумент();
НовыйДокумент.Ответственный = ПользовательДляРаботы;
// ... заполнение других реквизитов
НовыйДокумент.Записать(РежимЗаписиДокумента.Проведение);
КонецПроцедуры
Этот подход является наиболее чистым и предсказуемым. Он позволяет создавать множество экземпляров одного и того же задания для разных пользователей, каждый со своим контекстом. Для контроля таких процессов есть контроль фоновых заданий и оповещение об ошибках.
Если логика вашего задания не завязана на настройки конкретного пользователя, а требует лишь достаточных прав для выполнения операций (например, чтение данных и запись документов), то можно пойти более простым путем.
Необходимо убедиться, что у предопределенного пользователя, от имени которого запускаются все серверные фоновые задания, есть все необходимые права. Имя этого пользователя обычно задается в свойствах кластера в консоли администрирования серверов 1С.
Действия:
Важный момент: Этот способ требует осторожности, так как безопасность и права доступа при выполнении кода на сервере 1С играют ключевую роль в стабильности системы. Предоставляя широкие права системному пользователю, вы потенциально даете их всем регламентным заданиям, которые выполняются на сервере.
Подведем итог. Свойство ИмяПользователя у объекта РегламентноеЗадание работает только при выполнении на стороне клиента. Для серверного выполнения, которое является стандартом в клиент-серверной архитектуре, это свойство игнорируется.
Для корректной работы фоновых процессов на сервере в контексте определенного пользователя используйте самый надежный метод — передачу нужного пользователя в качестве параметра регламентного задания. Это делает ваш код гибким, управляемым и безопасным. Если же в процессе работы возникают трудности, всегда можно задействовать отладку внешних обработок (поможет пошаговая отладка кода 1С без конфигуратора) и мониторинг серверных регламентных заданий для быстрого поиска и устранения ошибок.