1с прочитать xml из хранилища

Обновлено: 04.07.2024

С помощью механизма XDTO можно описать систему типов и значений, с помощью которой можно легко выполнить сериализацию/десериализацию в XML/JSON.

XDTO можно сравнить со схемой XML. С помощью механизма XDTO можно создать XML-схему, а потом на основании этой схемы сформировать XML-документ.

XDTO может применяться в следующих случаях:

  • Для описания типов параметров и возвращаемых значений Web-сервисов.
  • Для описания структуры данных, используемой при обмене с внешними системами (в том числе с другими базами на платформе 1С).
  • Для создания собственных типов и значений, используемых внутри конфигурации 1С.

Создание XDTO-пакета

В качестве примера рассмотрим следующую задачу: нужно настроить обмен документами между двумя различными конфигурациями на 1С. В обеих конфигурациях используются 2 типа документов: приходные и расходные накладные. Состав и наименование реквизитов в разных конфигурациях отличается.

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

XDTO

Есть корневой элемент Документ, который имеет 2 свойства: Тип и Состав. Состав включает в себя массив строк со свойствами: Номенклатура, Количество и Сумма.

Для описания данного формата будем использовать XDTO-пакет. XDTO-пакет можно сравнить со схемой XML, в нем мы укажем какие типы будут использоваться внутри пакета и каким образом они должны быть сериализованы в XML.

URI пространства имен

URI пространства имен

Добавим в пакет новый Тип объекта:

Тип объекта

В свойствах укажем Имя Документ:

Тип объекта

Это корневой узел нашего формата.

Свойство

В свойствах укажем Имя Тип:

Свойство

В данном свойстве будет строкой храниться тип выгружаемого документа. Поэтому нужно заполнить свойство Тип, чтобы при записи в XML платформа знала как нужно его сериализовать.

Чтобы заполнить тип сначала нужно нажать на зеленую галочку возле свойства:

Тип

Тип
Тип

Данный тип соответствует типу 1С Строка.

Тип

Добавим для объекта Документ еще одно свойство Состав, но тип пока заполнять не будем. Должно получиться так:

Тип объекта

Теперь добавим новый тип объекта Состав. Он будет использоваться для сериализации табличной части документа. Добавим для него одно свойство Строка, тип пока не будем указывать:

Тип объекта

Так как в табличной части может быть несколько строк, то для свойства Строка в свойстве Максимальное количество нужно указать -1 (предварительно нужно нажать на зеленую галку):

Максимальное количество

Это означает, что в данном свойстве может храниться неограниченное количество значений (аналогично массиву).

Теперь для свойства Документа Состав в качестве типа укажем только что созданный объект Состав. Чтобы его выбрать нужно развернуть пространство имен созданного нами XDTO-пакета:


Тип объекта

Тип объекта

Свойства
Свойства
Свойства

И наконец для свойства Строка объекта Состав укажем тип Строка (только что созданный нами тип объекта):

Свойства

На этом создание XDTO-пакета завершено. Для удобства переименуем его в Документ (нужно щелкнуть по пакету правой кнопкой, выбрать Свойства и изменить свойство Имя):

XDTO-пакет

Сериализация XDTO в XML

Теперь напишем простую процедуру для сериализации приходного документа в XML через механизм XDTO.

Сначала рассмотрим некоторые понятия, которые будут использоваться в процессе сериализации:

Возникала необходимость чтения обработки XML файлов неизвестной структуры, вот написал процедуры, которые преобразуют XML файл любой в дерево значений, а также считывают и преобразуют данные в переменную типа структура причем типы переменных преобразуются в соответствии с требованиями, Дата, Булево, Число, Строка

Возможно, что кому нибудь эти данные будут интересны

Тестировалась на платформе 1С:Предприятие 8.3 (8.3.15).

Конфигурация 1С не имеет значения.

Преобразование XML файла в переменную структура, Загрузка в дерево значений.:

Специальные предложения

Electronic Software Distribution

Интеграция 1С с системой Меркурий

Алкогольная декларация

Готовые переносы данных

54-ФЗ

Управление проектом на Инфостарте

Траектория обучения 1С-разработчика

