Не работают регламентные задания?

Работают не всегда стабильно. Что делать, как обеспечить стабильную работу пользователей? Качественную и устойчивую работу ИС?
Делать контроль выполнения регламентных (фоновых) заданий.
Ниже подробные комментарии с фрагментами кода.

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

Например обработа выгрузи данных о товарах на кассу (обмен с фронт-офис) может начинаться так:

Процедура ПриОткрытии()
НачалоПериода = НачалоДня(ТекущаяДата());
КонецПериода = ТекущаяДата();
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Сообщение.Наименование,
| Сообщение.Выполнена,
| Сообщение.Дата
|ИЗ
| Задача.Сообщение КАК Сообщение
|ГДЕ
| Сообщение.Дата МЕЖДУ &Дата1 И &Дата2
| И Сообщение.ПометкаУдаления = ЛОЖЬ
| И Сообщение.Выполнена = ИСТИНА
| И Сообщение.ТекстСообщения ПОДОБНО ""%ВвестиПереоценку%""";
Запрос.УстановитьПараметр("Дата1",НачалоПериода);
Запрос.УстановитьПараметр("Дата2",КонецПериода);
//Запрос.УстановитьПараметр("Наименование","ПереоценкаПоОкончанииСкидок");
РТ = Запрос.Выполнить().Выгрузить();
Если РТ.Количество() = 0 Тогда
Попытка
исРегламентныеЗадания.ВвестиПереоценку();
Исключение
Сообщить("Сбой переоцени");
КонецПопытки;
КонецЕсли;
...

 

 2) Проблемное задание при выполнении должно сделать отметку о результатах выполнения. Я использую объект конфигурации "задача". Сначала создается задача, которая является маркером, что задание пыталось стартовать. В ТекстСообщения записывается название задачи (то есть имя процедуры регламентного задания) потому, что по этому названию будет искаться задание во время определения состояния базы. В заголовок задачи я пишу данные из регламентного задания, а в тексте — имя процедуры, чтобы легче автоматически судить о характере сбоя. Если есть заголовок, значит все идет по плану и обработка выполнялась в регламенте, если заголовка нет — при попытке восстановления и нужно разбиравться. В процессе обработи тест сообщения дополняется служебными данными и после обработки задача записывается с отметкой о выполнении. Вот так может выглядеть регламентное задание "Переоцена после окончания скидок":

 

Процедура ВвестиПереоценку() Экспорт

тмпПользователь = ПараметрыСеанса.Пользователь;
ПараметрыСеанса.Пользователь=Справочники.Пользователи.НайтиПоКоду("Робот");
ПараметрыСеанса.исУправляемаяБлокировка=Ложь;

НовоеСообщениеИдентификаторФоновогоЗадания = СоздатьЗадачуСообщениеИдентификаторФоновогоЗадания();
ТекстСообщенияИдентификаторФоновогоЗадания = "ВвестиПереоценку";
...
тут собственно создается переоцена и в конце нее :
...
НовоеСообщениеИдентификаторФоновогоЗадания.ТекстСообщения = НовоеСообщениеИдентификаторФоновогоЗадания.ТекстСообщения +
ТекстСообщенияИдентификаторФоновогоЗадания + "
|--
|Служебная информация " + Новый УникальныйИдентификатор;
НовоеСообщениеИдентификаторФоновогоЗадания.ВыполнитьЗадачу();
ПараметрыСеанса.Пользователь = тмпПользователь;
КонецПроцедуры

 

3) В начале рабочего дня, до того, как пользователи приступят к работе, должен быть сделан вывод о необходимости реанимировать информационную систему. Для этого можно использовать запускаемую внешне, например через бат-файл, обработу "Контроль выполнения регламентных заданий".

Процедура ОтправкаСообщенияКонтрольРегламентныхЗаданий() Экспорт

...
//04 "ПереоценкаПоОкончанииСкидок";
...
//12 "ВыгрузкаФорматов";
...
НачалоПериода = НачалоДня(ТекущаяДата())-1*24*60*60;
КонецПериода = КонецДня(ТекущаяДата())-1*24*60*60;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Сообщение.Наименование,
| Сообщение.Выполнена,
| Сообщение.Дата
|ИЗ
| Задача.Сообщение КАК Сообщение
|ГДЕ
| Сообщение.Дата МЕЖДУ &Дата1 И &Дата2
| И Сообщение.ПометкаУдаления = ЛОЖЬ";
Запрос.УстановитьПараметр("Дата1",НачалоПериода);
Запрос.УстановитьПараметр("Дата2",КонецПериода);
РТ = Запрос.Выполнить().Выгрузить();

Регламентные = РегламентныеЗадания.ПолучитьРегламентныеЗадания();

ТекстПочтовогоСообщения = "Сбой выполнения регламентных заданий";

ОтправитьПисьмо = Ложь;

Для Каждого Регламентное из Регламентные Цикл
Отбор = Новый Структура();
ОтборЗаполнен = Ложь;
Для Каждого СтрРТ Из РТ Цикл
Если Найти(СтрРТ.Наименование,Регламентное.Наименование) Тогда
Для Каждого СтрОтбор Из Отбор Цикл
Если СтрОтбор.Значение = Регламентное.Наименование Тогда
ОтборЗаполнен = Истина;
Продолжить;
КонецЕсли;
КонецЦикла;
Если ОтборЗаполнен = Ложь Тогда
Отбор.Вставить("Наименование",Регламентное.Наименование);
ОтборЗаполнен = Истина;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если ОтборЗаполнен = Ложь Тогда
Если Регламентное.Наименование = "Автозаказ" Тогда
ИначеЕсли Регламентное.Использование = Истина Тогда
ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
|с "+НачалоПериода+" по "+КонецПериода+" не запускалось "+Регламентное.Наименование;
ОтправитьПисьмо = Истина;
КонецЕсли;
Продолжить;
КонецЕсли;
РС = РТ.НайтиСтроки(Отбор);
Если РС.Количество() > 0 Тогда
СтрокаНайдена = Ложь;
ЗаданиеВыполнено = Ложь;
Для Каждого СтрРС Из РС Цикл
СтрокаНайдена = Истина;
Если СтрРС.Выполнена = Истина Тогда
ЗаданиеВыполнено = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если ЗаданиеВыполнено = Истина Тогда
Продолжить;
Иначе
ПоследнееЗадание = Регламентное.ПоследнееЗадание;
Если ПоследнееЗадание <> Неопределено Тогда
ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
|Не выполнено фоновое "+Регламентное.Наименование + " " + СокрЛП(ПоследнееЗадание.Начало);
ОтправитьПисьмо = Истина;
Иначе
Если СокрЛП(Регламентное.Наименование) > "" Тогда
ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
|Не выполнено "+Регламентное.Наименование + " " + СокрЛП(СтрРС.Дата);
ОтправитьПисьмо = Истина;
ИначеЕсли  СокрЛП(Регламентное.Код) > "" Тогда
ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
|Не выполнено "+Регламентное.Код + " " + СокрЛП(СтрРС.Дата) + " - у задания не заполнено наименование";
ОтправитьПисьмо = Истина;
Иначе
ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
|Не выполнено "+ СокрЛП(Регламентное) + " " + СокрЛП(СтрРС.Дата) + " - у задания не заполнено наименование и код";
ОтправитьПисьмо = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если СтрокаНайдена = Истина Тогда
Продолжить;
КонецЕсли;
КонецЕсли;

Отбор = Новый Структура();
ОтборЗаполнен = Ложь;
Для Каждого СтрРТ Из РТ Цикл
Если Найти(СтрРТ.Наименование,Регламентное.Ключ) Тогда
Для Каждого СтрОтбор Из Отбор Цикл
Если СтрОтбор.Значение = Регламентное.Ключ Тогда
ОтборЗаполнен = Истина;
Продолжить;
КонецЕсли;
КонецЦикла;
Если ОтборЗаполнен = Ложь Тогда
Отбор.Вставить("Наименование",Регламентное.Ключ);
ОтборЗаполнен = Истина;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если ОтборЗаполнен = Ложь Тогда
Если Регламентное.Наименование = "Автозаказ" Тогда
ИначеЕсли Регламентное.Использование = Истина Тогда
ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
|с "+НачалоПериода+" по "+КонецПериода+" не запускалось "+Регламентное.Наименование;
ОтправитьПисьмо = Истина;
КонецЕсли;
Продолжить;
КонецЕсли;
РС = РТ.НайтиСтроки(Отбор);
Если РС.Количество() > 0 Тогда
СтрокаНайдена = Ложь;
ЗаданиеВыполнено = Ложь;
Для Каждого СтрРС Из РС Цикл
СтрокаНайдена = Истина;
Если СтрРС.Выполнена = Истина Тогда
ЗаданиеВыполнено = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если ЗаданиеВыполнено = Истина Тогда
Продолжить;
Иначе
ПоследнееЗадание = Регламентное.ПоследнееЗадание;
Если ПоследнееЗадание <> Неопределено Тогда
ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
|Не выполнено фоновое "+Регламентное.Наименование + " " + СокрЛП(ПоследнееЗадание.Начало);
ОтправитьПисьмо = Истина;
Иначе
Если СокрЛП(Регламентное.Наименование) > "" Тогда
ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
|Не выполнено "+Регламентное.Наименование + " " + СокрЛП(СтрРС.Дата);
ОтправитьПисьмо = Истина;
ИначеЕсли  СокрЛП(Регламентное.Код) > "" Тогда
ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
|Не выполнено "+Регламентное.Код + " " + СокрЛП(СтрРС.Дата) + " - у задания не заполнено наименование";
ОтправитьПисьмо = Истина;
Иначе
ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
|Не выполнено "+ СокрЛП(Регламентное) + " " + СокрЛП(СтрРС.Дата) + " - у задания не заполнено наименование и код";
ОтправитьПисьмо = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если СтрокаНайдена = Истина Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Если Регламентное.Наименование = "Автозаказ" Тогда
ИначеЕсли Регламентное.Использование = Истина Тогда
ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
|с "+НачалоПериода+" по "+КонецПериода+" не запускалось "+Регламентное.Наименование;
ОтправитьПисьмо = Истина;
КонецЕсли;
КонецЦикла;

НачалоПериода = НачалоДня(ТекущаяДата());
КонецПериода = ТекущаяДата();
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Сообщение.Наименование,
| Сообщение.Выполнена,
| Сообщение.Дата
|ИЗ
| Задача.Сообщение КАК Сообщение
|ГДЕ
| Сообщение.Дата МЕЖДУ &Дата1 И &Дата2
| И Сообщение.ПометкаУдаления = ЛОЖЬ";
Запрос.УстановитьПараметр("Дата1",НачалоПериода);
Запрос.УстановитьПараметр("Дата2",КонецПериода);
РТ = Запрос.Выполнить().Выгрузить();

Регламентные = РегламентныеЗадания.ПолучитьРегламентныеЗадания();

Для Каждого Регламентное из Регламентные Цикл
Если Регламентное.Наименование = "ОтправкаСообщенияКонтрольРегламентныхЗаданий"
ИЛИ Регламентное.Ключ = "ОтправкаСообщенияКонтрольРегламентныхЗаданий" Тогда
Продолжить;
КонецЕсли;
//Регламентное.Расписание
ВремяЗадания = Регламентное.Расписание.ВремяНачала;
ЧасВремениЗадания = Час(ВремяЗадания);
МинутаВремениЗадания = Минута(ВремяЗадания);
СекундаВремениЗадания = Секунда(ВремяЗадания);
ДатаЗадания = НачалоДня(ТекущаяДата()) + ЧасВремениЗадания * 24 * 60
+ МинутаВремениЗадания * 60 + СекундаВремениЗадания;
Если ДатаЗадания > КонецПериода Тогда
Продолжить;
КонецЕсли;

Отбор = Новый Структура();
ОтборЗаполнен = Ложь;
Для Каждого СтрРТ Из РТ Цикл
Если Найти(СтрРТ.Наименование,Регламентное.Наименование) Тогда
Для Каждого СтрОтбор Из Отбор Цикл
Если СтрОтбор.Значение = Регламентное.Наименование Тогда
ОтборЗаполнен = Истина;
Продолжить;
КонецЕсли;
КонецЦикла;
Если ОтборЗаполнен = Ложь Тогда
Отбор.Вставить("Наименование",Регламентное.Наименование);
ОтборЗаполнен = Истина;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если ОтборЗаполнен = Ложь Тогда
Если Регламентное.Наименование = "Автозаказ" Тогда
ИначеЕсли Регламентное.Использование = Истина Тогда
ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
|с "+НачалоПериода+" по "+КонецПериода+" не запускалось "+Регламентное.Наименование;
ОтправитьПисьмо = Истина;
КонецЕсли;
Продолжить;
КонецЕсли;
РС = РТ.НайтиСтроки(Отбор);
Если РС.Количество() > 0 Тогда
СтрокаНайдена = Ложь;
ЗаданиеВыполнено = Ложь;
Для Каждого СтрРС Из РС Цикл
СтрокаНайдена = Истина;
Если СтрРС.Выполнена = Истина Тогда
ЗаданиеВыполнено = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если ЗаданиеВыполнено = Истина Тогда
Продолжить;
Иначе
ПоследнееЗадание = Регламентное.ПоследнееЗадание;
Если ПоследнееЗадание <> Неопределено Тогда
ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
|Не выполнено фоновое "+Регламентное.Наименование + " " + СокрЛП(ПоследнееЗадание.Начало);
ОтправитьПисьмо = Истина;
Иначе
ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
|Не выполнено "+Регламентное.Наименование + " " + СокрЛП(СтрРС.Дата);
ОтправитьПисьмо = Истина;
КонецЕсли;
КонецЕсли;
Если СтрокаНайдена = Истина Тогда
Продолжить;
КонецЕсли;
КонецЕсли;

ОтборЗаполнен = Ложь;
Для Каждого СтрРТ Из РТ Цикл
Если Найти(СтрРТ.Наименование,Регламентное.Ключ) Тогда
Для Каждого СтрОтбор Из Отбор Цикл
Если СтрОтбор.Значение = Регламентное.Ключ Тогда
ОтборЗаполнен = Истина;
Продолжить;
КонецЕсли;
Если ОтборЗаполнен = Ложь Тогда
Отбор.Вставить("Наименование",Регламентное.Ключ);
ОтборЗаполнен = Истина;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;
Если ОтборЗаполнен = Ложь Тогда
Если Регламентное.Наименование = "Автозаказ" Тогда
ИначеЕсли Регламентное.Использование = Истина Тогда
ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
|с "+НачалоПериода+" по "+КонецПериода+" не запускалось "+Регламентное.Наименование;
ОтправитьПисьмо = Истина;
КонецЕсли;
Продолжить;
КонецЕсли;
РС = РТ.НайтиСтроки(Отбор);
Если РС.Количество() > 0 Тогда
СтрокаНайдена = Ложь;
ЗаданиеВыполнено = Ложь;
Для Каждого СтрРС Из РС Цикл
СтрокаНайдена = Истина;
Если СтрРС.Выполнена = Истина Тогда
ЗаданиеВыполнено = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если ЗаданиеВыполнено = Истина Тогда
Продолжить;
Иначе
ПоследнееЗадание = Регламентное.ПоследнееЗадание;
Если ПоследнееЗадание <> Неопределено Тогда
ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
|Не выполнено фоновое "+Регламентное.Наименование + " " + СокрЛП(ПоследнееЗадание.Начало);
ОтправитьПисьмо = Истина;
Иначе
ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
|Не выполнено "+Регламентное.Наименование + " " + СокрЛП(СтрРС.Дата);
ОтправитьПисьмо = Истина;
КонецЕсли;
КонецЕсли;
Если СтрокаНайдена = Истина Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Если Регламентное.Наименование = "Автозаказ" Тогда
ИначеЕсли Регламентное.Использование = Истина Тогда
ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
|с "+НачалоПериода+" по "+КонецПериода+" не запускалось "+Регламентное.Наименование;
ОтправитьПисьмо = Истина;
КонецЕсли;
КонецЦикла;

Запрос = Новый Запрос;
Запрос.Текст =

"ВЫБРАТЬ
| ЗаказПоставщику.Ссылка
|ИЗ
| Документ.ЗаказПоставщику КАК ЗаказПоставщику
|ГДЕ
| ЗаказПоставщику.Контрагент = &Контрагент
| И ЗаказПоставщику.Автор В ИЕРАРХИИ(&Автор)
| И ЗаказПоставщику.СкладКоллекций В(&СкладКоллекций)
| И ЗаказПоставщику.Дата МЕЖДУ &Дата1 И &Дата2";
Запрос.УстановитьПараметр("Дата1",НачалоДня(ТекущаяДата()));
Запрос.УстановитьПараметр("Дата2",КонецДня(ТекущаяДата()));
Запрос.УстановитьПараметр("Контрагент",Справочники.Контрагенты.ОсновнойПоставщик);
СписокАвторов = Новый СписокЗначений;
 СписокАвторов.Добавить(Справочники.Пользователи.НайтиПоКоду("Робот"));
 Запрос.УстановитьПараметр("Автор",СписокАвторов);
СкладКоллекций = Новый СписокЗначений;
СкладКоллекций.Добавить(Справочники.СкладыКоллекций.НайтиПоКоду("..."));
СкладКоллекций.Добавить(Справочники.СкладыКоллекций.НайтиПоКоду("..."));
Запрос.УстановитьПараметр("СкладКоллекций",СкладКоллекций);
РТ = Запрос.Выполнить().Выгрузить();
Если Константы.ЗавтраПропуститьАвтозаказ.Получить() > 9 Тогда
Если РТ.Количество()< 5 Тогда
Если РТ.Количество() = 0 Тогда
ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
|Ошибка!Не сформировались заказы на Сигму
|Ошибка!Не сформировались заказы на Сигму
|Ошибка!Не сформировались заказы на Сигму
|Ошибка!Не сформировались заказы на Сигму
|Ошибка!Не сформировались заказы на Сигму";
Иначе
ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
|Ошибка!Сформировались не все заказы на Сигму, всего сформировалось "+СокрЛП(РТ.Количество())+" заказов из 5 необходимых:";
Для Каждого СтрРТ Из РТ Цикл
ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
|"+СокрЛП(СтрРТ.Ссылка);
КонецЦикла;
КонецЕсли;
ОтправитьПисьмо = Истина;
КонецЕсли;
КонецЕсли;

ДниНедели = СокрЛП(ДеньНедели(ТекущаяДата()));

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| исГрафикАвтозаказа.ПериодичностьНедель,
| исГрафикАвтозаказа.ДниНедели,
| исГрафикАвтозаказа.Поставщик,
| исГрафикАвтозаказа.Логист,
| исГрафикАвтозаказа.Активный,
| исГрафикАвтозаказа.СрокПоставки,
| исГрафикАвтозаказа.ДатаПоследнегоЗаказа,
| исГрафикАвтозаказа.НоменклатурнаяГруппа,
| исГрафикАвтозаказа.Комментарий
|ИЗ
| РегистрСведений.исГрафикАвтозаказа КАК исГрафикАвтозаказа
|ГДЕ
| исГрафикАвтозаказа.ДниНедели = &ДниНедели
| И исГрафикАвтозаказа.Активный = ИСТИНА
| И исГрафикАвтозаказа.ДатаПоследнегоЗаказа < &ДатаПоследнегоЗаказа";
Запрос.УстановитьПараметр("ДниНедели",ДниНедели);
Запрос.УстановитьПараметр("ДатаПоследнегоЗаказа",НачалоДня(ТекущаяДата()));
РТ = Запрос.Выполнить().Выгрузить();

ОтправитьПисьмоОбАвтозаказе = Ложь;
Если РТ.Количество() > 0 Тогда
НеобходимоДоформироватьВнешнийАвтозаказ = Ложь;
Для Каждого Стр Из РТ Цикл
ЗаказДолженБыть = Стр.ДатаПоследнегоЗаказа + (Стр.ПериодичностьНедель - 1)*7*24*60*60;
Если ЗаказДолженБыть>Стр.ДатаПоследнегоЗаказа Тогда
//Сообщить("Не формируем "+Стр.ПериодичностьНедель+" "+Стр.ДниНедели+" "+Стр.Поставщик+" "+Стр.Логист+" "+Стр.ДатаПоследнегоЗаказа);
Продолжить;
КонецЕсли;
НеобходимоДоформироватьВнешнийАвтозаказ = Истина;
ОтправитьПисьмоОбАвтозаказе = Истина;
ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
|Попытка доформировать "+Стр.Поставщик+" ("+Стр.Логист+") после "+Стр.ДатаПоследнегоЗаказа+" (делается 1 раз в "+Стр.ПериодичностьНедель+" недель в "+Стр.ДниНедели+" день недели),";
КонецЦикла;
КонецЕсли;
Если ОтправитьПисьмоОбАвтозаказе = Истина Тогда
ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
|по графику автозаказа.";
ОтправитьПисьмо = Истина;
КонецЕсли;

Если ОтправитьПисьмо = Ложь Тогда
Возврат;
КонецЕсли;

...

Вызывать эту процедуру стоит внешне, примерно таким образом:

Вызывать эту процедуру стоит таим образом:

...
ИмяЛогФайла = "\srvv7basesИмяБазыИмяКаталогаЛогФайл.txt";
Коннектор = СоздатьОбъект("V83.COMConnector");
v8 = Коннектор.Connect("Srvr=""имясервера"";Ref=""ccccccccc"";Usr=""aaaaaaaaa"";Pwd=""xxxxxxxxx"";");
ОтправкаОтчета=v8.Обработки.КонтрольРегламентныхЗаданий.Создать();
Если Фс.СуществуетФайл(ЛогФайл)=1 Тогда
Текст=СоздатьОбъект("Текст");
Текст.Открыть(ЛогФайл);
Текст.ДобавитьСтроку("Отправка отчета выполнена.");
Текст.Записать(ЛогФайл);
КонецЕсли;
ОтправкаОтчета.ОтправитьОтчет(ИмяЛогФайла,V8.NewObject("СписокЗначений"));
v8 = "";
Коннектор = "";
...

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

...
Процедура ВыгрузкаФорматов()Экспорт

НачалоПериода = НачалоДня(ТекущаяДата());
КонецПериода = ТекущаяДата();
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Сообщение.Наименование,
| Сообщение.Выполнена,
| Сообщение.Дата
|ИЗ
| Задача.Сообщение КАК Сообщение
|ГДЕ
| Сообщение.Дата МЕЖДУ &Дата1 И &Дата2
| И Сообщение.ПометкаУдаления = ЛОЖЬ
| И Сообщение.Выполнена = ИСТИНА
| И Сообщение.ТекстСообщения ПОДОБНО ""%ВвестиПереоценку%""";
Запрос.УстановитьПараметр("Дата1",НачалоПериода);
Запрос.УстановитьПараметр("Дата2",КонецПериода);
//Запрос.УстановитьПараметр("Наименование","ПереоценкаПоОкончанииСкидок");
РТ = Запрос.Выполнить().Выгрузить();
Если РТ.Количество() = 0 Тогда
исРегламентныеЗадания.ВвестиПереоценку();
КонецЕсли;

