Экспорт данных из 1С в XML

Как данные из 1С сохранить в формате eXtensible Markup Language?

Когда мы говорим об экспорте данных из 1С в файл XML, то мы подразумеваем создание такого файла и помещение в него определённых данных.

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

Я для работы с XML файлами использую внешнюю компоненту V7Plus от фирмы 1С. Рассказывают, что есть и другие инструменты. Например, хвалят библиотеку MSXML от компании Microsoft. Но мне функционала V7Plus достаточно.

Подключение внешней компоненты

Итак, подключаем внешнюю компоненту V7Plus.

//универсальная функция в Глобальном модуле
Функция гЗагрузитьВнешнююКомпоненту(Файл,Имя) Экспорт
	//наличие файла
	Если ФС.СуществуетФайл(КаталогИБ()+Файл)=0 Тогда
		Сообщить("Не найден файл внешней компоненты "+Имя,"!");
		Возврат(0);
	КонецЕсли;
	//загрузка
	Флаг=ЗагрузитьВнешнююКомпоненту(КаталогИБ()+Файл);
	Если Флаг=0 Тогда
		Сообщить("Не загружена внешняя компонента "+Имя+". Запустите программу 1С:Предприятие в монопольном режиме","!");
	КонецЕсли;
	Возврат(Флаг);
КонецФункции

//в модуле
гЗагрузитьВнешнююКомпоненту("v7plus.dll","V7Plus");

Теперь создаём объект XMLParser, который в специальной литературе называют Парсер или Анализатор.

//анализатор
Попытка
	Анализатор=СоздатьОбъект("AddIn.XMLParser");
Исключение
	Сообщить("Не удалось создать объект Addin.XMLParser!");
	Возврат;
КонецПопытки;

Сейчас всё готово для создания нового документа XML.

Два метода записи XML документа

Но здесь нужно оговориться о том, что существуют два метода записи данных в XML документ:

  1. Прямая или последовательная запись
  2. Объектная запись

При последовательной записи данных в XML документ, данные записываются последовательно: строчка за строчкой, тэг за тэгом. При объектной записи сначала идёт создание объектов документа XML, и затем им приписываются характеристики.

Кратко выскажусь о достоинствах и недостатках указанных методов записи документа XML.

  • Последовательная запись работает только с одним объектом - с документом. Объектная запись создаёт множество объектов, что требует больше оперативной памяти.
  • Объектная запись более логична, а потому ошибиться сложнее. При последовательной записи можно, например, забыть закрыть открытый элемент, из-за чего документ XML будет признан некорректным.
  • Последовательная запись проще и где-то даже красивее.

Рассмотрим оба метода записи документа XML.

Последовательный метод записи документа XML

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

Для примера возьмём задачу написания XML запроса для отправки СМС сообщения через API.

Функция Смс_Создать(Анализатор)
	//путь
	Путь="C:\Temp\";
	//документ
	Д=Анализатор.СоздатьПоследовательноЗаписываемыйДокумент();
	Д.ИмяФайла=Путь;
	Д.Кодировка="UTF-8";
	//операция
	Д.ОткрытьЭлемент("request");
	Д.ВключитьЭлемент("operation","SENDSMS");
	//сообщение
	Д.АтрибутыЭлемента.УстановитьАтрибут("source",Отправитель.Наименование);
	Д.АтрибутыЭлемента.УстановитьАтрибут("lifetime",24);
	Д.АтрибутыЭлемента.УстановитьАтрибут("rate",120);
	Д.АтрибутыЭлемента.УстановитьАтрибут("desc","1Cv77");
	//время
	Если ФлагВремя=0 Тогда
		Д.АтрибутыЭлемента.УстановитьАтрибут("start_time","AUTO");
	Иначе
		Значение=Время_Получить();
		Д.АтрибутыЭлемента.УстановитьАтрибут("start_time",Значение);
	КонецЕсли;
	Д.АтрибутыЭлемента.УстановитьАтрибут("end_time","AUTO");
	Д.ОткрытьЭлемент("message");
	Д.АтрибутыЭлемента.УдалитьВсе();
	//тело
	Значение=СокрЛП(Тело);
	Д.ВключитьЭлемент("body",Значение);
	//номера
	Телефоны.ВыбратьСтроки();
	Пока Телефоны.ПолучитьСтроку()=1 Цикл
		Д.ВключитьЭлемент("recipient",Телефоны.Телефон);
	КонецЦикла;
	//закрытие
	Д.ЗакрытьЭлемент();
	Д.ЗакрытьЭлемент();
	Д.Сбросить();
	Д.Завершить();
	//получить содержимое файла
	Д=Анализатор.СоздатьПоследовательноСчитываемыйДокумент();
	Д.СвязатьСФайлом(Путь);
	Д.Спуститься();
	Текст=Д.ТекущийЭлементВВидеСтроки();
	//источник
	Источник="<?xml version='1.0' encoding='utf-8'?>";
	Источник=Источник+Текст;
	//возврат
	Возврат(Источник);
КонецФункции

Обращаю ваше внимание на методы Сбросить() и Завершить(). Метод Сбросить() используется только при последовательной записи документа. В описании пишут, что он записывает содержимое в выходной файл и очищает память. Да, наверно. Но доступ к созданному файлу будет заблокирован. Чтобы освободить файл, нужно использовать метод Завершить(). Кстати, в описании внешней компоненты V7Plus метода Завершить() нет, но он упоминается в одном из примеров.

Объектный метод записи документа XML

При объектной записи, в документе создаются объекты и им приписываются характеристики.

//получатель
Получатель=Сообщение.СоздатьПодчиненныйЭлемент("recipient");
Получатель.Значение=Телефоны.Телефон;

