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

Столкнулся с проблемой передачи файла с клиента на сервер и обратно для выгрузки и загрузки данных в XML.
Много примеров для выгрузки/загрузки, но не встретил ни одного, где описывался бы механизм передачи файла на сервер и обратно

Стоит следующая задача. В рабочей базе неведомым образом очистились данные реквизита НомерСчета у справочника БанковскиеСчета, необходимо восстановить данные. В копии эти данные имеются. Так что задача проста, выгрузить данные в XML из копии и загрузить эти данные в рабочую базу. Решил использовать [code]ЗаписьXML[/code] и [code]ЧтениеXML[/code], так как решение задачи при помощи этиъх методов показалось мне самым быстрым способом.

Так как операция одноразовая, то пусть к файлу можно было бы указать сразу в коде, но решил, что хорошо было бы выбирать файл, в который выгружать данные и файл, из которого эти данные, соответственно, загружать. И тут столкнулся с очевидной проблемой: выбираю файл на клиенте, на сервере этого файла нет. [code]ЗаписьXML[/code] доступна на клиенте, но нельзя передать на сервер. Поэтому очевидное решение — надо использовать временное хранилище, куда помещать файл на клиенте, а на сервере из временного хранилища мы уже будет получать этот файл, заполнять его и снова помещать в хранилище, чтобы записать его на клиенте.

Выгрузка в XML:

Клиент: Выбрать файл — Поместить файл во временное хранилище

Сервер: Получить файл из временного хранилища — записать файл в каталог временных файлов — заполнить файл данными — поместить файл во временное хранилище- удалить файл из каталога временных файлов

Клиент: Получить файл из временного хранилище — записать файл

Загрузка из XML:

Клиент: Выбрать файл — Поместить файл во временное хранилище

Сервер: Получить файл из временного хранилища — записать файл в каталог временных файлов — загрузить данные — удалить файл из каталога временных файлов


&НаКлиенте
Процедура ВыгрузитьСчета(Команда)

//Открываем форму выбора каталога для сохранения файла
ОписаниеОповещения = Новый ОписаниеОповещения("ПослеВыбораКаталогаСохраненияФайла", ЭтаФорма);
ОткрытьФорму("ВнешняяОбработка._ГУОВ_ВыгрузкаЗагрузкаБанковскихСчетовXML.Форма.ФормаВыбораФайла", Новый Структура("Направление", "Выгрузка"),ЭтаФорма,,ВариантОткрытияОкна.ОтдельноеОкно,, ОписаниеОповещения, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);

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

&НаСервереБезКонтекста
Функция ВыгрузитьСчетаНаСервере(АдресХранилища, ИмяФайла)

//Получаем из временного хранилища файл, который будем заполнять
ДД = ПолучитьИзВременногоХранилища(АдресХранилища);

//Запишем временный файл в каталог временных файлов
Путь = КаталогВременныхФайлов();
ДД.Записать(Путь+ИмяФайла);

Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| БанковскиеСчета.Ссылка,
| БанковскиеСчета.НомерСчета,
| БанковскиеСчета.Наименование
|ИЗ
| Справочник.БанковскиеСчета КАК БанковскиеСчета
|ГДЕ
| БанковскиеСчета.ЭтоГруппа
| И НЕ БанковскиеСчета.ПометкаУдаления";

РезультатЗапроса = Запрос.Выполнить().Выгрузить();

ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(Путь+ИмяФайла);
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписьXML.ЗаписатьНачалоЭлемента("Справочник");

Счетчик = 0;
Для каждого Строка Из РезультатЗапроса Цикл

Если ЗначениеЗаполнено(Строка.НомерСчета) Тогда
ЗаписьXML.ЗаписатьНачалоЭлемента("Элемент");
ЗаписьXML.ЗаписатьАтрибут("Ссылка", ЗначениеВСтрокуВнутр(Строка.Ссылка));
ЗаписьXML.ЗаписатьАтрибут("Наименование", Строка.Наименование);
ЗаписьXML.ЗаписатьАтрибут("НомерСчета", Строка.НомерСчета);
ЗаписьXML.ЗаписатьКонецЭлемента();
Счетчик = Счетчик + 1;
КонецЕсли;

КонецЦикла;
Сообщить("" + Счетчик);
ЗаписьXML.ЗаписатьКонецЭлемента();
ЗаписьXML.Закрыть();

//После заполнения файла помещаем его во временное хранилище
ДвД = Новый ДвоичныеДанные(Путь+ИмяФайла);
АдресВрХранилищца = ПоместитьВоВременноеХранилище(ДвД);
УдалитьФайлы(Путь, ИмяФайла);
Возврат АдресВрХранилищца;

КонецФункции

&НаКлиенте
Процедура ЗагрузитьСчета(Команда)

//Открываем форму выбора файла
ОписаниеОповещения = Новый ОписаниеОповещения("ПослеВыбораКаталогаСохраненияФайла", ЭтаФорма);
ОткрытьФорму("ВнешняяОбработка._ГУОВ_ВыгрузкаЗагрузкаБанковскихСчетовXML.Форма.ФормаВыбораФайла", Новый Структура("Направление", "Загрузка"),ЭтаФорма,,ВариантОткрытияОкна.ОтдельноеОкно,, ОписаниеОповещения, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);

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

&НаСервереБезКонтекста
Процедура ЗагрузитьСчетаНаСервере(АдресХранилища, ИмяФайла)

//Получаем файл из хранилища и записываем его в каталог временных файлов
ДД = ПолучитьИзВременногоХранилища(АдресХранилища);
Путь = КаталогВременныхФайлов();
ДД.Записать(Путь+ИмяФайла);

Чтение = Новый ЧтениеXML;
Каталог = КаталогВременныхФайлов();
ИмяФайла = Путь+ИмяФайла;

Чтение.ОткрытьФайл(ИмяФайла);

Счетчик = 0;
НачатьТранзакцию();

Пока Чтение.Прочитать() Цикл

Если Чтение.Имя = "Элемент" Тогда

Ссылка = ЗначениеИзСтрокиВнутр(Чтение.ПолучитьАтрибут("Ссылка"));
НомерСчета = Чтение.ПолучитьАтрибут("НомерСчета");
Наименование = Чтение.ПолучитьАтрибут("Наименование");

Если ЗначениеЗаполнено(Ссылка.НомерСчета) Тогда
Продолжить;
КонецЕсли;

Попытка
СчетОбъект = Ссылка.ПолучитьОбъект();
СчетОбъект.НомерСчета = НомерСчета;
СчетОбъект.Записать();
Счетчик = Счетчик + 1;
Исключение
Сообщить("" + Наименование);
КонецПопытки;
КонецЕсли;
КонецЦикла;
ЗафиксироватьТранзакцию();
Чтение.Закрыть();
УдалитьФайлы(Путь, ИмяФайла);

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

// <Описание процедуры>
//
// Параметры:
// ПараметрыОбработки - Структура - направление выгрузки и каталог либо файл
//
&НаКлиенте
Процедура ПослеВыбораКаталогаСохраненияФайла(ПараметрыОбработки, Параметр2) Экспорт

//Общая процедура обработки выбора для выгрузки/загрузки
Если ПараметрыОбработки = Неопределено Тогда
Возврат;
КонецЕсли;

Если ПараметрыОбработки.Направление = "Выгрузка" Тогда
//Создание файла xml в выбранном каталоге
ИмяФайла = "unloading.xml";
ПолноеИмяФайла = ПараметрыОбработки.КаталогФайл + "" + ИмяФайла;
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(ПолноеИмяФайла);
ЗаписьXML.Закрыть();
Сообщить("Создан файл выгрузки: " + ПолноеИмяФайла);

//Помещаем файл во временное хранилище
ДД = Новый ДвоичныеДанные(ПолноеИмяФайла);
Адрес = ПоместитьВоВременноеХранилище(ДД);

//На сервере осуществляем заполнение файла
АдресХранилища = ВыгрузитьСчетаНаСервере(Адрес, ИмяФайла);

//Получаем из хранилища заполненный файл и записываем его на клиентском компьютере
ДвД = ПолучитьИзВременногоХранилища(АдресХранилища);
ДвД.Записать(ПолноеИмяФайла);
Иначе
//Загружаем данные из xml
ПолноеИмяФайла = ПараметрыОбработки.КаталогФайл;

//Помещаем файл во временное хранилище
ДД = Новый ДвоичныеДанные(ПолноеИмяФайла);
Адрес = ПоместитьВоВременноеХранилище(ДД);

//Обрабатываем файл на сервере
ЗагрузитьСчетаНаСервере(Адрес, ПолноеИмяФайла);
КонецЕсли;

КонецПроцедуры // ПослеВыбораКаталогаСохраненияФайла()

6 Comments

  1. Поручик

    Не могу понять, какая проблема с передачей туда-сюда. Механизм и так понятен из примеров. Смотрим управляемую форму Универсальный обмен данными XML.

    Reply
  2. Aphanas

    Помещение пустого файла во временное хранилище при выгрузке — совершенно лишняя операция.

    Reply
  3. Probot1c

    Батник написал на копирование и все

    Reply
  4. Anchoret

    (1) с примерами-то как раз и была проблема, не мог найти ничего подходящего.

    (2) согласен, можно выбрать каталог для сохранения, а с сервера уже достать файл и записать его на клиенте. Пятница была, соображал уже плохо=)

    Reply
  5. Aphanas

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

    Reply
  6. KereberoS

    (3) батник на копирование? Вы вообще не понимаете, что такое клиент-серверное программирование?

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *