При закрытии месяца и расчете себестоимости в 1С:ERP (а также в Комплексной Автоматизации) специалисты часто сталкиваются со сложными математическими ошибками. Одной из таких ситуаций является невозможность корректно рассчитать себестоимость при наличии "петель" (встречного выпуска) или появление странных остатков (суммы без количества). Часто в попытках решения проблемы мы пытаемся изменить настройки расчета, в частности — отключить использование платформенного механизма решения Систем Линейных Уравнений (СЛУ). Однако практика показывает, что эта настройка не работает. Для глубокой диагностики есть детальный анализ структуры себестоимости с разузлованием.
В этой статье мы подробно разберем, почему так происходит, куда исчез старый алгоритм расчета и как бороться с ошибками распределения затрат на современных версиях платформы.
Многие из нас привыкли, что в ранних версиях конфигураций существовала возможность выбора метода решения систем линейных уравнений: средствами платформы (native) или средствами встроенного языка 1С (матричный метод, метод Гаусса и т.д., написанный кодом). Это было полезно для отладки или обхода ошибок платформы.
В параметрах расчета себестоимости в 1С:ERP до сих пор можно найти признак (константу или параметр вызова), отвечающий за использование платформенного механизма. Логично предположить: если установить этот параметр в Ложь, система должна переключиться на "ручной" алгоритм расчета.
Однако при анализе поведения системы выясняется следующее: даже при принудительном отключении этого параметра, расчет все равно выполняется через платформу. Давайте разберемся, почему это происходит, заглянув "под капот" конфигурации.
Если мы попытаемся найти место в коде, где происходит выбор алгоритма, нас ждет сюрприз. Проанализируем цепочку вызовов в модуле расчета себестоимости. Обычно процесс выглядит так:
РассчитатьВсе.РасчетСебестоимостиРешениеСЛУ.РасчетСебестоимости_МатериальныеИТрудозатраты.При детальном изучении кода (особенно в версиях ERP 2.5.7 и выше) мы обнаружим следующую картину:
// Примерная схема вызова в модуле РасчетСебестоимостиРешениеСЛУ
Процедура РешитьСЛУПлатформой_СебестоимостьПредприятия(ПараметрыРасчета)
// ... подготовка данных ...
// Безусловный вызов платформенного компонента
РасчетСистемЛинейныхУравнений = ПолучитьКомпонентуДляРешенияСЛУ(ПараметрыРасчета);
// В этом месте отсутствует проверка:
// Если ПараметрыРасчета.ИспользоватьПлатформу Тогда ... Иначе ... КонецЕсли;
// ... выполнение расчета ...
КонецПроцедуры
Вывод неутешителен: в актуальных релизах ERP (редакция 2.5) разработчики 1С провели рефакторинг и полностью удалили код, отвечающий за решение СЛУ средствами встроенного языка ("неплатформенный" метод). Старый алгоритм был признан устаревшим и неэффективным по производительности для больших объемов данных.
Параметр "Использовать платформенное решение" остался в метаданных как рудимент (технический долг), но фактически он нигде не используется для ветвления алгоритма. Поэтому попытки найти скрытый переключатель или поставить точку останова в ветке Иначе обречены на неудачу — этой ветки просто нет.
Почему вообще возникает желание отключить платформенное решение? Чаще всего это связано с ошибками, возникающими после обновления технологической платформы.
Особое внимание стоит уделить поведению системы на платформе версии 8.3.27. Сообщество и техподдержка фиксируют, что на этой версии платформы был изменен математический движок работы с числами с плавающей запятой и решения матриц. Это привело к проблемам в расчете себестоимости при наличии зацикливания затрат.
При выполнении регламентных операций по закрытию месяца — для этого есть исправление ошибок учета для закрытия месяца — могут выдаваться сообщения об ошибке следующего вида:
"Обнаружены ненулевые остатки по суммам при нулевом остатке по количеству в регистре себестоимости...", что часто сопровождает отрицательные остатки партий в регистре себестоимости (поможет анализ причин отрицательных остатков в регистрах).
Типичный сценарий возникновения (в котором также может встретиться ошибка поступления из товаров в пути):
Такая ситуация создает "петлю" (математический цикл) в системе линейных уравнений. Платформенный решатель в версии 8.3.27 в некоторых случаях не может достичь сходимости решения (не может "утрясти" копейки до нуля) или некорректно обрабатывает значения, близкие к машинному нулю. В результате возникают "фантомные" суммовые остатки.
Поскольку мы выяснили, что вернуть "старый" метод расчета кодом невозможно (его просто нет), нам остаются административные и методические решения.
Для некоторых релизов ERP (например, 2.5.22.77) фирма 1С выпускает патчи (исправления), связанные с этой проблемой. Один из известных патчей — EF_00_00737225.
Однако стоит учитывать отзывы коллег: данный патч зачастую не устраняет проблему полностью, так как он пытается корректировать параметры вызова, но не меняет само ядро математического движка платформы.
На текущий момент самым надежным решением, если вы столкнулись с ошибкой расчета СЛУ на 8.3.27, является откат платформы на более стабильные ветки, например, 8.3.25 или 8.3.26. На этих версиях механизм решения СЛУ работает по старым алгоритмам ядра и корректно обрабатывает зацикливания себестоимости.
Если смена платформы невозможна, необходимо выполнить сравнение остатков и стоимости товаров по оперативному и бухгалтерскому учёту — здесь поможет поиск расхождений оперативного и бухгалтерского учета — и устранить причину сложности уравнений — зацикливание затрат.
Попробуем выполнить следующие действия:
СебестоимостьТоваров, чтобы найти конкретную номенклатуру, которая списывается сама на себя.Подводя итог нашему расследованию: