Как запустить регламентное задание из кода 1С 8.3: сразу, по расписанию и извне

· 10 мин

Содержание

Метода «выполнить сейчас» у объекта РегламентноеЗадание в 1С 8.3 нет. Программно регламентное задание запускают двумя путями: включают его и задают расписание через менеджер РегламентныеЗадания (тогда задание стартует планировщик кластера), либо сразу вызывают тот же метод фоновым заданием через ФоновыеЗадания.Выполнить(Задание.Метаданные.ИмяМетода, Задание.Параметры, ...). Так же работают кнопка «Выполнить сейчас» в типовых конфигурациях и обработка «Консоль заданий».

Типичная ситуация: ночная выгрузка остатков упала, склад ждёт данные к 9:00, а следующий запуск по расписанию только завтра. Ниже код для каждого способа, передача параметров, вызов извне через HTTP и COM и разбор, почему задание не стартует.

Что должно быть готово до запуска

Регламентное задание — это объект метаданных, который ссылается на процедуру. Без правильной процедуры никакой код запуска не поможет.

Проверьте в конфигураторе четыре вещи:

  • 📌 Имя метода. В свойствах задания указана экспортная процедура общего модуля. Модуль должен иметь флаг «Сервер». Клиентский модуль или неэкспортная процедура дадут ошибку при старте.
  • 📌 Сигнатура процедуры. Число параметров процедуры совпадает с числом элементов массива Параметры. Удобно делать параметры необязательными: Процедура ВыгрузкаОстатков(Склад = Неопределено) Экспорт.
  • 📌 Флаг «Предопределённое». Предопределённое задание существует в базе в одном экземпляре, его находят через НайтиПредопределенное(). Несколько экземпляров с разными параметрами создают только у задания со снятым флагом.
  • 📌 Режим базы. В клиент-серверном варианте задания запускает планировщик кластера. В файловой базе задания выполняются только при открытом сеансе клиента.

Для файловой базы можно держать отдельный сеанс под служебным пользователем, запущенный с ключом /AllowExecuteScheduledJobs -Force. Тогда задания выполняются в нём, а не в сеансе случайного бухгалтера.

Работа с объектами РегламентноеЗадание (поиск, запись, удаление) требует административных прав. Обычному пользователю код упадёт с нарушением прав доступа. Для запуска фонового задания такие права не нужны.

Как создать и включить регламентное задание кодом

Объекта «Планировщик регламентных заданий» во встроенном языке нет. Всё делается через менеджер РегламентныеЗадания, а расписание описывает объект РасписаниеРегламентногоЗадания.

Включить предопределённое задание и задать расписание

Код выполняется на сервере:

&НаСервереБезКонтекста
Процедура ВключитьВыгрузкуОстатков()

    Задание = РегламентныеЗадания.НайтиПредопределенное(
        Метаданные.РегламентныеЗадания.ВыгрузкаОстатков);

    Расписание = Новый РасписаниеРегламентногоЗадания;
    Расписание.ПериодПовтораДней = 1;            // каждый день
    Расписание.ПериодПовтораВТечениеДня = 3600;  // раз в час, в секундах
    Расписание.ВремяНачала = Дата(1, 1, 1, 7, 0, 0);
    Расписание.ВремяКонца  = Дата(1, 1, 1, 21, 0, 0);

    Задание.Расписание = Расписание;
    Задание.Использование = Истина;
    Задание.Записать();

КонецПроцедуры

Задание будет запускаться каждый час с 7:00 до 21:00. Если нужно «только по будням», заполните Расписание.ДниНедели массивом чисел от 1 до 5 (1 — понедельник).

Создать отдельный экземпляр с параметрами

Пример: одна процедура выгрузки, но по каждому складу своё задание и своё время.

Задание = РегламентныеЗадания.СоздатьРегламентноеЗадание(
    Метаданные.РегламентныеЗадания.ВыгрузкаОстатков);

Задание.Наименование = "Выгрузка остатков: склад Север";
Задание.Ключ = "Склад_Север";

Параметры = Новый Массив;
Параметры.Добавить(СкладСевер); // ссылка на элемент справочника
Задание.Параметры = Параметры;

Задание.ИмяПользователя = "Робот_Обмен";
Задание.Расписание = Расписание; // объект из примера выше
Задание.Использование = Истина;
Задание.Записать();

