При выполнении процедуры закрытия месяца в конфигурации 1С:ERP Управление предприятием пользователи часто сталкиваются с критическим сбоем. Ошибка сопровождается сообщением: Microsoft SQL Server Native Client 11.0: Ошибка арифметического переполнения при преобразовании numeric к типу данных numeric. Это происходит на этапе расчета себестоимости и корректировки стоимости запасов. Ситуация осложняется тем, что расчет прерывается полностью, не позволяя завершить финансовый период.
В этой статье мы подробно разберем, почему возникает эта ошибка (SQL Error 8115), как локализовать проблемные данные и какие настройки системы помогут обойти этот сбой.
Разберем ситуацию с технической точки зрения. В базе данных SQL Server для хранения суммовых показателей и количеств используются поля типа numeric с определенной точностью и разрядностью (например, numeric(15, 2) или numeric(32, 10)). Ошибка переполнения означает, что результат математической операции в запросе превысил максимально допустимое число, которое может быть записано в это поле.
Проанализируем основные причины, приводящие к таким гигантским числам в процессе расчета:
Себестоимость товаров записей, где количество равно нулю, а сумма отлична от нуля, создает помехи для алгоритмов распределения.Рассмотрим наиболее эффективный быстрый способ, упомянутый в практике решения подобных проблем. В 1С:ERP существует два способа решения систем линейных уравнений для распределения затрат: платформенный и прикладной.
Платформенный механизм работает на уровне ядра 1С, он быстрее, но крайне чувствителен к сингулярным матрицам и некорректным данным. При возникновении «петли» он часто выдает ошибку переполнения.
Прикладной механизм выполняется на языке запросов и коде конфигурации. Он медленнее, но обладает встроенными механизмами «отсечения» аномальных значений и более терпим к ошибкам в данных.
Для решения проблемы выполним следующие действия:
После смены механизма запустим расчет заново. Если расчет пройдет до конца, система может вывести предупреждения о конкретных узлах зацикливания, которые теперь можно исправить в первичных документах.
Если смена механизма СЛУ не помогла или недоступна, нам необходимо найти «виновника» — конкретную запись в базе данных, вызывающую переполнение. Проанализируем регистры накопления. Для этого воспользуемся консолью запросов.
Напишем запрос к регистру СебестоимостьТоваров, чтобы найти строки с аномально большими суммами. Рассмотрим пример кода запроса:
ВЫБРАТЬ
Себестоимость.Регистратор,
Себестоимость.Номенклатура,
Себестоимость.Стоимость КАК Сумма,
Себестоимость.Количество КАК Кол
ИЗ
РегистрНакопления.СебестоимостьТоваров КАК Себестоимость
ГДЕ
Себестоимость.Стоимость > 1000000000000 // Ищем суммы больше триллиона
ИЛИ Себестоимость.Стоимость < -1000000000000
Выясним причину появления таких записей. Чаще всего они порождаются документами Перемещение товаров, Сборка товаров или Распределение расходов. Если вы нашли такие документы, проверьте в них соответствие единиц измерения и корректность заполнения количества.
В сообщении об ошибке часто мелькают ссылки на общие модули, такие как РасчетСебестоимостиПрикладныеАлгоритмы. Однако, если в базе установлены расширения, они могут подменять типовые запросы. Рассмотрим, как проверить влияние расширений:
Для исправления кода в расширении рекомендуется использовать функцию ВЫРАЗИТЬ. Посмотрим на пример:
// Вместо прямого умножения:
// Сумма = Таблица.Цена * Таблица.Количество
// Используйте явное приведение типа:
ВЫРАЗИТЬ(Таблица.Цена * Таблица.Количество КАК ЧИСЛО(15, 2))
Это принудительно ограничит разрядность вычисления и предотвратит попытку SQL создать слишком «широкое» поле в памяти, вызывающее HRESULT=80040E57.
Иногда корень проблемы кроется в связке платформы 1С и СУБД. Ошибка SQLSTATE=22003 напрямую указывает на арифметическое переполнение в драйвере. Проанализируем техническую среду:
SQL Server Native Client 11.0, попробуем обновить его на актуальный Microsoft OLE DB Driver for SQL Server.ARITHABORT на уровне SQL-сервера. Если этот параметр установлен в значение ON, SQL-сервер немедленно прерывает выполнение при любом переполнении. В некоторых случаях (хотя это и не рекомендуется как постоянное решение) изменение этой настройки позволяет 1С обработать промежуточные данные самостоятельно.Подведем итог. Ошибка переполнения numeric при расчете себестоимости — это почти всегда сигнал о логической ошибке в данных текущего месяца (зацикливание или некорректное количество), а не о баге самой платформы.
Для исправления ситуации мы рекомендуем придерживаться следующего алгоритма:
Себестоимость товаров на наличие «пустых» остатков с огромными суммами и очистить их корректировкой записей регистров.ВЫРАЗИТЬ(... КАК ЧИСЛО) в расчетах внутри запросов.Помните, что расчет себестоимости — это сложный математический процесс. Тщательная проверка первичных документов на входе — лучший способ избежать подобных ошибок в конце месяца.