При
любом внедрении 1С на действующем
предприятии, первоочередной становится
задача по переносу данных в новую
программу. Платформа предоставляет
несколько возможностей для этого: DBF,
XML, COM соединение, OLE. В
этом посте я остановлюсь на XML, из
основных преимуществ данного подхода
это универсальность (данные могут быть
выгружены из различных программ),
относительно более быстрая скорость
обработки, по сравнению скажем с DBF,
возможность полного переноса
документа, справочника и т. п. в другую
базу (стоит упомянуть, что это более
менее корректно работает с одинаковыми
конфигурациями в ином случаи придется
«допиливать»).
Процитирую
википедию. 
XML —
это описанная в текстовом
формате иерархическая
структура, предназначенная для хранения
любых данных. Визуально структура может
быть представлена как дерево элементов.
Элементы XML описываются тегами.
Т.е. Документы, справочники
и другие объекты конфигурации могут
быть представлены в виде структуры:
<Сотрудник Код="0000000136"
ВидЗанятости="ОсновноеМестоРаботы"
ВидДоговора="ТрудовойДоговор">Зыбченко
Алексей Александрович</Сотрудник>
данная строка состоит
из атрибутов: Код, ВидЗанятости, у каждого
атрибута свое значение в качестве текста
в строке использовано ФИО сотрудника,
но мы можем обойтись и без текста, просто
переместив ФИО сотрудника в атрибут.
Для считывания/записи атрибутов, текстов,
узлов в платформе 1С предусмотрены
специальные функции.
Стоит сказать еще пару
слов о структуре. Структура всего XML
документа представлет
из себя следующее (рис. 1).
В документе
обязательно должен присутствовать
корневой узел, в который входят остальные
узлы. Порядок обхода следующий, получаем
значение 1 узла, проходим все его атрибуты
и идем к следующему узлу, т. е.
осуществляем последовательный обход
все узлов. Разберем кое что на примерах.
Перенос
документа из одной базы в другую.
Выполним
выгрузку следующей обработкой:
ЗаписьXML
= Новый ЗаписьXML();
//Создадим объект класса
XML
ЗаписьXML.ОткрытьФайл(«c:\doc.xml»);
//Если файла нет то он будет автоматически
создан, если существует то будет
перезаписан
ЗаписьXML.ЗаписатьНачалоЭлемента(«Root»);
//записываем корневой элемент
ВыгружаемыйОбъект
= Документ.ПолучитьОбъект();
ЗаписатьXML(ЗаписьXML,
ВыгружаемыйОбъект); //Записываем
нащ док в XML
ЗаписьXML.ЗаписатьКонецЭлемента();
//Конец узла Root
ЗаписьXML.Закрыть();
//Ну и записываем
Для загрузки
код такой:
ЧтениеXML
= Новый ЧтениеXML(); //Создаем
объект из класса ЧтениеXML
ЧтениеXML.ОткрытьФайл(«c:\doc.xml»);
//Открываем файл
ЧтениеXML.Прочитать();
//Эта функция чаще всего выполняется в
цикле, здесь мы прочитали узел Root
ЧтениеXML.Прочитать();
//Переходим к узлу с документом
Если
ВозможностьЧтенияXML(ЧтениеXML)
Тогда //Проверяем соответствует ли тип
в документе тип данных в платформе
ЗагружаемыйОбъект
= ПрочитатьXML(ЧтениеXML);
//Считывает данные
ЗагружаемыйОбъект.Записать();
//записываем наш документ
КонецЕсли;
ЧтениеXML.Закрыть();
Повторюсь данный
метод хорошо работает только в одинаковой
конфигурации.
Перенос
произвольной структуры.
Чаще
всего при переносе данных, получается
так что нельзя однозначно сопоставить
выгруженный документ/справочник, решение
проблемы заключается в выгрузке документа
произвольной структуры.
Разберем
опять на листинге. В примере мне был
необходимо перенести справочник
сотрудников, из ЗУП в УПП. Справочники
Организации, ПодразделенияОрганизаций,
ДолжностиОргаизаций, ФизическиеЛица
уже заполнены. Новые сотрудники так же
должны иметь одинаковый код. Листинг
слегка сократил. Документ XML
должен представлять из себя:
<?xml
version="1.0" encoding="UTF-8"?>
<Root>
 <Сотрудник
Код="0000000531" ФизлицоКод="0000000531"
ПодразделениеОрганизацииКод="000000018">Зыбченко
Алексей Александрович</Сотрудник> 
</Root>
Присутствует
корневой узел Root и узел
Сотрудник с атрибутами Кода,  ФизлицоКод,
 ПодразделениеОрганизацииКод, а ФИО
