Как записать XML-данные в реквизит справочника и прочитать их в 1С?

Программист IT и автоматизация бизнеса
← На главную

При разработке прикладных решений в 1С часто возникает необходимость сохранить структурированные данные (например, содержимое табличной части формы) в реквизит справочника, а затем при необходимости считывать их обратно. Нередко для этой задачи выбирают формат XML. Рассмотрим, как правильно реализовать запись и чтение XML без создания временных файлов на диске, а также проанализируем альтернативные способы хранения данных внутри информационной базы.

Запись XML в оперативную память и сохранение в ХранилищеЗначения

Главная ошибка при работе с объектом ЗаписьXML — попытка вызывать метод ОткрытьФайл, когда генерация файла на диске не требуется. Чтобы формировать XML-документ прямо в оперативной памяти, следует использовать метод УстановитьСтроку().

Рассмотрим пошагово процесс формирования XML и записи полученной строки в реквизит справочника типа ХранилищеЗначения:

  1. Создаем объект ЗаписьXML и инициализируем запись в строку с помощью метода УстановитьСтроку().
  2. Записываем объявление XML и необходимые элементы с помощью методов ЗаписатьНачалоЭлемента, ЗаписатьТекст, ЗаписатьКонецЭлемента.
  3. Завершаем запись вызовом метода Закрыть(), который возвращает сформированную строку XML.
  4. Помещаем полученный текст в объект ХранилищеЗначения (при необходимости сжатия передаем параметр Новый СжатиеДанных) и записываем элемент справочника.

Проанализируем пример кода записи:


ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
ЗаписьXML.ЗаписатьОбъявлениеXML();

ЗаписьXML.ЗаписатьНачалоЭлемента("ДанныеТоваров");

// Пример обхода строк табличной части
Для Каждого СтрИз ТЧТовары Цикл
    ЗаписьXML.ЗаписатьНачалоЭлемента("Товар");
    ЗаписьXML.ЗаписатьАтрибут("Наименование", Строка(СтрИз.Товар));
    ЗаписьXML.ЗаписатьАтрибут("Количество", Строка(СтрИз.Количество));
    ЗаписьXML.ЗаписатьКонецЭлемента(); // Товар
КонецЦикла;

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

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

НовыйОбъект = Справочники.Тест.СоздатьЭлемент();
НовыйОбъект.Наименование = "Настройки ценника";
НовыйОбъект.ХранилищеТест = Новый ХранилищеЗначения(ТекстXML, Новый СжатиеДанных);
НовыйОбъект.Записать();

Чтение XML из реквизита ХранилищеЗначения

Для восстановления данных из справочника необходимо выполнить обратную операцию. Получаем содержимое из реквизита типа ХранилищеЗначения с помощью метода Получить() и загружаем полученную строку в объект ЧтениеXML методом УстановитьСтроку().

Рассмотрим пример последовательного чтения XML-строки:


Процедура ПрочитатьФайлXMLПоследовательно(ХранилищеТест)

    ТекстXML = ХранилищеТест.Получить();
    Если НЕ ЗначениеЗаполнено(ТекстXML) Тогда
        Возврат;
    КонецЕсли;

    ФайлXML = Новый ЧтениеXML;
    ФайлXML.УстановитьСтроку(ТекстXML);

    Пока ФайлXML.Прочитать() Цикл
        ИмяУзла = ФайлXML.Имя;
        ТипУзла = ФайлXML.ТипУзла;
        
        Если ТипУзла = ТипУзлаXML.НачалоЭлемента И ИмяУзла = "Товар" Тогда
            Наименование = ФайлXML.ПолучитьАтрибут("Наименование");
            Количество = ФайлXML.ПолучитьАтрибут("Количество");
            // Добавление строк в табличную часть формы
        КонецЕсли;
    КонецЦикла;

    ФайлXML.Закрыть();

КонецПроцедуры

Использование реквизита типа Строка неограниченной длины

Если для реквизита справочника использовать тип Строка (неограниченной длины) вместо ХранилищеЗначения, код станет еще проще. Это удобно при отладке, так как содержимое XML-структуры можно сразу посмотреть в режиме «1С:Предприятие» или в отладчике без вызова метода Получить().

Запись в строковый реквизит выполняется следующим образом:


НовыйОбъект = Справочники.Тест.СоздатьЭлемент();
НовыйОбъект.Наименование = "Настройки";
НовыйОбъект.ХМЛТест = ЗаписьXML.Закрыть(); // Метод Закрыть() возвращает строку XML
НовыйОбъект.Записать();

Чтение из строкового реквизита:


ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(СсылкаНаСправочник.ХМЛТест);

Обратите внимание: использование типа ХранилищеЗначения с включенным сжатием (Новый СжатиеДанных) предпочтительнее при хранении больших объемов данных, так как это снижает размер базы данных. Строка неограниченной длины удобнее для небольших документов и быстрой разработки.

Альтернативный способ: Сериализация XDTO

Если вам требуется сохранять данные именно в формате XML, но вы не хотите вручную прописывать каждый тег с помощью ЗаписатьНачалоЭлемента, используйте механизм СериализаторXDTO. Он позволяет автоматически превратить таблицу значений в XML и обратно.

Пример автоматической записи табличной части в XML:


ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();

// Выгружаем табличную часть в таблицу значений и сериализуем
ТаблицаДанных = Объект.Товары.Выгрузить();
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ТаблицаДанных);

СтрокаXML = ЗаписьXML.Закрыть();
НовыйОбъект.ХранилищеТест = Новый ХранилищеЗначения(СтрокаXML, Новый СжатиеДанных);
НовыйОбъект.Записать();

Пример чтения данных из XML с помощью СериализаторXDTO:


ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(СсылкаНаСправочник.ХранилищеТест.Получить());

ТаблицаДанных = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
Объект.Товары.Загрузить(ТаблицаДанных);

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

Прямое сохранение объектов без использования XML

Выясним важную деталь: если данные формируются и читаются исключительно внутри одной информационной базы 1С, использовать промежуточный формат XML вообще не обязательно. В ХранилищеЗначения можно записать напрямую таблицу значений, структуру или массив.

Сохранение таблицы значений напрямую:


// Запись таблицы значений в реквизит справочника
НовыйОбъект = Справочники.Тест.СоздатьЭлемент();
НовыйОбъект.Наименование = "Сохраненный список";
НовыйОбъект.ХранилищеТест = Новый ХранилищеЗначения(Объект.Товары.Выгрузить(), Новый СжатиеДанных);
НовыйОбъект.Записать();

Восстановление таблицы значений из хранилища:


// Чтение таблицы значений из справочника
ТаблицаТоваров = СсылкаНаСправочник.ХранилищеТест.Получить();
Если ТипЗнч(ТаблицаТоваров) = Тип("ТаблицаЗначений") Тогда
    Объект.Товары.Загрузить(ТаблицаТоваров);
КонецЕсли;

Прямое сохранение данных в ХранилищеЗначения является наиболее эффективным способом для работы внутри одной базы: оно выполняется быстрее, не требует обхода тегов и автоматически сохраняет точные типы данных 1С.

← На главную