Как исправить ошибку «Номер сообщения меньше или равен номеру ранее принятого сообщения» в 1С?

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

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

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

Физический смысл ошибки и механизм защиты платформы

Для начала разберем внутреннюю логику работы платформы 1С:Предприятие. Ошибка при вызове метода НачатьЧтение — это не просто системный сбой, а штатный механизм защиты от повторной загрузки данных (так называемая защита от повторных атак или повторного импорта устаревших пакетов).

Когда база-источник формирует XML-файл обмена, в его заголовок записываются два важнейших служебных параметра:

  1. MessageNo — порядковый номер текущего отправляемого сообщения.
  2. ReceivedNo — номер последнего сообщения, которое эта база успешно приняла от своего партнера по обмену.

В принимающей базе для каждого узла плана обмена также хранятся два зеркальных реквизита: НомерПринятого и НомерОтправленного.

Жесткое правило платформы: База-получатель согласится прочитать и обработать входящий XML-файл обмена только в том случае, если значение MessageNo внутри файла строго больше, чем НомерПринятого, записанный в карточке этого узла в базе-получателе. Если это условие не выполняется, платформа прерывает транзакцию и выдает ошибку.

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

Почему простое «обнуление» номеров часто не помогает?

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

  1. Наличие старых файлов в каталоге обмена. Если в сетевой папке, на FTP-сервере или в облаке остались лежать старые файлы сообщений (например, с именами Message_001_002.xml), то при запуске автоматического обмена система попытается прочитать их первыми. Так как номера в базах вы уже сбросили в 0, а в файле записан старый реальный номер (например, 15), система выдаст ту же самую ошибку. Решение: Перед манипуляциями с номерами обязательно полностью очистите каталог обмена от файлов.
  2. Неправильное перекрестное сопоставление номеров. При ручной установке номеров легко запутаться в их соответствии. Должно строго соблюдаться следующее правило:
    • База А (Отправитель): НомерОтправленного = X, НомерПринятого = Y.
    • База Б (Приемник): НомерОтправленного = Y, НомерПринятого = X - 1 (или X после успешного завершения чтения).
    Если установить случайные одинаковые числа «наугад», это с высокой вероятностью заблокирует обмен в одну из сторон.

Пошаговая инструкция по исправлению конфликта нумерации

Выполним последовательность действий, которая гарантированно решит проблему с нумерацией пакетов:

  1. Остановите регламентные задания обмена данными, чтобы предотвратить фоновую перезапись файлов во время проведения работ.
  2. Полностью очистите каталог обмена (или FTP/облачную папку). Удалите все файлы формата XML и ZIP, относящиеся к этой паре обмена. При необходимости предварительно сохраните их в архивную папку вне каталога обмена.
  3. Сбросьте номера сообщений. Самый простой и надежный вариант — установить в обеих базах для конфликтующего узла значения реквизитов НомерПринятого и НомерОтправленного равными 0.

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


УзелОбъекта = ПланыОбмена.ИмяВашегоПланаОбмена.НайтиПоКоду("КодУзла").ПолучитьОбъект();
УзелОбъекта.НомерПринятого = 0;
УзелОбъекта.НомерОтправленного = 0;
УзелОбъекта.Записать();

Выполните этот код в обеих базах, подставив реальное имя вашего плана обмена (например, ОбменУправлениеТорговлейБухгалтерияПредприятия) и код узла-корреспондента.

Проблема восстановления данных и ручная регистрация изменений

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

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

Рассмотрим, как зарегистрировать изменения для объектов (например, справочника Контрагенты) ручными и программными методами.

Способ 1. Регистрация изменений через стандартный интерфейс БСП

Если вы работаете в современных конфигурациях на управляемых формах (например, БП 3.0, УТ 11, ERP, УНФ), в них встроен удобный инструмент для работы с составом отправляемых данных:

  1. Перейдите в раздел Администрирование — Синхронизация данных.
  2. Откройте ссылку Настройки синхронизации данных.
  3. Выделите нужную настройку обмена и нажмите кнопку Состав отправляемых данных (кнопка в виде двух зеленых кружков на панели инструментов).
  4. Перед вами откроется дерево метаданных. Найдите нужный объект (например, справочник Контрагенты).
  5. Если нужно зарегистрировать все измененные объекты этого типа: нажмите кнопку Зарегистрировать — Все объекты выбранных типов.
  6. Если требуется зарегистрировать точечно конкретные элементы: нажмите кнопку Еще (над деревом метаданных) — Зарегистрировать — Одиночный объект... (или Отбор... для регистрации группы объектов по условию).
  7. В открывшемся списке выберите конкретных контрагентов и подтвердите выбор.

Способ 2. Использование внешней обработки «Регистрация изменений для обмена»

В старых конфигурациях 1С (на обычных формах, таких как УТ 10.3 или БП 2.0) типовой интерфейс может не предоставлять детальных возможностей для регистрации единичных объектов. В этом случае воспользуемся внешней обработкой РегистрацияИзмененийДляОбмена.epf (ее можно найти на диске ИТС или в дистрибутиве конфигурации «Конвертация данных»):

  1. Откройте обработку в режиме Предприятия (меню Файл — Открыть).
  2. В верхней части формы выберите нужный узел плана обмена.
  3. В левой части окна отобразится дерево метаданных. Кликните правой кнопкой мыши по нужному справочнику или документу.
  4. Выберите пункт Зарегистрировать изменения элементов по одному... для точечного выбора конкретного объекта из списка, либо добавьте регистрацию по условию с помощью кнопки Добавить регистрацию по отбору....

Способ 3. Программный метод регистрации объектов к обмену

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


УзелСсылка = ПланыОбмена.ИмяВашегоПланаОбмена.НайтиПоКоду("КодУзла");
КонтрагентСсылка = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", "1234567890");

Если ЗначениеЗаполнено(КонтрагентСсылка) Тогда
    ПланыОбмена.ЗарегистрироватьИзменения(УзелСсылка, КонтрагентСсылка);
    Сообщить("Объект успешно зарегистрирован к обмену!");
КонецЕсли;

Этот код выполняет поиск элемента справочника по ИНН и регистрирует его для отправки на конкретный узел. При выполнении следующего сеанса обмена этот контрагент будет принудительно выгружен в базу-приемник, восстановив тем самым актуальность данных. Для массовой регистрации объектов без написания кода можно использовать обработку для регистрации изменений по спискам, журналу или запросу.

Таким образом, комплексное выполнение очистки каталога, сброса номеров сообщений и точечной регистрации потерянных объектов позволяет полностью и безболезненно ликвидировать последствия восстановления баз из архивных копий.

← На главную