Как выгрузить несколько таблиц значений в один XML-файл в 1С

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

В процессе разработки часто возникает задача передачи структурированных данных между базами 1С или внешними системами. Когда данных много и они распределены по разным таблицам, программисты сталкиваются с вопросом: как объединить несколько таблиц значений в один XML-файл так, чтобы его было удобно не только записать, но и корректно прочитать в обратную сторону? Разберем по шагам наиболее эффективные методы решения этой задачи, начиная от простых универсальных контейнеров и заканчивая оптимизированными способами для больших объемов данных.

Метод 1: Использование универсального контейнера (Массив или Структура)

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

Почему лучше использовать Структуру, а не Массив? Хотя оба варианта работоспособны, Структура позволяет назначать ключи (имена) для каждой таблицы. Это значительно упрощает последующее чтение: вам не нужно помнить, что в индексе 0 лежит таблица товаров, а в индексе 1 — таблица контрагентов. Вы просто обращаетесь к полю по имени.

Рассмотрим пример реализации через Структура:


// 1. Получаем данные из запроса
РезультатыПакетногоЗапроса = Запрос.ВыполнитьПакет();

// 2. Формируем контейнер для выгрузки
ДанныеДляЭкспорта = Новый Структура;
ДанныеДляЭкспорта.Вставить("ТаблицаТовары", РезультатыПакетногоЗапроса[0].Выгрузить());
ДанныеДляЭкспорта.Вставить("ТаблицаСклады", РезультатыПакетногоЗапроса[1].Выгрузить());

// 3. Подготавливаем механизмы записи
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл("C:\temp\DataExport.xml", "UTF-8");

// 4. Используем СериализаторXDTO для записи всего контейнера целиком
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ДанныеДляЭкспорта, НазначениеТипаXML.Явное);

ЗаписьXML.Закрыть();

В данном примере использование НазначениеТипаXML.Явное гарантирует, что в XML будут сохранены описания типов данных каждой колонки. Это критически важно, если в таблицах присутствуют типы Число, Дата или ссылки на объекты, которые должны корректно восстановиться при загрузке.

Метод 2: Последовательная ручная запись (для больших данных)

Проанализируем ситуацию, когда таблицы содержат сотни тысяч строк. Использование автоматической сериализации через контейнер может привести к ошибке «Нехватка памяти», так как 1С пытается построить полное дерево объектов в оперативной памяти перед физической записью на диск. В таких случаях нам поможет метод ручного управления узлами XML.

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

  1. Создаем корневой элемент (Root), чтобы файл был валидным XML-документом.
  2. Поочередно записываем каждую таблицу, используя СериализаторXDTO для записи объекта ТаблицаЗначений внутри нашего корневого узла.
  3. Закрываем корневой элемент.

Разберем программный код:


ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл("C:\temp\BigDataExport.xml", "UTF-8");

// Записываем начало общего корня
ЗаписьXML.ЗаписатьНачалоЭлемента("ДанныеЭкспорта");

// Записываем первую таблицу
Таблица1 = РезультатыПакетногоЗапроса[0].Выгрузить();
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, Таблица1, "TableInfo1", "http://v8.1c.ru/8.1/data/core");

// Записываем вторую таблицу
Таблица2 = РезультатыПакетногоЗапроса[1].Выгрузить();
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, Таблица2, "TableInfo2", "http://v8.1c.ru/8.1/data/core");

// Закрываем корень
ЗаписьXML.ЗаписатьКонецЭлемента();
ЗаписьXML.Закрыть();

Этот подход позволяет комбинировать автоматическую мощь СериализаторXDTO и ручной контроль над структурой файла, что более бережно относится к ресурсам сервера.

Чтение данных в обратную сторону

Посмотрим на процесс восстановления данных. Если мы использовали Структура при записи (Метод 1), то чтение превращается в простую операцию в одну строку. Платформа сама распознает типы объектов внутри файла и восстановит их в соответствующие коллекции 1С.


ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл("C:\temp\DataExport.xml");

// Десериализация всего контейнера обратно в структуру
ДанныеИзФайла = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);

// Теперь мы можем обращаться к таблицам по именам ключей
Если ТипЗнч(ДанныеИзФайла) = Тип("Структура") Тогда
    ТаблицаТовары = ДанныеИзФайла.ТаблицаТовары;
    ТаблицаСклады = ДанныеИзФайла.ТаблицаСклады;
КонецЕсли;

ЧтениеXML.Закрыть();

Важные технические нюансы и оптимизация

Проанализируем дополнительные возможности, которые помогут сделать вашу выгрузку более надежной:

1. Использование XDTO-пакетов для интеграции. Если ваш XML файл предназначен для сторонней системы (например, написанной на Java или Python), стандартные теги 1С (ValueTable, row, column) могут быть неудобны. В этом случае рекомендуется создать в конфигурации собственный XDTO-пакет. Это позволит вам строго описать схему данных (XSD), задать понятные имена тегов для каждой колонки таблицы и валидировать файл перед отправкой.

2. Метод XMLСтрока(). Помните, что встроенная функция XMLСтрока(ВашаТаблицаЗначений) не работает. Она предназначена только для простых типов. Для коллекций использование СериализаторXDTO является безальтернативным штатным средством.

3. Потоки в памяти. Если данные не нужно сохранять в файл, а нужно передать, например, в HTTP-запрос, рассмотрите использование объекта ПотокВПамяти. Это ускорит работу, так как исключит медленные дисковые операции:


Поток = Новый ПотокВПамяти();
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьПоток(Поток);
// ... запись данных ...
РезультатБайты = Поток.ЗакрытьИПолучитьДвоичныеДанные();

Таким образом, мы выяснили, что наиболее универсальным способом выгрузки нескольких таблиц является использование объекта Структура в связке с СериализаторXDTO. Это обеспечивает автоматическую типизацию колонок, простоту обратного чтения и высокую скорость разработки.

← На главную