Ошибка SQL "Arithmetic overflow" при распроведении документа в 1С:УТ 11: причины и решения

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

В практике администрирования и сопровождения "1С:Управление торговлей 11" (и других конфигураций на базе ERP/КА) мы можем столкнуться с критической ошибкой при попытке отменить проведение документа, пометить его на удаление или перезаписать. Ошибка возникает на уровне СУБД и блокирует любые действия с документом.

Текст ошибки обычно выглядит так:


Microsoft SQL Server Native Client 11.0: Ошибка арифметического переполнения при преобразовании numeric к типу данных numeric.
HRESULT=80040E57, SQLSrvr: SQLSTATE=22003, state=8, Severity=10, native=8115

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

Суть проблемы: почему возникает переполнение?

Давайте проанализируем механику работы системы. Когда мы распроводим документ (или отменяем его проведение), платформа 1С выполняет действия, обратные проведению. Если документ делал записи в регистры накопления, система должна "вычесть" эти движения из текущих рассчитанных итогов или агрегатов.

Ошибка Arithmetic overflow (арифметическое переполнение) означает, что в результате математической операции (например, ТекущийИтог - СуммаДокумента) получилось число, которое не помещается в допустимый диапазон типа данных поля в базе данных SQL. Это может произойти по нескольким причинам:

  1. "Мусор" в итогах или агрегатах. В таблицах прекалькулированных данных (итогов или агрегатов) могут содержаться некорректные, запредельно большие значения, возникшие из-за прошлых сбоев.
  2. Нарушение логики знаков. Если из-за сбоя в базе данных итог стал отрицательным там, где это недопустимо, или наоборот, попытка вычитания может привести к переполнению.
  3. Проблема точности. При сложной арифметике (например, распределении себестоимости) количество знаков после запятой может превысить допустимое для поля numeric(X,Y).

В рассматриваемом случае ошибка указывает на регистр накопления "Выручка и себестоимость продаж".

Решение 1: Управление агрегатами (для оборотных регистров)

Как мы выяснили в ходе обсуждения проблемы, регистр "Выручка и себестоимость продаж" в УТ 11 является оборотным и использует механизм агрегатов. Агрегаты — это специализированные таблицы, которые хранят сводные данные для быстрого построения отчетов. Они не обновляются синхронно с каждой транзакцией так же жестко, как итоги остатков, и иногда могут "протухать" или рассинхронизироваться с реальными движениями.

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

Порядок действий для исправления:

  1. Откройте меню "Все функции" (или "Функции для технического специалиста" в новых версиях платформы).
  2. Найдите пункт "Управление агрегатами" (обычно находится в ветке "Стандартные").
  3. В открывшемся окне найдите проблемный регистр (в нашем случае — ВыручкаИСебестоимостьПродаж).
  4. Посмотрим на режим работы. Если агрегаты включены, нам нужно их временно отключить или перестроить.
  5. Нажмите кнопку "Отключить" или выберите действие "Удалить агрегаты" (интерфейс может отличаться в зависимости от версии платформы, суть — очистить таблицу агрегатов).
  6. После того как агрегаты отключены/очищены, попробуйте снова распровести или пометить на удаление проблемный документ. Поскольку таблица агрегатов пуста, SQL-серверу не нужно пересчитывать в ней данные и ошибки не возникнет.
  7. После успешного удаления документа обязательно вернитесь в форму управления агрегатами и выполните "Перестроить" или включите их обратно, чтобы отчеты в базе формировались быстро.

Решение 2: Пересчет итогов (для регистров остатков)

Если проблема возникает в регистре остатков (например, "Товары на складах"), или если решение с агрегатами не помогло, необходимо обратиться к управлению итогами. Ошибка при пересчете итогов означает, что таблица итогов содержит некорректные данные.

Самый надежный способ "вылечить" таблицу итогов без прямых SQL-запросов — это полное очищение и пересчет средствами 1С.

Алгоритм действий:

  1. Обеспечьте монопольный доступ к базе (никто не должен работать) и сделайте резервную копию.
  2. Перейдите в "Все функции" -> "Управление итогами".
  3. Найдите в списке проблемный регистр.
  4. Снимите галочку "Использовать итоги" (или нажмите кнопку "Отключить").

    Что происходит в этот момент: Платформа посылает команду TRUNCATE TABLE для таблицы итогов в SQL. Это физически удаляет все записи итогов, включая "битые" записи, вызывающие переполнение.

  5. Теперь выполните нужное действие с документом (распроведение/удаление). Так как итогов нет, система работает только с таблицей движений, которая обычно корректна.
  6. Вернитесь в "Управление итогами" и включите итоги обратно. Установите границу рассчитанных итогов на актуальную дату.

    В этот момент система заново просканирует таблицу движений и сформирует корректную таблицу итогов.

Решение 3: Диагностика через Технологический журнал (если ничего не помогает)

Если вы не можете определить конкретный регистр или запись, вызывающую ошибку, нам поможет Технологический журнал (ТЖ). Это позволит увидеть конкретный SQL-запрос и значения параметров, которые вызывают переполнение.

Настроим файл logcfg.xml на сбор событий EXCP и DBMSSQL. Пример минимальной конфигурации:


<log location="C:\Logs\1c" history="4">
    <event>
        <eq property="name" value="DBMSSQL"/>
        <like property="sql" value="%UPDATE%"/> 
    </event>
    <event>
        <eq property="name" value="EXCP"/>
    </event>
    <property name="all"/>
</log>

После воспроизведения ошибки проанализируем логи. Мы ищем событие, где SQLState=22003. В тексте запроса мы увидим, с какой таблицей происходит работа (например, _AccumRgAgg... для агрегатов или _AccumRgT... для итогов). Параметры запроса (p_0, p_1 и т.д.) покажут нам конкретные числа. Если вы увидите там число с огромным количеством знаков или странное значение (например, близкое к 9.99...E+27), это подтвердит гипотезу о переполнении.

Чего делать не рекомендуется

В обсуждениях часто можно встретить советы "удалить запись напрямую в SQL". Рассмотрим, почему это опасно:

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

Резюме

Ошибка арифметического переполнения при распроведении документа чаще всего связана с повреждением данных во вспомогательных таблицах SQL (таблицах итогов или агрегатов), а не в самих движениях документа.

Для исправления в УТ 11:

  1. Определите тип регистра (оборотный или остаточный).
  2. Для оборотных регистров (например, "Выручка и себестоимость продаж") — перестройте агрегаты.
  3. Для регистров остатков — отключите и включите итоги.
← На главную