рубрики: Периодические запросы | Дата: 23 февраля, 2014
Эта статья открывает серию статей про периодические запросы в ЗУП.
В ней рассмотрен простейший случай, когда нам надо получить на каждую дату календаря за определенный период информацию по сотруднику. В нашем примере это будет должность и подразделение. Сложность заключается в том, что срез последних использовать не можем, т.к. нам надо получить информацию не на одну дату, а на несколько. Напомню что информация об изменении должности и подразделения хранится в периодическом регистре сведений «РаботникиОрганизаций». Даты календаря возьмем из регистра сведений «РегламентированныйПроизводственныйКалендарь».
Первым делом для каждой даты календаря найдем запись с максимальным периодом из регистра сведений «РаботникиОрганизаций» для сотрудника. Это будет вложенный запрос.
ВЫБРАТЬ
РегламентированныйПроизводственныйКалендарь.ДатаКалендаря КАК ДатаКалендаря,
МАКСИМУМ(РаботникиОрганизаций.Период) КАК ПериодМаксимум,
РаботникиОрганизаций.Сотрудник КАК Сотрудник
ИЗ
РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизаций
ПО РегламентированныйПроизводственныйКалендарь.ДатаКалендаря >= РаботникиОрганизаций.Период
ГДЕ
РегламентированныйПроизводственныйКалендарь.ДатаКалендаря МЕЖДУ &НачалоПериода И &КонецПериода
И РаботникиОрганизаций.Сотрудник = &Сотрудник
СГРУППИРОВАТЬ ПО
РегламентированныйПроизводственныйКалендарь.ДатаКалендаря,
РаботникиОрганизаций.Сотрудник
Хочу заметить, что получать исторические сведения можно не только в разрезе одного реквизита (в данном случае сотрудник), но и нескольких. В частности в версии ЗУП для платформы 8.0 в «Работниках организаций» не было измерения «Сотрудник», а было физлицо и приказ о приеме на работу. Соответственно вместо сотрудника приходилось делать группировку по физлицу и приказу о приеме. Самое главное не тащить в этот вложенный запрос избыточные данные. Только те для которых собираем историю.
Далее к вложенному запросу снова цепляем «РаботниковОрганизаций» с привязкой по сотруднику и максимальному периоду. и вот здесь уже выбираем подразделение и должность. Это и будут те подразделения и должность, которые сотрудник занимал на дату календаря. Итоговый запрос выглядит так:
ВЫБРАТЬ
МаксимальныйПериодСотрудника.ДатаКалендаря КАК ДатаКалендаря,
МаксимальныйПериодСотрудника.Сотрудник,
РаботникиОрганизаций.Должность,
РаботникиОрганизаций.ПодразделениеОрганизации
ИЗ
(ВЫБРАТЬ
РегламентированныйПроизводственныйКалендарь.ДатаКалендаря КАК ДатаКалендаря,
МАКСИМУМ(РаботникиОрганизаций.Период) КАК ПериодМаксимум,
РаботникиОрганизаций.Сотрудник КАК Сотрудник
ИЗ
РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизаций
ПО РегламентированныйПроизводственныйКалендарь.ДатаКалендаря >= РаботникиОрганизаций.Период
ГДЕ
РегламентированныйПроизводственныйКалендарь.ДатаКалендаря МЕЖДУ &НачалоПериода И &КонецПериода
И РаботникиОрганизаций.Сотрудник = &Сотрудник
СГРУППИРОВАТЬ ПО
РегламентированныйПроизводственныйКалендарь.ДатаКалендаря,
РаботникиОрганизаций.Сотрудник) КАК МаксимальныйПериодСотрудника
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизаций
ПО МаксимальныйПериодСотрудника.ПериодМаксимум = РаботникиОрганизаций.Период
И МаксимальныйПериодСотрудника.Сотрудник = РаботникиОрганизаций.Сотрудник
УПОРЯДОЧИТЬ ПО
ДатаКалендаря
Спасибо. Прочитал с интересом, и вообще полезный у Вас блог
Запрос не работает если у сотрудника было временное перемещение т.к. не учитывается дата окончания, подразделение окончания и должность окончания.
Спасибо большое, очень помог запрос.
А правильный запрос выглядит так:
ВЫБРАТЬ
РаботникиОрганизацийСрезПоследних.Сотрудник КАК Сотрудник,
ВЫБОР
КОГДА РаботникиОрганизацийСрезПоследних.ПериодЗавершения <= &КонецПериода
И РаботникиОрганизацийСрезПоследних.ПериодЗавершения ДАТАВРЕМЯ(1, 1, 1)
ТОГДА РаботникиОрганизацийСрезПоследних.ПериодЗавершения
ИНАЧЕ РаботникиОрганизацийСрезПоследних.Период
КОНЕЦ КАК Период,
ВЫБОР
КОГДА РаботникиОрганизацийСрезПоследних.ПериодЗавершения <= &КонецПериода
И РаботникиОрганизацийСрезПоследних.ПериодЗавершения ДАТАВРЕМЯ(1, 1, 1)
ТОГДА РаботникиОрганизацийСрезПоследних.ПодразделениеОрганизацииЗавершения
ИНАЧЕ РаботникиОрганизацийСрезПоследних.ПодразделениеОрганизации
КОНЕЦ КАК ПодразделениеОрганизации
ИЗ
РегистрСведений.РаботникиОрганизаций.СрезПоследних(&НачалоПериода, ) КАК РаботникиОрганизацийСрезПоследних
ГДЕ
РаботникиОрганизацийСрезПоследних.Сотрудник = &Сотрудник
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
РаботникиОрганизаций.Сотрудник,
РаботникиОрганизаций.Период,
РаботникиОрганизаций.ПодразделениеОрганизации
ИЗ
РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизаций
ГДЕ
РаботникиОрганизаций.Сотрудник = &Сотрудник
И РаботникиОрганизаций.Период > &НачалоПериода
И РаботникиОрганизаций.Период = ПериодыПерекрытия.Период
И РаботникиОрганизаций.Период < ПериодыПерекрытия.Период
ГДЕ
РаботникиОрганизаций.Сотрудник = &Сотрудник
И РаботникиОрганизаций.ПериодЗавершения ДАТАВРЕМЯ(1, 1, 1)
И РаботникиОрганизаций.ПериодЗавершения > &НачалоПериода
И РаботникиОрганизаций.ПериодЗавершения <= &КонецПериода
И ПериодыПерекрытия.Период ЕСТЬ NULL
1. Ты невнимательно читал мой пост. Я описывал ситуацию, когда надо получить должность и подразделение на КАЖДУЮ дату периода, т.е. результат запроса должен выглядеть следующим образом:
01.12.2015 | Должность_1 | Подразделение_1
02.12.2015 | Должность_1 | Подразделение_1
03.12.2015 | Должность_2 | Подразделение_1
04.12.2015 | Должность_2 | Подразделение_1
05.12.2015 | Должность_2 | Подразделение_1
06.12.2015 | Должность_2 | Подразделение_2
2. В своем посте я описывал сам принцип построения таких запросов. Поэтому для простоты изложения сделал допущение, что дата окончания всегда пустая, иначе читать и разбираться никто не будет. Мне самому не нравятся длинные и запутанные примеры, когда осваиваю что-то новое. А человек, который понял сам принцип без труда сможет реализовать и более сложные вещи.
3. Прежде чем выкладывать куда-то свой пример запроса, неплохо бы проверить его в консоли 😉
— В трех местах у тебя не хватает знаков сравнения. Вот здесь:
И РаботникиОрганизацийСрезПоследних.ПериодЗавершения ДАТАВРЕМЯ(1, 1, 1)
— Что такое ПериодыПерекрытия?
— При использовании виртуальных таблиц среза последних отбор устанавливается в параметрах виртуальной таблицы, а не в условии, т.е.
ИЗ РегистрСведений.РаботникиОрганизаций.СрезПоследних(&НачалоПериода, Сотрудник = &Сотрудник) КАК РаботникиОрганизацийСрезПоследних
вместо
ГДЕ РаботникиОрганизацийСрезПоследних.Сотрудник = &Сотрудник
— внизу непонятное дважды повторяющееся условие
ГДЕ
РаботникиОрганизаций.Сотрудник = &Сотрудник
И РаботникиОрганизаций.Период > &НачалоПериода
И РаботникиОрганизаций.Период = ПериодыПерекрытия.Период
И РаботникиОрганизаций.Период < ПериодыПерекрытия.Период ГДЕ РаботникиОрганизаций.Сотрудник = &Сотрудник ......................... Так что давай выкладывай рабочую версию 😉
zerg:
08.07.2015 в 06:33
«Запрос не работает если у сотрудника было временное перемещение т.к. не учитывается дата окончания, подразделение окончания и должность окончания.»
Удалите или доработайте
На своем сайте я стараюсь показать какие-то общие принципы. И примеры стараюсь приводить простейшие. Если вы поняли сам принцип того как строится запрос без учета даты окончания, то сможете и с датой окончания доработать самостоятельно. И удалять конечно же я ничего не буду.