Найти такие экземпляры потом можно отбором:

Отбор = Новый Структура("Метаданные, Ключ",
    Метаданные.РегламентныеЗадания.ВыгрузкаОстатков, "Склад_Север");
Найденные = РегламентныеЗадания.ПолучитьРегламентныеЗадания(Отбор);

Расписание и флаг использования хранятся в данных базы, а не в конфигурации. Менять их кодом можно в рабочей базе без монопольного режима и без обновления конфигурации.

В типовых конфигурациях на БСП

В Бухгалтерии 3.0, ЗУП 3.1, УТ 11 прямой вызов РегламентныеЗадания работает, но удобнее программный интерфейс библиотеки: модуль РегламентныеЗаданияСервер с функциями НайтиЗадания, ИзменитьЗадание, ДобавитьЗадание, УстановитьИспользованиеРегламентногоЗадания. Он учитывает режим работы в модели сервиса, где задания живут в очереди, а не в кластере.

Немедленный запуск регламентного задания программно

Чтобы выполнить задание прямо сейчас, не дожидаясь расписания, берут его метод и параметры и запускают фоновое задание. Этот приём главный, ради него обычно и ищут тему.

&НаСервере
Функция ЗапуститьЗаданиеСейчас(ИмяЗадания) Экспорт

    Задание = РегламентныеЗадания.НайтиПредопределенное(
        Метаданные.РегламентныеЗадания[ИмяЗадания]);

    Ключ = Строка(Задание.УникальныйИдентификатор);

    // Не запускаем второй экземпляр, если первый ещё работает
    Отбор = Новый Структура("Ключ, Состояние",
        Ключ, СостояниеФоновогоЗадания.Активно);
    Если ФоновыеЗадания.ПолучитьФоновыеЗадания(Отбор).Количество() > 0 Тогда
        ВызватьИсключение "Задание уже выполняется";
    КонецЕсли;

    Фоновое = ФоновыеЗадания.Выполнить(
        Задание.Метаданные.ИмяМетода,
        Задание.Параметры,
        Ключ,
        Задание.Наименование + " (ручной запуск)");

    Возврат Фоновое.УникальныйИдентификатор;

КонецФункции

Что здесь происходит:

  1. По имени объекта метаданных находим задание в базе.
  2. В качестве ключа берём его уникальный идентификатор. Платформа не даст запустить два активных фоновых задания с одинаковым ключом и методом.
  3. Проверяем, нет ли активного запуска, и выдаём понятное сообщение вместо системной ошибки.
  4. Запускаем фоновое задание с тем же методом и параметрами и возвращаем его идентификатор, чтобы потом проверить статус.

Фоновое задание, запущенное так, не привязано к регламентному. У него пустое свойство РегламентноеЗадание, и Задание.ПоследнееЗадание после ручного запуска не обновится. Ищите ручные запуски по ключу или по идентификатору, а не отбором по регламентному заданию.

Для непредопределённого экземпляра замените поиск на РегламентныеЗадания.НайтиПоУникальномуИдентификатору(УИД) или на отбор по ключу из предыдущего раздела.

Если нужно, чтобы ручной запуск отработал под тем же пользователем, что и по расписанию, учтите: фоновое задание выполняется от имени того, кто его запустил. Права и записи в журнале регистрации будут от текущего пользователя.

Параметры, ключ и пользователь: контекст выполнения

Регламентное задание выполняется на сервере в отдельном сеансе. Там нет форм, текущего клиента и значений, которые пользователь держал в памяти. Всё, что нужно процедуре, передают параметрами или читают из базы.

СвойствоЧто задаётНа что влияет
ПараметрыМассив значений для процедурыПорядок элементов = порядок параметров процедуры
КлючСтрока-идентификатор экземпляраНе даёт запустить два одинаковых задания параллельно
ИмяПользователяПользователь базыПрава, ПользователиИнформационнойБазы.ТекущийПользователь(), журнал регистрации
НаименованиеТекст для списка заданийТолько отображение
КоличествоПовторовПриАварийномЗавершенииЧисло повторовСколько раз платформа перезапустит упавшее задание
ИнтервалПовтораПриАварийномЗавершенииПауза в секундахЧерез сколько повторять

