Обновление учетных систем — это всегда риск, но иногда ошибки разработчика оказываются настолько критичными, что парализуют работу целого отдела. В этой статье мы подробно разберем ситуацию, возникшую с обновлением конфигурации "Управление производственным предприятием" (УПП) версии 1.3.244.1 от 21.03.2025. Пользователи столкнулись с тем, что расчет среднего заработка для отпусков и командировок стал выдавать совершенно некорректные цифры.
Разберемся, почему вместо положенных 29.3 дней программа берет в расчет кратно большие значения, как это связано с дополнительными начислениями и какие пути решения существуют на данный момент.
Первое, с чем сталкивается расчетчик после обновления, — это резкое занижение суммы отпускных. При детальном анализе печатной формы расчета среднего заработка или вкладки расчета в документе НачислениеОтпускаРаботникамОрганизаций выявляются следующие аномалии:
В результате, формула расчета среднего заработка искажается. Вместо деления базы на 29.3, база делится на (29.3 * N), где N — количество видов дополнительных расчетов. Это приводит к существенному занижению выплат сотрудникам.
Чтобы понять, как исправить ошибку, давайте заглянем "под капот" механизма расчета. Проблема кроется в запросе, который формирует данные для расчета среднего заработка. Этот запрос находится в Общем модуле (обычно это модули, связанные с проведением расчетов, например, ПроведениеРасчетов или специализированный модуль расчета среднего).
Суть ошибки заключается в некорректном соединении таблиц (JOIN) в запросе SQL/1C.
Представим, что у нас есть две виртуальные таблицы:
В корректном запросе данные об отработанном времени должны присоединяться к итогам месяца или группироваться таким образом, чтобы дни учитывались один раз. В проблемном релизе разработчики допустили ошибку в условиях соединения, что привело к так называемому "Декартову произведению" (Cartesian product) для поля дней.
Рассмотрим упрощенный пример того, как выглядит ошибочная логика запроса:
// Псевдокод ошибочного запроса
ВЫБРАТЬ
Начисления.Сотрудник,
Начисления.ПериодРегистрации,
СУММА(Начисления.Результат) КАК СуммаЗаработка,
СУММА(ОтработанноеВремя.ОтработаноДнейКалендарных) КАК УчтеноДней // ОШИБКА ЗДЕСЬ
ИЗ
РегистрРасчета.ОсновныеНачисления КАК ОтработанноеВремя
ЛЕВОЕ СОЕДИНЕНИЕ РегистрРасчета.ДополнительныеНачисления КАК Начисления
ПО ОтработанноеВремя.Сотрудник = Начисления.Сотрудник
И ОтработанноеВремя.ПериодРегистрации = Начисления.ПериодРегистрации
СГРУППИРОВАТЬ ПО
Начисления.Сотрудник,
Начисления.ПериодРегистрации
В данном примере, если в таблице Начисления есть 3 записи (Оклад, Премия, Доплата), то строка из таблицы ОтработанноеВремя присоединится к каждой из них. При последующей группировке и суммировании поле ОтработаноДнейКалендарных (29.3) сложится 3 раза, и мы получим 87.9 дней.
Важно: Это схематичное объяснение. В реальной конфигурации запрос намного сложнее и включает в себя временные таблицы и пакетные запросы, но принцип ошибки — дублирование данных о времени при множественных начислениях — остается тем же.
На данный момент существует три основных пути выхода из сложившейся ситуации. Рассмотрим их от наиболее надежного к временному.
Как показывает практика обсуждения на форуме, самым быстрым и надежным способом восстановить работоспособность расчета зарплаты является возврат к предыдущей версии конфигурации — 1.3.243.
Преимущества:
Недостатки:
Алгоритм действий:
Если откат невозможен (например, введен большой объем данных, который сложно перенести), программист 1С может внести точечные правки в модуль расчета.
Внимание! Снимать конфигурацию с поддержки рекомендуется только при наличии достаточной квалификации.
Необходимо найти общий модуль, отвечающий за сбор данных для среднего (обычно это модуль объекта документа или общие модули с названиями вроде ПроведениеРасчетов, РасчетСреднегоЗаработка).
Задача сводится к следующему:
СУММА(Дни) необходимо использовать конструкцию, выбирающую МАКСИМУМ для группировки, либо переписать запрос так, чтобы дни выбирались отдельным подзапросом и присоединялись к итоговой таблице уже после агрегации сумм.Пример правильной логики (псевдокод):
// Сначала собираем суммы
ВЫБРАТЬ ... СУММА(Результат) ... ПОМЕСТИТЬ ВТ_Суммы ...;
// Отдельно собираем время (только из основных начислений)
ВЫБРАТЬ ... СУММА(ОтработаноДней) ... ПОМЕСТИТЬ ВТ_Время ...;
// Соединяем итоги
ВЫБРАТЬ
ВТ_Суммы.Сумма,
ВТ_Время.Дни
ИЗ ВТ_Суммы ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Время ...
Если у вас небольшое количество сотрудников, уходящих в отпуск или увольняющихся, можно скорректировать расчет вручную прямо в документе.
Порядок действий:
Начисление отпуска сотрудникам организаций.Этот метод крайне трудоемок и чреват человеческими ошибками, поэтому подходит только как экстренная мера для 1-2 расчетов.
Ситуация, описанная в теме, ярко демонстрирует важность предварительного тестирования обновлений. Даже если вы используете типовую конфигурацию от 1С и платите за поддержку, это не гарантирует отсутствия критических ошибок.
Рекомендуемый процесс обновления для критически важных участков (Зарплата, НДС):
Помните, что ответственность за правильность начислений перед сотрудниками и налоговой несет организация, а не поставщик программного обеспечения. Поэтому контроль данных "на выходе" из программы остается обязательной процедурой для расчетного отдела.