НовоеСообщениеИдентификаторФоновогоЗадания = СоздатьЗадачуСообщениеИдентификаторФоновогоЗадания();
...
далее собственно начинается сама кассовая выгрузка
...

далее собственно идет сама кассовая выгрузка.

5) Настроить отправку отчета о результатах "Контроля выполнения регламентных заданий" по почте программистам.

...
ТемаПочтовогоСообщения = "Сбой выполнения регламентных заданий";

////ЗапуститьПриложение("systeminfo >> systeminfo.txt", "o:!",Истина);
//ИмяФайла = "o:!systeminfo.txt";
//ВыбФайл = Новый Файл(ИмяФайла);
//Если ВыбФайл.Существует() Тогда
// Стр = "Результат выполнения:"+Символы.ПС+
// +"Файл: "+ВыбФайл.ПолноеИмя+Символы.ПС+
// +"Имя: "+ ВыбФайл.Имя+Символы.ПС+
// +"Время изменения: "+ВыбФайл.ПолучитьВремяИзменения()+Символы.ПС+
// +"Только чтение: "+ВыбФайл.ПолучитьТолькоЧтение()+Символы.ПС+
// +"Невидимость: "+ВыбФайл.ПолучитьНевидимость();
...
// ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
// |"+Стр;
//Иначе
// ТекстПочтовогоСообщения = ТекстПочтовогоСообщения + "
// |Состояние сервера неизвестно.";
//КонецЕсли;