Практические правила по параметрам:

  • ✅ Передавайте простые значения и ссылки: строки, числа, даты, ссылки на справочники и документы.
  • ❌ Не передавайте объекты, таблицы значений с формы и данные формы. Их состояние в момент выполнения непредсказуемо.
  • ✅ Большой набор настроек храните в регистре сведений или константе, а в параметр кладите только ключ записи.
  • ✅ Задавайте ИмяПользователя явно. Служебный пользователь с нужной ролью проще в аудите, чем запуск «от имени никого».

Если поменять число параметров процедуры, а у созданных экземпляров оставить старый массив Параметры, задания начнут падать при старте. После изменения сигнатуры пройдитесь по экземплярам и перезапишите параметры.

Запуск регламентного задания извне: HTTP-сервис и COM

Иногда стартовать задание должна внешняя система: сайт, шина, скрипт администратора. Прямого вызова регламентного задания снаружи нет, поэтому делают серверную точку входа, которая запускает фоновое задание.

Через HTTP-сервис

Создайте HTTP-сервис с шаблоном URL /jobs/{job} и методом POST. Обработчик:

Функция ЗапускPOST(Запрос)

    Разрешённые = СтрРазделить("ВыгрузкаОстатков,ЗагрузкаКурсов", ",");
    ИмяЗадания = Запрос.ПараметрыURL["job"];

    Если Разрешённые.Найти(ИмяЗадания) = Неопределено Тогда
        Возврат Новый HTTPСервисОтвет(404);
    КонецЕсли;

    УстановитьПривилегированныйРежим(Истина);
    Задание = РегламентныеЗадания.НайтиПредопределенное(
        Метаданные.РегламентныеЗадания[ИмяЗадания]);

    Фоновое = ФоновыеЗадания.Выполнить(Задание.Метаданные.ИмяМетода,
        Задание.Параметры, Строка(Задание.УникальныйИдентификатор));

    Ответ = Новый HTTPСервисОтвет(202);
    Ответ.Заголовки.Вставить("Content-Type", "application/json");
    Ответ.УстановитьТелоИзСтроки(СтрШаблон("{""id"":""%1""}",
        Строка(Фоновое.УникальныйИдентификатор)));
    Возврат Ответ;

КонецФункции

Ключевые моменты:

  • 🔒 Белый список имён. Никогда не принимайте имя задания или метода из запроса без проверки. Иначе снаружи можно вызвать любую экспортную серверную процедуру.
  • 🔒 Привилегированный режим нужен, потому что пользователю публикации обычно не дают административных прав. Включайте его только на время поиска и запуска.
  • ⏱ Код 202 и идентификатор. HTTP-запрос не ждёт окончания задания. Внешняя система получает id и опрашивает статус вторым методом GET.

Повторный POST во время работы задания вызовет исключение из-за занятого ключа. Оберните запуск в Попытка, чтобы вернуть код 409 вместо 500.

Через COM-соединение

Из Windows-скрипта на машине с установленной платформой подключаются через V83.COMConnector. Компонента регистрируется командой regsvr32 comcntr.dll из папки bin платформы; разрядность скрипта должна совпадать с разрядностью зарегистрированной компоненты.

В конфигурации нужен общий модуль с флагами «Сервер» и «Внешнее соединение». Модуль и функцию удобно назвать латиницей, чтобы не мучиться с кодировкой в скриптах, например JobsExternal.Start(ИмяЗадания). Внутри — тот же код, что в разделе про немедленный запуск.

$connector = New-Object -ComObject V83.COMConnector
$base = $connector.Connect('Srvr="srv1c";Ref="buh";Usr="robot";Pwd="***";')
$id = $base.JobsExternal.Start("ВыгрузкаОстатков")
Write-Output $id

Пароль в открытом виде в скрипте — риск. Храните его в защищённом хранилище учётных данных Windows и давайте пользователю robot только роль для запуска заданий.

Третий вариант для простых случаев — запуск клиента 1cv8.exe ENTERPRISE с ключом /Execute и внешней обработкой из планировщика Windows. Он тяжелее: поднимается целый клиентский сеанс и занимает лицензию.

Какой способ запуска выбрать

