Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 
vtatarnikov
Creator
Creator

Подсчет сотрудников имея записи о приеме и увольнении

Здравствуйте!

У меня есть таблица, содержащая записи о приеме и увольнении сотрудников:

дата | id_Сотрудника | Должность | id_Магазина | Принят или уволен

Вопрос: как посчитать сколько человек трудоустроено в магазине на должностях в определенный день? Я имею в виду: 10.11.2012 в магазине А трудоустроено: 10 продавцов, 2 администратора, 4 кассира.

Прикрепляю таблицу. Буду благодарен любому совету. Спасибо.

1 Solution

Accepted Solutions
Eugeny_Ilyin
Creator II
Creator II

Выкладываю пример:

Table1:

LOAD * INLINE [

    Date, IdPerson, Flag

    01.02.2014, A, 1

    01.04.2014, B, 1

    11.05.2014, C, 1

    30.04.2014, A, -1

    30.04.2014, B, -1

    31.05.2014, C, -1

];

//Определяем диапазон

tmp1:

LOAD min(Date) as 'DateStart', max(Date) as 'DateEnd' Resident Table1;

LET Date_Start    = peek('DateStart',0,'tmp1');

LET Date_End    = peek('DateEnd',0,'tmp1');

DROP Table tmp1;

LET NumOfDays = Date_End - Date_Start + 1;

//Формируем календарь

Date_src:

LOAD

$(Date_Start) + Rowno() -1 as DateId

AUTOGENERATE $(NumOfDays);

Calendar:

LOAD

DateId,

year(DateId) as 'год',

dual('Кв.' & ceil(month(DateId)/3),ceil(month(DateId)/3)) as 'квартал',

dual('Кв.' & ceil(month(DateId)/3) & '-' & year(DateId),year(DateId) & ceil(month(DateId)/3)) as 'квартал-год',

month(DateId) as 'месяц',

ceil(month(DateId)) as 'месяц номер',

dual(month(DateId) & '-' & year(DateId),year(DateId) & num(month(DateId), '00')) as 'месяц-год',

week(DateId) as 'неделя',

weekday(DateId) as 'день недели',

date(DateId) as 'Дата',

day(DateId) as 'день'

RESIDENT Date_src;

Drop Table Date_src;

//Готовим сведения для подсчета по интервалам

table2:

load

    Date as [ДатаПринят],

    IdPerson

Resident Table1

Where Flag=1;

join load

    Date as [ДатаУволен],

    IdPerson

Resident Table1

Where Flag=-1;

DROP Table Table1;

//Формируем сведения по наличию персонала на каждый календарный день

count_tmp:

IntervalMatch (Дата) LOAD [ДатаПринят], [ДатаУволен] RESIDENT table2;

В Вашем случае потребуется избавится от пустых записей по должностям.
Проверить корректность данных (встречаются записи о приеме в одном магазине, а об увольнении в другом, пересечение периодов работы по сотруднику в разных магазинах,...)
Дата приема на работу должна быть по всем позициям. как и дата увольнения. У тех кто работает - ставим текущую дату в качестве даты увольнения.

View solution in original post

4 Replies
Eugeny_Ilyin
Creator II
Creator II

День добрый.
Суббота, под рукой примера нет

Первое, что я бы сделал - избавился бы от признака (принят/уволен) и сформировал бы две колонки, дата приема и дата увольнения.

Затем (для простого случая без подсчета по категориям)

count_tmp:

IntervalMatch (дата(все даты календаря)) LOAD [Дата приема], [Дата увольнения] RESIDENT [таблица с датами];

Далее идет подсчет

LOAD дата ,

    Count(дата) as 'РаботниковВДень',

    Resident count_tmp

    group by дата;

Получаем количество на каждый день календаря.

P.S. Вот такая идея, надеюсь поможет. Инструмент не под рукой

Eugeny_Ilyin
Creator II
Creator II

Выкладываю пример:

Table1:

LOAD * INLINE [

    Date, IdPerson, Flag

    01.02.2014, A, 1

    01.04.2014, B, 1

    11.05.2014, C, 1

    30.04.2014, A, -1

    30.04.2014, B, -1

    31.05.2014, C, -1

];

//Определяем диапазон

tmp1:

LOAD min(Date) as 'DateStart', max(Date) as 'DateEnd' Resident Table1;

LET Date_Start    = peek('DateStart',0,'tmp1');

LET Date_End    = peek('DateEnd',0,'tmp1');

DROP Table tmp1;

LET NumOfDays = Date_End - Date_Start + 1;

//Формируем календарь

Date_src:

LOAD

$(Date_Start) + Rowno() -1 as DateId

AUTOGENERATE $(NumOfDays);

Calendar:

LOAD

DateId,

year(DateId) as 'год',

dual('Кв.' & ceil(month(DateId)/3),ceil(month(DateId)/3)) as 'квартал',

dual('Кв.' & ceil(month(DateId)/3) & '-' & year(DateId),year(DateId) & ceil(month(DateId)/3)) as 'квартал-год',

month(DateId) as 'месяц',

ceil(month(DateId)) as 'месяц номер',

dual(month(DateId) & '-' & year(DateId),year(DateId) & num(month(DateId), '00')) as 'месяц-год',

week(DateId) as 'неделя',

weekday(DateId) as 'день недели',

date(DateId) as 'Дата',

day(DateId) as 'день'

RESIDENT Date_src;

Drop Table Date_src;

//Готовим сведения для подсчета по интервалам

table2:

load

    Date as [ДатаПринят],

    IdPerson

Resident Table1

Where Flag=1;

join load

    Date as [ДатаУволен],

    IdPerson

Resident Table1

Where Flag=-1;

DROP Table Table1;

//Формируем сведения по наличию персонала на каждый календарный день

count_tmp:

IntervalMatch (Дата) LOAD [ДатаПринят], [ДатаУволен] RESIDENT table2;

В Вашем случае потребуется избавится от пустых записей по должностям.
Проверить корректность данных (встречаются записи о приеме в одном магазине, а об увольнении в другом, пересечение периодов работы по сотруднику в разных магазинах,...)
Дата приема на работу должна быть по всем позициям. как и дата увольнения. У тех кто работает - ставим текущую дату в качестве даты увольнения.

vtatarnikov
Creator
Creator
Author

Большое спасибо, Евгений! Похоже, ваш метод подходит. Вы правы, первостепенная задача разобраться с исходными данными, они берутся из регистра сведений 1С, в котором содержатся записи не только о приеме и увольнении, но и о командировках, изменениях разрядов и т.п. Я решил упростить себе задачу и взял только записи о приеме и увольнении, но оказалось не все так просто... Разберусь с этим за выходные и обязательно отпишусь.

vtatarnikov
Creator
Creator
Author

После приведения регистра сведений к таблице вида: Сотрудник - ДатаПриема - ДатаУвольнения; всё решение свелось к джойну IntervalMatch'а к этой самой таблице. Получаем на каждый день календаря записи сотрудников, трудоустроенных в этот день. Далее удобно воспользоваться сводной таблицей с измерениями Дата, Магазин, Должность и подсчетом id сотрудников.

Евгений, еще раз спасибо!

Сотрудники:

LOAD id_Сотрудника,

     ФИО,

     Должность,

     id_Организации,

     AutoNumber(id_Склада, 'Склады') as id_Склада,

     ДатаПриема,

     if(isNull(ДатаУвольнения),Date(Date#(today(), 'DD.MM.YYYY'), 'DD.MM.YYYY'),ДатаУвольнения) as ДатаУвольнения,

     ИзмДолжности,

     Перевод,

     Key

FROM

КадровыеПриказы.qvd

(qvd);

left join (Сотрудники)

IntervalMatch (Дата)

LOAD

  ДатаПриема,

  ДатаУвольнения

RESIDENT Сотрудники

;