Дерево значений это хорошо, но у меня основная цель стояла создать переменную структуры а не дерево значений, а так спасибо!

модуль ИнтеграцияВЕТИС, 1С:ERP Управление предприятием 2 (2.4.9.82)

// Преобразует объект XDTO в структуру
//
// Параметры:
// ОбъектXDTO - ОбъектXDTO - Объект XDTO.
//
// Возвращаемое значение:
// Структура - Структура объекта.
//
Функция ОбъектXDTOВСтруктуру(ОбъектXDTO, ПараметрыПреобразования = Неопределено) Экспорт

Структура = Новый Структура;
ТипОбъектаXDTO = ОбъектXDTO.Тип();

Для Каждого Свойство Из ОбъектXDTO.Свойства() Цикл

ИмяСвойства = Свойство.Имя;
ЗначениеСвойства = ОбъектXDTO[ИмяСвойства];

Если ТипЗнч(ЗначениеСвойства) = Тип("ОбъектXDTO") Тогда

Структура.Вставить(ИмяСвойства, ОбъектXDTOВСтруктуру(ЗначениеСвойства, ПараметрыПреобразования));

ИначеЕсли ТипЗнч(ЗначениеСвойства) = Тип("СписокXDTO") Тогда

Структура.Вставить(ИмяСвойства, Новый Массив);
Для Индекс = 0 По ЗначениеСвойства.Количество() - 1 Цикл

ЭлементСписка = ЗначениеСвойства.Получить(Индекс);
Если ТипЗнч(ЭлементСписка) = Тип("ОбъектXDTO") Тогда
Структура[ИмяСвойства].Добавить(ОбъектXDTOВСтруктуру(ЭлементСписка, ПараметрыПреобразования));
Иначе
Структура[ИмяСвойства].Добавить(ЭлементСписка);
КонецЕсли;

Если ПараметрыПреобразования <> Неопределено
И ПараметрыПреобразования.НайтиИдентификаторы
И Свойство.Тип = ПараметрыПреобразования.ТипUUID Тогда

РезультатПоиска = ПараметрыПреобразования.ТипыИдентификаторов[ТипОбъектаXDTO];
Если РезультатПоиска <> Неопределено
И РезультатПоиска.ИмяПоля = ИмяСвойства Тогда
ПараметрыПреобразования.Идентификаторы[РезультатПоиска.ИмяТаблицы].Вставить(ЗначениеСвойства, РезультатПоиска.ПустоеЗначение);
КонецЕсли;

А вы знали? 1С любит держать данные помещенные в ХранилищеЗначения в временном файле на диске? Разумеется имеется ввиду те данные, то лежат в памяти. Возможно, она так любит избавляться только от больших данных, но это уже совсем другая история.

Суть решения "проста", запакованное хранилище значения из себя представляет данные, запакованные алгоритмом Deflate (которая сама 1С использует везде, а доступа к методам дать не могут) и некоторое служебные данные. Этим же методом Deflate, упаковываются ZIP архивы. Итого весь процесс проводится к следующему:

1) Получение из хранилища значений двоичных данных (да-да, 1С не добавила возможности прямого получения):

2) Получаем буфер двоичных за вычетом префикса хранилища значения

3) Формируем структуру ZIP архива и добавляем к нему данные из буфера двоичных данных

4) Распаковать ZIP архив, игнорируя ошибки распаковки (так как у нас нет данных о CRC сумме НЕ запакованных данных, а так же об их размере)

5) На выходе, мы уже получаем распакованные данные, которые были помещены в хранилище значения, НО, они окружены структурой, похожей на JSON которая всюду используется в 1С как минимум с 1С 7.7 (или даже раньше), для того чтобы от неё избавится, надо в начале файла отрезать чуток и в конце, а так-же убрать экранирование кавычек. Тут я пробовал разные варианты (кроме считывания всего текста и СтрЗаменить, ибо память не безлимитная, но и такой способ работает и 1С не падает), но самым оптимальным как по скорости, так и по потреблению памяти, оказалось порционное чтение из файла, замена двойных кавычек на одинарные и запись в результирующий файл (выполняется мгновенно, пруфов нет)

