При автоматизации рутинных регламентных операций в 1С:Предприятии — таких как перепроведение документов или восстановление последовательности партионного учета — разработчики часто сталкиваются с ситуацией, когда штатное регламентное задание выполнить невозможно из-за архитектурных ограничений конфигурации. В старых решениях на обычных формах модули проведения опираются на клиентский контекст и глобальные переменные, что делает невозможным их выполнение на стороне сервера.
Естественным выходом кажется запуск сеанса в режиме толстого клиента по расписанию через командный файл (батник) и Планировщик задач Windows (Task Scheduler). Однако на практике возникает распространенная проблема: при ручном клике по батнику все отрабатывает штатно, а при запуске через планировщик в консоли кластера серверов 1С появляется сеанс, который зависает бесконечно и не выполняет целевых действий. Разберем подробно, почему так происходит и как наладить стабильную работу скрипта.
Выясним причину такого поведения системы. Разница между интерактивным запуском пользователем и выполнением через Планировщик задач кроется в контексте безопасности операционной системы и поведении самой платформы 1С:
/Execute система безопасности выводит модальное окно с предупреждением об открытии потенциально опасного файла. В неинтерактивной сессии это окно не отображается на экране, и толстый клиент бесконечно ждет нажатия кнопки подтверждения.ПриОткрытии, а в конце вызываются методы ЭтаФорма.Закрыть() и ЗавершитьРаботуСистемы(), происходит коллизия: окно еще не успело завершить процедуру отрисовки и инициализации, а его уже пытаются принудительно уничтожить.Проанализируем базовый вызов через командную строку. Исходная строка запуска выглядит следующим образом:
"C:\Program Files (x86)\1cv8\8.3.8.1747\bin\1cv8.exe" Enterprise /S"Server\Base" /N"User" /P"Pass" /Execute"E:\1C\Test.epf"
Для предотвращения зависаний выполним следующие настройки:
conf.cfg платформы пропишем директиву DisableUnsafeActionProtection=.*./DisableStartupMessages, /DisableStartupDialogs, /ClearCache, а также укажем вывод системных сообщений в файл через /Out, чтобы можно было локализовать ошибки старта.E:, убедимся, что это локальный физический накопитель сервера. Если это сетевой диск, обращение к нему из планировщика завершится ошибкой, так как сопоставленные сетевые буквы не монтируются в фоновых сессиях. В таком случае следует использовать UNC-путь вида \\server\share\Test.epf.Посмотрим на пример правильного формирования батника:
@echo off
chcp 1251 >nul
"C:\Program Files (x86)\1cv8\8.3.8.1747\bin\1cv8.exe" Enterprise /S"Server\Base" /N"User" /P"Pass" /DisableStartupMessages /DisableStartupDialogs /ClearCache /Execute "E:\1C\Test.epf" /Out "E:\1C\log.txt" -NoTruncate
Рассмотрим алгоритм обработки. В исходном варианте перебор документов последовательности совмещен с интерактивными вызовами и прямым закрытием формы:
Граница = Последовательности.ПартионныйУчет.ПолучитьГраницу();
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Граница", Граница);
Запрос.УстановитьПараметр("Дата", Граница.Дата);
Запрос.Текст =
"ВЫБРАТЬ
| ПартионныйУчет.Регистратор,
| ПартионныйУчет.Период КАК Период,
| ПартионныйУчет.Регистратор.Проведен КАК Проведен
|ИЗ
| Последовательность.ПартионныйУчет КАК ПартионныйУчет
|ГДЕ
| ПартионныйУчет.МоментВремени > &Граница
| И ПартионныйУчет.Период >= &Дата
|УПОРЯДОЧИТЬ ПО
| Период,
| ПартионныйУчет.МоментВремени";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Если НЕ Выборка.Проведен Тогда
Выборка.Регистратор.ПолучитьОбъект().ПринадлежностьПоследовательностям.ПартионныйУчет.Записать();
Продолжить;
КонецЕсли;
Попытка
Выборка.Регистратор.ПолучитьОбъект().Записать(РежимЗаписиДокумента.Проведение);
Исключение
Прервать;
КонецПопытки;
КонецЦикла;
ПрекратитьРаботуСистемы(Ложь);
Обратим внимание на критически важные изменения:
Состояние(...) и ОбработкаПрерыванияПользователя; обращаются к оконной очереди Windows. В фоновом режиме планировщика они вызывают сбои или подвисания, поэтому их необходимо полностью исключить.ЗавершитьРаботуСистемы(Ложь, Ложь) производит мягкий опрос модулей и открытых окон на возможность выхода, из-за чего сеанс может застрять. Для фоновых скриптов используем метод ПрекратитьРаботуСистемы(Ложь), который безусловно прерывает выполнение платформы.ПриОткрытии(). Вместо этого подключаем отложенный вызов, давая форме инициализироваться:
Процедура ПриОткрытии()
ПодключитьОбработчикОжидания("ВыполнитьИЗакрыть", 0.1, Истина);
КонецПроцедуры
Процедура ВыполнитьИЗакрыть()
// Основной алгоритм проведения
// ...
ПрекратитьРаботуСистемы(Ложь);
КонецПроцедуры
Чтобы полностью обойти механизмы защиты от опасных действий и исключить проблемы с чтением внешних файлов .epf, применим запуск с параметром командной строки /C.
Разберем по шагам, как это реализовать:
/Execute и добавляем параметр /C "ВосстановитьПоследовательность":
"C:\Program Files (x86)\1cv8\8.3.8.1747\bin\1cv8.exe" Enterprise /S"Server\Base" /N"User" /P"Pass" /DisableStartupMessages /DisableStartupDialogs /C "ВосстановитьПоследовательность"
ПриНачалеРаботыСистемы().ПараметрЗапуска:
Если ПараметрЗапуска = "ВосстановитьПоследовательность" Тогда
// Вызываем процедуру проведения из общего модуля
МойОбщийМодуль.ВыполнитьВосстановлениеПоследовательности();
ПрекратитьРаботуСистемы(Ложь);
КонецЕсли;
Такой подход считается наиболее надежным: код компилируется внутри конфигурации, не требует внешних файлов и гарантированно не вызывает окон с предупреждениями безопасности платформы.
Если требуется контролировать возврат кода ошибки в операционную систему или обойти проблемы планировщика при прямом вызове .bat, используем запуск через VBScript-обертку с объектом WScript.Shell:
Dim WShShell, Command, ReCode
Set WShShell = WScript.CreateObject("WScript.Shell")
Command = """C:\Program Files (x86)\1cv8\8.3.8.1747\bin\1cv8.exe"" Enterprise /S""Server\Base"" /N""User"" /P""Pass"" /DisableStartupMessages /DisableStartupDialogs /Execute""E:\1C\Test.epf"""
' Параметр 0 скрывает окно, True заставляет скрипт ожидать завершения процесса
ReCode = WShShell.Run(Command, 0, True)
Set WShShell = Nothing
Сохраняем скрипт с расширением .vbs. В Планировщике задач Windows в поле «Программа или сценарий» указываем wscript.exe, а в поле аргументов передаем полный путь к нашему скрипту. В параметрах действия также обязательно заполняем поле «Рабочая папка» (Start in), указав каталог расположения скрипта, что предотвратит ошибки поиска зависимостей в системном каталоге System32.