Доброго времени суток.
Возможно, еще пригодится кому-нибудь.
Возникла необходимость записывать ответы от сервисов в XML для последующего разбора информации, а т.к. ответ могу получить от такого сервиса лишь один раз, и он не хранит результаты, то стал вопрос, как бы записать его для последующего разбора. Вот примерно так и родилась идея подобного решения.
Сам код находил где-то на площадке, ссылку на публикацию уже не найду, так что, автор, не серчай, если узнаешь - отзовись, я укажу в публикации.
От меня добавлена поддержка таблиц значений, массивов, Двоичных данных, Уникальных идентификаторов.
Также добавлена возможность записывать любые структуры с вложениями указанных типов и в любой последовательности.
Например, структура с таблицей значений как элемент массива, который является элементом структуры.
И, в общем, как угодно в любых вариантах.
#Область ЧтениеИЗаписьСТруктурыВXML
// ============= Сохранения и загрузка структуры в XML === НАЧАЛО ======
// Возвращает структру прочитанную из файла XML
// ФайлXML - Строка с путем до XML
// ФормаИндикатор - диалог индикатор
// Возвращает стурктуру
Функция ЗагрузитьСтруктуруИзXML(ФайлXML, ФормаИндикатор = Неопределено) Экспорт
Попытка
Чтение = Новый ЧтениеXML();
Чтение.ОткрытьФайл(ФайлXML);
Исключение
Сообщить("Ощибка при чтение данных из XML!" + Символы.ПС + ОписаниеОшибки());
КонецПопытки;
// --- выводим данные в форму прогресса ---
Если ФормаИндикатор <> Неопределено тогда
ФормаИндикатор.НаименованиеОбработкиДанных = "Загружаем таблицу значений из XML";
ФормаИндикатор.КомментарийОбработкиДанных = "Загружаем...";
ФормаИндикатор.МаксимальноеЗначение = 100;
ИндПозиция = 0;
КонецЕсли;
// ---
СтруктураДанные = XMLВСтруктуру(Чтение);
Возврат СтруктураДанные;
КонецФункции
// Сохраням структуру в XML файл
// Данные - переменная типа Структра
// ФайлXML - Путь до сохраняемого файла. Строка.
// ФормаИндикатор - Форма "ХодВыполненияОбработкиДанных" из общих форм
Функция СохранитьСтруктуруXML(Данные, ФайлXML, ФормаИндикатор = Неопределено) Экспорт
Попытка
Запись = Новый ЗаписьXML();
Запись.ОткрытьФайл(ФайлXML);
Исключение
Сообщить("Ошибка при создание XML файла! " + Символы.ПС + ОписаниеОшибки());
Возврат Ложь;
КонецПопытки;
// --- выводим данные в форму прогресса ---
Если ФормаИндикатор <> Неопределено тогда
ФормаИндикатор.НаименованиеОбработкиДанных = "Сохраняем таблицу значений в XML";
КонецЕсли;
// ---
Запись.ЗаписатьОбъявлениеXML();
Запись.ЗаписатьНачалоЭлемента("root");
СтукктураВXML(Запись,Данные,ФормаИндикатор);
Запись.ЗаписатьКонецЭлемента(); // root
Запись.Закрыть();
Возврат Истина;
КонецФункции
Функция ПолучитьЗначениеXML(Чтение , АтрибутУзла) Экспорт
ТипКлюча = АтрибутУзла["Type"];
ИмяКлюча = АтрибутУзла["Name"];
Если ТипКлюча = "ТаблицаЗначений" тогда
Значение = XMLВТаблицуЗначений(Чтение);
//СтруктураДанные.Вставить(ИмяКлюча, );//XMLВТаблицуЗначений(Чтение));
ИначеЕсли ТипКлюча = "Структура" тогда
Значение = XMLВСтруктуру(Чтение);
//СтруктураДанные.Вставить(ИмяКлюча, XMLВСтруктуру(Чтение));
ИначеЕсли ТипКлюча = "Массив" тогда
Значение = XMLВМассив(Чтение);
//СтруктураДанные.Вставить(ИмяКлюча, XMLВМассив(Чтение));
Иначе
ТекстовоеЗначениеДанных = "";
Чтение.Прочитать();
Если Чтение.ТипУзла = ТипУзлаXML.Текст тогда
ТекстовоеЗначениеДанных = СокрЛП(Чтение.Значение)
КонецЕсли;
АтрибутУзла.Вставить("String",ТекстовоеЗначениеДанных);
ЗначениеДанных = Описания2Значение(АтрибутУзла);
Значение = ЗначениеДанных;
//СтруктураДанные.Вставить(ИмяКлюча, ЗначениеДанных);
// Пропускаем закрывающийся тег
Если НЕ(Чтение.ТипУзла = ТипУзлаXML.КонецЭлемента и Чтение.Имя = "KeyValue") тогда
Чтение.Прочитать();
КонецЕсли;
КонецЕсли;
Возврат Значение;
КонецФункции
Функция ЗаписатьЗначениеВXML(Запись, Значение, ФормаИндикатор = Неопределено) Экспорт
//ОписаниеЗначения = Значение2Описание(Значение);
//
//ЗаписатьОписаниеКакАтрибутXML(Запись,ОписаниеЗначения);
//Если ОписаниеЗначения["Type"] = "Структура" тогда
// Запись.ЗаписатьНачалоЭлемента("STRTAB");
// СтукктураВXML(Запись,Значение,ФормаИндикатор);
// Запись.ЗаписатьКонецЭлемента(); // STRTAB
//Иначе
// СтрЗначение = ОписаниеЗначения["String"];
// Запись.ЗаписатьСекциюCDATA(СтрЗначение);
//КонецЕсли;
ОписаниеЗначения = Значение2Описание(Значение);
Если ОписаниеЗначения["Type"] = "ТаблицаЗначений" тогда
//Запись.ЗаписатьНачалоЭлемента("STRTAB");
ТаблицаЗначенийВXML(Запись,Значение,ФормаИндикатор);
//Запись.ЗаписатьКонецЭлемента(); // STRTAB
ИначеЕсли ОписаниеЗначения["Type"] = "Структура" тогда
СтукктураВXML(Запись,Значение,ФормаИндикатор);
ИначеЕсли ОписаниеЗначения["Type"] = "Массив" тогда
//Запись.ЗаписатьНачалоЭлемента("MassivClaster");
МассивВXML(Запись,Значение,ФормаИндикатор);
//Запись.ЗаписатьКонецЭлемента(); // MassivClaster
Иначе
Значение = ОписаниеЗначения["String"];
Запись.ЗаписатьСекциюCDATA(Значение);
КонецЕсли;
КонецФункции
// Производим запись структуры в XML
// Запись - переменная типа ЗаписьXML
// стДанные - стуктура
Функция СтукктураВXML(Запись, СтруктураДанных, ФормаИндикатор = Неопределено)
Запись.ЗаписатьНачалоЭлемента("StructureClaster");
Для каждого ЭлементСтруктуры из СтруктураДанных цикл
Если ФормаИндикатор <> Неопределено тогда
ФормаИндикатор.КомментарийОбработкиДанных = "Сохраняем..." + ЭлементСтруктуры.Ключ;
КонецЕсли;
Запись.ЗаписатьНачалоЭлемента("KeyValue");
ОписаниеЗначения = Значение2Описание(ЭлементСтруктуры.Значение);
ОписаниеЗначения.Вставить("Name", ЭлементСтруктуры.Ключ);
ЗаписатьОписаниеКакАтрибутXML(Запись,ОписаниеЗначения);
Значение = ЭлементСтруктуры.Значение;
ЗаписатьЗначениеВXML(Запись, Значение, ФормаИндикатор);
Запись.ЗаписатьКонецЭлемента(); // KeyValue
КонецЦикла;
Запись.ЗаписатьКонецЭлемента(); // KeyValue
КонецФункции
Функция XMLВСтруктуру(Чтение, ФормаИндикатор = Неопределено)
СтруктураДанные = Новый Структура;
Чтение.Прочитать();
Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента и Чтение.Имя = "StructureClaster" или Чтение.Имя = "root" тогда
Пока Чтение.Прочитать() Цикл
Если Чтение.ТипУзла = ТипУзлаXML.КонецЭлемента и Чтение.Имя = "StructureClaster" или Чтение.Имя = "root" тогда
//Чтение.Прочитать();
Возврат СтруктураДанные;
КонецЕсли;
//Если (Чтение.ТипУзла = ТипУзлаXML.КонецЭлемента и Чтение.Имя = "KeyValue") тогда
// Прервать;
//КонецЕсли;
Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента и Чтение.Имя = "KeyValue" тогда
АтрибутУзла = Новый Соответствие;
Пока Чтение.ПрочитатьАтрибут() цикл
АтрибутУзла[Чтение.Имя] = Чтение.Значение;
КонецЦикла;
ТипКлюча = АтрибутУзла["Type"];
ИмяКлюча = АтрибутУзла["Name"];
СтруктураДанные.Вставить(ИмяКлюча, ПолучитьЗначениеXML(Чтение, АтрибутУзла));
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат СтруктураДанные;
КонецФункции
// Производим запись таблицы значения в XML
// Запись - переменная типа ЗаписьXML
// Таблица - Таблица значений
Функция ТаблицаЗначенийВXML(Запись, Таблица, ФормаИндикатор = Неопределено)
ИндМакс = Таблица.Количество();
ИндПозиция = 0;
Если ФормаИндикатор <> Неопределено тогда
ФормаИндикатор.МаксимальноеЗначение = ИндМакс;
КонецЕсли;
// --- Данные по колонкам таблицы значений
МасКолонки = Новый Массив();
Запись.ЗаписатьНачалоЭлемента("columns");
Для Ном = 0 по Таблица.Колонки.Количество()-1 цикл
Колонка = Таблица.Колонки[Ном];
МасКолонки.Добавить(Колонка.Имя);
ТипВСтроку = ИмяТипа(Колонка.ТипЗначения);
Запись.ЗаписатьНачалоЭлемента("colum");
Запись.ЗаписатьАтрибут("Name",Колонка.Имя);
Запись.ЗаписатьАтрибут("Type",ТипВСтроку);
Запись.ЗаписатьКонецЭлемента(); // colum
КонецЦикла;
Запись.ЗаписатьКонецЭлемента(); // columns
// --- Строки из таблицы значений
Запись.ЗаписатьНачалоЭлемента("records");
Для Каждого СтрТаблицы из Таблица цикл
Если ФормаИндикатор <> Неопределено тогда
ИндПозиция = ИндПозиция + 1;
ФормаИндикатор.КомментарийЗначения = "(" + ИндПозиция + " из " + ИндМакс + ")";
ФормаИндикатор.Значение = ИндПозиция;
КонецЕсли;
Запись.ЗаписатьНачалоЭлемента("record");
Для каждого ИмяКолонки из МасКолонки цикл
Запись.ЗаписатьНачалоЭлемента(ИмяКолонки);
Значение = СтрТаблицы[ИмяКолонки];
ОписаниеЗначения = Значение2Описание(Значение);
ЗаписатьОписаниеКакАтрибутXML(Запись,ОписаниеЗначения);
Если ОписаниеЗначения["Type"] = "Структура" тогда
Запись.ЗаписатьНачалоЭлемента("STRTAB");
СтукктураВXML(Запись,Значение,ФормаИндикатор);
Запись.ЗаписатьКонецЭлемента(); // STRTAB
Иначе
СтрЗначение = ОписаниеЗначения["String"];
Запись.ЗаписатьСекциюCDATA(СтрЗначение);
КонецЕсли;
Запись.ЗаписатьКонецЭлемента();
КонецЦикла;
Запись.ЗаписатьКонецЭлемента();
КонецЦикла;
Запись.ЗаписатьКонецЭлемента(); // records
КонецФункции
// Разбирает XML содержащая таблицу значений
// Возвращает таблицу значений
// Чтение - переменная типа ЧтениеXML
Функция XMLВТаблицуЗначений(Чтение, ФормаИндикатор = Неопределено);
ТЗ = Новый ТаблицаЗначений;
МассивКолонок = Новый Массив;
ТаблицаПостроена = Ложь;
Если ФормаИндикатор <> Неопределено тогда
КонецЕсли;
Пока Чтение.Прочитать() Цикл
Если ФормаИндикатор <> Неопределено тогда
ИндПозиция = ИндПозиция + 1;
ФормаИндикатор.Значение = ИндПозиция - Цел(ИндПозиция / 100)*100;
ФормаИндикатор.КомментарийЗначения = Строка(ИндПозиция);
КонецЕсли;
// ЗАвершили работсу с таблицей значения
Если Чтение.ТипУзла = ТипУзлаXML.КонецЭлемента и Чтение.Имя = "KeyValue" тогда
Прервать;
КонецЕсли;
// Данные по колонке пошли
Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента и Чтение.Имя = "colum" и Не ТаблицаПостроена тогда
АтрибутУзла = Новый Соответствие;
Пока Чтение.ПрочитатьАтрибут() цикл
АтрибутУзла[Чтение.Имя] = Чтение.Значение;
КонецЦикла;
ИмяТипКолонки = АтрибутУзла["Type"];
ОписаниеТипа = ОписаниеТипаИзИмени(ИмяТипКолонки);
Если ОписаниеТипа = "" тогда
ТЗ.Колонки.Добавить(АтрибутУзла["Name"]);
Иначе
ТЗ.Колонки.Добавить(АтрибутУзла["Name"], ОписаниеТипа);
КонецЕсли;
МассивКолонок.Добавить(АтрибутУзла["Name"]);
КонецЕсли;
// Данные по колонке закончились
Если Чтение.ТипУзла = ТипУзлаXML.КонецЭлемента и Чтение.Имя = "columns" тогда
ТаблицаПостроена = Истина;
КонецЕсли;
Если Не ТаблицаПостроена тогда
Продолжить;
КонецЕсли;
// Началась запись в таблице значений
Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента и Чтение.Имя = "record" тогда
ЗаписьТЗ = ТЗ.Добавить();
Пока Чтение.Прочитать() цикл
// Конец данных по записи
Если Чтение.ТипУзла = ТипУзлаXML.КонецЭлемента и Чтение.Имя = "record" тогда
Прервать;
КонецЕсли;
// Есть такая колонка в нашей ТаблицеЗначений
Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента и
МассивКолонок.Найти(Чтение.Имя) <> Неопределено тогда
ИмяКолонки = Чтение.Имя;
АтрибутУзла = Новый Соответствие;
Пока Чтение.ПрочитатьАтрибут() цикл
АтрибутУзла[Чтение.Имя] = Чтение.Значение;
КонецЦикла;
Чтение.Прочитать();
Если Чтение.Имя = "STRTAB" и Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
ЗаписьТЗ[ИмяКолонки] = XMLВСтруктуру(Чтение);
Иначе
Если Чтение.ТипУзла = ТипУзлаXML.Текст тогда
АтрибутУзла["String"] = СокрЛП(Чтение.Значение);
КонецЕсли;
ЗаписьТЗ[ИмяКолонки] = Описания2Значение(АтрибутУзла);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли; // Данные в таблице
КонецЦикла;
Возврат ТЗ;
КонецФункции
// Производим запись таблицы значения в XML
// Запись - переменная типа ЗаписьXML
// Таблица - Таблица значений
Функция МассивВXML(Запись, Массив, ФормаИндикатор = Неопределено)
ИндМакс = Массив.Количество();
ИндПозиция = 0;
Если ФормаИндикатор <> Неопределено тогда
ФормаИндикатор.МаксимальноеЗначение = ИндМакс;
КонецЕсли;
Запись.ЗаписатьНачалоЭлемента("MassivClaster");//"MassivClaster"
Для Каждого ЭлементМассива из Массив цикл
Если ФормаИндикатор <> Неопределено тогда
ИндПозиция = ИндПозиция + 1;
ФормаИндикатор.КомментарийЗначения = "(" + ИндПозиция + " из " + ИндМакс + ")";
ФормаИндикатор.Значение = ИндПозиция;
КонецЕсли;
Запись.ЗаписатьНачалоЭлемента("MassivElement"); //("record");
Значение = ЭлементМассива;
//ЗаписатьЗначениеВXML(Запись, Значение, ФормаИндикатор);
ОписаниеЗначения = Значение2Описание(Значение);
ОписаниеЗначения.Вставить("Name", "MassivElement");
ЗаписатьОписаниеКакАтрибутXML(Запись,ОписаниеЗначения);
ЗаписатьЗначениеВXML(Запись, Значение, ФормаИндикатор);
Запись.ЗаписатьКонецЭлемента(); //MassivElement
КонецЦикла;
Запись.ЗаписатьКонецЭлемента(); //MassivClaster
КонецФункции
Функция XMLВМассив(Чтение, ФормаИндикатор = Неопределено);
//ТЗ = Новый ТаблицаЗначений;
Массив = Новый Массив;
//МассивКолонок = Новый Массив;
//ТаблицаПостроена = Ложь;
Если ФормаИндикатор <> Неопределено тогда
КонецЕсли;
Если Чтение.Прочитать() Тогда
Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента и Чтение.Имя = "MassivClaster" тогда
Пока Чтение.Прочитать() Цикл
Если Чтение.ТипУзла = ТипУзлаXML.КонецЭлемента и Чтение.Имя = "MassivClaster" тогда
//Чтение.Прочитать();
Возврат Массив;
КонецЕсли;
Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента и Чтение.Имя = "MassivElement" Тогда
АтрибутУзла = Новый Соответствие;
Пока Чтение.ПрочитатьАтрибут() цикл
АтрибутУзла[Чтение.Имя] = Чтение.Значение;
КонецЦикла;
ТипКлюча = АтрибутУзла["Type"];
ИмяКлюча = АтрибутУзла["Name"];
Массив.Добавить(ПолучитьЗначениеXML(Чтение , АтрибутУзла));
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Возврат Массив;
КонецФункции
// Заполняет переменную тзОбщееОписаниеТипов
// Таблица значений с описанием типов.
Функция ПолучитьОписаниеТипов()
// Массив с менеджерами объектов
мМенеджеров = Новый СписокЗначений();
мМенеджеров.Добавить(Справочники);
мМенеджеров.Добавить(Документы);
мМенеджеров.Добавить(ПланыСчетов);
мМенеджеров.Добавить(ПланыВидовРасчета);
мМенеджеров.Добавить(ПланыВидовХарактеристик);
мМенеджеров.Добавить(ПланыОбмена);
мМенеджеров.Добавить(Перечисления);
// Массив с примитивными типами
мТипов = Новый Массив;
мТипов.Добавить("NULL");
мТипов.Добавить("Неопределено");
мТипов.Добавить("Строка");
мТипов.Добавить("Число");
мТипов.Добавить("СписокЗначений");
мТипов.Добавить("ТаблицаЗначений");
мТипов.Добавить("Структура");
мТипов.Добавить("Соответствие");
мТипов.Добавить("Массив");
мТипов.Добавить("Дата");
мТипов.Добавить("МоментВремени");
мТипов.Добавить("Булево");
мТипов.Добавить("ВидДвиженияНакопления");
мТипов.Добавить("ДвоичныеДанные");
мТипов.Добавить("Файл");
тзОбщееОписаниеТипов = Новый ТаблицаЗначений();
тзОбщееОписаниеТипов.Колонки.Добавить("Менеджер"); // равно НЕОПРЕДЕЛЕННО для примитивных типов
тзОбщееОписаниеТипов.Колонки.Добавить("Имя");
тзОбщееОписаниеТипов.Колонки.Добавить("Тип");
тзОбщееОписаниеТипов.Колонки.Добавить("ОписаниеТипа");
тзОбщееОписаниеТипов.Колонки.Добавить("ОбъектМетаданных");
масТипа = Новый Массив;
// Прописываем примитивные типы
Для Каждого ИмяТипа Из мТипов Цикл
СтрДанные = тзОбщееОписаниеТипов.Добавить();
СтрДанные.ОбъектМетаданных = Неопределено;
СтрДанные.Менеджер = Неопределено;
СтрДанные.Имя = ИмяТипа;
СтрДанные.Тип = Тип(ИмяТипа);
масТипа.Очистить();
масТипа.Добавить(СтрДанные.Тип);
ОписаниеТипа = Новый ОписаниеТипов(масТипа);
СтрДанные.ОписаниеТипа = ОписаниеТипа;
КонецЦикла;
// Прописываем объекты с менеджерами
Для Каждого Менеджер Из мМенеджеров Цикл
Для каждого ОбъМенеджера из Менеджер.Значение цикл
метОбъекта = Метаданные.НайтиПоТипу(Тип(ОбъМенеджера));
СтрОбъМенеджера = метОбъекта.ПолноеИмя();
// Добавляем данные по типу метаданнх
СтрДанные = тзОбщееОписаниеТипов.Добавить();
СтрДанные.Менеджер = ОбъМенеджера;
СтрДанные.ОбъектМетаданных = метОбъекта;
СтрДанные.Имя = "ОбъектМетаданных." + СтрОбъМенеджера;
СтрДанные.Тип = ТипЗнч(метОбъекта);
масТипа.Очистить();
масТипа.Добавить(СтрДанные.Тип);
ОписаниеТипа = Новый ОписаниеТипов(масТипа);
СтрДанные.ОписаниеТипа = ОписаниеТипа;
// Добавляем данные по типу конкретного объекта
СтрДанные = тзОбщееОписаниеТипов.Добавить();
СтрДанные.Менеджер = ОбъМенеджера;
СтрДанные.ОбъектМетаданных = метОбъекта;
СтрДанные.Имя = СтрОбъМенеджера;
СтрДанные.Тип = ТипЗнч(ОбъМенеджера.ПустаяСсылка());
масТипа.Очистить();
масТипа.Добавить(СтрДанные.Тип);
ОписаниеТипа = Новый ОписаниеТипов(масТипа);
СтрДанные.ОписаниеТипа = ОписаниеТипа;
КонецЦикла;
КонецЦикла;
Попытка
////Добавляем вручную объекты методанных которые имеют разное наименование но одинаковые гуиды
//// в моем случае после перноса зупа 2.5 в зцп 3.1
ОбъМенеджера = Справочники.Сотрудники;
метОбъекта = Метаданные.НайтиПоТипу(Тип(ОбъМенеджера));
СтрОбъМенеджера = метОбъекта.ПолноеИмя();
СтрДанные = тзОбщееОписаниеТипов.Добавить();
СтрДанные.Менеджер = Справочники.Сотрудники;
СтрДанные.ОбъектМетаданных = метОбъекта;
СтрДанные.Имя = "Справочник.СотрудникиОрганизаций";//"Спарочни";
СтрДанные.Тип = ТипЗнч(ОбъМенеджера.ПустаяСсылка());
//СотрудникиОрганизаций
Исключение
КонецПопытки;
КонецФункции
// Инициализируемый переменную тзОбщееОписаниеТипов
Процедура ИницилизироватьОбщееОписаниеТипов() экспорт
Если ТипЗнч(тзОбщееОписаниеТипов) <> Тип("ТаблицаЗначений") тогда
ПолучитьОписаниеТипов();
КонецЕсли;
КонецПроцедуры
// Возвращает строку из тзОбщееОписаниеТипов с описанием типа значения
// Значение - Переменная, тип которой надо узнать
// Возвращает СтрокаТаблицыЗначений
// Если не нашел то Неопределенно
Функция ПолноеОписаниТипа(Значение)
ИницилизироватьОбщееОписаниеТипов();
стрНайдено = Неопределено;
ЭтоОбъектМетаданных = Тип("ОбъектМетаданных");
ЭтоОписаниеТипов = Тип("ОписаниеТипов");
ЭтоТип = Тип("Тип");
ТипЭтогоЗначения = ТипЗнч(Значение);
стрНайдено = Неопределено;
Если ТипЭтогоЗначения = ЭтоОписаниеТипов тогда
стрНайдено = тзОбщееОписаниеТипов.Найти(Значение,"ОписаниеТипа");
ИначеЕсли ТипЭтогоЗначения = ЭтоТип тогда
стрНайдено = тзОбщееОписаниеТипов.Найти(Значение,"Тип");
ИначеЕсли ТипЭтогоЗначения = ЭтоОбъектМетаданных тогда
стрОтбора = Новый Структура("ОбъектМетаданных,Тип",Значение,ТипЭтогоЗначения);
масНайдено = тзОбщееОписаниеТипов.НайтиСтроки(стрОтбора);
Если масНайдено.Количество() > 0 тогда
стрНайдено = масНайдено[0];
КонецЕсли;
Иначе
стрНайдено = тзОбщееОписаниеТипов.Найти(ТипЭтогоЗначения,"Тип");
КонецЕсли;
Возврат стрНайдено;
КонецФункции
// Возвращает строку из тзОбщееОписаниеТипов с полным описанием типа
// Возвращает СтрокаТаблицыЗначений
Функция ПолноеОписаниТипаИзИмени(ИмяТипа)
ИницилизироватьОбщееОписаниеТипов();
стрНайдено = тзОбщееОписаниеТипов.Найти(ИмяТипа,"Имя");
Возврат стрНайдено;
КонецФункции
// Возвращает строчное представление типа
// Значение - Тип, ОписаниеТипа, Переменная
// Возвращает имя типа
Функция ИмяТипа(Значение)Экспорт
стОписТипа = ПолноеОписаниТипа(Значение);
Если стОписТипа = Неопределено тогда
Возврат "";
Иначе
Возврат стОписТипа.Имя;
КонецЕсли;
КонецФункции
// Вовзращает тип из строчного предсталвения
// ИмяТипа - строка содержащее имя типа
// Возвращает "Тип"
Функция ТипИзИмени(ИмяТипа) Экспорт
стрНайдено = ПолноеОписаниТипаИзИмени(ИмяТипа);
Возврат ?(стрНайдено = Неопределено,"", стрНайдено.Тип);
КонецФункции
// Вовзращает Описание Типа из строчного предсталвения
// ИмяТипа - строка содержащее имя типа
Функция ОписаниеТипаИзИмени(ИмяТипа)
стрНайдено = ПолноеОписаниТипаИзИмени(ИмяТипа);
Возврат ?(стрНайдено = Неопределено,"", стрНайдено.ОписаниеТипа);
КонецФункции
// Возвращает стуктура с описанием типа
//
Функция ПустаяСтурктуруОписанияЗначения()
ОписаниеТипа = Новый Структура();
ОписаниеТипа.Вставить("String", ""); // Значение в строке
ОписаниеТипа.Вставить("Type", "Строка"); // Тип
ОписаниеТипа.Вставить("UID", ""); // УИД
ОписаниеТипа.Вставить("Cod", ""); // КОД
Возврат ОписаниеТипа;
КонецФункции
// Вовзращает стуктуру описавающая значение
// Значение - Значение данные которых надо поместить в стурктура
// стОпсианиеЗначения - структура с описанием значения
// Вовзращает сруктуру стОпсианиеЗначения с заполненными полями
Функция Значение2Описание(Значение, стОпсианиеЗначения = Неопределено) Экспорт
Если стОпсианиеЗначения = Неопределено тогда
стОпсианиеЗначения = ПустаяСтурктуруОписанияЗначения();
КонецЕсли;
ОписаниеТипа = ПолноеОписаниТипа(Значение);
ЭтоМетоданные = ОписаниеТипа.Тип = Тип("ОбъектМетаданных");
Попытка
стОпсианиеЗначения["String"] = Строка(Значение);
стОпсианиеЗначения["Type"] = ОписаниеТипа.Имя;
Исключение
Сообщить("Проверьте """ + Значение + """; Тип:" + ТипЗнч(Значение));
КонецПопытки;
Если ЭтоМетоданные тогда
стОпсианиеЗначения["String"] = Значение.ПолноеИмя();
ИначеЕсли ОписаниеТипа.Тип = тип("ДвоичныеДанные") Тогда
стОпсианиеЗначения["String"] = XMLСтрока(Значение);
стОпсианиеЗначения["Type"] = ОписаниеТипа.Имя;
//ИначеЕсли ОписаниеТипа.Тип = тип("Файл") Тогда
// стОпсианиеЗначения["String"] = XMLСтрока(Значение); //Новый ХранилищеЗначения(Значение, Новый СжатиеДанных(9)););
// стОпсианиеЗначения["Type"] = ОписаниеТипа.Имя;
ИначеЕсли ОписаниеТипа.Тип = тип("ХранилищеЗначения") Тогда
стОпсианиеЗначения["String"] = XMLСтрока(Значение);
стОпсианиеЗначения["Type"] = ОписаниеТипа.Имя;
ИначеЕсли ОписаниеТипа.Тип = тип("УникальныйИдентификатор") Тогда
стОпсианиеЗначения["String"] = XMLСтрока(Значение);
стОпсианиеЗначения["Type"] = ОписаниеТипа.Имя;
ИначеЕсли ОписаниеТипа.Менеджер <> Неопределено и не ЭтоМетоданные тогда
ЭтоДокумент = Метаданные.Документы.Найти(ОписаниеТипа.ОбъектМетаданных.Имя) <> Неопределено;
Если Метаданные.Перечисления.Содержит(Значение.Метаданные()) Тогда
ИмяПеречисления = Значение.Метаданные().Имя;
Если ЗначениеЗаполнено(Значение) Тогда
ИндексПеречисления = Перечисления[ИмяПеречисления].Индекс(Значение);
стОпсианиеЗначения["UID"] = Метаданные.Перечисления[ИмяПеречисления].ЗначенияПеречисления[ИндексПеречисления].Имя;
стОпсианиеЗначения["Cod"] = ИндексПеречисления;
Иначе
стОпсианиеЗначения["UID"] = "ПустаяСсылка";
стОпсианиеЗначения["Cod"] = "ПустаяСсылка";
КонецЕсли;
Иначе
стОпсианиеЗначения["UID"] = Строка(Значение.УникальныйИдентификатор());
стОпсианиеЗначения["Cod"] = ?(ЭтоДокумент, Значение.Номер, Значение.Код);
КонецЕсли;
КонецЕсли;
Возврат стОпсианиеЗначения
КонецФункции
// Ищет по данным из стурктуры (стОпсианиеЗначения) значение
// стОпсианиеЗначения - структура содержащая описание значение
// Возращает значение которое было описанно в стурктуре
Функция Описания2Значение(стОпсианиеЗначения) Экспорт
СтрЗнач = стОпсианиеЗначения["String"];
ИмяТипа = стОпсианиеЗначения["Type"];
ПолныйТип = ПолноеОписаниТипаИзИмени(ИмяТипа); // строка из описания типа
Значение = Неопределено;
Если ПолныйТип = Неопределено тогда
Возврат Неопределено;
КонецЕсли;
Если ПолныйТип.Тип = тип("ДвоичныеДанные") Тогда
Значение = XMLЗначение(Тип("ДвоичныеДанные"), СтрЗнач);
////ИначеЕсли ОписаниеТипа.Тип = тип("Файл") Тогда
ИначеЕсли ПолныйТип.Тип = тип("ХранилищеЗначения") Тогда
Значение = XMLЗначение(Тип("ХранилищеЗначения"),СтрЗнач);
ИначеЕсли ПолныйТип.Тип = тип("УникальныйИдентификатор") Тогда
Значение = XMLЗначение(Тип("УникальныйИдентификатор"),СтрЗнач);
ИначеЕсли ПолныйТип.Менеджер = Неопределено тогда
Значение = ПолныйТип.ОписаниеТипа.ПривестиЗначение(СтрЗнач)
ИначеЕсли ПолныйТип.Тип = Тип("ОбъектМетаданных") тогда
Значение = Метаданные.НайтиПоПолномуИмени(СтрЗнач);
Иначе
Код = стОпсианиеЗначения["Cod"];
УИД = стОпсианиеЗначения["UID"];
Если Код = "ПустаяСсылка" или УИД = "ПустаяСсылка" Тогда
Значение = ПолныйТип.Менеджер.ПустаяСсылка();
Иначе
Если Метаданные.Перечисления.Содержит(ПолныйТип.ОбъектМетаданных) Тогда
Значение = Перечисления[ПолныйТип.ОбъектМетаданных.Имя][УИД];
Иначе
Если Не ПустаяСтрока(УИД) тогда // Ищем по ссыле
UID = Новый УникальныйИдентификатор(УИД);
Значение = ПолныйТип.Менеджер.ПолучитьСсылку(UID);
Если Лев(СокрЛП(Значение),18) = "<Объект не найден>" Тогда
Значение = Неопределено;
//КастыльПеренос тут можно создать спраовчники которых нехвотает по ГУИДУ
Попытка
Если ПолныйТип.Менеджер = Справочники.Работодатели Тогда
СправочникОбъект = Справочники.Работодатели.СоздатьЭлемент();
СправочникОбъект.УстановитьСсылкуНового(Справочники.Работодатели.ПолучитьСсылку(UID));
СправочникОбъект.Наименование = СтрЗнач;
//СправочникОбъект.Код = Код;
СправочникОбъект.ОбменДанными.Загрузка = Истина;
СправочникОбъект.Записать();
//СправочникОбъект.Код =
СправочникОбъект.Записать();
Значение = СправочникОбъект.Ссылка;
КонецЕсли;
Исключение
КонецПопытки;
//КонецКостыля
КонецЕсли;
Иначе // Ищем по коду
Значение = ПолныйТип.Менеджер.НайтиПоКоду(Код);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Значение;
КонецФункции
// Записывает стурктуру (ОписаниеЗначение) как атрибут в XML записи
// ЗаписьXML - XML запись
// ОписаниеЗначение - структура с описанием значения
Процедура ЗаписатьОписаниеКакАтрибутXML(ЗаписьXML,ОписаниеЗначение);
Для каждого ПараметрЗначения из ОписаниеЗначение цикл
Если ПараметрЗначения.Ключ = "String" тогда
Продолжить;
КонецЕсли;
Если НЕ ПустаяСтрока(ПараметрЗначения.Значение) тогда
ЗаписьXML.ЗаписатьАтрибут(ПараметрЗначения.Ключ, ПараметрЗначения.Значение);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
#КонецОбласти
Код универсальный, работает везде, для тестовой структуры написаны два простых запроса для Документооборот 8 КОРП, редакция 2.1 (2.1.28.13), если у вас другая конфигурация, то не будет работать, просто замените при необходимости, основная часть по работе с XML не имеет привязки к конфигурациям.