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