В процессе разработки механизмов обмена данными между базами 1С часто возникает задача передачи объекта ТаблицаЗначений. Особую сложность представляет ситуация, когда состав колонок таблицы заранее неизвестен (динамическая структура), и мы не можем жестко описать типы данных в коде. Разберем, почему возникают ошибки при использовании стандартного СериализаторXDTO, и проанализируем наиболее эффективные способы решения этой задачи.
В исходном коде автора часто встречается попытка прочитать XML напрямую через метод СериализаторXDTO.ПрочитатьXML(ЧтениеXMLДанных). Основная причина возникновения ошибки в данном случае заключается в том, что Сериализатор XDTO ожидает в XML-файле строго определенную структуру с указанием типов данных (пространств имен). Если XML-файл был сформирован не через СериализаторXDTO.ЗаписатьXML(), а иным способом, или если в схеме базы-приемника отсутствуют описания типов колонок, система не сможет восстановить объект.
Рассмотрим ситуацию: если в колонках таблицы содержатся ссылки на объекты (справочники, документы), которых нет в конфигурации-приемнике, или типы колонок определены как "ЛюбаяСсылка", автоматическая десериализация может завершиться неудачей. Выясним, как обойти эти ограничения.
Если в ваших конфигурациях подключена Библиотека Стандартных Подсистем (БСП), задача решается буквально в две строки. Методы общего назначения позволяют преобразовать любое сериализуемое значение (включая ТаблицаЗначений) в строку XML и обратно, сохраняя при этом структуру колонок и типы данных.
Посмотрим на пример кода для выгрузки:
// В базе-источнике
СтрокаXML = ОбщегоНазначения.ЗначениеВСтрокуXML(ВашаТаблицаЗначений);
// Далее записываем СтрокаXML в файл или передаем через API
И код для загрузки в базе-приемнике:
// В базе-приемнике
НоваяТЗ = ОбщегоНазначения.ЗначениеИзСтрокиXML(СтрокаXML);
Важный нюанс: Эти функции используют системные методы ЗначениеВXMLСтроку и ЗначениеИзXMLСтроки. Они идеально подходят для обмена между базами 1С, так как автоматически упаковывают метаданные колонок в формат, понятный платформе.
Если стоит задача передать большой объем данных и при этом важно минимизировать размер файла (как упоминалось в сообщении 6), лучше всего использовать сериализацию в двоичные данные. Этот метод доступен в платформе 8.3.9 и выше. Он работает быстрее, чем XML, и создает файлы меньшего размера.
Проанализируем шаги реализации:
ДвоичныеДанные.Рассмотрим пример кода:
// Выгрузка
ДвоичныеДанныеТЗ = ПолучитьИзВременногоХранилища(Адрес); // Допустим, ТЗ уже там
// Или напрямую:
ДвоичныеДанныеТЗ = ЗначениеВДвоичныеДанные(ВашаТаблицаЗначений);
ДвоичныеДанныеТЗ.Записать(ПутьКФайлу);
// Загрузка
ДвоичныеДанныеСДиска = Новый ДвоичныеДанные(ПутьКФайлу);
ВашаТаблицаЗначений = ЗначениеИзДвоичныхДанных(ДвоичныеДанныеСДиска);
Этот метод полностью сохраняет динамическую структуру колонок и является наиболее современным стандартом платформы для внутреннего обмена.
Если по каким-то причинам использование XML или двоичных данных невозможно, можно воспользоваться "старым", но надежным методом ЗначениеВСтрокуВнутр. Этот метод переводит объект в специфический текстовый формат 1С, который включает в себя описание всех типов и структуру объекта.
Выполним следующие действия:
// Код для преобразования в текст
ТекстДляФайла = ЗначениеВСтрокуВнутр(ТаблицаЗначений);
// Код для восстановления из текста
НоваяТаблица = ЗначениеИзСтрокиВнутр(ТекстДляФайла);
Преимущество: Метод сохраняет абсолютно всё, включая индексы таблицы значений. Недостаток: Полученный текст не предназначен для чтения человеком или сторонними системами, он пригоден только для обмена между 1С-приложениями.
Как отмечалось в обсуждении, JSON может быть легче XML. Платформа 1С поддерживает автоматическую сериализацию коллекций (в том числе ТЗ) в JSON через СериализаторXDTO. Это полезно, если количество колонок "плавает", и вам не хочется описывать их вручную.
Разберем пример записи:
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
СериализаторXDTO.ЗаписатьJSON(ЗаписьJSON, ВашаТаблицаЗначений);
СтрокаJSON = ЗаписьJSON.Закрыть();
Однако помните: при чтении JSON в другой базе 1С, типы данных колонок должны быть примитивными (строка, число, дата) или ссылками, GUID которых совпадает в обеих базах. Если в колонках содержатся сложные объекты, при чтении может потребоваться дополнительная обработка.
Важно понимать фундаментальное ограничение всех вышеперечисленных методов (кроме полноценной Конвертации Данных). Если в вашей таблице значений есть колонка с типом СправочникСсылка.Номенклатура, то при сериализации в XML или JSON передается только Уникальный Идентификатор (GUID) ссылки.
Если в базе-приемнике нет справочника с таким же GUID, вы получите значение "Объект не найден". Если ваша задача — не просто передать "плоскую" таблицу, а создать недостающие элементы справочников в приемнике, вам придется использовать Конвертацию данных 2.1 (КД). В КД можно настроить выгрузку ТЗ как входящих данных для алгоритма, и она сама позаботится о создании ссылочных объектов.
Подводя итог нашему анализу, выберем оптимальный метод в зависимости от ситуации:
ОбщегоНазначения.ЗначениеВСтрокуXML(). Это стандарт де-факто для разработчиков на 1С.ЗначениеВДвоичныеДанные(). Это максимально эффективно для больших объемов данных.ЗаписьJSON или ручное формирование XML через ЗаписьXML, так как системные форматы 1С (InternalString или системный XML) внешние программы не поймут.Таким образом, для решения задачи автора с динамическими колонками лучше всего отказаться от попыток ручного управления ЧтениеXML в пользу высокоуровневых методов платформы, которые берут на себя описание структуры таблицы.