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