Рассмотрим распространенную и крайне неприятную проблему, с которой часто сталкиваются администраторы и разработчики 1С при организации обмена данными. Ошибка с текстом «Ошибка при вызове метода контекста (НачатьЧтение): Номер сообщения меньше или равен номеру ранее принятого сообщения» обычно возникает внезапно, блокируя синхронизацию между базами. В большинстве случаев первопричиной является восстановление одной из информационных баз (отправителя или получателя) из резервной копии.
В этой статье мы подробно проанализируем физический смысл данной ошибки, выясним, почему простое обнуление номеров в интерфейсе часто не приносит желаемого результата, и разберем по шагам надежные способы восстановления обмена и ручной регистрации изменений для объектов.
Для начала разберем внутреннюю логику работы платформы 1С:Предприятие. Ошибка при вызове метода НачатьЧтение — это не просто системный сбой, а штатный механизм защиты от повторной загрузки данных (так называемая защита от повторных атак или повторного импорта устаревших пакетов).
Когда база-источник формирует XML-файл обмена, в его заголовок записываются два важнейших служебных параметра:
В принимающей базе для каждого узла плана обмена также хранятся два зеркальных реквизита: НомерПринятого и НомерОтправленного.
Жесткое правило платформы: База-получатель согласится прочитать и обработать входящий XML-файл обмена только в том случае, если значение MessageNo внутри файла строго больше, чем НомерПринятого, записанный в карточке этого узла в базе-получателе. Если это условие не выполняется, платформа прерывает транзакцию и выдает ошибку.
Если одну из баз восстановили из бэкапа, ее счетчики сообщений откатились назад (например, на значение 10), в то время как во второй базе (которая не восстанавливалась) счетчики продолжали увеличиваться и ушли вперед (например, до значения 25). При следующей попытке обмена восстановленная база отправит пакет с номером 11, а база-приемник ожидает номер строго больше 25. Платформа мгновенно заблокирует этот процесс.
Многие специалисты пытаются исправить ситуацию, вручную сбрасывая номера сообщений в карточках узлов планов обмена в обеих базах в ноль. Однако это часто приводит к повторному возникновению ошибки. Проанализируем, почему так происходит:
Message_001_002.xml), то при запуске автоматического обмена система попытается прочитать их первыми. Так как номера в базах вы уже сбросили в 0, а в файле записан старый реальный номер (например, 15), система выдаст ту же самую ошибку. Решение: Перед манипуляциями с номерами обязательно полностью очистите каталог обмена от файлов.НомерОтправленного = X, НомерПринятого = Y.НомерОтправленного = Y, НомерПринятого = X - 1 (или X после успешного завершения чтения).Выполним последовательность действий, которая гарантированно решит проблему с нумерацией пакетов:
НомерПринятого и НомерОтправленного равными 0.Для быстрого программного сброса номеров в обеих базах можно использовать следующий код во внешней обработке или консоли кода:
УзелОбъекта = ПланыОбмена.ИмяВашегоПланаОбмена.НайтиПоКоду("КодУзла").ПолучитьОбъект();
УзелОбъекта.НомерПринятого = 0;
УзелОбъекта.НомерОтправленного = 0;
УзелОбъекта.Записать();
Выполните этот код в обеих базах, подставив реальное имя вашего плана обмена (например, ОбменУправлениеТорговлейБухгалтерияПредприятия) и код узла-корреспондента.
Сброс нумерации решает проблему прохождения самого файла обмена, однако восстановление базы из копии влечет за собой другую проблему: рассинхронизацию самих данных.
Объекты (документы, элементы справочников), которые были созданы и отправлены из восстановленной базы в базу-приемник после даты бэкапа, теперь физически отсутствуют в источнике. Обратно они автоматически не придут, так как в приемнике они уже считаются успешно отправленными. Чтобы восстановить эти данные, нам необходимо заново зарегистрировать их для обмена. Для автоматизации этого процесса можно использовать обработку для регистрации документов и справочников, созданных после определенной даты.
Рассмотрим, как зарегистрировать изменения для объектов (например, справочника Контрагенты) ручными и программными методами.
Если вы работаете в современных конфигурациях на управляемых формах (например, БП 3.0, УТ 11, ERP, УНФ), в них встроен удобный инструмент для работы с составом отправляемых данных:
Контрагенты).В старых конфигурациях 1С (на обычных формах, таких как УТ 10.3 или БП 2.0) типовой интерфейс может не предоставлять детальных возможностей для регистрации единичных объектов. В этом случае воспользуемся внешней обработкой РегистрацияИзмененийДляОбмена.epf (ее можно найти на диске ИТС или в дистрибутиве конфигурации «Конвертация данных»):
Если вам нужно оперативно зарегистрировать один или несколько конкретных объектов без использования интерактивных форм, вы можете написать простой скрипт и выполнить его через консоль разработчика:
УзелСсылка = ПланыОбмена.ИмяВашегоПланаОбмена.НайтиПоКоду("КодУзла");
КонтрагентСсылка = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", "1234567890");
Если ЗначениеЗаполнено(КонтрагентСсылка) Тогда
ПланыОбмена.ЗарегистрироватьИзменения(УзелСсылка, КонтрагентСсылка);
Сообщить("Объект успешно зарегистрирован к обмену!");
КонецЕсли;
Этот код выполняет поиск элемента справочника по ИНН и регистрирует его для отправки на конкретный узел. При выполнении следующего сеанса обмена этот контрагент будет принудительно выгружен в базу-приемник, восстановив тем самым актуальность данных. Для массовой регистрации объектов без написания кода можно использовать обработку для регистрации изменений по спискам, журналу или запросу.
Таким образом, комплексное выполнение очистки каталога, сброса номеров сообщений и точечной регистрации потерянных объектов позволяет полностью и безболезненно ликвидировать последствия восстановления баз из архивных копий.