v8: Хитрая система оповещенийМне понадобилось сделать оповещении о некотором событии в ЗУП за 14 и 31 день при старте системы.
Пришлось сделать хитроумно, т.к. пользователь мог отсутствовать 2-5 дней, а ему нужно известить. | | Автор статьи: Гений 1С Последняя редакция №1 от 21.04.08 URL: http://kb.mista.ru/article.php?id=663 | |
Ключевые слова: оповещение,алгоритм
В общем, нужно было извещать пользователя о наступлении некоторого события (конкретно - завершения действия должности штатного расписания) за 14 и за 31 день.
Проблема в том, что дата извещения может приходиться на выходной день пользователя, или пользователь просто может отсутствовать в этот день.
Решено, что при запуске 1С определяются, о каких событиях нужно извещать и смотрится, извещали ли мы уже о данном событии и в какую дату. Если извещали, то повторяются только сегодняшние извещения.
Если еще не извещали, то извещения помечаются, как сегодняшнее.
Для хранения дат извещений я не стал использовать регистр сведений, использую настройки пользователя, т.к. когда мы оповещали - не очень важные данные, чтобы насиловать ЗУП еще одним регистром, хотя можно было завести регистр {ПодразделениеОрганизации, Должность => Дата оповещения, Дата завершения}.
Если срок извещения изменен, то это означает, что нужно переизвестить.
Вот код:
Функция Сформировать() Экспорт
//Выводим в макет
Макет=ПолучитьМакет("НапоминаниеОЗавершениеДействииШтатногоРасписания");
ТабДок=ЭлементыФормы.ТабДок;
ТабДок.Очистить();
//Получаем напоминания
Запрос=Новый Запрос();
Запрос.Текст=
"ВЫБРАТЬ
| ШтатноеРасписаниеОрганизаций.ДействуетПО КАК Дата2,
| ШтатноеРасписаниеОрганизаций.Период КАК Дата1,
| ШтатноеРасписаниеОрганизаций.ПодразделениеОрганизации,
| ШтатноеРасписаниеОрганизаций.Должность,
| РАЗНОСТЬДАТ(&Сегодня, ШтатноеРасписаниеОрганизаций.ДействуетПО, ДЕНЬ) КАК ОсталосьДней
|ИЗ
| РегистрСведений.ШтатноеРасписаниеОрганизаций КАК ШтатноеРасписаниеОрганизаций
|ГДЕ
| ШтатноеРасписаниеОрганизаций.ДействуетПО <> ДАТАВРЕМЯ(1, 1, 1)";
Запрос.УстановитьПараметр("Сегодня", ТекущаяДата());
ТЗ=Запрос.Выполнить().Выгрузить();
ТЗ.Колонки.Добавить("Порядок");
ТЗ.Колонки.Добавить("КлючЗаписи");
ТЗ.Колонки.Добавить("СтруктураОповещения");
КоличествоНапоминаний=0;
НачалоСегодня=НачалоДня(ТекущаяДата());
Для Каждого Стр ИЗ ТЗ Цикл
Стр.КлючЗаписи="ОповещениеШтатногоРасписания_2_"+Стр.ПодразделениеОрганизации.УникальныйИдентификатор()+"_"+Стр.Должность.УникальныйИдентификатор();
Стр.СтруктураОповещения=ВосстановитьЗначение(Стр.КлючЗаписи);
Если ТипЗнч(Стр.СтруктураОповещения)<>Тип("Структура") Тогда
Стр.СтруктураОповещения=Новый Структура("Период14, Период31, Дата2", Неопределено, Неопределено, Неопределено);
//Неопределено - не оповещать
//Если стоит дата, то нужно оповещать в течении каждого запуска в течении дня
КонецЕсли;
Если Стр.ОсталосьДней<=14 Тогда
Если Стр.СтруктураОповещения.Период14=Неопределено ИЛИ Стр.СтруктураОповещения.Период14=НачалоСегодня ИЛИ Стр.СтруктураОповещения.Дата2<>Стр.Дата2 Тогда //Может уже оповестили
Стр.СтруктураОповещения.Период14=НачалоСегодня; //Больше не надо оповещать
Стр.Порядок=1;
Стр.СтруктураОповещения.Дата2=Стр.Дата2;
КоличествоНапоминаний=КоличествоНапоминаний+1;
КонецЕсли;
ИначеЕсли Стр.ОсталосьДней<=31 Тогда
Если Стр.СтруктураОповещения.Период31=Неопределено ИЛИ Стр.СтруктураОповещения.Период31=НачалоСегодня ИЛИ Стр.СтруктураОповещения.Дата2<>Стр.Дата2 Тогда //Может уже оповестили
Стр.СтруктураОповещения.Период31=НачалоСегодня; //Больше не надо оповещать
Стр.Порядок=2;
Стр.СтруктураОповещения.Дата2=Стр.Дата2;
КоличествоНапоминаний=КоличествоНапоминаний+1;
КонецЕсли;
Иначе
Порядок=3;
КонецЕсли;
КонецЦикла;
ТЗ.Сортировать("Порядок, ОсталосьДней Возр");
Область=Макет.ПолучитьОбласть("Шапка");
ТабДок.Вывести(Область);
Для Каждого Стр ИЗ ТЗ Цикл
//КоличествоНапоминаний=КоличествоНапоминаний+1;
Область=Макет.ПолучитьОбласть("Строка");
Область.Параметры.Заполнить(Стр);
ТабДок.Вывести(Область);
Если Стр.Порядок=1 Тогда
ТабДок.Область(ТабДок.ВысотаТаблицы, 1, ТабДок.ВысотаТаблицы, ТабДок.ШиринаТаблицы).ЦветФона=WebЦвета.Розовый;
ИначеЕсли Стр.Порядок=2 Тогда
ТабДок.Область(ТабДок.ВысотаТаблицы, 1, ТабДок.ВысотаТаблицы, ТабДок.ШиринаТаблицы).ЦветФона=WebЦвета.СветлоЗеленый;
КонецЕсли;
КонецЦикла;
Для Каждого Стр ИЗ ТЗ Цикл
СохранитьЗначение(Стр.КлючЗаписи, Стр.СтруктураОповещения);
КонецЦикла;
КонецФункции
Ну, естественно, нужно сделать оповещения отключаемыми в настройках пользователя:
Функция НапомнитьОЗавершенииДействияШтатногоРасписания() Экспорт
Ф=Отчеты.НапомнитьОЗавершенииДействияШтатногоРасписания.ПолучитьФорму();
Ф.Открыть();
Ф.Сформировать();
Если Ф.КоличествоНапоминаний=0 Тогда
Ф.Закрыть();
КонецЕсли;
КонецФункции
Функция ПриНачалеРаботыСистемы() Экспорт
...
флНапоминатьОЗавершенииДействияШтатногоРасписания = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(глЗначениеПеременной("глТекущийПользователь"), "НапоминатьОЗавершенииДействияШтатногоРасписания");
Если флНапоминатьОЗавершенииДействияШтатногоРасписания Тогда
НапомнитьОЗавершенииДействияШтатногоРасписания();
КонецЕсли;
...
КонецФункции
|