При обмене данными между конфигурациями 1С (например, между «Управление торговлей 10.3» и «Бухгалтерия предприятия 3.0») программисты часто сталкиваются с неприятной особенностью встроенных механизмов выгрузки. Когда количество строк в табличной части документа (Реализация товаров и услуг, Поступление и др.) превышает 1000, процесс прерывается ошибкой: «Ошибка при вызове метода контекста (ЗаписатьБезОбработки): Не установлен приемник XML».
В этой статье мы подробно разберем, почему возникает это ограничение, как оно связано с внутренними механизмами оптимизации 1С и какими способами можно устранить эту проблему раз и навсегда.
Для начала выясним, почему магическое число «1000» становится камнем преткновения. В основе механизма «Универсальный обмен данными XML» лежит технология «Конвертация данных 2.0». Разработчики платформы заложили в логику обработки выгрузки механизм экономии оперативной памяти.
Работает это следующим образом: пока количество строк в коллекции (например, в табличной части) невелико, данные формируются непосредственно в оперативной памяти и сразу записываются в итоговый XML-файл. Однако, как только счетчик строк достигает 1000, система решает, что объект слишком «тяжелый», и пытается переключиться в режим использования временного файла на диске. Это должно предотвратить ошибку Out of Memory на стороне сервера или клиента.
Ошибка Не установлен приемник XML возникает из-за программного бага в типовой обработке: при переключении в режим временного файла объект записи (приемник) не инициализируется корректно или теряет связь с основным потоком записи. Рассмотрим, как это исправить.
Этот метод считается наиболее правильным, так как он не просто отключает лимит, а исправляет некорректное поведение переменной состояния. Нам потребуется внести изменения в модуль объекта обработки УниверсальныйОбменДаннымиXML.
Разберем по шагам процесс внесения изменений:
УниверсальныйОбменДаннымиXML.ВыгрузитьГруппуСвойств.Если ВыгружатьГруппуЧерезФайл Тогда.Посмотрим на пример кода, который должен получиться в итоге:
// В типовой версии код выглядит так:
Если ВыгружатьГруппуЧерезФайл Тогда
// Здесь происходит сбой из-за отсутствия настройки узла
КонецЕсли;
// Нам нужно привести его к следующему виду:
Если ВыгружатьГруппуЧерезФайл Тогда
ПКГС.НуженУзелXMLПриВыгрузке = Ложь;
// Данная строка принудительно указывает системе, что текущий узел
// не требует создания отдельного дескриптора в памяти, так как идет работа через файл.
КонецЕсли;
После этого изменения выгрузка документов с любым количеством строк (1000, 5000 или 10000) будет проходить штатно.
Если вы не хотите глубоко погружаться в логику работы с временными файлами, существует более простой, «силовой» метод — увеличить пороговое значение, при котором система начинает паниковать и переходить на диск. Рассмотрим, как это сделать.
В том же модуле обработки найдем строку, где определяется условие ВыгружатьГруппуЧерезФайл. Обычно она выглядит так:
ВыгружатьГруппуЧерезФайл = ВыгружатьГруппуЧерезФайл ИЛИ (КоллекцияОбъектов.Количество() > 1000);
Мы можем модифицировать это условие двумя путями:
1000 на 10000. Это поможет в большинстве случаев, если ваши документы не достигают гигантских размеров.Проанализируем пример с комментированием:
// Было:
// ВыгружатьГруппуЧерезФайл = ВыгружатьГруппуЧерезФайл ИЛИ (КоллекцияОбъектов.Количество() > 1000);
// Стало:
ВыгружатьГруппуЧерезФайл = Ложь; // Всегда выгружаем в память
Важное предупреждение: используйте этот метод с осторожностью. Если на сервере 1С мало оперативной памяти или вы используете 32-битную версию платформы, выгрузка документа на 50 000 строк может привести к аварийному завершению работы процесса rphost.
В процессе обсуждения проблемы на форумах часто всплывает тема «НПП» — непечатаемых пробелов. В 1С при выводе чисел в строковом представлении (например, номера строки) часто используется группировка разрядов, где в качестве разделителя выступает Символы.НПП.
Если ваши правила обмена (ПКО/ПКС) настроены так, что номер строки передается как строка с форматированием, это может косвенно влиять на ошибки парсинга XML. Чтобы исключить этот фактор, найдите в правилах обмена (в информационной базе «Конвертация данных») ПКС для НомерСтроки и пропишите обработчик «Перед выгрузкой»:
Значение = Формат(ОбъектКоллекции.НомерСтроки, "ЧГ=");
Это гарантирует, что число 1 000 превратится в строку 1000 без лишних символов, которые могут некорректно обрабатываться при записи в XML-поток.
При работе с большими объемами данных через «Универсальный обмен» стоит обратить внимание на следующие моменты:
V8Exch82.epf (обычно идет в комплекте с конфигурацией «Конвертация данных»). В последних релизах этот баг уже может быть исправлен разработчиками 1С.Подведем итог: ошибка вызвана несовершенством механизма оптимизации памяти в старых версиях обработки выгрузки. Наиболее надежным решением является добавление строки ПКГС.НуженУзелXMLПриВыгрузке = Ложь; в процедуру ВыгрузитьГруппуСвойств, что восстанавливает корректную работу с приемником данных XML при записи во временный буфер.