Как видите, сначала создался объект Получатель, а затем ему было присвоено значение. Всё понятно. Но вспомним, как эта же операция записывается при последовательной записи.

Д.ВключитьЭлемент("recipient",Телефоны.Телефон);

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

//получатель
Сообщение.СоздатьПодчиненныйЭлемент("recipient").Значение=Телефоны.Телефон;

Так кода меньше. Одной строчкой кода мы выполняем две операции: создание нового подчинённого элемента и присваивание ему значения. И если выше я писал, что недостатком объектной записи является повышенное использование оперативной памяти из-за создания большего количества объектов, то похоже, что при последнем способе написания кода расход оперативной памяти не увеличится, поскольку мы работаем с одним объектом.

В следующем примере я напишу код решения той же задачи по отправке СМС, только методом объектной записи.

Функция Смс_Создать(Анализатор)
	//путь
	Путь="C:\Temp\";
	//документ
	Д=Анализатор.СоздатьДокумент();
	Д.Кодировка="UTF-8";
	//операция
	Корень=Д.СоздатьПодчиненныйЭлемент("request");
	Корень.СоздатьПодчиненныйЭлемент("operation").Значение="SENDSMS";
	//сообщение
	Сообщение=Корень.СоздатьПодчиненныйЭлемент("message");
	Сообщение.УстановитьАтрибут("source",Отправитель.Наименование);
	Сообщение.УстановитьАтрибут("lifetime",24);
	Сообщение.УстановитьАтрибут("rate",120);
	Сообщение.УстановитьАтрибут("desc","1Cv77");
	//время
	Если ФлагВремя=0 Тогда
		Значение="AUTO";
	Иначе
		Значение=Время_Получить();
	КонецЕсли;
	Сообщение.УстановитьАтрибут("start_time",Значение);
	Сообщение.УстановитьАтрибут("end_time","AUTO");
	//тело
	Сообщение.СоздатьПодчиненныйЭлемент("body").Значение=СокрЛП(Тело);
	//телефоны
	Телефоны.ВыбратьСтроки();
	Пока Телефоны.ПолучитьСтроку()=1 Цикл
		Сообщение.СоздатьПодчиненныйЭлемент("recipient").Значение=Телефоны.Телефон;
	КонецЦикла;
	//запись
	Д.Записать(Путь);
	//тело
	Д=Анализатор.СоздатьДокумент();
	Д.Загрузить(Путь);
	Текст=Д.ЭлементДокумента.ПредставлениеXML;
	//источник
	Источник="<?xml version='1.0' encoding='utf-8'?>";
	Источник=Источник+Текст;
	//возврат
	Возврат(Источник);
КонецФункции

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

Текстовой метод записи документа XML

Ради справедливости следует сказать, что в некоторых случаях можно воспользоваться и третим методом записи документа XML. Такой метод записи я назвал текстовым. Он пишется так же, как вы пишете запросы. То есть переменной Запрос вы присваиваете блок текста, а в этом тексте прописываете команды XML запроса.

Текстовой метод, пожалуй, можно рекомендовать к использованию в случаях:

  1. Запрос короткий.
  2. Запрос не содержит переменных.
  3. Запрос не содержит выгрузку из массива.
  4. Запрос посылается в виде текстовой строки, а не файла.

Например, при работе с API по отправке СМС нужно послать запрос на получение баланса. Такой запрос короткий и не содержит переменных. Наверно, такой запрос проще написать текстом.

Функция Баланс_Создать()
	Возврат
	"<?xml version='1.0' encoding='utf-8'?>
	|<request>
	|<operation>GETBALANCE</operation>
	|</request>";
КонецФункции

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

Функция Баланс_Создать()
	//путь
	Путь="C:\Temp\sms_balance.xml";
	//текст
	Текст=
	"<?xml version='1.0' encoding='utf-8'?>
	|<request>
	|<operation>GETBALANCE</operation>
	|</request>";
	//файл
	Т=СоздатьОбъект("Текст");
	Т.ДобавитьСтроку(Текст);
	Т.Записать(Путь);
	//возврат
	Возврат(Путь);
КонецФункции

Текстовой метод записи XML запроса можно использовать даже в случае, когда требуется выгрузка из массива, которым может быть список значений или таблица значений. В следующем примере я покажу код той же задачи по составлению запроса на отсылку СМС, но с использованием текстовой записи.

Функция Смс_Создать()
	//время отправки
	Если ФлагВремя=0 Тогда
		НачВремя="AUTO";
	Иначе
		НачВремя=Время_Получить();
	КонецЕсли;
	//запрос
	Запрос=
	"<?xml version='1.0' encoding='utf-8'?>
	|<request>
	|<operation>SENDSMS</operation>
	|<message start_time="+НачВремя+" end_time='AUTO' lifetime='4' rate='120' desc='1Cv77' source="+Отправитель.Наименование+">
	|<body>"+СокрЛП(Тело)+"</body>";
	//телефоны
	Телефоны.ВыбратьСтроки();
	Пока Телефоны.ПолучитьСтроку()=1 Цикл
		Запрос=Запрос+"
		|<recipient>"+Телефоны.Телефон+"</recipient>";
	КонецЦикла;
	Запрос=Запрос+"
	|</message>
	|</request>";
	//возврат
	Возврат(Запрос);
КонецФункции

Лично я текстовой метод записи для написания сложных запросов использовать не смогу, потому что при этом в коде вообще ничего понять нельзя, а потом ошибок не оберёшься. Тем не менее, такой запрос тоже будет работать.

Реклама:
Смотрите также:
Учёт комиссионной торговли в программе 1С
Порядок сортировки, установленный в базе данных, отличается от системного?
Отчёты администратора для обслуживания 1С
Скачать программы для 1С