Как исправить ошибку арифметического переполнения при расчете себестоимости в 1С:ERP?

Программист 1С v8.3 (Управляемые формы) 1С:ERP Управление предприятием Управленческий учет
← На главную

При выполнении процедуры закрытия месяца в конфигурации 1С:ERP Управление предприятием пользователи часто сталкиваются с критическим сбоем. Ошибка сопровождается сообщением: Microsoft SQL Server Native Client 11.0: Ошибка арифметического переполнения при преобразовании numeric к типу данных numeric. Это происходит на этапе расчета себестоимости и корректировки стоимости запасов. Ситуация осложняется тем, что расчет прерывается полностью, не позволяя завершить финансовый период.

В этой статье мы подробно разберем, почему возникает эта ошибка (SQL Error 8115), как локализовать проблемные данные и какие настройки системы помогут обойти этот сбой.

Природа возникновения ошибки переполнения numeric

Разберем ситуацию с технической точки зрения. В базе данных SQL Server для хранения суммовых показателей и количеств используются поля типа numeric с определенной точностью и разрядностью (например, numeric(15, 2) или numeric(32, 10)). Ошибка переполнения означает, что результат математической операции в запросе превысил максимально допустимое число, которое может быть записано в это поле.

Проанализируем основные причины, приводящие к таким гигантским числам в процессе расчета:

  1. Математические петли в себестоимости: Это самая частая причина в 1С:ERP. Если в цепочке движения товаров возникает «зацикливание» (например, Товар А потребляется для производства Товара Б, а Товар Б используется для производства Товара А), алгоритм решения систем линейных уравнений (СЛУ) может начать бесконечно увеличивать стоимость на каждой итерации. Число растет в геометрической прогрессии, пока не выходит за пределы разрядности SQL.
  2. Деление на сверхмалые величины: Если в документах указано ничтожно малое количество (например, 0,000001 из-за ошибок округления или некорректного импорта), а сумма при этом значительна, вычисление цены за единицу (Сумма / Количество) порождает число с огромным количеством знаков в целой части.
  3. Зависшие остатки с копейками: Наличие в регистре Себестоимость товаров записей, где количество равно нулю, а сумма отлична от нуля, создает помехи для алгоритмов распределения.

Способ 1. Переключение механизма решения СЛУ

Рассмотрим наиболее эффективный быстрый способ, упомянутый в практике решения подобных проблем. В 1С:ERP существует два способа решения систем линейных уравнений для распределения затрат: платформенный и прикладной.

Платформенный механизм работает на уровне ядра 1С, он быстрее, но крайне чувствителен к сингулярным матрицам и некорректным данным. При возникновении «петли» он часто выдает ошибку переполнения.

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

Для решения проблемы выполним следующие действия:

  1. Перейдем в раздел НСИ и администрирование — Настройка НСИ и разделов — Финансовый результат и контроллинг.
  2. В подразделе Учет товаров найдем настройки закрытия месяца.
  3. Попробуем временно отключить использование платформенного механизма решения СЛУ (если эта опция доступна в вашей версии конфигурации и включена).
  4. В некоторых версиях ERP управление этим механизмом находится в скрытых константах или включается автоматически. Если явного переключателя нет, проанализируем настройки в рабочем месте Закрытие месяца.

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

Способ 2. Поиск аномальных данных в регистрах

Если смена механизма СЛУ не помогла или недоступна, нам необходимо найти «виновника» — конкретную запись в базе данных, вызывающую переполнение. Проанализируем регистры накопления. Для этого воспользуемся консолью запросов.

Напишем запрос к регистру СебестоимостьТоваров, чтобы найти строки с аномально большими суммами. Рассмотрим пример кода запроса:


ВЫБРАТЬ
    Себестоимость.Регистратор,
    Себестоимость.Номенклатура,
    Себестоимость.Стоимость КАК Сумма,
    Себестоимость.Количество КАК Кол
ИЗ
    РегистрНакопления.СебестоимостьТоваров КАК Себестоимость
ГДЕ
    Себестоимость.Стоимость > 1000000000000 // Ищем суммы больше триллиона
    ИЛИ Себестоимость.Стоимость < -1000000000000

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

Способ 3. Проверка расширений конфигурации

В сообщении об ошибке часто мелькают ссылки на общие модули, такие как РасчетСебестоимостиПрикладныеАлгоритмы. Однако, если в базе установлены расширения, они могут подменять типовые запросы. Рассмотрим, как проверить влияние расширений:

  1. Отключим поочередно расширения, влияющие на расчет себестоимости.
  2. Если ошибка исчезла, проанализируем код в расширении. Обратим внимание на создание временных таблиц.
  3. В SQL Server типы данных для итогов во временных таблицах определяются автоматически. При умножении или сложении больших чисел SQL может назначить тип, не вмещающий результат.

Для исправления кода в расширении рекомендуется использовать функцию ВЫРАЗИТЬ. Посмотрим на пример:


// Вместо прямого умножения:
// Сумма = Таблица.Цена * Таблица.Количество

// Используйте явное приведение типа:
ВЫРАЗИТЬ(Таблица.Цена * Таблица.Количество КАК ЧИСЛО(15, 2))

Это принудительно ограничит разрядность вычисления и предотвратит попытку SQL создать слишком «широкое» поле в памяти, вызывающее HRESULT=80040E57.

Способ 4. Обновление драйверов и настроек SQL Server

Иногда корень проблемы кроется в связке платформы 1С и СУБД. Ошибка SQLSTATE=22003 напрямую указывает на арифметическое переполнение в драйвере. Проанализируем техническую среду:

  1. Проверим версию драйвера на сервере 1С. Если используется устаревший SQL Server Native Client 11.0, попробуем обновить его на актуальный Microsoft OLE DB Driver for SQL Server.
  2. Проверим настройку ARITHABORT на уровне SQL-сервера. Если этот параметр установлен в значение ON, SQL-сервер немедленно прерывает выполнение при любом переполнении. В некоторых случаях (хотя это и не рекомендуется как постоянное решение) изменение этой настройки позволяет 1С обработать промежуточные данные самостоятельно.

Резюме и рекомендации

Подведем итог. Ошибка переполнения numeric при расчете себестоимости — это почти всегда сигнал о логической ошибке в данных текущего месяца (зацикливание или некорректное количество), а не о баге самой платформы.

Для исправления ситуации мы рекомендуем придерживаться следующего алгоритма:

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

← На главную