Как устранить огромные (астрономические) суммы при проведении ОПЗС и расчета себестоимости в 1С:УПП и 1С:КА

Программист 1С v8.3 (Обычные формы) Управленческий учет Промышленность, строительство и АПК
← На главную

Каждый специалист, работающий с конфигурациями «1С:Управление производственным предприятием» (УПП) или «1С:Комплексная автоматизация 1.1» на режиме РАУЗ (Расширенная аналитика учета затрат), рано или поздно сталкивается с пугающим явлением. При проведении обычного документа Отчет производства за смену (ОПЗС) или при запуске регламентного документа Расчет себестоимости выпуска (РСВ) система формирует движения по регистрам с «космическими» цифрами — триллионами, биллионами или даже квадриллионами рублей.

Такая ситуация парализует работу базы данных: СУБД (например, MS SQL Server) выдает ошибку переполнения числового поля (Arithmetic overflow error), проведение документов полностью блокируется, а себестоимость продукции становится невозможно рассчитать. Разберем детально физику этого процесса, выясним причины расхождения алгоритмов распределения и рассмотрим пошаговое руководство по устранению этой проблемы.

Суть проблемы: математический аппарат РАУЗ

Для того чтобы понять, откуда берутся триллионы рублей при копеечной себестоимости сырья, обратимся к математике РАУЗ. В отличие от традиционного партионного учета, который рассчитывает себестоимость последовательно по цепочке документов, РАУЗ строит глобальную математическую модель. Все движения запасов и затрат за месяц представляются в виде системы линейных алгебраических уравнений (СЛУ) типа Ax = b.

Эта система уравнений решается в документе Расчет себестоимости методом итераций (чаще всего используется модифицированный метод Зейделя). В штатном режиме, когда исходные данные корректны, система сходится за 5–15 итераций, а погрешность (среднее отклонение решений) стремится к нулю. Однако, если в данных допущена грубая ошибка, система уравнений теряет устойчивость и начинает расходиться.

При расхождении СЛУ на каждой последующей итерации стоимости начинают умножаться на колоссальные коэффициенты (происходит деление на сверхмалые величины или отрицательные остатки). На 50-й итерации (это жестко зашитый лимит в коде 1С) алгоритм аварийно прекращает расчет, оставляя в базе данных те самые астрономические суммы. Лог расчета себестоимости при этом выглядит следующим образом:


Выполненное количество итераций расчета стоимости: 50
Полученное среднее отклонение решений: 0.274704...
Обнаружены отрицательные остатки по регистрам учета затрат!
Расчет себестоимости может быть выполнен некорректно.

Показатель отклонения 0.274704 — это огромная величина (в норме должно быть меньше 0.00001). Это прямой сигнал о том, что математическая модель "сломалась".

Почему огромные цифры появляются сразу при проведении ОПЗС?

Многих пользователей удивляет: почему триллионы появляются в движениях нового документа ОПЗС еще до того, как запущен расчет себестоимости за месяц? Дело в том, что при проведении ОПЗС в режиме РАУЗ система пытается рассчитать предварительную себестоимость списания затрат на выпуск.

Если в прошлых периодах или в текущем месяце по аналитике списываемой номенклатуры уже накопилась «грязь» (например, огромная сумма при нулевом количестве), документ ОПЗС подхватывает эту искаженную среднюю стоимость и умножает её на количество выпуска. В результате мы получаем мгновенную блокировку базы данных из-за переполнения разрядности регистров.

Рассмотрим основные причины, которые приводят к краху математической модели РАУЗ, и способы их локализации.

Причина 1: Отрицательные количественные остатки

Это самая распространенная причина расхождения СЛУ. Если на складе или в незавершенном производстве (НЗП) по конкретному ключу аналитики образовался минус по количеству (например, списали 10 единиц материала, когда на остатке было только 5), РАУЗ пытается рассчитать среднюю стоимость единицы.

Математически деление накопленной стоимости на отрицательное количество переворачивает знаки в системе уравнений, лишая матрицу диагонального преобладания. Метод итераций сходит с ума, лавинообразно увеличивая значения сумм с каждым шагом.

Решение:
Необходимо полностью искоренить количественные минусы. Для этого выполним следующие действия:

  1. Сформируем отчет Ведомость по учету затрат (или Ведомость по учету МПЗ) за проблемный период.
  2. В настройках отчета установим группировку по максимуму: Раздел учета, Склад, Номенклатура, Характеристика, Ключ аналитики.
  3. Добавим отбор по условию: КоличествоКонечныйОстаток < 0.
  4. Проанализируем каждую позицию с отрицательным остатком. Устраним минусы путем исправления хронологии документов, ввода документов оприходования излишков или исправления ошибочно завышенного списания. Важно: на конец месяца количественных минусов в РАУЗ быть не должно!

