рубрики: Периодические запросы | Дата: 7 апреля, 2014
Это вторая статья на тему периодических запросов в ЗУП. Рассмотрим пример, когда нам надо получить историю изменения должности сотрудников за какой-то период. Это может быть и история изменения подразделения и комбинация изменения должности с подразделением.
Принцип один и тот же. Но рассмотрим на примере должности. То есть в итоговой таблице после выполнения запроса у нас будут следующие поля: Сотрудник, ДатаНачала, ДатаОкончания, Должность. Соответственно будут заданы и два параметра: &НачалоПериода и &КонецПериода в рамках которых мы и будем анализировать изменение должностей. Заврос будем строить по регистру сведений РаботникиОрганизаций. Напомню, что в этом регистре есть ресурс ПериодЗавершения. То есть в кадровых документах есть возможность указывать и дату завершения действия данного приказа. Так в приеме на работу можно указать дату окончания, после которой сотрудник будет считаться уволенным. И эта дата окончания записывается именно в реквизит ПериодЗавершения. То же самое и с кадровыми перемещениями — если указана дата окончания, то после нее сотрудник считается вернувшимся на предыдущую должность в предыдущее подразделение. В то же самое время все эти кадровые движение есть возможность делать без указания даты окончания, т.е. просто использовать два разных кадровых документа вместо одного. Сразу оговорюсь, что в рамках данной статьи буду рассматривать ситуацию когда в кадровых документах дата окончания не указыватеся. Это значительно упростит запрос, хотя общий принцип останется тот же.
План будет такой. Сначала находим даты начала работ на новой должности каждого сотрудника, затем даты окончания, а затем присоединим даты окончания к датам начала. На первый взгляд все просто. Вообще на самом деле это общий план для всех периодических запросов где речь идет о получении в разрезе сотрудника истории изменения каких-либо реквизитов. Сначала получаем даты начала, затем даты окончания и наконец соединяем их в единую таблицу. Просто в зависимости от задачи трудоемкость получения этих дат может изменяться.
Теперь зададимся вопросом, по каким признакам нам выбрать даты начала из регистра сведений РаботникиОрганизаций, в каких записях поле Период может выступать в качестве даты начала работы сотрудника на новой должности. Рассмотрим все возможные варианты.
ВЫБРАТЬ
&НачалоПериода,
РаботникиОрганизацийСрезПоследних.Сотрудник,
РаботникиОрганизацийСрезПоследних.Должность
ИЗ
РегистрСведений.РаботникиОрганизаций.СрезПоследних(&НачалоПериода, ) КАК РаботникиОрганизацийСрезПоследних
ГДЕ
РаботникиОрганизацийСрезПоследних.ПричинаИзмененияСостояния <> ЗНАЧЕНИЕ(Перечисление.ПричиныИзмененияСостояния.Увольнение)
ВЫБРАТЬ
РаботникиОрганизаций.Период,
РаботникиОрганизаций.Сотрудник,
РаботникиОрганизаций.Должность
ИЗ
РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизаций
ГДЕ
РаботникиОрганизаций.Период МЕЖДУ &НачалоПериода И &КонецПериода
И РаботникиОрганизаций.ПричинаИзмененияСостояния = ЗНАЧЕНИЕ(Перечисление.ПричиныИзмененияСостояния.ПриемНаРаботу)
ВЫБРАТЬ
КадровоеПеремещениеПредыдущийПериод.Период,
КадровоеПеремещениеПредыдущийПериод.Сотрудник,
КадровоеПеремещениеПредыдущийПериод.Должность
ИЗ
(ВЫБРАТЬ
РаботникиОрганизаций.Период КАК Период,
РаботникиОрганизаций.Сотрудник КАК Сотрудник,
РаботникиОрганизаций.Должность КАК Должность,
МАКСИМУМ(РаботникиОрганизацийПредыдущая.Период) КАК ПериодМаксимум
ИЗ
РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизаций
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизацийПредыдущая
ПО РаботникиОрганизаций.Сотрудник = РаботникиОрганизацийПредыдущая.Сотрудник
И РаботникиОрганизаций.Период > РаботникиОрганизацийПредыдущая.Период
ГДЕ
РаботникиОрганизаций.ПричинаИзмененияСостояния = ЗНАЧЕНИЕ(Перечисление.ПричиныИзмененияСостояния.Перемещение)
И РаботникиОрганизаций.Период МЕЖДУ &НачалоПериода И &КонецПериода
СГРУППИРОВАТЬ ПО
РаботникиОрганизаций.Период,
РаботникиОрганизаций.Сотрудник,
РаботникиОрганизаций.Должность) КАК КадровоеПеремещениеПредыдущийПериод
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизаций
ПО КадровоеПеремещениеПредыдущийПериод.ПериодМаксимум = РаботникиОрганизаций.Период
И КадровоеПеремещениеПредыдущийПериод.Сотрудник = РаботникиОрганизаций.Сотрудник
ГДЕ
КадровоеПеремещениеПредыдущийПериод.Должность <> РаботникиОрганизаций.Должность
Ну а теперь объединим все три запроса в один и поместим во временную таблицу.
ВЫБРАТЬ
&НачалоПериода,
РаботникиОрганизацийСрезПоследних.Сотрудник,
РаботникиОрганизацийСрезПоследних.Должность
ПОМЕСТИТЬ ВТ_ДатыНачала
ИЗ
РегистрСведений.РаботникиОрганизаций.СрезПоследних(&НачалоПериода, ) КАК РаботникиОрганизацийСрезПоследних
ГДЕ
РаботникиОрганизацийСрезПоследних.ПричинаИзмененияСостояния <> ЗНАЧЕНИЕ(Перечисление.ПричиныИзмененияСостояния.Увольнение)
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
РаботникиОрганизаций.Период,
РаботникиОрганизаций.Сотрудник,
РаботникиОрганизаций.Должность
ИЗ
РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизаций
ГДЕ
РаботникиОрганизаций.Период МЕЖДУ &НачалоПериода И &КонецПериода
И РаботникиОрганизаций.ПричинаИзмененияСостояния = ЗНАЧЕНИЕ(Перечисление.ПричиныИзмененияСостояния.ПриемНаРаботу)
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
КадровоеПеремещениеПредыдущийПериод.Период,
КадровоеПеремещениеПредыдущийПериод.Сотрудник,
КадровоеПеремещениеПредыдущийПериод.Должность
ИЗ
(ВЫБРАТЬ
РаботникиОрганизаций.Период КАК Период,
РаботникиОрганизаций.Сотрудник КАК Сотрудник,
РаботникиОрганизаций.Должность КАК Должность,
МАКСИМУМ(РаботникиОрганизацийПредыдущая.Период) КАК ПериодМаксимум
ИЗ
РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизаций
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизацийПредыдущая
ПО РаботникиОрганизаций.Сотрудник = РаботникиОрганизацийПредыдущая.Сотрудник
И РаботникиОрганизаций.Период > РаботникиОрганизацийПредыдущая.Период
ГДЕ
РаботникиОрганизаций.ПричинаИзмененияСостояния = ЗНАЧЕНИЕ(Перечисление.ПричиныИзмененияСостояния.Перемещение)
И РаботникиОрганизаций.Период МЕЖДУ &НачалоПериода И &КонецПериода
СГРУППИРОВАТЬ ПО
РаботникиОрганизаций.Период,
РаботникиОрганизаций.Сотрудник,
РаботникиОрганизаций.Должность) КАК КадровоеПеремещениеПредыдущийПериод
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизаций
ПО КадровоеПеремещениеПредыдущийПериод.ПериодМаксимум = РаботникиОрганизаций.Период
И КадровоеПеремещениеПредыдущийПериод.Сотрудник = РаботникиОрганизаций.Сотрудник
ГДЕ
КадровоеПеремещениеПредыдущийПериод.Должность <> РаботникиОрганизаций.Должность
Теперь займемся датами окончания. Также рассмотрим все варианты.
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(РаботникиОрганизаций.Период, ДЕНЬ, -1) КАК ДатаОкончания,
РаботникиОрганизаций.Сотрудник
ИЗ
РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизаций
ГДЕ
РаботникиОрганизаций.ПричинаИзмененияСостояния = ЗНАЧЕНИЕ(Перечисление.ПричиныИзмененияСостояния.Увольнение)
И ДОБАВИТЬКДАТЕ(РаботникиОрганизаций.Период, ДЕНЬ, -1) МЕЖДУ &НачалоПериода И &КонецПериода
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(КадровоеПеремещениеПредыдущийПериод.Период, ДЕНЬ, -1) КАК ДатаОкончания,
КадровоеПеремещениеПредыдущийПериод.Сотрудник
ИЗ
(ВЫБРАТЬ
РаботникиОрганизаций.Период КАК Период,
РаботникиОрганизаций.Сотрудник КАК Сотрудник,
РаботникиОрганизаций.Должность КАК Должность,
МАКСИМУМ(РаботникиОрганизацийПредыдущая.Период) КАК ПериодМаксимум
ИЗ
РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизаций
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизацийПредыдущая
ПО РаботникиОрганизаций.Сотрудник = РаботникиОрганизацийПредыдущая.Сотрудник
И РаботникиОрганизаций.Период > РаботникиОрганизацийПредыдущая.Период
ГДЕ
РаботникиОрганизаций.ПричинаИзмененияСостояния = ЗНАЧЕНИЕ(Перечисление.ПричиныИзмененияСостояния.Перемещение)
И ДОБАВИТЬКДАТЕ(РаботникиОрганизаций.Период, ДЕНЬ, -1) МЕЖДУ &НачалоПериода И &КонецПериода
СГРУППИРОВАТЬ ПО
РаботникиОрганизаций.Период,
РаботникиОрганизаций.Сотрудник,
РаботникиОрганизаций.Должность) КАК КадровоеПеремещениеПредыдущийПериод
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизаций
ПО КадровоеПеремещениеПредыдущийПериод.ПериодМаксимум = РаботникиОрганизаций.Период
И КадровоеПеремещениеПредыдущийПериод.Сотрудник = РаботникиОрганизаций.Сотрудник
ГДЕ
КадровоеПеремещениеПредыдущийПериод.Должность <> РаботникиОрганизаций.Должность
Объединим два запроса по датам окончания и поместим результат во временную таблицу ВТ_ДатыОкончания. Далее присоединим даты окончания к датам начала. Причем внутри нашего периода может быть несколько периодов окончания, поэтому берем дату окончания ближайшую к дате начала. Делаем это с использованием группировки. Если дата окончания не найдена, то считаем датой окончания &КонецПериода. В общем вот итоговый текст запроса.
ВЫБРАТЬ
&НачалоПериода КАК ДатаНачала,
РаботникиОрганизацийСрезПоследних.Сотрудник,
РаботникиОрганизацийСрезПоследних.Должность
ПОМЕСТИТЬ ВТ_ДатыНачала
ИЗ
РегистрСведений.РаботникиОрганизаций.СрезПоследних(&НачалоПериода, ) КАК РаботникиОрганизацийСрезПоследних
ГДЕ
РаботникиОрганизацийСрезПоследних.ПричинаИзмененияСостояния <> ЗНАЧЕНИЕ(Перечисление.ПричиныИзмененияСостояния.Увольнение)
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
РаботникиОрганизаций.Период,
РаботникиОрганизаций.Сотрудник,
РаботникиОрганизаций.Должность
ИЗ
РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизаций
ГДЕ
РаботникиОрганизаций.Период МЕЖДУ &НачалоПериода И &КонецПериода
И РаботникиОрганизаций.ПричинаИзмененияСостояния = ЗНАЧЕНИЕ(Перечисление.ПричиныИзмененияСостояния.ПриемНаРаботу)
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
КадровоеПеремещениеПредыдущийПериод.Период,
КадровоеПеремещениеПредыдущийПериод.Сотрудник,
КадровоеПеремещениеПредыдущийПериод.Должность
ИЗ
(ВЫБРАТЬ
РаботникиОрганизаций.Период КАК Период,
РаботникиОрганизаций.Сотрудник КАК Сотрудник,
РаботникиОрганизаций.Должность КАК Должность,
МАКСИМУМ(РаботникиОрганизацийПредыдущая.Период) КАК ПериодМаксимум
ИЗ
РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизаций
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизацийПредыдущая
ПО РаботникиОрганизаций.Сотрудник = РаботникиОрганизацийПредыдущая.Сотрудник
И РаботникиОрганизаций.Период > РаботникиОрганизацийПредыдущая.Период
ГДЕ
РаботникиОрганизаций.ПричинаИзмененияСостояния = ЗНАЧЕНИЕ(Перечисление.ПричиныИзмененияСостояния.Перемещение)
И РаботникиОрганизаций.Период МЕЖДУ &НачалоПериода И &КонецПериода
СГРУППИРОВАТЬ ПО
РаботникиОрганизаций.Период,
РаботникиОрганизаций.Сотрудник,
РаботникиОрганизаций.Должность) КАК КадровоеПеремещениеПредыдущийПериод
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизаций
ПО КадровоеПеремещениеПредыдущийПериод.ПериодМаксимум = РаботникиОрганизаций.Период
И КадровоеПеремещениеПредыдущийПериод.Сотрудник = РаботникиОрганизаций.Сотрудник
ГДЕ
КадровоеПеремещениеПредыдущийПериод.Должность <> РаботникиОрганизаций.Должность
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(РаботникиОрганизаций.Период, ДЕНЬ, -1) КАК ДатаОкончания,
РаботникиОрганизаций.Сотрудник
ПОМЕСТИТЬ ВТ_ДатыОкончания
ИЗ
РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизаций
ГДЕ
РаботникиОрганизаций.ПричинаИзмененияСостояния = ЗНАЧЕНИЕ(Перечисление.ПричиныИзмененияСостояния.Увольнение)
И ДОБАВИТЬКДАТЕ(РаботникиОрганизаций.Период, ДЕНЬ, -1) МЕЖДУ &НачалоПериода И &КонецПериода
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(КадровоеПеремещениеПредыдущийПериод.Период, ДЕНЬ, -1),
КадровоеПеремещениеПредыдущийПериод.Сотрудник
ИЗ
(ВЫБРАТЬ
РаботникиОрганизаций.Период КАК Период,
РаботникиОрганизаций.Сотрудник КАК Сотрудник,
РаботникиОрганизаций.Должность КАК Должность,
МАКСИМУМ(РаботникиОрганизацийПредыдущая.Период) КАК ПериодМаксимум
ИЗ
РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизаций
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизацийПредыдущая
ПО РаботникиОрганизаций.Сотрудник = РаботникиОрганизацийПредыдущая.Сотрудник
И РаботникиОрганизаций.Период > РаботникиОрганизацийПредыдущая.Период
ГДЕ
РаботникиОрганизаций.ПричинаИзмененияСостояния = ЗНАЧЕНИЕ(Перечисление.ПричиныИзмененияСостояния.Перемещение)
И ДОБАВИТЬКДАТЕ(РаботникиОрганизаций.Период, ДЕНЬ, -1) МЕЖДУ &НачалоПериода И &КонецПериода
СГРУППИРОВАТЬ ПО
РаботникиОрганизаций.Период,
РаботникиОрганизаций.Сотрудник,
РаботникиОрганизаций.Должность) КАК КадровоеПеремещениеПредыдущийПериод
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизаций
ПО КадровоеПеремещениеПредыдущийПериод.ПериодМаксимум = РаботникиОрганизаций.Период
И КадровоеПеремещениеПредыдущийПериод.Сотрудник = РаботникиОрганизаций.Сотрудник
ГДЕ
КадровоеПеремещениеПредыдущийПериод.Должность <> РаботникиОрганизаций.Должность
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_ДатыНачала.Сотрудник,
ВТ_ДатыНачала.Должность,
ВТ_ДатыНачала.ДатаНачала КАК ДатаНачала,
МИНИМУМ(ЕСТЬNULL(ВТ_ДатыОкончания.ДатаОкончания, &КонецПериода)) КАК ДатаОкончания
ИЗ
ВТ_ДатыНачала КАК ВТ_ДатыНачала
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ДатыОкончания КАК ВТ_ДатыОкончания
ПО ВТ_ДатыНачала.Сотрудник = ВТ_ДатыОкончания.Сотрудник
И ВТ_ДатыНачала.ДатаНачала <= ВТ_ДатыОкончания.ДатаОкончания
СГРУППИРОВАТЬ ПО
ВТ_ДатыНачала.Сотрудник,
ВТ_ДатыНачала.Должность,
ВТ_ДатыНачала.ДатаНачала
УПОРЯДОЧИТЬ ПО
ВТ_ДатыНачала.Сотрудник.Наименование,
ДатаНачала
Здесь показан основной принцип. можно построить таким же образом историю изменения подразделения сотрудника за период или одновременно должности и подразделения. И конечно применять такой принцип можно не только к регистру сведений РаботникиОрганизаций, но и к другим периодическим регистрам сведений. Например, СостояниеРаботниковОрганизаций. Как правило необходимость в подобных запросах встречается в конфигурации ЗУП.
Добавить комментарий