РИБ: Неправильный формат сообщения
При загрузке от периферийного узла на последних 95% 1С долго думает, потом выдает ошибку:
Ошибка чтения файла сообщения обмена: Ошибка при вызове метода контекста (ЗакончитьЧтение)
{ОбщийМодуль.РасчетСебестоимостиПрикладныеАлгоритмы.Модуль(1805)}:Запрос.Выполнить();
{ОбщийМодуль.ОбменДаннымиУТ.Модуль(536)}:Возврат РасчетСебестоимостиПрикладныеАлгоритмы.СоздатьЗаданиеКРасчетуСебестоимостиПриОбменеДанными(ПолученныеДанные);
{ПланОбмена.Полный.МодульОбъекта(333)}:ОбменДаннымиУТ.СоздатьЗаданиеКРасчетуСебестоимостиПриОбменеДанными(ДанныеДляПерерасчета);
{ПланОбмена.Полный.МодульОбъекта(137)}:ПослеЗагрузкиДанных();
{Обработка.КонвертацияОбъектовРаспределенныхИнформационныхБаз.МодульОбъекта(232)}:ЧтениеСообщения.ЗакончитьЧтение();
{Обработка.КонвертацияОбъектовРаспределенныхИнформационныхБаз.МодульОбъекта(79)}:ПрочитатьФайлСообщенияОбмена(Отказ, ЧтениеXML, ЗагрузитьТолькоПараметры, ЗагрузитьМетаданные, СообщениеОбОшибке);
{ОбщийМодуль.ОбменДаннымиСервер.Модуль(5077)}:ОбработкаОбменаДанными.ВыполнитьЗагрузкуДанных(Отказ, ТолькоПараметры, СообщениеОбОшибке);
{ОбщийМодуль.ОбменДаннымиСервер.Модуль(8736)}:ПрочитатьСообщениеСИзменениямиДляУзла(СтруктураНастроекОбмена, СообщениеОбмена);
{ОбщийМодуль.ОбменДаннымиСервер.Модуль(1706)}:ВыполнитьОбменДаннымиЧерезФайловыйРесурс(СтруктураНастроекОбмена);
{ОбщийМодуль.ОбменДаннымиСервер.Модуль(9009)}:ВыполнитьДействиеОбмена(Отказ, УзелИнформационнойБазы,
{Обработка.ВыполнениеОбменаДанными.МодульМенеджера(30)}:ОбменДаннымиСервер.ВыполнитьОбменДаннымиДляУзлаИнформационнойБазы(
{(1)}:Обработки.ВыполнениеОбменаДанными.ВыполнитьЗапускОбменаДанными(Параметры[0],Параметры[1])
{ОбщийМодуль.ОбщегоНазначения.Модуль(6474)}:Выполнить ИмяМетода + "(" + ПараметрыСтрока + ")"; // АПК:487 Исполняемый код безопасен.
{ОбщийМодуль.ДлительныеОперации.Модуль(1781)}:ОбщегоНазначения.ВыполнитьМетодКонфигурации(ИмяПроцедуры, ПараметрыВызова);
{ОбщийМодуль.ДлительныеОперации.Модуль(1748)}:ВызватьПроцедуру(ВсеПараметры.ИмяПроцедуры, ВсеПараметры.ПараметрыПроцедуры, ПараметрыВыполнения);
[ОшибкаВоВремяВыполненияВстроенногоЯзыка]
по причине:
Ошибка при выполнении обработчика - 'ПередЗаписью'
по причине:
Ошибка при вызове метода контекста (Выполнить)
[ОшибкаВоВремяВыполненияВстроенногоЯзыка]
по причине:
Ошибка выполнения запроса
по причине:
В данной транзакции уже происходили ошибки!
При попытке прочитать файл непосредственно через узел плана обмена ошибка более лаконичная:

Ошибка при вызове метода контекста (ЗакончитьЧтение)
{mngbase/DataExchangeReadChanges.lf(93)}:Message.EndRead();
{mngbase/DataExchangeReadChanges.lf(21)}:ReadChangesAtServer(URL, TransactionSize);
[ОшибкаВоВремяВыполненияВстроенногоЯзыка]
по причине:
Неправильный формат сообщения
Ранее я уже сталкивался с подобной ошибкой, но тогда отличались релизы 1С на точке и в центре.
Проблема наблюдается при приеме данных из двух точек, с третьей все нормально проходит. Визуально различий в заголовках, дайджестах конфигурации, структуры XML нет.
Я предположил, что есть недопустимые символы XML и запустил свою обработку поиска недопустимых символов XML:

Правда, обработка работала довольно медленно, за минут 5 она обработала только 50.000 строк, а всего в файле обмена XML размером в распакованном виде 1,13 Гб было 13 миллионов строк. Я подумал, что такая скорость может быть из-за того, что 1С запущена под отладчиком и запустил 1С отдельно, чтобы ускорить процесс.
Файл иногда прирастал в обмене, видимо работала буферизация записи, по изменению объема можно было анализировать прогресс выполнения:

Правда, я задумался, что обработка работает слишком долго и понял, что написал функцию поиска недопустимых символов без директивы места выполнения, поэтому она выполнялась на сервере и для каждой строки файла вызывалась с клиента. Поправил обработку так:
&НаКлиентеНаСервереБезКонтекста Функция УдалитьНедопустимыеСимволыXML(Стр, ЕстьНедопустимые = ложь) //Осипов - функция по удалению недопустимых символов Позиция = НайтиНедопустимыеСимволыXML(Стр, , ); Пока Позиция <> 0 Цикл ЕстьНедопустимые = Истина; Стр = Лев(Стр, Позиция-1) + Сред(Стр, Позиция+1); Позиция = НайтиНедопустимыеСимволыXML(Стр, , ); КонецЦикла; Возврат Стр; КонецФункции
После этого файл пролетел за пол-минуты:
Время: 32 секунд . Строк файла: 13 617 580. Строк всего: 13 617 580. Обработан файл № 1 "C:\Users\Admin\Downloads\Yandex.Disk.Files\Message_P_Ts (2)\Message_P_Ts.xml"
Недопустимых символов не нашлось, значит проблема в чем-то другом.
Написал обработку по загрузке файла РИБ, используя рекомендации 1С:

Правда, не понял, будут ли регистрироваться изменения в обратную сторону, но по идее ЧтениеСообщения блокирует узел от регистрации изменений.
На всякий случай замерил изменения на узел до:

И после:

Кроме того, не записались записи регистра сведений из-за даты запрета изменения.
Чтобы избежать этого, добавил две строчки перед записью объекта:
ЭлементДанных.ОбменДанными.Отправитель = ЧтениеСообщения.Отправитель; ЭлементДанных.ОбменДанными.Загрузка = истина;
Сделал опять замеры числа изменений до:

И после:

Отлично, именно такой способ чтения изменений нужно практиковать в 1С, указывать отправителя в параметрах ОбменДанными.Отправитель и отключать контроль логики проверок через ОбменДанными.Загрузка.
Чтобы ЧтениеСообщения нормально закончило чтение, курсор ЧтениеXML должен стоять на закрыающем теге v8msg:Body.
Тогда нормально устанавливается номер принятого сообщения, в файле 33037:

После загрузки 33037:

Загрузка не выявила проблемы, но данные зарузила. Возможно, нужно сделать изменения в конфигурации и выгрузить конфигурацию на точки, произойдет какой-то пересчет. Может сделать тестирование и исправление периферийных баз. А может быть это сбой в текущем релизе 8.3.27. Сложно сказать.
Код обработки:
&НаКлиенте Процедура ВыбИмяФайлаНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка) РежимДиалога = РежимДиалогаВыбораФайла.Открытие; Диалог = Новый ДиалогВыбораФайла(РежимДиалога); Диалог.МножественныйВыбор = ложь; Диалог.ПолноеИмяФайла = Объект.ВыбИмяФайла; Диалог.Фильтр = "Файлы XML (*.xml)|*.xml"; Диалог.Показать(Новый ОписаниеОповещения("ВыбИмяФайлаОкончаниеВыбора", ЭтаФорма)); КонецПроцедуры &НаКлиенте Процедура ВыбИмяФайлаОкончаниеВыбора(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт Если ВыбранныеФайлы <> Неопределено Тогда Объект.ВыбИмяФайла = ВыбранныеФайлы[0]; КонецЕсли; КонецПроцедуры &НаСервере Процедура ЗагрузитьФайлНаСервере(ДД) //https://its.1c.ru/db/metod8dev/content/2275/hdoc ВФ = ПолучитьИмяВременногоФайла("XML"); ДД.Записать(ВФ); ЧтениеХМЛ = Новый ЧтениеXML; ЧтениеХМЛ.ОткрытьФайл(ВФ); ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения(); ЧтениеСообщения.НачатьЧтение(ЧтениеХМЛ); Узел = ЧтениеСообщения.Отправитель; Сч = 0; Пока Истина Цикл ТипХМЛ = ПолучитьXMLТип(ЧтениеХМЛ); //Если ТипХМЛ.Имя = "Changes" Тогда //ВозможностьЧтенияXML(ЧтениеХМЛ)Цикл //Если конец сообщения Если ЧтениеХМЛ.ТипУзла = ТипУзлаXML.КонецЭлемента И ЧтениеХМЛ.Имя = "v8msg:Body" Тогда Прервать; КонецЕсли; // Читаем элемент данных стандартным способом Если НЕ ВозможностьЧтенияXML(ЧтениеХМЛ) Тогда Сообщить("Невозможно прочитать тип: " + ?(ТипХМЛ = Неопределено, "Неопределено", ТипХМЛ.ИмяТипа) + ". " + ЧтениеХМЛ.ТипУзла + ": " + ЧтениеХМЛ.Имя + " = " + ЧтениеХМЛ.Значение); Если НЕ ЧтениеХМЛ.Прочитать() Тогда //Переходим к следующему //Если последний элемент Прервать; КонецЕсли; Иначе ЭлементДанных = ПрочитатьXML(ЧтениеХМЛ); Сч = Сч + 1; Попытка Если Объект.ЗаписыватьДанные Тогда ЭлементДанных.ОбменДанными.Отправитель = ЧтениеСообщения.Отправитель; ЭлементДанных.ОбменДанными.Загрузка = истина; ЭлементДанных.Записать(); КонецЕсли; Исключение ОписаниеОшибки = ОписаниеОшибки(); Сообщить("Не удалось прочитать: " + Символы.ПС + ЗначениеВСтрокуXML(ЭлементДанных) + Символы.ПС + "Ошибка: " + ОписаниеОшибки); КонецПопытки; КонецЕсли; КонецЦикла; Если Объект.ПодтверджатьПриемСообщения Тогда ПланыОбмена.УдалитьРегистрациюИзменений(ЧтениеСообщения.Отправитель, ЧтениеСообщения.НомерПринятого); ЧтениеСообщения.ЗакончитьЧтение(); КонецЕсли; ЧтениеХМЛ.Закрыть(); Сообщить("Прочитано объектов данных: " + Сч); КонецПроцедуры &НаКлиенте Процедура ЗагрузитьФайл(Команда) ДД = Новый ДвоичныеДанные(Объект.ВыбИмяФайла); ЗагрузитьФайлНаСервере(ДД); КонецПроцедуры Функция ЗначениеВСтрокуXML(Значение) Экспорт ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.УстановитьСтроку(); СериализаторXDTO.ЗаписатьXML(ЗаписьXML, Значение); Возврат ЗаписьXML.Закрыть(); КонецФункции
Среда: УТ 11.5.22.92, 1С 8.3.27.1688. Объем: 3 час.




Свежие комментарии