В одной внедряемой информационной системе значение регламентных заданий (РЗ) оказалось очень велико. С помощью них осуществляется автоматизированная проверка и загрузка исходных данных в систему. И надо же было такому случиться, РЗ стали иногда подвисать. Несколько раз в месяц, после перезапуска сервера 1С Предприятия, все РЗ переставали выполняться. Выяснилось, что ситуация легко локально лечится перезаписью каждого РЗ. После чего они начинают нормально работать.
Поиск в Инете показал, что мы не одиноки. Подобная проблема встречается давно, но есть нюансы. Один из хорошо известных случаев, когда сервер sql и сервер 1С стоят на одной машине. После физического перезапуска сервера сервис 1С Предприятия стартует раньше сервиса sql, и модуль обработки регламентных заданий не может ещё прочитать их из базы. И считает, что их нет. Есть даже рекомендация Микрософт для данной ситуации, которая предусматривает настройку зависимости сервиса 1С Предприятия от сервиса sql. То есть он всегда буде стартовать после. Решение! Но это был не наш случай, так как физического перезапуска сервера у нас не было. Только остановка и старт сервиса. Были проанализированы и другие аспекты. Сервер sql работает непрерывно. Базы в кластер если и добавляются, то порядком реже, чем сбоят РЗ. Разделителей нет. После перезапуска сервера 1С Предприятия РЗ стартуют независимо.
Попытка обсуждения на партнерском форуме 1С ни к чему не привела - https://partners.v8.1c.ru/forum/t/1171054/m/1171054. Не смотря на проявленное внимание со стороны сотрудников 1С, рекомендаций по решению не было.
В голове бродили идеи внешнего контроля над работой РЗ. Можно было бы использовать ЦКК, но он только информирует и не исправляет ошибки. Можно было бы запускать 1С с параметром с помощью системного планировщика раз в день, проверять и перезаписывать зависшие РЗ. Но тут на партнерском форуме попалось похожее решение от Евграфова Андрея - https://partners.v8.1c.ru/forum/t/916015/m/1103984. Суть его решения похожа на описанное выше, но метод, на мой взгляд, интереснее. Планировщик запускает vbs, а он в свою очередь запускает через COM 1С и вызывает модуль для контроля РЗ.
Модуль vbs передльно прост:
Dim v82, base
Set v82 = CreateObject("V82.ComConnector")
ConnString = "Srvr=имя_сервера;Ref=имя_базы"
Set base = v82.Connect(ConnString)
base.CheckScheduledTasks
В зависимости от настроек, в строку соединения возможно придется добавить пользователя и пароль: "usr=пользователь;pwd=пароль".
В конфигурацию я добавил процедуру в Модуль внешнего соединения, которая вызывает процедуру из Общего модуля:
Процедура CheckScheduledTasks() Экспорт
РегламентныеЗадания.ПроверитьПерезаписатьРегламентныеЗадания();
КонецПроцедуры
// Процедура проверяет выполнение и перезаписывает все включенные регламентные задания
Процедура ПроверитьПерезаписатьРегламентныеЗадания() Экспорт
мРЗ = РегламентныеЗадания.ПолучитьРегламентныеЗадания(Новый Структура("Использование", Истина));
Если мРЗ.Количество() = 0 тогда
ЗаписьЖурналаРегистрации("Регламентные задания",УровеньЖурналаРегистрации.Информация,,,"Отсутствуют Регламентные задания с признаком Использование");
КонецЕсли;
стрТекущееВремя = "00010101"+Формат(Час(ТекущаяДата()),"ЧЦ=2; ЧН=00; ЧВН=")+Формат(Минута(ТекущаяДата()),"ЧЦ=2; ЧН=00; ЧВН=")+
Формат(Секунда(ТекущаяДата()),"ЧЦ=2; ЧН=00; ЧВН=");
ТекущееВремя = Дата(стрТекущееВремя);
мПозже = Новый Массив;
фПерезаписываем = Ложь;
Для каждого РЗ из мРЗ цикл
Если РЗ.Расписание.ВремяНачала > ТекущееВремя тогда
мПозже.Добавить(РЗ);
ИначеЕсли РЗ.ПоследнееЗадание = Неопределено тогда
РЗ.Записать();
фПерезаписываем = Истина;
ЗаписьЖурналаРегистрации("Регламентные задания",УровеньЖурналаРегистрации.Предупреждение,РЗ.Метаданные,РЗ,"Перезаписано - "+РЗ.Метаданные.Имя);
Иначе
ЗаписьЖурналаРегистрации("Регламентные задания",УровеньЖурналаРегистрации.Информация,РЗ.Метаданные,РЗ,"Нормально выполняется - "+РЗ.Метаданные.Имя);
КонецЕсли;
КонецЦикла;
Если фПерезаписываем тогда
Для каждого РЗ из мПозже цикл
РЗ.Записать();
ЗаписьЖурналаРегистрации("Регламентные задания",УровеньЖурналаРегистрации.Предупреждение,РЗ.Метаданные,РЗ,"Перезаписано - "+РЗ.Метаданные.Имя);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Последний модуль был доработан. Обрабатываются все используемые РЗ. Если РЗ должно было начать выполняться до момента проверки, но не выполнялось, то перезаписываем его. Если были обновления, то перезаписываем и более поздние РЗ.
Получилась заглушка, но, как показала практика, весьма эффективная!
Благодарность - Андрею Евграфову!!!