Моя предыдущая публикация содержала текст запроса, который вычислял конфликты кадровых неявок.
Сейчас я приведу конкретный пример, как этот запрос можно использовать в типовой конфигурации ЗУП для информирования пользователя о конфликтах кадровых неявок при проведении любого кадрового документа, регистрирующего любые кадровые неявки.
Для этого нужно создать новую подписку на событие, скажем, ОперативныйКонтрольНеявок, источник события = РегистрСведенийНаборЗаписей.СостояниеРаботниковОрганизаций, событие = ПриЗаписи, а в качестве процедуры обработчика поместить следующий код :
Процедура ОперативныйКонтрольНеявокПриЗаписи(Источник, Отказ, Замещение) Экспорт
Если Источник.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Регистратор1 = Источник[0].Регистратор;
Запрос = Новый Запрос;
Запрос.Текст = «ВЫБРАТЬ
| СостояниеРаботниковОрганизаций.Период КАК Период,
| СостояниеРаботниковОрганизаций.Регистратор,
| СостояниеРаботниковОрганизаций.НомерСтроки,
| СостояниеРаботниковОрганизаций.Активность,
| СостояниеРаботниковОрганизаций.Сотрудник,
| СостояниеРаботниковОрганизаций.Организация,
| СостояниеРаботниковОрганизаций.Состояние,
| СостояниеРаботниковОрганизаций.ПериодЗавершения,
| СостояниеРаботниковОрганизаций.СостояниеЗавершения
|ПОМЕСТИТЬ ДвиженияОтслеживаемогоРегистратора
|ИЗ
| РегистрСведений.СостояниеРаботниковОрганизаций КАК СостояниеРаботниковОрганизаций
|ГДЕ
| СостояниеРаботниковОрганизаций.Регистратор = &ОтслеживаемыйРегистратор
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| ДвиженияОтслеживаемогоРегистратора.Сотрудник
|ПОМЕСТИТЬ ОптимизацияОтслеживаемыеСотрудники
|ИЗ
| ДвиженияОтслеживаемогоРегистратора КАК ДвиженияОтслеживаемогоРегистратора
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| МИНИМУМ(ДвиженияОтслеживаемогоРегистратора.Период) КАК Период
|ПОМЕСТИТЬ ОптимизацияМинимальныеИнтересующиеПериодыКалендаря
|ИЗ
| ДвиженияОтслеживаемогоРегистратора КАК ДвиженияОтслеживаемогоРегистратора
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| РегламентированныйПроизводственныйКалендарь.ДатаКалендаря
|ПОМЕСТИТЬ ОптимизацияКалендарь
|ИЗ
| РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ОптимизацияМинимальныеИнтересующиеПериодыКалендаря КАК ОптимизацияМинимальныеИнтересующиеПериодыКалендаря
| ПО РегламентированныйПроизводственныйКалендарь.ДатаКалендаря >= ОптимизацияМинимальныеИнтересующиеПериодыКалендаря.Период
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| СостояниеРаботниковОрганизаций.Период КАК Период,
| СостояниеРаботниковОрганизаций.Регистратор,
| СостояниеРаботниковОрганизаций.НомерСтроки,
| СостояниеРаботниковОрганизаций.Активность,
| СостояниеРаботниковОрганизаций.Сотрудник,
| СостояниеРаботниковОрганизаций.Организация,
| СостояниеРаботниковОрганизаций.Состояние,
| СостояниеРаботниковОрганизаций.ПериодЗавершения,
| СостояниеРаботниковОрганизаций.СостояниеЗавершения
|ПОМЕСТИТЬ ДвиженияБезОтслеживаемогоРегистратора
|ИЗ
| РегистрСведений.СостояниеРаботниковОрганизаций КАК СостояниеРаботниковОрганизаций
|ГДЕ
| СостояниеРаботниковОрганизаций.Регистратор <> &ОтслеживаемыйРегистратор
| И СостояниеРаботниковОрганизаций.Сотрудник В
| (ВЫБРАТЬ
| ОптимизацияОтслеживаемыеСотрудники.Сотрудник
| ИЗ
| ОптимизацияОтслеживаемыеСотрудники)
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| МАКСИМУМ(ВЫБОР
| КОГДА ДвиженияБезОтслеживаемогоРегистратора.ПериодЗавершения = ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0)
| ТОГДА ДвиженияБезОтслеживаемогоРегистратора.Период
| КОГДА ДвиженияБезОтслеживаемогоРегистратора.ПериодЗавершения > РегламентированныйПроизводственныйКалендарь.ДатаКалендаря
| ТОГДА ДвиженияБезОтслеживаемогоРегистратора.Период
| ИНАЧЕ ДвиженияБезОтслеживаемогоРегистратора.ПериодЗавершения
| КОНЕЦ) КАК Период,
| РегламентированныйПроизводственныйКалендарь.ДатаКалендаря,
| ДвиженияБезОтслеживаемогоРегистратора.Сотрудник
|ПОМЕСТИТЬ ПериодыСостоянийСотрудниковБезОтслеживаемогоРегистратора
|ИЗ
| ДвиженияБезОтслеживаемогоРегистратора КАК ДвиженияБезОтслеживаемогоРегистратора
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ОптимизацияКалендарь КАК РегламентированныйПроизводственныйКалендарь
| ПО ДвиженияБезОтслеживаемогоРегистратора.Период <= РегламентированныйПроизводственныйКалендарь.ДатаКалендаря
|
|СГРУППИРОВАТЬ ПО
| РегламентированныйПроизводственныйКалендарь.ДатаКалендаря,
| ДвиженияБезОтслеживаемогоРегистратора.Сотрудник
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| МАКСИМУМ(ВЫБОР
| КОГДА ДвиженияОтслеживаемогоРегистратора.ПериодЗавершения = ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0)
| ТОГДА ДвиженияОтслеживаемогоРегистратора.Период
| КОГДА ДвиженияОтслеживаемогоРегистратора.ПериодЗавершения > РегламентированныйПроизводственныйКалендарь.ДатаКалендаря
| ТОГДА ДвиженияОтслеживаемогоРегистратора.Период
| ИНАЧЕ ДвиженияОтслеживаемогоРегистратора.ПериодЗавершения
| КОНЕЦ) КАК Период,
| РегламентированныйПроизводственныйКалендарь.ДатаКалендаря,
| ДвиженияОтслеживаемогоРегистратора.Сотрудник
|ПОМЕСТИТЬ ПериодыСостоянийСотрудниковОтслеживаемогоРегистратора
|ИЗ
| ДвиженияОтслеживаемогоРегистратора КАК ДвиженияОтслеживаемогоРегистратора
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ОптимизацияКалендарь КАК РегламентированныйПроизводственныйКалендарь
| ПО ДвиженияОтслеживаемогоРегистратора.Период <= РегламентированныйПроизводственныйКалендарь.ДатаКалендаря
|
|СГРУППИРОВАТЬ ПО
| РегламентированныйПроизводственныйКалендарь.ДатаКалендаря,
| ДвиженияОтслеживаемогоРегистратора.Сотрудник
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ПериодыСостоянийСотрудников.ДатаКалендаря КАК ДатаКалендаря,
| ПериодыСостоянийСотрудников.Сотрудник,
| ДвиженияБезОтслеживаемогоРегистратора.Регистратор,
| ВЫБОР
| КОГДА ПериодыСостоянийСотрудников.Период = ДвиженияБезОтслеживаемогоРегистратора.Период
| ТОГДА ДвиженияБезОтслеживаемогоРегистратора.Состояние
| ИНАЧЕ ДвиженияБезОтслеживаемогоРегистратора.СостояниеЗавершения
| КОНЕЦ КАК Состояние
|ПОМЕСТИТЬ КалендарьСостоянийСотрудниковБезОтслеживаемогоРегистратора
|ИЗ
| ПериодыСостоянийСотрудниковБезОтслеживаемогоРегистратора КАК ПериодыСостоянийСотрудников
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ДвиженияБезОтслеживаемогоРегистратора КАК ДвиженияБезОтслеживаемогоРегистратора
| ПО (ПериодыСостоянийСотрудников.Период = ДвиженияБезОтслеживаемогоРегистратора.Период
| ИЛИ ПериодыСостоянийСотрудников.Период = ДвиженияБезОтслеживаемогоРегистратора.ПериодЗавершения)
| И ПериодыСостоянийСотрудников.Сотрудник = ДвиженияБезОтслеживаемогоРегистратора.Сотрудник
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ПериодыСостоянийСотрудников.ДатаКалендаря КАК ДатаКалендаря,
| ПериодыСостоянийСотрудников.Сотрудник,
| ДвиженияОтслеживаемогоРегистратора.Регистратор,
| ВЫБОР
| КОГДА ПериодыСостоянийСотрудников.Период = ДвиженияОтслеживаемогоРегистратора.Период
| ТОГДА ДвиженияОтслеживаемогоРегистратора.Состояние
| ИНАЧЕ ДвиженияОтслеживаемогоРегистратора.СостояниеЗавершения
| КОНЕЦ КАК Состояние
|ПОМЕСТИТЬ КалендарьСостоянийСотрудниковОтслеживаемогоРегистратора
|ИЗ
| ПериодыСостоянийСотрудниковОтслеживаемогоРегистратора КАК ПериодыСостоянийСотрудников
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ДвиженияОтслеживаемогоРегистратора КАК ДвиженияОтслеживаемогоРегистратора
| ПО (ПериодыСостоянийСотрудников.Период = ДвиженияОтслеживаемогоРегистратора.Период
| ИЛИ ПериодыСостоянийСотрудников.Период = ДвиженияОтслеживаемогоРегистратора.ПериодЗавершения)
| И ПериодыСостоянийСотрудников.Сотрудник = ДвиженияОтслеживаемогоРегистратора.Сотрудник
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| КалендарьСостоянийСотрудниковБезОтслеживаемогоРегистратора.ДатаКалендаря,
| КалендарьСостоянийСотрудниковБезОтслеживаемогоРегистратора.Сотрудник,
| КалендарьСостоянийСотрудниковБезОтслеживаемогоРегистратора.Регистратор,
| КалендарьСостоянийСотрудниковБезОтслеживаемогоРегистратора.Состояние
|ПОМЕСТИТЬ КалендарьНеявокСотрудниковБезОтслеживаемогоРегистратора
|ИЗ
| КалендарьСостоянийСотрудниковБезОтслеживаемогоРегистратора КАК КалендарьСостоянийСотрудниковБезОтслеживаемогоРегистратора
|ГДЕ
| КалендарьСостоянийСотрудниковБезОтслеживаемогоРегистратора.Состояние <> ЗНАЧЕНИЕ(Перечисление.СостоянияРаботникаОрганизации.Работает)
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| КалендарьСостоянийСотрудниковОтслеживаемогоРегистратора.ДатаКалендаря,
| КалендарьСостоянийСотрудниковОтслеживаемогоРегистратора.Сотрудник,
| КалендарьСостоянийСотрудниковОтслеживаемогоРегистратора.Регистратор,
| КалендарьСостоянийСотрудниковОтслеживаемогоРегистратора.Состояние
|ПОМЕСТИТЬ КалендарьНеявокСотрудниковОтслеживаемогоРегистратора
|ИЗ
| КалендарьСостоянийСотрудниковОтслеживаемогоРегистратора КАК КалендарьСостоянийСотрудниковОтслеживаемогоРегистратора
|ГДЕ
| КалендарьСостоянийСотрудниковОтслеживаемогоРегистратора.Состояние <> ЗНАЧЕНИЕ(Перечисление.СостоянияРаботникаОрганизации.Работает)
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| КалендарьНеявокСотрудниковБезОтслеживаемогоРегистратора.ДатаКалендаря КАК ДатаКалендаряМаксимум,
| КалендарьНеявокСотрудниковБезОтслеживаемогоРегистратора.Сотрудник КАК Сотрудник,
| КалендарьНеявокСотрудниковБезОтслеживаемогоРегистратора.Регистратор КАК Регистратор,
| КалендарьНеявокСотрудниковБезОтслеживаемогоРегистратора.Состояние КАК СостояниеБезОтслеживаемогоРегистратора,
| КалендарьНеявокСотрудниковОтслеживаемогоРегистратора.Состояние КАК СостояниеОтслеживаемогоРегистратора,
| КалендарьНеявокСотрудниковБезОтслеживаемогоРегистратора.ДатаКалендаря КАК ДатаКалендаряМинимум
|ИЗ
| КалендарьНеявокСотрудниковБезОтслеживаемогоРегистратора КАК КалендарьНеявокСотрудниковБезОтслеживаемогоРегистратора
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ КалендарьНеявокСотрудниковОтслеживаемогоРегистратора КАК КалендарьНеявокСотрудниковОтслеживаемогоРегистратора
| ПО КалендарьНеявокСотрудниковБезОтслеживаемогоРегистратора.Сотрудник = КалендарьНеявокСотрудниковОтслеживаемогоРегистратора.Сотрудник
| И КалендарьНеявокСотрудниковБезОтслеживаемогоРегистратора.ДатаКалендаря = КалендарьНеявокСотрудниковОтслеживаемогоРегистратора.ДатаКалендаря
| И КалендарьНеявокСотрудниковБезОтслеживаемогоРегистратора.Состояние <> КалендарьНеявокСотрудниковОтслеживаемогоРегистратора.Состояние
|ИТОГИ
| МАКСИМУМ(ДатаКалендаряМаксимум),
| МИНИМУМ(ДатаКалендаряМинимум)
|ПО
| Сотрудник,
| Регистратор,
| СостояниеОтслеживаемогоРегистратора,
| СостояниеБезОтслеживаемогоРегистратора»;
Запрос.УстановитьПараметр(«ОтслеживаемыйРегистратор», Регистратор1);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Если Выборка.Количество() > 0 Тогда
ОбработкаКомментариев = глЗначениеПеременной(«глОбработкаСообщений»);
ОбработкаКомментариев.УдалитьСообщения();
ТекстСообщения = «Проведение документа » + Регистратор1 + » : «;
ЗаголовокСообщения = ОбработкаКомментариев.ДобавитьСообщение(ТекстСообщения, Перечисления.ВидыСообщений.ВажнаяИнформация);
КонецЕсли;
Пока Выборка.СледующийПоЗначениюПоля(«Сотрудник») Цикл
Если НЕ ЗначениеЗаполнено(Выборка.Сотрудник) Тогда
Продолжить;
КонецЕсли;
Пока Выборка.СледующийПоЗначениюПоля(«Регистратор») Цикл
Если НЕ ЗначениеЗаполнено(Выборка.Регистратор) Тогда
Продолжить;
КонецЕсли;
Пока Выборка.СледующийПоЗначениюПоля(«СостояниеОтслеживаемогоРегистратора») Цикл
Если НЕ ЗначениеЗаполнено(Выборка.СостояниеОтслеживаемогоРегистратора) Тогда
Продолжить;
КонецЕсли;
Пока Выборка.СледующийПоЗначениюПоля(«СостояниеБезОтслеживаемогоРегистратора») Цикл
Если НЕ ЗначениеЗаполнено(Выборка.СостояниеБезОтслеживаемогоРегистратора) Тогда
Продолжить;
КонецЕсли;
ОбработкаКомментариев.ДобавитьСообщение(«Сотрудник `» + Выборка.Сотрудник + «‘ (» + Выборка.СостояниеОтслеживаемогоРегистратора + » » + Формат(Выборка.ДатаКалендаряМинимум, «ДФ=dd.MM.yyyy») + » — » + Формат(Выборка.ДатаКалендаряМаксимум, «ДФ=dd.MM.yyyy») + «) уже переведен в состояние «»» + Выборка.СостояниеБезОтслеживаемогоРегистратора + «»» документом » + Выборка.Регистратор + «»
, Перечисления.ВидыСообщений.Информация, , ЗаголовокСообщения);
КонецЦикла;
КонецЦикла;
КонецЦикла;
КонецЦикла;
Если Выборка.Количество() > 0 Тогда
ОбработкаКомментариев.ПоказатьСообщения();
КонецЕсли;
КонецПроцедуры
Примечание : поскольку никакие виды документов и никакие виды неявок в этом коде не поименованы, этот код не нужно будет модифицировать при добавлении «своих» видов документов (например, «Отзыв из отпуска», «Отзыв из командировки») или «своих» видов неявок.