использовал в качестве текста в теге.
Процедура
Кнопка1Нажатие(Элемент) //Выгрузка сотр
//Делаем
запрос к справочнику сотрудника
 Запрос
= Новый Запрос;
 Запрос.Текст
= 
 "ВЫБРАТЬ
 | СотрудникиОрганизаций.Код,
 | СотрудникиОрганизаций.Наименование,
 | СотрудникиОрганизаций.Физлицо.Код,
 | СотрудникиОрганизаций.ПодразделениеОрганизации.Код,
 |ИЗ
 | Справочник.СотрудникиОрганизаций
КАК СотрудникиОрганизаций
 |ГДЕ
 | СотрудникиОрганизаций.ДатаУвольнения
= &ДатаУвольнения";
 Запрос.УстановитьПараметр("ДатаУвольнения",
Дата("00010101"));
 Результат
= Запрос.Выполнить();
 ВыборкаДетальныеЗаписи
= Результат.Выбрать();
 Файл
= Новый ЗаписьXML; //Создаем объект для
записи XML
 Файл.ОткрытьФайл("C:\temp\uploadsot.xml");
//Файл с данными
 Файл.ЗаписатьОбъявлениеXML();
//Объявление обязательно!
 Файл.ЗаписатьНачалоЭлемента("Root");
//Пишем корневой элемент
 Пока
ВыборкаДетальныеЗаписи.Следующий()
Цикл //В цикле выводим  данные в XML
   Файл.ЗаписатьНачалоЭлемента("Сотрудник");
   Файл.ЗаписатьАтрибут("Код",
ВыборкаДетальныеЗаписи.Код); // Записываем
атрибут и его значение
   Файл.ЗаписатьАтрибут("ФизлицоКод",
ВыборкаДетальныеЗаписи.ФизлицоКод);
   Файл.ЗаписатьАтрибут("ПодразделениеОрганизацииКод",
ВыборкаДетальныеЗаписи.ПодразделениеОрганизацииКод);   Файл.ЗаписатьТекст(ВыборкаДетальныеЗаписи.Наименование);
   Файл.ЗаписатьКонецЭлемента();
 КонецЦикла;
 Файл.ЗаписатьКонецЭлемента();
 Файл.Закрыть();
//Записываем файл
КонецПроцедуры
Процедура
для загрузки. Листинг сокращен.
Процедура
ЗагрузитьСотрудникиНажатие(Элемент)
 Файл
= Новый ЧтениеXML;
 Файл.ОткрытьФайл("C:\temp\uploadsot.xml");
 Пока
Файл.Прочитать() Цикл //Проход по узлам
  Если
Файл.Имя <> "Сотрудник" Тогда
//Не проходим узел Root
   Продолжить;  
  КонецЕсли;
  Если
Файл.ТипУзла = ТипУзлаXML.НачалоЭлемента
Тогда 
   //Если
начало элемента то читаем атрибуты в
цикле
   Пока
Файл.ПрочитатьАтрибут() Цикл
    Если
Файл.Имя = "Код" Тогда //Проверяем
имя узла
     Код
= Файл.Значение; 
    ИначеЕсли
Файл.Имя = "ФизлицоКод" Тогда
     ФизлицоКод
= Файл.Значение;
    ИначеЕсли
Файл.Имя = "ПодразделениеОрганизацииКод"
Тогда
     ПодразделениеОрганизацииКод
= Файл.Значение;
    КонецЕсли;
   КонецЦикла;
//Если
в справочнике нет элемента то запишем
его    
   Если
НЕ
ЗначениеЗаполнено(Справочники.СотрудникиОрганизаций.НайтиПоКоду(Код))
Тогда 
    Сотрудник
= Справочники.СотрудникиОрганизаций.СоздатьЭлемент();
    Сотрудник.Код
= Код;
    Сотрудник.Физлицо
= Справочники.ФизическиеЛица.НайтиПоКоду(ФизлицоКод);
    Сотрудник.ПодразделениеОрганизации
=
Справочники.ПодразделенияОрганизаций.НайтиПоКоду(ПодразделениеОрганизацииКод);
    Если
Файл.Прочитать() Тогда //Поскольку текст
не атрибут а другой узел то перейдем к
нему
     //Проверяем
тип узла и пишем
     Если
Файл.ТипУзла = ТипУзлаXML.Текст Тогда
      Сотрудник.Наименование
= Файл.Значение;
      Сотрудник.Записать();
     Иначе
      Сообщить("Ошибка
формата");
      Возврат;
     КонецЕсли;
    КонецЕсли;
   КонецЕсли;
  КонецЕсли;
 КонецЦикла;
 Файл.Закрыть();
КонецПроцедуры
У
XML свои плюсы и минусы но
если нужно быстро выполнить перенос
данных это лучший вариант.

 
Комментариев нет:
Отправить комментарий