При работе с распределенными информационными базами (РИБ) специалисты 1С часто сталкиваются с неприятной ситуацией: плановый обмен данными внезапно прерывается ошибкой. Сообщение в журнале регистрации выглядит следующим образом: «Ошибка при чтении изменений при обмене РИБ: Ошибка при вызове метода контекста (ПрочитатьИзменения): Ошибка преобразования данных XML». При этом система указывает на конкретный временный файл и номер строки с ошибкой.
В этой статье мы подробно разберем, почему возникает эта проблема, как локализовать поврежденные данные и какими методами можно быстро восстановить работоспособность обмена в РИБ.
Давайте проанализируем ситуацию, описанную в теме форума. При детальном изучении проблемной строки XML-файла обмена обнаруживается скрытый дефект в строковых данных. Например, в строке идентификатора или наименования может присутствовать невидимый спецсимвол, такой как мягкий перенос (soft hyphen, код U+00AD) или другие управляющие символы ASCII (диапазон 0x00–0x1F).
Подобные символы обычно попадают в базу данных 1С при копировании текстовой информации пользователями из внешних источников: веб-сайтов, PDF-инструкций, электронных писем или документов MS Word. При выгрузке изменений в РИБ платформа записывает эти символы в XML-файл обмена «как есть». Однако стандартный XML-парсер на принимающей стороне (в периферийной или центральной базе) строго следует стандартам консорциума W3C. Встречая недопустимый или неэкранированный символ, парсер аварийно завершает работу метода ПрочитатьИзменения.
Ситуация усугубляется на старых версиях платформ (например, 8.3.10) и конфигурациях прошлых поколений (таких как Комплексная автоматизация 1.1), где встроенные механизмы сериализации еще не имели автоматической фильтрации «мусорных» символов Юникода.
Рассмотрим практическое решение, которое помогло автору темы успешно завершить обмен без потери данных. Этот способ отлично подходит, если проблемных объектов немного (например, несколько контрагентов).
Для реализации этого метода нам понадобятся две обработки: стандартная ВыгрузкаЗагрузкаДанныхXML.epf и любая обработка для удаления объектов без контроля ссылочной целостности (с установленным свойством ОбменДанными.Загрузка = Истина).
Разберем процесс по шагам:
ВыгрузкаЗагрузкаДанныхXML.epf настраиваем отбор по конкретному найденному элементу (например, по ссылке или коду контрагента) и выгружаем его в отдельный файл на диске.ОбменДанными.Загрузка = Истина, чтобы обойти проверки и не очищать ссылки в связанных документах.ВыгрузкаЗагрузкаДанныхXML.epf.Если база данных большая, ручной поиск каждого символа мягкого переноса может занять слишком много времени. Рассмотрим более технологичный подход с использованием механизмов платформы 1С и БСП.
В составе специализированных инструментов для разработчиков есть универсальное решение. В обработке ВыгрузкаЗагрузкаДанныхXML.epf предусмотрена встроенная функция проверки коллизий в планах обмена.
Выполним следующие действия:
Для предотвращения подобных ошибок в будущем мы можем написать простую процедуру очистки строк перед отправкой данных в РИБ. Если ваша конфигурация использует Библиотеку стандартных подсистем (БСП), в ней уже есть готовый метод:
ОбщегоНазначенияКлиентСервер.ЗаменитьНедопустимыеСимволыXML(Текст, СимволЗамены)
Если же мы работаем на старой конфигурации без БСП, напишем собственный алгоритм фильтрации строк. Посмотрим на пример кода:
Функция ОчиститьСтрокуОтНедопустимыхСимволовXML(ВходнаяСтрока) Экспорт
Результат = "";
Для Поз = 1 По СтрДлина(ВходнаяСтрока) Цикл
Символ = Сред(ВходнаяСтрока, Поз, 1);
КодСимвола = КодСимвола(Символ);
// Разрешаем стандартные символы XML: Символы с кодами >= 32, Табуляцию (9), Перенос строки (10, 13)
// Исключаем невидимый мягкий перенос (173 / U+00AD) и управляющие символы
Если (КодСимвола >= 32 И КодСимвола <> 173) Или КодСимвола = 9 Или КодСимвола = 10 Или КодСимвола = 13 Тогда
Результат = Результат + Символ;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Данную функцию можно вызывать в подписке на событие ПередЗаписью для всех справочников, данные которых часто копируются из внешних источников (Контрагенты, Номенклатура, ФизическиеЛица).
Иногда ошибка преобразования XML возникает не из-за спецсимволов в данных, а по причине несовпадения структуры конфигураций в центральной и периферийной базах. Например, если в центральной базе обновили реквизиты, а в периферийной обновление еще не применилось.
В такой ситуации проанализируем схему метаданных и выполним процедуру перепривязки периферийного узла:
ПланыОбмена.УстановитьГлавныйУзел(Неопределено);
1cv8.cf и загрузим его в периферийную базу через «Сравнить, объединить с конфигурацией из файла».
УзелЦБ = ПланыОбмена.ГлавныйУзел(); // Или находим ссылку на узел ЦБ явным образом
ПланыОбмена.УстановитьГлавныйУзел(СсылкаНаУзелЦБ);
Применяя указанные методы, мы сможем оперативно находить скрытые символы разметки в текстовых полях 1С и гарантировать стабильную, бесперебойную работу распределенной информационной системы.