Как исправить ошибку «Деление на 0 значения типа Numeric» при открытии документа «Установка цен номенклатуры» в 1С:Розница 2.2?

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

В практике работы с конфигурацией «1С:Розница 2.2» системные администраторы и программисты часто сталкиваются со специфической ошибкой при попытке открыть документ Установка цен номенклатуры. Проблема особенно актуальна после переноса данных из предыдущих версий (например, 1С 7.7) или при использовании механизмов автоматической загрузки через Универсальный обмен данными XML. Ошибка проявляется в виде системного сообщения: «Ошибка SQL: Деление на 0. Деление на 0 значения типа Numeric». При этом документ может быть визуально заполнен верно, а его копия открываться без проблем.

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

Анализ причины возникновения ошибки

Рассмотрим ситуацию глубже. Ошибка возникает не в момент записи данных, а в момент формирования динамического запроса при открытии формы документа. Конфигурация «Розница 2.2» при открытии формы УстановкаЦенНоменклатуры выполняет запрос для расчета текущих действующих цен и процента отклонения новой цены от старой. Проанализируем фрагмент запроса, который вызывает исключение:


|    ВЫРАЗИТЬ(ВЫБОР
|        КОГДА ЦеныНоменклатуры.Цена <> 0
|            ТОГДА 100 * (Товары.Цена - ВЫБОР
|                КОГДА ЕСТЬNULL(ЦеныНоменклатуры.Упаковка, &ПустаяУпаковка) = Товары.Упаковка
|                    ТОГДА ЕСТЬNULL(ЦеныНоменклатуры.Цена, 0)
|                ИНАЧЕ ЕСТЬNULL(ЦеныНоменклатуры.Цена, 0) / ЕСТЬNULL(ЦеныНоменклатуры.Упаковка.Коэффициент, 1) * ЕСТЬNULL(Товары.Упаковка.Коэффициент, 1)
|            КОНЕЦ) / ВЫБОР
|                КОГДА ЕСТЬNULL(ЦеныНоменклатуры.Упаковка, &ПустаяУпаковка) = Товары.Упаковка
|                    ТОГДА ЕСТЬNULL(ЦеныНоменклатуры.Цена, 0)
|                ИНАЧЕ ЕСТЬNULL(ЦеныНоменклатуры.Цена, 0) / ЕСТЬNULL(ЦеныНоменклатуры.Упаковка.Коэффициент, 1) * ЕСТЬNULL(Товары.Упаковка.Коэффициент, 1)
|            КОНЕЦ
|        ИНАЧЕ 0
|    КОНЕЦ КАК ЧИСЛО(19, 2)) КАК Процент

Проанализируем ситуацию: в запросе используется функция ЕСТЬNULL(ЦеныНоменклатуры.Упаковка.Коэффициент, 1). На первый взгляд кажется, что система защищена от деления на ноль. Однако здесь кроется главная техническая ловушка: если ссылка на Упаковку существует (она не NULL), но в самой карточке упаковки в поле Коэффициент записано значение 0, функция ЕСТЬNULL вернет этот самый ноль. SQL-сервер, выполняя операцию деления, мгновенно прерывает выполнение запроса с ошибкой.

Выясним причину, почему в базе появляются нулевые коэффициенты:

  1. Некорректная конвертация из 7.7: В старых версиях 1С структура хранения единиц измерения отличалась. При переносе данных через КМТ (Конвертацию данных) правила могут создать объект Упаковка, но не заполнить обязательный реквизит Коэффициент, который по умолчанию в базе данных инициализируется нулем.
  2. «Битые» ссылки: Если в регистре ЦеныНоменклатуры или в табличной части документа указана ссылка на несуществующую упаковку («Объект не найден»), обращение через точку к реквизиту Коэффициент также может вернуть 0 в контексте выполнения SQL-запроса.
  3. Ошибки ручного ввода: В некоторых случаях пользователи могут создать упаковку вручную и случайно установить коэффициент 0, если в конфигурации не настроена жесткая проверка на заполнение этого поля.

Шаг 1: Диагностика данных через консоль запросов

Прежде чем что-то исправлять, нам необходимо найти «виновника». Проанализируем справочник упаковок и единиц измерения. Для этого воспользуемся внешней обработкой «Консоль запросов» и выполним следующий код:


ВЫБРАТЬ
    Упаковки.Ссылка КАК Ссылка,
    Упаковки.Владелец КАК Владелец,
    Упаковки.Наименование КАК Наименование,
    Упаковки.Коэффициент КАК Коэффициент
ИЗ
    Справочник.УпаковкиНоменклатуры КАК Упаковки
ГДЕ
    Упаковки.Коэффициент <= 0

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

Шаг 2: Массовое исправление коэффициентов

Разберем, как исправить найденные ошибки. Если записей много, воспользуемся стандартной обработкой «Групповое изменение реквизитов» (встроена во все современные конфигурации на базе БСП):

  1. Перейдем в раздел Администрирование — Обслуживание — Корректировка данных — Групповое изменение реквизитов.
  2. В поле «Изменять» выберем Упаковки номенклатуры.
  3. Нажмем «Добавить условие отбора» и укажем: Коэффициент Меньше или равно 0.
  4. В списке реквизитов найдем Коэффициент и установим новое значение 1.
  5. Нажмем кнопку «Изменить реквизиты».

Важно: Убедитесь, что для базовых единиц измерения (которые в Рознице 2.2 выступают в роли упаковок) коэффициент действительно должен быть равен 1. В 99% случаев это именно так.

Шаг 3: Проверка регистра «Цены номенклатуры»

Иногда проблема кроется не только в справочнике, но и в уже записанных движениях регистра сведений. Если в регистре ЦеныНоменклатуры зафиксирована запись, где поле Упаковка пустое, а система ожидает коэффициент, может возникнуть сбой. Рассмотрим запрос для проверки регистра:


ВЫБРАТЬ
    Цены.Номенклатура,
    Цены.ВидЦены,
    Цены.Период,
    Цены.Упаковка
ИЗ
    РегистрСведений.ЦеныНоменклатуры КАК Цены
ГДЕ
    Цены.Упаковка = ЗНАЧЕНИЕ(Справочник.УпаковкиНоменклатуры.ПустаяСсылка)
    И Цены.Цена <> 0

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

Почему копия документа открывается успешно?

Посмотрим на ситуацию, описанную пользователем на форуме: «Если этот же документ скопировать, то форма открывается». Это происходит потому, что при копировании в 1С вызывается процедура ПриКопировании, и форма открывается как для нового (еще не записанного в базу) объекта. В этот момент алгоритмы расчета цен в форме могут использовать упрощенные механизмы или не находить соответствий в регистре сведений для «нового» документа, что позволяет избежать выполнения злополучного участка SQL-кода.

Профилактика проблемы при загрузке из 7.7

Чтобы избежать подобных ошибок в будущем при повторных загрузках данных, рекомендуется внести изменения в правила обмена (КМТ):

Подведем итог: ошибка деления на ноль в Установке цен номенклатуры — это практически всегда следствие некорректных данных в справочнике упаковок (коэффициент = 0). Исправление коэффициентов на единицу в справочнике и регистре цен полностью устраняет проблему и позволяет документу открываться в штатном режиме.

← На главную