Рассмотрим распространенную и довольно неприятную ситуацию при работе в программе 1С:Зарплата и управление персоналом, редакция 3.1. При заполнении документа Регистрация переработок по сотруднику со скользящим графиком за один месяц программа может показывать корректную норму (например, за январь — 40 часов, за февраль — 88 часов). Однако, если мы выберем период суммированного учета "январь - февраль", норма внезапно вырастает до неадекватных значений, например, 264 часа. При этом в настройках графика сотрудника для параметра "При подсчете переработок определять норму по:" установлено значение Производ. календарь. Выясним причину такого поведения системы и разберем по шагам доступные способы решения.
Проанализируем техническую сторону вопроса. Если заглянуть в конфигуратор и посмотреть код, формирующий данные для документа, мы обнаружим, что разработчики заложили жесткую логику сбора информации из разных источников в зависимости от месяца.
В типовом механизме присутствуют следующие вызовы процедур:
ДополнитьЗапросВТПоказателейПоРегиструРасчета — собирает данные из регистра расчетов (начислений) для всех месяцев учетного периода, кроме последнего.ДополнитьЗапросВТПоказателейПоУчетуВремени — собирает данные из регистра учета рабочего времени исключительно для последнего месяца учетного периода.Разберем подробнее, к чему это приводит. Основная проблема возникает, когда в предыдущих месяцах у сотрудника были отклонения: больничные, отпуска, неявки. При настройке определения нормы по производственному календарю программа вычитает часы отсутствия, исходя из нормы стандартной пятидневной рабочей недели (строго по 8 часов за каждый день отсутствия). Если у сотрудника скользящий график или вахтовый метод со сменами по 10-12 часов, норма за время болезни уменьшается некорректно. В рамках одного месяца эта разница может не бросаться в глаза, но за квартал или полугодие эти "недовычтенные" часы накапливаются, и итоговая норма сильно искажается.
Важный нюанс: искажения часто тянутся из регистра расчетов за прошлые периоды из-за перерасчетов. Если по сотруднику проводились исправления прошлых периодов, сторнирование больничных или отпусков, в регистре расчетов возникают корректирующие записи. Весь этот "мусор" захватывается типовым запросом 1С при сборе базы за прошлые месяцы и вываливается в итоговую цифру нормы в документе.
Посмотрим на самое простое и рекомендуемое методологическое решение без программирования. Ошибка часто кроется в выбранной настройке определения нормы.
Производ. календарь на Данным этого графика (либо создайте и укажите отдельный эталонный график-норму).В этом случае при отсутствии сотрудника (отпуск, больничный) норма будет уменьшаться ровно на то количество часов, которое он должен был отработать по своему графику, а не на абстрактные 8 часов. Это предотвращает "разъезжание" нормы за многомесячный учетный период. Также убедитесь, что в графике установлен флаг "Суммированный учет рабочего времени" и корректно отмечены праздничные дни.
Если методологическое изменение настроек по каким-то причинам невозможно, программисты прибегают к корректировке типового кода с помощью механизма расширений (patch).
Суть доработки заключается в том, чтобы перехватить вызов процедуры ДополнитьЗапросВТПоказателейПоРегиструРасчета и заставить систему собирать данные за весь учетный период только из одного надежного источника (например, по данным регистра учета рабочего времени). Это делает алгоритм однородным, исключает влияние перерасчетов из регистра расчетов и устраняет задвоение часов.
Рассмотрим вариант решения, предложенный на форуме. Автор решил обойти сложный типовой запрос 1С, состоящий из тысяч строк. Идея заключается в том, чтобы разбить большой учетный период на отдельные месяцы, получить данные стандартными функциями для каждого месяца в отдельности (поскольку для одного месяца расчет работает корректно), а затем сложить результаты.
Посмотрим на пример реализации в виде функции:
Функция ПоказателиСуммированногоУчетаСотрудниковПоМесяцам(МассивСотрудников, Объект)
Таб = Новый ТаблицаЗначений;
Таб.Колонки.Добавить("НормаЧасов", Новый ОписаниеТипов("Число"));
Таб.Колонки.Добавить("ОтработаноЧасов", Новый ОписаниеТипов("Число"));
Таб.Колонки.Добавить("ОтработаноЧасовВПраздники", Новый ОписаниеТипов("Число"));
Таб.Колонки.Добавить("Переработки", Новый ОписаниеТипов("Число"));
Таб.Колонки.Добавить("Сотрудник", Новый ОписаниеТипов("СправочникСсылка.Сотрудники"));
ДатаНачало = НачалоМесяца(Объект.ПериодСуммированногоУчетаНачало);
ДатаКонец = КонецМесяца(Объект.ПериодСуммированногоУчетаОкончание);
Для ч = 0 По МассивСотрудников.Количество() - 1 Цикл
датаОтчет = ДатаНачало;
МассивСотрудников2 = Новый Массив;
МассивСотрудников2.Добавить(МассивСотрудников[ч]);
Пока КонецДня(датаОтчет) <= КонецДня(ДатаКонец) Цикл
ТаблицаСотрудников = РасчетЗарплатыРасширенный.ПоказателиСуммированногоУчетаСотрудниковЗаПериод(
МассивСотрудников2,
НачалоМесяца(датаОтчет),
КонецМесяца(датаОтчет));
Для каждого СтрокаТЗ Из ТаблицаСотрудников Цикл
ЗаполнитьЗначенияСвойств(Таб.Добавить(), СтрокаТЗ);
КонецЦикла;
датаОтчет = КонецМесяца(ДобавитьМесяц(датаОтчет, 1));
КонецЦикла;
КонецЦикла;
Таб.Свернуть("Сотрудник","НормаЧасов, ОтработаноЧасов, ОтработаноЧасовВПраздники, Переработки");
ТаблицаСотрудников.Очистить();
ТаблицаСотрудников = Таб.Скопировать();
Возврат ТаблицаСотрудников;
КонецФункции
Данный код в цикле обходит каждый месяц заданного периода, вызывает типовую функцию РасчетЗарплатыРасширенный.ПоказателиСуммированногоУчетаСотрудниковЗаПериод, собирает результаты во временную таблицу значений и в конце применяет метод Свернуть для получения итоговых сумм по сотруднику.
Осторожно, методологический риск! При использовании такого подхода следует быть очень внимательными. С точки зрения Трудового кодекса РФ, при суммированном учете рабочего времени переработка вычисляется за учетный период целиком (квартал, полугодие, год), а не как арифметическая сумма переработок за каждый отдельный месяц. В одном месяце у сотрудника может быть недоработка, в другом — переработка. В рамках учетного периода они должны взаимозачитываться. Если вы просто просуммируете положительные переработки по месяцам, вы рискуете необоснованно завысить оплату сверхурочных там, где по итогам всего периода их не возникло. Используйте данный программный метод только если вы четко понимаете логику работы вашей компании с переработками и уверены, что это не нарушит законодательство.