Выполнение выгрузки данных в узел в 1С

Категория: Учебники по 1С » Технологии интеграции 1С Предприятия 8.2

В обработке выбирается узел обмена. Ссылка на выбранный узел сохраняется в реквизите обработки Узел, имеющем тип ПланОбменаСсылка. УдаленныеСклады. Затем в процедуре выгрузки данных из этой ссылки получается объект ПланОбмена и вызывается метод ЗаписатьСообщенияСИзменениями() этого объекта, реализующий, собственно, сам процесс выгрузки данных.

 

В процедуре ЗаписатьСообщенияСИзменениями(), определенной в модуле плана обмена, производится вызов процедур и функций, которые решают следующие задачи:

  • получение имени файла по заранее установленным правилам (известным на принимающей стороне);
  • вызов функции, в которой производится запись сообщения в файл с именем, переданным в качестве параметра; к вызов процедуры, осуществляющей доставку файла по указанному пути;
  • удаление сформированного файла.

Процедура ЗаписатьСообщениеСИзменениями() Экспорт
// Формируем имя временного файла
ИмяФайла = КаталогВременныхФайлов() + "\" + 
ОбменСУдаленнымиСкладами.ПолучитьИмяФайлаОбмена(ПланыОбмена.УдаленныеСклады.ЭтотУзел(), Ссылка, "_W");
Сообщение = Новый СообщениеПользователю();
Сообщение.Текст = "-------- Выгрузка в узел " + Строка(ЭтотОбъект) + " ------------";
Сообщение.Сообщить();
// Записываем новое сообщение обмена в файл
НомерСообщения = ЗаписатьНовоеСообщение(ИмяФайла);
// Публикуем файл с сообщением обмена
ОпубликоватьФайлОбмена(ИмяФайла, НомерСообщения);
Попытка
// Удаляем файл с сообщением обмена
УдалитьФайлы(ИмяФайла);
Исключение
КонецПопытки;
Сообщение.Текст = "-------- Конец выгрузки------------";
Сообщение.Сообщить();
   
