В процессе разработки отчетов на системе компоновки данных (СКД) для конфигурации 1С:Зарплата и управление персоналом 3.1 часто возникает задача вывода отработанного времени и нормы дней в разрезе должностей. Сложность заключается в том, что сотрудник может перемещаться между должностями внутри одного месяца. В таких случаях стандартные отчеты могут не давать нужной детализации, и нам требуется составить прямой запрос к базе данных. Чтобы получить эти данные без самостоятельной разработки запросов, можно использовать готовый отчет для анализа планового и фактического времени сотрудников.
В этой статье мы подробно разберем, какие источники данных использовать, как правильно соединять таблицы и на какие нюансы стоит обратить внимание при расчете нормы времени для сотрудников, сменивших позицию в середине периода.
Для начала нам необходимо определиться, откуда система берет данные. В ЗУП 3.1 расчетные механизмы сложны, и обращение напрямую к регистрам расчета (таким как ОсновныеНачисления) может быть избыточным из-за необходимости самостоятельно обрабатывать вытеснения (больничные, отпуска и т.д.).
Проанализируем наиболее эффективные источники для запроса в СКД:
Должность.Чтобы корректно распределить время, нам сначала нужно получить «карту» перемещений сотрудника. Разберем, как собрать временную таблицу с периодами работы. Мы будем использовать срезы последних или физические таблицы регистров сведений, чтобы понять, с какого по какое число сотрудник числился на конкретной должности.
Рассмотрим пример логики формирования такой таблицы:
ВЫБРАТЬ
ОсновныеДанные.Сотрудник КАК Сотрудник,
ОсновныеДанные.Должность КАК Должность,
ОсновныеДанные.Период КАК ДатаНачала,
ЕСТЬNULL(ДобавленныеДанные.Период, ДАТАВРЕМЯ(3999, 12, 31)) КАК ДатаОкончания
ИЗ
РегистрСведений.ОсновныеДанныеКонтрактаСотрудника КАК ОсновныеДанные
// Здесь логика получения следующей даты перемещения для ограничения интервала
Важно помнить, что в СКД мы можем ограничить этот выбор периодом отчета, чтобы не обрабатывать всю историю перемещений за несколько лет.
Теперь обратимся к регистру ДанныеОтработанногоВремениСотрудников. Мы проанализируем его структуру: нам важны ресурсы ОтработаноДней и ОтработаноЧасов. Основное преимущество этого регистра в том, что он уже учитывает все кадровые изменения, если документы начисления были сформированы корректно.
Посмотрим на пример запроса для получения факта:
ВЫБРАТЬ
ДанныеВремени.Сотрудник КАК Сотрудник,
ДанныеВремени.Должность КАК Должность,
СУММА(ДанныеВремени.ОтработаноДней) КАК ФактДней,
СУММА(ДанныеВремени.ОтработаноЧасов) КАК ФактЧасов
ИЗ
РегистрНакопления.ДанныеОтработанногоВремениСотрудников КАК ДанныеВремени
ГДЕ
ДанныеВремени.Период МЕЖДУ &НачалоПериода И &КонецПериода
СГРУППИРОВАТЬ ПО
ДанныеВремени.Сотрудник,
ДанныеВремени.Должность
Обратите внимание: если сотрудник перемещался внутри месяца, в этом регистре будет несколько записей с разными значениями в поле Должность, что идеально подходит для нашей задачи.
Это самый сложный этап. Норма времени в ЗУП 3.1 не привязана к должности напрямую в одной таблице с фактом. Нам нужно вычислить её, исходя из графика работы, который действовал для сотрудника в конкретный период.
Выясним причину возможных расхождений: в программе может быть настроено два варианта расчета нормы при перемещении:
Разберем по шагам, как получить составную норму через регистр ДанныеГрафиковРаботыСотрудников. Нам нужно соединить периоды работы на должностях с данными этого регистра по дням.
ВЫБРАТЬ
ПериодыДолжностей.Сотрудник,
ПериодыДолжностей.Должность,
СУММА(ДанныеГрафиков.Значение) КАК НормаДней
ИЗ
ВТПериодыРаботы КАК ПериодыДолжностей
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ДанныеГрафиковРаботыСотрудников КАК ДанныеГрафиков
ПО ПериодыДолжностей.Сотрудник = ДанныеГрафиков.Сотрудник
И ДанныеГрафиков.Дата МЕЖДУ ПериодыДолжностей.ДатаНачала И ПериодыДолжностей.ДатаОкончания
ГДЕ
ДанныеГрафиков.ВидУчетаВремени = ЗНАЧЕНИЕ(Справочник.ВидыИспользованияРабочегоВремени.Явка)
СГРУППИРОВАТЬ ПО
ПериодыДолжностей.Сотрудник,
ПериодыДолжностей.Должность
В данном примере мы используем поле Значение для получения количества дней (обычно это 1 для рабочего дня по графику). Если нужна норма в часах, следует использовать соответствующее поле или ресурс регистра.
После того как мы подготовили временные таблицы для факта и нормы, нам остается выполнить ЛЕВОЕ СОЕДИНЕНИЕ. Основанием (левой таблицей) лучше всего сделать таблицу периодов должностей, чтобы не потерять данные, если по какой-то причине факт еще не начислен или норма в графике не заполнена.
Проанализируем структуру итогового соединения:
Такой подход гарантирует, что если сотрудник перевелся с 15-го числа, норма до 15-го будет отнесена к старой должности, а после 15-го — к новой.
Если ваша задача позволяет использовать внешний набор данных в СКД, мы рекомендуем заглянуть в общий модуль УчетРабочегоВремени. Там существует функция СоздатьВременнуюТаблицуДанныхГрафиков. Она умеет собирать и норму, и факт, учитывая все тонкости конфигурации (индивидуальные графики, изменения графиков, праздничные дни).
Хотя напрямую в запросе СКД вызвать ее нельзя, вы можете:
Это более надежный, хоть и более трудоемкий с точки зрения кодинга способ, так как он использует те же алгоритмы, что и документы начисления зарплаты.
При работе с данными о времени всегда проверяйте следующие моменты:
Данные отработанного времени сотрудников будет пустым. Для получения «прогнозного» факта (до начисления) придется анализировать регистр сведений Данные оперативного учета рабочего времени.Пятидневка в регистре данных графиков.Подводя итог, можно сказать, что решение задачи получения времени «в разрезе должностей при перемещении» требует комбинированного подхода: фиксации периодов работы на каждой должности и последующего наложения этих периодов на данные о времени. Использование специализированных регистров накопления значительно упрощает жизнь разработчику, избавляя от ручного учета вытеснений. При необходимости план-фактного анализа с детализацией по видам времени можно воспользоваться отчетом для план-фактного анализа отработанного времени.