СпособКогда подходитОграничения
Включить задание и задать расписаниеРегулярная работа: обмены, загрузка курсов, закрытие дняСтарт по расписанию, не мгновенно; в файловой базе нужен открытый сеанс
ФоновыеЗадания.Выполнить с методом заданияРазовый запуск «сейчас» из формы или кодаНе обновляет ПоследнееЗадание, выполняется от текущего пользователя
HTTP-сервисЗапуск из сайта, шины, другой системыНужна публикация на веб-сервере и защита точки входа
COM-соединениеСкрипты администратора внутри сетиТолько Windows, нужна установленная платформа той же версии
1cv8.exe /ExecuteНет доступа к правке конфигурацииПолноценный сеанс, лицензия, медленный старт

Для большинства задач хватает пары «расписание + кнопка немедленного запуска на фоновом задании». Внешние способы нужны, когда инициатор запуска — не человек в 1С.

Контроль выполнения: статус, ошибки, отмена

Запустить мало: нужно знать, чем закончилось. Фоновое задание находят по идентификатору и смотрят состояние.

Функция СтатусЗадания(УИДСтрокой) Экспорт

    Фоновое = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(
        Новый УникальныйИдентификатор(УИДСтрокой));

    Если Фоновое = Неопределено Тогда
        Возврат "не найдено";
    ИначеЕсли Фоновое.Состояние = СостояниеФоновогоЗадания.Активно Тогда
        Возврат "выполняется с " + Формат(Фоновое.Начало, "ДФ=HH:mm");
    ИначеЕсли Фоновое.Состояние = СостояниеФоновогоЗадания.ЗавершеноАварийно Тогда
        Возврат ПодробноеПредставлениеОшибки(Фоновое.ИнформацияОбОшибке);
    Иначе
        Возврат Строка(Фоновое.Состояние);
    КонецЕсли;

КонецФункции

Для запусков по расписанию то же самое берут из Задание.ПоследнееЗадание: если задание ещё ни разу не выполнялось, там Неопределено.

Что ещё пригодится:

  • ⏳ Фоновое.ОжидатьЗавершенияВыполнения(30) — подождать до 30 секунд. Удобно в тестах, но не в обработчике HTTP-запроса.
  • ✋ Фоновое.Отменить() — попросить задание остановиться. Длинную процедуру стоит писать так, чтобы она работала порциями и фиксировала прогресс.
  • 💬 Фоновое.ПолучитьСообщенияПользователю() — забрать то, что процедура выводила через Сообщить().
  • 📜 Журнал регистрации с отбором по событиям фоновых заданий — история запусков, ошибок и отмен, в том числе по расписанию.

В типовых конфигурациях список, расписание и ручной запуск собраны в Администрирование → Обслуживание → Регламентные операции → Регламентные и фоновые задания.

Почему регламентное задание не стартует

Большинство «не работает » сводится к нескольким причинам. Проверяйте их по порядку, от простого к сложному.

Диагностика: выберите симптом

Снимать блокировку регламентных заданий на копии рабочей базы опасно: копия начнёт отправлять те же обмены, письма и выгрузки, что и боевая. Сначала отключите задания, которые ходят во внешние системы.

Если задание стартует, но падает, ответ почти всегда в ИнформацияОбОшибке последнего запуска или в журнале регистрации. Ещё одна частая причина — процедура обращается к тому, что есть только на клиенте: формам, диалогам, локальным файлам пользователя.

Частые вопросы

Можно ли запустить регламентное задание с клиента напрямую?
Нет. Менеджеры РегламентныеЗадания и ФоновыеЗадания доступны только на сервере. С клиента вызывают серверную процедуру, а уже она запускает фоновое задание.
Чем регламентное задание отличается от фонового?
Регламентное — это настройка: метод, параметры, расписание, пользователь. Фоновое — конкретный запуск метода в отдельном сеансе. Каждое срабатывание регламентного задания порождает фоновое.
Нужно ли выгонять пользователей, чтобы поменять расписание кодом?
Нет. Расписание хранится в данных базы, его запись не требует монопольного режима и обновления конфигурации.
Можно ли запускать одно задание раз в несколько минут?
Да, период повтора в течение дня задаётся в секундах. Но если очередной запуск наступает, пока предыдущий ещё работает, новый не начнётся. Слишком частое расписание для долгой процедуры даёт пропуски.
Почему в моём коде регламентного задания пустой текущий пользователь?
Не заполнено свойство ИмяПользователя. Укажите служебного пользователя базы, и задание будет выполняться от его имени с его правами.