4 Replies Latest reply: Nov 25, 2014 9:36 AM by Vladislav Tatarnikov RSS

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

    Vladislav Tatarnikov

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

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

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

       

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

       

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

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

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

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

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

          count_tmp:

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

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

          LOAD дата ,

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

              Resident count_tmp

              group by дата;

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

           

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

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

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

            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;
            
            

             

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

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

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

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

                После приведения регистра сведений к таблице вида: Сотрудник - ДатаПриема - ДатаУвольнения; всё решение свелось к джойну 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 Сотрудники

                ;