Попытка
Профиль = Новый ИнтернетПочтовыйПрофиль;
Профиль.АдресСервераSMTP = "ззз.ззз.ззз.ззз";
Профиль.АдресСервераPOP3 = "эээ.эээ.эээ.эээ";
Профиль.ПортSMTP = 25;
Профиль.ПортPOP3 = 110;
Профиль.Пользователь = "fff%kkk.ru";
Профиль.Пароль = "rrrrrrr";

Почта = Новый ИнтернетПочта;
Попытка
Почта.Подключиться(Профиль);
Исключение
Возврат;
КонецПопытки;

Сообщение = Новый ИнтернетПочтовоеСообщение;
Сообщение.Отправитель = "ssss@ddddd.ru";
Сообщение.ИмяОтправителя = "Торговый комплекс";
ПочтовыеАдреса = Сообщение.Получатели;
ПочтовыйАдрес = ПочтовыеАдреса.Добавить();
ПочтовыйАдрес.Адрес = "admin@hhhhhh.ru";
Сообщение.Тема =ТемаПочтовогоСообщения;
ИнтернетТекстПочтовогоСообщения = Сообщение.Тексты.Добавить();
ИнтернетТекстПочтовогоСообщения.Текст = ТекстПочтовогоСообщения;
ИнтернетТекстПочтовогоСообщения.ТипТекста = ТипТекстаПочтовогоСообщения.ПростойТекст;
Попытка
Почта.Послать(Сообщение);
Исключение
Возврат;
КонецПопытки;
Почта.Отключиться();

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

