Разберем распространенную прикладную задачу: сотруднику назначена ежемесячная надбавка (бонус) с фиксированным максимумом, например 1840 рублей. При полной выработке нормы начисляется 1840 рублей, при недоработке сумма должна уменьшаться пропорционально фактически отработанному времени, а при переработке (работе сверх нормы графика) итоговая сумма не должна превышать установленный лимит.
На первый взгляд задача кажется простой, однако при реализации в программе «1С:Зарплата и управление персоналом» часто возникают подводные камни, связанные с дроблением расчетных записей при изменении оклада или тарифной ставки в течение месяца. Проанализируем, почему типовая формула дает сбой, и рассмотрим практические способы настройки корректного расчета.
Для реализации логики расчета пропорционально отработанным часам с ограничением максимума в пользовательских формулах обычно применяют тернарный оператор ?() или математические функции ограничения. Рассмотрим классический вариант формулы:
?(ВремяВЧасах > НормаВремениВЧасах, РазмерБонуса, РазмерБонуса / НормаВремениВЧасах * ВремяВЧасах)
В конфигурациях на платформе «1С:Предприятие 8.3» аналогичное выражение можно записать более компактно через встроенную функцию минимума:
РазмерБонуса * Мин(1, ВремяВЧасах / НормаЧасов)
Такая формула превосходно отрабатывает, если у сотрудника на протяжении расчетного месяца не менялись кадровые условия и условия оплаты труда. Однако выясним причину, по которой расчет нарушается при кадровых перемещениях:
ВремяВЧасах и НормаВремениВЧасах (или НормаЧасов) рассчитываются исключительно для текущего интервала действия строки, а не накопительным итогом за месяц.?(...) или функция Мин() вычисляется отдельно по каждой подстроке, лимит не сработает в целом за месяц. Например, если в первой половине месяца норма составляла 80 часов, а сотрудник отработал 85, строка первой половины ограничится суммой 1840 рублей, а за вторую половину месяца начислится дополнительная сумма, что приведет к существенному превышению итогового лимита.Рассмотрим рабочие варианты решения данной задачи, исключающие некорректные перерасчеты.
Наиболее надежный расчетный механизм в рамках типового функционала 1С — вынесение контроля итоговой суммы на уровень зависимого начисления, рассчитываемого без привязки к табелю рабочего времени.
Разберем по шагам порядок настройки:
РазмерБонуса * ВремяВЧасах / НормаЧасов. На закладке «Учет времени» укажем использование рабочего времени по графику сотрудника (включая явку и при необходимости сверхурочные/праздничные часы).Мин(РазмерБонуса, РасчетнаяБаза) или через условие ?(РасчетнаяБаза > РазмерБонуса, РазмерБонуса, РасчетнаяБаза).Поскольку второе начисление рассчитывается за весь месяц одной строкой, расчетная база автоматически соберет все суммы из строк промежуточного начисления независимо от того, на сколько частей разбился период действия из-за смены тарифов. Ограничение применится строго к общей сумме начисления за расчетный месяц.
Обратите внимание: Чтобы избежать дублирования начисленных сумм к выплате, первое (промежуточное) начисление можно компенсировать через служебное сторнирующее удержание либо настроить второе начисление как корректировку (удержание превышения): Макс(0, РасчетнаяБаза - РазмерБонуса).
Если специфика учета не допускает создание вспомогательных начислений, проанализируем вариант с централизованным вводом итоговых данных за месяц.
Разберем алгоритм настройки:
ФактическиОтработаноБонусныхЧасов с назначением «Для сотрудника», порядок ввода — «Вводится единовременно документом ввода данных для расчета зарплаты».НормаЧасовЗаМесяц.РазмерБонуса * Мин(1, ФактическиОтработаноБонусныхЧасов / НормаЧасовЗаМесяц).При таком подходе начисление рассчитывается строго одной строкой на основании документа «Данные для расчета зарплаты», полностью игнорируя промежуточные кадровые срезы внутри расчетного периода.
В ситуациях, когда требуется полностью автоматический расчет без ручного ввода показателей и без создания цепочек начислений, используют доработку логики расчета.
Посмотрим на практическую реализацию: в процедуре расчета зарплаты расширением конфигурации перехватывается этап заполнения табличной части документа НачислениеЗарплатыИВзносов. Программный алгоритм выполняет свертку строк начисления по сотруднику, определяет суммарные отработанные часы за месяц и корректирует итоговый результат начисления, исключая превышение заданного предела РазмерБонуса.