При
любом внедрении 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 свои плюсы и минусы но
если нужно быстро выполнить перенос
данных это лучший вариант.
Комментариев нет:
Отправить комментарий