КонецПроцедуры 
Функция ПолучитьИмяФайлаОбмена( ) расположенная в общем модуле ОбменСУдаленнымиСкладами, собирает имя файла из ключевого слова Message, добавляя код узла источника и приемника. У файла определяется расширение XML:
Функция ПолучитьИмяФайлаОбмена(УзелИсточник, УзелПриемник, Постфикс = "") Экспорт
// формируем имя файла, исходя из кодов источника и приемника сообщения обмена
Возврат "Message" + СокрЛП(УзелИсточник.Код) + "_" + СокрЛП(УзелПриемник.Код) + СокрЛП(Постфикс) + ".xml";
КонецФункции 
В функции ЗаписатьНовоеСообщение () (листинг 2.29) в XML-файл с переданным в качестве параметра именем начинается запись данных. Для сокращения размера файла сообщения первоначально определяется соответствие используемым пространствам имен. Создается новое сообщение, производится выборка изменений. Функция определена в модуле плана обмена, ссылка на узел-получатель получается из контекста выполнения функции (одноименное свойство Ссылка).
Выбранные данные с помощью вызова функции НуженПереносДанных() (листинг 2.30) проверяются на необходимость выгрузки. В случае если выгрузка производится, вызываются процедуры ЗаписатьДанные() (листинг 2.31) и ВывестиДанные () (листинг 2.32). В противном случае вызывается процедура УдалениеДанных() (листинг 2.33). Все моменты, связанные с интерфейсной частью механизма (вывод информационных сообщений), выполняются только на стороне клиента (отмечено директивами препроцессора).
Функция ЗаписатьНовоеСообщение(ИмяФайла)
НомерСообщения = 0;
// Создаем объект записи XML
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(ИмяФайла);
ЗаписьXML.ЗаписатьОбъявлениеXML();
// Создаем новое сообщение
ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();
ЗаписьСообщения.НачатьЗапись(ЗаписьXML, Ссылка);
// Для сокращения размера файла сообщения записываем соответствие пространств имен
ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("xsd", "http://www.w3.org/2001/XMLSchema");
ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("xsi", "http://www.w3.org/2001/XMLSchema-instance");
ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("v8", "http://v8.1c.ru/data");
НомерСообщения = ЗаписьСообщения.НомерСообщения;
Сообщение = Новый СообщениеПользователю();
Сообщение.Текст = "    Номер сообщения: " + НомерСообщения;
Сообщение.Сообщить();
// Получаем выборку изменённых данных
Счетчик = 0;
ВыборкаИзменений = ПланыОбмена.ВыбратьИзменения(ЗаписьСообщения.Получатель, НомерСообщения);
Пока ВыборкаИзменений.Следующий() Цикл
Данные = ВыборкаИзменений.Получить();
#Если Клиент Тогда
Счетчик = Счетчик + 1;
Состояние("Выгрузка данных: " + Строка(Счетчик));
#КонецЕсли
// Если перенос данных не нужен, то, возможно, необходимо записать удаление данных
Если Не НуженПереносДанных(Данные) Тогда
// Получаем значение с возможным удалением данных
УдалениеДанных(Данные); 
КонецЕсли;
// Записываем данные в сообщение
ЗаписатьДанные(ЗаписьXML, Данные);
#Если Клиент Тогда
// Выводим диагностическое сообщение о записанных данных
ВывестиДанные(Данные);
#КонецЕсли
КонецЦикла;
// Завершаем запись сообщения
ЗаписьСообщения.ЗакончитьЗапись();
ЗаписьXML.Закрыть();
Возврат НомерСообщения;
КонецФункции
Функция НуженПереносДанных() (см. листинг 2.30) реализует стратегию распространения данных. Документы ПриходнаяНакладная и РасходнаяНакладная (и соответствующие им наборы записей регистра накопления) выгружаются только в случае, если значение реквизита Склад документом (и наборов записей регистра накопления) совпадают по значению с одно-именным реквизитом, определенным для узла получателя.
Для набора записей регистра накопления производится проверка на то, что во всех записях используется один склад. Данная проверка может и не проводиться, если такая ситуация изначально не может встретиться.
Функция НуженПереносДанных(Данные)
Перенос = Истина;
Если ТипЗнч(Данные) = Тип("ДокументОбъект.ПриходнаяНакладная") 
ИЛИТипЗнч(Данные) = Тип("ДокументОбъект.РасходнаяНакладная") Тогда
// Проверяем, что у документов склад совпадает  
Если Не Склад.Пустая() И Данные.Склад <> Склад Тогда
Перенос = Ложь;
КонецЕсли;
ИначеЕсли ТипЗнч(Данные) = Тип("РегистрНакопленияНаборЗаписей.УчетНоменклатуры") Тогда
// Проверяем, что у записей набора склад совпадает
СкладНабора = Неопределено;
Для Каждого Запись Из Данные  Цикл
Если СкладНабора <> Неопределено И Запись.Склад <> СкладНабора Тогда
ВызватьИсключение "Склад должен быть одинаковый для всех записей";
КонецЕсли;
СкладНабора = Запись.Склад;
КонецЦикла;
Если Не Склад.Пустая() И СкладНабора <> Склад Тогда
Перенос = Ложь;
КонецЕсли;
КонецЕсли;
Возврат Перенос;
КонецФункции
Рассматриваемый механизм выгрузки данных относится в разряду универсальных и подразумевает, что обмен данных производится между конфигурациями, имеющими разную структуру. В процедуре Записать Данные () (см. листинг 2.31) производится разделение данных на те, которые выгружаются в индивидуальном порядке (в нашем случае это элементы справочника Номенклатура) и с помощью метода платформы ЗаписатьХМL().
Процедура ЗаписатьДанные(ЗаписьXML, Данные)
Удаление = ?(ТипЗнч(Данные) = Тип("УдалениеОбъекта"), Истина, Ложь);
// Получаем объект описания метаданного, соответствующий данным
ОбъектМетаданных = ?(Удаление, Данные.Ссылка.Метаданные(), Данные.Метаданные());
// Если выгружаемыми данными является Справочник.Номенклатура, то его выгружаем вручную
Если Не Удаление И ОбъектМетаданных = Метаданные.Справочники.Номенклатура Тогда
// Записываем элемент справочника вручную
НоменклатураЗаписатьXML(ЗаписьXML, Данные);
Иначе
// Записываем данные с помощью стандартного метода
ЗаписатьXML(ЗаписьXML, Данные);
КонецЕсли;
КонецПроцедуры
Текст процедуры, производящей вывод диагностических сообщений, приведен ниже:
Процедура ВывестиДанные(Данные)
Перем Представление;
Если ТипЗнч(Данные) = Тип("УдалениеОбъекта") Тогда
Представление = "Удаление объекта: " + Строка(Данные.Ссылка.Метаданные()) + ": " + Строка(Данные.Ссылка);
Иначе
Представление = Строка(Данные.Метаданные()) + ": " + Строка(Данные);
КонецЕсли;
Сообщение = Новый СообщениеПользователю();
Сообщение.Текст = "- " + Представление;
Сообщение.Сообщить();
КонецПроцедуры
Если данные (полученные при выборке изменений) не подлежат выгрузке в текущий узел плана обмена, производится вызов процедуры УдалениеДанных() (см. листинг 2.33).
В данной процедуре для данных, имеющих объектную природу, создается объект УдалениеОбъекта. Этим достигается удаление в узле-приемнике ранее неправильно отосланных данных. Наборы записей регистров очищаются.
Процедура УдалениеДанных(Данные) 
// Получаем объект описания метаданного, соответствующий данным
ОбъектМетаданных = ?(ТипЗнч(Данные) = Тип("УдалениеОбъекта"), Данные.Ссылка.Метаданные(), Данные.Метаданные());
Если Метаданные.Справочники.Содержит(ОбъектМетаданных)
ИЛИ Метаданные.Документы.Содержит(ОбъектМетаданных)
ИЛИ Метаданные.ПланыСчетов.Содержит(ОбъектМетаданных)
ИЛИ Метаданные.ПланыВидовРасчета.Содержит(ОбъектМетаданных)
ИЛИ Метаданные.ПланыВидовХарактеристик.Содержит(ОбъектМетаданных) Тогда
// Перенос удаления объекта для объектных
Данные = Новый УдалениеОбъекта(Данные.Ссылка);
ИначеЕсли Метаданные.РегистрыСведений.Содержит(ОбъектМетаданных)
ИЛИ Метаданные.РегистрыНакопления.Содержит(ОбъектМетаданных)
ИЛИ Метаданные.РегистрыБухгалтерии.Содержит(ОбъектМетаданных)
ИЛИ Метаданные.РегистрыРасчета.Содержит(ОбъектМетаданных)
ИЛИ Метаданные.РегистрыРасчета.Содержит(ОбъектМетаданных.Родитель)
ИЛИ Метаданные.Последовательности.Содержит(ОбъектМетаданных) Тогда
// Очищаем данные
Данные.Очистить();
КонецЕсли;
КонецПроцедуры
С помощью процедуры ОпубликоватьФайлОбмена() (листинг 2.34) полученный в результате XML-документ может быть выложен на FTP- сервер либо на ресурс локальной сети. Имя ресурса определено в реквизите АдресОбмена. Для того чтобы была возможность отправлять файл, используя схемы FTP, HTTP, HTTPS, в пути приемника производится замена символов «\» на «/».
Процедура ОпубликоватьФайлОбмена(ИмяФайла, НомерСообщения)
ИмяФайлаСообщения = ОбменСУдаленнымиСкладами.ПолучитьИмяФайлаОбмена(ПланыОбмена.УдаленныеСклады.ЭтотУзел(), Ссылка, 
Формат(НомерСообщения, "ЧЦ=10; ЧВН=; ЧГ=0"));
Путь = СтрЗаменить(АдресОбмена, "\", "/");
Сообщение = Новый СообщениеПользователю();
// Копируем файл в каталог, определенный для данного узла
Попытка
КопироватьФайл(ИмяФайла, Путь + ?(Прав(Путь, 1) = "/", "", "/") + ИмяФайлаСообщения);
Исключение
Сообщение.Текст = " - Ошибка публикации файла: " + ИмяФайлаСообщения;
Сообщение.Сообщить();
Сообщение.Текст = ОписаниеОшибки();
Сообщение.Сообщить();
Возврат;
КонецПопытки;
Сообщение.Текст = " - Опубликован файл: " + ИмяФайлаСообщения;
Сообщение.Сообщить();
КонецПроцедуры 
При публикации файла его имя формируется из слова Message, кода узла-отправителя (предопределенного узла (ПланыОбмена .УдаленныеСклады. ЭтотУзел ())), кода узла-получателя и номера отправляемого сообщения (номер представлен в формате целого числа из 10 цифр).
Из вышеуказанной процедуры производится возврат в процедуру ЗаписатьСообщениеСИзменениямиО (см. листинг 2.27), после завершения которой процесс выгрузки завершается.
dle

Помоги проекту! Расскажи друзьям о сайте: