// ПОСЛЕ КАЖДОГО ИЗМЕНЕНИЯ НУЖНО ОБНОВЛЯТЬ ВЕРСИЮ в функции СведенияОВнешнейОбработке // Интерфейс для регистрации обработки. // Вызывается при добавлении обработки в справочник "ВнешниеОбработки" // // Возвращаемое значение: // Структура: // Вид - строка - возможные значения: "ДополнительнаяОбработка" // "ДополнительныйОтчет" // "ЗаполнениеОбъекта" // "Отчет" // "ПечатнаяФорма" // "СозданиеСвязанныхОбъектов" // // Назначение - массив строк имен объектов метаданных в формате: // <ИмяКлассаОбъектаМетаданного>.[ * | <ИмяОбъектаМетаданных>] // Например, "Документ.СчетЗаказ" или "Справочник.*" // Прим. параметр имеет смысл только для назначаемых обработок // // Наименование - строка - наименование обработки, которым будет заполнено // наименование справочника по умолчанию - краткая строка для // идентификации обработки администратором // // Версия - строка - версия обработки в формате <старший номер>.<младший номер> // используется при загрузке обработок в информационную базу // БезопасныйРежим – Булево – Если истина, обработка будет запущена в безопасном режиме. // Более подбробная информация в справке. // // Информация - Строка- краткая информация по обработке, описание обработки // // ВерсияБСП - Строка - Минимальная версия БСП, на которую рассчитывает код // дополнительной обработки. Номер версии БСП задается в формате «РР.ПП.ВВ.СС» // (РР – старший номер редакции; ПП – младший номер ре-дакции; ВВ – номер версии; СС – номер сборки). // // Команды - ТаблицаЗначений - команды, поставляемые обработкой, одная строка таблицы соотвествует // одной команде // колонки: // - Представление - строка - представление команды конечному пользователю // - Идентификатор - строка - идентефикатор команды. В случае печатных форм // перечисление через запятую списка макетов // - Использование - строка - варианты запуска обработки: // "ОткрытиеФормы" - открыть форму обработки // "ВызовКлиентскогоМетода" - вызов клиентского экспортного метода из формы обработки // "ВызовСерверногоМетода" - вызов серверного экспортного метода из модуля объекта обработки // - ПоказыватьОповещение – Булево – если Истина, требуется оказывать оповещение при начале // и при окончании запуска обработки. Прим. Имеет смысл только // при запуске обработки без открытия формы. // - Модификатор – строка - для печатных форм MXL, которые требуется // отображать в форме ПечатьДокументов подсистемы Печать // требуется установить как "ПечатьMXL" // // Предусмотрено 2 команды: // 1. "Открыть форму обработки" для загрузки прайс-листа в диалоговом режиме // 2. "Загрузить прайс-лист и сохранить протокол в файл" для загрузки прайс-листа по регламентному заданию и // сохранения протокола в файл. // Функция СведенияОВнешнейОбработке() Экспорт РегистрационныеДанные = Новый Структура; РегистрационныеДанные.Вставить("Наименование", "ирПортативныйСервер"); РегистрационныеДанные.Вставить("БезопасныйРежим", Ложь); РегистрационныеДанные.Вставить("Версия", "3.61.1"); РегистрационныеДанные.Вставить("ВерсияБСП", "1.2.1.4"); РегистрационныеДанные.Вставить("Вид", "ДополнительнаяОбработка"); РегистрационныеДанные.Вставить("Информация", ""); ТЗКоманд = Новый ТаблицаЗначений; ТЗКоманд.Колонки.Добавить("Идентификатор"); ТЗКоманд.Колонки.Добавить("Представление"); ТЗКоманд.Колонки.Добавить("Модификатор"); ТЗКоманд.Колонки.Добавить("ПоказыватьОповещение"); ТЗКоманд.Колонки.Добавить("Использование"); СтрокаКоманды = тзКоманд.Добавить(); СтрокаКоманды.Идентификатор = "ЗаписатьОбъектXMLЛкс"; СтрокаКоманды.Представление = "ЗаписатьОбъектXMLЛкс"; СтрокаКоманды.ПоказыватьОповещение = Ложь; СтрокаКоманды.Использование = "ВызовСерверногоМетода"; СтрокаКоманды = тзКоманд.Добавить(); СтрокаКоманды.Идентификатор = "ВыполнитьАлгоритм"; СтрокаКоманды.Представление = "ВыполнитьАлгоритм"; СтрокаКоманды.ПоказыватьОповещение = Ложь; СтрокаКоманды.Использование = "ВызовСерверногоМетода"; РегистрационныеДанные.Вставить("Команды", ТЗКоманд); Возврат РегистрационныеДанные; КонецФункции // Параметры // ОбъектыНазначения - массив - ссылоки на объекты информационной базы, для которых требуется вызвать обработку // ПараметрыВыполненияКоманды - структура - структура со свойством ДополнительнаяОбработкаСсылка (ссылка на // элемент справочника ДополнительныеОтчетыИОбработки, который связан с данной дополнительной обработкой) // Процедура ВыполнитьКоманду(ИдентификаторКоманды, ПараметрыКоманды) Экспорт Если ИдентификаторКоманды = "ЗаписатьОбъектXMLЛкс" Тогда ОбъектXML = ПараметрыКоманды.ОбъектXML; ДополнительныеСвойства = ПараметрыКоманды.ДополнительныеСвойства; РежимЗаписи = ПараметрыКоманды.РежимЗаписи; ОтключатьКонтрольЗаписи = ПараметрыКоманды.ОтключатьКонтрольЗаписи; БезАвторегистрацииИзменений = ПараметрыКоманды.БезАвторегистрацииИзменений; ЗаписатьОбъектXMLЛкс(ОбъектXML, ДополнительныеСвойства, РежимЗаписи, ОтключатьКонтрольЗаписи, БезАвторегистрацииИзменений); ПараметрыКоманды.ОбъектXML = ОбъектXML; ИначеЕсли ИдентификаторКоманды = "ВыполнитьАлгоритм" Тогда ВыполнитьАлгоритм(ПараметрыКоманды._ТекстДляВыполнения, ПараметрыКоманды._АлгоритмОбъект); КонецЕсли; КонецПроцедуры // Выполняет текст алгоритма. // // Параметры: // ТекстДляВыполнения – Строка; // _АлгоритмОбъект - СправочникОбъект // *СтруктураПараметров - Структура, *Неопределено. // Функция ВыполнитьАлгоритм(_ТекстДляВыполнения, _АлгоритмОбъект = Null, _Режим = Null, _П0 = Null, _П1 = Null, _П2 = Null, _П3 = Null, _П4 = Null, _П5 = Null, _П6 = Null, _П7 = Null, _П8 = Null, _П9 = Null) Экспорт Перем Результат; //Если Истина // И ирКэш.ЛиПортативныйРежимЛкс() // И ирПортативный.ЛиСерверныйМодульДоступенЛкс() //Тогда // ирПортативный.ВыполнитьСерверныйМетодЛкс("ВыполнитьАлгоритм", _АлгоритмОбъект); //Иначе Выполнить(_ТекстДляВыполнения); //КонецЕсли; Возврат Результат; КонецФункции // ПозиционныйМетод() Функция ЛиПортативныйРежимЛкс() Возврат Ложь; КонецФункции // Записывает объект с параметризованным контекстом (клиент/сервер). // Обеспечивает запись объекта с попытками. Позволяет обойти неинтенсивные дедлоки и превышения ожиданий блокировки. // Также обеспечивает обход оптимистичных объектных блокировок в случае, если в БД пишутся точно те же данные объекта, что и актуальные. // Эффективно для многопоточной записи объектов. Процедура ЗаписатьОбъектЛкс(Объект, НаСервере = Ложь, РежимЗаписи = Неопределено, РежимПроведения = Неопределено, ОтключатьКонтрольЗаписи = Неопределено, БезАвторегистрацииИзменений = Неопределено) Экспорт //Если НаСервере Тогда // ДополнительныеСвойства = СериализоватьДополнительныеСвойстваОбъектаЛкс(Объект); // ОбъектXML = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект); // ЗаписатьОбъектXMLЛкс(ОбъектXML, ДополнительныеСвойства, РежимЗаписи, ОтключатьКонтрольЗаписи, БезАвторегистрацииИзменений); // Объект = ВосстановитьОбъектИзСтрокиXMLЛкс(ОбъектXML); //Иначе НачалоПопыток = ТекущаяДата(); // Для обхода дедлоков и оптимистичной объектной блокировки при высокой параллельности Если РежимЗаписи = Неопределено Тогда ПопытокЗаписиОбъекта = 5; Иначе ПопытокЗаписиОбъекта = 3; КонецЕсли; ПредельнаяДлительность = 20; Для СчетчикПопыток = 1 По ПопытокЗаписиОбъекта Цикл УстановитьПараметрыЗаписиОбъектаЛкс(Объект, ОтключатьКонтрольЗаписи, БезАвторегистрацииИзменений); Попытка Если РежимЗаписи = Неопределено Тогда Объект.Записать(); ИначеЕсли РежимЗаписи = "ПометкаУдаления" Тогда Объект.Записать(); Объект.ОбменДанными.Загрузка = Ложь; Объект.УстановитьПометкуУдаления(Не Объект.ПометкаУдаления); ИначеЕсли Истина И ТипЗнч(РежимЗаписи) = Тип("РежимЗаписиДокумента") И РежимЗаписи <> РежимЗаписиДокумента.Запись Тогда Объект.ОбменДанными.Загрузка = Ложь; Объект.Записать(РежимЗаписи, РежимПроведения); Иначе Объект.Записать(РежимЗаписи); КонецЕсли; Прервать; Исключение НужноВызватьИсключение = Истина; ОписаниеОшибки = ОписаниеОшибки(); НовоеОписаниеОшибки = ""; Если ТранзакцияАктивна() Тогда //НовоеОписаниеОшибки = "Транзакция активна" + Символы.ПС + ОписаниеОшибки; Иначе НОписаниеОшибки = НРег(ОписаниеОшибки); Если Истина И РежимЗаписи = Неопределено И (Ложь Или Найти(НОписаниеОшибки, "несоответствия версии или отсутствия записи базы данных") > 0 Или Найти(НОписаниеОшибки, "version mismatch or lack of database record") > 0) Тогда НужноВызватьИсключение = Ложь; ТекущийXML = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект, Ложь); //Объект.Прочитать(); // Чтение с блокировкой нам не нужно ОбъектДляСравнения = ПеречитатьОбъектЗапросомЛкс(Объект); Если Объект <> Неопределено Тогда НовыйXML = СохранитьОбъектВВидеСтрокиXMLЛкс(ОбъектДляСравнения, Ложь); Если ТекущийXML = НовыйXML Тогда Прервать; Иначе Попытка лРежимЗагрузка = Объект.ОбменДанными.Загрузка; Исключение лРежимЗагрузка = Неопределено; КонецПопытки; ПолноеИмяМД = Объект.Метаданные().ПолноеИмя(); Если лРежимЗагрузка = Истина И СчетчикПопыток = 2 Тогда Сообщить("Возможно в обработчиках ПередЗаписью объекта " + ПолноеИмяМД + " в режиме Загрузка выполняется его нестабильная модификация"); КонецЕсли; НужноВызватьИсключение = СчетчикПопыток = ПопытокЗаписиОбъекта; Если НужноВызватьИсключение Тогда НовоеОписаниеОшибки = "Обход оптимистичной блокировки объекта " + ПолноеИмяМД + " отменен из-за его нестабильной модификации в обработчиках ПередЗаписью (Загрузка=" + XMLСтрока(лРежимЗагрузка) + ")" + Символы.ПС + ОписаниеОшибки; КонецЕсли; КонецЕсли; КонецЕсли; ИначеЕсли Ложь Или Найти(ОписаниеОшибки, "взаимоблокировк") > 0 Или Найти(ОписаниеОшибки, "deadlock") > 0 Тогда НужноВызватьИсключение = Ложь; КонецЕсли; КонецЕсли; Если Не НужноВызватьИсключение Тогда Если СчетчикПопыток = ПопытокЗаписиОбъекта Тогда //НовоеОписаниеОшибки = "Кончились попытки записи" + Символы.ПС + ОписаниеОшибки; НужноВызватьИсключение = Истина; ИначеЕсли ТекущаяДата() - НачалоПопыток >= ПредельнаяДлительность Тогда //НовоеОписаниеОшибки = "Кончилось время записи" + Символы.ПС + ОписаниеОшибки; НужноВызватьИсключение = Истина; ИначеЕсли СчетчикПопыток = ПопытокЗаписиОбъекта Тогда //НовоеОписаниеОшибки = "Кончились попытки записи" + Символы.ПС + ОписаниеОшибки; НужноВызватьИсключение = Истина; КонецЕсли; КонецЕсли; Если НужноВызватьИсключение Тогда СостояниеОбъекта = ПолучитьПредставлениеДопСвойствОбъектаЛкс(Объект); Если ЗначениеЗаполнено(СостояниеОбъекта) Тогда Если ЗначениеЗаполнено(НовоеОписаниеОшибки) Тогда НовоеОписаниеОшибки = НовоеОписаниеОшибки + СостояниеОбъекта; Иначе НовоеОписаниеОшибки = ОписаниеОшибки + СостояниеОбъекта; КонецЕсли; КонецЕсли; Если ЗначениеЗаполнено(НовоеОписаниеОшибки) Тогда ВызватьИсключение НовоеОписаниеОшибки; Иначе ВызватьИсключение; КонецЕсли; КонецЕсли; КонецПопытки; КонецЦикла; //КонецЕсли; КонецПроцедуры Функция ПолучитьПредставлениеДопСвойствОбъектаЛкс(Объект) Попытка ДополнительныеСвойства = Объект.ДополнительныеСвойства; Исключение ДополнительныеСвойства = Новый Структура; КонецПопытки; СостояниеОбъекта = ""; Для Каждого КлючИЗначение Из ДополнительныеСвойства Цикл СостояниеОбъекта = СостояниеОбъекта + Символы.ПС + КлючИЗначение.Ключ + ": " + КлючИЗначение.Значение; КонецЦикла; Возврат СостояниеОбъекта; КонецФункции Процедура УстановитьПометкуУдаленияОбъектаЛкс(ХМЛ, СтруктураДополнительныхСвойств, ЗначениеПометки = Истина) Экспорт Объект = ВосстановитьОбъектИзСтрокиXMLЛкс(ХМЛ); Объект.Прочитать(); // Иначе объект будет модифицирован и возникнет ошибка ВосстановитьДополнительныеСвойстваОбъектаЛкс(Объект, СтруктураДополнительныхСвойств); //Если РежимЗаписи = Неопределено Тогда // Объект.УстановитьПометкуУдаления(ЗначениеПометки); //Иначе Объект.УстановитьПометкуУдаления(ЗначениеПометки); //КонецЕсли; КонецПроцедуры // Позволяет перечитать объект грязным чтением, т.е. без учета блокировок. Не перечитывает свойство ВерсияДанных! // На выходе объект имеет модифицированноть. Для удаленного объекта возвращает Неопределено. Функция ПеречитатьОбъектЗапросомЛкс(Знач Объект) Экспорт ОбъектМД = Объект.Метаданные(); Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ * ИЗ " + ОбъектМД.ПолноеИмя() + " КАК Т ГДЕ Т.Ссылка = &Ссылка"; Запрос.УстановитьПараметр("Ссылка", Объект.Ссылка); ТаблицаОбъекта = Запрос.Выполнить().Выгрузить(); Если ТаблицаОбъекта.Количество() > 0 Тогда СтрокаДанных = ТаблицаОбъекта[0]; Для Каждого КолонкаТаблицы Из ТаблицаОбъекта.Колонки Цикл ЗначениеРеквизита = СтрокаДанных[КолонкаТаблицы.Имя]; Если ЗначениеРеквизита = Null Тогда // Реквизит (но не табличная часть) недоступен по признаку ЭтоГруппа. Если к нему обратиться у объекта, то будет ошибка "Ошибка установки значения свойства '...': Реквизит недоступен для группы" Продолжить; КонецЕсли; Пустышка = Объект[КолонкаТаблицы.Имя]; // Проверяем корректность вычисления выражения перед его использованием в попытке Если КолонкаТаблицы.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Тогда Попытка Объект[КолонкаТаблицы.Имя].Загрузить(ЗначениеРеквизита); Исключение // Табличная часть недоступна по признаку ЭтоГруппа. Выдается ошибка "Ошибка при вызове метода контекста (Загрузить): Объект недоступен для изменения" КонецПопытки; Иначе Попытка Объект[КолонкаТаблицы.Имя] = ЗначениеРеквизита; Исключение // Реквизит предназначен только для чтения КонецПопытки; КонецЕсли; КонецЦикла; Иначе Объект = Неопределено; КонецЕсли; Возврат Объект; КонецФункции Процедура УстановитьПараметрыЗаписиОбъектаЛкс(Знач Объект, ОтключатьКонтрольЗаписи = Неопределено, БезАвторегистрацииИзменений = Неопределено) Экспорт Попытка лОбменДанными = Объект.ОбменДанными; Исключение лОбменДанными = Неопределено; КонецПопытки; Если лОбменДанными <> Неопределено Тогда Если ОтключатьКонтрольЗаписи <> Неопределено Тогда Объект.ОбменДанными.Загрузка = ОтключатьКонтрольЗаписи; КонецЕсли; Если БезАвторегистрацииИзменений <> Неопределено Тогда Объект.ОбменДанными.Получатели.Автозаполнение = Не БезАвторегистрацииИзменений; КонецЕсли; КонецЕсли; КонецПроцедуры // Параметры: // Объект - // ИспользоватьXDTO - // Функция СохранитьОбъектВВидеСтрокиXMLЛкс(Знач Объект, Знач ИспользоватьXDTO = Истина, ИмяФайла = "") Экспорт Поток = Новый ЗаписьXML; Если ЗначениеЗаполнено(ИмяФайла) Тогда Поток.ОткрытьФайл(ИмяФайла); Иначе Поток.УстановитьСтроку(); КонецЕсли; Попытка Если ИспользоватьXDTO Тогда СериализаторXDTO.ЗаписатьXML(Поток, Объект); Иначе ЗаписатьXML(Поток, Объект); КонецЕсли; Исключение Поток.Закрыть(); ВызватьИсключение; КонецПопытки; Результат = Поток.Закрыть(); Возврат Результат; КонецФункции // Копирует все элементы переданного массива, структуры, соответствия, списка значений или коллекции объектов метаданных // в однотипную коллекцию приемник (для метаданных в массив). Если коллекция приемник не указана, она будет создана. // Фиксированные коллекции превращаются в нефиксированные. // // Параметры: // КоллекцияИсходная - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных - исходная коллекция; // КоллекцияПриемник - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных, *Неопределено - коллекция приемник. // // Возвращаемое значение: // КоллекцияПриемник - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных - коллекция приемник. // Функция СкопироватьУниверсальнуюКоллекциюЛкс(КоллекцияИсходная, КоллекцияПриемник = Неопределено) Экспорт ТипКоллекции = ТипЗнч(КоллекцияИсходная); Если Ложь Или ТипКоллекции = Тип("Массив") Или ТипКоллекции = Тип("ФиксированныйМассив") #Если Не ТонкийКлиент И Не ВебКлиент Тогда Или ТипКоллекции = Тип("КоллекцияОбъектовМетаданных") #КонецЕсли Тогда Если КоллекцияПриемник = Неопределено Тогда КоллекцияПриемник = Новый Массив; КонецЕсли; Для Каждого Элемент Из КоллекцияИсходная Цикл КоллекцияПриемник.Добавить(Элемент); КонецЦикла; Возврат КоллекцияПриемник; ИначеЕсли Ложь Или ТипКоллекции = Тип("Структура") Или ТипКоллекции = Тип("ФиксированнаяСтруктура") Тогда Если КоллекцияПриемник = Неопределено Тогда КоллекцияПриемник = Новый Структура; КонецЕсли; Для Каждого Элемент Из КоллекцияИсходная Цикл КоллекцияПриемник.Вставить(Элемент.Ключ, Элемент.Значение); КонецЦикла; Возврат КоллекцияПриемник; ИначеЕсли Ложь Или ТипКоллекции = Тип("Соответствие") Или ТипКоллекции = Тип("ФиксированноеСоответствие") Тогда Если КоллекцияПриемник = Неопределено Тогда КоллекцияПриемник = Новый Соответствие; КонецЕсли; Для Каждого Элемент Из КоллекцияИсходная Цикл КоллекцияПриемник.Вставить(Элемент.Ключ, Элемент.Значение); КонецЦикла; Возврат КоллекцияПриемник; ИначеЕсли ТипКоллекции = Тип("СписокЗначений") Тогда Если КоллекцияПриемник = Неопределено Тогда КоллекцияПриемник = Новый СписокЗначений; КонецЕсли; Для Каждого Элемент Из КоллекцияИсходная Цикл ЗаполнитьЗначенияСвойств(КоллекцияПриемник.Добавить(), Элемент); КонецЦикла; Возврат КоллекцияПриемник; #Если Не ТонкийКлиент И Не ВебКлиент Тогда ИначеЕсли ТипКоллекции = Тип("ТаблицаЗначений") Тогда Если КоллекцияПриемник = Неопределено Тогда КоллекцияПриемник = КоллекцияИсходная.СкопироватьКолонки(); КонецЕсли; ЗагрузитьВТаблицуЗначенийЛкс(КоллекцияИсходная, КоллекцияПриемник); Возврат КоллекцияПриемник; #КонецЕсли Иначе Сообщить("Неверный тип универсальной коллекции для копирования """ + ТипКоллекции + """"); Возврат Неопределено; КонецЕсли; КонецФункции // СкопироватьУниверсальнуюКоллекциюЛкс() // Добавляет в таблицу значений строки из другой таблицы значений и // в них значения колонок с совпадающими наименованиями. // // Параметры: // ТаблицаИсточник - таблица значений, откуда берутся значения; // ТаблицаПриемник - таблица значений, куда добавляются строки; // *СтруктураЗначенийПоУмолчанию - Структура, *Неопределено - значения по умолчанию для добавляемых строк; // *СтруктураНовыхЗначений - Структура, *Неопределено - значения колонок для добавляемых строк, имеют высший приоритет. // Процедура ЗагрузитьВТаблицуЗначенийЛкс(ТаблицаИсточник, ТаблицаПриемник, СтруктураЗначенийПоУмолчанию = Неопределено, СтруктураНовыхЗначений = Неопределено) Экспорт СтрокаСовпадающихКолонок = ""; Разделитель = ","; Если ТипЗнч(ТаблицаИсточник) = Тип("ТаблицаЗначений") Тогда КолонкиИсточника = ТаблицаИсточник.Колонки; Иначе КолонкиИсточника = Метаданные.НайтиПоТипу(ТипЗнч(ТаблицаИсточник)).Реквизиты; КонецЕсли; ЛиПриемникТЧ = ТипЗнч(ТаблицаПриемник) <> Тип("ТаблицаЗначений"); Если ЛиПриемникТЧ Тогда КолонкиПриемника = ТаблицаПриемник.ВыгрузитьКолонки().Колонки; Иначе КолонкиПриемника = ТаблицаПриемник.Колонки; КонецЕсли; Для каждого Колонка Из КолонкиПриемника Цикл Если СтруктураНовыхЗначений <> Неопределено Тогда Если СтруктураНовыхЗначений.Свойство(Колонка.Имя) Тогда Продолжить; КонецЕсли; КонецЕсли; Если Истина И (Ложь Или Не ЛиПриемникТЧ Или Колонка.Имя <> "НомерСтроки") И КолонкиИсточника.Найти(Колонка.Имя) <> Неопределено Тогда СтрокаСовпадающихКолонок = СтрокаСовпадающихКолонок + Разделитель+ Колонка.Имя; КонецЕсли; КонецЦикла; СтрокаСовпадающихКолонок = Сред(СтрокаСовпадающихКолонок, СтрДлина(Разделитель) + 1); Для каждого СтрокаТаблицыИсточника Из ТаблицаИсточник Цикл СтрокаТаблицыПриемника = ТаблицаПриемник.Добавить(); Если СтруктураЗначенийПоУмолчанию <> Неопределено Тогда ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтруктураЗначенийПоУмолчанию); КонецЕсли; // Заполним значения в совпадающих колонках. ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтрокаТаблицыИсточника, СтрокаСовпадающихКолонок); //Для каждого ЭлементМассива Из МассивСовпадающихКолонок Цикл // СтрокаТаблицыПриемника[ЭлементМассива] = СтрокаТаблицыИсточника[ЭлементМассива]; //КонецЦикла; Если СтруктураНовыхЗначений <> Неопределено Тогда ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтруктураНовыхЗначений); КонецЕсли; КонецЦикла; КонецПроцедуры // ЗагрузитьВТаблицуЗначенийЛкс() Процедура ВосстановитьДополнительныеСвойстваОбъектаЛкс(Объект, СтруктураДополнительныхСвойств) Экспорт Если СтруктураДополнительныхСвойств.Свойство("ОбменДанными") Тогда лОбменДанными = Объект.ОбменДанными; СтруктураОбменаДанными = СтруктураДополнительныхСвойств.ОбменДанными; ЗаполнитьЗначенияСвойств(лОбменДанными, СтруктураОбменаДанными); ЗаполнитьЗначенияСвойств(лОбменДанными.Получатели, СтруктураОбменаДанными.Получатели); лОбменДанными.Получатели.Очистить(); Для Каждого Получатель Из СтруктураОбменаДанными.Получатели.Узлы Цикл лОбменДанными.Получатели.Добавить(Получатель); КонецЦикла; КонецЕсли; Если ТипЗнч(Объект) <> Тип("УдалениеОбъекта") Тогда ДополнительныеСвойства = ВосстановитьОбъектИзСтрокиXMLЛкс(СтруктураДополнительныхСвойств.ДополнительныеСвойстваXML); СкопироватьУниверсальнуюКоллекциюЛкс(ДополнительныеСвойства, Объект.ДополнительныеСвойства); КонецЕсли; КонецПроцедуры // ВосстановитьПараметрыОбменаДаннымиЛкс() // Параметры: // XML - // Тип - // ИспользоватьXDTO - // СообщатьОбОшибках - // Функция ВосстановитьОбъектИзСтрокиXMLЛкс(Знач ФайлИлиXML = "", Знач Тип = "", Знач ИспользоватьXDTO = Истина, Знач СообщатьОбОшибках = Истина) Экспорт Если Ложь Или ТипЗнч(ФайлИлиXML) = Тип("Файл") Или ЗначениеЗаполнено(ФайлИлиXML) Тогда ЧтениеXML = Новый ЧтениеXML; Если ТипЗнч(ФайлИлиXML) = Тип("Файл") Тогда ЧтениеXML.ОткрытьФайл(ФайлИлиXML); Иначе ЧтениеXML.УстановитьСтроку(ФайлИлиXML); КонецЕсли; Попытка Если ИспользоватьXDTO Тогда Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеXML); Иначе Результат = ПрочитатьXML(ЧтениеXML); КонецЕсли; Исключение Если СообщатьОбОшибках Тогда Сообщить(ОписаниеОшибки(), СтатусСообщения.Важное); КонецЕсли; ЧтениеXML.Закрыть(); КонецПопытки; // Антибаг платформы 8.2-8.3.6 СериализаторXDTO некорректно восстанавливает пустую табличную часть поверх непустой https://partners.v8.1c.ru/forum/t/1329468/m/1329468 Попытка Пустышка = Результат.Модифицированность(); МетаТЧи = Результат.Метаданные().ТабличныеЧасти; Исключение МетаТЧи = Новый Массив; КонецПопытки; Для Каждого МетаТЧ Из МетаТЧи Цикл ТЧ = Результат[МетаТЧ.Имя]; Если ТЧ.Количество() = 0 Тогда Попытка ТЧ.Вставить(0); Исключение // Недоступна по разделению группа/элемент с неадекватной ошибкой https://partners.v8.1c.ru/forum/t/1374212/m/1374212 Продолжить; КонецПопытки; ТЧ.Удалить(0); КонецЕсли; КонецЦикла; КонецЕсли; Если Результат = Неопределено Тогда Если ЗначениеЗаполнено(Тип) Тогда Результат = Новый (Тип); КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Процедура ЗаписатьОбъектXMLЛкс(СтрокаХМЛ, ДополнительныеСвойства, РежимЗаписи = Неопределено, ОтключатьКонтрольЗаписи = Неопределено, БезАвторегистрацииИзменений = Неопределено) Экспорт Объект = ВосстановитьОбъектИзСтрокиXMLЛкс(СтрокаХМЛ); ВосстановитьДополнительныеСвойстваОбъектаЛкс(Объект, ДополнительныеСвойства); ЗаписатьОбъектЛкс(Объект, Ложь, РежимЗаписи, , ОтключатьКонтрольЗаписи, БезАвторегистрацииИзменений); СтрокаХМЛ = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект); КонецПроцедуры