RDT1C/DataProcessors/ирПортативныйСервер/Ext/ObjectModule.bsl
Администратор e2082add8d Консоль запросов
*Исправлена ошибка команды "Структура формы"
    Административная регистрация com-компонент
        +Добавлена кнопка "Запустить от имени администратора"
        *Исправлено выполнение административной регистрации под пользователем домена, являющимся локальным администратором
    Общее
        *Устранены проблемы с антивирусным ПО путем возврата к использованию старой версии утилиты hstart
    Подбор и обработка объектов
        +В схему компоновки добавлены поля-функции ТИПЗНАЧЕНИЯ() от полей составных типов

3.78
    Консоль запросов
        *Устранено ошибочное использование параметров в фигурных скобках при наличии параметра с типом "Выражение СКД"
        +В подменю "Вставка" для поля текста запроса добавлена команда "Ссылка из буфера"
        *Исправлено вычисление значений параметров для вложенных компоновок из макета компоновки
        *Исправлено некорректное извлечение вычисляемых параметров из макета компоновки
    Конструктор запроса
        +Добавлена поддержка типа запроса TRUNCATE TABLE
        +Для запроса типа WQL при двойном клике на доступном поле доступной таблицы поле теперь добавляется в выбранные поля
    Анализ журнала регистрации
        +Реализованы команды сортировки для списков значений отбора
        *Исправлено долгое обновление табличного поля отбора с большими списками
    Динамический список
        *В командую панель возвращены все стандартные кнопки
        *При открытии с установкой таблицы фокус ввода теперь устанавливается в табличное поле
    Редактор объекта БД
        *Инструмент "Поиск ссылок на объект" перенесен сюда в виде закладки
        +Добавлена поддержка перечислений и точек маршрута
    Интерфейсная панель
        *Исправлены ошибки при обработке веток не метаданных
    Общее
        +Обновлено внутренне описание платформы от версии 8.3.9
        *Исправлены ошибки при открытии ссылок в режиме совместимости 8.1
        *Обеспечена компипяция в режиме совместимости 8.3.9
        *Кнопка открытия настроек справочника Алгоритмы перенесена с общей панели инструментов в формы списка справочника
    Различные значения колонки
        *Исправлены ошибки при обработке булевых колонок
    Консоль кода
        +В подменю "Вставка" добавлена команда "Ссылка из буфера"
    Поиск дублей и замена ссылок
        *Исправлен учет равенства реквизитов при поиске по похожим словам
    Структура хранения БД
        *Исправлена ошибка при нажатии "Показать индекс" в контекстном меню таблицы "Наборы полей" на закладке "Индексы"
    Поиск ссылок на объект
        *Перенесен в инструмент "Редактор объекта БД" в виде закладки

3.77
    Общее
        *Элевация оставлена только в форме административной регистрации COM-компонент, в настройке техножурнала и при изменении параметров служб сервера 1С
        *Элевация теперь используется только если у учетной записи Windows есть административные права
        *Улучшены сообщения пользователю при проблемах регистрации COM компонент
        *Открытие формы объекта по двойному клику на ячейках табличных полей теперь выполняется без получения объекта
        *Улучшена установка ширины динамически добавляемых колонок табличных полей
    Административная регистрация COM компонент
        +Добавлены кнопки "Снять флажки" и "Установить флажки"
    Редактор объекта БД
        *Исправлено распознавание ссылки документа по представлению в поле выбора объекта
        *Исправлено переключение режима редактирования независимого регистра при изменении отбора командами "снять все" и "установить все"
    Динамический список
        *При открытии редактора объекта БД для добавления в независимый регистр сведений теперь включаются все элементы отбора
    Консоль запросов
        *Устранена ошибочная доступность для изменения флажков в коллекции результата запроса
        *Исправлена ошибка загрузки результата WQL запроса

3.76
    Управление службами сервера 1С
        *Улучшена диагностика ошибок
        +Добавлена элевация при изменении параметров служб
    Динамический список
        *Устранено свежее скрытие колонки со стандартной картинкой
    Интерфейсная панель
        +Добавлены перечисления
    Консоль запросов
        *Исправлена ошибка загрузки пустого результата запроса MSSQL
    Редактор констант
        +Включение функциональных опций теперь изменяет только булевы константы и не выполняет их запись
        *Реализован пропуск ошибок записи констант
    Конструктор запросов
        *Устранена ошибочная виртуальная таблица 1С ЗадачиПоИсполнителю  у задачи без адресации
    Редактор объекта БД
        *Флажок "Очищать по отбору чтения" теперь становится доступным только если в считанном наборе записей были строки
        +В режиме менеджера записи регистра сведений реализовано удаление
        *Исправлена свежая ошибка параметризованного открытия строки независимого регистра сведений
    Общее
        *Исправлена ошибка нажатия "Запустить обычное приложение" в тонком клиенте из формы "Невозможно выполнить действие"
2016-12-04 00:30:12 +03:00

599 lines
41 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ПОСЛЕ КАЖДОГО ИЗМЕНЕНИЯ НУЖНО ОБНОВЛЯТЬ ВЕРСИЮ в функции СведенияОВнешнейОбработке
// Интерфейс для регистрации обработки.
// Вызывается при добавлении обработки в справочник "ВнешниеОбработки"
//
// Возвращаемое значение:
// Структура:
// Вид - строка - возможные значения: "ДополнительнаяОбработка"
// "ДополнительныйОтчет"
// "ЗаполнениеОбъекта"
// "Отчет"
// "ПечатнаяФорма"
// "СозданиеСвязанныхОбъектов"
//
// Назначение - массив строк имен объектов метаданных в формате:
// <ИмяКлассаОбъектаМетаданного>.[ * | <ИмяОбъектаМетаданных>]
// Например, "Документ.СчетЗаказ" или "Справочник.*"
// Прим. параметр имеет смысл только для назначаемых обработок
//
// Наименование - строка - наименование обработки, которым будет заполнено
// наименование справочника по умолчанию - краткая строка для
// идентификации обработки администратором
//
// Версия - строка - версия обработки в формате <старший номер>.<младший номер>
// используется при загрузке обработок в информационную базу
// БезопасныйРежим Булево Если истина, обработка будет запущена в безопасном режиме.
// Более подбробная информация в справке.
//
// Информация - Строка- краткая информация по обработке, описание обработки
//
// ВерсияБСП - Строка - Минимальная версия БСП, на которую рассчитывает код
// дополнительной обработки. Номер версии БСП задается в формате «РР.ПП.ВВ.СС»
// (РР старший номер редакции; ПП младший номер ре-дакции; ВВ номер версии; СС номер сборки).
//
// Команды - ТаблицаЗначений - команды, поставляемые обработкой, одная строка таблицы соотвествует
// одной команде
// колонки:
// - Представление - строка - представление команды конечному пользователю
// - Идентификатор - строка - идентефикатор команды. В случае печатных форм
// перечисление через запятую списка макетов
// - Использование - строка - варианты запуска обработки:
// "ОткрытиеФормы" - открыть форму обработки
// "ВызовКлиентскогоМетода" - вызов клиентского экспортного метода из формы обработки
// "ВызовСерверногоМетода" - вызов серверного экспортного метода из модуля объекта обработки
// - ПоказыватьОповещение Булево если Истина, требуется оказывать оповещение при начале
// и при окончании запуска обработки. Прим. Имеет смысл только
// при запуске обработки без открытия формы.
// - Модификатор строка - для печатных форм MXL, которые требуется
// отображать в форме ПечатьДокументов подсистемы Печать
// требуется установить как "ПечатьMXL"
//
// Предусмотрено 2 команды:
// 1. "Открыть форму обработки" для загрузки прайс-листа в диалоговом режиме
// 2. "Загрузить прайс-лист и сохранить протокол в файл" для загрузки прайс-листа по регламентному заданию и
// сохранения протокола в файл.
//
Функция СведенияОВнешнейОбработке() Экспорт
РегистрационныеДанные = Новый Структура;
РегистрационныеДанные.Вставить("Наименование", "ирПортативныйСервер");
РегистрационныеДанные.Вставить("БезопасныйРежим", Ложь);
РегистрационныеДанные.Вставить("Версия", "3.77.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Лкс(Объект);
КонецПроцедуры