Как исправить ошибку «Операции сравнения на больше-меньше допустимы только для значений совпадающих примитивных типов» при проведении Поступления безналичных ДС в 1С:КА 2.4 / ERP

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

При проведении документов оплаты от клиентов (например, Поступление безналичных ДС или Приходный кассовый ордер) в программах «1С:Комплексная автоматизация 2.4» или «1С:ERP Управление предприятием» пользователи часто сталкиваются с неожиданным сбоем. Система выдает системное сообщение об ошибке в обработчике проведения, ссылаясь на невозможность выполнения метода Записать() для движений документа.

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

Выясняем техническую причину сбоя

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

Проанализируем проблемный участок кода, на котором спотыкается платформа:


// Область РасчетФактическойЗадолженности в модуле ОперативныеВзаиморасчетыСервер
Если СтрокаОплаты.ПорядокОперации < СтрокаОтгрузкиПоставки.ПорядокОперации Тогда
    // Алгоритм распределения авансов
КонецЕсли;

Причиной падения системы с ошибкой «Операции сравнения на больше-меньше допустимы только для значений совпадающих примитивных типов» является то, что в одной из сравниваемых строк (чаще всего в таблице отгрузок) реквизит ПорядокОперации имеет значение NULL (или Неопределено). Платформа 1С:Предприятие не умеет сравнивать строковый тип данных с системным типом NULL на больше/меньше, что и вызывает прерывание транзакции проведения.

Зачем нужен реквизит «ПорядокОперации»?

В рамках новой архитектуры взаиморасчетов, представленной в ERP 2.4 и КА 2.4, распределение платежей и отгрузок происходит автоматически по методу FIFO в режиме реального времени при проведении документов. Чтобы программа знала точную хронологическую последовательность операций, используется служебный строковый реквизит ПорядокОперации, который пишется в регистры накопления группы «Расчеты с клиентами» и «Расчеты с поставщиками» (в частности, в регистр РасчетыСКлиентамиПоСрокам).

Эта служебная строка формируется по шаблону и обычно содержит информацию в следующем формате:

[Дата в формате ГГГГММДД][ТипОперации(Приоритет)][Время][УникальныйИдентификатор/НомерДокумента]

Пример заполненного порядка операции: 201907094235959330М00-000262. За счет строкового сравнения таких кодов система мгновенно выстраивает документы в правильную FIFO-цепочку.

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

Почему поле «ПорядокОперации» оказывается незаполненным?

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

  1. Человеческий фактор при вводе дат документов. Это самая частая причина. При ручном вводе документов (например, документов ввода начальных остатков или реализаций прошлых периодов) пользователи случайно ошибаются в годе документа. Например, вместо 28.09.2018 указывают дату 28.09.2019 или даже уходят в далекое будущее (например, 2029 год). Вся цепочка FIFO ломается, и расчетные механизмы начинают выдавать пустые значения.
  2. Сбои при программном переносе или синхронизации данных. При обмене данными через EnterpriseData или РИБ документы могут переноситься частично, либо записываться в обход стандартных обработчиков проведения (например, с отключенным свойством ОбменДанными.Загрузка = Истина). Движения по регистрам формируются без вызова процедур заполнения оперативных взаиморасчетов.
  3. Прямое некорректное удаление документов. Если в базе данных были удалены документы-основания (например, заказы или накладные) напрямую обработками, без контроля ссылочной целостности, в регистрах сведений и накопления остаются «осиротевшие» записи движений, ссылающиеся на «Битые ссылки».

Разберем по шагам решение проблемы

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

Шаг 1. Локализация поврежденных данных в базе

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

  1. В режиме отладки поставьте точку останова в общем модуле ОперативныеВзаиморасчетыСервер на строке с ошибкой.
  2. В табло вычислите переменные СтрокаОплаты.Регистратор и СтрокаОтгрузкиПоставки.Регистратор. Один из этих документов и будет нашей проблемной сделкой.
  3. Если отладка на сервере недоступна, воспользуемся Универсальным отчетом. Настройте отчет по регистру накопления РасчетыСКлиентамиПоСрокам. Добавьте группировку по регистратору и выведите колонку Порядок зачета или Порядок операции. Настройте отбор, где Порядок операции не заполнен или равен NULL.

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


ВЫБРАТЬ
    Расчеты.Регистратор КАК ПроблемныйДокумент,
    Расчеты.АналитикаУчетаПоПартнерам.Партнер КАК Партнер,
    Расчеты.ПорядокОперации КАК ПорядокОперации
ИЗ
    РегистрНакопления.РасчетыСКлиентамиПоСрокам КАК Расчеты
ГДЕ
    Расчеты.ПорядокОперации ЕСТЬ NULL
    ИЛИ Расчеты.ПорядокОперации = ""

Шаг 2. Исправление документов и дат

После того как сбойный документ обнаружен (например, это оказалась старая Реализация товаров и услуг или Документ ввода остатков), проанализируем его реквизиты:

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

Шаг 3. Временное программное исправление кода (через Расширение)

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

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


// Внедряем безопасное приведение к строке для исключения NULL
ПорядокОплаты = ?(СтрокаОплаты.ПорядокОперации = NULL, "", СтрокаОплаты.ПорядокОперации);
ПорядокОтгрузки = ?(СтрокаОтгрузкиПоставки.ПорядокОперации = NULL, "", СтрокаОтгрузкиПоставки.ПорядокОперации);

Если ПорядокОплаты < ПорядокОтгрузки Тогда
    // Алгоритмы распределения оплат по FIFO продолжат работу без аварийного завершения
КонецЕсли;

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

← На главную