Подробне по п.5 в качестве примера могу предложить вот такой код:

 

 Пример кода

Ставьте плюсы, пишите в комментарии к статье если возникнут вопросы.

14 Comments

  1. Yashazz

    В своё время мучился-мучился с регламентными заданиями, так проку и не добился. То они не запускались по неведомым причинам ни в какую, то сбоили системные библиотеки 1С, то с сервером приложений связь терялась, то наоборот, все дружно задания как ломанутся (наплевав на свои реальные расписания) и повесят базу…

    Короче, я сделал экспортные пускачи и дёргаю их через обычный sheduler винды. Работает как из пушки. Просто, прозрачно, управляемо. Логи в файлы валю, прикрутил оснастку их регулярного анализа и наступило щастье.

    Reply
  2. TrinitronOTV

    (1) Yashazz, а как вы в sheduler запускаете свои задания?

    Reply
  3. ksnik

    (1) Yashazz, все упомянутое конечно бывает. Можно с помощью bat-файла выполнить вход под клиентом в базу 1С и запуск проблемного задания по тому же самому принципу, как это делается в 1С: Предприятии 7.7:

    date /t >> auto_log.txt
    time /t >> auto_log.txt
    echo Выгрузка в центральную базу  >> auto_log.txt
    start «» /wait «C:Program Files1Cv77BIN1cv7s.exe» config /D\СерверБаза /Nпользователь /Pпароль /@БазаAutoobmenOUT_BB.prm
    time /t >> auto_log.txt
    sleep 20
    …

    или без батника в команде «выполнить» регламентного задания одна строчка:

    «C:Program Files1Cv77BIN1cv7s.exe» enterprise /d\сервербаза /nИмяПользователя /pПароль

    а в процедуре «ПриНачалеРаботыСистемы()»

     Если (ИмяПользователя()=»аааа») Тогда
    Если СокрЛП( Константа.ПрефиксИБ)=»аа» Тогда
    ОткрытьФормуМодально(«Обработка.аааааа»);
    Иначе
    ОткрытьФормуМодально(«Обработка.ббббб»);
    КонецЕсли;
    ИначеЕсли (ИмяПользователя()=»ввв») или (ИмяПользователя()=»ГГГГ») или (ИмяПользователя()=»ДДД») Тогда
    ОткрытьФормуМодально(«Обработка.ЕЕЕЕ»);
    ИначеЕсли (ИмяПользователя()=»ЖЖЖЖ») Тогда
    ОткрытьФормуМодально(«Обработка.ззззз»);
    ИначеЕсли (ИмяПользователя()=»ииии») или (ИмяПользователя()=»ккккк») Тогда
    ОткрытьФормуМодально(«Обработка.ллллллл»);
    КонецЕсли;
    

    Показать

    Такой батник и для 8-ки можно написать, только нужно будет следить за сеансом в котором работает проблемное задание чтоб он не подох и серверные операции инициировать на клиенте.

    Reply
  4. i_lo

    (0), http://infostart.ru/public/237960/. Пол года. Полет нормальный…

    Reply
  5. ksnik

    (4) i_lo, замечательная публикация «Если РЗ должно было начать выполняться до момента проверки, но не выполнялось, то перезаписываем его». Возьму на вооружение, нужно перезапускать и чинить регламентные задания. Я тоже предложил внешний пускач через КОМ, предложенная Вами публикация имеет сходный функционал. Однако регламентные задания должны выполняться сервером и не зависеть от клиента, особенно если они долго выполняются, например у заданий «перепроведение последовательностей взаиморасчетов» или «перепроведение по партиям после обмена» опасно снижать надежность вешая их на клиент.

    п.с. Все таки такого анализа как у меня в «Лекарстве от зависших регламентных заданий» нет, может он уже и не нужен?

    Reply
  6. i_lo

    (5) все, что описано в статье работает на сервере. Никаких клиентов. Запускается серверным планировщиком раз в сутки перед началом рабочего дня. У меня такие регламенты, что так удобнее. Главное, чтобы пользователь, от которого запускается регламентное задание был прописан, как пользователь базы с возможностью доменной аутентификации.

    Reply
  7. ksnik

    (6) i_lo, Ваша статья мне понравилась, спасибо за уточнение «все работает на сервере» и «запускается серверным планировщиком». Я часто делал перезапись вручную (снять использование — записать — установить использование — записать), но иногда не помогает. Вообще не помогает. Поэтому я считаю, что контроль выполнения регламентных заданий мне необходим.

    Reply
  8. alexey_kurdyukov

    Любую системную информацию можно добыть с помощью Windows Management Instrumentation, WMI доступно в 1С.

    msdn

    WMI Samples

    Reply
  9. SerG_121

    Вот еще тебе альтернатива! ) http://infostart.ru/public/116973/

    Reply
  10. ksnik

    (9) SerG_121, работа интересная, но увы админы не разрешат — даже акел пад на сервере не разрешают ставить, когда-то ставил выгонялку из 1С (скачал здесь) и когда ключ 1С заглючил подумали на эту выгонялку. Нужно потроха этого чуда, чтоб самому делать. Можете поделиться немного подробнее?

    Reply
  11. AlexO

    (0) а что вы делаете, если у вас сервер не запускает РЗ в принципе?

    Reply
  12. ksnik

    (11) AlexO, если речь об одном отдельном РЗ, проблема в расписании, поле ввода «повторять» должно быть больше нуля, то есть например каждый день; с 8:00:00 один раз в день, противное значит однократный запуск.

    Чтобы сервер вообще не выполнял — такого у нас не бывало, может Вам переустановить его?

    Reply
  13. AlexO

    (12)

    если речь об одном отдельном РЗ, проблема в расписании

    Так тема называется «Не работают регламентные задания», вот и спросил — если не работают все, что делать-то? )

    может Вам переустановить его?

    В 1С только это и помогает ))

    На самом деле, все перепробовали — перегрузка базы, переподключение сервиса 1С, пинки и уговоры сервера )) … осталось только переустановка 1С-сервера…

    Reply
  14. ksnik

    обновил статью (добавил новый материал), поместил текст примера анализа состояния и отправки сообщения

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *