При открытии обработки загружаем необходимую компоненту v7plus.dll и создаём объект XMLParser. После загрузки файла в анализатор, создаём выборку основного узла документа "Файл" и последовательно считываем подчиненные элементы, разворачивая их процедурой с рекурсией. Во время чтения узлов можно делать параллельную обработку их значений и компоновать данные в объекты формы, для дальнейшего использования. Если узел не является текстом, то процедура создаёт для него структуру в виде таблицы значений, у которой всегда будут колонки "имя" [строка], "атрибуты" [список значений] и "значение" [текст/структура]
Во время обработки узлов можно получать данные для синхронизации с текущими объектами базы данных, и находить соответствующие объекты, подразумеваемые в файле обмена. Таким образом можно автоматизировать подбор товаров, поиск контрагента и его подчиненных объектов.
Зачем это нужно? В связи с распространением ЭДО появилась возможность быстро передавать данные, однако в большинстве случаев оказывается, что у разных организаций одни и те же объекты (товары, контрагенты и т.д) имеют различное представление, разные коды, разные наименования, и вообще, всё что можно сделать разным - разное. Данная обработка позволяет автоматизировать процесс превращения текстовых данных в объекты программы, находить их не только по уникальным кодам, но и по любым другим признакам, которые может передавать партнер в документе. Можно группировать различные виды дополнительной информации в один вид, подходящий для вашей организации. Без такой автоматизации передача текстовой информации - всё равно, что очки мартышке - ни сколько не облегчает работу сотрудника, т.к. после приёма приходится вручную обрабатывать данные.
//........ //******************************************* Процедура ОбработкаУзла(ТЗ) // пример обработки некоторых узлов Если ТЗ.Имя = "Документ" Тогда // какие-то движухи по атрибутам узла ИначеЕсли ТЗ.Имя = "СвСчФакт" Тогда Если ТипЗначенияСтр(ТЗ.Атрибуты) = "СписокЗначений" Тогда НомерДок = ТЗ.Атрибуты.Получить("НомерСчФ"); ДатаДок = Дата(ТЗ.Атрибуты.Получить("ДатаСчФ")); КонецЕсли; ИначеЕсли ТЗ.Имя = "Продавец" Тогда ИНН = ""; Если ТипЗначенияСтр(ТЗ.Значение) = "СписокЗначений" Тогда идСВ = ТЗ.Значение.Получить("ИдСв"); Если ТипЗначенияСтр(идСВ) = "ТаблицаЗначений" Тогда СвОрг = идСВ.Значение.Получить("СвОрг"); Если ТипЗначенияСтр(СвОрг) = "ТаблицаЗначений" Тогда СвЮЛ = СвОрг.Значение.Получить("СвЮЛ"); ИНН = СвЮЛ.Атрибуты.Получить("ИННЮЛ"); КонецЕсли; КонецЕсли; КонецЕсли; Сообщить("- ИНН продавца: " + ИНН); Если ПустаяСтрока(ИНН) = 0 Тогда Продавец = глНайтиПоРеквизиту("Контрагенты","ИНН",ИНН); КонецЕсли; ИначеЕсли ТЗ.Имя = "СвПрод" Тогда // .... ИначеЕсли ТЗ.Имя = "Покупатель" Тогда // .... ИначеЕсли ТЗ.Имя = "СвПокуп" Тогда // .... ИначеЕсли ТЗ.Имя = "ИдентДок" Тогда Если ТипЗначенияСтр(ТЗ.Атрибуты) = "СписокЗначений" Тогда НомерДок = ТЗ.Атрибуты.Получить("НомДокПТ"); ДатаДок = Дата(ТЗ.Атрибуты.Получить("ДатаДокПТ")); КонецЕсли; ИначеЕсли (ТЗ.Имя = "СведТов") ИЛИ (ТЗ.Имя = "СвТов") Тогда // поиск товара выбТовар = ""; Количество = 0; Ставка = ""; Сумма = ""; Если ТипЗначенияСтр(ТЗ.Атрибуты) = "СписокЗначений" Тогда Код = ТЗ.Атрибуты.Получить("КодТов"); Наименование = ТЗ.Атрибуты.Получить("НаимТов"); Артикул = ТЗ.Атрибуты.Получить("АртикулТов"); ШК = ТЗ.Атрибуты.Получить("Штрихкод"); Ставка = Число(ТЗ.Атрибуты.Получить("НалСт")); Если ТЗ.Имя = "СвТов" Тогда Количество = Число(ТЗ.Атрибуты.Получить("КолМест")); Сумма = Число(ТЗ.Атрибуты.Получить("СтУчНДС")); Иначе Количество = Число(ТЗ.Атрибуты.Получить("КолТов")); Сумма = Число(ТЗ.Атрибуты.Получить("СтТовУчНал")); КонецЕсли; Если (ПустаяСтрока(Код) = 0) ИЛИ (ПустаяСтрока(Наименование) = 0) ИЛИ (ПустаяСтрока(Артикул) = 0) Тогда выбТовар = НайтиТовар(Код,Наименование,Артикул,ШК); КонецЕсли; Сообщить("-- товар: " + ?(ПустоеЗначение(выбТовар) = 1,"не найден",выбТовар)); КонецЕсли; Если ПустоеЗначение(выбТовар) = 1 Тогда Если ТипЗначенияСтр(ТЗ.Значение) = "СписокЗначений" Тогда Код = ""; Наименование = ""; Артикул = ""; ШК = ""; Для Сч = 1 По ТЗ.Значение.РазмерСписка() Цикл подчВетка = ТЗ.Значение.ПолучитьЗначение(Сч); подчВетка.ВыбратьСтроки(); Пока подчВетка.ПолучитьСтроку() = 1 Цикл Ид = ""; Зн = ""; Если подчВетка.Имя = "ИнфПолФХЖ2" Тогда Если ТипЗначенияСтр(подчВетка.Атрибуты) = "СписокЗначений" Тогда Ид = подчВетка.Атрибуты.Получить("Идентиф"); Зн = подчВетка.Атрибуты.Получить("Значен"); КонецЕсли; Если (Нрег(Ид) = "код") ИЛИ (Нрег(Ид) = "ид") ИЛИ (Нрег(Ид) = "кодтов") Тогда Код = Зн КонецЕсли; Если (Нрег(Ид) = "шк") ИЛИ (Нрег(Ид) = "штрихкод") ИЛИ (Нрег(Ид) = "штрихкодтов") Тогда ШК = Зн КонецЕсли; Если (Нрег(Ид) = "артикул") ИЛИ (Нрег(Ид) = "арт") ИЛИ (Нрег(Ид) = "артикултов") Тогда Артикул = Зн КонецЕсли; Если (Нрег(Ид) = "наименование") ИЛИ (Нрег(Ид) = "название") ИЛИ (Нрег(Ид) = "наимтов") Тогда Наименование = Зн КонецЕсли; ИначеЕсли подчВетка.Имя = "ДопСведТов" Тогда Если ТипЗначенияСтр(подчВетка.Атрибуты) = "СписокЗначений" Тогда Если ПустаяСтрока(Наименование) = 1 Тогда Наименование = подчВетка.Атрибуты.Получить("НаимТов"); КонецЕсли; Если ПустаяСтрока(Артикул) = 1 Тогда Артикул = подчВетка.Атрибуты.Получить("АртикулТов"); КонецЕсли; Если ПустаяСтрока(Код) = 1 Тогда Код = подчВетка.Атрибуты.Получить("КодТов"); КонецЕсли; Если ПустаяСтрока(ШК) = 1 Тогда ШК = подчВетка.Атрибуты.Получить("ШтрихкодТов"); КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла; КонецЦикла; выбТовар = НайтиТовар(Код,Наименование,Артикул,ШК); КонецЕсли; Сообщить("-- товар: " + ?(ПустоеЗначение(выбТовар) = 1,"не найден",выбТовар)); КонецЕсли; // .... Иначе // .... КонецЕсли; КонецПроцедуры //******************************************* Функция ПрочитатьПодч(Узел,Уровень=0) тзВетка = СоздатьОбъект("ТаблицаЗначений"); тзВетка.НоваяКолонка("Имя","Строка",,,,,,); тзВетка.НоваяКолонка("Значение",,,,,,,); тзВетка.НоваяКолонка("Атрибуты",,,,,,,); Если Узел.nodename = "#text" Тогда // если тип узла обычный текст, то возвращаем его без стуктуры Возврат Узел.Текст; Иначе // узел не является текстом, следовательно у него будет структура таблицы значений, где будет колонка с именем узла, атрибутами и их значениями в виде списка и само значение как ссылка на вложенные объекты СП = СоздатьОбъект("СписокЗначений"); Для Сч = 1 По Узел.КоличествоАтрибутов() Цикл УзелАтрибута = Узел.ПолучитьУзелАтрибута(Сч); СП.ДобавитьЗначение(УзелАтрибута.value,УзелАтрибута.name); КонецЦикла; тзВетка.НоваяСтрока(); тзВетка.Имя = Узел.nodename; тзВетка.Атрибуты = СП; тзВетка.Значение = СоздатьОбъект("СписокЗначений"); Для Сч = 1 По Узел.КоличествоПодчиненных() Цикл Подч = Узел.ПолучитьПодчиненныйПоНомеру(Сч); Если Узел.КоличествоПодчиненных() > 0 Тогда тзВетка.Значение.Установить(Подч.nodename,ПрочитатьПодч(Подч,Уровень + 1)); КонецЕсли; КонецЦикла; ОбработкаУзла(тзВетка); КонецЕсли; Возврат тзВетка; КонецФункции //******************************************* Процедура ПрочитатьФайлXML() XMLАнализатор = СоздатьОбъект("AddIn.XMLParser"); текФайл = XMLАнализатор.СоздатьДокумент(); текФайл.Загрузить(ИмяФайла); Выборка = текФайл.ВыбратьУзлы("Файл"); Для й = 0 По Выборка.КоличествоУзлов - 1 Цикл Узел = Выборка.ПолучитьУзел(й); ПрочитатьПодч(Узел); КонецЦикла; КонецПроцедуры //******************************************* Процедура ПриОткрытии() ЗагрузитьВнешнююКомпоненту(КаталогПрограммы() + "v7plus.dll"); // список всех названий узлов в файле тзТовары.НоваяКолонка("Товар","Справочник.Номенклатура",,,,,,); тзТовары.НоваяКолонка("Количество","Число",,,,,,); тзТовары.НоваяКолонка("Сумма","Число",,,,,,); тзТовары.НоваяКолонка("Цена","Число",,,,,,); тзТовары.НоваяКолонка("Ставка","Число",,,,,,); Если ТипЗначенияСтр(Форма.Параметр) = "ГрупповойКонтекст" Тогда Конт = Форма.Параметр; КонецЕсли; КонецПроцедуры