Причина 2: Отсутствие связи между управленческими и регламентированными подразделениями

В РАУЗ учет ведется одновременно по управленческому и регламентированному учету. Каждое движение привязывается к ключу аналитики, который содержит в себе два поля: Подразделение (управленческая структура) и ПодразделениеОрганизации (регламентированная структура).

Если в справочнике Подразделения для управленческого подразделения не задано сопоставление с соответствующим подразделением организации (или наоборот), система не может корректно связать затраты. Возникает ситуация, когда затраты приходят по одному ключу аналитики, а выпуск отражается по другому. Это разрывает цепочку распределения и ломает расчет.

Решение:
Свяжем подразделения организации с управленческими подразделениями:

  1. Перейдем в справочник Подразделения (управленческий учет).
  2. Откроем карточку каждого подразделения, задействованного в производстве (например, цеха).
  3. В нижней части формы в табличной части сопоставления добавим соответствующее ему подразделение из справочника Подразделения организаций.
  4. Проверим обратную связь. Если в логе расчета себестоимости есть предупреждение: «С подразделением организации "хххх Цех" не связано ни одно подразделение», эту связь нужно восстановить незамедлительно.

Причина 3: Технологические «петли» и некорректный встречный выпуск

Зацикливание (кольцевые зависимости) возникает, когда затраты распределяются по кругу. Рассмотрим классический пример петли:

Если в настройках распределения не заданы жесткие правила оценки встречного выпуска, алгоритм РАУЗ будет бесконечно гонять стоимость по кругу, увеличивая ее до астрономических масштабов на каждой итерации.

Решение:
Для разрыва кольцевых зависимостей в РАУЗ предусмотрен специальный регистр сведений Встречный выпуск продукции (услуг). Проанализируем встречные потоки и настроим правила:

  1. Перейдем в меню: Предприятие — Учет политики — Встречный выпуск продукции (услуг).
  2. Добавим записи для зацикленных позиций номенклатуры или услуг.
  3. Зададим явный способ оценки встречного выпуска — например, выберем По расчетной стоимости или укажем фиксированные Цены номенклатуры. Это позволит алгоритму РАУЗ зафиксировать стоимость на одном из этапов и разорвать бесконечный цикл расчетов.

Причина 4: Использование модифицированных процедур распределения затрат (патч кода)

В некоторых случаях, когда исправить учетные ошибки оперативно не удается, разработчики прибегают к программному «лечению» симптомов. В общем модуле УчетЗатрат можно доработать процедуру ВыполнитьРаспределениеЗатрат.

Суть доработки заключается в принудительном пресечении роста сумм при итерациях. Программа отслеживает появление сверхмалых коэффициентов распределения (например, меньше 0.000001) или отрицательных количеств в процессе итерационных циклов и принудительно обнуляет их, не позволяя стоимости расти до триллионов.

Ниже приведен концептуальный пример кода, который может быть внедрен разработчиком для предотвращения переполнения разрядности при расчете:


// Фрагмент модификации алгоритма распределения в общем модуле УчетЗатрат
Процедура ВыполнитьРаспределениеЗатрат(ТаблицаЗатрат, ПараметрыРасчета) Экспорт
    
    // Перебор итераций расчета стоимости
    Для Итерация = 1 По 50 Цикл
        
        // [Штатный код расчета стоимостей]
        
        // Внедряемый защитный механизм против раздувания сумм
        Для Каждого СтрокаДанных Из ТаблицаЗатрат Цикл
            Если СтрокаДанных.Стоимость > 1000000000000 Тогда // Ограничиваем триллионные суммы
                СтрокаДанных.Стоимость = 0;
                СтрокаДанных.СтоимостьРег = 0;
                СтрокаДанных.ПревышенЛимитСтоимости = Истина;
            КонецЕсли;
            
            // Защита от деления на сверхмалые остатки количества
            Если Абс(СтрокаДанных.Количество) < 0.00001 И СтрокаДанных.Стоимость <> 0 Тогда
                СтрокаДанных.Стоимость = 0;
                СтрокаДанных.СтоимостьРег = 0;
            КонецЕсли;
        КонецЦикла;
        
    КонецЦикла;

КонецПроцедуры

Важное предупреждение: такой патч является «костылем». Он помогает провести документ Расчет себестоимости без падения СУБД в ошибку переполнения, но он маскирует реальные проблемы учета. Истинная себестоимость продукции при использовании таких заглушек все равно будет искажена. Настоятельно рекомендуем решать проблему через зачистку данных, а не через модификацию кода.

Рекомендации по профилактике проблемы

Чтобы избежать внезапного появления триллионных сумм в будущем, рекомендуем придерживаться следующих правил в повседневной работе:

← На главную