7) Так же не забывайте убирать за собой, помогите сборщику мусора 1С, донесите свой мусор хотя бы до помойки:

Как и писалось в анонсе, данный способ не претендует на использование в продакшене (хотя мы у себя впилили, вместо ХранилищеЗначение.Получить() на проде), но надеюсь, данная публикация вам поможет, когда нужно через хранилище значения, передать много данных, а штатный механизм прожорлив или вообще падает (как в моём случае). Разумеется, вы бы сделали лучше чем я и код фактически один большой костыль.

Тем же, кто думает о своей реализации обмена данными через веб-сервис, я бы пожалуй посоветовал паковку в ZIP архив на сервере (можно даже в памяти это сделать, без записи на диск) и передавать двоичные данные, а на клиенте уже сохранить полученные двоичные данные на диск, а дальше можно использовать типовой механизм.

Выражаю благодарность автору обработки, которая сделала сказку - былью!
Если у вас есть лишние помидоры и яйца, то вспомните о голодающих ;)

PS: Прошу обратить внимание на то, что данная публикация, получает строку, помещенную в хранилище значение, если вы хотите таким образов получать другие типы данных помещенные в хранилище значение, вам явно придется вооружится напильником, но нет ничего не возможного!

PS: Так же надо учитывать, что данный способ медленней чем штатный способ получения значения! Обратите так же внимание, тестировать обработку лучше в файловой базе или хотя бы на 32-х битном сервере 1С, где есть техническое ограничение на потребляемую память. На 64-х битном сервере 1С, даже очень большие данные сможет получить. Да, обработка не демонстрирует проблему, а демонстрирует решение.

В связи с новым подходом в программировании на платформе 8.2 возникла необходимость передачи данных между клиентом и сервером при этом прямая передача в виде параметров имеет ряд ограничений. И тогда был введен объект «Временное хранилище».

Чем полезно временное хранилище:

  • Не надо создавать объекты в конфигурации
  • Доступно и с сервера и с клиента
  • Можно записать любой объект

Временное хранилище это не объект конфигурации, а объект платформы поэтому для разработчика он выглядит как черный ящик. Можно туда положить что-то получив псевдоним(адрес) и получить из него что-то указав псевдоним(адрес). Но узнать что находится во временном хранилище и сколько нельзя. В ниже рассмотренных примерах помещение в хранилище происходит на клиенте, а чтение на сервере. Хотя можно передавать данные и в обратном направлении.

Синтаксис работы с хранилищем простой:

Передав параметром, данные которые хотим поместить(Посылка) и УникальныйИдентификатор получаем Адрес, по которому потом можно будет обратиться. Причем передаваемый идентификатор не является получаемым в последствии адресом. Вместо идентификатора можно передать строку Адреса, по которому и будет помещено наше значение, но это не любая строка! Строка Адреса выглядит примерно вот так «e1cib/tempstorage/ae5c5472-0266-4892-9073-20392dd5a6a6» .

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

Чтобы получить из хранилища нужно только указать адрес:

Также можно удалить помещенный объект, используя адрес

Если помещаемые данные не являются объектами конфигурации, то для того чтобы их поместить нужно перевести в доступный тип - «ДвоичныеДанные»

Помещение в хранилище

Здесь мы сначала преобразуем файл в формат двоичных данных и только потом помещаем их в хранилище

Чтение из хранилища

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

Если мы имеем дело с файлами, то может оказаться удобным метод ПоместитьФайл. Он преобразует файл в двоичные данные и записывает их во ВременноеХранилище. При этом параметром можно настроить открытие диалогового окна для выбора файла. Сделаю оговорку, этот метод нельзя использовать на сервере.

В параметре Адрес, можно указать Адрес в который нужно записать файл, если нужен новый адрес, то нужно передать пустую строку.

Истина – открывает окно для выбора папки и имени файла, при значении Истина есть возможность открыть файл."КопияФайла.xml" – Имя файла под которым будет сохранен файл.Адрес – это адрес в хранилище,ПолучитьФайл(Адрес,"Копияфайла.xml" , Истина);Чтобы сохранить файл из временного хранилища на Клиенте можно использовать метод

Читайте также: