diff --git "a/\320\230\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/src/CommonModules/\320\243\320\230_\320\236\320\261\321\211\320\265\320\263\320\276\320\235\320\260\320\267\320\275\320\260\321\207\320\265\320\275\320\270\321\217\320\232\320\273\320\270\320\265\320\275\321\202\320\241\320\265\321\200\320\262\320\265\321\200/Module.bsl" "b/\320\230\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/src/CommonModules/\320\243\320\230_\320\236\320\261\321\211\320\265\320\263\320\276\320\235\320\260\320\267\320\275\320\260\321\207\320\265\320\275\320\270\321\217\320\232\320\273\320\270\320\265\320\275\321\202\320\241\320\265\321\200\320\262\320\265\321\200/Module.bsl"
index cfd532f9..16b49bf9 100644
--- "a/\320\230\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/src/CommonModules/\320\243\320\230_\320\236\320\261\321\211\320\265\320\263\320\276\320\235\320\260\320\267\320\275\320\260\321\207\320\265\320\275\320\270\321\217\320\232\320\273\320\270\320\265\320\275\321\202\320\241\320\265\321\200\320\262\320\265\321\200/Module.bsl"
+++ "b/\320\230\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/src/CommonModules/\320\243\320\230_\320\236\320\261\321\211\320\265\320\263\320\276\320\235\320\260\320\267\320\275\320\260\321\207\320\265\320\275\320\270\321\217\320\232\320\273\320\270\320\265\320\275\321\202\320\241\320\265\321\200\320\262\320\265\321\200/Module.bsl"
@@ -917,6 +917,25 @@
КонецПроцедуры
+Функция УстановитьЗначениеПараметраСКД(КомпоновщикНастроек, ИмяПараметра, ЗначениеПараметра, ИспользоватьНеЗаполненный = Истина) Экспорт
+
+ ПараметрУстановлен = Ложь;
+
+ ПараметрКомпоновкиДанных = Новый ПараметрКомпоновкиДанных(ИмяПараметра);
+ ЗначениеПараметраКомпоновкиДанных = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(ПараметрКомпоновкиДанных);
+ Если ЗначениеПараметраКомпоновкиДанных <> Неопределено Тогда
+
+ ЗначениеПараметраКомпоновкиДанных.Значение = ЗначениеПараметра;
+ ЗначениеПараметраКомпоновкиДанных.Использование = ?(ИспользоватьНеЗаполненный, Истина, ЗначениеЗаполнено(ЗначениеПараметраКомпоновкиДанных.Значение));
+
+ ПараметрУстановлен = Истина;
+
+ КонецЕсли;
+
+ Возврат ПараметрУстановлен;
+
+КонецФункции
+
Процедура НайтиРекурсивно(КоллекцияЭлементов, МассивЭлементов, СпособПоиска, ЗначениеПоиска)
Для Каждого ЭлементОтбора Из КоллекцияЭлементов Цикл
@@ -970,6 +989,92 @@
Возврат ВозвращаемоеЗначение
КонецФункции
+Процедура СкопироватьЭлементы(ПриемникЗначения, ИсточникЗначения, ОчищатьПриемник = Истина) Экспорт
+
+ Если ТипЗнч(ИсточникЗначения) = Тип("УсловноеОформлениеКомпоновкиДанных")
+ ИЛИ ТипЗнч(ИсточникЗначения) = Тип("ВариантыПользовательскогоПоляВыборКомпоновкиДанных")
+ ИЛИ ТипЗнч(ИсточникЗначения) = Тип("ОформляемыеПоляКомпоновкиДанных")
+ ИЛИ ТипЗнч(ИсточникЗначения) = Тип("ЗначенияПараметровДанныхКомпоновкиДанных") Тогда
+ СоздаватьПоТипу = Ложь;
+ Иначе
+ СоздаватьПоТипу = Истина;
+ КонецЕсли;
+ ПриемникЭлементов = ПриемникЗначения.Элементы;
+ ИсточникЭлементов = ИсточникЗначения.Элементы;
+ Если ОчищатьПриемник Тогда
+ ПриемникЭлементов.Очистить();
+ КонецЕсли;
+
+ Для каждого ЭлементИсточник Из ИсточникЭлементов Цикл
+
+ Если ТипЗнч(ЭлементИсточник) = Тип("ЭлементПорядкаКомпоновкиДанных") Тогда
+ // Элементы порядка добавляем в начало
+ Индекс = ИсточникЭлементов.Индекс(ЭлементИсточник);
+ ЭлементПриемник = ПриемникЭлементов.Вставить(Индекс, ТипЗнч(ЭлементИсточник));
+ Иначе
+ Если СоздаватьПоТипу Тогда
+ ЭлементПриемник = ПриемникЭлементов.Добавить(ТипЗнч(ЭлементИсточник));
+ Иначе
+ ЭлементПриемник = ПриемникЭлементов.Добавить();
+ КонецЕсли;
+ КонецЕсли;
+
+ ЗаполнитьЗначенияСвойств(ЭлементПриемник, ЭлементИсточник);
+ // В некоторых коллекциях необходимо заполнить другие коллекции
+ Если ТипЗнч(ИсточникЭлементов) = Тип("КоллекцияЭлементовУсловногоОформленияКомпоновкиДанных") Тогда
+ СкопироватьЭлементы(ЭлементПриемник.Поля, ЭлементИсточник.Поля);
+ СкопироватьЭлементы(ЭлементПриемник.Отбор, ЭлементИсточник.Отбор);
+ ЗаполнитьЭлементы(ЭлементПриемник.Оформление, ЭлементИсточник.Оформление);
+ ИначеЕсли ТипЗнч(ИсточникЭлементов) = Тип("КоллекцияВариантовПользовательскогоПоляВыборКомпоновкиДанных") Тогда
+ СкопироватьЭлементы(ЭлементПриемник.Отбор, ЭлементИсточник.Отбор);
+ КонецЕсли;
+
+ // В некоторых элементах коллекции необходимо заполнить другие коллекции
+ Если ТипЗнч(ЭлементИсточник) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда
+ СкопироватьЭлементы(ЭлементПриемник, ЭлементИсточник);
+ ИначеЕсли ТипЗнч(ЭлементИсточник) = Тип("ГруппаВыбранныхПолейКомпоновкиДанных") Тогда
+ СкопироватьЭлементы(ЭлементПриемник, ЭлементИсточник);
+ ИначеЕсли ТипЗнч(ЭлементИсточник) = Тип("ПользовательскоеПолеВыборКомпоновкиДанных") Тогда
+ СкопироватьЭлементы(ЭлементПриемник.Варианты, ЭлементИсточник.Варианты);
+ ИначеЕсли ТипЗнч(ЭлементИсточник) = Тип("ПользовательскоеПолеВыражениеКомпоновкиДанных") Тогда
+ ЭлементПриемник.УстановитьВыражениеДетальныхЗаписей (ЭлементИсточник.ПолучитьВыражениеДетальныхЗаписей());
+ ЭлементПриемник.УстановитьВыражениеИтоговыхЗаписей(ЭлементИсточник.ПолучитьВыражениеИтоговыхЗаписей());
+ ЭлементПриемник.УстановитьПредставлениеВыраженияДетальныхЗаписей(ЭлементИсточник.ПолучитьПредставлениеВыраженияДетальныхЗаписей ());
+ ЭлементПриемник.УстановитьПредставлениеВыраженияИтоговыхЗаписей(ЭлементИсточник.ПолучитьПредставлениеВыраженияИтоговыхЗаписей ());
+ КонецЕсли;
+
+ КонецЦикла;
+
+КонецПроцедуры
+
+
+Процедура ЗаполнитьЭлементы(ПриемникЗначения, ИсточникЗначения, ПервыйУровень = Неопределено) Экспорт
+
+ Если ТипЗнч(ПриемникЗначения) = Тип("КоллекцияЗначенийПараметровКомпоновкиДанных") Тогда
+ КоллекцияЗначений = ИсточникЗначения;
+ Иначе
+ КоллекцияЗначений = ИсточникЗначения.Элементы;
+ КонецЕсли;
+
+ Для каждого ЭлементИсточник Из КоллекцияЗначений Цикл
+ Если ПервыйУровень = Неопределено Тогда
+ ЭлементПриемник = ПриемникЗначения.НайтиЗначениеПараметра(ЭлементИсточник.Параметр);
+ Иначе
+ ЭлементПриемник = ПервыйУровень.НайтиЗначениеПараметра(ЭлементИсточник.Параметр);
+ КонецЕсли;
+ Если ЭлементПриемник = Неопределено Тогда
+ Продолжить;
+ КонецЕсли;
+ ЗаполнитьЗначенияСвойств(ЭлементПриемник, ЭлементИсточник);
+ Если ТипЗнч(ЭлементИсточник) = Тип("ЗначениеПараметраКомпоновкиДанных") Тогда
+ Если ЭлементИсточник.ЗначенияВложенныхПараметров.Количество() <> 0 Тогда
+ ЗаполнитьЭлементы(ЭлементПриемник.ЗначенияВложенныхПараметров, ЭлементИсточник.ЗначенияВложенныхПараметров, ПриемникЗначения);
+ КонецЕсли;
+ КонецЕсли;
+ КонецЦикла;
+
+КонецПроцедуры
+
#КонецОбласти
#Область Отладка
diff --git "a/\320\230\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/src/CommonPictures/\320\243\320\230_\320\230\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217/Picture.png" "b/\320\230\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/src/CommonPictures/\320\243\320\230_\320\230\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217/Picture.png"
new file mode 100644
index 00000000..24fea125
Binary files /dev/null and "b/\320\230\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/src/CommonPictures/\320\243\320\230_\320\230\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217/Picture.png" differ
diff --git "a/\320\230\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/src/CommonPictures/\320\243\320\230_\320\230\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217/\320\243\320\230_\320\230\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217.mdo" "b/\320\230\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/src/CommonPictures/\320\243\320\230_\320\230\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217/\320\243\320\230_\320\230\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217.mdo"
new file mode 100644
index 00000000..177242e7
--- /dev/null
+++ "b/\320\230\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/src/CommonPictures/\320\243\320\230_\320\230\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217/\320\243\320\230_\320\230\320\275\321\204\320\276\321\200\320\274\320\260\321\206\320\270\321\217.mdo"
@@ -0,0 +1,8 @@
+
+
Обработка "Универсальный обмен данными в формате XML" предназначена для загрузки и выгрузки данных в файл из любой конфигурации, реализованной на платформе 1С:Предприятие 8.
+При использовании управляемой формы обработка имеет два режим работы:
1. На клиенте. При использовании этого режима файлы правил и загружаемых данных передаются с клиента на сервер, а файл выгружаемых данных передается с сервера на клиент. Пути к этим файлам, находящимся на клиенте, необходимо указывать в диалоговом окне непосредственно перед выполнением действия.
2. На сервере. В этом режиме файлы не передаются на клиент и пути к ним необходимо указывать на сервере.
Примечание: Файл внешней обработки и файлы протоколов обмена всегда должны находиться на сервере вне зависимости от режима работы.
Обработка имеет четыре закладки
+Для осуществления выгрузки данных необходимо указать имя файла, в который будет осуществляться выгрузка данных и выбрать файл правил обмена. Правила обмена для любых конфигураций могут быть настроены в специализированной конфигурации "Конвертация данных, редакция 2".
+Для выгрузки документов и записей независимых периодических регистров сведений необходимо указать период - "Дату начала" и "Дату окончания". Результирующий файл с выгруженными данными может быть сжат.
+На закладке "Правила выгрузки данных" можно выбрать те типы объектов, которые должны выгружаться, настроить отборы для выборки объектов, либо указать узел обмена данными, для которого нужно выгружать данные.
+На закладке "Параметры выгрузки" можно указать дополнительные параметры выгрузки данных.
+На закладке "Комментарий" можно написать произвольный текст-комментарий, включаемый в файл обмена.
+Для осуществления загрузки данных необходимо указать имя файла, из которого будет осуществляться загрузка данных.
+Режим "Безопасная загрузка данных" позволяет использовать для загрузки данных правила обмена, указанные в поле "Имя файла правил" (по умолчанию используются правила обмена, содержащиеся в сообщении обмена). Этот режим востребован в случаях, когда необходимо обезопасить информационную базу от выполнения вредоносного кода из правил обмена, содержащихся в файле с данными.
+Есть возможность настроить загрузку данных в транзакции. Для этого необходимо взвести флажок "Использовать транзакции" и указать количество элементов в одной транзакции при загрузке.
+"Загружать данные в режиме обмена (ОбменДанными.Загрузка = Истина)" – если флаг установлен, то загрузка объектов будет выполнятся с установленным признаком загрузки. Это означает, что при записи объектов в базу данных будут отключены все платформенные и прикладные проверки. Исключение составляют документы, которые записываются в режиме проведения или отмены проведения. Проведение и отмена проведения документа выполняется всегда без установки режима загрузки, т.е. проверки будут выполняться.
+Закладка служит для детальной настройки выгрузки и загрузки данных.
+"Режим отладки" – флаг для задания режима отладки обмена. Если этот флаг установлен, то процесс обмена данными не будет остановлен при возникновении какой-либо ошибки. Обмен завершится до конца с выводом отладочных сообщений в файл протокола обмена. Этот режим рекомендуется использовать при отладке правил обмена.
+"Вывод информационных сообщений в окно сообщений" – если флаг установлен, то в окно сообщений будет выводиться протокол процесса обмена данными.
+"Количество обработанных объектов для обновления статуса" – параметр служит для определения количества обработанных элементов перед изменением строки состояние загрузки/выгрузки
+"Настройки выгрузки данных" – позволяют определить количество элементов обрабатываемых в одной транзакции при выгрузке данных, выгружать и обрабатывать только те объекты, на которые есть права доступа, настроить тип изменения регистрации для выгруженных объектов через планы обмена.
+"Использовать оптимизированный формат для обмена данными (V8 - V8, версия обработки не ниже 2.0.18)" – оптимизированный формат сообщения обмена предполагает наличие узла "ИнформацияОТипахДанных" в заголовке сообщения, в который выгружается информация о типах данных. Это позволяет ускорить процесс загрузки данных.
+"Использовать транзакции при выгрузке для планов обмена" – флаг определяет режим использования транзакций при выгрузке данных при выборке изменений на узлах планов обмена. Если флаг установлен, то выгрузка данных будет выполняться в транзакции.
+"Количество элементов в транзакции" – определяет максимальное число элементов данных, которые помещаются в сообщение в рамках одной транзакции базы данных. Если значение параметра равно 0 (значение по умолчанию), то все данные помещаются в рамках одной транзакции. Такой режим является рекомендуемым, так как гарантирует согласованность данных, помещаемых в сообщение. Но при создании сообщения в многопользовательском режиме могут быть конфликты блокировок между транзакцией, в которой данные помещаются в сообщение, и транзакциями, выполняемыми другими пользователями. Для снижения вероятности возникновения таких конфликтов можно задать значение этого параметра, отличное от значения по умолчанию. Чем меньше значение параметра, тем меньше вероятность конфликта блокировок, но выше вероятность помещения в сообщение несогласованных данных.
+"Выгружать объекты на которые есть права доступа" – если флаг установлен, то выборка объектов информационной базы будет выполняться с учетом прав доступа текущего пользователя программы. Это предполагает использование литерала "РАЗРЕШЕННЫЕ" в тексте запроса для выборки данных.
+"Автоматически удалять недопустимые символы из строк для записи в XML" – если флаг установлен, то при записи данных в сообщение обмена недопустимые символы будут удалены. Символы проверяются на соответствие рекомендации XML 1.0.
+"Изменения регистрации для узлов обмена после выгрузки" – поле определяет режим работы с регистрацией изменений данных после завершения выгрузки данных. Возможные значения:
+
"Протокол обмена" – позволяет настроить вывод информационных сообщений в окно сообщений, ведение и запись в отдельный файл протокола обмена.
"Имя файла, протокола обмена" – имя файла для вывода протокола процесса обмена данными.
+"Протокол загрузки (для COM - соединения)" – имя файла для вывода протокола процесса обмена данными в базе-приемнике при обмене через COM-соединение. Важно: путь к файлу должен быть доступен с компьютера, на котором установлена база-приемник.
+"Дописывать данные в протокол обмена"– если флаг установлен, то содержимое файла протокола обмена сохраняется, если файл протокола уже существует.
+"Вывод в протокол информационных сообщений" – если флаг установлен, то в протокол обмена будут выводиться сообщения информативного характера, помимо сообщений об ошибках обмена.
+"Открывать файлы протоколов обмена после выполнения операций" – если флаг установлен, то после выполнения обмена данными файлы протоколов обмена будут автоматически открыты для просмотра.
+Закладка нужна только для разработчиков правил обмена. Позволяет удалять из информационной базы произвольные объекты.
+Обработка позволяет совершать отладку обработчиков событий и генерировать модуль отладки из файла-правил или файла-данных.
+Включение режима отладки обработчиков выгрузки производится на закладке "Выгрузка данных" установкой флажка "Режим отладки обработчиков выгрузки". Соответственно, на закладке "Загрузка данных" включение режима отладки загрузки производится установкой флажка "Режим отладки обработчиков загрузки".
+После установки режима отладки обработчиков станет доступной кнопка настройки отладки. По нажатию на эту кнопку откроется окно настройки.
+Настройка отладки обработчиков выполняется в четыре шага:
+
На первом шаге необходимо определиться с режимом отладки алгоритмов:
Первый режим удобно использовать, когда мы точно знаем, что ошибка в обработчике не связана с кодом какого-либо алгоритма. В этом режиме код алгоритмов не выгружается в модуль отладки. Алгоритмы выполняются в контексте оператора "Выполнить()" и их код недоступен для отладки.
+Второй режим необходимо использовать в тех случаях, когда ошибка находится в коде алгоритма. При установке этого режима алгоритмы будут выгружены как отдельные процедуры. В момент вызова алгоритма из какого-либо обработчика происходит обращение к соответствующей процедуре обработки. Этот режим удобно использовать, когда для передачи параметров в алгоритмы используется глобальная переменная "Параметры". Ограничения использования этого режима в том, что при отладке в алгоритме недоступны локальные переменные обработчика, из которого он вызывается.
+Третий режим отладки используется, как и во втором случае, при отладке кода алгоритмов и в тех случаях, при которых второй режим отладки не подходит. При установке этого режима алгоритмы будут выгружены как интегрированный код в обработчиках. Т.е. взамен оператора вызова алгоритма вставляется полный код алгоритма с учетом вложенных алгоритмов. В этом режиме нет ограничений на использование локальных переменных обработчика, однако есть ограничение при отладке алгоритмов с рекурсивным вызовом.
+
На втором шаге необходимо произвести выгрузку обработчиков нажатием на кнопку "Сформировать модуль отладки выгрузки (загрузки)". Сформированные обработчики и алгоритмы будут выведены в отдельное окно для просмотра. Содержимое модуля отладки необходимо скопировать в буфер обмена нажатием на кнопку "Копировать в буфер обмена".
На этом шаге необходимо запустить конфигуратор и создать новую внешнюю обработку. В модуль обработки необходимо вставить содержимое буфера обмена (модуль отладки) и сохранить обработку под любым именем.
На четвертом, завершающем шаге, надо указать имя файла внешней обработки в поле ввода. При этом программа выполняет проверку по времени создания (обновления) файла обработки. Если обработка имеет более раннюю версию, чем версия файла модуля отладки, то будет выведено предупреждение и форма настройки закрыта не будет.
Примечание: Возможность отладки глобального обработчика конвертации "После загрузки правил обмена" не поддерживается.
\ No newline at end of file diff --git "a/\320\230\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/src/DataProcessors/\320\243\320\230_\320\243\320\275\320\270\320\262\320\265\321\200\321\201\320\260\320\273\321\214\320\275\321\213\320\271\320\236\320\261\320\274\320\265\320\275\320\224\320\260\320\275\320\275\321\213\320\274\320\270XML/ObjectModule.bsl" "b/\320\230\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/src/DataProcessors/\320\243\320\230_\320\243\320\275\320\270\320\262\320\265\321\200\321\201\320\260\320\273\321\214\320\275\321\213\320\271\320\236\320\261\320\274\320\265\320\275\320\224\320\260\320\275\320\275\321\213\320\274\320\270XML/ObjectModule.bsl" new file mode 100644 index 00000000..b1ca9d34 --- /dev/null +++ "b/\320\230\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/src/DataProcessors/\320\243\320\230_\320\243\320\275\320\270\320\262\320\265\321\200\321\201\320\260\320\273\321\214\320\275\321\213\320\271\320\236\320\261\320\274\320\265\320\275\320\224\320\260\320\275\320\275\321\213\320\274\320\270XML/ObjectModule.bsl" @@ -0,0 +1,14859 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2019, ООО 1С-Софт +// Все права защищены. Эта программа и сопроводительные материалы предоставляются +// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0) +// Текст лицензии доступен по ссылке: +// https://creativecommons.org/licenses/by/4.0/legalcode +/////////////////////////////////////////////////////////////////////////////////////////////////////// + +#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда + +#Область ОписаниеПеременных + +//////////////////////////////////////////////////////////////////////////////// +// ИСПОЛЬЗУЕМЫЕ СОКРАЩЕНИЯ ИМЕН ПЕРЕМЕННЫХ (АБРЕВИАТУРЫ) + +// ПКО - правило конвертации объектов. +// ПКС - правило конвертации свойств объектов. +// ПКГС - правило конвертации группы свойств объектов. +// ПКЗ - правило конвертации значений объектов. +// ПВД - правило выгрузки данных. +// ПОД - правило очистки данных. + +//////////////////////////////////////////////////////////////////////////////// +// ВСПОМОГАТЕЛЬНЫЕ ПЕРЕМЕННЫЕ МОДУЛЯ ДЛЯ НАПИСАНИЯ АЛГОРИТМОВ (ОБЩИЕ ДЛЯ ВЫГРУЗКИ И ЗАГРУЗКИ) + +Перем Конвертация Экспорт; // Структура свойств конвертации (Имя, Ид, обработчики событий обмена). + +Перем Алгоритмы Экспорт; // Структура, содержащая используемые алгоритмы. +Перем Запросы Экспорт; // Структура, содержащая используемые запросы. +Перем ДопОбработки Экспорт; // Структура, содержащая используемые внешние обработки. + +Перем Правила Экспорт; // Структура, содержащая ссылки на ПКО. + +Перем Менеджеры Экспорт; // Соответствие, содержащее поля Имя, ИмяТипа, ТипСсылкиСтрокой, Менеджер, ОбъектМД, ПКО. +Перем МенеджерыДляПлановОбмена Экспорт; +Перем ФайлОбмена Экспорт; // Последовательно записываемый/читаемый файл обмена. + +Перем ПараметрыДопОбработок Экспорт; // Структура, содержащая параметры, используемых внешних обработок. + +Перем ПараметрыИнициализированы Экспорт; // Если Истина, то необходимые параметры конвертации проинициализированы. + +Перем мФайлПротоколаДанных Экспорт; // Файл для ведения протокола обмена данными. +Перем ФлагКомментироватьОбработкуОбъектов Экспорт; + +Перем ВнешняяОбработкаОбработчиковСобытий Экспорт; // Объект "ВнешниеОбработкиМенеджер" для вызова экспортных процедур + // обработчиков при отладке загрузки/выгрузки. + +Перем ОбщиеПроцедурыФункции; // Переменная хранит ссылку на данный экземпляр обработки - ЭтотОбъект. + // Необходима для вызова экспортных процедур из обработчиков событий. + +Перем мМакетПараметровОбработчиков; // Табличный документ с параметрами обработчиков. +Перем мМакетОбщиеПроцедурыФункции; // Текстовый документ с комментариями, глобальными переменными и обертками общих + // процедур и функций. + +Перем мРежимыОбработкиДанных; // Структура, содержащая режимы использования этой обработки. +Перем РежимОбработкиДанных; // Содержит текущее значение режима обработки данных. + +Перем мРежимыОтладкиАлгоритмов; // Структура, содержащая режимы отладки алгоритмов. +Перем АлгоритмыИнтегрированные; // Структура, содержащая алгоритмы с интегрированным кодом вложенных алгоритмов. + +Перем ИменаОбработчиков; // Структура, содержащая имена всех обработчиков правил обмена. + +Перем РазделителиКонфигурации; // Массив: содержащий разделители конфигурации. + +//////////////////////////////////////////////////////////////////////////////// +// ФЛАГИ НАЛИЧИЯ ГЛОБАЛЬНЫХ ОБРАБОТЧИКОВ СОБЫТИЙ + +Перем ЕстьГлобальныйОбработчикПередВыгрузкойОбъекта; +Перем ЕстьГлобальныйОбработчикПослеВыгрузкиОбъекта; + +Перем ЕстьГлобальныйОбработчикПередКонвертациейОбъекта; + +Перем ЕстьГлобальныйОбработчикПередЗагрузкойОбъекта; +Перем ЕстьГлобальныйОбработчикПослеЗагрузкиОбъекта; + +Перем ВерсияПлатформыПриемника; +Перем ПлатформаПриемника; + +//////////////////////////////////////////////////////////////////////////////// +// ПЕРЕМЕННЫЕ ОБРАБОТОК ОБМЕНА (ОБЩИЕ ДЛЯ ВЫГРУЗКИ И ЗАГРУЗКИ) + +Перем одТипСтрока; // Тип("Строка") +Перем одТипБулево; // Тип("Булево") +Перем одТипЧисло; // Тип("Число") +Перем одТипДата; // Тип("Дата") +Перем одТипХранилищеЗначения; // Тип("ХранилищеЗначения") +Перем одТипУникальныйИдентификатор; // Тип("УникальныйИдентификатор") +Перем одТипДвоичныеДанные; // Тип("ДвоичныеДанные") +Перем одТипВидДвиженияНакопления; // Тип("ВидДвиженияНакопления") +Перем одТипУдалениеОбъекта; // Тип("УдалениеОбъекта") +Перем одТипВидСчета; // Тип("ВидСчета") +Перем одТипТип; // Тип("Тип") +Перем одТипСоответствие; // Тип("Соответствие"). + +Перем одТипУзлаXML_КонецЭлемента Экспорт; +Перем одТипУзлаXML_НачалоЭлемента Экспорт; +Перем одТипУзлаXML_Текст Экспорт; + +Перем ЗначениеПустаяДата Экспорт; + +Перем одСообщения; // Соответствие. Ключ - код ошибки, Значение - описание ошибки. + +Перем мСписокМакетовПравилОбмена Экспорт; + + +//////////////////////////////////////////////////////////////////////////////// +// ПЕРЕМЕННЫЕ МОДУЛЯ ОБРАБОТКИ ВЫГРУЗКИ + +Перем мСчетчикВыгруженныхОбъектов Экспорт; // Число - счетчик выгруженных объектов. +Перем мСчетчикНПП Экспорт; // Число - счетчик НПП +Перем мТаблицаПравилКонвертацииСвойств; // ТаблицаЗначений - шаблон для воссоздания структуры таблицы путем + // копирования. +Перем мXMLПравила; // Xml-Строка, содержащая описание правил обмена. +Перем мСтрокаТиповДляПриемника; + + +//////////////////////////////////////////////////////////////////////////////// +// ПЕРЕМЕННЫЕ МОДУЛЯ ОБРАБОТКИ ЗАГРУЗКИ + +Перем мСчетчикЗагруженныхОбъектов Экспорт;// Число - счетчик загруженных объектов. + +Перем мАтрибутыФайлаОбмена Экспорт; // Структура. После открытия файла + // содержит атрибуты файла обмена + // согласно формату. + +Перем ЗагруженныеОбъекты Экспорт; // Соответствие. Ключ - НПП объекта в файле, + // Значение - ссылка на загруженный объект. +Перем ЗагруженныеГлобальныеОбъекты Экспорт; +Перем ЧислоХранимыхЗагруженныхОбъектов Экспорт; // Число хранимых загруженных объектов, + // после которого Соответствие ЗагруженныеОбъекты + // очищается. +Перем ЗапоминатьЗагруженныеОбъекты Экспорт; + +Перем мСоответствиеДопПараметровПоиска; +Перем мСоответствиеПравилКонвертации; // Соответствие для определения правила конвертации объекта по типу этого объекта. + +Перем мОбработкаДляЗагрузкиДанных Экспорт; + +Перем мСоответствиеПустыхЗначенийТипов; +Перем мСоответствиеОписаниеТипов; + +Перем мБылиПрочитаныПравилаОбменаПриЗагрузке Экспорт; + +Перем мСтекВызововВыгрузкиДанных; + +Перем мСоответствиеТиповДанныхДляЗагрузки; + +Перем мГлобальныйСтекНеЗаписанныхОбъектов; + +Перем СобытияПослеЗагрузкиПараметров Экспорт; + +Перем ТекущийУровеньВложенностиВыгрузитьПоПравилу; + +//////////////////////////////////////////////////////////////////////////////// +// ПЕРЕМЕННЫЕ ДЛЯ ХРАНЕНИЯ МОДУЛЕЙ СТАНДАРТНЫХ ПОДСИСТЕМ + +Перем МодульДатыЗапретаИзменения; + +#КонецОбласти + +#Область ПрограммныйИнтерфейс + +#Область РаботаСоСтроками + +// Разбирает строку на две части: до подстроки разделителя и после. +// +// Параметры: +// Стр - Строка - разбираемая строка; +// Разделитель - Строка - подстрока-разделитель: +// Режим - Число -0 - разделитель в возвращаемые подстроки не включается; +// 1 - разделитель включается в левую подстроку; +// 2 - разделитель включается в правую подстроку. +// +// Возвращаемое значение: +// Правая часть строки - до символа-разделителя. +// +Функция ОтделитьРазделителем(Стр, Знач Разделитель, Режим=0) Экспорт + + ПраваяЧасть = ""; + ПозРазделителя = СтрНайти(Стр, Разделитель); + ДлинаРазделителя = СтрДлина(Разделитель); + Если ПозРазделителя > 0 Тогда + ПраваяЧасть = Сред(Стр, ПозРазделителя + ?(Режим=2, 0, ДлинаРазделителя)); + Стр = СокрЛП(Лев(Стр, ПозРазделителя - ?(Режим=1, -ДлинаРазделителя + 1, 1))); + КонецЕсли; + + Возврат(ПраваяЧасть); + +КонецФункции + +// Преобразует значения из строки в массив, используя указанный разделитель. +// +// Параметры: +// Стр - Строка - Разбираемая строка. +// Разделитель - Строка - подстрока разделитель. +// +// Возвращаемое значение: +// Массив - полученный массив значений. +// +Функция МассивИзСтроки(Знач Стр, Разделитель=",") Экспорт + + Массив = Новый Массив; + ПраваяЧасть = ОтделитьРазделителем(Стр, Разделитель); + + Пока Не ПустаяСтрока(Стр) Цикл + Массив.Добавить(СокрЛП(Стр)); + Стр = ПраваяЧасть; + ПраваяЧасть = ОтделитьРазделителем(Стр, Разделитель); + КонецЦикла; + + Возврат(Массив); + +КонецФункции + +// Разбивает строку на несколько строк по разделителю. Разделитель может иметь любую длину. +// +// Параметры: +// Строка - Строка - текст с разделителями; +// Разделитель - Строка - разделитель строк текста, минимум 1 символ; +// ПропускатьПустыеСтроки - Булево - признак необходимости включения в результат пустых строк. +// Если параметр не задан, то функция работает в режиме совместимости со своей предыдущей версией: +// - для разделителя-пробела пустые строки не включаются в результат, для остальных разделителей пустые строки +// включаются в результат. +// Е если параметр Строка не содержит значащих символов или не содержит ни одного символа (пустая строка), то в +// случае разделителя-пробела результатом функции будет массив, содержащий одно значение "" (пустая строка), а +// при других разделителях результатом функции будет пустой массив. +// +// +// Возвращаемое значение: +// Массив - массив строк. +// +// Пример: +// РазложитьСтрокуВМассивПодстрок(",один,,два,", ",") - возвратит массив из 5 элементов, три из которых - пустые +// строки; +// РазложитьСтрокуВМассивПодстрок(",один,,два,", ",", Истина) - возвратит массив из двух элементов; +// РазложитьСтрокуВМассивПодстрок(" один два ", " ") - возвратит массив из двух элементов; +// РазложитьСтрокуВМассивПодстрок("") - возвратит пустой массив; +// РазложитьСтрокуВМассивПодстрок("",,Ложь) - возвратит массив с одним элементом "" (пустой строкой); +// РазложитьСтрокуВМассивПодстрок("", " ") - возвратит массив с одним элементом "" (пустой строкой); +// +Функция РазложитьСтрокуВМассивПодстрок(Знач Строка, Знач Разделитель = ",", Знач ПропускатьПустыеСтроки = Неопределено) Экспорт + + Результат = Новый Массив; + + // Для обеспечения обратной совместимости. + Если ПропускатьПустыеСтроки = Неопределено Тогда + ПропускатьПустыеСтроки = ?(Разделитель = " ", Истина, Ложь); + Если ПустаяСтрока(Строка) Тогда + Если Разделитель = " " Тогда + Результат.Добавить(""); + КонецЕсли; + Возврат Результат; + КонецЕсли; + КонецЕсли; + // + + Позиция = СтрНайти(Строка, Разделитель); + Пока Позиция > 0 Цикл + Подстрока = Лев(Строка, Позиция - 1); + Если Не ПропускатьПустыеСтроки Или Не ПустаяСтрока(Подстрока) Тогда + Результат.Добавить(Подстрока); + КонецЕсли; + Строка = Сред(Строка, Позиция + СтрДлина(Разделитель)); + Позиция = СтрНайти(Строка, Разделитель); + КонецЦикла; + + Если Не ПропускатьПустыеСтроки Или Не ПустаяСтрока(Строка) Тогда + Результат.Добавить(Строка); + КонецЕсли; + + Возврат Результат; + +КонецФункции + +// Возвращает строку номера без символьных префиксов. +// Например: +// ПолучитьСтроковыйНомерБезПрефиксов("УТ0000001234") = "0000001234" +// +// Параметры: +// Номер - Строка - номер, из которого необходимо вычислить результат функции. +// +// Возвращаемое значение: +// Строка - строка номера без символьных префиксов. +// +Функция ПолучитьСтроковыйНомерБезПрефиксов(Номер) Экспорт + + НомерБезПрефиксов = ""; + Сч = СтрДлина(Номер); + + Пока Сч > 0 Цикл + + Символ = Сред(Номер, Сч, 1); + + Если (Символ >= "0" И Символ <= "9") Тогда + + НомерБезПрефиксов = Символ + НомерБезПрефиксов; + + Иначе + + Возврат НомерБезПрефиксов; + + КонецЕсли; + + Сч = Сч - 1; + + КонецЦикла; + + Возврат НомерБезПрефиксов; + +КонецФункции + +// Разбирает строку, выделяя из нее префикс и числовую часть. +// +// Параметры: +// Стр - Строка - Разбираемая строка; +// ЧисловаяЧасть - Число - Переменная, в которую возвратится числовая часть строки; +// Режим - Строка - Если "Число", то возвратит числовую часть, иначе - префикс. +// +// Возвращаемое значение: +// Строка - Префикс строки +// +Функция ПолучитьПрефиксЧислоНомера(Знач Стр, ЧисловаяЧасть = "", Режим = "") Экспорт + + ЧисловаяЧасть = 0; + Префикс = ""; + Стр = СокрЛП(Стр); + Длина = СтрДлина(Стр); + + СтроковыйНомерБезПрефикса = ПолучитьСтроковыйНомерБезПрефиксов(Стр); + ДлинаСтроковойЧасти = СтрДлина(СтроковыйНомерБезПрефикса); + Если ДлинаСтроковойЧасти > 0 Тогда + ЧисловаяЧасть = Число(СтроковыйНомерБезПрефикса); + Префикс = Сред(Стр, 1, Длина - ДлинаСтроковойЧасти); + Иначе + Префикс = Стр; + КонецЕсли; + + Если Режим = "Число" Тогда + Возврат(ЧисловаяЧасть); + Иначе + Возврат(Префикс); + КонецЕсли; + +КонецФункции + +// Приводит номер (код) к требуемой длине. При этом выделяется префикс, +// и числовая часть номера, остальное пространство между префиксом и +// номером заполняется нулями. +// Функция может быть использована в обработчиках событий, программный код +// которых хранится в правила обмена данными. Вызывается методом Выполнить(). +// Сообщение "Не обнаружено ссылок на функцию" при проверке конфигурации +// не является ошибкой проверки конфигурации. +// +// Параметры: +// Стр - Строка - преобразовываемая строка. +// Длина - Число - требуемая длина строки. +// ДобавлятьНулиЕслиДлинаНеМеньшеТекущейДлиныНомера - Булево - признак необходимости дополнять нулями. +// Префикс - Строка - префикс который следует добавить к номеру. +// +// Возвращаемое значение: +// Строка - код или номер, приведенная к требуемой длине. +// +Функция ПривестиНомерКДлине(Знач Стр, Длина, ДобавлятьНулиЕслиДлинаНеМеньшеТекущейДлиныНомера = Истина, Префикс = "") Экспорт + + Если ПустаяСтрока(Стр) + ИЛИ СтрДлина(Стр) = Длина Тогда + + Возврат Стр; + + КонецЕсли; + + Стр = СокрЛП(Стр); + ВходящаяДлинаНомера = СтрДлина(Стр); + + ЧисловаяЧасть = ""; + ПрефиксНомераСтроки = ПолучитьПрефиксЧислоНомера(Стр, ЧисловаяЧасть); + + ИтоговыйПрефикс = ?(ПустаяСтрока(Префикс), ПрефиксНомераСтроки, Префикс); + ДлинаИтоговогоПрефикса = СтрДлина(ИтоговыйПрефикс); + + СтрокаЧисловойЧасти = Формат(ЧисловаяЧасть, "ЧГ=0"); + ДлинаЧисловойЧасти = СтрДлина(СтрокаЧисловойЧасти); + + Если (Длина >= ВходящаяДлинаНомера И ДобавлятьНулиЕслиДлинаНеМеньшеТекущейДлиныНомера) + ИЛИ (Длина < ВходящаяДлинаНомера) Тогда + + Для ВременнаяПеременная = 1 По Длина - ДлинаИтоговогоПрефикса - ДлинаЧисловойЧасти Цикл + + СтрокаЧисловойЧасти = "0" + СтрокаЧисловойЧасти; + + КонецЦикла; + + КонецЕсли; + + // обрезаем лишние символы + СтрокаЧисловойЧасти = Прав(СтрокаЧисловойЧасти, Длина - ДлинаИтоговогоПрефикса); + + Результат = ИтоговыйПрефикс + СтрокаЧисловойЧасти; + + Возврат Результат; + +КонецФункции + +// Добавляет к префиксу номера или кода подстроку. +// Функция может быть использована в обработчиках событий, программный код +// которых хранится в правила обмена данными. Вызывается методом Выполнить(). +// Сообщение "Не обнаружено ссылок на функцию" при проверке конфигурации +// не является ошибкой проверки конфигурации. +// +// Параметры: +// Стр - Строка - Номер или код; +// Добавок - Строка - добавляемая к префиксу подстрока; +// Длина - Число - требуемая результирующая длина строки; +// Режим - Строка - "Слева" - подстрока добавляется слева к префиксу, иначе - справа. +// +// Возвращаемое значение: +// Строка - номер или код, к префиксу которого добавлена указанная подстрока. +// +Функция ДобавитьКПрефиксу(Знач Стр, Добавок = "", Длина = "", Режим = "Слева") Экспорт + + Стр = СокрЛП(Формат(Стр,"ЧГ=0")); + + Если ПустаяСтрока(Длина) Тогда + Длина = СтрДлина(Стр); + КонецЕсли; + + ЧисловаяЧасть = ""; + Префикс = ПолучитьПрефиксЧислоНомера(Стр, ЧисловаяЧасть); + + Если Режим = "Слева" Тогда + Результат = СокрЛП(Добавок) + Префикс; + Иначе + Результат = Префикс + СокрЛП(Добавок); + КонецЕсли; + + Пока Длина - СтрДлина(Результат) - СтрДлина(Формат(ЧисловаяЧасть, "ЧГ=0")) > 0 Цикл + Результат = Результат + "0"; + КонецЦикла; + + Результат = Результат + Формат(ЧисловаяЧасть, "ЧГ=0"); + + Возврат Результат; + +КонецФункции + +// Дополняет строку указанным символом до указанной длины. +// +// Параметры: +// Стр - Строка - дополняемая строка; +// Длина - Число - требуемая длина результирующей строки; +// Чем - Строка - символ, которым дополняется строка. +// +// Возвращаемое значение: +// Строка - полученная строка, дополненная указанным символом до указанной длины. +// +Функция одДополнитьСтроку(Стр, Длина, Чем = " ") Экспорт + + Результат = СокрЛП(Стр); + Пока Длина - СтрДлина(Результат) > 0 Цикл + Результат = Результат + Чем; + КонецЦикла; + + Возврат(Результат); + +КонецФункции + +#КонецОбласти + +#Область РаботаСДанными + +// Возвращает строку - имя переданного значения перечисления. +// Функция может быть использована в обработчиках событий, программный код +// которых хранится в правила обмена данными. Вызывается методом Выполнить(). +// Сообщение "Не обнаружено ссылок на функцию" при проверке конфигурации +// не является ошибкой проверки конфигурации. +// +// Параметры: +// Значение - ПеречислениеСсылка - значение перечисления. +// +// Возвращаемое значение: +// Строка - имя переданного значения перечисления. +// +Функция одИмяЗначенияПеречисления(Значение) Экспорт + + ОбъектМД = Значение.Метаданные(); + + МенеджерПеречисления = Перечисления[ОбъектМД.Имя]; // ПеречислениеМенеджер + ИндексЗначения = МенеджерПеречисления.Индекс(Значение); + + Возврат ОбъектМД.ЗначенияПеречисления.Получить(ИндексЗначения).Имя; + +КонецФункции + +// Определяет заполнено ли переданное значение. +// +// Параметры: +// Значение - Произвольный - СправочникСсылка, ДокументСсылка, Строка или любой другой тип. +// Значение, заполнение которого надо проверить. +// ЭтоNULL - Булево - в эту переменную возвращается Истина, если переданное значение NULL. +// +// Возвращаемое значение: +// Булево - Истина - значение не заполнено, ложь - иначе. +// +Функция одПустое(Значение, ЭтоNULL=Ложь) Экспорт + + // Сначала примитивные типы + Если Значение = Неопределено Тогда + Возврат Истина; + ИначеЕсли Значение = NULL Тогда + ЭтоNULL = Истина; + Возврат Истина; + КонецЕсли; + + ТипЗначения = ТипЗнч(Значение); + + Если ТипЗначения = одТипХранилищеЗначения Тогда + + Результат = одПустое(Значение.Получить()); + Возврат Результат; + + ИначеЕсли ТипЗначения = одТипДвоичныеДанные Тогда + + Возврат Ложь; + + Иначе + + // Для остальных будем считать значение пустым, если оно равно + // значению по умолчанию своего типа. + Попытка + Возврат Не ЗначениеЗаполнено(Значение); + Исключение + // На случай мутабельных значений. + Возврат Ложь; + КонецПопытки; + КонецЕсли; + +КонецФункции + +// Возвращает объект ОписаниеТипов, содержащий указанный тип. +// +// Параметры: +// ЗначениеТипа - Строка, Тип - Содержит имя типа или значение типа Тип. +// +// Возвращаемое значение: +// ОписаниеТипов - объект Описание типов. +// +Функция одОписаниеТипа(ЗначениеТипа) Экспорт + + ОписаниеТипов = мСоответствиеОписаниеТипов[ЗначениеТипа]; + + Если ОписаниеТипов = Неопределено Тогда + + МассивТипов = Новый Массив; + Если ТипЗнч(ЗначениеТипа) = одТипСтрока Тогда + МассивТипов.Добавить(Тип(ЗначениеТипа)); + Иначе + МассивТипов.Добавить(ЗначениеТипа); + КонецЕсли; + ОписаниеТипов = Новый ОписаниеТипов(МассивТипов); + + мСоответствиеОписаниеТипов.Вставить(ЗначениеТипа, ОписаниеТипов); + + КонецЕсли; + + Возврат ОписаниеТипов; + +КонецФункции + +// Возвращает пустое (дефолтное) значение указанного типа. +// +// Параметры: +// Тип - Строка, Тип - имя типа или значение типа Тип. +// +// Возвращаемое значение: +// Произвольный - Пустое значение указанного типа. +// +Функция одПолучитьПустоеЗначение(Тип) Экспорт + + ПустоеЗначениеТипа = мСоответствиеПустыхЗначенийТипов[Тип]; + + Если ПустоеЗначениеТипа = Неопределено Тогда + + ПустоеЗначениеТипа = одОписаниеТипа(Тип).ПривестиЗначение(Неопределено); + мСоответствиеПустыхЗначенийТипов.Вставить(Тип, ПустоеЗначениеТипа); + + КонецЕсли; + + Возврат ПустоеЗначениеТипа; + +КонецФункции + +// Осуществляет простой поиск объекта информационной базы по указанному свойству. +// +// Параметры: +// Менеджер - СправочникМенеджер, ДокументМенеджер - Менеджер искомого объекта; +// Свойство - Строка - свойство, по которому осуществляем поиск: Имя, Код, +// Наименование или Имя индексируемого реквизита. +// Значение - Строка, Число, Дата - Значение свойства, по которому ищем объект. +// НайденныйОбъектПоУникальномуИдентификатору - СправочникОбъект, ДокументОбъект - Объект информационной базы, +// который был найден по уникальному идентификатору в ходе выполнения функции. +// ОбщаяСтруктураСвойств - структура - свойства искомого объекта. +// ОбщиеСвойстваПоиска - Структура - общие свойства поиска. +// СтрокаЗапросаПоискаПоУникальномуИдентификатору - Строка - текст запроса для поиска по уникальному идентификатору. +// +// Возвращаемое значение: +// Произвольный - найденный объект информационной базы. +// +Функция НайтиОбъектПоСвойству(Менеджер, Свойство, Значение, + НайденныйОбъектПоУникальномуИдентификатору, + ОбщаяСтруктураСвойств = Неопределено, ОбщиеСвойстваПоиска = Неопределено, + СтрокаЗапросаПоискаПоУникальномуИдентификатору = "") Экспорт + + Если ОбщаяСтруктураСвойств = Неопределено Тогда + Попытка + ТекСтруктураСвойств = Менеджеры[ТипЗнч(Менеджер.ПустаяСсылка())]; + ИмяТипа = ТекСтруктураСвойств.ИмяТипа; + Исключение + ИмяТипа = ""; + КонецПопытки; + Иначе + ИмяТипа = ОбщаяСтруктураСвойств.ИмяТипа; + КонецЕсли; + + Если Свойство = "Имя" Тогда + + Возврат Менеджер[Значение]; + + ИначеЕсли Свойство = "Код" + И (ИмяТипа = "Справочник" + ИЛИ ИмяТипа = "ПланВидовХарактеристик" + ИЛИ ИмяТипа = "ПланСчетов" + ИЛИ ИмяТипа = "ПланОбмена" + ИЛИ ИмяТипа = "ПланВидовРасчета") Тогда + + Возврат Менеджер.НайтиПоКоду(Значение); + + ИначеЕсли Свойство = "Наименование" + И (ИмяТипа = "Справочник" + ИЛИ ИмяТипа = "ПланВидовХарактеристик" + ИЛИ ИмяТипа = "ПланСчетов" + ИЛИ ИмяТипа = "ПланОбмена" + ИЛИ ИмяТипа = "ПланВидовРасчета" + ИЛИ ИмяТипа = "Задача") Тогда + + Возврат Менеджер.НайтиПоНаименованию(Значение, ИСТИНА); + + ИначеЕсли Свойство = "Номер" + И (ИмяТипа = "Документ" + ИЛИ ИмяТипа = "БизнесПроцесс" + ИЛИ ИмяТипа = "Задача") Тогда + + Возврат Менеджер.НайтиПоНомеру(Значение); + + ИначеЕсли Свойство = "{УникальныйИдентификатор}" Тогда + + СсылкаПоИдентификатору = Менеджер.ПолучитьСсылку(Новый УникальныйИдентификатор(Значение)); + + Ссылка = ПроверитьСуществованиеСсылки(СсылкаПоИдентификатору, Менеджер, НайденныйОбъектПоУникальномуИдентификатору, + СтрокаЗапросаПоискаПоУникальномуИдентификатору); + + Возврат Ссылка; + + ИначеЕсли Свойство = "{ИмяПредопределенногоЭлемента}" Тогда + + Попытка + + Ссылка = Менеджер[Значение]; + + Исключение + + Ссылка = Менеджер.НайтиПоКоду(Значение); + + КонецПопытки; + + Возврат Ссылка; + + Иначе + + // Можно найти только по реквизиту, кроме строк произвольной длины и хранилища значений. + Если НЕ (Свойство = "Дата" + ИЛИ Свойство = "Проведен" + ИЛИ Свойство = "ПометкаУдаления" + ИЛИ Свойство = "Владелец" + ИЛИ Свойство = "Родитель" + ИЛИ Свойство = "ЭтоГруппа") Тогда + + Попытка + + СтрокаНеограниченнойДлины = ОпределитьЭтотПараметрНеограниченнойДлинны(ОбщаяСтруктураСвойств, Значение, Свойство); + + Исключение + + СтрокаНеограниченнойДлины = Ложь; + + КонецПопытки; + + Если НЕ СтрокаНеограниченнойДлины Тогда + + Возврат Менеджер.НайтиПоРеквизиту(Свойство, Значение); + + КонецЕсли; + + КонецЕсли; + + СсылкаНаОбъект = НайтиЭлементЗапросом(ОбщаяСтруктураСвойств, ОбщиеСвойстваПоиска, , Менеджер); + Возврат СсылкаНаОбъект; + + КонецЕсли; + +КонецФункции + +// Осуществляет простой поиск объекта информационной базы по указанному свойству. +// +// Параметры: +// Стр - Строка - значение свойства, по которому осуществляется +// поиск объект; +// Тип - Тип - тип искомого объекта; +// Свойство - Строка - имя свойства, по-которому ищем объект. +// +// Возвращаемое значение: +// Произвольный - Найденный объект информационной базы. +// +Функция одПолучитьЗначениеПоСтроке(Стр, Тип, Свойство = "") Экспорт + + Если ПустаяСтрока(Стр) Тогда + Возврат Новый(Тип); + КонецЕсли; + + Свойства = Менеджеры[Тип]; + + Если Свойства = Неопределено Тогда + + ОписаниеТипов = одОписаниеТипа(Тип); + Возврат ОписаниеТипов.ПривестиЗначение(Стр); + + КонецЕсли; + + Если ПустаяСтрока(Свойство) Тогда + + Если Свойства.ИмяТипа = "Перечисление" Тогда + Свойство = "Имя"; + Иначе + Свойство = "{ИмяПредопределенногоЭлемента}"; + КонецЕсли; + + КонецЕсли; + + Возврат НайтиОбъектПоСвойству(Свойства.Менеджер, Свойство, Стр, Неопределено); + +КонецФункции + +// Возвращает строковое представление типа значения. +// +// Параметры: +// ЗначениеИлиТип - Произвольный - Значение любого типа или Тип. +// +// Возвращаемое значение: +// Строка - строковое представление типа значения. +// +Функция одТипЗначенияСтрокой(ЗначениеИлиТип) Экспорт + + ТипЗначения = ТипЗнч(ЗначениеИлиТип); + + Если ТипЗначения = одТипТип Тогда + ТипЗначения = ЗначениеИлиТип; + КонецЕсли; + + Если (ТипЗначения = Неопределено) Или (ЗначениеИлиТип = Неопределено) Тогда + Результат = ""; + ИначеЕсли ТипЗначения = одТипСтрока Тогда + Результат = "Строка"; + ИначеЕсли ТипЗначения = одТипЧисло Тогда + Результат = "Число"; + ИначеЕсли ТипЗначения = одТипДата Тогда + Результат = "Дата"; + ИначеЕсли ТипЗначения = одТипБулево Тогда + Результат = "Булево"; + ИначеЕсли ТипЗначения = одТипХранилищеЗначения Тогда + Результат = "ХранилищеЗначения"; + ИначеЕсли ТипЗначения = одТипУникальныйИдентификатор Тогда + Результат = "УникальныйИдентификатор"; + ИначеЕсли ТипЗначения = одТипВидДвиженияНакопления Тогда + Результат = "ВидДвиженияНакопления"; + Иначе + Менеджер = Менеджеры[ТипЗначения]; + Если Менеджер = Неопределено Тогда + + Текст= НСтр("ru = 'Неизвестный тип:'") + Строка(ТипЗнч(ТипЗначения)); + СообщитьПользователю(Текст); + + Иначе + Результат = Менеджер.ТипСсылкиСтрокой; + КонецЕсли; + КонецЕсли; + + Возврат Результат; + +КонецФункции + +// Возвращает XML представление объекта ОписаниеТипов. +// Функция может быть использована в обработчиках событий, программный код +// которых хранится в правила обмена данными. +// Параметры: +// ОписаниеТипов - ОписаниеТипов - Объект ОписаниеТипов, XML представление которого требуется получить. +// +// Возвращаемое значение: +// Строка - XML представление переданного объекта ОписаниеТипов. +// +Функция одПолучитьXMLПредставлениеОписанияТипов(ОписаниеТипов) Экспорт + + УзелТипов = СоздатьУзел("Типы"); + + Если ТипЗнч(ОписаниеТипов) = Тип("Структура") Тогда + УстановитьАтрибут(УзелТипов, "ДопустимыйЗнак", СокрЛП(ОписаниеТипов.ДопустимыйЗнак)); + УстановитьАтрибут(УзелТипов, "Разрядность", СокрЛП(ОписаниеТипов.Разрядность)); + УстановитьАтрибут(УзелТипов, "РазрядностьДробнойЧасти", СокрЛП(ОписаниеТипов.РазрядностьДробнойЧасти)); + УстановитьАтрибут(УзелТипов, "Длина", СокрЛП(ОписаниеТипов.Длина)); + УстановитьАтрибут(УзелТипов, "ДопустимаяДлина", СокрЛП(ОписаниеТипов.ДопустимаяДлина)); + УстановитьАтрибут(УзелТипов, "СоставДаты", СокрЛП(ОписаниеТипов.ЧастиДаты)); + + Для каждого СтрТип Из ОписаниеТипов.Типы Цикл + УзелТипа = СоздатьУзел("Тип"); + УзелТипа.ЗаписатьТекст(СокрЛП(СтрТип)); + ДобавитьПодчиненный(УзелТипов, УзелТипа); + КонецЦикла; + Иначе + КвЧисла = ОписаниеТипов.КвалификаторыЧисла; + КвСтроки = ОписаниеТипов.КвалификаторыСтроки; + КвДаты = ОписаниеТипов.КвалификаторыДаты; + + УстановитьАтрибут(УзелТипов, "ДопустимыйЗнак", СокрЛП(КвЧисла.ДопустимыйЗнак)); + УстановитьАтрибут(УзелТипов, "Разрядность", СокрЛП(КвЧисла.Разрядность)); + УстановитьАтрибут(УзелТипов, "РазрядностьДробнойЧасти", СокрЛП(КвЧисла.РазрядностьДробнойЧасти)); + УстановитьАтрибут(УзелТипов, "Длина", СокрЛП(КвСтроки.Длина)); + УстановитьАтрибут(УзелТипов, "ДопустимаяДлина", СокрЛП(КвСтроки.ДопустимаяДлина)); + УстановитьАтрибут(УзелТипов, "СоставДаты", СокрЛП(КвДаты.ЧастиДаты)); + + Для каждого Тип Из ОписаниеТипов.Типы() Цикл + УзелТипа = СоздатьУзел("Тип"); + УзелТипа.ЗаписатьТекст(одТипЗначенияСтрокой(Тип)); + ДобавитьПодчиненный(УзелТипов, УзелТипа); + КонецЦикла; + КонецЕсли; + + УзелТипов.ЗаписатьКонецЭлемента(); + + Возврат(УзелТипов.Закрыть()); + +КонецФункции + +#КонецОбласти + +#Область ПроцедурыИФункцииДляРаботыСОбъектомXMLЗапись + +// Заменяет недопустимые символы XML на другой символ. +// +// Параметры: +// Текст - Строка - Текст, в котором следует заменить символы. +// СимволЗамены - Строка - значение на которое следует заменять недопустимые символы. +// Возвращаемое значение: +// Строка - результат замены. +// +Функция ЗаменитьНедопустимыеСимволыXML(Знач Текст, СимволЗамены = " ") Экспорт + + Позиция = НайтиНедопустимыеСимволыXML(Текст); + Пока Позиция > 0 Цикл + Текст = СтрЗаменить(Текст, Сред(Текст, Позиция, 1), СимволЗамены); + Позиция = НайтиНедопустимыеСимволыXML(Текст); + КонецЦикла; + + Возврат Текст; +КонецФункции + +// Создает новый xml-узел +// Функция может быть использована в обработчиках событий, программный код. +// которых хранится в правила обмена данными. Вызывается методом Выполнить(). +// +// Параметры: +// Имя - Строка - имя узла. +// +// Возвращаемое значение: +// ЗаписьXML - объект нового xml-узла. +// +Функция СоздатьУзел(Имя) Экспорт + + ЗаписьXML = Новый ЗаписьXML; + ЗаписьXML.УстановитьСтроку(); + ЗаписьXML.ЗаписатьНачалоЭлемента(Имя); + + Возврат ЗаписьXML; + +КонецФункции + +// Добавляет новый xml-узел к указанному узлу-родителю. +// Функция может быть использована в обработчиках событий, программный код +// которых хранится в правила обмена данными. Вызывается методом Выполнить(). +// Сообщение "Не обнаружено ссылок на функцию" при проверке конфигурации +// не является ошибкой проверки конфигурации. +// +// Параметры: +// УзелРодитель - xml-узел-родитель. +// Имя - Строка - имя добавляемого узла. +// +// Возвращаемое значение: +// Новый xml-узел, добавленный к указанному узлу-родителю. +// +Функция ДобавитьУзел(УзелРодитель, Имя) Экспорт + + УзелРодитель.ЗаписатьНачалоЭлемента(Имя); + + Возврат УзелРодитель; + +КонецФункции + +// Копирует указанный xml-узел. +// Функция может быть использована в обработчиках событий, программный код +// которых хранится в правила обмена данными. Вызывается методом Выполнить(). +// Сообщение "Не обнаружено ссылок на функцию" при проверке конфигурации +// не является ошибкой проверки конфигурации. +// +// Параметры: +// Узел - xml - узел. +// +// Возвращаемое значение: +// Новый xml - копия указанного узла. +// +Функция КопироватьУзел(Узел) Экспорт + + Стр = Узел.Закрыть(); + + ЗаписьXML = Новый ЗаписьXML; + ЗаписьXML.УстановитьСтроку(); + + Если ВестиДополнительныйКонтрольЗаписиВXML Тогда + + Стр = УдалитьНедопустимыеСимволыXML(Стр); + + КонецЕсли; + + ЗаписьXML.ЗаписатьБезОбработки(Стр); + + Возврат ЗаписьXML; + +КонецФункции + +// Осуществляет запись элемента и его значения в указанный объект. +// +// Параметры: +// Объект - ЗаписьXML - объект типа XMLЗапись. +// Имя - Строка - Имя элемента. +// Значение - Произвольный - Значение элемента. +// +Процедура одЗаписатьЭлемент(Объект, Имя, Значение="") Экспорт + + Объект.ЗаписатьНачалоЭлемента(Имя); + Стр = XMLСтрока(Значение); + + Если ВестиДополнительныйКонтрольЗаписиВXML Тогда + + Стр = УдалитьНедопустимыеСимволыXML(Стр); + + КонецЕсли; + + Объект.ЗаписатьТекст(Стр); + Объект.ЗаписатьКонецЭлемента(); + +КонецПроцедуры + +// Подчиняет xml-узел указанному узлу-родителю. +// +// Параметры: +// УзелРодитель - xml-узел-родитель. +// Узел - xml - подчиняемый узел. +// +Процедура ДобавитьПодчиненный(УзелРодитель, Узел) Экспорт + + Если ТипЗнч(Узел) <> одТипСтрока Тогда + Узел.ЗаписатьКонецЭлемента(); + ИнформацияДляЗаписиВФайл = Узел.Закрыть(); + Иначе + ИнформацияДляЗаписиВФайл = Узел; + КонецЕсли; + + УзелРодитель.ЗаписатьБезОбработки(ИнформацияДляЗаписиВФайл); + +КонецПроцедуры + +// Устанавливает атрибут указанного xml-узла. +// +// Параметры: +// Узел - xml-узел +// Имя - Строка - имя атрибута. +// Значение - Произвольный - устанавливаемое значение. +// +Процедура УстановитьАтрибут(Узел, Имя, Значение) Экспорт + + СтрокаЗаписи = XMLСтрока(Значение); + + Если ВестиДополнительныйКонтрольЗаписиВXML Тогда + + СтрокаЗаписи = УдалитьНедопустимыеСимволыXML(СтрокаЗаписи); + + КонецЕсли; + + Узел.ЗаписатьАтрибут(Имя, СтрокаЗаписи); + +КонецПроцедуры + +#КонецОбласти + +#Область ПроцедурыИФункцииДляРаботыСОбъектомXMLЧтение + +// Читает значение атрибута по имени из указанного объекта, приводит значение +// к указанному примитивному типу. +// +// Параметры: +// Объект - ЧтениеXML - объект типа XMLЧтение, спозиционированный на начале элемента, +// атрибут которого требуется получить. +// Тип - Тип - Тип атрибута. +// Имя - Строка - Имя атрибута. +// +// Возвращаемое значение: +// Произвольный - Значение атрибута полученное по имени и приведенное к указанному типу. +// +Функция одАтрибут(Объект, Тип, Имя) Экспорт + + СтрЗначение = Объект.ПолучитьАтрибут(Имя); + Если Не ПустаяСтрока(СтрЗначение) Тогда + Возврат XMLЗначение(Тип, СокрП(СтрЗначение)); + ИначеЕсли Тип = одТипСтрока Тогда + Возврат ""; + ИначеЕсли Тип = одТипБулево Тогда + Возврат Ложь; + ИначеЕсли Тип = одТипЧисло Тогда + Возврат 0; + ИначеЕсли Тип = одТипДата Тогда + Возврат ЗначениеПустаяДата; + КонецЕсли; + +КонецФункции + +// Пропускает узлы xml до конца указанного элемента (по умолчанию текущего). +// +// Параметры: +// Объект - ЧтениеXML - объект типа XMLЧтение. +// Имя - Строка - имя узла, до конца которого пропускаем элементы. +// +Процедура одПропустить(Объект, Имя = "") Экспорт + + КоличествоВложений = 0; // Количество одноименных вложений. + + Если Имя = "" Тогда + + Имя = Объект.ЛокальноеИмя; + + КонецЕсли; + + Пока Объект.Прочитать() Цикл + + Если Объект.ЛокальноеИмя <> Имя Тогда + Продолжить; + КонецЕсли; + + ТипУзла = Объект.ТипУзла; + + Если ТипУзла = одТипУзлаXML_КонецЭлемента Тогда + + Если КоличествоВложений = 0 Тогда + + Прервать; + + Иначе + + КоличествоВложений = КоличествоВложений - 1; + + КонецЕсли; + + ИначеЕсли ТипУзла = одТипУзлаXML_НачалоЭлемента Тогда + + КоличествоВложений = КоличествоВложений + 1; + + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + +// Читает текст элемента и приводит значение к указанному типу. +// +// Параметры: +// Объект - ЧтениеXML - объект типа XMLЧтение, из которого осуществляется чтение. +// Тип - Тип - тип получаемого значения. +// ИскатьПоСвойству - Строка - для ссылочных типов может быть указано свойство, по которому. +// следует искать объект: "Код", "Наименование", <ИмяРеквизита>, "Имя" (предопределенного значения). +// ОбрезатьСтрокуСправа - Булево - признак необходимости обрезать строку справа. +// +// Возвращаемое значение: +// Значение xml-элемента, приведенное к соответствующему типу. +// +Функция одЗначениеЭлемента(Объект, Тип, ИскатьПоСвойству = "", ОбрезатьСтрокуСправа = Истина) Экспорт + + Значение = ""; + Имя = Объект.ЛокальноеИмя; + + Пока Объект.Прочитать() Цикл + + ТипУзла = Объект.ТипУзла; + + Если ТипУзла = одТипУзлаXML_Текст Тогда + + Значение = Объект.Значение; + + Если ОбрезатьСтрокуСправа Тогда + + Значение = СокрП(Значение); + + КонецЕсли; + + ИначеЕсли (Объект.ЛокальноеИмя = Имя) И (ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + + Прервать; + + Иначе + + Возврат Неопределено; + + КонецЕсли; + + КонецЦикла; + + + Если (Тип = одТипСтрока) + ИЛИ (Тип = одТипБулево) + ИЛИ (Тип = одТипЧисло) + ИЛИ (Тип = одТипДата) + ИЛИ (Тип = одТипХранилищеЗначения) + ИЛИ (Тип = одТипУникальныйИдентификатор) + ИЛИ (Тип = одТипВидДвиженияНакопления) + ИЛИ (Тип = одТипВидСчета) Тогда + + Возврат XMLЗначение(Тип, Значение); + + Иначе + + Возврат одПолучитьЗначениеПоСтроке(Значение, Тип, ИскатьПоСвойству); + + КонецЕсли; + +КонецФункции + +#КонецОбласти + +#Область ПроцедурыИФункцииРаботыСФайломОбмена + +// Сохраняет в файл указанный xml-узел. +// +// Параметры: +// Узел - xml-узел, сохраняемый в файл. +// +Процедура ЗаписатьВФайл(Узел) Экспорт + + Если ТипЗнч(Узел) <> одТипСтрока Тогда + ИнформацияДляЗаписиВФайл = Узел.Закрыть(); + Иначе + ИнформацияДляЗаписиВФайл = Узел; + КонецЕсли; + + Если НепосредственноеЧтениеВИБПриемнике Тогда + + СтрокаОшибкиВБазеПриемнике = ""; + ПередатьИнформациюОЗаписиВПриемник(ИнформацияДляЗаписиВФайл, СтрокаОшибкиВБазеПриемнике); + Если Не ПустаяСтрока(СтрокаОшибкиВБазеПриемнике) Тогда + + ВызватьИсключение СтрокаОшибкиВБазеПриемнике; + + КонецЕсли; + + Иначе + + ФайлОбмена.ЗаписатьСтроку(ИнформацияДляЗаписиВФайл); + + КонецЕсли; + +КонецПроцедуры + +#КонецОбласти + +#Область ПроцедурыИФункцииРаботыСПротоколомОбмена + +// Возвращает объект типа структура, содержащий все возможные поля +// записи протокола выполнения (сообщения об ошибках и т.п.). +// +// Параметры: +// КодСообщения - Строка - код сообщения. +// СтрокаОшибки - Строка - строковое содержание ошибки. +// +// Возвращаемое значение: +// Структура - все возможные поля записи протокола выполнения. +// +Функция ПолучитьСтруктуруЗаписиПротокола(КодСообщения = "", СтрокаОшибки = "") Экспорт + + СтруктураОшибки = Новый Структура( + "ИмяПКО, + |ИмяПОД, + |Нпп, + |Гнпп, + |Источник, + |ТипОбъекта, + |Свойство, + |Значение, + |ТипЗначения, + |ПКО, + |ПКС, + |ПКГС, + |ПВД, + |ПОД, + |Объект, + |СвойствоПриемника, + |КонвертируемоеЗначение, + |Обработчик, + |ОписаниеОшибки, + |ПозицияМодуля, + |Текст, + |КодСообщения, + |УзелПланаОбмена"); + + СтрокаМодуля = ОтделитьРазделителем(СтрокаОшибки, "{"); + Если ПустаяСтрока(СтрокаОшибки) Тогда + ОписаниеОшибки = СокрЛП(ОтделитьРазделителем(СтрокаМодуля, "}:")); + Иначе + ОписаниеОшибки = СтрокаОшибки; + СтрокаМодуля = "{" + СтрокаМодуля; + КонецЕсли; + + Если ОписаниеОшибки <> "" Тогда + СтруктураОшибки.ОписаниеОшибки = ОписаниеОшибки; + СтруктураОшибки.ПозицияМодуля = СтрокаМодуля; + КонецЕсли; + + Если СтруктураОшибки.КодСообщения <> "" Тогда + + СтруктураОшибки.КодСообщения = КодСообщения; + + КонецЕсли; + + Возврат СтруктураОшибки; + +КонецФункции + +// Записывает информацию об ошибке в протокол выполнения обмена. +// +// Параметры: +// КодСообщения - Строка - код сообщения. +// СтрокаОшибки - Строка - строковое содержание ошибки. +// Объект - Произвольный - Объект, к которому относится ошибка. +// ТипОбъекта - Тип - тип объекта к которому относится ошибка. +// +// Возвращаемое значение: +// Строка - строка ошибки. +// +Функция ЗаписатьИнформациюОбОшибкеВПротокол(КодСообщения, СтрокаОшибки, Объект, ТипОбъекта = Неопределено) Экспорт + + ЗП = ПолучитьСтруктуруЗаписиПротокола(КодСообщения, СтрокаОшибки); + ЗП.Объект = Объект; + + Если ТипОбъекта <> Неопределено Тогда + ЗП.ТипОбъекта = ТипОбъекта; + КонецЕсли; + + СтрокаОшибки = ЗаписатьВПротоколВыполнения(КодСообщения, ЗП); + + Возврат СтрокаОшибки; + +КонецФункции + +// Регистрирует в протоколе выполнения ошибку обработчика ПКО (загрузка). +// +// Параметры: +// КодСообщения - Строка - код сообщения. +// СтрокаОшибки - Строка - строковое содержание ошибки. +// ИмяПравила - строка - имя правила конвертации объекта. +// Источник - Произвольный - источник при конвертации которого возникла ошибка. +// ТипОбъекта - Тип - тип объекта при конвертации которого возникла ошибка. +// Объект - Произвольный - объект, полученный в результате конвертации. +// ИмяОбработчика - Строка - имя обработчика в котором возникла ошибка. +// +Процедура ЗаписатьИнформациюОбОшибкеЗагрузкиОбработчикаПКО(КодСообщения, СтрокаОшибки, ИмяПравила, Источник, + ТипОбъекта, Объект, ИмяОбработчика) Экспорт + + ЗП = ПолучитьСтруктуруЗаписиПротокола(КодСообщения, СтрокаОшибки); + ЗП.ИмяПКО = ИмяПравила; + ЗП.ТипОбъекта = ТипОбъекта; + ЗП.Обработчик = ИмяОбработчика; + + Если Не ПустаяСтрока(Источник) Тогда + + ЗП.Источник = Источник; + + КонецЕсли; + + Если Объект <> Неопределено Тогда + + ЗП.Объект = Строка(Объект); + + КонецЕсли; + + СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(КодСообщения, ЗП); + + Если Не ФлагРежимОтладки Тогда + ВызватьИсключение СтрокаСообщенияОбОшибке; + КонецЕсли; + +КонецПроцедуры + +// Регистрирует в протоколе выполнения ошибку обработчика ПКС. +// +// Параметры: +// КодСообщения - Строка - код сообщения. +// СтрокаОшибки - Строка - строковое содержание ошибки. +// ПКО - СтрокаТаблицыЗначений - Правило конвертации объекта. +// ПКС - СтрокаТаблицыЗначений - Правило конвертации свойства. +// Источник - Произвольный - источник при конвертации которого возникла ошибка. +// ИмяОбработчика - Строка - имя обработчика в котором возникла ошибка. +// Значение - Произвольный - значение, при конвертации которого возникла ошибка. +// ЭтоПКС - Булево - ошибка возникла при обработке правила конвертации свойств. +// +Процедура ЗаписатьИнформациюОбОшибкеОбработчикиПКС(КодСообщения, СтрокаОшибки, ПКО, ПКС, Источник = "", + ИмяОбработчика = "", Значение = Неопределено, ЭтоПКС = Истина) Экспорт + + ЗП = ПолучитьСтруктуруЗаписиПротокола(КодСообщения, СтрокаОшибки); + ЗП.ПКО = ПКО.Имя + " (" + ПКО.Наименование + ")"; + + ИмяПравила = ПКС.Имя + " (" + ПКС.Наименование + ")"; + Если ЭтоПКС Тогда + ЗП.ПКС = ИмяПравила; + Иначе + ЗП.ПКГС = ИмяПравила; + КонецЕсли; + + ОписаниеТипов = Новый ОписаниеТипов("Строка"); + ИсточникСтрока = ОписаниеТипов.ПривестиЗначение(Источник); + Если Не ПустаяСтрока(ИсточникСтрока) Тогда + ЗП.Объект = ИсточникСтрока + " (" + ТипЗнч(Источник) + ")"; + Иначе + ЗП.Объект = "(" + ТипЗнч(Источник) + ")"; + КонецЕсли; + + Если ЭтоПКС Тогда + ЗП.СвойствоПриемника = ПКС.Приемник + " (" + ПКС.ТипПриемника + ")"; + КонецЕсли; + + Если ИмяОбработчика <> "" Тогда + ЗП.Обработчик = ИмяОбработчика; + КонецЕсли; + + Если Значение <> Неопределено Тогда + ЗП.КонвертируемоеЗначение = Строка(Значение) + " (" + ТипЗнч(Значение) + ")"; + КонецЕсли; + + СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(КодСообщения, ЗП); + + Если Не ФлагРежимОтладки Тогда + ВызватьИсключение СтрокаСообщенияОбОшибке; + КонецЕсли; + +КонецПроцедуры + +#КонецОбласти + +#Область ПроцедурыСозданияИнтерфейсаВызоваОбработчиковВПравилахОбмена + +// Дополняет имеющиеся коллекции с правилами обмена интерфейсами вызова обработчиков. +// +// Параметры: +// СтруктураКонвертация - Структура - содержит правила конвертации и глобальные обработчики. +// ТаблицаПКО - ТаблицаЗначений - содержит правила конвертации объектов. +// ТаблицаПВД - ДеревоЗначений - содержит правила выгрузки данных. +// ТаблицаПОД - ДеревоЗначений - содержит правила очистки данных. +// +Процедура ДополнитьПравилаИнтерфейсамиОбработчиков(СтруктураКонвертация, ТаблицаПКО, ТаблицаПВД, ТаблицаПОД) Экспорт + + мМакетПараметровОбработчиков = ПолучитьМакет("ПараметрыОбработчиков"); + + // Добавляем интерфейсы Конвертации (глобальные). + ДополнитьИнтерфейсамиОбработчиковПравилаКонвертации(СтруктураКонвертация); + + // Добавляем интерфейсы ПВД + ДополнитьИнтерфейсамиОбработчиковПравилаВыгрузкиДанных(ТаблицаПВД, ТаблицаПВД.Строки); + + // Добавляем интерфейсы ПОД + ДополнитьИнтерфейсамиОбработчиковПравилаОчисткиДанных(ТаблицаПОД, ТаблицаПОД.Строки); + + // Добавляем интерфейсы ПКО, ПКС, ПКГС. + ДополнитьИнтерфейсамиОбработчиковПравилаКонвертацииОбъектов(ТаблицаПКО); + +КонецПроцедуры + +#КонецОбласти + +#Область ПроцедурыРаботыСПравиламиОбмена + +// Осуществляет поиск правила конвертации по имени или в соответствии с типом +// переданного объекта. +// +// Параметры: +// Объект - Произвольный - объект-источник, для которого ищем правило конвертации. +// ИмяПравила - Строка - имя правила конвертации. +// +// Возвращаемое значение: +// СтрокаТаблицыЗначений - ссылка на правило конвертации (строка в таблице правил): +// * Имя - Строка - +// * Наименование - Строка - +// * Источник - Строка - +// * Свойства - см. КоллекцияПравилаКонвертацииСвойств +// +Функция НайтиПравило(Объект = Неопределено, ИмяПравила = "") Экспорт + + Если Не ПустаяСтрока(ИмяПравила) Тогда + + Правило = Правила[ИмяПравила]; // см. НайтиПравило + + Иначе + + Правило = Менеджеры[ТипЗнч(Объект)]; + Если Правило <> Неопределено Тогда + Правило = Правило.ПКО; // см. НайтиПравило + + Если Правило <> Неопределено Тогда + ИмяПравила = Правило.Имя; + КонецЕсли; + + КонецЕсли; + + КонецЕсли; + + Возврат Правило; + +КонецФункции + +// Сохраняет правила обмена во внутреннем формате. +// +Процедура СохранитьПравилаВоВнутреннемФормате() Экспорт + + Для Каждого Правило Из ТаблицаПравилКонвертации Цикл + Правило.Выгруженные.Очистить(); + Правило.ВыгруженныеТолькоСсылки.Очистить(); + КонецЦикла; + + СтруктураПравил = ОписаниеСтруктурыПравил(); + + // Сохраняем запросы + ЗапросыДляСохранения = Новый Структура; + Для Каждого ЭлементСтруктуры Из Запросы Цикл + ЗапросыДляСохранения.Вставить(ЭлементСтруктуры.Ключ, ЭлементСтруктуры.Значение.Текст); + КонецЦикла; + + ПараметрыДляСохранения = Новый Структура; + Для Каждого ЭлементСтруктуры Из Параметры Цикл + ПараметрыДляСохранения.Вставить(ЭлементСтруктуры.Ключ, Неопределено); + КонецЦикла; + + СтруктураПравил.ТаблицаПравилВыгрузки = ТаблицаПравилВыгрузки; + СтруктураПравил.ТаблицаПравилКонвертации = ТаблицаПравилКонвертации; + СтруктураПравил.Алгоритмы = Алгоритмы; + СтруктураПравил.Запросы = ЗапросыДляСохранения; + СтруктураПравил.Конвертация = Конвертация; + СтруктураПравил.мXMLПравила = мXMLПравила; + СтруктураПравил.ТаблицаНастройкиПараметров = ТаблицаНастройкиПараметров; + СтруктураПравил.Параметры = ПараметрыДляСохранения; + + СтруктураПравил.Вставить("ВерсияПлатформыПриемника", ВерсияПлатформыПриемника); + + СохраненныеНастройки = Новый ХранилищеЗначения(СтруктураПравил); + +КонецПроцедуры + +// Устанавливает значения параметров в структуре Параметры +// по таблице ТаблицаНастройкиПараметров. +// +Процедура УстановитьПараметрыИзДиалога() Экспорт + + Для Каждого СтрокаТаблицы Из ТаблицаНастройкиПараметров Цикл + Параметры.Вставить(СтрокаТаблицы.Имя, СтрокаТаблицы.Значение); + КонецЦикла; + +КонецПроцедуры + +// Устанавливает значение параметра в таблице параметров в форме обработки. +// +// Параметры: +// ИмяПараметра - Строка - Имя параметра. +// ЗначениеПараметра - Произвольный - значение параметра. +// +Процедура УстановитьЗначениеПараметраВТаблице(ИмяПараметра, ЗначениеПараметра) Экспорт + + СтрокаТаблицы = ТаблицаНастройкиПараметров.Найти(ИмяПараметра, "Имя"); + + Если СтрокаТаблицы <> Неопределено Тогда + + СтрокаТаблицы.Значение = ЗначениеПараметра; + + КонецЕсли; + +КонецПроцедуры + +#КонецОбласти + +#Область ОбработкаПравилОчистки + +// Производит удаление (или помечает на удаление) объект выборки в соответствии с указанным правилом. +// +// Параметры: +// Объект - Произвольный - удаляемый (помечаемый на удаление) объект выборки. +// Правило - СтрокаТаблицыЗначений - ссылка на правило очистки данных. +// Свойства - Менеджер - свойства объекта метаданного удаляемого объекта. +// ВходящиеДанные - Произвольный - произвольные вспомогательные данные. +// +Процедура УдалениеОбъектаВыборки(Объект, Правило, Свойства=Неопределено, ВходящиеДанные=Неопределено) Экспорт + + Если БезопасныйРежим Тогда + УстановитьБезопасныйРежим(Истина); + Для Каждого ИмяРазделителя Из РазделителиКонфигурации Цикл + УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина); + КонецЦикла; + КонецЕсли; + + Отказ = Ложь; + УдалитьНепосредственно = Правило.Непосредственно; + + + // Обработчик ПередУдалениемОбъектаВыборки + Если Не ПустаяСтрока(Правило.ПередУдалением) Тогда + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(Правило, "ПередУдалением")); + + Иначе + + Выполнить(Правило.ПередУдалением); + + КонецЕсли; + + Исключение + + ЗаписатьИнформациюОбОшибкеОбработчикаОчисткиДанных(29, ОписаниеОшибки(), Правило.Имя, Объект, "ПередУдалениемОбъектаВыборки"); + + КонецПопытки; + + Если Отказ Тогда + + Возврат; + + КонецЕсли; + + КонецЕсли; + + + Попытка + + ВыполнитьУдалениеОбъекта(Объект, Свойства, УдалитьНепосредственно); + + Исключение + + ЗаписатьИнформациюОбОшибкеОбработчикаОчисткиДанных(24, ОписаниеОшибки(), Правило.Имя, Объект, ""); + + КонецПопытки; + +КонецПроцедуры + +#КонецОбласти + +#Область ПроцедурыВыгрузкиДанных + +// Производит выгрузку объекта в соответствии с указанным правилом конвертации. +// +// Параметры: +// Источник - Произвольный - источник данных. +// Приемник - ЗаписьXML - xml-узел объекта приемника. +// ВходящиеДанные - Произвольный - произвольные вспомогательные данные, +// для выполнения конвертации. +// ИсходящиеДанные - Произвольный - произвольные вспомогательные данные, передаваемые правилам +// передаваемые правилу конвертации свойств. +// ИмяПКО - Строка - имя правила конвертации, согласно которому осуществляется выгрузка. +// УзелСсылки - xml-узел ссылки объекта приемника. +// ТолькоПолучитьУзелСсылки - Булево - если Истина, то выгрузка объекта не производится, +// только формируется xml-узел ссылки. +// ПКО - СтрокаТаблицыЗначений - строка таблицы правил конвертации. +// ЭтоПравилоСГлобальнойВыгрузкойОбъектов - Булево - признак правила с глобальной выгрузкой объектов. +// ВыборкаДляВыгрузкиДанных - ВыборкаРезультатаЗапроса - выборка содержащая данные для выгрузки. +// +// Возвращаемое значение: +// ЗаписьXML - xml-узел ссылки или значение приемника. +// +Функция ВыгрузитьПоПравилу(Источник = Неопределено, + Приемник = Неопределено, + ВходящиеДанные = Неопределено, + ИсходящиеДанные = Неопределено, + ИмяПКО = "", + УзелСсылки = Неопределено, + ТолькоПолучитьУзелСсылки = Ложь, + ПКО = Неопределено, + ЭтоПравилоСГлобальнойВыгрузкойОбъектов = Ложь, + ВыборкаДляВыгрузкиДанных = Неопределено) Экспорт + + Если БезопасныйРежим Тогда + УстановитьБезопасныйРежим(Истина); + Для Каждого ИмяРазделителя Из РазделителиКонфигурации Цикл + УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина); + КонецЦикла; + КонецЕсли; + + // Поиск ПКО + Если ПКО = Неопределено Тогда + + ПКО = НайтиПравило(Источник, ИмяПКО); + + ИначеЕсли (Не ПустаяСтрока(ИмяПКО)) + И ПКО.Имя <> ИмяПКО Тогда + + ПКО = НайтиПравило(Источник, ИмяПКО); + + КонецЕсли; + + Если ПКО = Неопределено Тогда + + ЗП = ПолучитьСтруктуруЗаписиПротокола(45); + + ЗП.Объект = Источник; + ЗП.ТипОбъекта = ТипЗнч(Источник); + + ЗаписатьВПротоколВыполнения(45, ЗП, Истина); // не найдено ПКО + Возврат Неопределено; + + КонецЕсли; + + ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу + 1; + + Если ФлагКомментироватьОбработкуОбъектов Тогда + + ОписаниеТипа = Новый ОписаниеТипов("Строка"); + ИсточникВСтроку = ОписаниеТипа.ПривестиЗначение(Источник); + ИсточникВСтроку = ?(ИсточникВСтроку = "", " ", ИсточникВСтроку); + + ПрОбъекта = ИсточникВСтроку + " (" + ТипЗнч(Источник) + ")"; + + СтрокаНазванияПКО = " ПКО: " + СокрЛП(ИмяПКО) + " (" + СокрЛП(ПКО.Наименование) + ")"; + + СтрокаПользователю = ?(ТолькоПолучитьУзелСсылки, НСтр("ru = 'Конвертация ссылки на объект: %1'"), НСтр("ru = 'Конвертация объекта: %1'")); + СтрокаПользователю = ПодставитьПараметрыВСтроку(СтрокаПользователю, ПрОбъекта); + + ЗаписатьВПротоколВыполнения(СтрокаПользователю + СтрокаНазванияПКО, , Ложь, ТекущийУровеньВложенностиВыгрузитьПоПравилу + 1, 7); + + КонецЕсли; + + ЭтоПравилоСГлобальнойВыгрузкойОбъектов = ВыполнитьОбменДаннымиВОптимизированномФормате И ПКО.ИспользоватьБыстрыйПоискПриЗагрузке; + + ЗапоминатьВыгруженные = ПКО.ЗапоминатьВыгруженные; + ВыгруженныеОбъекты = ПКО.Выгруженные; + ВыгруженныеОбъектыТолькоСсылки = ПКО.ВыгруженныеТолькоСсылки; + ВсеОбъектыВыгружены = ПКО.ВсеОбъектыВыгружены; + НеЗамещатьОбъектПриЗагрузке = ПКО.НеЗамещать; + НеСоздаватьЕслиНеНайден = ПКО.НеСоздаватьЕслиНеНайден; + ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD = ПКО.ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD; + + ПрефиксАвтонумерации = ""; + РежимЗаписи = ""; + РежимПроведения = ""; + СписокВременныхФайлов = Неопределено; + + ИмяТипа = ""; + СтруктураСвойств = Менеджеры[ПКО.Источник]; + Если СтруктураСвойств = Неопределено Тогда + СтруктураСвойств = Менеджеры[ТипЗнч(Источник)]; + КонецЕсли; + + Если СтруктураСвойств <> Неопределено Тогда + ИмяТипа = СтруктураСвойств.ИмяТипа; + КонецЕсли; + + // КлючВыгружаемыхДанных + + Если (Источник <> Неопределено) И ЗапоминатьВыгруженные Тогда + Если ИмяТипа = "РегистрСведений" ИЛИ ИмяТипа = "Константы" ИЛИ ПустаяСтрока(ИмяТипа) Тогда + ЗапоминатьВыгруженные = Ложь; + Иначе + КлючВыгружаемыхДанных = ЗначениеВСтрокуВнутр(Источник); + КонецЕсли; + Иначе + КлючВыгружаемыхДанных = ИмяПКО; + ЗапоминатьВыгруженные = Ложь; + КонецЕсли; + + + // Переменная для хранения имени предопределенного элемента. + ИмяПредопределенногоЭлемента = Неопределено; + + // Глобальный обработчик ПередКонвертациейОбъекта. + Отказ = Ложь; + Если ЕстьГлобальныйОбработчикПередКонвертациейОбъекта Тогда + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(Конвертация, "ПередКонвертациейОбъекта")); + + Иначе + + Выполнить(Конвертация.ПередКонвертациейОбъекта); + + КонецЕсли; + + Исключение + ЗаписатьИнформациюОбОшибкеВыгрузкиОбработчикаПКО(64, ОписаниеОшибки(), ПКО, Источник, НСтр("ru = 'ПередКонвертациейОбъекта (глобальный)'")); + КонецПопытки; + + Если Отказ Тогда // Отказ от дальнейшей обработки правила. + ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу - 1; + Возврат Приемник; + КонецЕсли; + + КонецЕсли; + + // Обработчик ПередВыгрузкой + Если ПКО.ЕстьОбработчикПередВыгрузкой Тогда + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(ПКО, "ПередВыгрузкой")); + + Иначе + + Выполнить(ПКО.ПередВыгрузкой); + + КонецЕсли; + + Исключение + ЗаписатьИнформациюОбОшибкеВыгрузкиОбработчикаПКО(41, ОписаниеОшибки(), ПКО, Источник, "ПередВыгрузкойОбъекта"); + КонецПопытки; + + Если Отказ Тогда // Отказ от дальнейшей обработки правила. + ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу - 1; + Возврат Приемник; + КонецЕсли; + + КонецЕсли; + + // Возможно такие данные уже выгружались. + Если Не ВсеОбъектыВыгружены Тогда + + НПП = 0; + + Если ЗапоминатьВыгруженные Тогда + + УзелСсылки = ВыгруженныеОбъекты[КлючВыгружаемыхДанных]; + Если УзелСсылки <> Неопределено Тогда + + Если ТолькоПолучитьУзелСсылки Тогда + ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу - 1; + Возврат УзелСсылки; + КонецЕсли; + + НомерВыгруженнойСсылки = ВыгруженныеОбъектыТолькоСсылки[КлючВыгружаемыхДанных]; + Если НомерВыгруженнойСсылки = Неопределено Тогда + ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу - 1; + Возврат УзелСсылки; + Иначе + + СтрокаВСтекеВыгрузки = КоллекцияСтекВызововВыгрузкиДанных().Найти(КлючВыгружаемыхДанных, "Ссылка"); + + Если СтрокаВСтекеВыгрузки <> Неопределено Тогда + ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу - 1; + Возврат УзелСсылки; + КонецЕсли; + + СтрокаВСтекеВыгрузки = КоллекцияСтекВызововВыгрузкиДанных().Добавить(); + СтрокаВСтекеВыгрузки.Ссылка = КлючВыгружаемыхДанных; + + НПП = НомерВыгруженнойСсылки; + КонецЕсли; + КонецЕсли; + + КонецЕсли; + + Если НПП = 0 Тогда + + мСчетчикНПП = мСчетчикНПП + 1; + НПП = мСчетчикНПП; + + КонецЕсли; + + // Это позволит избежать циклических ссылок. + Если ЗапоминатьВыгруженные Тогда + + ВыгруженныеОбъекты[КлючВыгружаемыхДанных] = НПП; + Если ТолькоПолучитьУзелСсылки Тогда + ВыгруженныеОбъектыТолькоСсылки[КлючВыгружаемыхДанных] = НПП; + Иначе + + СтрокаВСтекеВыгрузки = КоллекцияСтекВызововВыгрузкиДанных().Добавить(); + СтрокаВСтекеВыгрузки.Ссылка = КлючВыгружаемыхДанных; + + КонецЕсли; + + КонецЕсли; + + КонецЕсли; + + СоответствиеЗначений = ПКО.Значения; + КоличествоЭлементовСоответствияЗначений = СоответствиеЗначений.Количество(); + + // Обработка соответствий предопределенных элементов. + Если ПлатформаПриемника = "V8" Тогда + + // Если имя предопределенного элемента пока не определено, то попытаемся его определить. + Если ИмяПредопределенногоЭлемента = Неопределено Тогда + + Если СтруктураСвойств <> Неопределено + И КоличествоЭлементовСоответствияЗначений > 0 + И СтруктураСвойств.ВозможенПоискПоПредопределенным Тогда + + Попытка + ИмяПредопределенногоИсточник = ИмяПредопределенного(Источник); + Исключение + ИмяПредопределенногоИсточник = ""; + КонецПопытки; + + Иначе + + ИмяПредопределенногоИсточник = ""; + + КонецЕсли; + + Если НЕ ПустаяСтрока(ИмяПредопределенногоИсточник) + И КоличествоЭлементовСоответствияЗначений > 0 Тогда + + ИмяПредопределенногоЭлемента = СоответствиеЗначений[Источник]; + + Иначе + ИмяПредопределенногоЭлемента = Неопределено; + КонецЕсли; + + КонецЕсли; + + Если ИмяПредопределенногоЭлемента <> Неопределено Тогда + КоличествоЭлементовСоответствияЗначений = 0; + КонецЕсли; + + Иначе + ИмяПредопределенногоЭлемента = Неопределено; + КонецЕсли; + + НеНужноВыгружатьПоСоответствиюЗначений = (КоличествоЭлементовСоответствияЗначений = 0); + + Если Не НеНужноВыгружатьПоСоответствиюЗначений Тогда + + // Если нет объекта в соответствии значений - выгружаем его штатным образом. + УзелСсылки = СоответствиеЗначений[Источник]; + Если УзелСсылки = Неопределено + И ПКО.СвойстваПоиска.Количество() > 0 Тогда + + // Возможно это конвертация из перечисления в перечисление и мы просто не нашли по. + // ПКЗ нужное свойство - тогда просто выгружаем пустую ссылку и все. + Если СтруктураСвойств.ИмяТипа = "Перечисление" + И СтрНайти(ПКО.Приемник, "ПеречислениеСсылка.") > 0 Тогда + + УзелСсылки = ""; + + Иначе + + НеНужноВыгружатьПоСоответствиюЗначений = Истина; + + КонецЕсли; + + КонецЕсли; + + КонецЕсли; + + НужноЗапоминатьОбъект = ЗапоминатьВыгруженные И (Не ВсеОбъектыВыгружены); + + Если НеНужноВыгружатьПоСоответствиюЗначений Тогда + + Если ПКО.СвойстваПоиска.Количество() > 0 + ИЛИ ИмяПредопределенногоЭлемента <> Неопределено Тогда + + // Формируем узел ссылки + УзелСсылки = СоздатьУзел("Ссылка"); + + Если НужноЗапоминатьОбъект Тогда + + Если ЭтоПравилоСГлобальнойВыгрузкойОбъектов Тогда + УстановитьАтрибут(УзелСсылки, "ГНпп", НПП); + Иначе + УстановитьАтрибут(УзелСсылки, "Нпп", НПП); + КонецЕсли; + + КонецЕсли; + + ВыгрузитьТолькоСсылку = ПКО.НеВыгружатьОбъектыСвойствПоСсылкам ИЛИ ТолькоПолучитьУзелСсылки; + + Если НеСоздаватьЕслиНеНайден Тогда + УстановитьАтрибут(УзелСсылки, "НеСоздаватьЕслиНеНайден", НеСоздаватьЕслиНеНайден); + КонецЕсли; + + Если ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD Тогда + УстановитьАтрибут(УзелСсылки, "ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD", ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD); + КонецЕсли; + + ВыгрузитьСвойства(Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ПКО, ПКО.СвойстваПоиска, + УзелСсылки, ВыборкаДляВыгрузкиДанных, ИмяПредопределенногоЭлемента, ВыгрузитьТолькоСсылку); + + УзелСсылки.ЗаписатьКонецЭлемента(); + УзелСсылки = УзелСсылки.Закрыть(); + + Если НужноЗапоминатьОбъект Тогда + + ВыгруженныеОбъекты[КлючВыгружаемыхДанных] = УзелСсылки; + + КонецЕсли; + + Иначе + УзелСсылки = НПП; + КонецЕсли; + + Иначе + + // Поиск в соответствии значений по ПКЗ. + Если УзелСсылки = Неопределено Тогда + // По Соответствию значений не нашли - пробуем найти по свойствам поиска. + СтруктураЗаписи = Новый Структура("Источник,ТипИсточника", Источник, ТипЗнч(Источник)); + ЗаписатьВПротоколВыполнения(71, СтруктураЗаписи); + Если СтрокаВСтекеВыгрузки <> Неопределено Тогда + мСтекВызововВыгрузкиДанных.Удалить(СтрокаВСтекеВыгрузки); + КонецЕсли; + ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу - 1; + Возврат Неопределено; + КонецЕсли; + + Если ЗапоминатьВыгруженные Тогда + ВыгруженныеОбъекты[КлючВыгружаемыхДанных] = УзелСсылки; + КонецЕсли; + + Если СтрокаВСтекеВыгрузки <> Неопределено Тогда + мСтекВызововВыгрузкиДанных.Удалить(СтрокаВСтекеВыгрузки); + КонецЕсли; + ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу - 1; + Возврат УзелСсылки; + + КонецЕсли; + + Если ТолькоПолучитьУзелСсылки Или ВсеОбъектыВыгружены Тогда + + Если СтрокаВСтекеВыгрузки <> Неопределено Тогда + мСтекВызововВыгрузкиДанных.Удалить(СтрокаВСтекеВыгрузки); + КонецЕсли; + ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу - 1; + Возврат УзелСсылки; + + КонецЕсли; + + Если Приемник = Неопределено Тогда + + Приемник = СоздатьУзел("Объект"); + + Если ЭтоПравилоСГлобальнойВыгрузкойОбъектов Тогда + УстановитьАтрибут(Приемник, "ГНпп", НПП); + Иначе + УстановитьАтрибут(Приемник, "Нпп", НПП); + КонецЕсли; + + УстановитьАтрибут(Приемник, "Тип", ПКО.Приемник); + УстановитьАтрибут(Приемник, "ИмяПравила", ПКО.Имя); + + Если НеЗамещатьОбъектПриЗагрузке Тогда + УстановитьАтрибут(Приемник, "НеЗамещать", "true"); + КонецЕсли; + + Если Не ПустаяСтрока(ПрефиксАвтонумерации) Тогда + УстановитьАтрибут(Приемник, "ПрефиксАвтонумерации", ПрефиксАвтонумерации); + КонецЕсли; + + Если Не ПустаяСтрока(РежимЗаписи) Тогда + УстановитьАтрибут(Приемник, "РежимЗаписи", РежимЗаписи); + Если Не ПустаяСтрока(РежимПроведения) Тогда + УстановитьАтрибут(Приемник, "РежимПроведения", РежимПроведения); + КонецЕсли; + КонецЕсли; + + Если ТипЗнч(УзелСсылки) <> одТипЧисло Тогда + ДобавитьПодчиненный(Приемник, УзелСсылки); + КонецЕсли; + + КонецЕсли; + + // Обработчик ПриВыгрузке + СтандартнаяОбработка = Истина; + Отказ = Ложь; + + Если ПКО.ЕстьОбработчикПриВыгрузке Тогда + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(ПКО, "ПриВыгрузке")); + + Иначе + + Выполнить(ПКО.ПриВыгрузке); + + КонецЕсли; + + Исключение + ЗаписатьИнформациюОбОшибкеВыгрузкиОбработчикаПКО(42, ОписаниеОшибки(), ПКО, Источник, "ПриВыгрузкеОбъекта"); + КонецПопытки; + + Если Отказ Тогда // Отказ от записи объекта в файл. + Если СтрокаВСтекеВыгрузки <> Неопределено Тогда + мСтекВызововВыгрузкиДанных.Удалить(СтрокаВСтекеВыгрузки); + КонецЕсли; + ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу - 1; + Возврат УзелСсылки; + КонецЕсли; + + КонецЕсли; + + // Выгрузка свойств + Если СтандартнаяОбработка Тогда + + ВыгрузитьСвойства(Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ПКО, ПКО.Свойства, , ВыборкаДляВыгрузкиДанных, , + ПКО.НеВыгружатьОбъектыСвойствПоСсылкам ИЛИ ТолькоПолучитьУзелСсылки, СписокВременныхФайлов); + + КонецЕсли; + + // Обработчик ПослеВыгрузки + Если ПКО.ЕстьОбработчикПослеВыгрузки Тогда + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(ПКО, "ПослеВыгрузки")); + + Иначе + + Выполнить(ПКО.ПослеВыгрузки); + + КонецЕсли; + + Исключение + ЗаписатьИнформациюОбОшибкеВыгрузкиОбработчикаПКО(43, ОписаниеОшибки(), ПКО, Источник, "ПослеВыгрузкиОбъекта"); + КонецПопытки; + + Если Отказ Тогда // Отказ от записи объекта в файл. + + Если СтрокаВСтекеВыгрузки <> Неопределено Тогда + мСтекВызововВыгрузкиДанных.Удалить(СтрокаВСтекеВыгрузки); + КонецЕсли; + ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу - 1; + Возврат УзелСсылки; + + КонецЕсли; + + КонецЕсли; + + Если СписокВременныхФайлов = Неопределено Тогда + + // Запись объекта в файл + Приемник.ЗаписатьКонецЭлемента(); + ЗаписатьВФайл(Приемник); + + Иначе + + ЗаписатьВФайл(Приемник); + + ПеренестиДанныеИзВременныхФайлов(СписокВременныхФайлов); + + ЗаписатьВФайл("Объект>"); + + КонецЕсли; + + мСчетчикВыгруженныхОбъектов = 1 + мСчетчикВыгруженныхОбъектов; + + Если НужноЗапоминатьОбъект Тогда + + Если ЭтоПравилоСГлобальнойВыгрузкойОбъектов Тогда + ВыгруженныеОбъекты[КлючВыгружаемыхДанных] = НПП; + КонецЕсли; + + КонецЕсли; + + Если СтрокаВСтекеВыгрузки <> Неопределено Тогда + мСтекВызововВыгрузкиДанных.Удалить(СтрокаВСтекеВыгрузки); + КонецЕсли; + + ТекущийУровеньВложенностиВыгрузитьПоПравилу = ТекущийУровеньВложенностиВыгрузитьПоПравилу - 1; + + // Обработчик ПослеВыгрузкиВФайл + Если ПКО.ЕстьОбработчикПослеВыгрузкиВФайл Тогда + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(ПКО, "ПослеВыгрузкиВФайл")); + + Иначе + + Выполнить(ПКО.ПослеВыгрузкиВФайл); + + КонецЕсли; + + Исключение + ЗаписатьИнформациюОбОшибкеВыгрузкиОбработчикаПКО(76, ОписаниеОшибки(), ПКО, Источник, "ЕстьОбработчикПослеВыгрузкиВФайл"); + КонецПопытки; + + КонецЕсли; + + Возврат УзелСсылки; + +КонецФункции // ВыгрузитьПоПравилу() + +// Возвращает фрагмент текста языка запросов, который выражает условие ограничения на интервал дат. +// +// Параметры: +// Свойства - Метаданные - Свойства объекта метаданных. +// ИмяТипа - Строка - Имя типа. +// ИмяГруппыТаблицы - Строка - Имя группы таблицы. +// ВыборкаДляОчисткиДанных - Булево - выборка для очистки данных. +// +// Возвращаемое значение: +// Строка - фрагмент запроса с условием ограничения на интервал дат. +// +Функция ПолучитьСтрокуОграниченияПоДатеДляЗапроса(Свойства, ИмяТипа, ИмяГруппыТаблицы = "", ВыборкаДляОчисткиДанных = Ложь) Экспорт + + ИтоговоеОграничениеПоДате = ""; + + Если НЕ (ИмяТипа = "Документ" ИЛИ ИмяТипа = "РегистрСведений") Тогда + Возврат ИтоговоеОграничениеПоДате; + КонецЕсли; + + Если ИмяТипа = "РегистрСведений" Тогда + + Непериодический = НЕ Свойства.Периодический; + НеНужноОграничениеПоДатам = ВыборкаДляОчисткиДанных ИЛИ Непериодический; + + Если НеНужноОграничениеПоДатам Тогда + Возврат ИтоговоеОграничениеПоДате; + КонецЕсли; + + КонецЕсли; + + Если ПустаяСтрока(ИмяГруппыТаблицы) Тогда + ИмяПоляОграничения = ?(ИмяТипа = "Документ", "Дата", "Период"); + Иначе + ИмяПоляОграничения = ИмяГруппыТаблицы + "." + ?(ИмяТипа = "Документ", "Дата", "Период"); + КонецЕсли; + + Если ДатаНачала <> ЗначениеПустаяДата Тогда + + ИтоговоеОграничениеПоДате = " + | ГДЕ + | " + ИмяПоляОграничения + " >= &ДатаНачала"; + + КонецЕсли; + + Если ДатаОкончания <> ЗначениеПустаяДата Тогда + + Если ПустаяСтрока(ИтоговоеОграничениеПоДате) Тогда + + ИтоговоеОграничениеПоДате = " + | ГДЕ + | " + ИмяПоляОграничения + " <= &ДатаОкончания"; + + Иначе + + ИтоговоеОграничениеПоДате = ИтоговоеОграничениеПоДате + " + | И + | " + ИмяПоляОграничения + " <= &ДатаОкончания"; + + КонецЕсли; + + КонецЕсли; + + Возврат ИтоговоеОграничениеПоДате; + +КонецФункции + +// Формирует результат запроса для выгрузки очистки данных. +// +// Параметры: +// Свойства - Структура - описание типа значения, см. СтруктураПараметровМенеджера. +// ИмяТипа - Строка - Имя типа. +// ВыборкаДляОчисткиДанных - Булево - выборка для очистки данных. +// УдалятьОбъектыНепосредственно - Булево - признак необходимости непосредственного удаления. +// ВыбиратьВсеПоля - Булево - признак необходимости выбирать все поля. +// +// Возвращаемое значение: +// РезультатЗапроса, Неопределено - результат запроса для выгрузки очистки данных. +// +Функция ПолучитьРезультатЗапросаДляВыгрузкиОчисткиДанных(Свойства, ИмяТипа, + ВыборкаДляОчисткиДанных = Ложь, УдалятьОбъектыНепосредственно = Ложь, ВыбиратьВсеПоля = Истина) Экспорт + + СтрокаРазрешения = ?(ВыгружатьТолькоРазрешенные, " РАЗРЕШЕННЫЕ ", ""); + + СтрокаВыбораПолей = ?(ВыбиратьВсеПоля, " * ", " ОбъектДляВыгрузки.Ссылка КАК Ссылка "); + + Если ИмяТипа = "Справочник" + Или ИмяТипа = "ПланВидовХарактеристик" + Или ИмяТипа = "ПланСчетов" + Или ИмяТипа = "ПланВидовРасчета" + Или ИмяТипа = "РегистрБухгалтерии" + Или ИмяТипа = "ПланОбмена" + Или ИмяТипа = "Задача" + Или ИмяТипа = "БизнесПроцесс" Тогда + + Запрос = Новый Запрос(); + + Если ИмяТипа = "Справочник" Тогда + МетаданныеОбъектов = Метаданные.Справочники[Свойства.Имя]; + ИначеЕсли ИмяТипа = "ПланВидовХарактеристик" Тогда + МетаданныеОбъектов = Метаданные.ПланыВидовХарактеристик[Свойства.Имя]; + ИначеЕсли ИмяТипа = "ПланСчетов" Тогда + МетаданныеОбъектов = Метаданные.ПланыСчетов[Свойства.Имя]; + ИначеЕсли ИмяТипа = "ПланВидовРасчета" Тогда + МетаданныеОбъектов = Метаданные.ПланыВидовРасчета[Свойства.Имя]; + ИначеЕсли ИмяТипа = "РегистрБухгалтерии" Тогда + МетаданныеОбъектов = Метаданные.РегистрыБухгалтерии[Свойства.Имя]; + ИначеЕсли ИмяТипа = "ПланОбмена" Тогда + МетаданныеОбъектов = Метаданные.ПланыОбмена[Свойства.Имя]; + ИначеЕсли ИмяТипа = "Задача" Тогда + МетаданныеОбъектов = Метаданные.Задачи[Свойства.Имя]; + ИначеЕсли ИмяТипа = "БизнесПроцесс" Тогда + МетаданныеОбъектов = Метаданные.БизнесПроцессы[Свойства.Имя]; + КонецЕсли; + + Если ИмяТипа = "РегистрБухгалтерии" Тогда + + СтрокаВыбораПолей = "*"; + ИмяТаблицыДляВыборки = Свойства.Имя + ".ДвиженияССубконто"; + + Иначе + + ИмяТаблицыДляВыборки = Свойства.Имя; + + Если ВыгружатьТолькоРазрешенные + И НЕ ВыбиратьВсеПоля Тогда + + ИмяПервогоРеквизита = ПолучитьИмяПервогоРеквизитаМетаданных(МетаданныеОбъектов); + Если Не ПустаяСтрока(ИмяПервогоРеквизита) Тогда + СтрокаВыбораПолей = СтрокаВыбораПолей + ", ОбъектДляВыгрузки." + ИмяПервогоРеквизита; + КонецЕсли; + + КонецЕсли; + + КонецЕсли; + + Запрос.Текст = "ВЫБРАТЬ " + СтрокаРазрешения + " + | " + СтрокаВыбораПолей + " + |ИЗ + | " + ИмяТипа + "." + ИмяТаблицыДляВыборки + " КАК ОбъектДляВыгрузки + | + |"; + + ИначеЕсли ИмяТипа = "Документ" Тогда + + Если ВыгружатьТолькоРазрешенные Тогда + + ИмяПервогоРеквизита = ПолучитьИмяПервогоРеквизитаМетаданных(Метаданные.Документы[Свойства.Имя]); + Если Не ПустаяСтрока(ИмяПервогоРеквизита) Тогда + СтрокаВыбораПолей = СтрокаВыбораПолей + ", ОбъектДляВыгрузки." + ИмяПервогоРеквизита; + КонецЕсли; + + КонецЕсли; + + ИтоговоеОграничениеПоДате = ПолучитьСтрокуОграниченияПоДатеДляЗапроса(Свойства, ИмяТипа, "ОбъектДляВыгрузки", ВыборкаДляОчисткиДанных); + + Запрос = Новый Запрос(); + + Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала); + Запрос.УстановитьПараметр("ДатаОкончания", ДатаОкончания); + + Запрос.Текст = "ВЫБРАТЬ " + СтрокаРазрешения + " + | " + СтрокаВыбораПолей + " + |ИЗ + | " + ИмяТипа + "." + Свойства.Имя + " КАК ОбъектДляВыгрузки + | + |" + ИтоговоеОграничениеПоДате; + + + ИначеЕсли ИмяТипа = "РегистрСведений" Тогда + + Непериодический = НЕ Свойства.Периодический; + ПодчиненныйРегистратору = Свойства.ПодчиненныйРегистратору; + + ИтоговоеОграничениеПоДате = ПолучитьСтрокуОграниченияПоДатеДляЗапроса(Свойства, ИмяТипа, "ОбъектДляВыгрузки", ВыборкаДляОчисткиДанных); + + Запрос = Новый Запрос(); + + Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала); + Запрос.УстановитьПараметр("ДатаОкончания", ДатаОкончания); + + СтрокаДополненияПолейВыборкиПодчиненРегистратору = ?(НЕ ПодчиненныйРегистратору, ", NULL КАК Активность, + | NULL КАК Регистратор, + | NULL КАК НомерСтроки", ""); + + СтрокаДополненияПолейВыборкиПериодичность = ?(Непериодический, ", NULL КАК Период", ""); + + Запрос.Текст = "ВЫБРАТЬ " + СтрокаРазрешения + " + | * + | + | " + СтрокаДополненияПолейВыборкиПодчиненРегистратору + " + | " + СтрокаДополненияПолейВыборкиПериодичность + " + | + |ИЗ + | " + ИмяТипа + "." + Свойства.Имя + " КАК ОбъектДляВыгрузки + | + |" + ИтоговоеОграничениеПоДате; + + Иначе + + Возврат Неопределено; + + КонецЕсли; + + Возврат Запрос.Выполнить(); + +КонецФункции + +// Формирует выборку для выгрузки очистки данных. +// +// Параметры: +// Свойства - Менеджер - Свойства объекта метаданных. +// ИмяТипа - Строка - Имя типа. +// ВыборкаДляОчисткиДанных - Булево - выборка для очистки данных. +// УдалятьОбъектыНепосредственно - Булево - признак необходимости удалять непосредственно. +// ВыбиратьВсеПоля - Булево - признак необходимости выбирать все поля. +// +// Возвращаемое значение: +// ВыборкаРезультатаЗапроса - выборка для выгрузки очистки данных. +// +Функция ПолучитьВыборкуДляВыгрузкиОчисткиДанных(Свойства, ИмяТипа, + ВыборкаДляОчисткиДанных = Ложь, УдалятьОбъектыНепосредственно = Ложь, ВыбиратьВсеПоля = Истина) Экспорт + + РезультатЗапроса = ПолучитьРезультатЗапросаДляВыгрузкиОчисткиДанных(Свойства, ИмяТипа, + ВыборкаДляОчисткиДанных, УдалятьОбъектыНепосредственно, ВыбиратьВсеПоля); + + Если РезультатЗапроса = Неопределено Тогда + Возврат Неопределено; + КонецЕсли; + + Выборка = РезультатЗапроса.Выбрать(); + + Возврат Выборка; + +КонецФункции + +#КонецОбласти + +#Область ЭкспортируемыеПроцедурыИФункции + +// Заполняет переданную таблицу значений типами объектов метаданных для удаления, на которые есть право доступа для +// удаления. +// +// Параметры: +// ТаблицаДанных - ТаблицаЗначений - Таблица для заполнения. +// +Процедура ЗаполнитьСписокТиповДоступныхДляУдаления(ТаблицаДанных) Экспорт + + ТаблицаДанных.Очистить(); + + Для каждого ОбъектМД Из Метаданные.Справочники Цикл + + Если Не ПравоДоступа("Удаление", ОбъектМД) Тогда + Продолжить; + КонецЕсли; + + СтрокаТаблицы = ТаблицаДанных.Добавить(); + СтрокаТаблицы.Метаданные = "СправочникСсылка." + ОбъектМД.Имя; + + КонецЦикла; + + Для каждого ОбъектМД Из Метаданные.ПланыВидовХарактеристик Цикл + + Если Не ПравоДоступа("Удаление", ОбъектМД) Тогда + Продолжить; + КонецЕсли; + + СтрокаТаблицы = ТаблицаДанных.Добавить(); + СтрокаТаблицы.Метаданные = "ПланВидовХарактеристикСсылка." + ОбъектМД.Имя; + КонецЦикла; + + Для Каждого ОбъектМД Из Метаданные.Документы Цикл + + Если Не ПравоДоступа("Удаление", ОбъектМД) Тогда + Продолжить; + КонецЕсли; + + СтрокаТаблицы = ТаблицаДанных.Добавить(); + СтрокаТаблицы.Метаданные = "ДокументСсылка." + ОбъектМД.Имя; + КонецЦикла; + + Для каждого ОбъектМД Из Метаданные.РегистрыСведений Цикл + + Если Не ПравоДоступа("Удаление", ОбъектМД) Тогда + Продолжить; + КонецЕсли; + + Подчинен = (ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору); + Если Подчинен Тогда Продолжить КонецЕсли; + + СтрокаТаблицы = ТаблицаДанных.Добавить(); + СтрокаТаблицы.Метаданные = "РегистрСведенийЗапись." + ОбъектМД.Имя; + + КонецЦикла; + +КонецПроцедуры + +// Устанавливает состояние пометки у подчиненных строк строки дерева значений +// в зависимости от пометки текущей строки. +// +// Параметры: +// ТекСтрока - СтрокаДереваЗначений - Строка, у которой следует обработать подчиненные строки. +// Реквизит - Строка - Имя реквизита, в котором содержится пометка. +// +Процедура УстановитьПометкиПодчиненных(ТекСтрока, Реквизит) Экспорт + + Подчиненные = ТекСтрока.Строки; + + Если Подчиненные.Количество() = 0 Тогда + Возврат; + КонецЕсли; + + Для Каждого Строка Из Подчиненные Цикл + + Если Строка.Отбор = Неопределено //УИ + И Реквизит = "ИспользоватьОтбор" Тогда + + Строка[Реквизит] = 0; + + Иначе + + Строка[Реквизит] = ТекСтрока[Реквизит]; + + КонецЕсли; + + УстановитьПометкиПодчиненных(Строка, Реквизит); + + КонецЦикла; + +КонецПроцедуры + +// Устанавливает состояние пометки у родительских строк строки дерева значений. +// в зависимости от пометки текущей строки. +// +// Параметры: +// ТекСтрока - СтрокаДереваЗначений - Строка, у которой следует обработать родительские строки. +// Реквизит - Строка - Имя реквизита, в котором содержится пометка. +// +Процедура УстановитьПометкиРодителей(ТекСтрока, Реквизит) Экспорт + + Родитель = ТекСтрока.Родитель; + Если Родитель = Неопределено Тогда + Возврат; + КонецЕсли; + + ТекСостояние = Родитель[Реквизит]; + + НайденыВключенные = Ложь; + НайденыВыключенные = Ложь; + + Если Реквизит = "ИспользоватьОтбор" Тогда + + Для Каждого Строка Из Родитель.Строки Цикл + + Если Строка[Реквизит] = 0 + И Строка.Отбор <> Неопределено Тогда //УИ + + НайденыВыключенные = Истина; + + ИначеЕсли Строка[Реквизит] = 1 Тогда + НайденыВключенные = Истина; + КонецЕсли; + + Если НайденыВключенные И НайденыВыключенные Тогда + Прервать; + КонецЕсли; + + КонецЦикла; + + Иначе + + Для Каждого Строка Из Родитель.Строки Цикл + Если Строка[Реквизит] = 0 Тогда + НайденыВыключенные = Истина; + ИначеЕсли Строка[Реквизит] = 1 + ИЛИ Строка[Реквизит] = 2 Тогда + НайденыВключенные = Истина; + КонецЕсли; + Если НайденыВключенные И НайденыВыключенные Тогда + Прервать; + КонецЕсли; + КонецЦикла; + + КонецЕсли; + + + Если НайденыВключенные И НайденыВыключенные Тогда + Включить = 2; + ИначеЕсли НайденыВключенные И (Не НайденыВыключенные) Тогда + Включить = 1; + ИначеЕсли (Не НайденыВключенные) И НайденыВыключенные Тогда + Включить = 0; + ИначеЕсли (Не НайденыВключенные) И (Не НайденыВыключенные) Тогда + Включить = 2; + КонецЕсли; + + Если Включить = ТекСостояние Тогда + Возврат; + Иначе + Родитель[Реквизит] = Включить; + УстановитьПометкиРодителей(Родитель, Реквизит); + КонецЕсли; + +КонецПроцедуры + +// Составляет полное имя файла из имени каталога и имени файла. +// +// Параметры: +// ИмяКаталога - Строка - путь к каталогу файла на диске. +// ИмяФайла - Строка - имя файла, без имени каталога. +// +// Возвращаемое значение: +// Строка - полное имя файла с учетом каталога. +// +Функция ПолучитьИмяФайлаОбмена(ИмяКаталога, ИмяФайла) Экспорт + + Если Не ПустаяСтрока(ИмяФайла) Тогда + + Возврат ИмяКаталога + ?(Прав(ИмяКаталога, 1) = "\", "", "\") + ИмяФайла; + + Иначе + + Возврат ИмяКаталога; + + КонецЕсли; + +КонецФункции + +// Выполняет передачу строки данных для загрузки в базе-приемнике. +// +// Параметры: +// ИнформацияДляЗаписиВФайл - Строка - строка с данными (текст XML). +// СтрокаОшибкиВБазеПриемнике - Строка - содержит описание ошибки при загрузке в базе-приемнике. +// +Процедура ПередатьИнформациюОЗаписиВПриемник(ИнформацияДляЗаписиВФайл, СтрокаОшибкиВБазеПриемнике = "") Экспорт + + мОбработкаДляЗагрузкиДанных.ФайлОбмена.УстановитьСтроку(ИнформацияДляЗаписиВФайл); + + мОбработкаДляЗагрузкиДанных.ПроизвестиЧтениеДанных(СтрокаОшибкиВБазеПриемнике); + + Если Не ПустаяСтрока(СтрокаОшибкиВБазеПриемнике) Тогда + + СтрокаСообщения = ПодставитьПараметрыВСтроку(НСтр("ru = 'Загрузка в приемнике: %1'"), СтрокаОшибкиВБазеПриемнике); + ЗаписатьВПротоколВыполнения(СтрокаСообщения, Неопределено, Истина, , , Истина); + + КонецЕсли; + +КонецПроцедуры + +// Выполняет запись имени, типа и значения параметра в фай сообщения обмена для передачи в базу-приемник. +// +// Параметры: +// Имя - Строка - Имя параметра. +// ИсходноеЗначениеПараметра - Произвольный - значение параметра. +// ПравилоКонвертации - Строка - имя правила конвертации для ссылочных типов. +// +Процедура ПередатьОдинПараметрВПриемник(Имя, ИсходноеЗначениеПараметра, ПравилоКонвертации = "") Экспорт + + Если ПустаяСтрока(ПравилоКонвертации) Тогда + + УзелПараметра = СоздатьУзел("ЗначениеПараметра"); + + УстановитьАтрибут(УзелПараметра, "Имя", Имя); + УстановитьАтрибут(УзелПараметра, "Тип", одТипЗначенияСтрокой(ИсходноеЗначениеПараметра)); + + ЭтоNULL = Ложь; + Пусто = одПустое(ИсходноеЗначениеПараметра, ЭтоNULL); + + Если Пусто Тогда + + // Надо записать что это пустое значение. + одЗаписатьЭлемент(УзелПараметра, "Пусто"); + + УзелПараметра.ЗаписатьКонецЭлемента(); + + ЗаписатьВФайл(УзелПараметра); + + Возврат; + + КонецЕсли; + + одЗаписатьЭлемент(УзелПараметра, "Значение", ИсходноеЗначениеПараметра); + + УзелПараметра.ЗаписатьКонецЭлемента(); + + ЗаписатьВФайл(УзелПараметра); + + Иначе + + УзелПараметра = СоздатьУзел("ЗначениеПараметра"); + + УстановитьАтрибут(УзелПараметра, "Имя", Имя); + + ЭтоNULL = Ложь; + Пусто = одПустое(ИсходноеЗначениеПараметра, ЭтоNULL); + + Если Пусто Тогда + + ПКОСвойств = НайтиПравило(ИсходноеЗначениеПараметра, ПравилоКонвертации); + ТипПриемника = ПКОСвойств.Приемник; + УстановитьАтрибут(УзелПараметра, "Тип", ТипПриемника); + + // Надо записать что это пустое значение. + одЗаписатьЭлемент(УзелПараметра, "Пусто"); + + УзелПараметра.ЗаписатьКонецЭлемента(); + + ЗаписатьВФайл(УзелПараметра); + + Возврат; + + КонецЕсли; + + ВыгрузитьДанныеСсылочногоОбъекта(ИсходноеЗначениеПараметра, Неопределено, ПравилоКонвертации, Неопределено, Неопределено, УзелПараметра, Истина); + + УзелПараметра.ЗаписатьКонецЭлемента(); + + ЗаписатьВФайл(УзелПараметра); + + КонецЕсли; + +КонецПроцедуры + +#КонецОбласти + +#Область УстановкаЗначенийРеквизитовИМодальныхПеременныхОбработки + +// Возвращает текущее значение версии обработки. +// +// Возвращаемое значение: +// Число - Текущее значение версии обработки. +// +Функция ВерсияОбъекта() Экспорт + + Возврат 218; + +КонецФункции + +#КонецОбласти + +#Область ИнициализацияТаблицПравилОбмена + +// Инициализирует колонки таблицы правил конвертации свойств объектов. +// +// Параметры: +// Таб - ТаблицаЗначений - инициализируемая таблица правил конвертации свойств. +// +Процедура ИнициализацияТаблицыПравилКонвертацииСвойств(Таб) Экспорт + + Колонки = Таб.Колонки; + + ДобавитьНедостающиеКолонки(Колонки, "Имя"); + ДобавитьНедостающиеКолонки(Колонки, "Наименование"); + ДобавитьНедостающиеКолонки(Колонки, "Порядок"); + + ДобавитьНедостающиеКолонки(Колонки, "ЭтоГруппа", одОписаниеТипа("Булево")); + ДобавитьНедостающиеКолонки(Колонки, "ПравилаГруппы"); + + ДобавитьНедостающиеКолонки(Колонки, "ВидИсточника"); + ДобавитьНедостающиеКолонки(Колонки, "ВидПриемника"); + + ДобавитьНедостающиеКолонки(Колонки, "УпрощеннаяВыгрузкаСвойства", одОписаниеТипа("Булево")); + ДобавитьНедостающиеКолонки(Колонки, "НуженУзелXMLПриВыгрузке", одОписаниеТипа("Булево")); + ДобавитьНедостающиеКолонки(Колонки, "НуженУзелXMLПриВыгрузкеГруппы", одОписаниеТипа("Булево")); + + ДобавитьНедостающиеКолонки(Колонки, "ТипИсточника", одОписаниеТипа("Строка")); + ДобавитьНедостающиеКолонки(Колонки, "ТипПриемника", одОписаниеТипа("Строка")); + + ДобавитьНедостающиеКолонки(Колонки, "Источник"); + ДобавитьНедостающиеКолонки(Колонки, "Приемник"); + + ДобавитьНедостающиеКолонки(Колонки, "ПравилоКонвертации"); + + ДобавитьНедостающиеКолонки(Колонки, "ПолучитьИзВходящихДанных", одОписаниеТипа("Булево")); + + ДобавитьНедостающиеКолонки(Колонки, "НеЗамещать", одОписаниеТипа("Булево")); + + ДобавитьНедостающиеКолонки(Колонки, "ПередВыгрузкой"); + ДобавитьНедостающиеКолонки(Колонки, "ПриВыгрузке"); + ДобавитьНедостающиеКолонки(Колонки, "ПослеВыгрузки"); + + ДобавитьНедостающиеКолонки(Колонки, "ПередОбработкойВыгрузки"); + ДобавитьНедостающиеКолонки(Колонки, "ПослеОбработкиВыгрузки"); + + ДобавитьНедостающиеКолонки(Колонки, "ЕстьОбработчикПередВыгрузкой", одОписаниеТипа("Булево")); + ДобавитьНедостающиеКолонки(Колонки, "ЕстьОбработчикПриВыгрузке", одОписаниеТипа("Булево")); + ДобавитьНедостающиеКолонки(Колонки, "ЕстьОбработчикПослеВыгрузки", одОписаниеТипа("Булево")); + + ДобавитьНедостающиеКолонки(Колонки, "ЕстьОбработчикПередОбработкойВыгрузки", одОписаниеТипа("Булево")); + ДобавитьНедостающиеКолонки(Колонки, "ЕстьОбработчикПослеОбработкиВыгрузки", одОписаниеТипа("Булево")); + + ДобавитьНедостающиеКолонки(Колонки, "ПриводитьКДлине", одОписаниеТипа("Число")); + ДобавитьНедостающиеКолонки(Колонки, "ИмяПараметраДляПередачи"); + ДобавитьНедостающиеКолонки(Колонки, "ПоискПоДатеНаРавенство", одОписаниеТипа("Булево")); + ДобавитьНедостающиеКолонки(Колонки, "ВыгружатьГруппуЧерезФайл", одОписаниеТипа("Булево")); + + ДобавитьНедостающиеКолонки(Колонки, "СтрокаПолейПоиска"); + +КонецПроцедуры + +#КонецОбласти + +#Область ИнициализацияРеквизитовИМодульныхПеременных + +// Инициализирует внешнюю обработку с модулем отладки обработчиков событий. +// +// Параметры: +// РаботаВозможна - Булево - флаг успешной инициализации внешней обработки. +// ОбъектВладелец - ОбработкаОбъект - объект, который будет являться владельцем +// инициализируемой внешней обработки. +// +Процедура ИнициализацияВнешнейОбработкиОбработчиковСобытий(РаботаВозможна, ОбъектВладелец) Экспорт + + Если Не РаботаВозможна Тогда + Возврат; + КонецЕсли; + + Если ФлагРежимОтладкиОбработчиков И ПустаяСтрока(ИмяФайлаВнешнейОбработкиОбработчиковСобытий) Тогда + + ЗаписатьВПротоколВыполнения(77); + РаботаВозможна = Ложь; + + ИначеЕсли ФлагРежимОтладкиОбработчиков Тогда + + Попытка + + Если ЭтоВнешняяОбработка() Тогда + + ВызватьИсключение + НСтр("ru = 'Внешняя обработка отладки, загружаемая из файла на диске, не поддерживается.'"); + + Иначе + + ВнешняяОбработкаОбработчиковСобытий = Обработки[ИмяФайлаВнешнейОбработкиОбработчиковСобытий].Создать(); + + КонецЕсли; + + ВнешняяОбработкаОбработчиковСобытий.Конструктор(ОбъектВладелец); + + Исключение + + ДеструкторВнешнейОбработкиОбработчиковСобытий(); + + СообщитьПользователю(КраткоеПредставлениеОшибки(ИнформацияОбОшибке())); + ЗаписатьВПротоколВыполнения(78); + + РаботаВозможна = Ложь; + ФлагРежимОтладкиОбработчиков = Ложь; + + КонецПопытки; + + КонецЕсли; + + Если РаботаВозможна Тогда + + ОбщиеПроцедурыФункции = ЭтотОбъект; + + КонецЕсли; + +КонецПроцедуры + +// Деструктор внешней обработки. +// +// Параметры: +// ВключенРежимОтладки - Булево - Признак включения режима отладки. +// +Процедура ДеструкторВнешнейОбработкиОбработчиковСобытий(ВключенРежимОтладки = Ложь) Экспорт + + Если Не ВключенРежимОтладки Тогда + + Если ВнешняяОбработкаОбработчиковСобытий <> Неопределено Тогда + + Попытка + + ВнешняяОбработкаОбработчиковСобытий.Деструктор(); + + Исключение + СообщитьПользователю(КраткоеПредставлениеОшибки(ИнформацияОбОшибке())); + КонецПопытки; + + КонецЕсли; + + ВнешняяОбработкаОбработчиковСобытий = Неопределено; + ОбщиеПроцедурыФункции = Неопределено; + + КонецЕсли; + +КонецПроцедуры + +// Удаляет временные файлы с заданным именем. +// +// Параметры: +// ИмяВременногоФайла - Строка - полное имя удаляемого файла. После выполнения процедуры очищается. +// +Процедура УдалитьВременныеФайлы(ИмяВременногоФайла) Экспорт + + Если Не ПустаяСтрока(ИмяВременногоФайла) Тогда + + Попытка + + УдалитьФайлы(ИмяВременногоФайла); + + ИмяВременногоФайла = ""; + + Исключение + ЗаписьЖурналаРегистрации(НСтр("ru = 'Универсальный обмен данными в формате XML'", КодОсновногоЯзыка()), + УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())); + КонецПопытки; + + КонецЕсли; + +КонецПроцедуры + +#КонецОбласти + +#КонецОбласти + +#Область СлужебныеПроцедурыИФункции + +#Область ПроцедурыИФункцииРаботыСФайломОбмена + +// Открывает файл обмена, записывает заголовок файла в соответствии с форматом обмена. +// +// Параметры: +// Нет. +// +Функция ОткрытьФайлВыгрузки(СтрокаСообщенияОбОшибке = "") + + // Архивные файлы будем идентифицировать по расширению ".zip". + + Если АрхивироватьФайл Тогда + ИмяФайлаОбмена = СтрЗаменить(ИмяФайлаОбмена, ".zip", ".xml"); + КонецЕсли; + + ФайлОбмена = Новый ЗаписьТекста; + Попытка + + Если НепосредственноеЧтениеВИБПриемнике Тогда + ФайлОбмена.Открыть(ПолучитьИмяВременногоФайла(".xml"), КодировкаТекста.UTF8); + Иначе + ФайлОбмена.Открыть(ИмяФайлаОбмена, КодировкаТекста.UTF8); + КонецЕсли; + + Исключение + + СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(8); + Возврат ""; + + КонецПопытки; + + СтрокаИнформацииОXML = ""; + + ФайлОбмена.ЗаписатьСтроку(СтрокаИнформацииОXML); + + ВременныйЗаписьXML = Новый ЗаписьXML(); + + ВременныйЗаписьXML.УстановитьСтроку(); + + ВременныйЗаписьXML.ЗаписатьНачалоЭлемента("ФайлОбмена"); + + УстановитьАтрибут(ВременныйЗаписьXML, "ВерсияФормата", "2.0"); + УстановитьАтрибут(ВременныйЗаписьXML, "ДатаВыгрузки", ТекущаяДатаСеанса()); + УстановитьАтрибут(ВременныйЗаписьXML, "НачалоПериодаВыгрузки", ДатаНачала); + УстановитьАтрибут(ВременныйЗаписьXML, "ОкончаниеПериодаВыгрузки", ДатаОкончания); + УстановитьАтрибут(ВременныйЗаписьXML, "ИмяКонфигурацииИсточника", Конвертация().Источник); + УстановитьАтрибут(ВременныйЗаписьXML, "ИмяКонфигурацииПриемника", Конвертация().Приемник); + УстановитьАтрибут(ВременныйЗаписьXML, "ИдПравилКонвертации", Конвертация().Ид); + УстановитьАтрибут(ВременныйЗаписьXML, "Комментарий", Комментарий); + + ВременныйЗаписьXML.ЗаписатьКонецЭлемента(); + + Стр = ВременныйЗаписьXML.Закрыть(); + + Стр = СтрЗаменить(Стр, "/>", ">"); + + ФайлОбмена.ЗаписатьСтроку(Стр); + + Возврат СтрокаИнформацииОXML + Символы.ПС + Стр; + +КонецФункции + +// Закрывает файл обмена +// +// Параметры: +// Нет. +// +Процедура ЗакрытьФайл() + + ФайлОбмена.ЗаписатьСтроку("ФайлОбмена>"); + ФайлОбмена.Закрыть(); + +КонецПроцедуры + +#КонецОбласти + +#Область ПроцедурыИФункцииРаботыСВременнымиФайлами + +Функция ЗаписьТекстаВоВременныйФайл(СписокВременныхФайлов) + + ИмяФайлаЗаписей = ПолучитьИмяВременногоФайла(); + + ВременныйФайлЗаписей = Новый ЗаписьТекста; + + Если БезопасныйРежим() <> Ложь Тогда + УстановитьОтключениеБезопасногоРежима(Истина); + КонецЕсли; + + Попытка + ВременныйФайлЗаписей.Открыть(ИмяФайлаЗаписей, КодировкаТекста.UTF8); + Исключение + ЗаписатьИнформациюОбОшибкеОбработчикиКонвертации(1000, + ОписаниеОшибки(), + НСтр("ru = 'Ошибка при создании временного файла для выгрузки данных'")); + ВызватьИсключение; + КонецПопытки; + + // Удаление временных файлов происходит не по месту, + // с помощью УдалитьФайлы(ИмяФайлаЗаписей), а централизованно. + СписокВременныхФайлов.Добавить(ИмяФайлаЗаписей); + + Возврат ВременныйФайлЗаписей; + +КонецФункции + +Функция ЧтениеТекстаИзВременногоФайла(ИмяВременногоФайла) + + ВременныйФайл = Новый ЧтениеТекста; + + Если БезопасныйРежим() <> Ложь Тогда + УстановитьОтключениеБезопасногоРежима(Истина); + КонецЕсли; + + Попытка + ВременныйФайл.Открыть(ИмяВременногоФайла, КодировкаТекста.UTF8); + Исключение + ЗаписатьИнформациюОбОшибкеОбработчикиКонвертации(1000, + ОписаниеОшибки(), + НСтр("ru = 'Ошибка при открытии временного файла для переноса данных в файл обмена'")); + ВызватьИсключение; + КонецПопытки; + + Возврат ВременныйФайл; +КонецФункции + +Процедура ПеренестиДанныеИзВременныхФайлов(СписокВременныхФайлов) + + Для Каждого ИмяВременногоФайла Из СписокВременныхФайлов Цикл + ВременныйФайл = ЧтениеТекстаИзВременногоФайла(ИмяВременногоФайла); + + СтрокаВременногоФайла = ВременныйФайл.ПрочитатьСтроку(); + Пока СтрокаВременногоФайла <> Неопределено Цикл + ЗаписатьВФайл(СтрокаВременногоФайла); + СтрокаВременногоФайла = ВременныйФайл.ПрочитатьСтроку(); + КонецЦикла; + + ВременныйФайл.Закрыть(); + КонецЦикла; + + Если БезопасныйРежим() <> Ложь Тогда + УстановитьОтключениеБезопасногоРежима(Истина); + КонецЕсли; + + Для Каждого ИмяВременногоФайла Из СписокВременныхФайлов Цикл + УдалитьФайлы(ИмяВременногоФайла); + КонецЦикла; + +КонецПроцедуры + +#КонецОбласти + +#Область ПроцедурыИФункцииРаботыСПротоколомОбмена + +// Выполняет инициализацию файла для записи событий загрузки/выгрузки данных. +// +// Параметры: +// Нет. +// +Процедура ИнициализироватьВедениеПротоколаОбмена() Экспорт + + Если ПустаяСтрока(ИмяФайлаПротоколаОбмена) Тогда + + мФайлПротоколаДанных = Неопределено; + ФлагКомментироватьОбработкуОбъектов = ВыводВОкноСообщенийИнформационныхСообщений; + Возврат; + + Иначе + + ФлагКомментироватьОбработкуОбъектов = ВыводВПротоколИнформационныхСообщений ИЛИ ВыводВОкноСообщенийИнформационныхСообщений; + + КонецЕсли; + + мФайлПротоколаДанных = Новый ЗаписьТекста(ИмяФайлаПротоколаОбмена, КодировкаФайлаПротоколаОбмена(), , ДописыватьДанныеВПротоколОбмена) ; + +КонецПроцедуры + +Процедура ИнициализироватьВедениеПротоколаОбменаДляЭкспортаОбработчиков() + + ИмяВременногоФайлаПротоколаОбмена = ПолучитьНовоеУникальноеИмяВременногоФайла(ИмяВременногоФайлаПротоколаОбмена); + + мФайлПротоколаДанных = Новый ЗаписьТекста(ИмяВременногоФайлаПротоколаОбмена, КодировкаФайлаПротоколаОбмена()); + + ФлагКомментироватьОбработкуОбъектов = Ложь; + +КонецПроцедуры + +Функция КодировкаФайлаПротоколаОбмена() + + ПредставлениеКодировки = СокрЛП(КодировкаФайлаПротоколаОбмена); + + Результат = КодировкаТекста.ANSI; + Если Не ПустаяСтрока(КодировкаФайлаПротоколаОбмена) Тогда + Если СтрНачинаетсяС(ПредставлениеКодировки, "КодировкаТекста.") Тогда + ПредставлениеКодировки = СтрЗаменить(ПредставлениеКодировки, "КодировкаТекста.", ""); + Попытка + Результат = КодировкаТекста[ПредставлениеКодировки]; + Исключение + ТекстОшибки = ПодставитьПараметрыВСтроку(НСтр("ru = 'Неизвестная кодировка файла протокола обмена: %1. + |Используется ANSI.'"), ПредставлениеКодировки); + ЗаписьЖурналаРегистрации(НСтр("ru = 'Универсальный обмен данными в формате XML'", КодОсновногоЯзыка()), + УровеньЖурналаРегистрации.Предупреждение, , , ТекстОшибки); + КонецПопытки; + Иначе + Результат = ПредставлениеКодировки; + КонецЕсли; + КонецЕсли; + + Возврат Результат; + +КонецФункции + +// Закрывает файл протокола обмена данными. Файл сохраняется на диск. +// +Процедура ЗавершитьВедениеПротоколаОбмена() Экспорт + + Если мФайлПротоколаДанных <> Неопределено Тогда + + мФайлПротоколаДанных.Закрыть(); + + КонецЕсли; + + мФайлПротоколаДанных = Неопределено; + +КонецПроцедуры + +// Сохраняет в протокол выполнения (или выводит на экран) сообщения указанной структуры. +// +// Параметры: +// Код - Число. Код сообщения. +// СтруктураЗаписи - Структура. Структура записи протокола. +// ВзвестиФлагОшибок - Если истина, то - это сообщение об ошибке. Взводится ФлагОшибки. +// +Функция ЗаписатьВПротоколВыполнения(Код="", СтруктураЗаписи=Неопределено, ВзвестиФлагОшибок=Истина, + Уровень=0, Выравнивание=22, БезусловнаяЗаписьВПротоколОбмена = Ложь) Экспорт + + Отступ = ""; + Для Сч = 0 По Уровень-1 Цикл + Отступ = Отступ + Символы.Таб; + КонецЦикла; + + Если ТипЗнч(Код) = одТипЧисло Тогда + + Если одСообщения = Неопределено Тогда + ИнициализацияСообщений(); + КонецЕсли; + + Стр = одСообщения[Код]; + + Иначе + + Стр = Строка(Код); + + КонецЕсли; + + Стр = Отступ + Стр; + + Если СтруктураЗаписи <> Неопределено Тогда + + Для каждого Поле Из СтруктураЗаписи Цикл + + Значение = Поле.Значение; + Если Значение = Неопределено Тогда + Продолжить; + КонецЕсли; + Ключ = Поле.Ключ; + Стр = Стр + Символы.ПС + Отступ + Символы.Таб + одДополнитьСтроку(Ключ, Выравнивание) + " = " + Строка(Значение); + + КонецЦикла; + + КонецЕсли; + + ИтоговаяСтрокаДляЗаписи = Символы.ПС + Стр; + + + Если ВзвестиФлагОшибок Тогда + + УстановитьФлагОшибки(Истина); + СообщитьПользователю(ИтоговаяСтрокаДляЗаписи); + + Иначе + + Если НеВыводитьНикакихИнформационныхСообщенийПользователю = Ложь + И (БезусловнаяЗаписьВПротоколОбмена ИЛИ ВыводВОкноСообщенийИнформационныхСообщений) Тогда + + СообщитьПользователю(ИтоговаяСтрокаДляЗаписи); + + КонецЕсли; + + КонецЕсли; + + Если мФайлПротоколаДанных <> Неопределено Тогда + + Если ВзвестиФлагОшибок Тогда + + мФайлПротоколаДанных.ЗаписатьСтроку(Символы.ПС + "Ошибка."); + + КонецЕсли; + + Если ВзвестиФлагОшибок ИЛИ БезусловнаяЗаписьВПротоколОбмена ИЛИ ВыводВПротоколИнформационныхСообщений Тогда + + мФайлПротоколаДанных.ЗаписатьСтроку(ИтоговаяСтрокаДляЗаписи); + + КонецЕсли; + + КонецЕсли; + + Возврат Стр; + +КонецФункции + +// Записывает информацию об ошибке в протокол выполнения обмена для обработчика очистки данных. +// +Процедура ЗаписатьИнформациюОбОшибкеОбработчикаОчисткиДанных(КодСообщения, СтрокаОшибки, ИмяПравилаОчисткиДанных, Объект = "", ИмяОбработчика = "") + + ЗП = ПолучитьСтруктуруЗаписиПротокола(КодСообщения, СтрокаОшибки); + ЗП.ПОД = ИмяПравилаОчисткиДанных; + + Если Объект <> "" Тогда + ОписаниеТипов = Новый ОписаниеТипов("Строка"); + ОбъектСтрока = ОписаниеТипов.ПривестиЗначение(Объект); + Если Не ПустаяСтрока(ОбъектСтрока) Тогда + ЗП.Объект = ОбъектСтрока + " (" + ТипЗнч(Объект) + ")"; + Иначе + ЗП.Объект = "" + ТипЗнч(Объект) + ""; + КонецЕсли; + КонецЕсли; + + Если ИмяОбработчика <> "" Тогда + ЗП.Обработчик = ИмяОбработчика; + КонецЕсли; + + СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(КодСообщения, ЗП); + + Если Не ФлагРежимОтладки Тогда + ВызватьИсключение СтрокаСообщенияОбОшибке; + КонецЕсли; + +КонецПроцедуры + +// Регистрирует в протоколе выполнения ошибку обработчика ПКО (выгрузка). +// +Процедура ЗаписатьИнформациюОбОшибкеВыгрузкиОбработчикаПКО(КодСообщения, СтрокаОшибки, ПКО, Источник, ИмяОбработчика) + + ЗП = ПолучитьСтруктуруЗаписиПротокола(КодСообщения, СтрокаОшибки); + ЗП.ПКО = ПКО.Имя + " (" + ПКО.Наименование + ")"; + + ОписаниеТипов = Новый ОписаниеТипов("Строка"); + ИсточникСтрока = ОписаниеТипов.ПривестиЗначение(Источник); + Если Не ПустаяСтрока(ИсточникСтрока) Тогда + ЗП.Объект = ИсточникСтрока + " (" + ТипЗнч(Источник) + ")"; + Иначе + ЗП.Объект = "(" + ТипЗнч(Источник) + ")"; + КонецЕсли; + + ЗП.Обработчик = ИмяОбработчика; + + СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(КодСообщения, ЗП); + + Если Не ФлагРежимОтладки Тогда + ВызватьИсключение СтрокаСообщенияОбОшибке; + КонецЕсли; + +КонецПроцедуры + +Процедура ЗаписатьИнформациюОбОшибкеОбработчикиПВД(КодСообщения, СтрокаОшибки, ИмяПравила, ИмяОбработчика, Объект = Неопределено) + + ЗП = ПолучитьСтруктуруЗаписиПротокола(КодСообщения, СтрокаОшибки); + ЗП.ПВД = ИмяПравила; + + Если Объект <> Неопределено Тогда + ОписаниеТипов = Новый ОписаниеТипов("Строка"); + ОбъектСтрока = ОписаниеТипов.ПривестиЗначение(Объект); + Если Не ПустаяСтрока(ОбъектСтрока) Тогда + ЗП.Объект = ОбъектСтрока + " (" + ТипЗнч(Объект) + ")"; + Иначе + ЗП.Объект = "" + ТипЗнч(Объект) + ""; + КонецЕсли; + КонецЕсли; + + ЗП.Обработчик = ИмяОбработчика; + + СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(КодСообщения, ЗП); + + Если Не ФлагРежимОтладки Тогда + ВызватьИсключение СтрокаСообщенияОбОшибке; + КонецЕсли; + +КонецПроцедуры + +Функция ЗаписатьИнформациюОбОшибкеОбработчикиКонвертации(КодСообщения, СтрокаОшибки, ИмяОбработчика) + + ЗП = ПолучитьСтруктуруЗаписиПротокола(КодСообщения, СтрокаОшибки); + ЗП.Обработчик = ИмяОбработчика; + СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(КодСообщения, ЗП); + Возврат СтрокаСообщенияОбОшибке; + +КонецФункции + +#КонецОбласти + +#Область ОписаниеТиповКоллекций + +// Возвращаемое значение: +// ТаблицаЗначений - коллекция правил конвертации данных: +// * Имя - Строка - +// * Наименование - Строка - +// * Порядок - Число - +// * СинхронизироватьПоИдентификатору - Булево - +// * НеСоздаватьЕслиНеНайден - Булево - +// * НеВыгружатьОбъектыСвойствПоСсылкам - Булево - +// * ПродолжитьПоискПоПолямПоискаЕслиПоИдентификаторуНеНашли - Булево - +// * ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD - Булево - +// * ИспользоватьБыстрыйПоискПриЗагрузке - Булево - +// * ГенерироватьНовыйНомерИлиКодЕслиНеУказан - Булево - +// * МаленькоеКоличествоОбъектов - Булево - +// * КоличествоОбращенийДляВыгрузкиСсылки - Число - +// * КоличествоЭлементовВИБ - Число - +// * СпособВыгрузки - Произвольный - +// * Источник - Произвольный - +// * Приемник - Произвольный - +// * ТипИсточника - Строка - +// * ПередВыгрузкой - Произвольный - +// * ПриВыгрузке - Произвольный - +// * ПослеВыгрузки - Произвольный - +// * ПослеВыгрузкиВФайл - Произвольный - +// * ЕстьОбработчикПередВыгрузкой - Булево - +// * ЕстьОбработчикПриВыгрузке - Булево - +// * ЕстьОбработчикПослеВыгрузки - Булево - +// * ЕстьОбработчикПослеВыгрузкиВФайл - Булево - +// * ПередЗагрузкой - Произвольный - +// * ПриЗагрузке - Произвольный - +// * ПослеЗагрузки - Произвольный - +// * ПоследовательностьПолейПоиска - Произвольный - +// * ПоискПоТабличнымЧастям - см. КоллекцияПоискПоТабличнымЧастям +// * ЕстьОбработчикПередЗагрузкой - Булево - +// * ЕстьОбработчикПриЗагрузке - Булево - +// * ЕстьОбработчикПослеЗагрузки - Булево - +// * ЕстьОбработчикПоследовательностьПолейПоиска - Булево - +// * СвойстваПоиска - см. КоллекцияПравилаКонвертацииСвойств +// * Свойства - см. КоллекцияПравилаКонвертацииСвойств +// * Выгруженные - ТаблицаЗначений - +// * ВыгружатьПредставлениеИсточника - Булево - +// * НеЗамещать - Булево - +// * ЗапоминатьВыгруженные - Булево - +// * ВсеОбъектыВыгружены - Булево - +// +Функция КоллекцияПравилаКонвертации() + + Возврат ТаблицаПравилКонвертации; + +КонецФункции + +// Возвращаемое значение: +// ДеревоЗначений - коллекция правил выгрузки данных: +// * Включить - Число - +// * ЭтоГруппа - Булево - +// * Имя - Строка - +// * Наименование - Строка - +// * Порядок - Число - +// * СпособОтбораДанных - Произвольный - +// * ОбъектВыборки - Произвольный - +// * ПравилоКонвертации - Произвольный - +// * ПередОбработкой - Строка - +// * ПослеОбработки - Строка - +// * ПередВыгрузкой - Строка - +// * ПослеВыгрузки - Строка - +// * ИспользоватьОтбор - Булево - +// * НастройкиПостроителя - Произвольный - +// * ИмяОбъектаДляЗапроса - Строка - +// * ИмяОбъектаДляЗапросаРегистра - Строка - +// * ВыбиратьДанныеДляВыгрузкиОднимЗапросом - Булево - +// * СсылкаНаУзелОбмена - ПланОбменаСсылка - +// +Функция КоллекцияПравилаВыгрузки() + + Возврат ТаблицаПравилВыгрузки; + +КонецФункции + +// Возвращаемое значение: +// ТаблицаЗначений - коллекция правил поиска по табличным частям: +// * ИмяЭлемента - Произвольный - +// * ПоляПоискаТЧ - Массив из Произвольный - +// +Функция КоллекцияПоискПоТабличнымЧастям() + + ПоискПоТабличнымЧастям = Новый ТаблицаЗначений; + ПоискПоТабличнымЧастям.Колонки.Добавить("ИмяЭлемента"); + ПоискПоТабличнымЧастям.Колонки.Добавить("ПоляПоискаТЧ"); + + Возврат ПоискПоТабличнымЧастям; + +КонецФункции + +// Возвращаемое значение: +// ТаблицаЗначений - коллекция правил конвертации свойств данных: +// * Имя - Строка - +// * Наименование - Строка - +// * Порядок - Число - +// * ЭтоГруппа - Булево - +// * ЭтоПолеПоиска - Булево - +// * ПравилаГруппы - см. КоллекцияПравилаКонвертацииСвойств +// * ПравилаГруппыОтключенные - Произвольный - +// * ВидИсточника - Произвольный - +// * ВидПриемника - Произвольный - +// * УпрощеннаяВыгрузкаСвойства - Булево - +// * НуженУзелXMLПриВыгрузке - Булево - +// * НуженУзелXMLПриВыгрузкеГруппы - Булево - +// * ТипИсточника - Строка - +// * ТипПриемника - Строка - +// * Источник - Произвольный - +// * Приемник - Произвольный - +// * ПравилоКонвертации - Произвольный - +// * ПолучитьИзВходящихДанных - Булево - +// * НеЗамещать - Булево - +// * ЭтоОбязательноеСвойство - Булево - +// * ПередВыгрузкой - Произвольный - +// * ИмяОбработчикаПередВыгрузкой - Произвольный - +// * ПриВыгрузке - Произвольный - +// * ИмяОбработчикаПриВыгрузке - Произвольный - +// * ПослеВыгрузки - Произвольный - +// * ИмяОбработчикаПослеВыгрузки - Произвольный - +// * ПередОбработкойВыгрузки - Произвольный - +// * ИмяОбработчикаПередОбработкойВыгрузки - Произвольный - +// * ПослеОбработкиВыгрузки - Произвольный - +// * ИмяОбработчикаПослеОбработкиВыгрузки - Произвольный - +// * ЕстьОбработчикПередВыгрузкой - Булево - +// * ЕстьОбработчикПриВыгрузке - Булево - +// * ЕстьОбработчикПослеВыгрузки - Булево - +// * ЕстьОбработчикПередОбработкойВыгрузки - Булево - +// * ЕстьОбработчикПослеОбработкиВыгрузки - Булево - +// * ПриводитьКДлине - Число - +// * ИмяПараметраДляПередачи - Строка - +// * ПоискПоДатеНаРавенство - Булево - +// * ВыгружатьГруппуЧерезФайл - Булево - +// * СтрокаПолейПоиска - Произвольный - +// +Функция КоллекцияПравилаКонвертацииСвойств() + + Возврат мТаблицаПравилКонвертацииСвойств; + +КонецФункции + +// Возвращаемое значение: +// ТаблицаЗначений - стек выгрузки: +// * Ссылка - ЛюбаяСсылка - ссылка на выгружаемый объект. +// +Функция КоллекцияСтекВызововВыгрузкиДанных() + + Возврат мСтекВызововВыгрузкиДанных; + +КонецФункции + +// Возвращаемое значение: +// Структура - структура правил: +// * ТаблицаПравилВыгрузки - см. КоллекцияПравилаВыгрузки +// * ТаблицаПравилКонвертации - см. КоллекцияПравилаКонвертации +// * Алгоритмы - Структура - +// * Запросы - Структура - +// * Конвертация - Произвольный - +// * мXMLПравила - Произвольный - +// * ТаблицаНастройкиПараметров - ТаблицаЗначений - +// * Параметры - Структура - +// * ВерсияПлатформыПриемника - Строка - +// +Функция ОписаниеСтруктурыПравил() + + СтруктураПравил = Новый Структура; + + СтруктураПравил.Вставить("ТаблицаПравилВыгрузки"); + СтруктураПравил.Вставить("ТаблицаПравилКонвертации"); + СтруктураПравил.Вставить("Алгоритмы"); + СтруктураПравил.Вставить("Запросы"); + СтруктураПравил.Вставить("Конвертация"); + СтруктураПравил.Вставить("мXMLПравила"); + СтруктураПравил.Вставить("ТаблицаНастройкиПараметров"); + СтруктураПравил.Вставить("Параметры"); + + СтруктураПравил.Вставить("ВерсияПлатформыПриемника"); + + Возврат СтруктураПравил; + +КонецФункции + +#КонецОбласти + +#Область ПроцедурыЗагрузкиПравилОбмена + +// Осуществляет загрузку правила конвертации группы свойств. +// +// Параметры: +// ПравилаОбмена - ЧтениеXML - Объект типа ЧтениеXML. +// ТаблицаСвойств - см. КоллекцияПравилаКонвертацииСвойств +// +Процедура ЗагрузитьПКГС(ПравилаОбмена, ТаблицаСвойств) + + Если одАтрибут(ПравилаОбмена, одТипБулево, "Отключить") Тогда + одПропустить(ПравилаОбмена); + Возврат; + КонецЕсли; + + НоваяСтрока = ТаблицаСвойств.Добавить(); + НоваяСтрока.ЭтоГруппа = Истина; + НоваяСтрока.ПравилаГруппы = КоллекцияПравилаКонвертацииСвойств().Скопировать(); + + // Значения по умолчанию + + НоваяСтрока.НеЗамещать = Ложь; + НоваяСтрока.ПолучитьИзВходящихДанных = Ложь; + НоваяСтрока.УпрощеннаяВыгрузкаСвойства = Ложь; + + СтрокаПолейПоиска = ""; + + Пока ПравилаОбмена.Прочитать() Цикл + + ИмяУзла = ПравилаОбмена.ЛокальноеИмя; + + Если ИмяУзла = "Источник" Тогда + НоваяСтрока.Источник = одАтрибут(ПравилаОбмена, одТипСтрока, "Имя"); + НоваяСтрока.ВидИсточника = одАтрибут(ПравилаОбмена, одТипСтрока, "Вид"); + НоваяСтрока.ТипИсточника = одАтрибут(ПравилаОбмена, одТипСтрока, "Тип"); + одПропустить(ПравилаОбмена); + + ИначеЕсли ИмяУзла = "Приемник" Тогда + НоваяСтрока.Приемник = одАтрибут(ПравилаОбмена, одТипСтрока, "Имя"); + НоваяСтрока.ВидПриемника = одАтрибут(ПравилаОбмена, одТипСтрока, "Вид"); + НоваяСтрока.ТипПриемника = одАтрибут(ПравилаОбмена, одТипСтрока, "Тип"); + одПропустить(ПравилаОбмена); + + ИначеЕсли ИмяУзла = "Свойство" Тогда + ЗагрузитьПКС(ПравилаОбмена, НоваяСтрока.ПравилаГруппы, , СтрокаПолейПоиска); + + ИначеЕсли ИмяУзла = "ПередОбработкойВыгрузки" Тогда + НоваяСтрока.ПередОбработкойВыгрузки = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + НоваяСтрока.ЕстьОбработчикПередОбработкойВыгрузки = Не ПустаяСтрока(НоваяСтрока.ПередОбработкойВыгрузки); + + ИначеЕсли ИмяУзла = "ПослеОбработкиВыгрузки" Тогда + НоваяСтрока.ПослеОбработкиВыгрузки = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + НоваяСтрока.ЕстьОбработчикПослеОбработкиВыгрузки = Не ПустаяСтрока(НоваяСтрока.ПослеОбработкиВыгрузки); + + ИначеЕсли ИмяУзла = "Код" Тогда + НоваяСтрока.Имя = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + + ИначеЕсли ИмяУзла = "Наименование" Тогда + НоваяСтрока.Наименование = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + + ИначеЕсли ИмяУзла = "Порядок" Тогда + НоваяСтрока.Порядок = одЗначениеЭлемента(ПравилаОбмена, одТипЧисло); + + ИначеЕсли ИмяУзла = "НеЗамещать" Тогда + НоваяСтрока.НеЗамещать = одЗначениеЭлемента(ПравилаОбмена, одТипБулево); + + ИначеЕсли ИмяУзла = "КодПравилаКонвертации" Тогда + НоваяСтрока.ПравилоКонвертации = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + + ИначеЕсли ИмяУзла = "ПередВыгрузкой" Тогда + НоваяСтрока.ПередВыгрузкой = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + НоваяСтрока.ЕстьОбработчикПередВыгрузкой = Не ПустаяСтрока(НоваяСтрока.ПередВыгрузкой); + + ИначеЕсли ИмяУзла = "ПриВыгрузке" Тогда + НоваяСтрока.ПриВыгрузке = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + НоваяСтрока.ЕстьОбработчикПриВыгрузке = Не ПустаяСтрока(НоваяСтрока.ПриВыгрузке); + + ИначеЕсли ИмяУзла = "ПослеВыгрузки" Тогда + НоваяСтрока.ПослеВыгрузки = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + НоваяСтрока.ЕстьОбработчикПослеВыгрузки = Не ПустаяСтрока(НоваяСтрока.ПослеВыгрузки); + + ИначеЕсли ИмяУзла = "ВыгружатьГруппуЧерезФайл" Тогда + НоваяСтрока.ВыгружатьГруппуЧерезФайл = одЗначениеЭлемента(ПравилаОбмена, одТипБулево); + + ИначеЕсли ИмяУзла = "ПолучитьИзВходящихДанных" Тогда + НоваяСтрока.ПолучитьИзВходящихДанных = одЗначениеЭлемента(ПравилаОбмена, одТипБулево); + + ИначеЕсли (ИмяУзла = "Группа") И (ПравилаОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + Прервать; + КонецЕсли; + + КонецЦикла; + + НоваяСтрока.СтрокаПолейПоиска = СтрокаПолейПоиска; + + НоваяСтрока.НуженУзелXMLПриВыгрузке = НоваяСтрока.ЕстьОбработчикПриВыгрузке ИЛИ НоваяСтрока.ЕстьОбработчикПослеВыгрузки; + + НоваяСтрока.НуженУзелXMLПриВыгрузкеГруппы = НоваяСтрока.ЕстьОбработчикПослеОбработкиВыгрузки; + +КонецПроцедуры + +Процедура ДобавитьПолеКСтрокеПоиска(СтрокаПолейПоиска, ИмяПоля) + + Если ПустаяСтрока(ИмяПоля) Тогда + Возврат; + КонецЕсли; + + Если НЕ ПустаяСтрока(СтрокаПолейПоиска) Тогда + СтрокаПолейПоиска = СтрокаПолейПоиска + ","; + КонецЕсли; + + СтрокаПолейПоиска = СтрокаПолейПоиска + ИмяПоля; + +КонецПроцедуры + +// Осуществляет загрузку правила конвертации свойств. +// +// Параметры: +// ПравилаОбмена - ЧтениеXML - объект, содержащий текст правил обмена. +// ТаблицаСвойств - см. КоллекцияПравилаКонвертацииСвойств +// ТаблицаПоиска - см. КоллекцияПравилаКонвертацииСвойств +// +Процедура ЗагрузитьПКС(ПравилаОбмена, ТаблицаСвойств, ТаблицаПоиска = Неопределено, СтрокаПолейПоиска = "") + + Если одАтрибут(ПравилаОбмена, одТипБулево, "Отключить") Тогда + одПропустить(ПравилаОбмена); + Возврат; + КонецЕсли; + + + ЭтоПолеПоиска = одАтрибут(ПравилаОбмена, одТипБулево, "Поиск"); + + Если ЭтоПолеПоиска + И ТаблицаПоиска <> Неопределено Тогда + + НоваяСтрока = ТаблицаПоиска.Добавить(); + + Иначе + + НоваяСтрока = ТаблицаСвойств.Добавить(); + + КонецЕсли; + + + // Значения по умолчанию + + НоваяСтрока.НеЗамещать = Ложь; + НоваяСтрока.ПолучитьИзВходящихДанных = Ложь; + + + Пока ПравилаОбмена.Прочитать() Цикл + + ИмяУзла = ПравилаОбмена.ЛокальноеИмя; + + Если ИмяУзла = "Источник" Тогда + НоваяСтрока.Источник = одАтрибут(ПравилаОбмена, одТипСтрока, "Имя"); + НоваяСтрока.ВидИсточника = одАтрибут(ПравилаОбмена, одТипСтрока, "Вид"); + НоваяСтрока.ТипИсточника = одАтрибут(ПравилаОбмена, одТипСтрока, "Тип"); + одПропустить(ПравилаОбмена); + + ИначеЕсли ИмяУзла = "Приемник" Тогда + НоваяСтрока.Приемник = одАтрибут(ПравилаОбмена, одТипСтрока, "Имя"); + НоваяСтрока.ВидПриемника = одАтрибут(ПравилаОбмена, одТипСтрока, "Вид"); + НоваяСтрока.ТипПриемника = одАтрибут(ПравилаОбмена, одТипСтрока, "Тип"); + + Если ЭтоПолеПоиска Тогда + ДобавитьПолеКСтрокеПоиска(СтрокаПолейПоиска, НоваяСтрока.Приемник); + КонецЕсли; + + одПропустить(ПравилаОбмена); + + ИначеЕсли ИмяУзла = "Код" Тогда + НоваяСтрока.Имя = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + + ИначеЕсли ИмяУзла = "Наименование" Тогда + НоваяСтрока.Наименование = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + + ИначеЕсли ИмяУзла = "Порядок" Тогда + НоваяСтрока.Порядок = одЗначениеЭлемента(ПравилаОбмена, одТипЧисло); + + ИначеЕсли ИмяУзла = "НеЗамещать" Тогда + НоваяСтрока.НеЗамещать = одЗначениеЭлемента(ПравилаОбмена, одТипБулево); + + ИначеЕсли ИмяУзла = "КодПравилаКонвертации" Тогда + НоваяСтрока.ПравилоКонвертации = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + + ИначеЕсли ИмяУзла = "ПередВыгрузкой" Тогда + НоваяСтрока.ПередВыгрузкой = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + НоваяСтрока.ЕстьОбработчикПередВыгрузкой = Не ПустаяСтрока(НоваяСтрока.ПередВыгрузкой); + + ИначеЕсли ИмяУзла = "ПриВыгрузке" Тогда + НоваяСтрока.ПриВыгрузке = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + НоваяСтрока.ЕстьОбработчикПриВыгрузке = Не ПустаяСтрока(НоваяСтрока.ПриВыгрузке); + + ИначеЕсли ИмяУзла = "ПослеВыгрузки" Тогда + НоваяСтрока.ПослеВыгрузки = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + НоваяСтрока.ЕстьОбработчикПослеВыгрузки = Не ПустаяСтрока(НоваяСтрока.ПослеВыгрузки); + + ИначеЕсли ИмяУзла = "ПолучитьИзВходящихДанных" Тогда + НоваяСтрока.ПолучитьИзВходящихДанных = одЗначениеЭлемента(ПравилаОбмена, одТипБулево); + + ИначеЕсли ИмяУзла = "ПриводитьКДлине" Тогда + НоваяСтрока.ПриводитьКДлине = одЗначениеЭлемента(ПравилаОбмена, одТипЧисло); + + ИначеЕсли ИмяУзла = "ИмяПараметраДляПередачи" Тогда + НоваяСтрока.ИмяПараметраДляПередачи = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + + ИначеЕсли ИмяУзла = "ПоискПоДатеНаРавенство" Тогда + НоваяСтрока.ПоискПоДатеНаРавенство = одЗначениеЭлемента(ПравилаОбмена, одТипБулево); + + ИначеЕсли (ИмяУзла = "Свойство") И (ПравилаОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + Прервать; + КонецЕсли; + + КонецЦикла; + + НоваяСтрока.УпрощеннаяВыгрузкаСвойства = НЕ НоваяСтрока.ПолучитьИзВходящихДанных + И НЕ НоваяСтрока.ЕстьОбработчикПередВыгрузкой + И НЕ НоваяСтрока.ЕстьОбработчикПриВыгрузке + И НЕ НоваяСтрока.ЕстьОбработчикПослеВыгрузки + И ПустаяСтрока(НоваяСтрока.ПравилоКонвертации) + И НоваяСтрока.ТипИсточника = НоваяСтрока.ТипПриемника + И (НоваяСтрока.ТипИсточника = "Строка" ИЛИ НоваяСтрока.ТипИсточника = "Число" ИЛИ НоваяСтрока.ТипИсточника = "Булево" ИЛИ НоваяСтрока.ТипИсточника = "Дата"); + + НоваяСтрока.НуженУзелXMLПриВыгрузке = НоваяСтрока.ЕстьОбработчикПриВыгрузке ИЛИ НоваяСтрока.ЕстьОбработчикПослеВыгрузки; + +КонецПроцедуры + +// Осуществляет загрузку правил конвертации свойств. +// +// Параметры: +// ПравилаОбмена - ЧтениеXML - Объект типа ЧтениеXML. +// ТаблицаСвойств - ТаблицаЗначений - таблица значений, содержащая ПКС. +// ТаблицаПоиска - ТаблицаЗначений - таблица значений, содержащая ПКС (синхронизирующих). +// +Процедура ЗагрузитьСвойства(ПравилаОбмена, ТаблицаСвойств, ТаблицаПоиска) + + Пока ПравилаОбмена.Прочитать() Цикл + + ИмяУзла = ПравилаОбмена.ЛокальноеИмя; + + Если ИмяУзла = "Свойство" Тогда + ЗагрузитьПКС(ПравилаОбмена, ТаблицаСвойств, ТаблицаПоиска); + ИначеЕсли ИмяУзла = "Группа" Тогда + ЗагрузитьПКГС(ПравилаОбмена, ТаблицаСвойств); + ИначеЕсли (ИмяУзла = "Свойства") И (ПравилаОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + Прервать; + КонецЕсли; + + КонецЦикла; + + ТаблицаСвойств.Сортировать("Порядок"); + ТаблицаПоиска.Сортировать("Порядок"); + +КонецПроцедуры + +// Осуществляет загрузку правила конвертации значений. +// +// Параметры: +// ПравилаОбмена - ЧтениеXML - Объект типа ЧтениеXML. +// Значения - соответствие значений объекта источника - строковым +// представлениям объекта приемника. +// ТипИсточника - значение Тип - типа Тип - тип объекта источника. +// +Процедура ЗагрузитьПКЗ(ПравилаОбмена, Значения, ТипИсточника) + + Источник = ""; + Приемник = ""; + Пока ПравилаОбмена.Прочитать() Цикл + + ИмяУзла = ПравилаОбмена.ЛокальноеИмя; + + Если ИмяУзла = "Источник" Тогда + Источник = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + ИначеЕсли ИмяУзла = "Приемник" Тогда + Приемник = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + ИначеЕсли (ИмяУзла = "Значение") И (ПравилаОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + Прервать; + КонецЕсли; + + КонецЦикла; + + Если РежимОбмена <> "Загрузка" Тогда + Значения[одПолучитьЗначениеПоСтроке(Источник, ТипИсточника)] = Приемник; + КонецЕсли; + +КонецПроцедуры + +// Осуществляет загрузку правил конвертации значений. +// +// Параметры: +// ПравилаОбмена - ЧтениеXML - Объект типа ЧтениеXML. +// Значения - соответствие значений объекта источника - строковым +// представлениям объекта приемника. +// ТипИсточника - значение Тип - типа Тип - тип объекта источника. +// +Процедура ЗагрузитьЗначения(ПравилаОбмена, Значения, ТипИсточника); + + Пока ПравилаОбмена.Прочитать() Цикл + + ИмяУзла = ПравилаОбмена.ЛокальноеИмя; + + Если ИмяУзла = "Значение" Тогда + ЗагрузитьПКЗ(ПравилаОбмена, Значения, ТипИсточника); + ИначеЕсли (ИмяУзла = "Значения") И (ПравилаОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + Прервать; + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + +// Процедура очистки ПКо у менеджеров для правил обмена. +Процедура ОчиститьПКОМенеджеров() + + Если Менеджеры = Неопределено Тогда + Возврат; + КонецЕсли; + + Для Каждого МенеджерПравила Из Менеджеры Цикл + МенеджерПравила.Значение.ПКО = Неопределено; + КонецЦикла; + +КонецПроцедуры + +// Осуществляет загрузку правила конвертации объектов. +// +// Параметры: +// ПравилаОбмена - ЧтениеXML - Объект типа ЧтениеXML. +// ЗаписьXML - ЗаписьXML - Объект типа ЗаписьXML - правила, сохраняемые в файл обмена и +// используемые при загрузке данных. +// +Процедура ЗагрузитьПравилоКонвертации(ПравилаОбмена, ЗаписьXML) + + ЗаписьXML.ЗаписатьНачалоЭлемента("Правило"); + + НоваяСтрока = КоллекцияПравилаКонвертации().Добавить(); + + // Значения по умолчанию + + НоваяСтрока.ЗапоминатьВыгруженные = Истина; + НоваяСтрока.НеЗамещать = Ложь; + + ТаблицаПоискПоТЧ = КоллекцияПоискПоТабличнымЧастям(); + НоваяСтрока.ПоискПоТабличнымЧастям = ТаблицаПоискПоТЧ; + + Пока ПравилаОбмена.Прочитать() Цикл + + ИмяУзла = ПравилаОбмена.ЛокальноеИмя; + + Если ИмяУзла = "Код" Тогда + + Значение = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение); + НоваяСтрока.Имя = Значение; + + ИначеЕсли ИмяУзла = "Наименование" Тогда + + НоваяСтрока.Наименование = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + + ИначеЕсли ИмяУзла = "СинхронизироватьПоИдентификатору" Тогда + + НоваяСтрока.СинхронизироватьПоИдентификатору = одЗначениеЭлемента(ПравилаОбмена, одТипБулево); + одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, НоваяСтрока.СинхронизироватьПоИдентификатору); + + ИначеЕсли ИмяУзла = "НеСоздаватьЕслиНеНайден" Тогда + + НоваяСтрока.НеСоздаватьЕслиНеНайден = одЗначениеЭлемента(ПравилаОбмена, одТипБулево); + + ИначеЕсли ИмяУзла = "НеВыгружатьОбъектыСвойствПоСсылкам" Тогда + + НоваяСтрока.НеВыгружатьОбъектыСвойствПоСсылкам = одЗначениеЭлемента(ПравилаОбмена, одТипБулево); + + ИначеЕсли ИмяУзла = "ПродолжитьПоискПоПолямПоискаЕслиПоИдентификаторуНеНашли" Тогда + + НоваяСтрока.ПродолжитьПоискПоПолямПоискаЕслиПоИдентификаторуНеНашли = одЗначениеЭлемента(ПравилаОбмена, одТипБулево); + одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, НоваяСтрока.ПродолжитьПоискПоПолямПоискаЕслиПоИдентификаторуНеНашли); + + ИначеЕсли ИмяУзла = "ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD" Тогда + + НоваяСтрока.ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD = одЗначениеЭлемента(ПравилаОбмена, одТипБулево); + одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, НоваяСтрока.ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD); + + ИначеЕсли ИмяУзла = "НеЗамещатьОбъектСозданныйВИнформационнойБазеПриемнике" Тогда + // не влияет на обмен + одЗначениеЭлемента(ПравилаОбмена, одТипБулево); + + ИначеЕсли ИмяУзла = "ИспользоватьБыстрыйПоискПриЗагрузке" Тогда + + НоваяСтрока.ИспользоватьБыстрыйПоискПриЗагрузке = одЗначениеЭлемента(ПравилаОбмена, одТипБулево); + + ИначеЕсли ИмяУзла = "ГенерироватьНовыйНомерИлиКодЕслиНеУказан" Тогда + + НоваяСтрока.ГенерироватьНовыйНомерИлиКодЕслиНеУказан = одЗначениеЭлемента(ПравилаОбмена, одТипБулево); + одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, НоваяСтрока.ГенерироватьНовыйНомерИлиКодЕслиНеУказан); + + ИначеЕсли ИмяУзла = "НеЗапоминатьВыгруженные" Тогда + + НоваяСтрока.ЗапоминатьВыгруженные = Не одЗначениеЭлемента(ПравилаОбмена, одТипБулево); + + ИначеЕсли ИмяУзла = "НеЗамещать" Тогда + + Значение = одЗначениеЭлемента(ПравилаОбмена, одТипБулево); + одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение); + НоваяСтрока.НеЗамещать = Значение; + + ИначеЕсли ИмяУзла = "ПриоритетОбъектовОбмена" Тогда + + // В универсальном обмене не участвует. + одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + + ИначеЕсли ИмяУзла = "Приемник" Тогда + + Значение = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение); + НоваяСтрока.Приемник = Значение; + + ИначеЕсли ИмяУзла = "Источник" Тогда + + Значение = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение); + + Если РежимОбмена = "Загрузка" Тогда + + НоваяСтрока.Источник = Значение; + + Иначе + + Если Не ПустаяСтрока(Значение) Тогда + + НоваяСтрока.ТипИсточника = Значение; + НоваяСтрока.Источник = Тип(Значение); + + Попытка + + Менеджеры[НоваяСтрока.Источник].ПКО = НоваяСтрока; + + Исключение + + ЗаписатьИнформациюОбОшибкеВПротокол(11, ОписаниеОшибки(), Строка(НоваяСтрока.Источник)); + + КонецПопытки; + + КонецЕсли; + + КонецЕсли; + + // Свойства + + ИначеЕсли ИмяУзла = "Свойства" Тогда + + НоваяСтрока.СвойстваПоиска = мТаблицаПравилКонвертацииСвойств.Скопировать(); + НоваяСтрока.Свойства = мТаблицаПравилКонвертацииСвойств.Скопировать(); + + + Если НоваяСтрока.СинхронизироватьПоИдентификатору <> Неопределено И НоваяСтрока.СинхронизироватьПоИдентификатору Тогда + + СвойствоПоискаУИ = НоваяСтрока.СвойстваПоиска.Добавить(); + СвойствоПоискаУИ.Имя = "{УникальныйИдентификатор}"; + СвойствоПоискаУИ.Источник = "{УникальныйИдентификатор}"; + СвойствоПоискаУИ.Приемник = "{УникальныйИдентификатор}"; + + КонецЕсли; + + ЗагрузитьСвойства(ПравилаОбмена, НоваяСтрока.Свойства, НоваяСтрока.СвойстваПоиска); + + + // Значения + + ИначеЕсли ИмяУзла = "Значения" Тогда + + ЗагрузитьЗначения(ПравилаОбмена, НоваяСтрока.Значения, НоваяСтрока.Источник); + + // Обработчики событий + + ИначеЕсли ИмяУзла = "ПередВыгрузкой" Тогда + + НоваяСтрока.ПередВыгрузкой = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + НоваяСтрока.ЕстьОбработчикПередВыгрузкой = Не ПустаяСтрока(НоваяСтрока.ПередВыгрузкой); + + ИначеЕсли ИмяУзла = "ПриВыгрузке" Тогда + + НоваяСтрока.ПриВыгрузке = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + НоваяСтрока.ЕстьОбработчикПриВыгрузке = Не ПустаяСтрока(НоваяСтрока.ПриВыгрузке); + + ИначеЕсли ИмяУзла = "ПослеВыгрузки" Тогда + + НоваяСтрока.ПослеВыгрузки = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + НоваяСтрока.ЕстьОбработчикПослеВыгрузки = Не ПустаяСтрока(НоваяСтрока.ПослеВыгрузки); + + ИначеЕсли ИмяУзла = "ПослеВыгрузкиВФайл" Тогда + + НоваяСтрока.ПослеВыгрузкиВФайл = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + НоваяСтрока.ЕстьОбработчикПослеВыгрузкиВФайл = Не ПустаяСтрока(НоваяСтрока.ПослеВыгрузкиВФайл); + + // Для загрузки + + ИначеЕсли ИмяУзла = "ПередЗагрузкой" Тогда + + Значение = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + + + Если РежимОбмена = "Загрузка" Тогда + + НоваяСтрока.ПередЗагрузкой = Значение; + НоваяСтрока.ЕстьОбработчикПередЗагрузкой = Не ПустаяСтрока(Значение); + + Иначе + + одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение); + + КонецЕсли; + + ИначеЕсли ИмяУзла = "ПриЗагрузке" Тогда + + Значение = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + + Если РежимОбмена = "Загрузка" Тогда + + НоваяСтрока.ПриЗагрузке = Значение; + НоваяСтрока.ЕстьОбработчикПриЗагрузке = Не ПустаяСтрока(Значение); + + Иначе + + одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение); + + КонецЕсли; + + ИначеЕсли ИмяУзла = "ПослеЗагрузки" Тогда + + Значение = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + + Если РежимОбмена = "Загрузка" Тогда + + НоваяСтрока.ПослеЗагрузки = Значение; + НоваяСтрока.ЕстьОбработчикПослеЗагрузки = Не ПустаяСтрока(Значение); + + Иначе + + одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение); + + КонецЕсли; + + ИначеЕсли ИмяУзла = "ПоследовательностьПолейПоиска" Тогда + + Значение = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + + НоваяСтрока.ЕстьОбработчикПоследовательностьПолейПоиска = Не ПустаяСтрока(Значение); + + Если РежимОбмена = "Загрузка" Тогда + + НоваяСтрока.ПоследовательностьПолейПоиска = Значение; + + Иначе + + одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение); + + КонецЕсли; + + ИначеЕсли ИмяУзла = "ПоискПоТабличнымЧастям" Тогда + + Значение = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + + Для Номер = 1 По СтрЧислоСтрок(Значение) Цикл + + ТекущаяСтрока = СтрПолучитьСтроку(Значение, Номер); + + СтрокаПоиска = ОтделитьРазделителем(ТекущаяСтрока, ":"); + + СтрокаТаблицы = ТаблицаПоискПоТЧ.Добавить(); + СтрокаТаблицы.ИмяЭлемента = ТекущаяСтрока; + + СтрокаТаблицы.ПоляПоискаТЧ = РазложитьСтрокуВМассивПодстрок(СтрокаПоиска); + + КонецЦикла; + + ИначеЕсли (ИмяУзла = "Правило") И (ПравилаОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + + Прервать; + + КонецЕсли; + + КонецЦикла; + + ИтоговаяСтрокаПоискаПоТЧ = ""; + + // В приемник нужно передать информацию о полях поиска для табличных частей. + Для Каждого СтрокаСвойств Из НоваяСтрока.Свойства Цикл + + Если Не СтрокаСвойств.ЭтоГруппа + ИЛИ ПустаяСтрока(СтрокаСвойств.ВидИсточника) + ИЛИ ПустаяСтрока(СтрокаСвойств.Приемник) Тогда + + Продолжить; + + КонецЕсли; + + Если ПустаяСтрока(СтрокаСвойств.СтрокаПолейПоиска) Тогда + Продолжить; + КонецЕсли; + + ИтоговаяСтрокаПоискаПоТЧ = ИтоговаяСтрокаПоискаПоТЧ + Символы.ПС + СтрокаСвойств.ВидИсточника + "." + СтрокаСвойств.Приемник + ":" + СтрокаСвойств.СтрокаПолейПоиска; + + КонецЦикла; + + ИтоговаяСтрокаПоискаПоТЧ = СокрЛП(ИтоговаяСтрокаПоискаПоТЧ); + + Если Не ПустаяСтрока(ИтоговаяСтрокаПоискаПоТЧ) Тогда + + одЗаписатьЭлемент(ЗаписьXML, "ПоискПоТабличнымЧастям", ИтоговаяСтрокаПоискаПоТЧ); + + КонецЕсли; + + ЗаписьXML.ЗаписатьКонецЭлемента(); + + + // Быстрый доступ к ПКО по имени. + + Правила.Вставить(НоваяСтрока.Имя, НоваяСтрока); + +КонецПроцедуры + +// Осуществляет загрузку правил конвертации объектов. +// +// Параметры: +// ПравилаОбмена - ЧтениеXML - Объект типа ЧтениеXML. +// ЗаписьXML - ЗаписьXML - Объект типа ЗаписьXML - правила, сохраняемые в файл обмена и +// используемые при загрузке данных. +// +Процедура ЗагрузитьПравилаКонвертации(ПравилаОбмена, ЗаписьXML) + + ТаблицаПравилКонвертации.Очистить(); + ОчиститьПКОМенеджеров(); + + ЗаписьXML.ЗаписатьНачалоЭлемента("ПравилаКонвертацииОбъектов"); + + Пока ПравилаОбмена.Прочитать() Цикл + + ИмяУзла = ПравилаОбмена.ЛокальноеИмя; + + Если ИмяУзла = "Правило" Тогда + + ЗагрузитьПравилоКонвертации(ПравилаОбмена, ЗаписьXML); + + ИначеЕсли (ИмяУзла = "ПравилаКонвертацииОбъектов") И (ПравилаОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + + Прервать; + + КонецЕсли; + + КонецЦикла; + + ЗаписьXML.ЗаписатьКонецЭлемента(); + + ТаблицаПравилКонвертации.Индексы.Добавить("Приемник"); + +КонецПроцедуры + +// Осуществляет загрузку группы правил очистки данных в соответствии с форматом правил обмена. +// +// Параметры: +// НоваяСтрока - СтрокаДереваЗначений - структура, описывающая группу правил очистки данных: +// * Имя - Строка - идентификатор правила. +// * Наименование - Строка - пользовательское представление правила. +// +Процедура ЗагрузитьГруппуПОД(ПравилаОбмена, НоваяСтрока) + + НоваяСтрока.ЭтоГруппа = Истина; + НоваяСтрока.Включить = Число(Не одАтрибут(ПравилаОбмена, одТипБулево, "Отключить")); + + Пока ПравилаОбмена.Прочитать() Цикл + + ИмяУзла = ПравилаОбмена.ЛокальноеИмя; + ТипУзла = ПравилаОбмена.ТипУзла; + + Если ИмяУзла = "Код" Тогда + НоваяСтрока.Имя = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + + ИначеЕсли ИмяУзла = "Наименование" Тогда + НоваяСтрока.Наименование = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + + ИначеЕсли ИмяУзла = "Порядок" Тогда + НоваяСтрока.Порядок = одЗначениеЭлемента(ПравилаОбмена, одТипЧисло); + + ИначеЕсли ИмяУзла = "Правило" Тогда + СтрокаДЗ = НоваяСтрока.Строки.Добавить(); + ЗагрузитьПОД(ПравилаОбмена, СтрокаДЗ); + + ИначеЕсли (ИмяУзла = "Группа") И (ТипУзла = одТипУзлаXML_НачалоЭлемента) Тогда + СтрокаДЗ = НоваяСтрока.Строки.Добавить(); + ЗагрузитьГруппуПОД(ПравилаОбмена, СтрокаДЗ); + + ИначеЕсли (ИмяУзла = "Группа") И (ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + Прервать; + КонецЕсли; + + КонецЦикла; + + Если ПустаяСтрока(НоваяСтрока.Наименование) Тогда + НоваяСтрока.Наименование = НоваяСтрока.Имя; + КонецЕсли; + +КонецПроцедуры + +// Осуществляет загрузку правила очистки данных в соответствии с форматом правил обмена. +// +// Параметры: +// НоваяСтрока - СтрокаДереваЗначений - структура, описывающая правило очистки данных: +// * Имя - Строка - идентификатор правила. +// * Наименование - Строка - пользовательское представление правила. +// +Процедура ЗагрузитьПОД(ПравилаОбмена, НоваяСтрока) + + НоваяСтрока.Включить = Число(Не одАтрибут(ПравилаОбмена, одТипБулево, "Отключить")); + + Пока ПравилаОбмена.Прочитать() Цикл + + ИмяУзла = ПравилаОбмена.ЛокальноеИмя; + + Если ИмяУзла = "Код" Тогда + Значение = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + НоваяСтрока.Имя = Значение; + + ИначеЕсли ИмяУзла = "Наименование" Тогда + НоваяСтрока.Наименование = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + + ИначеЕсли ИмяУзла = "Порядок" Тогда + НоваяСтрока.Порядок = одЗначениеЭлемента(ПравилаОбмена, одТипЧисло); + + ИначеЕсли ИмяУзла = "СпособОтбораДанных" Тогда + НоваяСтрока.СпособОтбораДанных = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + + ИначеЕсли ИмяУзла = "ОбъектВыборки" Тогда + ОбъектВыборки = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + Если Не ПустаяСтрока(ОбъектВыборки) Тогда + НоваяСтрока.ОбъектВыборки = Тип(ОбъектВыборки); + КонецЕсли; + + ИначеЕсли ИмяУзла = "УдалятьЗаПериод" Тогда + НоваяСтрока.УдалятьЗаПериод = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + + ИначеЕсли ИмяУзла = "Непосредственно" Тогда + НоваяСтрока.Непосредственно = одЗначениеЭлемента(ПравилаОбмена, одТипБулево); + + + // Обработчики событий + + ИначеЕсли ИмяУзла = "ПередОбработкойПравила" Тогда + НоваяСтрока.ПередОбработкой = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + + ИначеЕсли ИмяУзла = "ПослеОбработкиПравила" Тогда + НоваяСтрока.ПослеОбработки = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + + ИначеЕсли ИмяУзла = "ПередУдалениемОбъекта" Тогда + НоваяСтрока.ПередУдалением = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + + // Выход + ИначеЕсли (ИмяУзла = "Правило") И (ПравилаОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + Прервать; + + КонецЕсли; + + КонецЦикла; + + + Если ПустаяСтрока(НоваяСтрока.Наименование) Тогда + НоваяСтрока.Наименование = НоваяСтрока.Имя; + КонецЕсли; + +КонецПроцедуры + +// Осуществляет загрузку правил очистки данных. +// +// Параметры: +// ПравилаОбмена - ЧтениеXML - Объект типа ЧтениеXML. +// ЗаписьXML - ЗаписьXML - Объект типа ЗаписьXML - правила, сохраняемые в файл обмена и +// используемые при загрузке данных. +// +Процедура ЗагрузитьПравилаОчистки(ПравилаОбмена, ЗаписьXML) + + ТаблицаПравилОчистки.Строки.Очистить(); + СтрокиДЗ = ТаблицаПравилОчистки.Строки; + + ЗаписьXML.ЗаписатьНачалоЭлемента("ПравилаОчисткиДанных"); + + Пока ПравилаОбмена.Прочитать() Цикл + + ТипУзла = ПравилаОбмена.ТипУзла; + + Если ТипУзла = одТипУзлаXML_НачалоЭлемента Тогда + ИмяУзла = ПравилаОбмена.ЛокальноеИмя; + Если РежимОбмена <> "Загрузка" Тогда + ЗаписьXML.ЗаписатьНачалоЭлемента(ПравилаОбмена.Имя); + Пока ПравилаОбмена.ПрочитатьАтрибут() Цикл + ЗаписьXML.ЗаписатьАтрибут(ПравилаОбмена.Имя, ПравилаОбмена.Значение); + КонецЦикла; + Иначе + Если ИмяУзла = "Правило" Тогда + СтрокаДЗ = СтрокиДЗ.Добавить(); + ЗагрузитьПОД(ПравилаОбмена, СтрокаДЗ); + ИначеЕсли ИмяУзла = "Группа" Тогда + СтрокаДЗ = СтрокиДЗ.Добавить(); + ЗагрузитьГруппуПОД(ПравилаОбмена, СтрокаДЗ); + КонецЕсли; + КонецЕсли; + ИначеЕсли ТипУзла = одТипУзлаXML_КонецЭлемента Тогда + ИмяУзла = ПравилаОбмена.ЛокальноеИмя; + Если ИмяУзла = "ПравилаОчисткиДанных" Тогда + Прервать; + Иначе + Если РежимОбмена <> "Загрузка" Тогда + ЗаписьXML.ЗаписатьКонецЭлемента(); + КонецЕсли; + КонецЕсли; + ИначеЕсли ТипУзла = одТипУзлаXML_Текст Тогда + Если РежимОбмена <> "Загрузка" Тогда + ЗаписьXML.ЗаписатьТекст(ПравилаОбмена.Значение); + КонецЕсли; + КонецЕсли; + КонецЦикла; + + СтрокиДЗ.Сортировать("Порядок", Истина); + + ЗаписьXML.ЗаписатьКонецЭлемента(); + +КонецПроцедуры + +// Осуществляет загрузку алгоритма в соответствии с форматом правил обмена. +// +// Параметры: +// ПравилаОбмена - ЧтениеXML - Объект типа ЧтениеXML. +// ЗаписьXML - ЗаписьXML - Объект типа ЗаписьXML - правила, сохраняемые в файл обмена и +// используемые при загрузке данных. +// +Процедура ЗагрузитьАлгоритм(ПравилаОбмена, ЗаписьXML) + + ИспользуетсяПриЗагрузке = одАтрибут(ПравилаОбмена, одТипБулево, "ИспользуетсяПриЗагрузке"); + Имя = одАтрибут(ПравилаОбмена, одТипСтрока, "Имя"); + + Пока ПравилаОбмена.Прочитать() Цикл + + ИмяУзла = ПравилаОбмена.ЛокальноеИмя; + + Если ИмяУзла = "Текст" Тогда + Текст = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + ИначеЕсли (ИмяУзла = "Алгоритм") И (ПравилаОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + Прервать; + Иначе + одПропустить(ПравилаОбмена); + КонецЕсли; + + КонецЦикла; + + + Если ИспользуетсяПриЗагрузке Тогда + Если РежимОбмена = "Загрузка" Тогда + Алгоритмы.Вставить(Имя, Текст); + Иначе + ЗаписьXML.ЗаписатьНачалоЭлемента("Алгоритм"); + УстановитьАтрибут(ЗаписьXML, "ИспользуетсяПриЗагрузке", Истина); + УстановитьАтрибут(ЗаписьXML, "Имя", Имя); + одЗаписатьЭлемент(ЗаписьXML, "Текст", Текст); + ЗаписьXML.ЗаписатьКонецЭлемента(); + КонецЕсли; + Иначе + Если РежимОбмена <> "Загрузка" Тогда + Алгоритмы.Вставить(Имя, Текст); + КонецЕсли; + КонецЕсли; + + +КонецПроцедуры + +// Осуществляет загрузку алгоритмов в соответствии с форматом правил обмена. +// +// Параметры: +// ПравилаОбмена - ЧтениеXML - Объект типа ЧтениеXML. +// ЗаписьXML - ЗаписьXML - Объект типа ЗаписьXML - правила, сохраняемые в файл обмена и +// используемые при загрузке данных. +// +Процедура ЗагрузитьАлгоритмы(ПравилаОбмена, ЗаписьXML) + + Алгоритмы.Очистить(); + + ЗаписьXML.ЗаписатьНачалоЭлемента("Алгоритмы"); + + Пока ПравилаОбмена.Прочитать() Цикл + ИмяУзла = ПравилаОбмена.ЛокальноеИмя; + Если ИмяУзла = "Алгоритм" Тогда + ЗагрузитьАлгоритм(ПравилаОбмена, ЗаписьXML); + ИначеЕсли (ИмяУзла = "Алгоритмы") И (ПравилаОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + Прервать; + КонецЕсли; + + КонецЦикла; + + ЗаписьXML.ЗаписатьКонецЭлемента(); + +КонецПроцедуры + +// Осуществляет загрузку запроса в соответствии с форматом правил обмена. +// +// Параметры: +// ПравилаОбмена - ЧтениеXML - Объект типа ЧтениеXML. +// ЗаписьXML - ЗаписьXML - Объект типа ЗаписьXML - правила, сохраняемые в файл обмена и +// используемые при загрузке данных. +// +Процедура ЗагрузитьЗапрос(ПравилаОбмена, ЗаписьXML) + + ИспользуетсяПриЗагрузке = одАтрибут(ПравилаОбмена, одТипБулево, "ИспользуетсяПриЗагрузке"); + Имя = одАтрибут(ПравилаОбмена, одТипСтрока, "Имя"); + + Пока ПравилаОбмена.Прочитать() Цикл + + ИмяУзла = ПравилаОбмена.ЛокальноеИмя; + + Если ИмяУзла = "Текст" Тогда + Текст = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + ИначеЕсли (ИмяУзла = "Запрос") И (ПравилаОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + Прервать; + Иначе + одПропустить(ПравилаОбмена); + КонецЕсли; + + КонецЦикла; + + Если ИспользуетсяПриЗагрузке Тогда + Если РежимОбмена = "Загрузка" Тогда + Запрос = Новый Запрос(Текст); + Запросы.Вставить(Имя, Запрос); + Иначе + ЗаписьXML.ЗаписатьНачалоЭлемента("Запрос"); + УстановитьАтрибут(ЗаписьXML, "ИспользуетсяПриЗагрузке", Истина); + УстановитьАтрибут(ЗаписьXML, "Имя", Имя); + одЗаписатьЭлемент(ЗаписьXML, "Текст", Текст); + ЗаписьXML.ЗаписатьКонецЭлемента(); + КонецЕсли; + Иначе + Если РежимОбмена <> "Загрузка" Тогда + Запрос = Новый Запрос(Текст); + Запросы.Вставить(Имя, Запрос); + КонецЕсли; + КонецЕсли; + +КонецПроцедуры + +// Осуществляет загрузку запросов в соответствии с форматом правил обмена. +// +// Параметры: +// ПравилаОбмена - ЧтениеXML - Объект типа ЧтениеXML. +// ЗаписьXML - ЗаписьXML - Объект типа ЗаписьXML - правила, сохраняемые в файл обмена и +// используемые при загрузке данных. +// +Процедура ЗагрузитьЗапросы(ПравилаОбмена, ЗаписьXML) + + Запросы.Очистить(); + + ЗаписьXML.ЗаписатьНачалоЭлемента("Запросы"); + + Пока ПравилаОбмена.Прочитать() Цикл + + ИмяУзла = ПравилаОбмена.ЛокальноеИмя; + + Если ИмяУзла = "Запрос" Тогда + ЗагрузитьЗапрос(ПравилаОбмена, ЗаписьXML); + ИначеЕсли (ИмяУзла = "Запросы") И (ПравилаОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + Прервать; + КонецЕсли; + + КонецЦикла; + + ЗаписьXML.ЗаписатьКонецЭлемента(); + +КонецПроцедуры + +// Осуществляет загрузку параметров в соответствии с форматом правил обмена. +// +// Параметры: +// ПравилаОбмена - ЧтениеXML - Объект типа ЧтениеXML. +// +Процедура ЗагрузитьПараметры(ПравилаОбмена, ЗаписьXML) + + Параметры.Очистить(); + СобытияПослеЗагрузкиПараметров.Очистить(); + ТаблицаНастройкиПараметров.Очистить(); + + ЗаписьXML.ЗаписатьНачалоЭлемента("Параметры"); + + Пока ПравилаОбмена.Прочитать() Цикл + ИмяУзла = ПравилаОбмена.ЛокальноеИмя; + ТипУзла = ПравилаОбмена.ТипУзла; + + Если ИмяУзла = "Параметр" И ТипУзла = одТипУзлаXML_НачалоЭлемента Тогда + + // Загрузка по версии правил 2.01. + Имя = одАтрибут(ПравилаОбмена, одТипСтрока, "Имя"); + Наименование = одАтрибут(ПравилаОбмена, одТипСтрока, "Наименование"); + УстанавливатьВДиалоге = одАтрибут(ПравилаОбмена, одТипБулево, "УстанавливатьВДиалоге"); + СтрокаТипаЗначения = одАтрибут(ПравилаОбмена, одТипСтрока, "ТипЗначения"); + ИспользуетсяПриЗагрузке = одАтрибут(ПравилаОбмена, одТипБулево, "ИспользуетсяПриЗагрузке"); + ПередаватьПараметрПриВыгрузке = одАтрибут(ПравилаОбмена, одТипБулево, "ПередаватьПараметрПриВыгрузке"); + ПравилоКонвертации = одАтрибут(ПравилаОбмена, одТипСтрока, "ПравилоКонвертации"); + АлгоритмПослеЗагрузкиПараметра = одАтрибут(ПравилаОбмена, одТипСтрока, "ПослеЗагрузкиПараметра"); + + Если Не ПустаяСтрока(АлгоритмПослеЗагрузкиПараметра) Тогда + + СобытияПослеЗагрузкиПараметров.Вставить(Имя, АлгоритмПослеЗагрузкиПараметра); + + КонецЕсли; + + Если РежимОбмена = "Загрузка" И НЕ ИспользуетсяПриЗагрузке Тогда + Продолжить; + КонецЕсли; + + // Определяем типы значений и устанавливаем начальные значения. + Если Не ПустаяСтрока(СтрокаТипаЗначения) Тогда + + Попытка + ТипЗначенияДанных = Тип(СтрокаТипаЗначения); + ТипОпределен = ИСТИНА; + Исключение + ТипОпределен = ЛОЖЬ; + КонецПопытки; + + Иначе + + ТипОпределен = ЛОЖЬ; + + КонецЕсли; + + Если ТипОпределен Тогда + ЗначениеПараметра = одПолучитьПустоеЗначение(ТипЗначенияДанных); + Параметры.Вставить(Имя, ЗначениеПараметра); + Иначе + ЗначениеПараметра = ""; + Параметры.Вставить(Имя); + КонецЕсли; + + Если УстанавливатьВДиалоге = ИСТИНА Тогда + + СтрокаТаблицы = ТаблицаНастройкиПараметров.Добавить(); + СтрокаТаблицы.Наименование = Наименование; + СтрокаТаблицы.Имя = Имя; + СтрокаТаблицы.Значение = ЗначениеПараметра; + СтрокаТаблицы.ПередаватьПараметрПриВыгрузке = ПередаватьПараметрПриВыгрузке; + СтрокаТаблицы.ПравилоКонвертации = ПравилоКонвертации; + + КонецЕсли; + + Если ИспользуетсяПриЗагрузке + И РежимОбмена = "Выгрузка" Тогда + + ЗаписьXML.ЗаписатьНачалоЭлемента("Параметр"); + УстановитьАтрибут(ЗаписьXML, "Имя", Имя); + УстановитьАтрибут(ЗаписьXML, "Наименование", Наименование); + + Если НЕ ПустаяСтрока(АлгоритмПослеЗагрузкиПараметра) Тогда + УстановитьАтрибут(ЗаписьXML, "ПослеЗагрузкиПараметра", XMLСтрока(АлгоритмПослеЗагрузкиПараметра)); + КонецЕсли; + + ЗаписьXML.ЗаписатьКонецЭлемента(); + + КонецЕсли; + + ИначеЕсли (ТипУзла = одТипУзлаXML_Текст) Тогда + + // Для совместимости с версией правил 2.0 используем загрузку из строки. + СтрокаПараметров = ПравилаОбмена.Значение; + Для каждого Пар Из МассивИзСтроки(СтрокаПараметров) Цикл + Параметры.Вставить(Пар); + КонецЦикла; + + ИначеЕсли (ИмяУзла = "Параметры") И (ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + Прервать; + КонецЕсли; + + КонецЦикла; + + ЗаписьXML.ЗаписатьКонецЭлемента(); + +КонецПроцедуры + +// Осуществляет загрузку обработки в соответствии с форматом правил обмена. +// +// Параметры: +// ПравилаОбмена - ЧтениеXML - Объект типа ЧтениеXML. +// ЗаписьXML - ЗаписьXML - Объект типа ЗаписьXML - правила, сохраняемые в файл обмена и +// используемые при загрузке данных. +// +Процедура ЗагрузитьОбработку(ПравилаОбмена, ЗаписьXML) + + Имя = одАтрибут(ПравилаОбмена, одТипСтрока, "Имя"); + Наименование = одАтрибут(ПравилаОбмена, одТипСтрока, "Наименование"); + ЭтоОбработкаНастройки = одАтрибут(ПравилаОбмена, одТипБулево, "ЭтоОбработкаНастройки"); + + ИспользуетсяПриВыгрузке = одАтрибут(ПравилаОбмена, одТипБулево, "ИспользуетсяПриВыгрузке"); + ИспользуетсяПриЗагрузке = одАтрибут(ПравилаОбмена, одТипБулево, "ИспользуетсяПриЗагрузке"); + + СтрокаПараметров = одАтрибут(ПравилаОбмена, одТипСтрока, "Параметры"); + + ХранилищеОбработки = одЗначениеЭлемента(ПравилаОбмена, одТипХранилищеЗначения); + + ПараметрыДопОбработок.Вставить(Имя, МассивИзСтроки(СтрокаПараметров)); + + + Если ИспользуетсяПриЗагрузке Тогда + Если РежимОбмена = "Загрузка" Тогда + + Иначе + ЗаписьXML.ЗаписатьНачалоЭлемента("Обработка"); + УстановитьАтрибут(ЗаписьXML, "ИспользуетсяПриЗагрузке", Истина); + УстановитьАтрибут(ЗаписьXML, "Имя", Имя); + УстановитьАтрибут(ЗаписьXML, "Наименование", Наименование); + УстановитьАтрибут(ЗаписьXML, "ЭтоОбработкаНастройки", ЭтоОбработкаНастройки); + ЗаписьXML.ЗаписатьТекст(XMLСтрока(ХранилищеОбработки)); + ЗаписьXML.ЗаписатьКонецЭлемента(); + КонецЕсли; + КонецЕсли; + + Если ЭтоОбработкаНастройки Тогда + Если (РежимОбмена = "Загрузка") И ИспользуетсяПриЗагрузке Тогда + ОбработкиНастройкиЗагрузки.Добавить(Имя, Наименование, , ); + + ИначеЕсли (РежимОбмена = "Выгрузка") И ИспользуетсяПриВыгрузке Тогда + ОбработкиНастройкиВыгрузки.Добавить(Имя, Наименование, , ); + + КонецЕсли; + КонецЕсли; + +КонецПроцедуры + +// Осуществляет загрузку внешних обработок в соответствии с форматом правил обмена. +// +// Параметры: +// ПравилаОбмена - ЧтениеXML - Объект типа ЧтениеXML. +// ЗаписьXML - ЗаписьXML - Объект типа ЗаписьXML - правила, сохраняемые в файл обмена и +// используемые при загрузке данных. +// +Процедура ЗагрузитьОбработки(ПравилаОбмена, ЗаписьXML) + + ДопОбработки.Очистить(); + ПараметрыДопОбработок.Очистить(); + + ОбработкиНастройкиВыгрузки.Очистить(); + ОбработкиНастройкиЗагрузки.Очистить(); + + ЗаписьXML.ЗаписатьНачалоЭлемента("Обработки"); + + Пока ПравилаОбмена.Прочитать() Цикл + + ИмяУзла = ПравилаОбмена.ЛокальноеИмя; + + Если ИмяУзла = "Обработка" Тогда + ЗагрузитьОбработку(ПравилаОбмена, ЗаписьXML); + ИначеЕсли (ИмяУзла = "Обработки") И (ПравилаОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + Прервать; + КонецЕсли; + + КонецЦикла; + + ЗаписьXML.ЗаписатьКонецЭлемента(); + +КонецПроцедуры + +// Осуществляет загрузку группы правил выгрузки данных в соответствии с форматом правил обмена. +// +// Параметры: +// ПравилаОбмена - ЧтениеXML - объект типа ЧтениеXML. +// НоваяСтрока - СтрокаДереваЗначений - структура, описывающая группу правил выгрузки данных: +// * Имя - Строка - идентификатор правила. +// * Наименование - Строка - пользовательское представление правила. +// +Процедура ЗагрузитьГруппуПВД(ПравилаОбмена, НоваяСтрока) + + НоваяСтрока.ЭтоГруппа = Истина; + НоваяСтрока.Включить = Число(Не одАтрибут(ПравилаОбмена, одТипБулево, "Отключить")); + + Пока ПравилаОбмена.Прочитать() Цикл + ИмяУзла = ПравилаОбмена.ЛокальноеИмя; + ТипУзла = ПравилаОбмена.ТипУзла; + Если ИмяУзла = "Код" Тогда + НоваяСтрока.Имя = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + + ИначеЕсли ИмяУзла = "Наименование" Тогда + НоваяСтрока.Наименование = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + + ИначеЕсли ИмяУзла = "Порядок" Тогда + НоваяСтрока.Порядок = одЗначениеЭлемента(ПравилаОбмена, одТипЧисло); + + ИначеЕсли ИмяУзла = "Правило" Тогда + СтрокаДЗ = НоваяСтрока.Строки.Добавить(); + ЗагрузитьПВД(ПравилаОбмена, СтрокаДЗ); + + ИначеЕсли (ИмяУзла = "Группа") И (ТипУзла = одТипУзлаXML_НачалоЭлемента) Тогда + СтрокаДЗ = НоваяСтрока.Строки.Добавить(); + ЗагрузитьГруппуПВД(ПравилаОбмена, СтрокаДЗ); + + ИначеЕсли (ИмяУзла = "Группа") И (ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + Прервать; + КонецЕсли; + + КонецЦикла; + + Если ПустаяСтрока(НоваяСтрока.Наименование) Тогда + НоваяСтрока.Наименование = НоваяСтрока.Имя; + КонецЕсли; + +КонецПроцедуры + +// Осуществляет загрузку правила выгрузки данных в соответствии с форматом правил обмена. +// +// Параметры: +// ПравилаОбмена - ЧтениеXML - Объект типа ЧтениеXML. +// НоваяСтрока - СтрокаДереваЗначений - структура, описывающая правило выгрузки данных: +// * Имя - Строка - идентификатор правила. +// * Наименование - Строка - пользовательское представление правила. +// +Процедура ЗагрузитьПВД(ПравилаОбмена, НоваяСтрока) + + НоваяСтрока.Включить = Число(Не одАтрибут(ПравилаОбмена, одТипБулево, "Отключить")); + + Пока ПравилаОбмена.Прочитать() Цикл + + ИмяУзла = ПравилаОбмена.ЛокальноеИмя; + Если ИмяУзла = "Код" Тогда + НоваяСтрока.Имя = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + + ИначеЕсли ИмяУзла = "Наименование" Тогда + НоваяСтрока.Наименование = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + + ИначеЕсли ИмяУзла = "Порядок" Тогда + НоваяСтрока.Порядок = одЗначениеЭлемента(ПравилаОбмена, одТипЧисло); + + ИначеЕсли ИмяУзла = "СпособОтбораДанных" Тогда + НоваяСтрока.СпособОтбораДанных = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + + ИначеЕсли ИмяУзла = "ВыбиратьДанныеДляВыгрузкиОднимЗапросом" Тогда + НоваяСтрока.ВыбиратьДанныеДляВыгрузкиОднимЗапросом = одЗначениеЭлемента(ПравилаОбмена, одТипБулево); + + ИначеЕсли ИмяУзла = "НеВыгружатьОбъектыСозданныеВБазеПриемнике" Тогда + // Параметр игнорируется при обмене данными. + одЗначениеЭлемента(ПравилаОбмена, одТипБулево); + + ИначеЕсли ИмяУзла = "ОбъектВыборки" Тогда + ОбъектВыборки = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + Если Не ПустаяСтрока(ОбъектВыборки) Тогда + НоваяСтрока.ОбъектВыборки = Тип(ОбъектВыборки); + КонецЕсли; + // Для поддержки отбора с помощью построителя. + Если СтрНайти(ОбъектВыборки, "Ссылка.") Тогда + НоваяСтрока.ИмяОбъектаДляЗапроса = СтрЗаменить(ОбъектВыборки, "Ссылка.", "."); + Иначе + НоваяСтрока.ИмяОбъектаДляЗапросаРегистра = СтрЗаменить(ОбъектВыборки, "Запись.", "."); + КонецЕсли; + + ИначеЕсли ИмяУзла = "КодПравилаКонвертации" Тогда + НоваяСтрока.ПравилоКонвертации = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + + // Обработчики событий + + ИначеЕсли ИмяУзла = "ПередОбработкойПравила" Тогда + НоваяСтрока.ПередОбработкой = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + + ИначеЕсли ИмяУзла = "ПослеОбработкиПравила" Тогда + НоваяСтрока.ПослеОбработки = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + + ИначеЕсли ИмяУзла = "ПередВыгрузкойОбъекта" Тогда + НоваяСтрока.ПередВыгрузкой = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + + ИначеЕсли ИмяУзла = "ПослеВыгрузкиОбъекта" Тогда + НоваяСтрока.ПослеВыгрузки = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + + ИначеЕсли (ИмяУзла = "Правило") И (ПравилаОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + Прервать; + КонецЕсли; + + КонецЦикла; + + Если ПустаяСтрока(НоваяСтрока.Наименование) Тогда + НоваяСтрока.Наименование = НоваяСтрока.Имя; + КонецЕсли; + + //УИ Изменено + Если ПустаяСтрока(НоваяСтрока.ИмяМетаданных) Тогда + НоваяСтрока.ИмяМетаданных = ?(ЗначениеЗаполнено(НоваяСтрока.ИмяОбъектаДляЗапросаРегистра),НоваяСтрока.ИмяОбъектаДляЗапросаРегистра,НоваяСтрока.ИмяОбъектаДляЗапроса); + КонецЕсли; + +КонецПроцедуры + +// Осуществляет загрузку правил выгрузки данных в соответствии с форматом правил обмена. +// +// Параметры: +// ПравилаОбмена - ЧтениеXML - Объект типа ЧтениеXML. +// +Процедура ЗагрузитьПравилаВыгрузки(ПравилаОбмена) + + ТаблицаПравилВыгрузки.Строки.Очистить(); + + СтрокиДЗ = ТаблицаПравилВыгрузки.Строки; + + Пока ПравилаОбмена.Прочитать() Цикл + + ИмяУзла = ПравилаОбмена.ЛокальноеИмя; + + Если ИмяУзла = "Правило" Тогда + + СтрокаДЗ = СтрокиДЗ.Добавить(); + ЗагрузитьПВД(ПравилаОбмена, СтрокаДЗ); + + ИначеЕсли ИмяУзла = "Группа" Тогда + + СтрокаДЗ = СтрокиДЗ.Добавить(); + ЗагрузитьГруппуПВД(ПравилаОбмена, СтрокаДЗ); + + ИначеЕсли (ИмяУзла = "ПравилаВыгрузкиДанных") И (ПравилаОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + + Прервать; + + КонецЕсли; + + КонецЦикла; + + СтрокиДЗ.Сортировать("Порядок", Истина); + +КонецПроцедуры + +#КонецОбласти + +#Область ПроцедурыЭкспортаОбработчиковИАлгоритмовВTXTФайлИзПравилОбмена + +// Выгружает обработчики событий и алгоритмы во временный текстовый файл +// (во временный каталог пользователя). +// Формирует модуль отладки с обработчиками и алгоритмами и со всеми +// необходимыми глобальными переменными, обертками общих функций и комментариями. +// +// Параметры: +// Отказ - Булево - флаг отказа от создания модуля отладки. Возникает если не +// удалось прочесть правила обмена. +// +Процедура ВыгрузитьОбработчикиСобытий(Отказ) Экспорт + + ИнициализироватьВедениеПротоколаОбменаДляЭкспортаОбработчиков(); + + РежимОбработкиДанных = мРежимыОбработкиДанных.ЭкспортОбработчиковСобытий; + + ФлагОшибки = Ложь; + + ЗагрузитьПравилаОбменаДляЭкспортаОбработчиков(); + + Если ФлагОшибки Тогда + Отказ = Истина; + Возврат; + КонецЕсли; + + ДополнитьПравилаИнтерфейсамиОбработчиков(Конвертация, ТаблицаПравилКонвертации, ТаблицаПравилВыгрузки, ТаблицаПравилОчистки); + + Если РежимОтладкиАлгоритмов = мРежимыОтладкиАлгоритмов.ИнтеграцияКода Тогда + + ПолучитьПолныйКодАлгоритмовСУчетомВложенности(); + + КонецЕсли; + + ИмяВременногоФайлаОбработчиковСобытий = ПолучитьНовоеУникальноеИмяВременногоФайла(ИмяВременногоФайлаОбработчиковСобытий); + + Результат = Новый ЗаписьТекста(ИмяВременногоФайлаОбработчиковСобытий, КодировкаТекста.ANSI); + + мМакетОбщиеПроцедурыФункции = ПолучитьМакет("ОбщиеПроцедурыФункции"); + + // Выводим комментарии. + ДобавитьВПотокКомментарий(Результат, "Шапка"); + ДобавитьВПотокКомментарий(Результат, "ПеременныеОбработки"); + + // Выводим служебный код. + ДобавитьВПотокСлужебныйКод(Результат, "ПеременныеОбработки"); + + // Выгружаем глобальные обработчики. + ВыгрузитьОбработчикиКонвертации(Результат); + + // Выгружаем ПВД. + ДобавитьВПотокКомментарий(Результат, "ПВД", ТаблицаПравилВыгрузки.Строки.Количество() <> 0); + ВыгрузитьОбработчикиПравилВыгрузкиДанных(Результат, ТаблицаПравилВыгрузки.Строки); + + // Выгружаем ПОД. + ДобавитьВПотокКомментарий(Результат, "ПОД", ТаблицаПравилОчистки.Строки.Количество() <> 0); + ВыгрузитьОбработчикиПравилОчисткиДанных(Результат, ТаблицаПравилОчистки.Строки); + + // Выгружаем ПКО, ПКС, ПКГС. + ВыгрузитьОбработчикиПравилКонвертации(Результат); + + Если РежимОтладкиАлгоритмов = мРежимыОтладкиАлгоритмов.ПроцедурныйВызов Тогда + + // Выгружаем Алгоритмы со стандартными параметрами (параметрами по умолчанию). + ВыгрузитьАлгоритмы(Результат); + + КонецЕсли; + + // Выводим комментарии + ДобавитьВПотокКомментарий(Результат, "Предупреждение"); + ДобавитьВПотокКомментарий(Результат, "ОбщиеПроцедурыФункции"); + + // Выводим общие процедуры и функции в поток. + ДобавитьВПотокСлужебныйКод(Результат, "ОбщиеПроцедурыФункции"); + + // Выводим конструктор внешней обработки. + ВыгрузитьКонструкторВнешнейОбработки(Результат); + + // Выводим деструктор + ДобавитьВПотокСлужебныйКод(Результат, "Деструктор"); + + Результат.Закрыть(); + + ЗавершитьВедениеПротоколаОбмена(); + + Если ЭтоИнтерактивныйРежим Тогда + + Если ФлагОшибки Тогда + + СообщитьПользователю(НСтр("ru = 'При выгрузке обработчиков были обнаружены ошибки.'")); + + Иначе + + СообщитьПользователю(НСтр("ru = 'Обработчики успешно выгружены.'")); + + КонецЕсли; + + КонецЕсли; + +КонецПроцедуры + +// Очищает переменные со структурой правил обмена. +// +// Параметры: +// Нет. +// +Процедура ОчиститьПравилаОбмена() + + ТаблицаПравилВыгрузки.Строки.Очистить(); + ТаблицаПравилОчистки.Строки.Очистить(); + ТаблицаПравилКонвертации.Очистить(); + Алгоритмы.Очистить(); + Запросы.Очистить(); + + // Обработки + ДопОбработки.Очистить(); + ПараметрыДопОбработок.Очистить(); + ОбработкиНастройкиВыгрузки.Очистить(); + ОбработкиНастройкиЗагрузки.Очистить(); + +КонецПроцедуры + +// Производит загрузку правил обмена из файла-правил или файла-данных. +// +// Параметры: +// Нет. +// +Процедура ЗагрузитьПравилаОбменаДляЭкспортаОбработчиков() + + ОчиститьПравилаОбмена(); + + Если ОбработчикиСобытийЧитаемИзФайлаПравилОбмена Тогда + + РежимОбмена = ""; // Выгрузка + + ЗагрузитьПравилаОбмена(); + + мБылиПрочитаныПравилаОбменаПриЗагрузке = Ложь; + + ИнициализироватьПервоначальныеЗначенияПараметров(); + + Иначе // файл данных + + РежимОбмена = "Загрузка"; + + Если ПустаяСтрока(ИмяФайлаОбмена) Тогда + ЗаписатьВПротоколВыполнения(15); + Возврат; + КонецЕсли; + + ОткрытьФайлЗагрузки(Истина); + + // При наличии флага обработка потребует перечитать + // правила при попытке выгрузки данных. + мБылиПрочитаныПравилаОбменаПриЗагрузке = Истина; + + КонецЕсли; + +КонецПроцедуры + +// Выгружает глобальные обработчики конвертации в текстовый файл. +// При выгрузке обработчиков из файла с данными содержимое обработчика "Конвертация_ПослеЗагрузкиПараметров" +// не выгружается, т.к. код обработчика находится не в узле правил обмена, а в отдельном узле. +// При выгрузке обработчиков из файла правил этот алгоритм выгружается как и другие. +// +// Параметры: +// Результат - ЗаписьТекста - Объект типа ЗаписьТекста - для вывода обработчиков в текстовый файл. +// +Процедура ВыгрузитьОбработчикиКонвертации(Результат) + + ДобавитьВПотокКомментарий(Результат, "Конвертация"); + + Для Каждого Элемент Из ИменаОбработчиков.Конвертация Цикл + + ДобавитьВПотокОбработчикКонвертации(Результат, Элемент.Ключ); + + КонецЦикла; + +КонецПроцедуры + +// Выгружает обработчики правил выгрузки данных в текстовый файл. +// +// Параметры: +// Результат - ЗаписьТекста - Объект типа ЗаписьТекста - для вывода обработчиков в текстовый файл. +// СтрокиДерева - КоллекцияСтрокДереваЗначений - Объект типа КоллекцияСтрокДереваЗначений - содержит ПВД данного уровня +// дерева значений. +// +Процедура ВыгрузитьОбработчикиПравилВыгрузкиДанных(Результат, СтрокиДерева) + + Для Каждого Правило Из СтрокиДерева Цикл + + Если Правило.ЭтоГруппа Тогда + + ВыгрузитьОбработчикиПравилВыгрузкиДанных(Результат, Правило.Строки); + + Иначе + + Для Каждого Элемент Из ИменаОбработчиков.ПВД Цикл + + ДобавитьВПотокОбработчик(Результат, Правило, "ПВД", Элемент.Ключ); + + КонецЦикла; + + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + +// Выгружает обработчики правил очистки данных в текстовый файл. +// +// Параметры: +// Результат - ЗаписьТекста - Объект типа ЗаписьТекста - для вывода обработчиков в текстовый файл. +// СтрокиДерева - КоллекцияСтрокДереваЗначений - Объект типа КоллекцияСтрокДереваЗначений - содержит ПОД данного уровня +// дерева значений. +// +Процедура ВыгрузитьОбработчикиПравилОчисткиДанных(Результат, СтрокиДерева) + + Для Каждого Правило Из СтрокиДерева Цикл + + Если Правило.ЭтоГруппа Тогда + + ВыгрузитьОбработчикиПравилОчисткиДанных(Результат, Правило.Строки); + + Иначе + + Для Каждого Элемент Из ИменаОбработчиков.ПОД Цикл + + ДобавитьВПотокОбработчик(Результат, Правило, "ПОД", Элемент.Ключ); + + КонецЦикла; + + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + +// Выгружает обработчики правил конвертации: ПКО, ПКС, ПКГС в текстовый файл. +// +// Параметры: +// Результат - ЗаписьТекста - Объект типа ЗаписьТекста - для вывода обработчиков в текстовый файл. +// +Процедура ВыгрузитьОбработчикиПравилКонвертации(Результат) + + ВывестиКомментарий = ТаблицаПравилКонвертации.Количество() <> 0; + + // Выгружаем ПКО. + ДобавитьВПотокКомментарий(Результат, "ПКО", ВывестиКомментарий); + + Для Каждого ПКО Из ТаблицаПравилКонвертации Цикл + + Для Каждого Элемент Из ИменаОбработчиков.ПКО Цикл + + ДобавитьВПотокОбработчикПКО(Результат, ПКО, Элемент.Ключ); + + КонецЦикла; + + КонецЦикла; + + // Выгружаем ПКС и ПКГС. + ДобавитьВПотокКомментарий(Результат, "ПКС", ВывестиКомментарий); + + Для Каждого ПКО Из ТаблицаПравилКонвертации Цикл + + ВыгрузитьОбработчикиПравилКонвертацииСвойств(Результат, ПКО.СвойстваПоиска); + ВыгрузитьОбработчикиПравилКонвертацииСвойств(Результат, ПКО.Свойства); + + КонецЦикла; + +КонецПроцедуры + +// Выгружает обработчики правил конвертации свойств в текстовый файл. +// +// Параметры: +// Результат - ЗаписьТекста - Объект типа ЗаписьТекста - для вывода обработчиков в текстовый файл. +// ПКС - ТаблицаЗначений - содержит правила конвертации свойств или групп свойств объекта. +// +Процедура ВыгрузитьОбработчикиПравилКонвертацииСвойств(Результат, ПКС) + + Для Каждого Правило Из ПКС Цикл + + Если Правило.ЭтоГруппа Тогда // ПКГС + + Для Каждого Элемент Из ИменаОбработчиков.ПКГС Цикл + + ДобавитьВПотокОбработчикПКО(Результат, Правило, Элемент.Ключ); + + КонецЦикла; + + ВыгрузитьОбработчикиПравилКонвертацииСвойств(Результат, Правило.ПравилаГруппы); + + Иначе + + Для Каждого Элемент Из ИменаОбработчиков.ПКС Цикл + + ДобавитьВПотокОбработчикПКО(Результат, Правило, Элемент.Ключ); + + КонецЦикла; + + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + +// Выгружает алгоритмы в текстовый файл. +// +// Параметры: +// Результат - ЗаписьТекста - Объект типа ЗаписьТекста - для вывода алгоритмов в текстовый файл. +// +Процедура ВыгрузитьАлгоритмы(Результат) + + // Комментарий к блоку "Алгоритмы". + ДобавитьВПотокКомментарий(Результат, "Алгоритмы", Алгоритмы.Количество() <> 0); + + Для Каждого Алгоритм Из Алгоритмы Цикл + + ДобавитьВПотокАлгоритм(Результат, Алгоритм); + + КонецЦикла; + +КонецПроцедуры + +// Выгружает конструктор внешней обработки в текстовый файл. +// Если режим отладки алгоритмов - "алгоритмы отлаживать как процедуры", то в конструктор добавляется структура +// "Алгоритмы". +// Ключ элемента структуры - имя алгоритма, значение - интерфейс вызова процедуры, содержащей код алгоритма. +// +// Параметры: +// Результат - ЗаписьТекста - Объект типа ЗаписьТекста - для вывода обработчиков в текстовый файл. +// +Процедура ВыгрузитьКонструкторВнешнейОбработки(Результат) + + // Выводим комментарий + ДобавитьВПотокКомментарий(Результат, "Конструктор"); + + ТелоПроцедуры = ПолучитьСлужебныйКод("Конструктор_ТелоПроцедуры"); + + Если РежимОтладкиАлгоритмов = мРежимыОтладкиАлгоритмов.ПроцедурныйВызов Тогда + + ТелоПроцедуры = ТелоПроцедуры + ПолучитьСлужебныйКод("Конструктор_ТелоПроцедуры_ПроцедурныйВызовАлгоритмов"); + + // Добавляем в тело конструктора вызовы Алгоритмов. + Для Каждого Алгоритм Из Алгоритмы Цикл + + КлючАлгоритма = СокрЛП(Алгоритм.Ключ); + + ИнтерфейсАлгоритма = ПолучитьИнтерфейсАлгоритма(КлючАлгоритма) + ";"; + + ИнтерфейсАлгоритма = СтрЗаменить(СтрЗаменить(ИнтерфейсАлгоритма, Символы.ПС, " ")," ",""); + + ТелоПроцедуры = ТелоПроцедуры + Символы.ПС + + "Алгоритмы.Вставить(""" + КлючАлгоритма + """, """ + ИнтерфейсАлгоритма + """);"; + + + КонецЦикла; + + ИначеЕсли РежимОтладкиАлгоритмов = мРежимыОтладкиАлгоритмов.ИнтеграцияКода Тогда + + ТелоПроцедуры = ТелоПроцедуры + ПолучитьСлужебныйКод("Конструктор_ТелоПроцедуры_ИнтеграцияКодаАлгоритмов"); + + ИначеЕсли РежимОтладкиАлгоритмов = мРежимыОтладкиАлгоритмов.НеИспользовать Тогда + + ТелоПроцедуры = ТелоПроцедуры + ПолучитьСлужебныйКод("Конструктор_ТелоПроцедуры_НеИспользоватьОтладкуАлгоритмов"); + + КонецЕсли; + + ИнтерфейсПроцедурыВнешнейОбработки = "Процедура " + ПолучитьИнтерфейсПроцедурыВнешнейОбработки("Конструктор") + " Экспорт"; + + ДобавитьВПотокПолныйОбработчик(Результат, ИнтерфейсПроцедурыВнешнейОбработки, ТелоПроцедуры); + +КонецПроцедуры + +// Добавляет в объект "Результат" обработчик ПКО, ПКС или ПКГС. +// +// Параметры: +// Результат - ЗаписьТекста - Объект типа ЗаписьТекста - для вывода обработчика в текстовый файл. +// Правило - строка таблицы значений с правилами конвертации объекта. +// ИмяОбработчика - строка - имя обработчика. +// +Процедура ДобавитьВПотокОбработчикПКО(Результат, Правило, ИмяОбработчика) + + Если Не Правило["ЕстьОбработчик" + ИмяОбработчика] Тогда + Возврат; + КонецЕсли; + + ИнтерфейсОбработчика = "Процедура " + Правило["ИнтерфейсОбработчика" + ИмяОбработчика] + " Экспорт"; + + ДобавитьВПотокПолныйОбработчик(Результат, ИнтерфейсОбработчика, Правило[ИмяОбработчика]); + +КонецПроцедуры + +// Добавляет в объект "Результат" код алгоритма. +// +// Параметры: +// Результат - ЗаписьТекста - Объект типа ЗаписьТекста - для вывода обработчика в текстовый файл. +// Алгоритм - элемент структуры - алгоритм для выгрузки. +// +Процедура ДобавитьВПотокАлгоритм(Результат, Алгоритм) + + ИнтерфейсАлгоритма = "Процедура " + ПолучитьИнтерфейсАлгоритма(Алгоритм.Ключ); + + ДобавитьВПотокПолныйОбработчик(Результат, ИнтерфейсАлгоритма, Алгоритм.Значение); + +КонецПроцедуры + +// Добавляет в объект "Результат" обработчик ПВД или ПОД. +// +// Параметры: +// Результат - ЗаписьТекста - Объект типа ЗаписьТекста - для вывода обработчика в текстовый файл. +// Правило - строка дерева значений с правилами. +// ПрефиксОбработчика - строка - префикс обработчика: "ПВД" или "ПОД". +// ИмяОбработчика - строка - имя обработчика. +// +Процедура ДобавитьВПотокОбработчик(Результат, Правило, ПрефиксОбработчика, ИмяОбработчика) + + Если ПустаяСтрока(Правило[ИмяОбработчика]) Тогда + Возврат; + КонецЕсли; + + ИнтерфейсОбработчика = "Процедура " + Правило["ИнтерфейсОбработчика" + ИмяОбработчика] + " Экспорт"; + + ДобавитьВПотокПолныйОбработчик(Результат, ИнтерфейсОбработчика, Правило[ИмяОбработчика]); + +КонецПроцедуры + +// Добавляет в объект "Результат" глобальный обработчик конвертации. +// +// Параметры: +// Результат - ЗаписьТекста - Объект типа ЗаписьТекста - для вывода обработчика в текстовый файл. +// ИмяОбработчика - строка - имя обработчика. +// +Процедура ДобавитьВПотокОбработчикКонвертации(Результат, ИмяОбработчика) + + АлгоритмОбработчика = ""; + + Если Конвертация.Свойство(ИмяОбработчика, АлгоритмОбработчика) И Не ПустаяСтрока(АлгоритмОбработчика) Тогда + + ИнтерфейсОбработчика = "Процедура " + Конвертация["ИнтерфейсОбработчика" + ИмяОбработчика] + " Экспорт"; + + ДобавитьВПотокПолныйОбработчик(Результат, ИнтерфейсОбработчика, АлгоритмОбработчика); + + КонецЕсли; + +КонецПроцедуры + +// Добавляет в объект "Результат" процедуру с кодом обработчика или кодом алгоритма. +// +// Параметры: +// Результат - ЗаписьТекста - Объект типа ЗаписьТекста - для вывода процедуры в текстовый файл. +// ИнтерфейсОбработчика - Строка - полное описание интерфейса обработчика: +// имя процедуры, параметры процедуры, ключевое слово "Экспорт". +// Обработчик - Строка - тело обработчика или алгоритма. +// +Процедура ДобавитьВПотокПолныйОбработчик(Результат, ИнтерфейсОбработчика, Обработчик) + + СтрокаПрефикса = Символы.Таб; + + Результат.ЗаписатьСтроку(""); + + Результат.ЗаписатьСтроку(ИнтерфейсОбработчика); + + Результат.ЗаписатьСтроку(""); + + Для Индекс = 1 По СтрЧислоСтрок(Обработчик) Цикл + + СтрокаОбработчика = СтрПолучитьСтроку(Обработчик, Индекс); + + // В режиме отладки алгоритмов "Интеграция кода" вставляем код алгоритмов + // непосредственно в код обработчика. Код алгоритма вставляем взамен его вызова. + // В коде алгоритмов уже учтена вложенность алгоритмов друг в друга. + Если РежимОтладкиАлгоритмов = мРежимыОтладкиАлгоритмов.ИнтеграцияКода Тогда + + АлгоритмыОбработчика = ПолучитьАлгоритмыОбработчика(СтрокаОбработчика); + + Если АлгоритмыОбработчика.Количество() <> 0 Тогда // В этой строке есть вызовы алгоритмов. + + // Получаем начальное смещение кода алгоритма относительно текущего кода обработчика. + СтрокаПрефиксаДляВложенногоКода = ПолучитьПрефиксДляВложенногоАлгоритма(СтрокаОбработчика, СтрокаПрефикса); + + Для Каждого Алгоритм Из АлгоритмыОбработчика Цикл + + ОбработчикАлгоритма = АлгоритмыИнтегрированные[Алгоритм]; + + Для ИндексСтрокиАлгоритма = 1 По СтрЧислоСтрок(ОбработчикАлгоритма) Цикл + + Результат.ЗаписатьСтроку(СтрокаПрефиксаДляВложенногоКода + СтрПолучитьСтроку(ОбработчикАлгоритма, ИндексСтрокиАлгоритма)); + + КонецЦикла; + + КонецЦикла; + + КонецЕсли; + КонецЕсли; + + Результат.ЗаписатьСтроку(СтрокаПрефикса + СтрокаОбработчика); + + КонецЦикла; + + Результат.ЗаписатьСтроку(""); + Результат.ЗаписатьСтроку("КонецПроцедуры"); + +КонецПроцедуры + +// Добавляет в объект "Результат" комментарий. +// +// Параметры: +// Результат - ЗаписьТекста - Объект типа ЗаписьТекста - для вывода комментария в текстовый файл. +// ИмяОбласти - Строка - имя области текстового макета "мМакетОбщиеПроцедурыФункции" +// в которой содержится требуемый комментарий. +// ВывестиКомментарий - Булево - признак необходимости вывода комментария. +// +Процедура ДобавитьВПотокКомментарий(Результат, ИмяОбласти, ВывестиКомментарий = Истина) + + Если Не ВывестиКомментарий Тогда + Возврат; + КонецЕсли; + + // Получаем комментарии обработчиков по названию области. + ТекущаяОбласть = мМакетОбщиеПроцедурыФункции.ПолучитьОбласть(ИмяОбласти+"_Комментарий"); + + КомментарийИзМакета = СокрЛП(ПолучитьТекстПоОбластиБезНазванияОбласти(ТекущаяОбласть)); + + // Исключаем последний перевод строки. + КомментарийИзМакета = Сред(КомментарийИзМакета, 1, СтрДлина(КомментарийИзМакета)); + + Результат.ЗаписатьСтроку(Символы.ПС + Символы.ПС + КомментарийИзМакета); + +КонецПроцедуры + +// Добавляет в объект "Результат" служебный код: параметры, общие процедуры и функции, деструктор внешней обработки. +// +// Параметры: +// Результат - ЗаписьТекста - Объект типа ЗаписьТекста - для вывода служебного кода в текстовый файл. +// ИмяОбласти - Строка - имя области текстового макета "мМакетОбщиеПроцедурыФункции" +// в которой содержится требуемый служебный код. +// +Процедура ДобавитьВПотокСлужебныйКод(Результат, ИмяОбласти) + + // Получаем текст области + ТекущаяОбласть = мМакетОбщиеПроцедурыФункции.ПолучитьОбласть(ИмяОбласти); + + Текст = СокрЛП(ПолучитьТекстПоОбластиБезНазванияОбласти(ТекущаяОбласть)); + + Текст = Сред(Текст, 1, СтрДлина(Текст)); // Исключаем последний перевод строки. + + Результат.ЗаписатьСтроку(Символы.ПС + Символы.ПС + Текст); + +КонецПроцедуры + +// Получает служебный код из указанной области макета "мМакетОбщиеПроцедурыФункции". +// +// Параметры: +// ИмяОбласти - Строка - имя области текстового макета "мМакетОбщиеПроцедурыФункции". +// +// Возвращаемое значение: +// Текст из макета +// +Функция ПолучитьСлужебныйКод(ИмяОбласти) + + // Получаем текст области + ТекущаяОбласть = мМакетОбщиеПроцедурыФункции.ПолучитьОбласть(ИмяОбласти); + + Возврат ПолучитьТекстПоОбластиБезНазванияОбласти(ТекущаяОбласть); +КонецФункции + +#КонецОбласти + +#Область ПроцедурыИФункцииПолученияПолногоКодаАлгоритмовСУчетомИхВложенности + +// Формирует полный код алгоритмов с учетом их вложенности друг в друга. +// +// Параметры: +// Нет. +// +Процедура ПолучитьПолныйКодАлгоритмовСУчетомВложенности() + + // Заполняем структуру интегрированных алгоритмов. + АлгоритмыИнтегрированные = Новый Структура; + + Для Каждого Алгоритм Из Алгоритмы Цикл + + АлгоритмыИнтегрированные.Вставить(Алгоритм.Ключ, ЗаменитьВызовыАлгоритмовКодомЭтихАлгоритмовВОбработчике(Алгоритм.Значение, Алгоритм.Ключ, Новый Массив)); + + КонецЦикла; + +КонецПроцедуры + +// Добавляет строку "ОбработчикНовый" комментарием к вставке кода очередного алгоритма. +// +// Параметры: +// ОбработчикНовый - Строка - итоговая строка содержащая полный код алгоритма с учетом вложенности алгоритмов. +// ИмяАлгоритма - Строка - имя алгоритма. +// СтрокаПрефикса - строка - задает начальное смещение выводимого комментария. +// Заголовок - строка - наименование комментария: "{НАЧАЛО АЛГОРИТМА}", "{КОНЕЦ АЛГОРИТМА}"... +// +Процедура ЗаписатьЗаголовокБлокаАлгоритма(ОбработчикНовый, ИмяАлгоритма, СтрокаПрефикса, Заголовок) + + ЗаголовокАлгоритма = "//============================ " + Заголовок + " """ + ИмяАлгоритма + """ ============================"; + + ОбработчикНовый = ОбработчикНовый + Символы.ПС; + ОбработчикНовый = ОбработчикНовый + Символы.ПС + СтрокаПрефикса + ЗаголовокАлгоритма; + ОбработчикНовый = ОбработчикНовый + Символы.ПС; + +КонецПроцедуры + +// Дополняет массив "АлгоритмыОбработчика" именами алгоритмов, которые вызываются +// из переданной процедуре строки обработчика "СтрокаОбработчика". +// +// Параметры: +// СтрокаОбработчика - Строка - строка обработчика или алгоритма в которой выполняется поиск вызовов алгоритмов. +// АлгоритмыОбработчика - Массив- содержит имена алгоритмов, которые вызывается из заданного обработчика. +// +Процедура ПолучитьАлгоритмыСтрокиОбработчика(СтрокаОбработчика, АлгоритмыОбработчика) + + СтрокаОбработчика = ВРег(СтрокаОбработчика); + + ШаблонПоиска = "АЛГОРИТМЫ."; + + ДлинаСтрокиШаблона = СтрДлина(ШаблонПоиска); + + СимволНачальный = СтрНайти(СтрокаОбработчика, ШаблонПоиска); + + Если СимволНачальный = 0 Тогда + // В данной строке нет алгоритмов или все алгоритмы из этой строки уже учтены. + Возврат; + КонецЕсли; + + // Проверка на наличие признака того, что этот оператор закомментирован. + СтрокаОбработчикаДоВызоваАлгоритма = Лев(СтрокаОбработчика, СимволНачальный); + + Если СтрНайти(СтрокаОбработчикаДоВызоваАлгоритма, "//") <> 0 Тогда + // Этот оператор и все последующие закомментированы. + // Выходим из цикла. + Возврат; + КонецЕсли; + + СтрокаОбработчика = Сред(СтрокаОбработчика, СимволНачальный + ДлинаСтрокиШаблона); + + СимволКонечный = СтрНайти(СтрокаОбработчика, ")") - 1; + + ИмяАлгоритма = Сред(СтрокаОбработчика, 1, СимволКонечный); + + АлгоритмыОбработчика.Добавить(СокрЛП(ИмяАлгоритма)); + + // Пробегаем строку обработчика до конца, + // пока все вызовы алгоритмов из этой строки не будут учтены. + ПолучитьАлгоритмыСтрокиОбработчика(СтрокаОбработчика, АлгоритмыОбработчика); + +КонецПроцедуры + +// Функция возвращает измененный код алгоритма с учетом вложенных алгоритмов. Вместо оператора вызова +// алгоритма "Выполнить(Алгоритмы.Алгоритм_1);" вставляется полный код вызываемого алгоритма +// со сдвигом на величину "СтрокаПрефикса". +// Функция рекурсивно вызывает саму себя до тех по, пока все вложенные алгоритмы не будут учтены. +// +// Параметры: +// Обработчик - Строка - исходный код алгоритма. +// СтрокаПрефикса - Строка - значение смещения вставляемого кода алгоритма. +// АлгоритмВладелец - Строка - имя алгоритма, являющегося родительским по отношению +// к алгоритму, код которого обрабатывается этой функцией. +// МассивЗапрошенныхЭлементов - Массив - содержит имена алгоритмов которые уже были обработаны в данной ветке рекурсии. +// Необходим для предотвращения бесконечной рекурсии функции +// и вывода предупреждения об ошибке. +// +// Возвращаемое значение: +// ОбработчикНовый - Строка - измененный код алгоритма с учетом вложенных алгоритмов. +// +Функция ЗаменитьВызовыАлгоритмовКодомЭтихАлгоритмовВОбработчике(Обработчик, АлгоритмВладелец, МассивЗапрошенныхЭлементов, Знач СтрокаПрефикса = "") + + МассивЗапрошенныхЭлементов.Добавить(ВРег(АлгоритмВладелец)); + + // Инициализируем возвращаемое значение. + ОбработчикНовый = ""; + + ЗаписатьЗаголовокБлокаАлгоритма(ОбработчикНовый, АлгоритмВладелец, СтрокаПрефикса, НСтр("ru = '{НАЧАЛО АЛГОРИТМА}'")); + + Для Индекс = 1 По СтрЧислоСтрок(Обработчик) Цикл + + СтрокаОбработчика = СтрПолучитьСтроку(Обработчик, Индекс); + + АлгоритмыОбработчика = ПолучитьАлгоритмыОбработчика(СтрокаОбработчика); + + Если АлгоритмыОбработчика.Количество() <> 0 Тогда // В этой строке есть вызовы алгоритмов. + + // Получаем начальное смещение кода алгоритма относительно текущего кода. + СтрокаПрефиксаДляВложенногоКода = ПолучитьПрефиксДляВложенногоАлгоритма(СтрокаОбработчика, СтрокаПрефикса); + + // Разворачиваем полный код каждого алгоритма, + // который был вызван из строки "СтрокаОбработчика". + Для Каждого Алгоритм Из АлгоритмыОбработчика Цикл + + Если МассивЗапрошенныхЭлементов.Найти(ВРег(Алгоритм)) <> Неопределено Тогда // Рекурсивный вызов алгоритма. + + ЗаписатьЗаголовокБлокаАлгоритма(ОбработчикНовый, Алгоритм, СтрокаПрефиксаДляВложенногоКода, НСтр("ru = '{РЕКУРСИВНЫЙ ВЫЗОВ АЛГОРИТМА}'")); + + СтрокаОператора = НСтр("ru = 'ВызватьИсключение ""РЕКУРСИВНЫЙ ВЫЗОВ АЛГОРИТМА: %1"";'"); + СтрокаОператора = ПодставитьПараметрыВСтроку(СтрокаОператора, Алгоритм); + + ОбработчикНовый = ОбработчикНовый + Символы.ПС + СтрокаПрефиксаДляВложенногоКода + СтрокаОператора; + + ЗаписатьЗаголовокБлокаАлгоритма(ОбработчикНовый, Алгоритм, СтрокаПрефиксаДляВложенногоКода, НСтр("ru = '{РЕКУРСИВНЫЙ ВЫЗОВ АЛГОРИТМА}'")); + + СтруктураЗаписи = Новый Структура; + СтруктураЗаписи.Вставить("Алгоритм_1", АлгоритмВладелец); + СтруктураЗаписи.Вставить("Алгоритм_2", Алгоритм); + + ЗаписатьВПротоколВыполнения(79, СтруктураЗаписи); + + Иначе + + ОбработчикНовый = ОбработчикНовый + ЗаменитьВызовыАлгоритмовКодомЭтихАлгоритмовВОбработчике(Алгоритмы[Алгоритм], Алгоритм, СкопироватьМассив(МассивЗапрошенныхЭлементов), СтрокаПрефиксаДляВложенногоКода); + + КонецЕсли; + + КонецЦикла; + + КонецЕсли; + + ОбработчикНовый = ОбработчикНовый + Символы.ПС + СтрокаПрефикса + СтрокаОбработчика; + + КонецЦикла; + + ЗаписатьЗаголовокБлокаАлгоритма(ОбработчикНовый, АлгоритмВладелец, СтрокаПрефикса, НСтр("ru = '{КОНЕЦ АЛГОРИТМА}'")); + + Возврат ОбработчикНовый; + +КонецФункции + +// Копирует переданный массив и возвращает новый массив. +// +// Параметры: +// МассивИсточник - Массив - источник для получения нового массива копированием. +// +// Возвращаемое значение: +// НовыйМассив - Массив - массив, полученный копированием из переданного массива. +// +Функция СкопироватьМассив(МассивИсточник) + + НовыйМассив = Новый Массив; + + Для Каждого ЭлементМассива Из МассивИсточник Цикл + + НовыйМассив.Добавить(ЭлементМассива); + + КонецЦикла; + + Возврат НовыйМассив; +КонецФункции + +// Возвращает массив с именами алгоритмов, которые были обнаружены в теле переданного обработчика. +// +// Параметры: +// Обработчик - Строка - тело обработчика. +// +// Возвращаемое значение: +// АлгоритмыОбработчика - Массив - массив с именами алгоритмов, которые присутствуют в переданном обработчике. +// +Функция ПолучитьАлгоритмыОбработчика(Обработчик) + + // Инициализируем возвращаемое значение. + АлгоритмыОбработчика = Новый Массив; + + Для Индекс = 1 По СтрЧислоСтрок(Обработчик) Цикл + + СтрокаОбработчика = СокрЛ(СтрПолучитьСтроку(Обработчик, Индекс)); + + Если СтрНачинаетсяС(СтрокаОбработчика, "//") Тогда //Строка закомментирована, ее пропускаем. + Продолжить; + КонецЕсли; + + ПолучитьАлгоритмыСтрокиОбработчика(СтрокаОбработчика, АлгоритмыОбработчика); + + КонецЦикла; + + Возврат АлгоритмыОбработчика; +КонецФункции + +// Получает строку префикса для вывода кода вложенного алгоритма. +// +// Параметры: +// СтрокаОбработчика - Строка - строка из которой извлекается значение смещения вызова +// (смещение при котором производится вызов алгоритма). +// СтрокаПрефикса - Строка - начальное смещение. +// Возвращаемое значение: +// СтрокаПрефиксаДляВложенногоКода - Строка - Итоговое смещение кода алгоритма. +// +Функция ПолучитьПрефиксДляВложенногоАлгоритма(СтрокаОбработчика, СтрокаПрефикса) + + СтрокаОбработчика = ВРег(СтрокаОбработчика); + + НомерПозицииШаблонаВыполнить = СтрНайти(СтрокаОбработчика, "ВЫПОЛНИТЬ"); + + СтрокаПрефиксаДляВложенногоКода = СтрокаПрефикса + Лев(СтрокаОбработчика, НомерПозицииШаблонаВыполнить - 1) + Символы.Таб; + + // Если в строке обработчика был вызов алгоритма (алгоритмов), то строку полностью удаляем из кода. + СтрокаОбработчика = ""; + + Возврат СтрокаПрефиксаДляВложенногоКода; +КонецФункции + +#КонецОбласти + +#Область ФункцииФормированияУникальногоИмениОбработчиковСобытий + +// Формирует интерфейс обработчика ПКС, ПКГС (уникальное имя процедуры с параметрами соответствующего обработчика). +// +// Параметры: +// ПКО - СтрокаТаблицыЗначений - содержит правило конвертации объекта. +// ПКГС - СтрокаТаблицыЗначений - содержит правило конвертации группы свойств. +// Правило - СтрокаТаблицыЗначений - содержит правило конвертации свойств объекта. +// ИмяОбработчика - Строка - имя обработчика события. +// +// Возвращаемое значение: +// Строка - интерфейс обработчика. +// +Функция ПолучитьИнтерфейсОбработчикаПКС(ПКО, ПКГС, Правило, ИмяОбработчика) + + ПрефиксИмени = ?(Правило.ЭтоГруппа, "ПКГС", "ПКС"); + ИмяОбласти = ПрефиксИмени + "_" + ИмяОбработчика; + + ИмяВладельца = "_" + СокрЛП(ПКО.Имя); + + ИмяРодителя = ""; + + Если ПКГС <> Неопределено Тогда + + Если Не ПустаяСтрока(ПКГС.ВидПриемника) Тогда + + ИмяРодителя = "_" + СокрЛП(ПКГС.Приемник); + + КонецЕсли; + + КонецЕсли; + + ИмяПриемника = "_" + СокрЛП(Правило.Приемник); + ВидПриемника = "_" + СокрЛП(Правило.ВидПриемника); + + КодСвойства = СокрЛП(Правило.Имя); + + ПолноеИмяОбработчика = ИмяОбласти + ИмяВладельца + ИмяРодителя + ИмяПриемника + ВидПриемника + КодСвойства; + + Возврат ПолноеИмяОбработчика + "(" + ПолучитьПараметрыОбработчика(ИмяОбласти) + ")"; +КонецФункции + +// Формирует интерфейс обработчика ПКО, ПВД, ПОД (уникальное имя процедуры с параметрами соответствующего обработчика). +// +// Параметры: +// Правило - СтрокаТаблицыЗначений - ПКО, ПВД, ПОД: +// * Имя - Строка - имя правила. +// ПрефиксОбработчика - Строка - принимает значения: "ПКО", "ПВД", "ПОД". +// ИмяОбработчика - Строка - имя обработчика события для данного правила. +// +// Возвращаемое значение: +// Строка - интерфейс обработчика. +// +Функция ПолучитьИнтерфейсОбработчика(Правило, ПрефиксОбработчика, ИмяОбработчика) + + ИмяОбласти = ПрефиксОбработчика + "_" + ИмяОбработчика; + + ИмяПравила = "_" + СокрЛП(Правило.Имя); + + ПолноеИмяОбработчика = ИмяОбласти + ИмяПравила; + + Возврат ПолноеИмяОбработчика + "(" + ПолучитьПараметрыОбработчика(ИмяОбласти) + ")"; +КонецФункции + +// Формирует интерфейс глобального обработчика конвертации (уникальное имя процедуры с параметрами соответствующего +// обработчика). +// +// Параметры: +// ИмяОбработчика - Строка - имя обработчика события конвертации. +// +// Возвращаемое значение: +// Строка - интерфейс обработчика. +// +Функция ПолучитьИнтерфейсОбработчикаКонвертация(ИмяОбработчика) + + ИмяОбласти = "Конвертация_" + ИмяОбработчика; + + ПолноеИмяОбработчика = ИмяОбласти; + + Возврат ПолноеИмяОбработчика + "(" + ПолучитьПараметрыОбработчика(ИмяОбласти) + ")"; +КонецФункции + +// Формирует интерфейс процедуры (конструктора или деструктора) для внешней обработки. +// +// Параметры: +// ИмяПроцедуры - Строка - имя процедуры. +// +// Возвращаемое значение: +// Строка - интерфейс процедуры. +// +Функция ПолучитьИнтерфейсПроцедурыВнешнейОбработки(ИмяПроцедуры) + + ИмяОбласти = "Обработка_" + ИмяПроцедуры; + + ПолноеИмяОбработчика = ИмяПроцедуры; + + Возврат ПолноеИмяОбработчика + "(" + ПолучитьПараметрыОбработчика(ИмяОбласти) + ")"; +КонецФункции + +// Формирует интерфейс алгоритма для внешней обработки. +// Для всех алгоритмов получаем одинаковый набор параметров по умолчанию. +// +// Параметры: +// ИмяАлгоритма - Строка - имя алгоритма. +// +// Возвращаемое значение: +// Строка - интерфейс алгоритма. +// +Функция ПолучитьИнтерфейсАлгоритма(ИмяАлгоритма) + + ПолноеИмяОбработчика = "Алгоритм_" + ИмяАлгоритма; + + ИмяОбласти = "Алгоритм_ПоУмолчанию"; + + Возврат ПолноеИмяОбработчика + "(" + ПолучитьПараметрыОбработчика(ИмяОбласти) + ")"; +КонецФункции + +Функция ПолучитьСтрокуВызоваОбработчика(Правило, ИмяОбработчика) + + Возврат "ВнешняяОбработкаОбработчиковСобытий." + Правило["ИнтерфейсОбработчика" + ИмяОбработчика] + ";"; + +КонецФункции + +Функция ПолучитьТекстПоОбластиБезНазванияОбласти(Область) + + ТекстОбласти = Область.ПолучитьТекст(); + + Если СтрНайти(ТекстОбласти, "#Область") > 0 Тогда + + ПервыйПереводСтроки = СтрНайти(ТекстОбласти, Символы.ПС); + + ТекстОбласти = Сред(ТекстОбласти, ПервыйПереводСтроки + 1); + + КонецЕсли; + + Возврат ТекстОбласти; + +КонецФункции + +Функция ПолучитьПараметрыОбработчика(ИмяОбласти) + + СтрокаПеревода = Символы.ПС + " "; + + ПараметрыОбработчика = ""; + + ИтогоСтрока = ""; + + Область = мМакетПараметровОбработчиков.ПолучитьОбласть(ИмяОбласти); + + ОбластьПараметров = Область.Области[ИмяОбласти]; + + Для НомерСтроки = ОбластьПараметров.Верх По ОбластьПараметров.Низ Цикл + + ТекущаяОбласть = Область.ПолучитьОбласть(НомерСтроки, 2, НомерСтроки, 2); + + Параметр = СокрЛП(ТекущаяОбласть.ТекущаяОбласть.Текст); + + Если Не ПустаяСтрока(Параметр) Тогда + + ПараметрыОбработчика = ПараметрыОбработчика + Параметр + ", "; + + ИтогоСтрока = ИтогоСтрока + Параметр; + + КонецЕсли; + + Если СтрДлина(ИтогоСтрока) > 50 Тогда + + ИтогоСтрока = ""; + + ПараметрыОбработчика = ПараметрыОбработчика + СтрокаПеревода; + + КонецЕсли; + + КонецЦикла; + + ПараметрыОбработчика = СокрЛП(ПараметрыОбработчика); + + // Убираем последний знак "," и возвращаем строку. + + Возврат Сред(ПараметрыОбработчика, 1, СтрДлина(ПараметрыОбработчика) - 1); +КонецФункции + +#КонецОбласти + +#Область ПроцедурыСозданияИнтерфейсаВызоваОбработчиковВПравилахОбмена + +// Дополняет коллекцию значений правил очистки данных интерфейсами обработчиков. +// +// Параметры: +// ТаблицаПОД - ДеревоЗначений - содержит правила очистки данных. +// СтрокиДерева - КоллекцияСтрокДереваЗначений - Объект типа КоллекцияСтрокДереваЗначений - содержит ПОД данного уровня +// дерева значений. +// +Процедура ДополнитьИнтерфейсамиОбработчиковПравилаОчисткиДанных(ТаблицаПОД, СтрокиДерева) + + Для Каждого Правило Из СтрокиДерева Цикл + + Если Правило.ЭтоГруппа Тогда + + ДополнитьИнтерфейсамиОбработчиковПравилаОчисткиДанных(ТаблицаПОД, Правило.Строки); + + Иначе + + Для Каждого Элемент Из ИменаОбработчиков.ПОД Цикл + + ДобавитьИнтерфейсОбработчика(ТаблицаПОД, Правило, "ПОД", Элемент.Ключ); + + КонецЦикла; + + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + +// Дополняет коллекцию значений правил выгрузки данных интерфейсами обработчиков. +// +// Параметры: +// ТаблицаПВД - ДеревоЗначений - содержит правила выгрузки данных. +// СтрокиДерева - КоллекцияСтрокДереваЗначений - Объект типа КоллекцияСтрокДереваЗначений - содержит ПВД данного уровня +// дерева значений. +// +Процедура ДополнитьИнтерфейсамиОбработчиковПравилаВыгрузкиДанных(ТаблицаПВД, СтрокиДерева) + + Для Каждого Правило Из СтрокиДерева Цикл + + Если Правило.ЭтоГруппа Тогда + + ДополнитьИнтерфейсамиОбработчиковПравилаВыгрузкиДанных(ТаблицаПВД, Правило.Строки); + + Иначе + + Для Каждого Элемент Из ИменаОбработчиков.ПВД Цикл + + ДобавитьИнтерфейсОбработчика(ТаблицаПВД, Правило, "ПВД", Элемент.Ключ); + + КонецЦикла; + + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + +// Дополняет структуру конвертации интерфейсами обработчиков. +// +// Параметры: +// СтруктураКонвертация - Структура - содержит правила конвертации и глобальные обработчики. +// +Процедура ДополнитьИнтерфейсамиОбработчиковПравилаКонвертации(СтруктураКонвертация) + + Для Каждого Элемент Из ИменаОбработчиков.Конвертация Цикл + + ДобавитьИнтерфейсОбработчикаКонвертации(СтруктураКонвертация, Элемент.Ключ); + + КонецЦикла; + +КонецПроцедуры + +// Дополняет коллекцию значений правил конвертации объектов интерфейсами обработчиков. +// +// Параметры: +// ТаблицаПКО - см. КоллекцияПравилаКонвертации +// +Процедура ДополнитьИнтерфейсамиОбработчиковПравилаКонвертацииОбъектов(ТаблицаПКО) + + Для Каждого ПКО Из ТаблицаПКО Цикл + + Для Каждого Элемент Из ИменаОбработчиков.ПКО Цикл + + ДобавитьИнтерфейсОбработчикаПКО(ТаблицаПКО, ПКО, Элемент.Ключ); + + КонецЦикла; + + // Добавляем интерфейсы для ПКС. + ДополнитьИнтерфейсамиОбработчиковПКС(ПКО, ПКО.СвойстваПоиска); + ДополнитьИнтерфейсамиОбработчиковПКС(ПКО, ПКО.Свойства); + + КонецЦикла; + +КонецПроцедуры + +// Дополняет коллекцию значений правил конвертации свойств объектов интерфейсами обработчиков. +// +// Параметры: +// ПКО - СтрокаТаблицыЗначений - содержит правило конвертации объекта. +// ПравилаКонвертацииСвойствОбъекта - ТаблицаЗначений - содержит правила конвертации свойств или группы свойств +// объекта из правила ПКО. +// ПКГС - СтрокаТаблицыЗначений - содержит правило конвертации группы свойств. +// +Процедура ДополнитьИнтерфейсамиОбработчиковПКС(ПКО, ПравилаКонвертацииСвойствОбъекта, ПКГС = Неопределено) + + Для Каждого ПКС Из ПравилаКонвертацииСвойствОбъекта Цикл + + Если ПКС.ЭтоГруппа Тогда // ПКГС + + Для Каждого Элемент Из ИменаОбработчиков.ПКГС Цикл + + ДобавитьИнтерфейсОбработчикаПКС(ПравилаКонвертацииСвойствОбъекта, ПКО, ПКГС, ПКС, Элемент.Ключ); + + КонецЦикла; + + ДополнитьИнтерфейсамиОбработчиковПКС(ПКО, ПКС.ПравилаГруппы, ПКС); + + Иначе + + Для Каждого Элемент Из ИменаОбработчиков.ПКС Цикл + + ДобавитьИнтерфейсОбработчикаПКС(ПравилаКонвертацииСвойствОбъекта, ПКО, ПКГС, ПКС, Элемент.Ключ); + + КонецЦикла; + + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + +Процедура ДобавитьИнтерфейсОбработчика(Таблица, Правило, ПрефиксОбработчика, ИмяОбработчика) + + Если ПустаяСтрока(Правило[ИмяОбработчика]) Тогда + Возврат; + КонецЕсли; + + ИмяПоля = "ИнтерфейсОбработчика" + ИмяОбработчика; + + ДобавитьНедостающиеКолонки(Таблица.Колонки, ИмяПоля); + + Правило[ИмяПоля] = ПолучитьИнтерфейсОбработчика(Правило, ПрефиксОбработчика, ИмяОбработчика); + +КонецПроцедуры + +Процедура ДобавитьИнтерфейсОбработчикаПКО(Таблица, Правило, ИмяОбработчика) + + Если Не Правило["ЕстьОбработчик" + ИмяОбработчика] Тогда + Возврат; + КонецЕсли; + + ИмяПоля = "ИнтерфейсОбработчика" + ИмяОбработчика; + + ДобавитьНедостающиеКолонки(Таблица.Колонки, ИмяПоля); + + Правило[ИмяПоля] = ПолучитьИнтерфейсОбработчика(Правило, "ПКО", ИмяОбработчика); + +КонецПроцедуры + +Процедура ДобавитьИнтерфейсОбработчикаПКС(Таблица, ПКО, ПКГС, ПКС, ИмяОбработчика) + + Если Не ПКС["ЕстьОбработчик" + ИмяОбработчика] Тогда + Возврат; + КонецЕсли; + + ИмяПоля = "ИнтерфейсОбработчика" + ИмяОбработчика; + + ДобавитьНедостающиеКолонки(Таблица.Колонки, ИмяПоля); + + ПКС[ИмяПоля] = ПолучитьИнтерфейсОбработчикаПКС(ПКО, ПКГС, ПКС, ИмяОбработчика); + +КонецПроцедуры + +Процедура ДобавитьИнтерфейсОбработчикаКонвертации(СтруктураКонвертация, ИмяОбработчика) + + АлгоритмОбработчика = ""; + + Если СтруктураКонвертация.Свойство(ИмяОбработчика, АлгоритмОбработчика) И Не ПустаяСтрока(АлгоритмОбработчика) Тогда + + ИмяПоля = "ИнтерфейсОбработчика" + ИмяОбработчика; + + СтруктураКонвертация.Вставить(ИмяПоля); + + СтруктураКонвертация[ИмяПоля] = ПолучитьИнтерфейсОбработчикаКонвертация(ИмяОбработчика); + + КонецЕсли; + +КонецПроцедуры + +#КонецОбласти + +#Область ПроцедурыРаботыСПравиламиОбмена + +Функция ОпределитьПоВерсииПлатформыПриемникаПлатформу(ВерсияПлатформы) + + Если СтрНайти(ВерсияПлатформы, "8.") > 0 Тогда + + Возврат "V8"; + + Иначе + + Возврат "V7"; + + КонецЕсли; + +КонецФункции + +// Восстанавливает правила из внутреннего формата. +// +// Параметры: +// +Процедура ВосстановитьПравилаИзВнутреннегоФормата() Экспорт + + Если СохраненныеНастройки = Неопределено Тогда + Возврат; + КонецЕсли; + + СтруктураПравил = СохраненныеНастройки.Получить(); // см. ОписаниеСтруктурыПравил + + ТаблицаПравилВыгрузки = СтруктураПравил.ТаблицаПравилВыгрузки; + ТаблицаПравилКонвертации = СтруктураПравил.ТаблицаПравилКонвертации; + Алгоритмы = СтруктураПравил.Алгоритмы; + ЗапросыДляВосстановления = СтруктураПравил.Запросы; + Конвертация = СтруктураПравил.Конвертация; + мXMLПравила = СтруктураПравил.мXMLПравила; + ТаблицаНастройкиПараметров = СтруктураПравил.ТаблицаНастройкиПараметров; + Параметры = СтруктураПравил.Параметры; + + ДополнитьСлужебныеТаблицыКолонками(); + + СтруктураПравил.Свойство("ВерсияПлатформыПриемника", ВерсияПлатформыПриемника); + + ПлатформаПриемника = ОпределитьПоВерсииПлатформыПриемникаПлатформу(ВерсияПлатформыПриемника); + + ЕстьГлобальныйОбработчикПередВыгрузкойОбъекта = Не ПустаяСтрока(Конвертация.ПередВыгрузкойОбъекта); + ЕстьГлобальныйОбработчикПослеВыгрузкиОбъекта = Не ПустаяСтрока(Конвертация.ПослеВыгрузкиОбъекта); + ЕстьГлобальныйОбработчикПередЗагрузкойОбъекта = Не ПустаяСтрока(Конвертация.ПередЗагрузкойОбъекта); + ЕстьГлобальныйОбработчикПослеЗагрузкиОбъекта = Не ПустаяСтрока(Конвертация.ПослеЗагрузкиОбъекта); + ЕстьГлобальныйОбработчикПередКонвертациейОбъекта = Не ПустаяСтрока(Конвертация.ПередКонвертациейОбъекта); + + // Восстанавливаем запросы + Запросы.Очистить(); + Для Каждого ЭлементСтруктуры Из ЗапросыДляВосстановления Цикл + Запрос = Новый Запрос(ЭлементСтруктуры.Значение); + Запросы.Вставить(ЭлементСтруктуры.Ключ, Запрос); + КонецЦикла; + + ИнициализироватьМенеджерыИСообщения(); + + Правила.Очистить(); + ОчиститьПКОМенеджеров(); + + Если РежимОбмена = "Выгрузка" Тогда + + Для Каждого СтрокаТаблицы Из КоллекцияПравилаКонвертации() Цикл + Правила.Вставить(СтрокаТаблицы.Имя, СтрокаТаблицы); + + Источник = СтрокаТаблицы.Источник; + + Если Источник <> Неопределено Тогда + + Попытка + Если ТипЗнч(Источник) = одТипСтрока Тогда + Менеджеры[Тип(Источник)].ПКО = СтрокаТаблицы; + Иначе + Менеджеры[Источник].ПКО = СтрокаТаблицы; + КонецЕсли; + Исключение + ЗаписатьИнформациюОбОшибкеВПротокол(11, ОписаниеОшибки(), Строка(Источник)); + КонецПопытки; + + КонецЕсли; + + КонецЦикла; + + КонецЕсли; + +КонецПроцедуры + +// Выполняет инициализацию параметров значениями по умолчанию, из правил обмена. +// +// Параметры: +// Нет. +// +Процедура ИнициализироватьПервоначальныеЗначенияПараметров() Экспорт + + Для Каждого ТекПараметр Из Параметры Цикл + + УстановитьЗначениеПараметраВТаблице(ТекПараметр.Ключ, ТекПараметр.Значение); + + КонецЦикла; + +КонецПроцедуры + +#КонецОбласти + +#Область ОбработкаПравилОчистки + +Процедура ВыполнитьУдалениеОбъекта(Объект, Свойства, УдалитьНепосредственно) + + ИмяТипа = Свойства.ИмяТипа; + + Если ИмяТипа = "РегистрСведений" Тогда + + Объект.Удалить(); + + Иначе + + Если (ИмяТипа = "Справочник" + Или ИмяТипа = "ПланВидовХарактеристик" + Или ИмяТипа = "ПланСчетов" + Или ИмяТипа = "ПланВидовРасчета") + И Объект.Предопределенный Тогда + + Возврат; + + КонецЕсли; + + Если УдалитьНепосредственно Тогда + + Объект.Удалить(); + + Иначе + + УстановитьПометкуУдаленияУОбъекта(Объект, Истина, Свойства.ИмяТипа); + + КонецЕсли; + + КонецЕсли; + +КонецПроцедуры + +// Очищает данные по указанному правилу. +// +// Параметры: +// Правило - СтрокаТаблицыЗначений - ссылка на правило очистки данных: +// * Имя - Строка - имя правила. +// +Процедура ОчиститьДанныеПоПравилу(Правило) + + Если БезопасныйРежим Тогда + УстановитьБезопасныйРежим(Истина); + Для Каждого ИмяРазделителя Из РазделителиКонфигурации Цикл + УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина); + КонецЦикла; + КонецЕсли; + + // Обработчик ПередОбработкой + + Отказ = Ложь; + ВыборкаДанных = Неопределено; + + ИсходящиеДанные = Неопределено; + + + // Обработчик ПередОбработкойПравилаОчистки + Если Не ПустаяСтрока(Правило.ПередОбработкой) Тогда + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(Правило, "ПередОбработкой")); + + Иначе + + Выполнить(Правило.ПередОбработкой); + + КонецЕсли; + + Исключение + + ЗаписатьИнформациюОбОшибкеОбработчикаОчисткиДанных(27, ОписаниеОшибки(), Правило.Имя, "", "ПередОбработкойПравилаОчистки"); + + КонецПопытки; + + Если Отказ Тогда + + Возврат; + + КонецЕсли; + + КонецЕсли; + + // Стандартная выборка + + Свойства = Менеджеры[Правило.ОбъектВыборки]; + + Если Правило.СпособОтбораДанных = "СтандартнаяВыборка" Тогда + + ИмяТипа = Свойства.ИмяТипа; + + Если ИмяТипа = "РегистрБухгалтерии" + ИЛИ ИмяТипа = "Константы" Тогда + + Возврат; + + КонецЕсли; + + НужныВсеПоля = Не ПустаяСтрока(Правило.ПередУдалением); + + Выборка = ПолучитьВыборкуДляВыгрузкиОчисткиДанных(Свойства, ИмяТипа, Истина, Правило.Непосредственно, НужныВсеПоля); + + Пока Выборка.Следующий() Цикл + + Если ИмяТипа = "РегистрСведений" Тогда + + МенеджерЗаписи = Свойства.Менеджер.СоздатьМенеджерЗаписи(); + ЗаполнитьЗначенияСвойств(МенеджерЗаписи, Выборка); + + УдалениеОбъектаВыборки(МенеджерЗаписи, Правило, Свойства, ИсходящиеДанные); + + Иначе + + УдалениеОбъектаВыборки(Выборка.Ссылка.ПолучитьОбъект(), Правило, Свойства, ИсходящиеДанные); + + КонецЕсли; + + КонецЦикла; + + ИначеЕсли Правило.СпособОтбораДанных = "ПроизвольныйАлгоритм" Тогда + + Если ВыборкаДанных <> Неопределено Тогда + + Выборка = ПолучитьВыборкуДляВыгрузкиПоПроизвольномуАлгоритму(ВыборкаДанных); + + Если Выборка <> Неопределено Тогда + + Пока Выборка.Следующий() Цикл + + Если ИмяТипа = "РегистрСведений" Тогда + + МенеджерЗаписи = Свойства.Менеджер.СоздатьМенеджерЗаписи(); + ЗаполнитьЗначенияСвойств(МенеджерЗаписи, Выборка); + + УдалениеОбъектаВыборки(МенеджерЗаписи, Правило, Свойства, ИсходящиеДанные); + + Иначе + + УдалениеОбъектаВыборки(Выборка.Ссылка.ПолучитьОбъект(), Правило, Свойства, ИсходящиеДанные); + + КонецЕсли; + + КонецЦикла; + + Иначе + + Для каждого Объект Из ВыборкаДанных Цикл + + УдалениеОбъектаВыборки(Объект.ПолучитьОбъект(), Правило, Свойства, ИсходящиеДанные); + + КонецЦикла; + + КонецЕсли; + + КонецЕсли; + + КонецЕсли; + + + // Обработчик ПослеОбработкиПравилаОчистки + + Если Не ПустаяСтрока(Правило.ПослеОбработки) Тогда + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(Правило, "ПослеОбработки")); + + Иначе + + Выполнить(Правило.ПослеОбработки); + + КонецЕсли; + + Исключение + + ЗаписатьИнформациюОбОшибкеОбработчикаОчисткиДанных(28, ОписаниеОшибки(), Правило.Имя, "", "ПослеОбработкиПравилаОчистки"); + + КонецПопытки; + + КонецЕсли; + +КонецПроцедуры + +// Обходит дерево правил очистки данных и выполняет очистку. +// +// Параметры: +// Строки - Коллекция строк дерева значений. +// +Процедура ОбработатьПравилаОчистки(Строки) + + Для каждого ПравилоОчистки Из Строки Цикл + + Если ПравилоОчистки.Включить = 0 Тогда + + Продолжить; + + КонецЕсли; + + Если ПравилоОчистки.ЭтоГруппа Тогда + + ОбработатьПравилаОчистки(ПравилоОчистки.Строки); + Продолжить; + + КонецЕсли; + + ОчиститьДанныеПоПравилу(ПравилоОчистки); + + КонецЦикла; + +КонецПроцедуры + +#КонецОбласти + +#Область ПроцедурыЗагрузкиДанных + +// Устанавливает значение параметра "Загрузка" для свойства объекта "ОбменДанными". +// +// Параметры: +// Объект - объект, для которого устанавливается свойство. +// Значение - значение устанавливаемого свойства "Загрузка". +// +Процедура УстановитьОбменДаннымиЗагрузка(Объект, Значение = Истина) Экспорт + + Если Не ЗагружатьДанныеВРежимеОбмена Тогда + Возврат; + КонецЕсли; + + Если ЕстьРеквизитИлиСвойствоОбъекта(Объект, "ОбменДанными") Тогда + СтруктураДляЗаполнения = Новый Структура("Загрузка", Значение); + ЗаполнитьЗначенияСвойств(Объект.ОбменДанными, СтруктураДляЗаполнения); + КонецЕсли; + +КонецПроцедуры + +Функция УстановитьСсылкуНового(Объект, Менеджер, СвойстваПоиска) + + УИ = СвойстваПоиска["{УникальныйИдентификатор}"]; + + Если УИ <> Неопределено Тогда + + НоваяСсылка = Менеджер.ПолучитьСсылку(Новый УникальныйИдентификатор(УИ)); + + Объект.УстановитьСсылкуНового(НоваяСсылка); + + СвойстваПоиска.Удалить("{УникальныйИдентификатор}"); + + Иначе + + НоваяСсылка = Неопределено; + + КонецЕсли; + + Возврат НоваяСсылка; + +КонецФункции + +// Ищет объект по номеру в списке уже загруженных объектов. +// +// Параметры: +// НПП - номер искомого объекта в файле обмена. +// +// Возвращаемое значение: +// Ссылка на найденный объект. Если объект не найден, возвращается Неопределено. +// +Функция НайтиОбъектПоНомеру(НПП, РежимПоискаОсновногоОбъекта = Ложь) + + Если НПП = 0 Тогда + Возврат Неопределено; + КонецЕсли; + + СтруктураРезультата = ЗагруженныеОбъекты[НПП]; + + Если СтруктураРезультата = Неопределено Тогда + Возврат Неопределено; + КонецЕсли; + + Если РежимПоискаОсновногоОбъекта И СтруктураРезультата.СсылкаФиктивная Тогда + Возврат Неопределено; + Иначе + Возврат СтруктураРезультата.СсылкаНаОбъект; + КонецЕсли; + +КонецФункции + +Функция НайтиОбъектПоГлобальномуНомеру(НПП, РежимПоискаОсновногоОбъекта = Ложь) + + СтруктураРезультата = ЗагруженныеГлобальныеОбъекты[НПП]; + + Если СтруктураРезультата = Неопределено Тогда + Возврат Неопределено; + КонецЕсли; + + Если РежимПоискаОсновногоОбъекта И СтруктураРезультата.СсылкаФиктивная Тогда + Возврат Неопределено; + Иначе + Возврат СтруктураРезультата.СсылкаНаОбъект; + КонецЕсли; + +КонецФункции + +Процедура ЗаписатьОбъектВИБ(Объект, Тип) + + Попытка + + УстановитьОбменДаннымиЗагрузка(Объект); + Объект.Записать(); + + Исключение + + СтрокаСообщенияОбОшибке = ЗаписатьИнформациюОбОшибкеВПротокол(26, ОписаниеОшибки(), Объект, Тип); + + Если Не ФлагРежимОтладки Тогда + ВызватьИсключение СтрокаСообщенияОбОшибке; + КонецЕсли; + + КонецПопытки; + +КонецПроцедуры + +// Создает новый объект указанного типа, устанавливает реквизиты, указанные +// в структуре СвойстваПоиска. +// +// Параметры: +// Тип - тип создаваемого объекта. +// СвойстваПоиска - Структура, содержащая устанавливаемые реквизиты нового объекта. +// +// Возвращаемое значение: +// Новый объект информационной базы. +// +Функция СоздатьНовыйОбъект(Тип, СвойстваПоиска, Объект = Неопределено, + ЗаписыватьОбъектСразуПослеСоздания = Истина, НаборЗаписейРегистра = Неопределено, + НоваяСсылка = Неопределено, НПП = 0, ГНПП = 0, ПараметрыОбъекта = Неопределено, + УстанавливатьУОбъектаВсеСвойстваПоиска = Истина) + + СвойстваМД = Менеджеры[Тип]; + ИмяТипа = СвойстваМД.ИмяТипа; + Менеджер = СвойстваМД.Менеджер; // СправочникМенеджер, ДокументМенеджер, РегистрСведенийМенеджер, и т.п. + + Если ИмяТипа = "Справочник" + ИЛИ ИмяТипа = "ПланВидовХарактеристик" Тогда + + ЭтоГруппа = СвойстваПоиска["ЭтоГруппа"]; + + Если ЭтоГруппа = Истина Тогда + + Объект = Менеджер.СоздатьГруппу(); + + Иначе + + Объект = Менеджер.СоздатьЭлемент(); + + КонецЕсли; + + ИначеЕсли ИмяТипа = "Документ" Тогда + + Объект = Менеджер.СоздатьДокумент(); + + ИначеЕсли ИмяТипа = "ПланСчетов" Тогда + + Объект = Менеджер.СоздатьСчет(); + + ИначеЕсли ИмяТипа = "ПланВидовРасчета" Тогда + + Объект = Менеджер.СоздатьВидРасчета(); + + ИначеЕсли ИмяТипа = "РегистрСведений" Тогда + + Если ЗаписыватьРегистрыНаборамиЗаписей Тогда + + НаборЗаписейРегистра = Менеджер.СоздатьНаборЗаписей(); + Объект = НаборЗаписейРегистра.Добавить(); + + Иначе + + Объект = Менеджер.СоздатьМенеджерЗаписи(); + + КонецЕсли; + + Возврат Объект; + + ИначеЕсли ИмяТипа = "ПланОбмена" Тогда + + Объект = Менеджер.СоздатьУзел(); + + ИначеЕсли ИмяТипа = "Задача" Тогда + + Объект = Менеджер.СоздатьЗадачу(); + + ИначеЕсли ИмяТипа = "БизнесПроцесс" Тогда + + Объект = Менеджер.СоздатьБизнесПроцесс(); + + ИначеЕсли ИмяТипа = "Перечисление" Тогда + + Объект = СвойстваМД.ПустаяСсылка; + Возврат Объект; + + ИначеЕсли ИмяТипа = "ТочкаМаршрутаБизнесПроцесса" Тогда + + Возврат Неопределено; + + КонецЕсли; + + НоваяСсылка = УстановитьСсылкуНового(Объект, Менеджер, СвойстваПоиска); + + Если УстанавливатьУОбъектаВсеСвойстваПоиска Тогда + УстановитьРеквизитыПоискаУОбъекта(Объект, СвойстваПоиска, Неопределено, Ложь, Ложь); + КонецЕсли; + + // Проверки + Если ИмяТипа = "Документ" + ИЛИ ИмяТипа = "Задача" + ИЛИ ИмяТипа = "БизнесПроцесс" Тогда + + Если НЕ ЗначениеЗаполнено(Объект.Дата) Тогда + + Объект.Дата = ТекущаяДатаСеанса(); + + КонецЕсли; + + КонецЕсли; + + // Если Владелец не установлен, то нужно поле добавить + // в возможные поля поиска, а в событии ПОЛЯПОИСКА указать поля без Владельца, если по нему поиск реально не нужен. + + Если ЗаписыватьОбъектСразуПослеСоздания Тогда + + Если НЕ ОбъектыПоСсылкеЗагружатьБезПометкиУдаления Тогда + Объект.ПометкаУдаления = Истина; + КонецЕсли; + + Если ГНПП <> 0 + ИЛИ Не ОптимизированнаяЗаписьОбъектов Тогда + + ЗаписатьОбъектВИБ(Объект, Тип); + + Иначе + + // Записывать объект сразу не будем, а только запомним что нужно записать + // сохраним эту информацию в специальном стеке объектов для записи + // вернем и новую ссылку и сам объект, хотя он еще не записан. + Если НоваяСсылка = Неопределено Тогда + + // Самостоятельно генерируем новую ссылку. + НовыйУникальныйИдентификатор = Новый УникальныйИдентификатор; + НоваяСсылка = Менеджер.ПолучитьСсылку(НовыйУникальныйИдентификатор); + Объект.УстановитьСсылкуНового(НоваяСсылка); + + КонецЕсли; + + ДополнитьСтекНеЗаписанныхОбъектов(НПП, ГНПП, Объект, НоваяСсылка, Тип, ПараметрыОбъекта); + + Возврат НоваяСсылка; + + КонецЕсли; + + Иначе + + Возврат Неопределено; + + КонецЕсли; + + Возврат Объект.Ссылка; + +КонецФункции + +// Читает из файла узел свойства объекта, устанавливает значение свойства. +// +// Параметры: +// Тип - тип значения свойства. +// ОбъектНайден - если после выполнения функции - Ложь, то значит +// объект свойства не найден в информационной базе и создан новый. +// +// Возвращаемое значение: +// Значение свойства +// +Функция ПрочитатьСвойство(Тип, ИмяПКО = "") + + Значение = Неопределено; + НаличиеСвойств = Ложь; + + Пока ФайлОбмена.Прочитать() Цикл + + ИмяУзла = ФайлОбмена.ЛокальноеИмя; + + Если ИмяУзла = "Значение" Тогда + + ИскатьПоСвойству = одАтрибут(ФайлОбмена, одТипСтрока, "Свойство"); + Значение = одЗначениеЭлемента(ФайлОбмена, Тип, ИскатьПоСвойству, ОбрезатьСтрокиСправа); + НаличиеСвойств = Истина; + + ИначеЕсли ИмяУзла = "Ссылка" Тогда + + Значение = НайтиОбъектПоСсылке(Тип, ИмяПКО); + НаличиеСвойств = Истина; + + ИначеЕсли ИмяУзла = "Нпп" Тогда + + одПропустить(ФайлОбмена); + + ИначеЕсли ИмяУзла = "ГНпп" Тогда + + ФайлОбмена.Прочитать(); + ГНПП = Число(ФайлОбмена.Значение); + Если ГНПП <> 0 Тогда + Значение = НайтиОбъектПоГлобальномуНомеру(ГНПП); + НаличиеСвойств = Истина; + КонецЕсли; + + ФайлОбмена.Прочитать(); + + ИначеЕсли (ИмяУзла = "Свойство" ИЛИ ИмяУзла = "ЗначениеПараметра") И (ФайлОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + + Если Не НаличиеСвойств + И ЗначениеЗаполнено(Тип) Тогда + + // Если вообще ничего нет - значит пустое значение. + Значение = одПолучитьПустоеЗначение(Тип); + + КонецЕсли; + + Прервать; + + ИначеЕсли ИмяУзла = "Выражение" Тогда + + Выражение = одЗначениеЭлемента(ФайлОбмена, одТипСтрока, , Ложь); + Значение = ВычислитьВыражение(Выражение); + + НаличиеСвойств = Истина; + + ИначеЕсли ИмяУзла = "Пусто" Тогда + + Значение = одПолучитьПустоеЗначение(Тип); + НаличиеСвойств = Истина; + + Иначе + + ЗаписатьВПротоколВыполнения(9); + Прервать; + + КонецЕсли; + + КонецЦикла; + + Возврат Значение; + +КонецФункции + +Функция УстановитьРеквизитыПоискаУОбъекта(НайденныйОбъект, СвойстваПоиска, СвойстваПоискаНеЗамещать, + НужноСравниватьСТекущимиРеквизитами = Истина, НЕЗаменятьСвойстваНеПодлежащиеИзменению = Истина) + + ИзмененыРеквизитыОбъекта = Ложь; + + Для каждого Свойство Из СвойстваПоиска Цикл + + Имя = Свойство.Ключ; + Значение = Свойство.Значение; + + Если НЕЗаменятьСвойстваНеПодлежащиеИзменению + И СвойстваПоискаНеЗамещать[Имя] <> Неопределено Тогда + + Продолжить; + + КонецЕсли; + + Если Имя = "ЭтоГруппа" + ИЛИ Имя = "{УникальныйИдентификатор}" + ИЛИ Имя = "{ИмяПредопределенногоЭлемента}" Тогда + + Продолжить; + + ИначеЕсли Имя = "ПометкаУдаления" Тогда + + Если НЕ НужноСравниватьСТекущимиРеквизитами + ИЛИ НайденныйОбъект.ПометкаУдаления <> Значение Тогда + + НайденныйОбъект.ПометкаУдаления = Значение; + ИзмененыРеквизитыОбъекта = Истина; + + КонецЕсли; + + Иначе + + // Отличные реквизиты устанавливаем. + Если НайденныйОбъект[Имя] <> NULL Тогда + + Если НЕ НужноСравниватьСТекущимиРеквизитами + ИЛИ НайденныйОбъект[Имя] <> Значение Тогда + + НайденныйОбъект[Имя] = Значение; + ИзмененыРеквизитыОбъекта = Истина; + + КонецЕсли; + + КонецЕсли; + + КонецЕсли; + + КонецЦикла; + + Возврат ИзмененыРеквизитыОбъекта; + +КонецФункции + +Функция НайтиИлиСоздатьОбъектПоСвойству(СтруктураСвойств, ТипОбъекта, СвойстваПоиска, СвойстваПоискаНеЗамещать, + ИмяТипаОбъекта, СвойствоПоиска, ЗначениеСвойстваПоиска, ОбъектНайден, + СоздаватьНовыйЭлементЕслиНеНайден, НайденныйИлиСозданныйОбъект, + РежимПоискаОсновногоОбъекта, СвойстваОбъектаМодифицированы, НПП, ГНПП, + ПараметрыОбъекта, НоваяСсылкаУникальногоИдентификатора = Неопределено) + + ЭтоПеречисление = СтруктураСвойств.ИмяТипа = "Перечисление"; + + Если ЭтоПеречисление Тогда + + СтрокаПоиска = ""; + + Иначе + + СтрокаПоиска = СтруктураСвойств.СтрокаПоиска; + + КонецЕсли; + + Если РежимПоискаОсновногоОбъекта Или ПустаяСтрока(СтрокаПоиска) Тогда + СтрокаЗапросаПоискаПоУникальномуИдентификатору = ""; + КонецЕсли; + + Объект = НайтиОбъектПоСвойству(СтруктураСвойств.Менеджер, СвойствоПоиска, ЗначениеСвойстваПоиска, + НайденныйИлиСозданныйОбъект, , , СтрокаЗапросаПоискаПоУникальномуИдентификатору); + + ОбъектНайден = НЕ (Объект = Неопределено ИЛИ Объект.Пустая()); + + Если Не ОбъектНайден Тогда + Если СоздаватьНовыйЭлементЕслиНеНайден Тогда + + Объект = СоздатьНовыйОбъект(ТипОбъекта, СвойстваПоиска, НайденныйИлиСозданныйОбъект, + НЕ РежимПоискаОсновногоОбъекта,,НоваяСсылкаУникальногоИдентификатора, НПП, ГНПП, ПараметрыОбъекта); + + СвойстваОбъектаМодифицированы = Истина; + КонецЕсли; + Возврат Объект; + + КонецЕсли; + + Если ЭтоПеречисление Тогда + Возврат Объект; + КонецЕсли; + + Если РежимПоискаОсновногоОбъекта Тогда + + Если НайденныйИлиСозданныйОбъект = Неопределено Тогда + НайденныйИлиСозданныйОбъект = Объект.ПолучитьОбъект(); + КонецЕсли; + + СвойстваОбъектаМодифицированы = УстановитьРеквизитыПоискаУОбъекта(НайденныйИлиСозданныйОбъект, СвойстваПоиска, СвойстваПоискаНеЗамещать); + + КонецЕсли; + + Возврат Объект; + +КонецФункции + +Функция ПолучитьТипСвойства() + + СтроковыйТипСвойства = одАтрибут(ФайлОбмена, одТипСтрока, "Тип"); + Если ПустаяСтрока(СтроковыйТипСвойства) Тогда + Возврат Неопределено; + КонецЕсли; + + Возврат Тип(СтроковыйТипСвойства); + +КонецФункции + +Функция ПолучитьТипСвойстваПоДополнительнымДанным(ИнформацияОТипах, ИмяСвойства) + + ТипСвойства = ПолучитьТипСвойства(); + + Если ТипСвойства = Неопределено + И ИнформацияОТипах <> Неопределено Тогда + + ТипСвойства = ИнформацияОТипах[ИмяСвойства]; + + КонецЕсли; + + Возврат ТипСвойства; + +КонецФункции + +Процедура ПрочитатьСвойстваПоискаИзФайла(СвойстваПоиска, СвойстваПоискаНеЗамещать, ИнформацияОТипах, + ПоискПоДатеНаРавенство = Ложь, ПараметрыОбъекта = Неопределено) + + ПоискПоДатеНаРавенство = Ложь; + + Пока ФайлОбмена.Прочитать() Цикл + + ИмяУзла = ФайлОбмена.ЛокальноеИмя; + + Если ИмяУзла = "Свойство" + ИЛИ ИмяУзла = "ЗначениеПараметра" Тогда + + ЭтоПараметр = (ИмяУзла = "ЗначениеПараметра"); + + Имя = одАтрибут(ФайлОбмена, одТипСтрока, "Имя"); + + Если Имя = "{УникальныйИдентификатор}" + ИЛИ Имя = "{ИмяПредопределенногоЭлемента}" Тогда + + ТипСвойства = одТипСтрока; + + Иначе + + ТипСвойства = ПолучитьТипСвойстваПоДополнительнымДанным(ИнформацияОТипах, Имя); + + КонецЕсли; + + НеЗамещатьСвойство = одАтрибут(ФайлОбмена, одТипБулево, "НеЗамещать"); + ПоискПоДатеНаРавенство = ПоискПоДатеНаРавенство + ИЛИ одАтрибут(ФайлОбмена, одТипБулево, "ПоискПоДатеНаРавенство"); + // + ИмяПКО = одАтрибут(ФайлОбмена, одТипСтрока, "ИмяПКО"); + + ЗначениеСвойства = ПрочитатьСвойство(ТипСвойства, ИмяПКО); + + Если (Имя = "ЭтоГруппа") И (ЗначениеСвойства <> Истина) Тогда + + ЗначениеСвойства = Ложь; + + КонецЕсли; + + Если ЭтоПараметр Тогда + + + ДобавитьПараметрПриНеобходимости(ПараметрыОбъекта, Имя, ЗначениеСвойства); + + Иначе + + СвойстваПоиска[Имя] = ЗначениеСвойства; + + Если НеЗамещатьСвойство Тогда + + СвойстваПоискаНеЗамещать[Имя] = Истина; + + КонецЕсли; + + КонецЕсли; + + ИначеЕсли (ИмяУзла = "Ссылка") И (ФайлОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + + Прервать; + + Иначе + + ЗаписатьВПротоколВыполнения(9); + Прервать; + + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + +Функция ОпределитьУПоляНеограниченнаяДлина(МенеджерТипа, ИмяПараметра) + + ДлинныеСтроки = Неопределено; + Если НЕ МенеджерТипа.Свойство("ДлинныеСтроки", ДлинныеСтроки) Тогда + + ДлинныеСтроки = Новый Соответствие; + Для Каждого Реквизит Из МенеджерТипа.ОбъектМД.Реквизиты Цикл + + Если Реквизит.Тип.СодержитТип(одТипСтрока) + И (Реквизит.Тип.КвалификаторыСтроки.Длина = 0) Тогда + + ДлинныеСтроки.Вставить(Реквизит.Имя, Реквизит.Имя); + + КонецЕсли; + + КонецЦикла; + + МенеджерТипа.Вставить("ДлинныеСтроки", ДлинныеСтроки); + + КонецЕсли; + + Возврат (ДлинныеСтроки[ИмяПараметра] <> Неопределено); + +КонецФункции + +Функция ОпределитьЭтотПараметрНеограниченнойДлинны(МенеджерТипа, ЗначениеПараметра, ИмяПараметра) + + Попытка + + Если ТипЗнч(ЗначениеПараметра) = одТипСтрока Тогда + СтрокаНеограниченнойДлины = ОпределитьУПоляНеограниченнаяДлина(МенеджерТипа, ИмяПараметра); + Иначе + СтрокаНеограниченнойДлины = Ложь; + КонецЕсли; + + Исключение + + СтрокаНеограниченнойДлины = Ложь; + + КонецПопытки; + + Возврат СтрокаНеограниченнойДлины; + +КонецФункции + +Функция НайтиЭлементЗапросом(СтруктураСвойств, СвойстваПоиска, ТипОбъекта = Неопределено, + МенеджерТипа = Неопределено, КоличествоРеальныхСвойствДляПоиска = Неопределено) + + КоличествоСвойствДляПоиска = ?(КоличествоРеальныхСвойствДляПоиска = Неопределено, СвойстваПоиска.Количество(), КоличествоРеальныхСвойствДляПоиска); + + Если КоличествоСвойствДляПоиска = 0 + И СтруктураСвойств.ИмяТипа = "Перечисление" Тогда + + Возврат СтруктураСвойств.ПустаяСсылка; + + КонецЕсли; + + ТекстЗапроса = СтруктураСвойств.СтрокаПоиска; + + Если ПустаяСтрока(ТекстЗапроса) Тогда + Возврат СтруктураСвойств.ПустаяСсылка; + КонецЕсли; + + ЗапросПоиска = Новый Запрос(); + КоличествоСвойствПоКоторымУстановленПоиск = 0; + + Для каждого Свойство Из СвойстваПоиска Цикл + + ИмяПараметра = Свойство.Ключ; + + // Не по всем параметрам можно искать. + Если ИмяПараметра = "{УникальныйИдентификатор}" + ИЛИ ИмяПараметра = "{ИмяПредопределенногоЭлемента}" Тогда + + Продолжить; + + КонецЕсли; + + ЗначениеПараметра = Свойство.Значение; + ЗапросПоиска.УстановитьПараметр(ИмяПараметра, ЗначениеПараметра); + + Попытка + + СтрокаНеограниченнойДлины = ОпределитьЭтотПараметрНеограниченнойДлинны(СтруктураСвойств, ЗначениеПараметра, ИмяПараметра); + + Исключение + + СтрокаНеограниченнойДлины = Ложь; + + КонецПопытки; + + КоличествоСвойствПоКоторымУстановленПоиск = КоличествоСвойствПоКоторымУстановленПоиск + 1; + + Если СтрокаНеограниченнойДлины Тогда + + ТекстЗапроса = ТекстЗапроса + ?(КоличествоСвойствПоКоторымУстановленПоиск > 1, " И ", "") + ИмяПараметра + " ПОДОБНО &" + ИмяПараметра; + + Иначе + + ТекстЗапроса = ТекстЗапроса + ?(КоличествоСвойствПоКоторымУстановленПоиск > 1, " И ", "") + ИмяПараметра + " = &" + ИмяПараметра; + + КонецЕсли; + + КонецЦикла; + + Если КоличествоСвойствПоКоторымУстановленПоиск = 0 Тогда + Возврат Неопределено; + КонецЕсли; + + ЗапросПоиска.Текст = ТекстЗапроса; + Результат = ЗапросПоиска.Выполнить(); + + Если Результат.Пустой() Тогда + + Возврат Неопределено; + + Иначе + + // Возвращаем первый найденный объект. + Выборка = Результат.Выбрать(); + Выборка.Следующий(); + СсылкаНаОбъект = Выборка.Ссылка; + + КонецЕсли; + + Возврат СсылкаНаОбъект; + +КонецФункции + +Функция ОпределитьПоТипуОбъектаИспользоватьДополнительныйПоискПоПолямПоиска(ТипСсылкиСтрокой) + + ЗначениеСоответствия = мСоответствиеДопПараметровПоиска.Получить(ТипСсылкиСтрокой); + + Если ЗначениеСоответствия <> Неопределено Тогда + Возврат ЗначениеСоответствия; + КонецЕсли; + + Попытка + + Для Каждого Элемент Из Правила Цикл + + Если Элемент.Значение.Приемник = ТипСсылкиСтрокой Тогда + + Если Элемент.Значение.СинхронизироватьПоИдентификатору = Истина Тогда + + НужноПродолжитьПоиск = (Элемент.Значение.ПродолжитьПоискПоПолямПоискаЕслиПоИдентификаторуНеНашли = Истина); + мСоответствиеДопПараметровПоиска.Вставить(ТипСсылкиСтрокой, НужноПродолжитьПоиск); + + Возврат НужноПродолжитьПоиск; + + КонецЕсли; + + КонецЕсли; + + КонецЦикла; + + мСоответствиеДопПараметровПоиска.Вставить(ТипСсылкиСтрокой, Ложь); + Возврат Ложь; + + Исключение + + мСоответствиеДопПараметровПоиска.Вставить(ТипСсылкиСтрокой, Ложь); + Возврат Ложь; + + КонецПопытки; + +КонецФункции + +// Определяет по типу объекта приемника правило конвертации объекта (ПКО). +// +// Параметры: +// ТипСсылкиСтрокой - Строка - тип объекта в строковом представлении, например, "СправочникСсылка.Номенклатура". +// +// Возвращаемое значение: +// ЗначениеСоответствия = Правило конвертации объекта. +// +Функция ОпределитьПоТипуОбъектаПриемникаПравилоКонвертацииКотороеСодержитАлгоритмПоиска(ТипСсылкиСтрокой) + + ЗначениеСоответствия = мСоответствиеПравилКонвертации.Получить(ТипСсылкиСтрокой); + + Если ЗначениеСоответствия <> Неопределено Тогда + Возврат ЗначениеСоответствия; + КонецЕсли; + + Попытка + + Для Каждого Элемент Из Правила Цикл + + Если Элемент.Значение.Приемник = ТипСсылкиСтрокой Тогда + + Если Элемент.Значение.ЕстьОбработчикПоследовательностьПолейПоиска = Истина Тогда + + Правило = Элемент.Значение; + + мСоответствиеПравилКонвертации.Вставить(ТипСсылкиСтрокой, Правило); + + Возврат Правило; + + КонецЕсли; + + КонецЕсли; + + КонецЦикла; + + мСоответствиеПравилКонвертации.Вставить(ТипСсылкиСтрокой, Неопределено); + Возврат Неопределено; + + Исключение + + мСоответствиеПравилКонвертации.Вставить(ТипСсылкиСтрокой, Неопределено); + Возврат Неопределено; + + КонецПопытки; + +КонецФункции + +Функция НайтиСсылкуНаОбъектПоОдномуСвойству(СвойстваПоиска, СтруктураСвойств) + + Для каждого Свойство Из СвойстваПоиска Цикл + + ИмяПараметра = Свойство.Ключ; + + // Не по всем параметрам можно искать. + Если ИмяПараметра = "{УникальныйИдентификатор}" + ИЛИ ИмяПараметра = "{ИмяПредопределенногоЭлемента}" Тогда + + Продолжить; + + КонецЕсли; + + ЗначениеПараметра = Свойство.Значение; + СсылкаНаОбъект = НайтиОбъектПоСвойству(СтруктураСвойств.Менеджер, ИмяПараметра, ЗначениеПараметра, Неопределено, СтруктураСвойств, СвойстваПоиска); + + КонецЦикла; + + Возврат СсылкаНаОбъект; + +КонецФункции + +Функция НайтиСсылкуНаДокумент(СвойстваПоиска, СтруктураСвойств, КоличествоРеальныхСвойствДляПоиска, ИскатьЗапросом, ПоискПоДатеНаРавенство) + + // Попробуем документ по дате и номеру найти. + ИскатьЗапросом = ПоискПоДатеНаРавенство ИЛИ (КоличествоРеальныхСвойствДляПоиска <> 2); + + Если ИскатьЗапросом Тогда + Возврат Неопределено; + КонецЕсли; + + НомерДокумента = СвойстваПоиска["Номер"]; + ДатаДокумента = СвойстваПоиска["Дата"]; + + Если (НомерДокумента <> Неопределено) И (ДатаДокумента <> Неопределено) Тогда + + СсылкаНаОбъект = СтруктураСвойств.Менеджер.НайтиПоНомеру(НомерДокумента, ДатаДокумента); + + Иначе + + // По дате и номеру найти не удалось - надо искать запросом. + ИскатьЗапросом = Истина; + СсылкаНаОбъект = Неопределено; + + КонецЕсли; + + Возврат СсылкаНаОбъект; + +КонецФункции + +Функция НайтиСсылкуНаСправочник(СвойстваПоиска, СтруктураСвойств, КоличествоРеальныхСвойствДляПоиска, ИскатьЗапросом) + + Владелец = СвойстваПоиска["Владелец"]; + Родитель = СвойстваПоиска["Родитель"]; + Код = СвойстваПоиска["Код"]; + Наименование = СвойстваПоиска["Наименование"]; + + Кол = 0; + + Если Владелец <> Неопределено Тогда Кол = 1 + Кол; КонецЕсли; + Если Родитель <> Неопределено Тогда Кол = 1 + Кол; КонецЕсли; + Если Код <> Неопределено Тогда Кол = 1 + Кол; КонецЕсли; + Если Наименование <> Неопределено Тогда Кол = 1 + Кол; КонецЕсли; + + ИскатьЗапросом = (Кол <> КоличествоРеальныхСвойствДляПоиска); + + Если ИскатьЗапросом Тогда + Возврат Неопределено; + КонецЕсли; + + Если (Код <> Неопределено) И (Наименование = Неопределено) Тогда + + СсылкаНаОбъект = СтруктураСвойств.Менеджер.НайтиПоКоду(Код, , Родитель, Владелец); + + ИначеЕсли (Код = Неопределено) И (Наименование <> Неопределено) Тогда + + СсылкаНаОбъект = СтруктураСвойств.Менеджер.НайтиПоНаименованию(Наименование, ИСТИНА, Родитель, Владелец); + + Иначе + + ИскатьЗапросом = Истина; + СсылкаНаОбъект = Неопределено; + + КонецЕсли; + + Возврат СсылкаНаОбъект; + +КонецФункции + +Функция НайтиСсылкуНаПВХ(СвойстваПоиска, СтруктураСвойств, КоличествоРеальныхСвойствДляПоиска, ИскатьЗапросом) + + Родитель = СвойстваПоиска["Родитель"]; + Код = СвойстваПоиска["Код"]; + Наименование = СвойстваПоиска["Наименование"]; + Кол = 0; + + Если Родитель <> Неопределено Тогда Кол = 1 + Кол КонецЕсли; + Если Код <> Неопределено Тогда Кол = 1 + Кол КонецЕсли; + Если Наименование <> Неопределено Тогда Кол = 1 + Кол КонецЕсли; + + ИскатьЗапросом = (Кол <> КоличествоРеальныхСвойствДляПоиска); + + Если ИскатьЗапросом Тогда + Возврат Неопределено; + КонецЕсли; + + Если (Код <> Неопределено) И (Наименование = Неопределено) Тогда + + СсылкаНаОбъект = СтруктураСвойств.Менеджер.НайтиПоКоду(Код, Родитель); + + ИначеЕсли (Код = Неопределено) И (Наименование <> Неопределено) Тогда + + СсылкаНаОбъект = СтруктураСвойств.Менеджер.НайтиПоНаименованию(Наименование, ИСТИНА, Родитель); + + Иначе + + ИскатьЗапросом = Истина; + СсылкаНаОбъект = Неопределено; + + КонецЕсли; + + Возврат СсылкаНаОбъект; + +КонецФункции + +Функция НайтиСсылкуНаПланОбмена(СвойстваПоиска, СтруктураСвойств, КоличествоРеальныхСвойствДляПоиска, ИскатьЗапросом) + + Код = СвойстваПоиска["Код"]; + Наименование = СвойстваПоиска["Наименование"]; + Кол = 0; + + Если Код <> Неопределено Тогда Кол = 1 + Кол КонецЕсли; + Если Наименование <> Неопределено Тогда Кол = 1 + Кол КонецЕсли; + + ИскатьЗапросом = (Кол <> КоличествоРеальныхСвойствДляПоиска); + + Если ИскатьЗапросом Тогда + Возврат Неопределено; + КонецЕсли; + + Если (Код <> Неопределено) И (Наименование = Неопределено) Тогда + + СсылкаНаОбъект = СтруктураСвойств.Менеджер.НайтиПоКоду(Код); + + ИначеЕсли (Код = Неопределено) И (Наименование <> Неопределено) Тогда + + СсылкаНаОбъект = СтруктураСвойств.Менеджер.НайтиПоНаименованию(Наименование, ИСТИНА); + + Иначе + + ИскатьЗапросом = Истина; + СсылкаНаОбъект = Неопределено; + + КонецЕсли; + + Возврат СсылкаНаОбъект; + +КонецФункции + +Функция НайтиСсылкуНаЗадачу(СвойстваПоиска, СтруктураСвойств, КоличествоРеальныхСвойствДляПоиска, ИскатьЗапросом) + + Код = СвойстваПоиска["Номер"]; + Наименование = СвойстваПоиска["Наименование"]; + Кол = 0; + + Если Код <> Неопределено Тогда Кол = 1 + Кол КонецЕсли; + Если Наименование <> Неопределено Тогда Кол = 1 + Кол КонецЕсли; + + ИскатьЗапросом = (Кол <> КоличествоРеальныхСвойствДляПоиска); + + Если ИскатьЗапросом Тогда + Возврат Неопределено; + КонецЕсли; + + + Если (Код <> Неопределено) И (Наименование = Неопределено) Тогда + + СсылкаНаОбъект = СтруктураСвойств.Менеджер.НайтиПоНомеру(Код); + + ИначеЕсли (Код = Неопределено) И (Наименование <> Неопределено) Тогда + + СсылкаНаОбъект = СтруктураСвойств.Менеджер.НайтиПоНаименованию(Наименование, ИСТИНА); + + Иначе + + ИскатьЗапросом = Истина; + СсылкаНаОбъект = Неопределено; + + КонецЕсли; + + Возврат СсылкаНаОбъект; + +КонецФункции + +Функция НайтиСсылкуНаБизнесПроцесс(СвойстваПоиска, СтруктураСвойств, КоличествоРеальныхСвойствДляПоиска, ИскатьЗапросом) + + Код = СвойстваПоиска["Номер"]; + Кол = 0; + + Если Код <> Неопределено Тогда Кол = 1 + Кол КонецЕсли; + + ИскатьЗапросом = (Кол <> КоличествоРеальныхСвойствДляПоиска); + + Если ИскатьЗапросом Тогда + Возврат Неопределено; + КонецЕсли; + + Если (Код <> Неопределено) Тогда + + СсылкаНаОбъект = СтруктураСвойств.Менеджер.НайтиПоНомеру(Код); + + Иначе + + ИскатьЗапросом = Истина; + СсылкаНаОбъект = Неопределено; + + КонецЕсли; + + Возврат СсылкаНаОбъект; + +КонецФункции + +Процедура ДобавитьСсылкуВСписокЗагруженныхОбъектов(ГНППСсылки, НППСсылки, СсылкаНаОбъект, СсылкаФиктивная = Ложь) + + // Запоминаем ссылку на объект. + Если НЕ ЗапоминатьЗагруженныеОбъекты + ИЛИ СсылкаНаОбъект = Неопределено Тогда + + Возврат; + + КонецЕсли; + + СтруктураЗаписи = Новый Структура("СсылкаНаОбъект, СсылкаФиктивная", СсылкаНаОбъект, СсылкаФиктивная); + + // Запоминаем ссылку на объект. + Если ГНППСсылки <> 0 Тогда + + ЗагруженныеГлобальныеОбъекты[ГНППСсылки] = СтруктураЗаписи; + + ИначеЕсли НППСсылки <> 0 Тогда + + ЗагруженныеОбъекты[НППСсылки] = СтруктураЗаписи; + + КонецЕсли; + +КонецПроцедуры + +Функция НайтиЭлементПоСвойствамПоиска(ТипОбъекта, ИмяТипаОбъекта, СвойстваПоиска, + СтруктураСвойств, СтрокаИменСвойствПоиска, ПоискПоДатеНаРавенство) + + // Не нужно искать по имени предопределенного элемента и по уникальной ссылке на объект + // нужно искать только по тем свойствам, которые имеются в строке имен свойств. Если там пусто, то по + // всем имеющимся свойствам поиска. + + ИскатьЗапросом = Ложь; + + Если ПустаяСтрока(СтрокаИменСвойствПоиска) Тогда + + ВременныеСвойстваПоиска = СвойстваПоиска; + + Иначе + + ГотоваяСтрокаДляРазбора = СтрЗаменить(СтрокаИменСвойствПоиска, " ", ""); + ДлинаСтроки = СтрДлина(ГотоваяСтрокаДляРазбора); + Если Сред(ГотоваяСтрокаДляРазбора, ДлинаСтроки, 1) <> "," Тогда + + ГотоваяСтрокаДляРазбора = ГотоваяСтрокаДляРазбора + ","; + + КонецЕсли; + + ВременныеСвойстваПоиска = Новый Соответствие; + Для Каждого ЭлементСвойств Из СвойстваПоиска Цикл + + ИмяПараметра = ЭлементСвойств.Ключ; + Если СтрНайти(ГотоваяСтрокаДляРазбора, ИмяПараметра + ",") > 0 Тогда + + ВременныеСвойстваПоиска.Вставить(ИмяПараметра, ЭлементСвойств.Значение); + + КонецЕсли; + + КонецЦикла; + + КонецЕсли; + + СвойствоУникальныйИдентификатор = ВременныеСвойстваПоиска["{УникальныйИдентификатор}"]; + СвойствоИмяПредопределенного = ВременныеСвойстваПоиска["{ИмяПредопределенногоЭлемента}"]; + + КоличествоРеальныхСвойствДляПоиска = ВременныеСвойстваПоиска.Количество(); + КоличествоРеальныхСвойствДляПоиска = КоличествоРеальныхСвойствДляПоиска - ?(СвойствоУникальныйИдентификатор <> Неопределено, 1, 0); + КоличествоРеальныхСвойствДляПоиска = КоличествоРеальныхСвойствДляПоиска - ?(СвойствоИмяПредопределенного <> Неопределено, 1, 0); + + + Если КоличествоРеальныхСвойствДляПоиска = 1 Тогда + + СсылкаНаОбъект = НайтиСсылкуНаОбъектПоОдномуСвойству(ВременныеСвойстваПоиска, СтруктураСвойств); + + ИначеЕсли ИмяТипаОбъекта = "Документ" Тогда + + СсылкаНаОбъект = НайтиСсылкуНаДокумент(ВременныеСвойстваПоиска, СтруктураСвойств, КоличествоРеальныхСвойствДляПоиска, ИскатьЗапросом, ПоискПоДатеНаРавенство); + + ИначеЕсли ИмяТипаОбъекта = "Справочник" Тогда + + СсылкаНаОбъект = НайтиСсылкуНаСправочник(ВременныеСвойстваПоиска, СтруктураСвойств, КоличествоРеальныхСвойствДляПоиска, ИскатьЗапросом); + + ИначеЕсли ИмяТипаОбъекта = "ПланВидовХарактеристик" Тогда + + СсылкаНаОбъект = НайтиСсылкуНаПВХ(ВременныеСвойстваПоиска, СтруктураСвойств, КоличествоРеальныхСвойствДляПоиска, ИскатьЗапросом); + + ИначеЕсли ИмяТипаОбъекта = "ПланОбмена" Тогда + + СсылкаНаОбъект = НайтиСсылкуНаПланОбмена(ВременныеСвойстваПоиска, СтруктураСвойств, КоличествоРеальныхСвойствДляПоиска, ИскатьЗапросом); + + ИначеЕсли ИмяТипаОбъекта = "Задача" Тогда + + СсылкаНаОбъект = НайтиСсылкуНаЗадачу(ВременныеСвойстваПоиска, СтруктураСвойств, КоличествоРеальныхСвойствДляПоиска, ИскатьЗапросом); + + ИначеЕсли ИмяТипаОбъекта = "БизнесПроцесс" Тогда + + СсылкаНаОбъект = НайтиСсылкуНаБизнесПроцесс(ВременныеСвойстваПоиска, СтруктураСвойств, КоличествоРеальныхСвойствДляПоиска, ИскатьЗапросом); + + Иначе + + ИскатьЗапросом = Истина; + + КонецЕсли; + + Если ИскатьЗапросом Тогда + + СсылкаНаОбъект = НайтиЭлементЗапросом(СтруктураСвойств, ВременныеСвойстваПоиска, ТипОбъекта, , КоличествоРеальныхСвойствДляПоиска); + + КонецЕсли; + + Возврат СсылкаНаОбъект; + +КонецФункции + +Процедура ОбработатьУстановкуСвойствПоискаУОбъекта(УстанавливатьУОбъектаВсеСвойстваПоиска, ТипОбъекта, СвойстваПоиска, + СвойстваПоискаНеЗамещать, СсылкаНаОбъект, СозданныйОбъект, ЗаписыватьНовыйОбъектВИнформационнуюБазу = Истина, ИзмененыРеквизитыОбъекта = Ложь) + + Если УстанавливатьУОбъектаВсеСвойстваПоиска <> Истина Тогда + Возврат; + КонецЕсли; + + Если Не ЗначениеЗаполнено(СсылкаНаОбъект) Тогда + Возврат; + КонецЕсли; + + Если СозданныйОбъект = Неопределено Тогда + СозданныйОбъект = СсылкаНаОбъект.ПолучитьОбъект(); + КонецЕсли; + + ИзмененыРеквизитыОбъекта = УстановитьРеквизитыПоискаУОбъекта(СозданныйОбъект, СвойстваПоиска, СвойстваПоискаНеЗамещать); + + // Если было то что изменено, тогда перезаписываем объект. + Если ИзмененыРеквизитыОбъекта + И ЗаписыватьНовыйОбъектВИнформационнуюБазу Тогда + + ЗаписатьОбъектВИБ(СозданныйОбъект, ТипОбъекта); + + КонецЕсли; + +КонецПроцедуры + +Функция ОбработатьПоискОбъектаПоСтруктуре(НомерОбъекта, ТипОбъекта, СозданныйОбъект, + РежимПоискаОсновногоОбъекта, СвойстваОбъектаМодифицированы, ОбъектНайден, + ЭтоГлобальныйНомер, ПараметрыОбъекта) + + СтруктураДанных = мГлобальныйСтекНеЗаписанныхОбъектов[НомерОбъекта]; + + Если СтруктураДанных <> Неопределено Тогда + + СвойстваОбъектаМодифицированы = Истина; + СозданныйОбъект = СтруктураДанных.Объект; + + Если СтруктураДанных.ИзвестнаяСсылка = Неопределено Тогда + + УстановитьСсылкуДляОбъекта(СтруктураДанных); + + КонецЕсли; + + СсылкаНаОбъект = СтруктураДанных.ИзвестнаяСсылка; + ПараметрыОбъекта = СтруктураДанных.ПараметрыОбъекта; + + ОбъектНайден = Ложь; + + Иначе + + СозданныйОбъект = Неопределено; + + Если ЭтоГлобальныйНомер Тогда + СсылкаНаОбъект = НайтиОбъектПоГлобальномуНомеру(НомерОбъекта, РежимПоискаОсновногоОбъекта); + Иначе + СсылкаНаОбъект = НайтиОбъектПоНомеру(НомерОбъекта, РежимПоискаОсновногоОбъекта); + КонецЕсли; + + КонецЕсли; + + Если СсылкаНаОбъект <> Неопределено Тогда + + Если РежимПоискаОсновногоОбъекта Тогда + + СвойстваПоиска = ""; + СвойстваПоискаНеЗамещать = ""; + ПрочитатьИнформациюОСвойствахПоиска(ТипОбъекта, СвойстваПоиска, СвойстваПоискаНеЗамещать, , ПараметрыОбъекта); + + // Для основного поиска нужно поля поиска еще раз проверить, возможно нужно их переустановить... + Если СозданныйОбъект = Неопределено Тогда + + СозданныйОбъект = СсылкаНаОбъект.ПолучитьОбъект(); + + КонецЕсли; + + СвойстваОбъектаМодифицированы = УстановитьРеквизитыПоискаУОбъекта(СозданныйОбъект, СвойстваПоиска, СвойстваПоискаНеЗамещать); + + Иначе + + одПропустить(ФайлОбмена); + + КонецЕсли; + + Возврат СсылкаНаОбъект; + + КонецЕсли; + + Возврат Неопределено; + +КонецФункции + +Процедура ПрочитатьИнформациюОСвойствахПоиска(ТипОбъекта, СвойстваПоиска, СвойстваПоискаНеЗамещать, + ПоискПоДатеНаРавенство = Ложь, ПараметрыОбъекта = Неопределено) + + Если СвойстваПоиска = "" Тогда + СвойстваПоиска = Новый Соответствие; + КонецЕсли; + + Если СвойстваПоискаНеЗамещать = "" Тогда + СвойстваПоискаНеЗамещать = Новый Соответствие; + КонецЕсли; + + ИнформацияОТипах = мСоответствиеТиповДанныхДляЗагрузки[ТипОбъекта]; + ПрочитатьСвойстваПоискаИзФайла(СвойстваПоиска, СвойстваПоискаНеЗамещать, ИнформацияОТипах, ПоискПоДатеНаРавенство, ПараметрыОбъекта); + +КонецПроцедуры + +// Производит поиск объекта в информационной базе, если не найден создает новый. +// +// Параметры: +// ТипОбъекта - тип искомого объекта. +// СвойстваПоиска - структура, содержащая свойства по которым производится поиск объекта. +// ОбъектНайден - если Ложь, то объект не найден, а создан новый. +// +// Возвращаемое значение: +// Новый или найденный объект информационной базы. +// +Функция НайтиОбъектПоСсылке(ТипОбъекта, + ИмяПКО = "", + СвойстваПоиска = "", + СвойстваПоискаНеЗамещать = "", + ОбъектНайден = Истина, + СозданныйОбъект = Неопределено, + НеСоздаватьОбъектЕслиНеНайден = Неопределено, + РежимПоискаОсновногоОбъекта = Ложь, + СвойстваОбъектаМодифицированы = Ложь, + НППГлобальнойСсылки = 0, + НППСсылки = 0, + ИзвестнаяСсылкаУникальногоИдентификатора = Неопределено, + ПараметрыОбъекта = Неопределено) + + Если БезопасныйРежим Тогда + УстановитьБезопасныйРежим(Истина); + Для Каждого ИмяРазделителя Из РазделителиКонфигурации Цикл + УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина); + КонецЦикла; + КонецЕсли; + + ПоискПоДатеНаРавенство = Ложь; + СсылкаНаОбъект = Неопределено; + СтруктураСвойств = Неопределено; + ИмяТипаОбъекта = Неопределено; + СсылкаНаОбъектФиктивная = Ложь; + ПКО = Неопределено; + АлгоритмПоиска = ""; + + Если ЗапоминатьЗагруженныеОбъекты Тогда + + // Есть номер по порядку из файла - по нему и ищем. + НППГлобальнойСсылки = одАтрибут(ФайлОбмена, одТипЧисло, "ГНпп"); + + Если НППГлобальнойСсылки <> 0 Тогда + + СсылкаНаОбъект = ОбработатьПоискОбъектаПоСтруктуре(НППГлобальнойСсылки, ТипОбъекта, СозданныйОбъект, + РежимПоискаОсновногоОбъекта, СвойстваОбъектаМодифицированы, ОбъектНайден, Истина, ПараметрыОбъекта); + + Если СсылкаНаОбъект <> Неопределено Тогда + Возврат СсылкаНаОбъект; + КонецЕсли; + + КонецЕсли; + + // Есть номер по порядку из файла - по нему и ищем. + НППСсылки = одАтрибут(ФайлОбмена, одТипЧисло, "Нпп"); + + Если НППСсылки <> 0 Тогда + + СсылкаНаОбъект = ОбработатьПоискОбъектаПоСтруктуре(НППСсылки, ТипОбъекта, СозданныйОбъект, + РежимПоискаОсновногоОбъекта, СвойстваОбъектаМодифицированы, ОбъектНайден, Ложь, ПараметрыОбъекта); + + Если СсылкаНаОбъект <> Неопределено Тогда + Возврат СсылкаНаОбъект; + КонецЕсли; + + КонецЕсли; + + КонецЕсли; + + НеСоздаватьОбъектЕслиНеНайден = одАтрибут(ФайлОбмена, одТипБулево, "НеСоздаватьЕслиНеНайден"); + ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD = НЕ РежимПоискаОсновногоОбъекта + И одАтрибут(ФайлОбмена, одТипБулево, "ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD"); + + // Создаем свойства поиска объектов. + ПрочитатьИнформациюОСвойствахПоиска(ТипОбъекта, СвойстваПоиска, СвойстваПоискаНеЗамещать, ПоискПоДатеНаРавенство, ПараметрыОбъекта); + + СозданныйОбъект = Неопределено; + + Если Не ОбъектНайден Тогда + + СсылкаНаОбъект = СоздатьНовыйОбъект(ТипОбъекта, СвойстваПоиска, СозданныйОбъект, , , , НППСсылки, НППГлобальнойСсылки); + ДобавитьСсылкуВСписокЗагруженныхОбъектов(НППГлобальнойСсылки, НППСсылки, СсылкаНаОбъект); + Возврат СсылкаНаОбъект; + + КонецЕсли; + + СтруктураСвойств = Менеджеры[ТипОбъекта]; + ИмяТипаОбъекта = СтруктураСвойств.ИмяТипа; + + СвойствоУникальныйИдентификатор = СвойстваПоиска["{УникальныйИдентификатор}"]; + СвойствоИмяПредопределенного = СвойстваПоиска["{ИмяПредопределенногоЭлемента}"]; + + ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD = ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD + И СвойствоУникальныйИдентификатор <> Неопределено; + + // Если это предопределенный элемент ищем по имени. + Если СвойствоИмяПредопределенного <> Неопределено Тогда + + АвтоматическиСоздаватьНовыйОбъект = НЕ НеСоздаватьОбъектЕслиНеНайден + И НЕ ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD; + + СсылкаНаОбъект = НайтиИлиСоздатьОбъектПоСвойству(СтруктураСвойств, ТипОбъекта, СвойстваПоиска, СвойстваПоискаНеЗамещать, + ИмяТипаОбъекта, "{ИмяПредопределенногоЭлемента}", СвойствоИмяПредопределенного, ОбъектНайден, + АвтоматическиСоздаватьНовыйОбъект, СозданныйОбъект, РежимПоискаОсновногоОбъекта, СвойстваОбъектаМодифицированы, + НППСсылки, НППГлобальнойСсылки, ПараметрыОбъекта); + + ИначеЕсли (СвойствоУникальныйИдентификатор <> Неопределено) Тогда + + // Не всегда нужно по уникальному идентификатору новый элемент создавать, возможно нужно продолжить поиск. + НужноПродолжитьПоискЕслиЭлементПоGUIDНеНайден = ОпределитьПоТипуОбъектаИспользоватьДополнительныйПоискПоПолямПоиска(СтруктураСвойств.ТипСсылкиСтрокой); + + АвтоматическиСоздаватьНовыйОбъект = (НЕ НеСоздаватьОбъектЕслиНеНайден + И НЕ НужноПродолжитьПоискЕслиЭлементПоGUIDНеНайден) + И НЕ ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD; + + СсылкаНаОбъект = НайтиИлиСоздатьОбъектПоСвойству(СтруктураСвойств, ТипОбъекта, СвойстваПоиска, СвойстваПоискаНеЗамещать, + ИмяТипаОбъекта, "{УникальныйИдентификатор}", СвойствоУникальныйИдентификатор, ОбъектНайден, + АвтоматическиСоздаватьНовыйОбъект, СозданныйОбъект, + РежимПоискаОсновногоОбъекта, СвойстваОбъектаМодифицированы, + НППСсылки, НППГлобальнойСсылки, ПараметрыОбъекта, ИзвестнаяСсылкаУникальногоИдентификатора); + + Если Не НужноПродолжитьПоискЕслиЭлементПоGUIDНеНайден Тогда + + Если Не ЗначениеЗаполнено(СсылкаНаОбъект) + И ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD Тогда + + СсылкаНаОбъект = СтруктураСвойств.Менеджер.ПолучитьСсылку(Новый УникальныйИдентификатор(СвойствоУникальныйИдентификатор)); + ОбъектНайден = Ложь; + СсылкаНаОбъектФиктивная = Истина; + + КонецЕсли; + + Если СсылкаНаОбъект <> Неопределено + И СсылкаНаОбъект.Пустая() Тогда + + СсылкаНаОбъект = Неопределено; + + КонецЕсли; + + Если СсылкаНаОбъект <> Неопределено + ИЛИ СозданныйОбъект <> Неопределено Тогда + + ДобавитьСсылкуВСписокЗагруженныхОбъектов(НППГлобальнойСсылки, НППСсылки, СсылкаНаОбъект, СсылкаНаОбъектФиктивная); + + КонецЕсли; + + Возврат СсылкаНаОбъект; + + КонецЕсли; + + КонецЕсли; + + Если СсылкаНаОбъект <> Неопределено + И СсылкаНаОбъект.Пустая() Тогда + + СсылкаНаОбъект = Неопределено; + + КонецЕсли; + + // СсылкаНаОбъект пока не найден. + Если СсылкаНаОбъект <> Неопределено + ИЛИ СозданныйОбъект <> Неопределено Тогда + + ДобавитьСсылкуВСписокЗагруженныхОбъектов(НППГлобальнойСсылки, НППСсылки, СсылкаНаОбъект); + Возврат СсылкаНаОбъект; + + КонецЕсли; + + НомерВариантаПоиска = 1; + СтрокаИменСвойствПоиска = ""; + ПредыдущаяСтрокаПоиска = Неопределено; + ПрекратитьПоиск = Ложь; + УстанавливатьУОбъектаВсеСвойстваПоиска = Истина; + + Если Не ПустаяСтрока(ИмяПКО) Тогда + + ПКО = Правила[ИмяПКО]; + + КонецЕсли; + + Если ПКО = Неопределено Тогда + + ПКО = ОпределитьПоТипуОбъектаПриемникаПравилоКонвертацииКотороеСодержитАлгоритмПоиска(СтруктураСвойств.ТипСсылкиСтрокой); + + КонецЕсли; + + Если ПКО <> Неопределено Тогда + + АлгоритмПоиска = ПКО.ПоследовательностьПолейПоиска; + + КонецЕсли; + + ЕстьАлгоритмПоиска = Не ПустаяСтрока(АлгоритмПоиска); + + Пока НомерВариантаПоиска <= 10 + И ЕстьАлгоритмПоиска Цикл + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(ПКО, "ПоследовательностьПолейПоиска")); + + Иначе + + Выполнить(АлгоритмПоиска); + + КонецЕсли; + + Исключение + + ЗаписатьИнформациюОбОшибкеЗагрузкиОбработчикаПКО(73, ОписаниеОшибки(), "", "", + ТипОбъекта, Неопределено, НСтр("ru = 'Последовательность полей поиска'")); + + КонецПопытки; + + НеНужноВыполнятьПоиск = ПрекратитьПоиск = Истина + ИЛИ СтрокаИменСвойствПоиска = ПредыдущаяСтрокаПоиска + ИЛИ ЗначениеЗаполнено(СсылкаНаОбъект); + + Если НЕ НеНужноВыполнятьПоиск Тогда + + // сам поиск непосредственно + СсылкаНаОбъект = НайтиЭлементПоСвойствамПоиска(ТипОбъекта, ИмяТипаОбъекта, СвойстваПоиска, СтруктураСвойств, + СтрокаИменСвойствПоиска, ПоискПоДатеНаРавенство); + + НеНужноВыполнятьПоиск = ЗначениеЗаполнено(СсылкаНаОбъект); + + Если СсылкаНаОбъект <> Неопределено + И СсылкаНаОбъект.Пустая() Тогда + СсылкаНаОбъект = Неопределено; + КонецЕсли; + + КонецЕсли; + + Если НеНужноВыполнятьПоиск Тогда + + Если РежимПоискаОсновногоОбъекта И УстанавливатьУОбъектаВсеСвойстваПоиска = Истина Тогда + + ОбработатьУстановкуСвойствПоискаУОбъекта(УстанавливатьУОбъектаВсеСвойстваПоиска, ТипОбъекта, СвойстваПоиска, СвойстваПоискаНеЗамещать, + СсылкаНаОбъект, СозданныйОбъект, НЕ РежимПоискаОсновногоОбъекта, СвойстваОбъектаМодифицированы); + + КонецЕсли; + + Прервать; + + КонецЕсли; + + НомерВариантаПоиска = НомерВариантаПоиска + 1; + ПредыдущаяСтрокаПоиска = СтрокаИменСвойствПоиска; + + КонецЦикла; + + Если Не ЕстьАлгоритмПоиска Тогда + + // Сам поиск непосредственно и без алгоритма поиска. + СсылкаНаОбъект = НайтиЭлементПоСвойствамПоиска(ТипОбъекта, ИмяТипаОбъекта, СвойстваПоиска, СтруктураСвойств, + СтрокаИменСвойствПоиска, ПоискПоДатеНаРавенство); + + КонецЕсли; + + ОбъектНайден = ЗначениеЗаполнено(СсылкаНаОбъект); + + Если РежимПоискаОсновногоОбъекта + И ЗначениеЗаполнено(СсылкаНаОбъект) + И (ИмяТипаОбъекта = "Документ" + ИЛИ ИмяТипаОбъекта = "Задача" + ИЛИ ИмяТипаОбъекта = "БизнесПроцесс") Тогда + + // Если у документа дата есть в свойствах поиска - то устанавливаем ее. + ДатаПустая = Не ЗначениеЗаполнено(СвойстваПоиска["Дата"]); + МожноЗамещать = (Не ДатаПустая) + И (СвойстваПоискаНеЗамещать["Дата"] = Неопределено); + + Если МожноЗамещать Тогда + + Если СозданныйОбъект = Неопределено Тогда + СозданныйОбъект = СсылкаНаОбъект.ПолучитьОбъект(); + КонецЕсли; + + СозданныйОбъект.Дата = СвойстваПоиска["Дата"]; + + КонецЕсли; + + КонецЕсли; + + // Создавать новый объект нужно не всегда. + Если Не ЗначениеЗаполнено(СсылкаНаОбъект) + И СозданныйОбъект = Неопределено Тогда + + Если ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD Тогда + + СсылкаНаОбъект = СтруктураСвойств.Менеджер.ПолучитьСсылку(Новый УникальныйИдентификатор(СвойствоУникальныйИдентификатор)); + СсылкаНаОбъектФиктивная = Истина; + + ИначеЕсли НЕ НеСоздаватьОбъектЕслиНеНайден Тогда + + СсылкаНаОбъект = СоздатьНовыйОбъект(ТипОбъекта, СвойстваПоиска, СозданныйОбъект, НЕ РежимПоискаОсновногоОбъекта, , ИзвестнаяСсылкаУникальногоИдентификатора, НППСсылки, + НППГлобальнойСсылки, ,УстанавливатьУОбъектаВсеСвойстваПоиска); + + СвойстваОбъектаМодифицированы = Истина; + + КонецЕсли; + + ОбъектНайден = Ложь; + + Иначе + + ОбъектНайден = ЗначениеЗаполнено(СсылкаНаОбъект); + + КонецЕсли; + + Если СсылкаНаОбъект <> Неопределено + И СсылкаНаОбъект.Пустая() Тогда + + СсылкаНаОбъект = Неопределено; + + КонецЕсли; + + ДобавитьСсылкуВСписокЗагруженныхОбъектов(НППГлобальнойСсылки, НППСсылки, СсылкаНаОбъект, СсылкаНаОбъектФиктивная); + + Возврат СсылкаНаОбъект; + +КонецФункции + +// Устанавливает свойства объекта (записи). +// +// Параметры: +// Запись - объект, свойства которого устанавливаем. +// Например, строка табличной части или запись регистра. +// +Процедура УстановитьСвойстваЗаписи(Объект, Запись, ИнформацияОТипах, + ПараметрыОбъекта, ИмяВетки, ДанныеПоискаПоТЧ, КопияТЧДляПоиска, НомерЗаписи) + + НужноОрганизоватьПоискПоТЧ = (ДанныеПоискаПоТЧ <> Неопределено) + И (КопияТЧДляПоиска <> Неопределено) + И КопияТЧДляПоиска.Количество() <> 0; + + Если НужноОрганизоватьПоискПоТЧ Тогда + + СтруктураЧтенияСвойств = Новый Структура(); + СтруктураЧтенияСубконто = Новый Структура(); + + КонецЕсли; + + Пока ФайлОбмена.Прочитать() Цикл + + ИмяУзла = ФайлОбмена.ЛокальноеИмя; + + Если ИмяУзла = "Свойство" + ИЛИ ИмяУзла = "ЗначениеПараметра" Тогда + + ЭтоПараметр = (ИмяУзла = "ЗначениеПараметра"); + + Имя = одАтрибут(ФайлОбмена, одТипСтрока, "Имя"); + ИмяПКО = одАтрибут(ФайлОбмена, одТипСтрока, "ИмяПКО"); + + Если Имя = "ВидДвижения" И СтрНайти(Метаданные.НайтиПоТипу(ТипЗнч(Запись)).ПолноеИмя(), "РегистрНакопления") Тогда + + ТипСвойства = одТипВидДвиженияНакопления; + + Иначе + + ТипСвойства = ПолучитьТипСвойстваПоДополнительнымДанным(ИнформацияОТипах, Имя); + + КонецЕсли; + + ЗначениеСвойства = ПрочитатьСвойство(ТипСвойства, ИмяПКО); + + Если ЭтоПараметр Тогда + ДобавитьСложныйПараметрПриНеобходимости(ПараметрыОбъекта, ИмяВетки, НомерЗаписи, Имя, ЗначениеСвойства); + ИначеЕсли НужноОрганизоватьПоискПоТЧ Тогда + СтруктураЧтенияСвойств.Вставить(Имя, ЗначениеСвойства); + Иначе + + Попытка + + Запись[Имя] = ЗначениеСвойства; + + Исключение + + ЗП = ПолучитьСтруктуруЗаписиПротокола(26, ОписаниеОшибки()); + ЗП.ИмяПКО = ИмяПКО; + ЗП.Объект = Объект; + ЗП.ТипОбъекта = ТипЗнч(Объект); + ЗП.Свойство = Строка(Запись) + "." + Имя; + ЗП.Значение = ЗначениеСвойства; + ЗП.ТипЗначения = ТипЗнч(ЗначениеСвойства); + СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(26, ЗП, Истина); + + Если Не ФлагРежимОтладки Тогда + ВызватьИсключение СтрокаСообщенияОбОшибке; + КонецЕсли; + КонецПопытки; + + КонецЕсли; + + ИначеЕсли ИмяУзла = "СубконтоДт" ИЛИ ИмяУзла = "СубконтоКт" Тогда + + // Поиск по субконто не реализован. + + Ключ = Неопределено; + Значение = Неопределено; + + Пока ФайлОбмена.Прочитать() Цикл + + ИмяУзла = ФайлОбмена.ЛокальноеИмя; + + Если ИмяУзла = "Свойство" Тогда + + Имя = одАтрибут(ФайлОбмена, одТипСтрока, "Имя"); + ИмяПКО = одАтрибут(ФайлОбмена, одТипСтрока, "ИмяПКО"); + ТипСвойства = ПолучитьТипСвойстваПоДополнительнымДанным(ИнформацияОТипах, Имя); + + Если Имя = "Ключ" Тогда + + Ключ = ПрочитатьСвойство(ТипСвойства); + + ИначеЕсли Имя = "Значение" Тогда + + Значение = ПрочитатьСвойство(ТипСвойства, ИмяПКО); + + КонецЕсли; + + ИначеЕсли (ИмяУзла = "СубконтоДт" ИЛИ ИмяУзла = "СубконтоКт") И (ФайлОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + + Прервать; + + Иначе + + ЗаписатьВПротоколВыполнения(9); + Прервать; + + КонецЕсли; + + КонецЦикла; + + Если Ключ <> Неопределено + И Значение <> Неопределено Тогда + + Если НЕ НужноОрганизоватьПоискПоТЧ Тогда + + Запись[ИмяУзла][Ключ] = Значение; + + Иначе + + СоответствиеЗаписи = Неопределено; + Если НЕ СтруктураЧтенияСубконто.Свойство(ИмяУзла, СоответствиеЗаписи) Тогда + СоответствиеЗаписи = Новый Соответствие; + СтруктураЧтенияСубконто.Вставить(ИмяУзла, СоответствиеЗаписи); + КонецЕсли; + + СоответствиеЗаписи.Вставить(Ключ, Значение); + + КонецЕсли; + + КонецЕсли; + + ИначеЕсли (ИмяУзла = "Запись") И (ФайлОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + + Прервать; + + Иначе + + ЗаписатьВПротоколВыполнения(9); + Прервать; + + КонецЕсли; + + КонецЦикла; + + Если НужноОрганизоватьПоискПоТЧ Тогда + + СтруктураПоиска = Новый Структура(); + + Для Каждого ЭлементПоиска Из ДанныеПоискаПоТЧ.ПоляПоискаТЧ Цикл + + ЗначениеЭлемента = Неопределено; + СтруктураЧтенияСвойств.Свойство(ЭлементПоиска, ЗначениеЭлемента); + + СтруктураПоиска.Вставить(ЭлементПоиска, ЗначениеЭлемента); + + КонецЦикла; + + МассивРезультатовПоиска = КопияТЧДляПоиска.НайтиСтроки(СтруктураПоиска); + + НайденаЗапись = МассивРезультатовПоиска.Количество() > 0; + Если НайденаЗапись Тогда + ЗаполнитьЗначенияСвойств(Запись, МассивРезультатовПоиска[0]); + КонецЕсли; + + // Поверх заполнение свойствами и значением субконто. + Для Каждого КлючИЗначение Из СтруктураЧтенияСвойств Цикл + + Запись[КлючИЗначение.Ключ] = КлючИЗначение.Значение; + + КонецЦикла; + + Для Каждого ЭлементИмя Из СтруктураЧтенияСубконто Цикл + + Для Каждого ЭлементКлюч Из ЭлементИмя.Значение Цикл + + Запись[ЭлементИмя.Ключ][ЭлементКлюч.Ключ] = ЭлементКлюч.Значение; + + КонецЦикла; + + КонецЦикла; + + КонецЕсли; + +КонецПроцедуры + +// Загружает табличную часть объекта. +// +// Параметры: +// Объект - объект, табличную часть которого загружаем. +// Имя - имя табличной части. +// Очистить - если Истина, то табличная часть предварительно очищается. +// +Процедура ЗагрузитьТабличнуюЧасть(Объект, Имя, Очистить, ОбщаяИнформацияОТипеДокумента, НужноЗаписатьОбъект, + ПараметрыОбъекта, Правило) + + ИмяТабличнойЧасти = Имя + "ТабличнаяЧасть"; + Если ОбщаяИнформацияОТипеДокумента <> Неопределено Тогда + ИнформацияОТипах = ОбщаяИнформацияОТипеДокумента[ИмяТабличнойЧасти]; + Иначе + ИнформацияОТипах = Неопределено; + КонецЕсли; + + ДанныеПоискаПоТЧ = Неопределено; + Если Правило <> Неопределено Тогда + ДанныеПоискаПоТЧ = Правило.ПоискПоТабличнымЧастям.Найти("ТабличнаяЧасть." + Имя, "ИмяЭлемента"); + КонецЕсли; + + КопияТЧДляПоиска = Неопределено; + + ТЧ = Объект[Имя]; + + Если Очистить + И ТЧ.Количество() <> 0 Тогда + + НужноЗаписатьОбъект = Истина; + + Если ДанныеПоискаПоТЧ <> Неопределено Тогда + КопияТЧДляПоиска = ТЧ.Выгрузить(); + КонецЕсли; + ТЧ.Очистить(); + + ИначеЕсли ДанныеПоискаПоТЧ <> Неопределено Тогда + + КопияТЧДляПоиска = ТЧ.Выгрузить(); + + КонецЕсли; + + НомерЗаписи = 0; + Пока ФайлОбмена.Прочитать() Цикл + + ИмяУзла = ФайлОбмена.ЛокальноеИмя; + + Если ИмяУзла = "Запись" Тогда + Попытка + + НужноЗаписатьОбъект = Истина; + Запись = ТЧ.Добавить(); + + Исключение + Запись = Неопределено; + КонецПопытки; + + Если Запись = Неопределено Тогда + одПропустить(ФайлОбмена); + Иначе + УстановитьСвойстваЗаписи(Объект, Запись, ИнформацияОТипах, ПараметрыОбъекта, ИмяТабличнойЧасти, ДанныеПоискаПоТЧ, КопияТЧДляПоиска, НомерЗаписи); + КонецЕсли; + + НомерЗаписи = НомерЗаписи + 1; + + ИначеЕсли (ИмяУзла = "ТабличнаяЧасть") И (ФайлОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + + Прервать; + + Иначе + + ЗаписатьВПротоколВыполнения(9); + Прервать; + + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + +// Загружает движения объекта +// +// Параметры: +// Объект - объект, движения которого загружаем. +// Имя - имя регистра. +// Очистить - если Истина, то движения предварительно очищается. +// +Процедура ЗагрузитьДвижения(Объект, Имя, Очистить, ОбщаяИнформацияОТипеДокумента, НужноЗаписатьОбъект, + ПараметрыОбъекта, Правило) + + ИмяДвижений = Имя + "НаборЗаписей"; + Если ОбщаяИнформацияОТипеДокумента <> Неопределено Тогда + ИнформацияОТипах = ОбщаяИнформацияОТипеДокумента[ИмяДвижений]; + Иначе + ИнформацияОТипах = Неопределено; + КонецЕсли; + + ДанныеПоискаПоТЧ = Неопределено; + Если Правило <> Неопределено Тогда + ДанныеПоискаПоТЧ = Правило.ПоискПоТабличнымЧастям.Найти("НаборЗаписей." + Имя, "ИмяЭлемента"); + КонецЕсли; + + КопияТЧДляПоиска = Неопределено; + + Движения = Объект.Движения[Имя]; + Движения.Записывать = Истина; + + Если Движения.Количество()=0 Тогда + Движения.Прочитать(); + КонецЕсли; + + Если Очистить + И Движения.Количество() <> 0 Тогда + + НужноЗаписатьОбъект = Истина; + + Если ДанныеПоискаПоТЧ <> Неопределено Тогда + КопияТЧДляПоиска = Движения.Выгрузить(); + КонецЕсли; + + Движения.Очистить(); + + ИначеЕсли ДанныеПоискаПоТЧ <> Неопределено Тогда + + КопияТЧДляПоиска = Движения.Выгрузить(); + + КонецЕсли; + + НомерЗаписи = 0; + Пока ФайлОбмена.Прочитать() Цикл + + ИмяУзла = ФайлОбмена.ЛокальноеИмя; + + Если ИмяУзла = "Запись" Тогда + + Запись = Движения.Добавить(); + НужноЗаписатьОбъект = Истина; + УстановитьСвойстваЗаписи(Объект, Запись, ИнформацияОТипах, ПараметрыОбъекта, ИмяДвижений, ДанныеПоискаПоТЧ, КопияТЧДляПоиска, НомерЗаписи); + НомерЗаписи = НомерЗаписи + 1; + + ИначеЕсли (ИмяУзла = "НаборЗаписей") И (ФайлОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + + Прервать; + + Иначе + + ЗаписатьВПротоколВыполнения(9); + Прервать; + + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + +// Загружает объект типа ОписаниеТипов из указанного xml-источника. +// +// Параметры: +// Источник - xml-источник. +// +Функция ЗагрузитьТипыОбъекта(Источник) + + // КвалификаторыДаты + + СоставДаты = одАтрибут(Источник, одТипСтрока, "СоставДаты"); + + // КвалификаторыСтроки + + Длина = одАтрибут(Источник, одТипЧисло, "Длина"); + ДлинаДопустимая = одАтрибут(Источник, одТипСтрока, "ДопустимаяДлина"); + + // КвалификаторыЧисла + + Разрядность = одАтрибут(Источник, одТипЧисло, "Разрядность"); + РазрядностьДробнойЧасти = одАтрибут(Источник, одТипЧисло, "РазрядностьДробнойЧасти"); + ЗнакДопустимый = одАтрибут(Источник, одТипСтрока, "ДопустимыйЗнак"); + + // Читаем массив типов + + МассивТипов = Новый Массив; + + Пока Источник.Прочитать() Цикл + ИмяУзла = Источник.ЛокальноеИмя; + + Если ИмяУзла = "Тип" Тогда + МассивТипов.Добавить(Тип(одЗначениеЭлемента(Источник, одТипСтрока))); + ИначеЕсли (ИмяУзла = "Типы") И ( Источник.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + Прервать; + Иначе + ЗаписатьВПротоколВыполнения(9); + Прервать; + КонецЕсли; + + КонецЦикла; + + Если МассивТипов.Количество() > 0 Тогда + + // КвалификаторыДаты + + Если СоставДаты = "Дата" Тогда + КвалификаторыДаты = Новый КвалификаторыДаты(ЧастиДаты.Дата); + ИначеЕсли СоставДаты = "ДатаВремя" Тогда + КвалификаторыДаты = Новый КвалификаторыДаты(ЧастиДаты.ДатаВремя); + ИначеЕсли СоставДаты = "Время" Тогда + КвалификаторыДаты = Новый КвалификаторыДаты(ЧастиДаты.Время); + Иначе + КвалификаторыДаты = Новый КвалификаторыДаты(ЧастиДаты.ДатаВремя); + КонецЕсли; + + // КвалификаторыЧисла + + Если Разрядность > 0 Тогда + Если ЗнакДопустимый = "Неотрицательный" Тогда + Знак = ДопустимыйЗнак.Неотрицательный; + Иначе + Знак = ДопустимыйЗнак.Любой; + КонецЕсли; + КвалификаторыЧисла = Новый КвалификаторыЧисла(Разрядность, РазрядностьДробнойЧасти, Знак); + Иначе + КвалификаторыЧисла = Новый КвалификаторыЧисла(); + КонецЕсли; + + // КвалификаторыСтроки + + Если Длина > 0 Тогда + Если ДлинаДопустимая = "Фиксированная" Тогда + ДлинаДопустимая = ДопустимаяДлина.Фиксированная; + Иначе + ДлинаДопустимая = ДопустимаяДлина.Переменная; + КонецЕсли; + КвалификаторыСтроки = Новый КвалификаторыСтроки(Длина, ДлинаДопустимая); + Иначе + КвалификаторыСтроки = Новый КвалификаторыСтроки(); + КонецЕсли; + + Возврат Новый ОписаниеТипов(МассивТипов, КвалификаторыЧисла, КвалификаторыСтроки, КвалификаторыДаты); + КонецЕсли; + + Возврат Неопределено; + +КонецФункции + +Процедура УстановитьПометкуУдаленияУОбъекта(Объект, ПометкаУдаления, ИмяТипаОбъекта) + + Если (ПометкаУдаления = Неопределено) + И (Объект.ПометкаУдаления <> Истина) Тогда + + Возврат; + + КонецЕсли; + + ПометкаДляУстановки = ?(ПометкаУдаления <> Неопределено, ПометкаУдаления, Ложь); + + УстановитьОбменДаннымиЗагрузка(Объект); + + // Дли иерархических объектов пометку удаления только у конкретного объекта ставим. + Если ИмяТипаОбъекта = "Справочник" + ИЛИ ИмяТипаОбъекта = "ПланВидовХарактеристик" + ИЛИ ИмяТипаОбъекта = "ПланСчетов" Тогда + + Объект.УстановитьПометкуУдаления(ПометкаДляУстановки, Ложь); + + Иначе + + Объект.УстановитьПометкуУдаления(ПометкаДляУстановки); + + КонецЕсли; + +КонецПроцедуры + +Процедура ЗаписатьДокументВБезопасномРежиме(Документ, ТипОбъекта) + + Если Документ.Проведен Тогда + + Документ.Проведен = Ложь; + + КонецЕсли; + + ЗаписатьОбъектВИБ(Документ, ТипОбъекта); + +КонецПроцедуры + +Функция ПолучитьОбъектПоСсылкеИДопИнформации(СозданныйОбъект, Ссылка) + + // Если объект создали, то работаем с ним, если нашли - получаем объект. + Если СозданныйОбъект <> Неопределено Тогда + Объект = СозданныйОбъект; + Иначе + Если Ссылка.Пустая() Тогда + Объект = Неопределено; + Иначе + Объект = Ссылка.ПолучитьОбъект(); + КонецЕсли; + КонецЕсли; + + Возврат Объект; + +КонецФункции + +Процедура КомментарииКЗагрузкеОбъекта(НПП, ИмяПравила, Источник, ТипОбъекта, ГНПП = 0) + + Если ФлагКомментироватьОбработкуОбъектов Тогда + + Если НПП <> 0 Тогда + СтрокаСообщения = ПодставитьПараметрыВСтроку(НСтр("ru = 'Загрузка объекта № %1'"), НПП); + Иначе + СтрокаСообщения = ПодставитьПараметрыВСтроку(НСтр("ru = 'Загрузка объекта № %1'"), ГНПП); + КонецЕсли; + + ЗП = ПолучитьСтруктуруЗаписиПротокола(); + + Если Не ПустаяСтрока(ИмяПравила) Тогда + + ЗП.ИмяПКО = ИмяПравила; + + КонецЕсли; + + Если Не ПустаяСтрока(Источник) Тогда + + ЗП.Источник = Источник; + + КонецЕсли; + + ЗП.ТипОбъекта = ТипОбъекта; + ЗаписатьВПротоколВыполнения(СтрокаСообщения, ЗП, Ложь); + + КонецЕсли; + +КонецПроцедуры + +Процедура ДобавитьПараметрПриНеобходимости(ПараметрыДанных, ИмяПараметра, ЗначениеПараметра) + + Если ПараметрыДанных = Неопределено Тогда + ПараметрыДанных = Новый Соответствие; + КонецЕсли; + + ПараметрыДанных.Вставить(ИмяПараметра, ЗначениеПараметра); + +КонецПроцедуры + +Процедура ДобавитьСложныйПараметрПриНеобходимости(ПараметрыДанных, ИмяВеткиПараметров, НомерСтроки, ИмяПараметра, ЗначениеПараметра) + + Если ПараметрыДанных = Неопределено Тогда + ПараметрыДанных = Новый Соответствие; + КонецЕсли; + + ТекущиеДанныеПараметра = ПараметрыДанных[ИмяВеткиПараметров]; + + Если ТекущиеДанныеПараметра = Неопределено Тогда + + ТекущиеДанныеПараметра = Новый ТаблицаЗначений; + ТекущиеДанныеПараметра.Колонки.Добавить("НомерСтроки"); + ТекущиеДанныеПараметра.Колонки.Добавить("ИмяПараметра"); + ТекущиеДанныеПараметра.Индексы.Добавить("НомерСтроки"); + + ПараметрыДанных.Вставить(ИмяВеткиПараметров, ТекущиеДанныеПараметра); + + КонецЕсли; + + Если ТекущиеДанныеПараметра.Колонки.Найти(ИмяПараметра) = Неопределено Тогда + ТекущиеДанныеПараметра.Колонки.Добавить(ИмяПараметра); + КонецЕсли; + + ДанныеСтроки = ТекущиеДанныеПараметра.Найти(НомерСтроки, "НомерСтроки"); + Если ДанныеСтроки = Неопределено Тогда + ДанныеСтроки = ТекущиеДанныеПараметра.Добавить(); + ДанныеСтроки.НомерСтроки = НомерСтроки; + КонецЕсли; + + ДанныеСтроки[ИмяПараметра] = ЗначениеПараметра; + +КонецПроцедуры + +Процедура УстановитьСсылкуДляОбъекта(СтрокаСтекаНезаписанныхОбъектов) + + // Объект еще не записан, а на него ссылаются. + ОбъектДляЗаписи = СтрокаСтекаНезаписанныхОбъектов.Объект; + + СвойстваМД = Менеджеры[СтрокаСтекаНезаписанныхОбъектов.ТипОбъекта]; + Менеджер = СвойстваМД.Менеджер; + + НовыйУникальныйИдентификатор = Новый УникальныйИдентификатор; + НоваяСсылка = Менеджер.ПолучитьСсылку(НовыйУникальныйИдентификатор); + + ОбъектДляЗаписи.УстановитьСсылкуНового(НоваяСсылка); + СтрокаСтекаНезаписанныхОбъектов.ИзвестнаяСсылка = НоваяСсылка; + +КонецПроцедуры + +Процедура ДополнитьСтекНеЗаписанныхОбъектов(НПП, ГНПП, Объект, ИзвестнаяСсылка, ТипОбъекта, ПараметрыОбъекта) + + НомерДляСтека = ?(НПП = 0, ГНПП, НПП); + + СтрокаСтека = мГлобальныйСтекНеЗаписанныхОбъектов[НомерДляСтека]; + Если СтрокаСтека <> Неопределено Тогда + Возврат; + КонецЕсли; + СтруктураПараметров = Новый Структура(); + СтруктураПараметров.Вставить("Объект", Объект); + СтруктураПараметров.Вставить("ИзвестнаяСсылка", ИзвестнаяСсылка); + СтруктураПараметров.Вставить("ТипОбъекта", ТипОбъекта); + СтруктураПараметров.Вставить("ПараметрыОбъекта", ПараметрыОбъекта); + + мГлобальныйСтекНеЗаписанныхОбъектов.Вставить(НомерДляСтека, СтруктураПараметров); + +КонецПроцедуры + +Процедура УдалитьИзСтекаНеЗаписанныхОбъектов(НПП, ГНПП) + + НомерДляСтека = ?(НПП = 0, ГНПП, НПП); + СтрокаСтека = мГлобальныйСтекНеЗаписанныхОбъектов[НомерДляСтека]; + Если СтрокаСтека = Неопределено Тогда + Возврат; + КонецЕсли; + + мГлобальныйСтекНеЗаписанныхОбъектов.Удалить(НомерДляСтека); + +КонецПроцедуры + +Процедура ПровестиЗаписьНеЗаписанныхОбъектов() + + Если мГлобальныйСтекНеЗаписанныхОбъектов = Неопределено Тогда + Возврат; + КонецЕсли; + + Для Каждого СтрокаДанных Из мГлобальныйСтекНеЗаписанныхОбъектов Цикл + + // отложенная запись объектов + Объект = СтрокаДанных.Значение.Объект; // СправочникОбъект, ДокументОбъект, и т.п. + НППСсылки = СтрокаДанных.Ключ; + + ЗаписатьОбъектВИБ(Объект, СтрокаДанных.Значение.ТипОбъекта); + + ДобавитьСсылкуВСписокЗагруженныхОбъектов(0, НППСсылки, Объект.Ссылка); + + КонецЦикла; + + мГлобальныйСтекНеЗаписанныхОбъектов.Очистить(); + +КонецПроцедуры + +Процедура ПровестиГенерациюКодаНомераПриНеобходимости(ГенерироватьНовыйНомерИлиКодЕслиНеУказан, Объект, ИмяТипаОбъекта, НужноЗаписатьОбъект, + РежимОбменДанными) + + Если Не ГенерироватьНовыйНомерИлиКодЕслиНеУказан + ИЛИ НЕ РежимОбменДанными Тогда + + // Если номер не нужно генерировать, или не в режиме обмена данными то ничего не нужно делать... платформа сама все + // сгенерирует. + Возврат; + КонецЕсли; + + // По типу документа смотрим заполнен кол или номер. + Если ИмяТипаОбъекта = "Документ" + ИЛИ ИмяТипаОбъекта = "БизнесПроцесс" + ИЛИ ИмяТипаОбъекта = "Задача" Тогда + + Если НЕ ЗначениеЗаполнено(Объект.Номер) Тогда + + Объект.УстановитьНовыйНомер(); + НужноЗаписатьОбъект = Истина; + + КонецЕсли; + + ИначеЕсли ИмяТипаОбъекта = "Справочник" + ИЛИ ИмяТипаОбъекта = "ПланВидовХарактеристик" + ИЛИ ИмяТипаОбъекта = "ПланОбмена" Тогда + + Если НЕ ЗначениеЗаполнено(Объект.Код) Тогда + + Объект.УстановитьНовыйКод(); + НужноЗаписатьОбъект = Истина; + + КонецЕсли; + + КонецЕсли; + +КонецПроцедуры + +// Читает очередной объект из файла обмена, производит загрузку. +// +// Параметры: +// Нет. +// +Функция ПрочитатьОбъект() + + Если БезопасныйРежим Тогда + УстановитьБезопасныйРежим(Истина); + Для Каждого ИмяРазделителя Из РазделителиКонфигурации Цикл + УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина); + КонецЦикла; + КонецЕсли; + + НПП = одАтрибут(ФайлОбмена, одТипЧисло, "Нпп"); + ГНПП = одАтрибут(ФайлОбмена, одТипЧисло, "ГНпп"); + Источник = одАтрибут(ФайлОбмена, одТипСтрока, "Источник"); + ИмяПравила = одАтрибут(ФайлОбмена, одТипСтрока, "ИмяПравила"); + НеЗамещатьОбъект = одАтрибут(ФайлОбмена, одТипБулево, "НеЗамещать"); + ПрефиксАвтонумерации = одАтрибут(ФайлОбмена, одТипСтрока, "ПрефиксАвтонумерации"); + ТипОбъектаСтрокой = одАтрибут(ФайлОбмена, одТипСтрока, "Тип"); + ТипОбъекта = Тип(ТипОбъектаСтрокой); + ИнформацияОТипах = мСоответствиеТиповДанныхДляЗагрузки[ТипОбъекта]; + + КомментарииКЗагрузкеОбъекта(НПП, ИмяПравила, Источник, ТипОбъекта, ГНПП); + + СтруктураСвойств = Менеджеры[ТипОбъекта]; + ИмяТипаОбъекта = СтруктураСвойств.ИмяТипа; + + Если ИмяТипаОбъекта = "Документ" Тогда + + РежимЗаписи = одАтрибут(ФайлОбмена, одТипСтрока, "РежимЗаписи"); + РежимПроведения = одАтрибут(ФайлОбмена, одТипСтрока, "РежимПроведения"); + + КонецЕсли; + + Ссылка = Неопределено; + Объект = Неопределено; // СправочникОбъект, ДокументОбъект, РегистрСведенийНаборЗаписей, и т.п. + ОбъектНайден = Истина; + ПометкаУдаления = Неопределено; + + СвойстваПоиска = Новый Соответствие; + СвойстваПоискаНеЗамещать = Новый Соответствие; + + НужноЗаписатьОбъект = НЕ ЗаписыватьВИнформационнуюБазуТолькоИзмененныеОбъекты; + + + + Если Не ПустаяСтрока(ИмяПравила) Тогда + + Правило = Правила[ИмяПравила]; + ЕстьОбработчикПередЗагрузкой = Правило.ЕстьОбработчикПередЗагрузкой; + ЕстьОбработчикПриЗагрузке = Правило.ЕстьОбработчикПриЗагрузке; + ЕстьОбработчикПослеЗагрузки = Правило.ЕстьОбработчикПослеЗагрузки; + ГенерироватьНовыйНомерИлиКодЕслиНеУказан = Правило.ГенерироватьНовыйНомерИлиКодЕслиНеУказан; + + Иначе + + ЕстьОбработчикПередЗагрузкой = Ложь; + ЕстьОбработчикПриЗагрузке = Ложь; + ЕстьОбработчикПослеЗагрузки = Ложь; + ГенерироватьНовыйНомерИлиКодЕслиНеУказан = Ложь; + + КонецЕсли; + + + // Глобальный обработчик события ПередЗагрузкойОбъекта. + Если ЕстьГлобальныйОбработчикПередЗагрузкойОбъекта Тогда + + Отказ = Ложь; + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(Конвертация, "ПередЗагрузкойОбъекта")); + + Иначе + + Выполнить(Конвертация.ПередЗагрузкойОбъекта); + + КонецЕсли; + + Исключение + + ЗаписатьИнформациюОбОшибкеЗагрузкиОбработчикаПКО(53, ОписаниеОшибки(), ИмяПравила, Источник, + ТипОбъекта, Неопределено, НСтр("ru = 'ПередЗагрузкойОбъекта (глобальный)'")); + + КонецПопытки; + + Если Отказ Тогда // Отказ от загрузки объекта + + одПропустить(ФайлОбмена, "Объект"); + Возврат Неопределено; + + КонецЕсли; + + КонецЕсли; + + + // Обработчик события ПередЗагрузкойОбъекта. + Если ЕстьОбработчикПередЗагрузкой Тогда + + Отказ = Ложь; + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(Правило, "ПередЗагрузкой")); + + Иначе + + Выполнить(Правило.ПередЗагрузкой); + + КонецЕсли; + + Исключение + + ЗаписатьИнформациюОбОшибкеЗагрузкиОбработчикаПКО(19, ОписаниеОшибки(), ИмяПравила, Источник, + ТипОбъекта, Неопределено, "ПередЗагрузкойОбъекта"); + + КонецПопытки; + + Если Отказ Тогда // Отказ от загрузки объекта + + одПропустить(ФайлОбмена, "Объект"); + Возврат Неопределено; + + КонецЕсли; + + КонецЕсли; + + СвойстваОбъектаМодифицированы = Ложь; + НаборЗаписей = Неопределено; + НППГлобальнойСсылки = 0; + НППСсылки = 0; + ПараметрыОбъекта = Неопределено; + + Пока ФайлОбмена.Прочитать() Цикл + + ИмяУзла = ФайлОбмена.ЛокальноеИмя; + + Если ИмяУзла = "Свойство" + ИЛИ ИмяУзла = "ЗначениеПараметра" Тогда + + ЭтоПараметрДляОбъекта = (ИмяУзла = "ЗначениеПараметра"); + + Если НЕ ЭтоПараметрДляОбъекта + И Объект = Неопределено Тогда + + // Объект не нашли и не создали - попробуем сейчас это сделать. + ОбъектНайден = Ложь; + + // Обработчик события ПриЗагрузкеОбъекта. + Если ЕстьОбработчикПриЗагрузке Тогда + + // Если есть обработчик при загрузке, то объект нужно перезаписывать, так как могут быть изменения. + НужноБылоЗаписатьОбъект = НужноЗаписатьОбъект; + ОбъектМодифицирован = Истина; + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(Правило, "ПриЗагрузке")); + + Иначе + + Выполнить(Правило.ПриЗагрузке); + + КонецЕсли; + НужноЗаписатьОбъект = ОбъектМодифицирован ИЛИ НужноБылоЗаписатьОбъект; + + Исключение + + ЗаписатьИнформациюОбОшибкеЗагрузкиОбработчикаПКО(20, ОписаниеОшибки(), ИмяПравила, Источник, + ТипОбъекта, Объект, "ПриЗагрузкеОбъекта"); + + КонецПопытки; + + КонецЕсли; + + // Так м не смогли создать объект в событии - создаем его отдельно. + Если Объект = Неопределено Тогда + + НужноЗаписатьОбъект = Истина; + + Если ИмяТипаОбъекта = "Константы" Тогда + + Объект = Константы.СоздатьНабор(); + Объект.Прочитать(); + + Иначе + + СоздатьНовыйОбъект(ТипОбъекта, СвойстваПоиска, Объект, Ложь, НаборЗаписей, , НППСсылки, НППГлобальнойСсылки, ПараметрыОбъекта); + + КонецЕсли; + + КонецЕсли; + + КонецЕсли; + + Имя = одАтрибут(ФайлОбмена, одТипСтрока, "Имя"); + НеЗамещатьСвойство = одАтрибут(ФайлОбмена, одТипБулево, "НеЗамещать"); + ИмяПКО = одАтрибут(ФайлОбмена, одТипСтрока, "ИмяПКО"); + + Если НЕ ЭтоПараметрДляОбъекта + И ((ОбъектНайден И НеЗамещатьСвойство) + ИЛИ (Имя = "ЭтоГруппа") + ИЛИ (Объект[Имя] = NULL)) Тогда + + // неизвестное свойство + одПропустить(ФайлОбмена, ИмяУзла); + Продолжить; + + КонецЕсли; + + + // Читаем и устанавливаем значение свойства. + ТипСвойства = ПолучитьТипСвойстваПоДополнительнымДанным(ИнформацияОТипах, Имя); + Значение = ПрочитатьСвойство(ТипСвойства, ИмяПКО); + + Если ЭтоПараметрДляОбъекта Тогда + + // Дополняем коллекцию параметров объекта. + ДобавитьПараметрПриНеобходимости(ПараметрыОбъекта, Имя, Значение); + + Иначе + + Если Имя = "ПометкаУдаления" Тогда + + ПометкаУдаления = Значение; + + Если Объект.ПометкаУдаления <> ПометкаУдаления Тогда + Объект.ПометкаУдаления = ПометкаУдаления; + НужноЗаписатьОбъект = Истина; + КонецЕсли; + + Иначе + + Попытка + + Если Не НужноЗаписатьОбъект Тогда + + НужноЗаписатьОбъект = (Объект[Имя] <> Значение); + + КонецЕсли; + + Объект[Имя] = Значение; + + Исключение + + ЗП = ПолучитьСтруктуруЗаписиПротокола(26, ОписаниеОшибки()); + ЗП.ИмяПКО = ИмяПравила; + ЗП.НПП = НПП; + ЗП.ГНПП = ГНПП; + ЗП.Источник = Источник; + ЗП.Объект = Объект; + ЗП.ТипОбъекта = ТипОбъекта; + ЗП.Свойство = Имя; + ЗП.Значение = Значение; + ЗП.ТипЗначения = ТипЗнч(Значение); + СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(26, ЗП, Истина); + + Если Не ФлагРежимОтладки Тогда + ВызватьИсключение СтрокаСообщенияОбОшибке; + КонецЕсли; + + КонецПопытки; + + КонецЕсли; + + КонецЕсли; + + ИначеЕсли ИмяУзла = "Ссылка" Тогда + + // Ссылка на элемент - сначала получаем по ссылке объект, а потом устанавливаем свойства. + СозданныйОбъект = Неопределено; + НеСоздаватьОбъектЕслиНеНайден = Неопределено; + ИзвестнаяСсылкаУникальногоИдентификатора = Неопределено; + + Ссылка = НайтиОбъектПоСсылке(ТипОбъекта, + ИмяПравила, + СвойстваПоиска, + СвойстваПоискаНеЗамещать, + ОбъектНайден, + СозданныйОбъект, + НеСоздаватьОбъектЕслиНеНайден, + Истина, + СвойстваОбъектаМодифицированы, + НППГлобальнойСсылки, + НППСсылки, + ИзвестнаяСсылкаУникальногоИдентификатора, + ПараметрыОбъекта); + + НужноЗаписатьОбъект = НужноЗаписатьОбъект ИЛИ СвойстваОбъектаМодифицированы; + + Если Ссылка = Неопределено + И НеСоздаватьОбъектЕслиНеНайден = Истина Тогда + + одПропустить(ФайлОбмена, "Объект"); + Прервать; + + ИначеЕсли ИмяТипаОбъекта = "Перечисление" Тогда + + Объект = Ссылка; + + Иначе + + Объект = ПолучитьОбъектПоСсылкеИДопИнформации(СозданныйОбъект, Ссылка); + + Если ОбъектНайден И НеЗамещатьОбъект И (Не ЕстьОбработчикПриЗагрузке) Тогда + + одПропустить(ФайлОбмена, "Объект"); + Прервать; + + КонецЕсли; + + Если Ссылка = Неопределено Тогда + + ДополнитьСтекНеЗаписанныхОбъектов(НПП, ГНПП, СозданныйОбъект, ИзвестнаяСсылкаУникальногоИдентификатора, ТипОбъекта, ПараметрыОбъекта); + + КонецЕсли; + + КонецЕсли; + + // Обработчик события ПриЗагрузкеОбъекта. + Если ЕстьОбработчикПриЗагрузке Тогда + + НужноБылоЗаписатьОбъект = НужноЗаписатьОбъект; + ОбъектМодифицирован = Истина; + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(Правило, "ПриЗагрузке")); + + Иначе + + Выполнить(Правило.ПриЗагрузке); + + КонецЕсли; + + НужноЗаписатьОбъект = ОбъектМодифицирован ИЛИ НужноБылоЗаписатьОбъект; + + Исключение + УдалитьИзСтекаНеЗаписанныхОбъектов(НПП, ГНПП); + ЗаписатьИнформациюОбОшибкеЗагрузкиОбработчикаПКО(20, ОписаниеОшибки(), ИмяПравила, Источник, + ТипОбъекта, Объект, "ПриЗагрузкеОбъекта"); + + КонецПопытки; + + Если ОбъектНайден И НеЗамещатьОбъект Тогда + + одПропустить(ФайлОбмена, "Объект"); + Прервать; + + КонецЕсли; + + КонецЕсли; + + ИначеЕсли ИмяУзла = "ТабличнаяЧасть" + ИЛИ ИмяУзла = "НаборЗаписей" Тогда + + Если Объект = Неопределено Тогда + + ОбъектНайден = Ложь; + + // Обработчик события ПриЗагрузкеОбъекта. + + Если ЕстьОбработчикПриЗагрузке Тогда + + НужноБылоЗаписатьОбъект = НужноЗаписатьОбъект; + ОбъектМодифицирован = Истина; + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(Правило, "ПриЗагрузке")); + + Иначе + + Выполнить(Правило.ПриЗагрузке); + + КонецЕсли; + + НужноЗаписатьОбъект = ОбъектМодифицирован ИЛИ НужноБылоЗаписатьОбъект; + + Исключение + УдалитьИзСтекаНеЗаписанныхОбъектов(НПП, ГНПП); + ЗаписатьИнформациюОбОшибкеЗагрузкиОбработчикаПКО(20, ОписаниеОшибки(), ИмяПравила, Источник, + ТипОбъекта, Объект, "ПриЗагрузкеОбъекта"); + + КонецПопытки; + + КонецЕсли; + + КонецЕсли; + + Имя = одАтрибут(ФайлОбмена, одТипСтрока, "Имя"); + НеЗамещатьСвойство = одАтрибут(ФайлОбмена, одТипБулево, "НеЗамещать"); + НеОчищать = одАтрибут(ФайлОбмена, одТипБулево, "НеОчищать"); + + Если ОбъектНайден И НеЗамещатьСвойство Тогда + + одПропустить(ФайлОбмена, ИмяУзла); + Продолжить; + + КонецЕсли; + + Если Объект = Неопределено Тогда + + СоздатьНовыйОбъект(ТипОбъекта, СвойстваПоиска, Объект, Ложь, НаборЗаписей, , НППСсылки, НППГлобальнойСсылки, ПараметрыОбъекта); + НужноЗаписатьОбъект = Истина; + + КонецЕсли; + + Если ИмяУзла = "ТабличнаяЧасть" Тогда + + // Загрузка элементов из табличной части. + ЗагрузитьТабличнуюЧасть(Объект, Имя, Не НеОчищать, ИнформацияОТипах, НужноЗаписатьОбъект, ПараметрыОбъекта, Правило); + + ИначеЕсли ИмяУзла = "НаборЗаписей" Тогда + + // загрузка движений + ЗагрузитьДвижения(Объект, Имя, Не НеОчищать, ИнформацияОТипах, НужноЗаписатьОбъект, ПараметрыОбъекта, Правило); + + КонецЕсли; + + ИначеЕсли (ИмяУзла = "Объект") И (ФайлОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + + Отказ = Ложь; + + // Глобальный обработчик события ПослеЗагрузкиОбъекта. + Если ЕстьГлобальныйОбработчикПослеЗагрузкиОбъекта Тогда + + НужноБылоЗаписатьОбъект = НужноЗаписатьОбъект; + ОбъектМодифицирован = Истина; + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(Конвертация, "ПослеЗагрузкиОбъекта")); + + Иначе + + Выполнить(Конвертация.ПослеЗагрузкиОбъекта); + + КонецЕсли; + + НужноЗаписатьОбъект = ОбъектМодифицирован ИЛИ НужноБылоЗаписатьОбъект; + + Исключение + УдалитьИзСтекаНеЗаписанныхОбъектов(НПП, ГНПП); + ЗаписатьИнформациюОбОшибкеЗагрузкиОбработчикаПКО(54, ОписаниеОшибки(), ИмяПравила, Источник, + ТипОбъекта, Объект, НСтр("ru = 'ПослеЗагрузкиОбъекта (глобальный)'")); + + КонецПопытки; + + КонецЕсли; + + // Обработчик события ПослеЗагрузкиОбъекта. + Если ЕстьОбработчикПослеЗагрузки Тогда + + НужноБылоЗаписатьОбъект = НужноЗаписатьОбъект; + ОбъектМодифицирован = Истина; + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(Правило, "ПослеЗагрузки")); + + Иначе + + Выполнить(Правило.ПослеЗагрузки); + + КонецЕсли; + + НужноЗаписатьОбъект = ОбъектМодифицирован ИЛИ НужноБылоЗаписатьОбъект; + + Исключение + УдалитьИзСтекаНеЗаписанныхОбъектов(НПП, ГНПП); + ЗаписатьИнформациюОбОшибкеЗагрузкиОбработчикаПКО(21, ОписаниеОшибки(), ИмяПравила, Источник, + ТипОбъекта, Объект, "ПослеЗагрузкиОбъекта"); + + КонецПопытки; + + КонецЕсли; + + Если ИмяТипаОбъекта <> "РегистрСведений" + И ИмяТипаОбъекта <> "Константы" + И ИмяТипаОбъекта <> "Перечисление" Тогда + // Проверка даты запрета для всех объектов кроме регистров сведений и констант. + Отказ = Отказ Или ЗапретИзмененияДанныхПоДате(Объект); + КонецЕсли; + + Если Отказ Тогда + + ДобавитьСсылкуВСписокЗагруженныхОбъектов(НППГлобальнойСсылки, НППСсылки, Неопределено); + УдалитьИзСтекаНеЗаписанныхОбъектов(НПП, ГНПП); + Возврат Неопределено; + + КонецЕсли; + + Если ИмяТипаОбъекта = "Документ" Тогда + + Если РежимЗаписи = "Проведение" Тогда + + РежимЗаписи = РежимЗаписиДокумента.Проведение; + + Иначе + + РежимЗаписи = ?(РежимЗаписи = "ОтменаПроведения", РежимЗаписиДокумента.ОтменаПроведения, РежимЗаписиДокумента.Запись); + + КонецЕсли; + + + РежимПроведения = ?(РежимПроведения = "Оперативный", РежимПроведенияДокумента.Оперативный, РежимПроведенияДокумента.Неоперативный); + + + // Если хотим провести документ помеченный на удаление, то пометку удаления снимаем ... + Если Объект.ПометкаУдаления + И (РежимЗаписи = РежимЗаписиДокумента.Проведение) Тогда + + Объект.ПометкаУдаления = Ложь; + НужноЗаписатьОбъект = Истина; + + // Пометку удаления в любом случае нужно удалять. + ПометкаУдаления = Ложь; + + КонецЕсли; + + Попытка + + НужноЗаписатьОбъект = НужноЗаписатьОбъект ИЛИ (РежимЗаписи <> РежимЗаписиДокумента.Запись); + + РежимОбменДанными = РежимЗаписи = РежимЗаписиДокумента.Запись; + + ПровестиГенерациюКодаНомераПриНеобходимости(ГенерироватьНовыйНомерИлиКодЕслиНеУказан, Объект, + ИмяТипаОбъекта, НужноЗаписатьОбъект, РежимОбменДанными); + + Если НужноЗаписатьОбъект Тогда + + УстановитьОбменДаннымиЗагрузка(Объект, РежимОбменДанными); + Если Объект.Проведен Тогда + Объект.ПометкаУдаления = Ложь; + КонецЕсли; + + Объект.Записать(РежимЗаписи, РежимПроведения); + + КонецЕсли; + + Исключение + + // Не смогли выполнить необходимые действия для документа. + ЗаписатьДокументВБезопасномРежиме(Объект, ТипОбъекта); + + + ЗП = ПолучитьСтруктуруЗаписиПротокола(25, ОписаниеОшибки()); + ЗП.ИмяПКО = ИмяПравила; + + Если Не ПустаяСтрока(Источник) Тогда + + ЗП.Источник = Источник; + + КонецЕсли; + + ЗП.ТипОбъекта = ТипОбъекта; + ЗП.Объект = Строка(Объект); + ЗаписатьВПротоколВыполнения(25, ЗП); + + КонецПопытки; + + ДобавитьСсылкуВСписокЗагруженныхОбъектов(НППГлобальнойСсылки, НППСсылки, Объект.Ссылка); + + УдалитьИзСтекаНеЗаписанныхОбъектов(НПП, ГНПП); + + ИначеЕсли ИмяТипаОбъекта <> "Перечисление" Тогда + + Если ИмяТипаОбъекта = "РегистрСведений" Тогда + + НужноЗаписатьОбъект = НЕ ЗаписыватьВИнформационнуюБазуТолькоИзмененныеОбъекты; + + Если СтруктураСвойств.Периодический + И Не ЗначениеЗаполнено(Объект.Период) Тогда + + Объект.Период = ТекущаяДатаСеанса(); + НужноЗаписатьОбъект = Истина; + + КонецЕсли; + + Если ЗаписыватьРегистрыНаборамиЗаписей Тогда + + НужноПроверитьДанныеДляВременногоНабора = + (ЗаписыватьВИнформационнуюБазуТолькоИзмененныеОбъекты + И НЕ НужноЗаписатьОбъект) + ИЛИ НеЗамещатьОбъект; + + Если НужноПроверитьДанныеДляВременногоНабора Тогда + + ВременныйНаборЗаписей = РегистрыСведений[СтруктураСвойств.Имя].СоздатьНаборЗаписей(); + + КонецЕсли; + + // Нужно отбор установить у регистра. + Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл + + ЭлементОтбора.Установить(Объект[ЭлементОтбора.Имя]); + Если НужноПроверитьДанныеДляВременногоНабора Тогда + УстановитьЗначениеЭлементаОтбора(ВременныйНаборЗаписей.Отбор, ЭлементОтбора.Имя, Объект[ЭлементОтбора.Имя]); + КонецЕсли; + + КонецЦикла; + + Если НужноПроверитьДанныеДляВременногоНабора Тогда + + ВременныйНаборЗаписей.Прочитать(); + + Если ВременныйНаборЗаписей.Количество() = 0 Тогда + НужноЗаписатьОбъект = Истина; + Иначе + + // Не хотим замещать существующий набор. + Если НеЗамещатьОбъект Тогда + Возврат Неопределено; + КонецЕсли; + + НужноЗаписатьОбъект = Ложь; + ТаблицаНовая = НаборЗаписей.Выгрузить(); // ТаблицаЗначений + ТаблицаСтарая = ВременныйНаборЗаписей.Выгрузить(); + + СтрокаНовая = ТаблицаНовая[0]; + СтрокаСтарая = ТаблицаСтарая[0]; + + Для Каждого КолонкаТаблицы Из ТаблицаНовая.Колонки Цикл + + НужноЗаписатьОбъект = СтрокаНовая[КолонкаТаблицы.Имя] <> СтрокаСтарая[КолонкаТаблицы.Имя]; + Если НужноЗаписатьОбъект Тогда + Прервать; + КонецЕсли; + + КонецЦикла; + + КонецЕсли; + + КонецЕсли; + + Объект = НаборЗаписей; + + Если СтруктураСвойств.Периодический Тогда + // Проверка даты запрета изменения для набора записей. + // Если не проходит - не записывать набор. + Если ЗапретИзмененияДанныхПоДате(Объект) Тогда + Возврат Неопределено; + КонецЕсли; + КонецЕсли; + + Иначе + + // Регистр записываем не набором записей. + Если НеЗамещатьОбъект Или СтруктураСвойств.Периодический Тогда + + // Возможно мы не хотим замещать существующую запись, либо нужна проверка на дату запрета. + ВременныйНаборЗаписей = РегистрыСведений[СтруктураСвойств.Имя].СоздатьНаборЗаписей(); + + // Нужно отбор установить у регистра. + Для Каждого ЭлементОтбора Из ВременныйНаборЗаписей.Отбор Цикл + + ЭлементОтбора.Установить(Объект[ЭлементОтбора.Имя]); + + КонецЦикла; + + ВременныйНаборЗаписей.Прочитать(); + + Если ВременныйНаборЗаписей.Количество() > 0 + Или ЗапретИзмененияДанныхПоДате(ВременныйНаборЗаписей) Тогда + Возврат Неопределено; + КонецЕсли; + + Иначе + // Считаем что объект следует записать. + НужноЗаписатьОбъект = Истина; + КонецЕсли; + + КонецЕсли; + + КонецЕсли; + + ЭтоСсылочныйТипОбъекта = НЕ( ИмяТипаОбъекта = "РегистрСведений" + ИЛИ ИмяТипаОбъекта = "Константы" + ИЛИ ИмяТипаОбъекта = "Перечисление"); + + Если ЭтоСсылочныйТипОбъекта Тогда + + ПровестиГенерациюКодаНомераПриНеобходимости(ГенерироватьНовыйНомерИлиКодЕслиНеУказан, Объект, ИмяТипаОбъекта, НужноЗаписатьОбъект, ЗагружатьДанныеВРежимеОбмена); + + Если ПометкаУдаления = Неопределено Тогда + ПометкаУдаления = Ложь; + КонецЕсли; + + Если Объект.ПометкаУдаления <> ПометкаУдаления Тогда + Объект.ПометкаУдаления = ПометкаУдаления; + НужноЗаписатьОбъект = Истина; + КонецЕсли; + + КонецЕсли; + + // Непосредственная запись самого объекта. + Если НужноЗаписатьОбъект Тогда + + ЗаписатьОбъектВИБ(Объект, ТипОбъекта); + + КонецЕсли; + + Если ЭтоСсылочныйТипОбъекта Тогда + + ДобавитьСсылкуВСписокЗагруженныхОбъектов(НППГлобальнойСсылки, НППСсылки, Объект.Ссылка); + + КонецЕсли; + + УдалитьИзСтекаНеЗаписанныхОбъектов(НПП, ГНПП); + + КонецЕсли; + + Прервать; + + ИначеЕсли ИмяУзла = "НаборЗаписейПоследовательности" Тогда + + одПропустить(ФайлОбмена); + + ИначеЕсли ИмяУзла = "Типы" Тогда + + Если Объект = Неопределено Тогда + + ОбъектНайден = Ложь; + Ссылка = СоздатьНовыйОбъект(ТипОбъекта, СвойстваПоиска, Объект, , , , НППСсылки, НППГлобальнойСсылки, ПараметрыОбъекта); + + КонецЕсли; + + ОписаниеТиповОбъекта = ЗагрузитьТипыОбъекта(ФайлОбмена); + + Если ОписаниеТиповОбъекта <> Неопределено Тогда + + Объект.ТипЗначения = ОписаниеТиповОбъекта; + + КонецЕсли; + + Иначе + + ЗаписатьВПротоколВыполнения(9); + Прервать; + + КонецЕсли; + + КонецЦикла; + + Возврат Объект; + +КонецФункции + +// Выполняет проверку на наличие запрета загрузки по дате. +// +// Параметры: +// ЭлементДанных - СправочникОбъект, ДокументОбъект, РегистрСведенийНаборЗаписей и др. данные. +// Данные, которые были зачитаны из сообщения обмена, но еще не были записаны в ИБ. +// ПолучениеЭлемента - ПолучениеЭлементаДанных. +// +// Возвращаемое значение: +// Булево - Истина - установлена дата запрета изменения и загружаемый объект имеет дату меньше установленной, иначе Ложь. +// +Функция ЗапретИзмененияДанныхПоДате(ЭлементДанных) + + ИзменениеЗапрещено = Ложь; + + Если МодульДатыЗапретаИзменения <> Неопределено + И Не Метаданные.Константы.Содержит(ЭлементДанных.Метаданные()) Тогда + Попытка + Если МодульДатыЗапретаИзменения.ИзменениеЗапрещено(ЭлементДанных) Тогда + ИзменениеЗапрещено = Истина; + КонецЕсли; + Исключение + ИзменениеЗапрещено = Ложь; + КонецПопытки; + КонецЕсли; + + ЭлементДанных.ДополнительныеСвойства.Вставить("ПропуститьПроверкуЗапретаИзменения"); + + Возврат ИзменениеЗапрещено; + +КонецФункции + +Функция ПроверитьСуществованиеСсылки(Ссылка, Менеджер, НайденныйОбъектПоУникальномуИдентификатору, + СтрокаЗапросаПоискаПоУникальномуИдентификатору) + + Попытка + + Если ПустаяСтрока(СтрокаЗапросаПоискаПоУникальномуИдентификатору) Тогда + + НайденныйОбъектПоУникальномуИдентификатору = Ссылка.ПолучитьОбъект(); + + Если НайденныйОбъектПоУникальномуИдентификатору = Неопределено Тогда + + Возврат Менеджер.ПустаяСсылка(); + + КонецЕсли; + + Иначе + // Это режим поиска по ссылке - достаточно сделать запрос к информационной базе + // шаблон для запроса СтруктураСвойств.СтрокаПоиска. + + Запрос = Новый Запрос(); + Запрос.Текст = СтрокаЗапросаПоискаПоУникальномуИдентификатору + " Ссылка = &Ссылка "; + Запрос.УстановитьПараметр("Ссылка", Ссылка); + + РезультатЗапроса = Запрос.Выполнить(); + + Если РезультатЗапроса.Пустой() Тогда + + Возврат Менеджер.ПустаяСсылка(); + + КонецЕсли; + + КонецЕсли; + + Возврат Ссылка; + + Исключение + + Возврат Менеджер.ПустаяСсылка(); + + КонецПопытки; + +КонецФункции + +Функция ВычислитьВыражение(Знач Выражение) + + Если БезопасныйРежим Тогда + УстановитьБезопасныйРежим(Истина); + Для Каждого ИмяРазделителя Из РазделителиКонфигурации Цикл + УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина); + КонецЦикла; + КонецЕсли; + + // Вызов ВычислитьВБезопасномРежиме не требуется, т.к. безопасный режим устанавливается без использования средств БСП. + Возврат Вычислить(Выражение); + +КонецФункции + +Функция ЕстьРеквизитИлиСвойствоОбъекта(Объект, ИмяРеквизита) + + КлючУникальности = Новый УникальныйИдентификатор; + СтруктураРеквизита = Новый Структура(ИмяРеквизита, КлючУникальности); + ЗаполнитьЗначенияСвойств(СтруктураРеквизита, Объект); + + Возврат СтруктураРеквизита[ИмяРеквизита] <> КлючУникальности; + +КонецФункции + +// Параметры: +// Отбор - Отбор - произвольный отбор. +// КлючЭлемента - Строка - имя элемента отбора. +// ЗначениеЭлемента - Произвольный - значение элемента отбора. +// +Процедура УстановитьЗначениеЭлементаОтбора(Отбор, КлючЭлемента, ЗначениеЭлемента) + + ЭлементОтбора = Отбор.Найти(КлючЭлемента); + Если ЭлементОтбора <> Неопределено Тогда + ЭлементОтбора.Установить(ЗначениеЭлемента); + КонецЕсли; + +КонецПроцедуры + +#КонецОбласти + +#Область ПроцедурыВыгрузкиДанных + +Функция ПолучитьНаборДвиженийДокумента(СсылкаНаДокумент, ВидИсточника, ИмяРегистра) + + Если ВидИсточника = "НаборДвиженийРегистраНакопления" Тогда + + НаборДвиженийДокумента = РегистрыНакопления[ИмяРегистра].СоздатьНаборЗаписей(); + + ИначеЕсли ВидИсточника = "НаборДвиженийРегистраСведений" Тогда + + НаборДвиженийДокумента = РегистрыСведений[ИмяРегистра].СоздатьНаборЗаписей(); + + ИначеЕсли ВидИсточника = "НаборДвиженийРегистраБухгалтерии" Тогда + + НаборДвиженийДокумента = РегистрыБухгалтерии[ИмяРегистра].СоздатьНаборЗаписей(); + + ИначеЕсли ВидИсточника = "НаборДвиженийРегистраРасчета" Тогда + + НаборДвиженийДокумента = РегистрыРасчета[ИмяРегистра].СоздатьНаборЗаписей(); + + Иначе + + Возврат Неопределено; + + КонецЕсли; + + УстановитьЗначениеЭлементаОтбора(НаборДвиженийДокумента.Отбор, "Регистратор", СсылкаНаДокумент); + НаборДвиженийДокумента.Прочитать(); + + Возврат НаборДвиженийДокумента; + +КонецФункции + +Процедура ВыполнитьЗаписьСтруктурыВXML(СтруктураДанных, УзелКоллекцииСвойств) + + УзелКоллекцииСвойств.ЗаписатьНачалоЭлемента("Свойство"); + + Для Каждого ЭлементКоллекции Из СтруктураДанных Цикл + + Если ЭлементКоллекции.Ключ = "Выражение" + ИЛИ ЭлементКоллекции.Ключ = "Значение" + ИЛИ ЭлементКоллекции.Ключ = "Нпп" + ИЛИ ЭлементКоллекции.Ключ = "ГНпп" Тогда + + одЗаписатьЭлемент(УзелКоллекцииСвойств, ЭлементКоллекции.Ключ, ЭлементКоллекции.Значение); + + ИначеЕсли ЭлементКоллекции.Ключ = "Ссылка" Тогда + + УзелКоллекцииСвойств.ЗаписатьБезОбработки(ЭлементКоллекции.Значение); + + Иначе + + УстановитьАтрибут(УзелКоллекцииСвойств, ЭлементКоллекции.Ключ, ЭлементКоллекции.Значение); + + КонецЕсли; + + КонецЦикла; + + УзелКоллекцииСвойств.ЗаписатьКонецЭлемента(); + +КонецПроцедуры + +Процедура СоздатьОбъектыДляЗаписиДанныхВXML(СтруктураДанных, УзелСвойства, НуженУзелXML, ИмяУзла, НаименованиеУзлаXML = "Свойство") + + Если НуженУзелXML Тогда + + УзелСвойства = СоздатьУзел(НаименованиеУзлаXML); + УстановитьАтрибут(УзелСвойства, "Имя", ИмяУзла); + + Иначе + + СтруктураДанных = Новый Структура("Имя", ИмяУзла); + + КонецЕсли; + +КонецПроцедуры + +Процедура ДобавитьАтрибутДляЗаписиВXML(СтруктураУзлаСвойств, УзелСвойства, ИмяАтрибута, ЗначениеАтрибута) + + Если СтруктураУзлаСвойств <> Неопределено Тогда + СтруктураУзлаСвойств.Вставить(ИмяАтрибута, ЗначениеАтрибута); + Иначе + УстановитьАтрибут(УзелСвойства, ИмяАтрибута, ЗначениеАтрибута); + КонецЕсли; + +КонецПроцедуры + +Процедура ПроизвестиЗаписьДанныхВГоловнойУзел(УзелКоллекцииСвойств, СтруктураУзлаСвойств, УзелСвойства) + + Если СтруктураУзлаСвойств <> Неопределено Тогда + ВыполнитьЗаписьСтруктурыВXML(СтруктураУзлаСвойств, УзелКоллекцииСвойств); + Иначе + ДобавитьПодчиненный(УзелКоллекцииСвойств, УзелСвойства); + КонецЕсли; + +КонецПроцедуры + +// Формирует узлы свойств объекта приемника в соответствии с указанной коллекцией правил конвертации свойств. +// +// Параметры: +// Источник - произвольный источник данных. +// Приемник - xml-узел объекта приемника. +// ВходящиеДанные - произвольные вспомогательные данные, передаваемые правилу +// для выполнения конвертации. +// ИсходящиеДанные - произвольные вспомогательные данные, передаваемые правилам +// конвертации объектов свойств. +// ПКО - ссылка на правило конвертации объектов (родитель коллекции правил конвертации свойств). +// ПКГС - ссылка на правило конвертации группы свойств. +// УзелКоллекцииСвойств - xml-узел коллекции свойств. +// +Процедура ВыгрузитьГруппуСвойств(Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ПКО, ПКГС, УзелКоллекцииСвойств, + ВыгрузитьТолькоСсылку, СписокВременныхФайлов = Неопределено) + + Если БезопасныйРежим Тогда + УстановитьБезопасныйРежим(Истина); + Для Каждого ИмяРазделителя Из РазделителиКонфигурации Цикл + УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина); + КонецЦикла; + КонецЕсли; + + КоллекцияОбъектов = Неопределено; + НеЗамещать = ПКГС.НеЗамещать; + НеОчищать = Ложь; + ВыгружатьГруппуЧерезФайл = ПКГС.ВыгружатьГруппуЧерезФайл; + + // Обработчик ПередОбработкойВыгрузки + Если ПКГС.ЕстьОбработчикПередОбработкойВыгрузки Тогда + + Отказ = Ложь; + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(ПКГС, "ПередОбработкойВыгрузки")); + + Иначе + + Выполнить(ПКГС.ПередОбработкойВыгрузки); + + КонецЕсли; + + Исключение + + ЗаписатьИнформациюОбОшибкеОбработчикиПКС(48, ОписаниеОшибки(), ПКО, ПКГС, + Источник, "ПередОбработкойВыгрузкиГруппыСвойств",, Ложь); + + КонецПопытки; + + Если Отказ Тогда // Отказ от обработки группы свойств. + + Возврат; + + КонецЕсли; + + КонецЕсли; + + + ВидПриемника = ПКГС.ВидПриемника; + ВидИсточника = ПКГС.ВидИсточника; + + + // Создание узла коллекции подчиненных объектов. + СтруктураУзлаСвойств = Неопределено; + УзелКоллекцииОбъектов = Неопределено; + ИмяГоловногоУзла = ""; + + Если ВидПриемника = "ТабличнаяЧасть" Тогда + + ИмяГоловногоУзла = "ТабличнаяЧасть"; + + СоздатьОбъектыДляЗаписиДанныхВXML(СтруктураУзлаСвойств, УзелКоллекцииОбъектов, ИСТИНА, ПКГС.Приемник, ИмяГоловногоУзла); + + Если НеЗамещать Тогда + + ДобавитьАтрибутДляЗаписиВXML(СтруктураУзлаСвойств, УзелКоллекцииОбъектов, "НеЗамещать", "true"); + + КонецЕсли; + + Если НеОчищать Тогда + + ДобавитьАтрибутДляЗаписиВXML(СтруктураУзлаСвойств, УзелКоллекцииОбъектов, "НеОчищать", "true"); + + КонецЕсли; + + ИначеЕсли ВидПриемника = "ПодчиненныйСправочник" Тогда + + + ИначеЕсли ВидПриемника = "НаборЗаписейПоследовательности" Тогда + + ИмяГоловногоУзла = "НаборЗаписей"; + + СоздатьОбъектыДляЗаписиДанныхВXML(СтруктураУзлаСвойств, УзелКоллекцииОбъектов, ИСТИНА, ПКГС.Приемник, ИмяГоловногоУзла); + + ИначеЕсли СтрНайти(ВидПриемника, "НаборДвижений") > 0 Тогда + + ИмяГоловногоУзла = "НаборЗаписей"; + + СоздатьОбъектыДляЗаписиДанныхВXML(СтруктураУзлаСвойств, УзелКоллекцииОбъектов, ИСТИНА, ПКГС.Приемник, ИмяГоловногоУзла); + + Если НеЗамещать Тогда + + ДобавитьАтрибутДляЗаписиВXML(СтруктураУзлаСвойств, УзелКоллекцииОбъектов, "НеЗамещать", "true"); + + КонецЕсли; + + Если НеОчищать Тогда + + ДобавитьАтрибутДляЗаписиВXML(СтруктураУзлаСвойств, УзелКоллекцииОбъектов, "НеОчищать", "true"); + + КонецЕсли; + + Иначе // это простая группировка + + ВыгрузитьСвойства(Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ПКО, ПКГС.ПравилаГруппы, + УзелКоллекцииСвойств, , , ПКО.НеВыгружатьОбъектыСвойствПоСсылкам ИЛИ ВыгрузитьТолькоСсылку); + + Если ПКГС.ЕстьОбработчикПослеОбработкиВыгрузки Тогда + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(ПКГС, "ПослеОбработкиВыгрузки")); + + Иначе + + Выполнить(ПКГС.ПослеОбработкиВыгрузки); + + КонецЕсли; + + Исключение + + ЗаписатьИнформациюОбОшибкеОбработчикиПКС(49, ОписаниеОшибки(), ПКО, ПКГС, + Источник, "ПослеОбработкиВыгрузкиГруппыСвойств",, Ложь); + + КонецПопытки; + + КонецЕсли; + + Возврат; + + КонецЕсли; + + // Получение коллекции подчиненных объектов. + + Если КоллекцияОбъектов <> Неопределено Тогда + + // Инициализировали коллекцию в обработчике ПередОбработкой. + + ИначеЕсли ПКГС.ПолучитьИзВходящихДанных Тогда + + Попытка + + КоллекцияОбъектов = ВходящиеДанные[ПКГС.Приемник]; + + Если ТипЗнч(КоллекцияОбъектов) = Тип("РезультатЗапроса") Тогда + + КоллекцияОбъектов = КоллекцияОбъектов.Выгрузить(); + + КонецЕсли; + + Исключение + + ЗаписатьИнформациюОбОшибкеОбработчикиПКС(66, ОписаниеОшибки(), ПКО, ПКГС, Источник,,,Ложь); + + Возврат; + КонецПопытки; + + ИначеЕсли ВидИсточника = "ТабличнаяЧасть" Тогда + + КоллекцияОбъектов = Источник[ПКГС.Источник]; + + Если ТипЗнч(КоллекцияОбъектов) = Тип("РезультатЗапроса") Тогда + + КоллекцияОбъектов = КоллекцияОбъектов.Выгрузить(); + + КонецЕсли; + + ИначеЕсли ВидИсточника = "ПодчиненныйСправочник" Тогда + + ИначеЕсли СтрНайти(ВидИсточника, "НаборДвижений") > 0 Тогда + + КоллекцияОбъектов = ПолучитьНаборДвиженийДокумента(Источник, ВидИсточника, ПКГС.Источник); + + ИначеЕсли ПустаяСтрока(ПКГС.Источник) Тогда + + КоллекцияОбъектов = Источник[ПКГС.Приемник]; + + Если ТипЗнч(КоллекцияОбъектов) = Тип("РезультатЗапроса") Тогда + + КоллекцияОбъектов = КоллекцияОбъектов.Выгрузить(); + + КонецЕсли; + + КонецЕсли; + + ВыгружатьГруппуЧерезФайл = ВыгружатьГруппуЧерезФайл Или (КоллекцияОбъектов.Количество() > 1000); + ВыгружатьГруппуЧерезФайл = ВыгружатьГруппуЧерезФайл И (НепосредственноеЧтениеВИБПриемнике = Ложь); + + Если ВыгружатьГруппуЧерезФайл Тогда + + ПКГС.НуженУзелXMLПриВыгрузке = Ложь; + + Если СписокВременныхФайлов = Неопределено Тогда + СписокВременныхФайлов = Новый Массив; + КонецЕсли; + + ВременныйФайлЗаписей = ЗаписьТекстаВоВременныйФайл(СписокВременныхФайлов); + + ИнформацияДляЗаписиВФайл = УзелКоллекцииОбъектов.Закрыть(); + ВременныйФайлЗаписей.ЗаписатьСтроку(ИнформацияДляЗаписиВФайл); + + КонецЕсли; + + Для Каждого ОбъектКоллекции Из КоллекцияОбъектов Цикл + + // Обработчик ПередВыгрузкой + Если ПКГС.ЕстьОбработчикПередВыгрузкой Тогда + + Отказ = Ложь; + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(ПКГС, "ПередВыгрузкой")); + + Иначе + + Выполнить(ПКГС.ПередВыгрузкой); + + КонецЕсли; + + Исключение + + ЗаписатьИнформациюОбОшибкеОбработчикиПКС(50, ОписаниеОшибки(), ПКО, ПКГС, + Источник, "ПередВыгрузкойГруппыСвойств",, Ложь); + + Прервать; + + КонецПопытки; + + Если Отказ Тогда // Отказ от выгрузки подчиненного объекта. + + Продолжить; + + КонецЕсли; + + КонецЕсли; + + // Обработчик ПриВыгрузке + + Если ПКГС.НуженУзелXMLПриВыгрузке ИЛИ ВыгружатьГруппуЧерезФайл Тогда + УзелОбъектаКоллекции = СоздатьУзел("Запись"); + Иначе + УзелКоллекцииОбъектов.ЗаписатьНачалоЭлемента("Запись"); + УзелОбъектаКоллекции = УзелКоллекцииОбъектов; + КонецЕсли; + + СтандартнаяОбработка = Истина; + + Если ПКГС.ЕстьОбработчикПриВыгрузке Тогда + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(ПКГС, "ПриВыгрузке")); + + Иначе + + Выполнить(ПКГС.ПриВыгрузке); + + КонецЕсли; + + Исключение + + ЗаписатьИнформациюОбОшибкеОбработчикиПКС(51, ОписаниеОшибки(), ПКО, ПКГС, + Источник, "ПриВыгрузкеГруппыСвойств",, Ложь); + + Прервать; + + КонецПопытки; + + КонецЕсли; + + // Выгрузка свойств объекта коллекции. + + Если СтандартнаяОбработка Тогда + + Если ПКГС.ПравилаГруппы.Количество() > 0 Тогда + + ВыгрузитьСвойства(Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ПКО, ПКГС.ПравилаГруппы, + УзелОбъектаКоллекции, ОбъектКоллекции, , ПКО.НеВыгружатьОбъектыСвойствПоСсылкам ИЛИ ВыгрузитьТолькоСсылку); + + КонецЕсли; + + КонецЕсли; + + // Обработчик ПослеВыгрузки + + Если ПКГС.ЕстьОбработчикПослеВыгрузки Тогда + + Отказ = Ложь; + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(ПКГС, "ПослеВыгрузки")); + + Иначе + + Выполнить(ПКГС.ПослеВыгрузки); + + КонецЕсли; + + Исключение + + ЗаписатьИнформациюОбОшибкеОбработчикиПКС(52, ОписаниеОшибки(), ПКО, ПКГС, + Источник, "ПослеВыгрузкиГруппыСвойств",, Ложь); + + Прервать; + КонецПопытки; + + Если Отказ Тогда // Отказ от выгрузки подчиненного объекта. + + Продолжить; + + КонецЕсли; + + КонецЕсли; + + Если ПКГС.НуженУзелXMLПриВыгрузке Тогда + ДобавитьПодчиненный(УзелКоллекцииОбъектов, УзелОбъектаКоллекции); + КонецЕсли; + + // Заполняем файл объектами узла. + Если ВыгружатьГруппуЧерезФайл Тогда + + УзелОбъектаКоллекции.ЗаписатьКонецЭлемента(); + ИнформацияДляЗаписиВФайл = УзелОбъектаКоллекции.Закрыть(); + ВременныйФайлЗаписей.ЗаписатьСтроку(ИнформацияДляЗаписиВФайл); + + Иначе + + Если Не ПКГС.НуженУзелXMLПриВыгрузке Тогда + + УзелКоллекцииОбъектов.ЗаписатьКонецЭлемента(); + + КонецЕсли; + + КонецЕсли; + + КонецЦикла; + + + // Обработчик ПослеОбработкиВыгрузки + + Если ПКГС.ЕстьОбработчикПослеОбработкиВыгрузки Тогда + + Отказ = Ложь; + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(ПКГС, "ПослеОбработкиВыгрузки")); + + Иначе + + Выполнить(ПКГС.ПослеОбработкиВыгрузки); + + КонецЕсли; + + Исключение + + ЗаписатьИнформациюОбОшибкеОбработчикиПКС(49, ОписаниеОшибки(), ПКО, ПКГС, + Источник, "ПослеОбработкиВыгрузкиГруппыСвойств",, Ложь); + + КонецПопытки; + + Если Отказ Тогда // Отказ от записи коллекции подчиненных объектов. + + Возврат; + + КонецЕсли; + + КонецЕсли; + + Если ВыгружатьГруппуЧерезФайл Тогда + ВременныйФайлЗаписей.ЗаписатьСтроку("" + ИмяГоловногоУзла + ">"); // закрыть узел + ВременныйФайлЗаписей.Закрыть(); // закрыть файл явно + Иначе + ПроизвестиЗаписьДанныхВГоловнойУзел(УзелКоллекцииСвойств, СтруктураУзлаСвойств, УзелКоллекцииОбъектов); + КонецЕсли; + +КонецПроцедуры + +Процедура ПолучитьЗначениеСвойства(Значение, ОбъектКоллекции, ПКО, ПКС, ВходящиеДанные, Источник) + + Если Значение <> Неопределено Тогда + Возврат; + КонецЕсли; + + Если ПКС.ПолучитьИзВходящихДанных Тогда + + ОбъектДляПолученияДанных = ВходящиеДанные; + + Если Не ПустаяСтрока(ПКС.Приемник) Тогда + + ИмяСвойства = ПКС.Приемник; + + Иначе + + ИмяСвойства = ПКС.ИмяПараметраДляПередачи; + + КонецЕсли; + + КодОшибки = ?(ОбъектКоллекции <> Неопределено, 67, 68); + + ИначеЕсли ОбъектКоллекции <> Неопределено Тогда + + ОбъектДляПолученияДанных = ОбъектКоллекции; + + Если Не ПустаяСтрока(ПКС.Источник) Тогда + + ИмяСвойства = ПКС.Источник; + КодОшибки = 16; + + Иначе + + ИмяСвойства = ПКС.Приемник; + КодОшибки = 17; + + КонецЕсли; + + Иначе + + ОбъектДляПолученияДанных = Источник; + + Если Не ПустаяСтрока(ПКС.Источник) Тогда + + ИмяСвойства = ПКС.Источник; + КодОшибки = 13; + + Иначе + + ИмяСвойства = ПКС.Приемник; + КодОшибки = 14; + + КонецЕсли; + + КонецЕсли; + + Попытка + + Значение = ОбъектДляПолученияДанных[ИмяСвойства]; + + Исключение + + Если КодОшибки <> 14 Тогда + ЗаписатьИнформациюОбОшибкеОбработчикиПКС(КодОшибки, ОписаниеОшибки(), ПКО, ПКС, Источник, ""); + КонецЕсли; + + КонецПопытки; + +КонецПроцедуры + +Процедура ВыгрузитьТипСвойстваЭлемента(УзелСвойства, ТипСвойства) + + УстановитьАтрибут(УзелСвойства, "Тип", ТипСвойства); + +КонецПроцедуры + +Процедура ВыгрузитьСубконто(Источник, + Приемник, + ВходящиеДанные, + ИсходящиеДанные, + ПКО, + ПКС, + УзелКоллекцииСвойств , + ОбъектКоллекции, + Знач ВыгрузитьТолькоСсылку) + + // + // Переменные-заглушки для поддержки механизма отладки кода обработчиков событий + // (поддержка интерфейса процедуры-обертки обработчика). + Перем ТипПриемника, Пусто, Выражение, НеЗамещать, УзелСвойства, ПКОСвойств; + + Если БезопасныйРежим Тогда + УстановитьБезопасныйРежим(Истина); + Для Каждого ИмяРазделителя Из РазделителиКонфигурации Цикл + УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина); + КонецЦикла; + КонецЕсли; + + // Инициализация значения + Значение = Неопределено; + ИмяПКО = ""; + ИмяПКОВидСубконто = ""; + + // Обработчик ПередВыгрузкой + Если ПКС.ЕстьОбработчикПередВыгрузкой Тогда + + Отказ = Ложь; + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(ПКС, "ПередВыгрузкой")); + + Иначе + + Выполнить(ПКС.ПередВыгрузкой); + + КонецЕсли; + + Исключение + + ЗаписатьИнформациюОбОшибкеОбработчикиПКС(55, ОписаниеОшибки(), ПКО, ПКС, Источник, + "ПередВыгрузкойСвойства", Значение); + + КонецПопытки; + + Если Отказ Тогда // Отказ от выгрузки + + Возврат; + + КонецЕсли; + + КонецЕсли; + + ПолучитьЗначениеСвойства(Значение, ОбъектКоллекции, ПКО, ПКС, ВходящиеДанные, Источник); + + Если ПКС.ПриводитьКДлине <> 0 Тогда + + ВыполнитьПриведениеЗначенияКДлине(Значение, ПКС); + + КонецЕсли; + + Для каждого КлючИЗначение Из Значение Цикл + + ВидСубконто = КлючИЗначение.Ключ; + Субконто = КлючИЗначение.Значение; + ИмяПКО = ""; + + // Обработчик ПриВыгрузке + Если ПКС.ЕстьОбработчикПриВыгрузке Тогда + + Отказ = Ложь; + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(ПКС, "ПриВыгрузке")); + + Иначе + + Выполнить(ПКС.ПриВыгрузке); + + КонецЕсли; + + Исключение + + ЗаписатьИнформациюОбОшибкеОбработчикиПКС(56, ОписаниеОшибки(), ПКО, ПКС, Источник, + "ПриВыгрузкеСвойства", Значение); + + КонецПопытки; + + Если Отказ Тогда // Отказ от выгрузки субконто + + Продолжить; + + КонецЕсли; + + КонецЕсли; + + Если Субконто = Неопределено + ИЛИ НайтиПравило(Субконто, ИмяПКО) = Неопределено Тогда + + Продолжить; + + КонецЕсли; + + УзелСубконто = СоздатьУзел(ПКС.Приемник); + + // Ключ + УзелСвойства = СоздатьУзел("Свойство"); + + Если ПустаяСтрока(ИмяПКОВидСубконто) Тогда + + ПКОКлюч = НайтиПравило(ВидСубконто, ИмяПКОВидСубконто); + + Иначе + + ПКОКлюч = НайтиПравило(, ИмяПКОВидСубконто); + + КонецЕсли; + + УстановитьАтрибут(УзелСвойства, "Имя", "Ключ"); + ВыгрузитьТипСвойстваЭлемента(УзелСвойства, ПКОКлюч.Приемник); + + УзелСсылки = ВыгрузитьПоПравилу(ВидСубконто,, ИсходящиеДанные,, ИмяПКОВидСубконто,, ВыгрузитьТолькоСсылку, ПКОКлюч); + + Если УзелСсылки <> Неопределено Тогда + + ЭтоПравилоСГлобальнойВыгрузкой = Ложь; + ТипУзлаСсылки = ТипЗнч(УзелСсылки); + ДобавитьСвойстваДляВыгрузки(УзелСсылки, ТипУзлаСсылки, УзелСвойства, ЭтоПравилоСГлобальнойВыгрузкой); + + КонецЕсли; + + ДобавитьПодчиненный(УзелСубконто, УзелСвойства); + + // Значение + УзелСвойства = СоздатьУзел("Свойство"); + + ПКОЗначение = НайтиПравило(Субконто, ИмяПКО); + + ТипПриемника = ПКОЗначение.Приемник; + + ЭтоNULL = Ложь; + Пусто = одПустое(Субконто, ЭтоNULL); + + Если Пусто Тогда + + Если ЭтоNULL + Или Субконто = Неопределено Тогда + + Продолжить; + + КонецЕсли; + + Если ПустаяСтрока(ТипПриемника) Тогда + + ТипПриемника = ОпределитьТипДанныхДляПриемника(Субконто); + + КонецЕсли; + + УстановитьАтрибут(УзелСвойства, "Имя", "Значение"); + + Если Не ПустаяСтрока(ТипПриемника) Тогда + УстановитьАтрибут(УзелСвойства, "Тип", ТипПриемника); + КонецЕсли; + + // Если тип множественный, то возможно это пустая ссылка и выгрузить ее нужно именно с указанием типа. + одЗаписатьЭлемент(УзелСвойства, "Пусто"); + + ДобавитьПодчиненный(УзелСубконто, УзелСвойства); + + Иначе + + ЭтоПравилоСГлобальнойВыгрузкой = Ложь; + УзелСсылки = ВыгрузитьПоПравилу(Субконто,, ИсходящиеДанные, , ИмяПКО, , ВыгрузитьТолькоСсылку, ПКОЗначение, ЭтоПравилоСГлобальнойВыгрузкой); + + УстановитьАтрибут(УзелСвойства, "Имя", "Значение"); + ВыгрузитьТипСвойстваЭлемента(УзелСвойства, ТипПриемника); + + Если УзелСсылки = Неопределено Тогда + + Продолжить; + + КонецЕсли; + + ТипУзлаСсылки = ТипЗнч(УзелСсылки); + + ДобавитьСвойстваДляВыгрузки(УзелСсылки, ТипУзлаСсылки, УзелСвойства, ЭтоПравилоСГлобальнойВыгрузкой); + + ДобавитьПодчиненный(УзелСубконто, УзелСвойства); + + КонецЕсли; + + // Обработчик ПослеВыгрузки + Если ПКС.ЕстьОбработчикПослеВыгрузки Тогда + + Отказ = Ложь; + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(ПКС, "ПослеВыгрузки")); + + Иначе + + Выполнить(ПКС.ПослеВыгрузки); + + КонецЕсли; + + Исключение + + ЗаписатьИнформациюОбОшибкеОбработчикиПКС(57, ОписаниеОшибки(), ПКО, ПКС, Источник, + "ПослеВыгрузкиСвойства", Значение); + + КонецПопытки; + + Если Отказ Тогда // Отказ от выгрузки + + Продолжить; + + КонецЕсли; + + КонецЕсли; + + ДобавитьПодчиненный(УзелКоллекцииСвойств, УзелСубконто); + + КонецЦикла; + +КонецПроцедуры + +Процедура ДобавитьСвойстваДляВыгрузки(УзелСсылки, ТипУзлаСсылки, УзелСвойства, ЭтоПравилоСГлобальнойВыгрузкой) + + Если ТипУзлаСсылки = одТипСтрока Тогда + + Если СтрНайти(УзелСсылки, "<Ссылка") > 0 Тогда + + УзелСвойства.ЗаписатьБезОбработки(УзелСсылки); + + Иначе + + одЗаписатьЭлемент(УзелСвойства, "Значение", УзелСсылки); + + КонецЕсли; + + ИначеЕсли ТипУзлаСсылки = одТипЧисло Тогда + + Если ЭтоПравилоСГлобальнойВыгрузкой Тогда + + одЗаписатьЭлемент(УзелСвойства, "ГНпп", УзелСсылки); + + Иначе + + одЗаписатьЭлемент(УзелСвойства, "Нпп", УзелСсылки); + + КонецЕсли; + + Иначе + + ДобавитьПодчиненный(УзелСвойства, УзелСсылки); + + КонецЕсли; + +КонецПроцедуры + +Процедура ДобавитьЗначениеСвойстваВУзел(Значение, ТипЗначения, ТипПриемника, УзелСвойства, СвойствоУстановлено) + + СвойствоУстановлено = Истина; + + Если ТипЗначения = одТипСтрока Тогда + + Если ТипПриемника = "Строка" Тогда + ИначеЕсли ТипПриемника = "Число" Тогда + + Значение = Число(Значение); + + ИначеЕсли ТипПриемника = "Булево" Тогда + + Значение = Булево(Значение); + + ИначеЕсли ТипПриемника = "Дата" Тогда + + Значение = Дата(Значение); + + ИначеЕсли ТипПриемника = "ХранилищеЗначения" Тогда + + Значение = Новый ХранилищеЗначения(Значение); + + ИначеЕсли ТипПриемника = "УникальныйИдентификатор" Тогда + + Значение = Новый УникальныйИдентификатор(Значение); + + ИначеЕсли ПустаяСтрока(ТипПриемника) Тогда + + УстановитьАтрибут(УзелСвойства, "Тип", "Строка"); + + КонецЕсли; + + одЗаписатьЭлемент(УзелСвойства, "Значение", Значение); + + ИначеЕсли ТипЗначения = одТипЧисло Тогда + + Если ТипПриемника = "Число" Тогда + ИначеЕсли ТипПриемника = "Булево" Тогда + + Значение = Булево(Значение); + + ИначеЕсли ТипПриемника = "Строка" Тогда + ИначеЕсли ПустаяСтрока(ТипПриемника) Тогда + + УстановитьАтрибут(УзелСвойства, "Тип", "Число"); + + Иначе + + Возврат; + + КонецЕсли; + + одЗаписатьЭлемент(УзелСвойства, "Значение", Значение); + + ИначеЕсли ТипЗначения = одТипДата Тогда + + Если ТипПриемника = "Дата" Тогда + ИначеЕсли ТипПриемника = "Строка" Тогда + + Значение = Лев(Строка(Значение), 10); + + ИначеЕсли ПустаяСтрока(ТипПриемника) Тогда + + УстановитьАтрибут(УзелСвойства, "Тип", "Дата"); + + Иначе + + Возврат; + + КонецЕсли; + + одЗаписатьЭлемент(УзелСвойства, "Значение", Значение); + + ИначеЕсли ТипЗначения = одТипБулево Тогда + + Если ТипПриемника = "Булево" Тогда + ИначеЕсли ТипПриемника = "Число" Тогда + + Значение = Число(Значение); + + ИначеЕсли ПустаяСтрока(ТипПриемника) Тогда + + УстановитьАтрибут(УзелСвойства, "Тип", "Булево"); + + Иначе + + Возврат; + + КонецЕсли; + + одЗаписатьЭлемент(УзелСвойства, "Значение", Значение); + + ИначеЕсли ТипЗначения = одТипХранилищеЗначения Тогда + + Если ПустаяСтрока(ТипПриемника) Тогда + + УстановитьАтрибут(УзелСвойства, "Тип", "ХранилищеЗначения"); + + ИначеЕсли ТипПриемника <> "ХранилищеЗначения" Тогда + + Возврат; + + КонецЕсли; + + одЗаписатьЭлемент(УзелСвойства, "Значение", Значение); + + ИначеЕсли ТипЗначения = одТипУникальныйИдентификатор Тогда + + Если ТипПриемника = "УникальныйИдентификатор" Тогда + ИначеЕсли ТипПриемника = "Строка" Тогда + + Значение = Строка(Значение); + + ИначеЕсли ПустаяСтрока(ТипПриемника) Тогда + + УстановитьАтрибут(УзелСвойства, "Тип", "УникальныйИдентификатор"); + + Иначе + + Возврат; + + КонецЕсли; + + одЗаписатьЭлемент(УзелСвойства, "Значение", Значение); + + ИначеЕсли ТипЗначения = одТипВидДвиженияНакопления Тогда + + одЗаписатьЭлемент(УзелСвойства, "Значение", Строка(Значение)); + + Иначе + + СвойствоУстановлено = Ложь; + + КонецЕсли; + +КонецПроцедуры + +Функция ВыгрузитьДанныеСсылочногоОбъекта(Значение, ИсходящиеДанные, ИмяПКО, ПКОСвойств, ТипПриемника, УзелСвойства, Знач ВыгрузитьТолькоСсылку) + + ЭтоПравилоСГлобальнойВыгрузкой = Ложь; + УзелСсылки = ВыгрузитьПоПравилу(Значение, , ИсходящиеДанные, , ИмяПКО, , ВыгрузитьТолькоСсылку, ПКОСвойств, ЭтоПравилоСГлобальнойВыгрузкой); + ТипУзлаСсылки = ТипЗнч(УзелСсылки); + + Если ПустаяСтрока(ТипПриемника) Тогда + + ТипПриемника = ПКОСвойств.Приемник; + УстановитьАтрибут(УзелСвойства, "Тип", ТипПриемника); + + КонецЕсли; + + Если УзелСсылки = Неопределено Тогда + + Возврат Неопределено; + + КонецЕсли; + + ДобавитьСвойстваДляВыгрузки(УзелСсылки, ТипУзлаСсылки, УзелСвойства, ЭтоПравилоСГлобальнойВыгрузкой); + + Возврат УзелСсылки; + +КонецФункции + +Функция ОпределитьТипДанныхДляПриемника(Значение) + + ТипПриемника = одТипЗначенияСтрокой(Значение); + + // Есть ли хоть какое ПКО с типом приемника ТипПриемника + // если правила нет - то "", если есть , то то что нашли оставляем. + СтрокаТаблицы = ТаблицаПравилКонвертации.Найти(ТипПриемника, "Приемник"); + + Если СтрокаТаблицы = Неопределено Тогда + ТипПриемника = ""; + КонецЕсли; + + Возврат ТипПриемника; + +КонецФункции + +Процедура ВыполнитьПриведениеЗначенияКДлине(Значение, ПКС) + + Значение = ПривестиНомерКДлине(Строка(Значение), ПКС.ПриводитьКДлине); + +КонецПроцедуры + +// Формирует узлы свойств объекта приемника в соответствии с указанной коллекцией правил конвертации свойств. +// +// Параметры: +// Источник - Произвольный - произвольный источник данных. +// Приемник - ЗаписьXML - xml-узел объекта приемника. +// ВходящиеДанные - Произвольный - произвольные вспомогательные данные, передаваемые правилу +// для выполнения конвертации. +// ИсходящиеДанные - Произвольный - произвольные вспомогательные данные, передаваемые правилам +// конвертации объектов свойств. +// ПКО - СтрокаТаблицыЗначений - ссылка на правило конвертации объектов. +// КоллекцияПКС - см. КоллекцияПравилаКонвертацииСвойств +// УзелКоллекцииСвойств - ЗаписьXML - xml-узел коллекции свойств. +// ОбъектКоллекции - Произвольный - если указан, то выполняется выгрузка свойств объекта коллекции, иначе Источника. +// ИмяПредопределенногоЭлемента - Строка - если указан, то в свойствах пишется имя предопределенного элемента. +// ПКГС - ссылка на правило конвертации группы свойств (папка-родитель коллекции ПКС). +// Например, табличная часть документа. +// +Процедура ВыгрузитьСвойства(Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ПКО, КоллекцияПКС, УзелКоллекцииСвойств = Неопределено, + ОбъектКоллекции = Неопределено, ИмяПредопределенногоЭлемента = Неопределено, Знач ВыгрузитьТолькоСсылку = Ложь, + СписокВременныхФайлов = Неопределено) + + Перем КлючИЗначение, ВидСубконто, Субконто, ИмяПКОВидСубконто, УзелСубконто; // Пустышки, для корректного запуска + // обработчиков. + + Если УзелКоллекцииСвойств = Неопределено Тогда + + УзелКоллекцииСвойств = Приемник; + + КонецЕсли; + + // Выгружаем имя предопределенного если оно указано. + Если ИмяПредопределенногоЭлемента <> Неопределено Тогда + + УзелКоллекцииСвойств.ЗаписатьНачалоЭлемента("Свойство"); + УстановитьАтрибут(УзелКоллекцииСвойств, "Имя", "{ИмяПредопределенногоЭлемента}"); + Если НЕ ВыполнитьОбменДаннымиВОптимизированномФормате Тогда + УстановитьАтрибут(УзелКоллекцииСвойств, "Тип", "Строка"); + КонецЕсли; + одЗаписатьЭлемент(УзелКоллекцииСвойств, "Значение", ИмяПредопределенногоЭлемента); + УзелКоллекцииСвойств.ЗаписатьКонецЭлемента(); + + КонецЕсли; + + Для каждого ПКС Из КоллекцияПКС Цикл + + Если ПКС.УпрощеннаяВыгрузкаСвойства Тогда + + // Создаем узел свойства + + УзелКоллекцииСвойств.ЗаписатьНачалоЭлемента("Свойство"); + УстановитьАтрибут(УзелКоллекцииСвойств, "Имя", ПКС.Приемник); + + Если НЕ ВыполнитьОбменДаннымиВОптимизированномФормате + И Не ПустаяСтрока(ПКС.ТипПриемника) Тогда + + УстановитьАтрибут(УзелКоллекцииСвойств, "Тип", ПКС.ТипПриемника); + + КонецЕсли; + + Если ПКС.НеЗамещать Тогда + + УстановитьАтрибут(УзелКоллекцииСвойств, "НеЗамещать", "true"); + + КонецЕсли; + + Если ПКС.ПоискПоДатеНаРавенство Тогда + + УстановитьАтрибут(УзелКоллекцииСвойств, "ПоискПоДатеНаРавенство", "true"); + + КонецЕсли; + + Значение = Неопределено; + ПолучитьЗначениеСвойства(Значение, ОбъектКоллекции, ПКО, ПКС, ВходящиеДанные, Источник); + + Если ПКС.ПриводитьКДлине <> 0 Тогда + + ВыполнитьПриведениеЗначенияКДлине(Значение, ПКС); + + КонецЕсли; + + ЭтоNULL = Ложь; + Пусто = одПустое(Значение, ЭтоNULL); + + Если Пусто Тогда + + // Надо записать что это пустое значение. + Если НЕ ВыполнитьОбменДаннымиВОптимизированномФормате Тогда + одЗаписатьЭлемент(УзелКоллекцииСвойств, "Пусто"); + КонецЕсли; + + УзелКоллекцииСвойств.ЗаписатьКонецЭлемента(); + Продолжить; + + КонецЕсли; + + одЗаписатьЭлемент(УзелКоллекцииСвойств, "Значение", Значение); + + УзелКоллекцииСвойств.ЗаписатьКонецЭлемента(); + Продолжить; + + ИначеЕсли ПКС.ВидПриемника = "ВидыСубконтоСчета" Тогда + + ВыгрузитьСубконто(Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ПКО, + ПКС, УзелКоллекцииСвойств, ОбъектКоллекции, ВыгрузитьТолькоСсылку); + + Продолжить; + + ИначеЕсли ПКС.Имя = "{УникальныйИдентификатор}" + И ПКС.Источник = "{УникальныйИдентификатор}" + И ПКС.Приемник = "{УникальныйИдентификатор}" Тогда + + Если Источник = Неопределено Тогда + Продолжить; + КонецЕсли; + + Если ЗначениеСсылочногоТипа(Источник) Тогда + УникальныйИдентификатор = Источник.УникальныйИдентификатор(); + Иначе + + НачальноеЗначение = Новый УникальныйИдентификатор(); + СтруктураДляПроверкиНаличияСвойства = Новый Структура("Ссылка", НачальноеЗначение); + ЗаполнитьЗначенияСвойств(СтруктураДляПроверкиНаличияСвойства, Источник); + + Если НачальноеЗначение <> СтруктураДляПроверкиНаличияСвойства.Ссылка + И ЗначениеСсылочногоТипа(СтруктураДляПроверкиНаличияСвойства.Ссылка) Тогда + УникальныйИдентификатор = Источник.Ссылка.УникальныйИдентификатор(); + КонецЕсли; + + КонецЕсли; + + УзелКоллекцииСвойств.ЗаписатьНачалоЭлемента("Свойство"); + УстановитьАтрибут(УзелКоллекцииСвойств, "Имя", "{УникальныйИдентификатор}"); + + Если НЕ ВыполнитьОбменДаннымиВОптимизированномФормате Тогда + УстановитьАтрибут(УзелКоллекцииСвойств, "Тип", "Строка"); + КонецЕсли; + + одЗаписатьЭлемент(УзелКоллекцииСвойств, "Значение", УникальныйИдентификатор); + УзелКоллекцииСвойств.ЗаписатьКонецЭлемента(); + Продолжить; + + ИначеЕсли ПКС.ЭтоГруппа Тогда + + ВыгрузитьГруппуСвойств(Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ПКО, ПКС, УзелКоллекцииСвойств, ВыгрузитьТолькоСсылку, СписокВременныхФайлов); + Продолжить; + + КонецЕсли; + + + // Инициализируем значение, которое будем конвертировать. + Значение = Неопределено; + ИмяПКО = ПКС.ПравилоКонвертации; + НеЗамещать = ПКС.НеЗамещать; + + Пусто = Ложь; + Выражение = Неопределено; + ТипПриемника = ПКС.ТипПриемника; + + ЭтоNULL = Ложь; + + + // Обработчик ПередВыгрузкой + Если ПКС.ЕстьОбработчикПередВыгрузкой Тогда + + Отказ = Ложь; + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(ПКС, "ПередВыгрузкой")); + + Иначе + + Выполнить(ПКС.ПередВыгрузкой); + + КонецЕсли; + + Исключение + + ЗаписатьИнформациюОбОшибкеОбработчикиПКС(55, ОписаниеОшибки(), ПКО, ПКС, Источник, + "ПередВыгрузкойСвойства", Значение); + + КонецПопытки; + + Если Отказ Тогда // Отказ от выгрузки свойства + + Продолжить; + + КонецЕсли; + + КонецЕсли; + + + // Создаем узел свойства + Если ПустаяСтрока(ПКС.ИмяПараметраДляПередачи) Тогда + + УзелСвойства = СоздатьУзел("Свойство"); + УстановитьАтрибут(УзелСвойства, "Имя", ПКС.Приемник); + + Иначе + + УзелСвойства = СоздатьУзел("ЗначениеПараметра"); + УстановитьАтрибут(УзелСвойства, "Имя", ПКС.ИмяПараметраДляПередачи); + + КонецЕсли; + + Если НеЗамещать Тогда + + УстановитьАтрибут(УзелСвойства, "НеЗамещать", "true"); + + КонецЕсли; + + Если ПКС.ПоискПоДатеНаРавенство Тогда + + УстановитьАтрибут(УзелКоллекцииСвойств, "ПоискПоДатеНаРавенство", "true"); + + КонецЕсли; + + + // Возможно правило конвертации уже определено. + Если Не ПустаяСтрока(ИмяПКО) Тогда + + ПКОСвойств = Правила[ИмяПКО]; + + Иначе + + ПКОСвойств = Неопределено; + + КонецЕсли; + + + // Попытка определить тип свойства приемника. + Если ПустаяСтрока(ТипПриемника) И ПКОСвойств <> Неопределено Тогда + + ТипПриемника = ПКОСвойств.Приемник; + УстановитьАтрибут(УзелСвойства, "Тип", ТипПриемника); + + ИначеЕсли НЕ ВыполнитьОбменДаннымиВОптимизированномФормате + И Не ПустаяСтрока(ТипПриемника) Тогда + + УстановитьАтрибут(УзелСвойства, "Тип", ТипПриемника); + + КонецЕсли; + + Если Не ПустаяСтрока(ИмяПКО) + И ПКОСвойств <> Неопределено + И ПКОСвойств.ЕстьОбработчикПоследовательностьПолейПоиска = Истина Тогда + + УстановитьАтрибут(УзелСвойства, "ИмяПКО", ИмяПКО); + + КонецЕсли; + + // Определяем конвертируемое значение. + Если Выражение <> Неопределено Тогда + + одЗаписатьЭлемент(УзелСвойства, "Выражение", Выражение); + ДобавитьПодчиненный(УзелКоллекцииСвойств, УзелСвойства); + Продолжить; + + ИначеЕсли Пусто Тогда + + Если ПустаяСтрока(ТипПриемника) Тогда + + Продолжить; + + КонецЕсли; + + Если НЕ ВыполнитьОбменДаннымиВОптимизированномФормате Тогда + одЗаписатьЭлемент(УзелСвойства, "Пусто"); + КонецЕсли; + + ДобавитьПодчиненный(УзелКоллекцииСвойств, УзелСвойства); + Продолжить; + + Иначе + + ПолучитьЗначениеСвойства(Значение, ОбъектКоллекции, ПКО, ПКС, ВходящиеДанные, Источник); + + Если ПКС.ПриводитьКДлине <> 0 Тогда + + ВыполнитьПриведениеЗначенияКДлине(Значение, ПКС); + + КонецЕсли; + + КонецЕсли; + + + СтароеЗначениеДоОбработчикаПриВыгрузке = Значение; + Пусто = одПустое(Значение, ЭтоNULL); + + + // Обработчик ПриВыгрузке + Если ПКС.ЕстьОбработчикПриВыгрузке Тогда + + Отказ = Ложь; + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(ПКС, "ПриВыгрузке")); + + Иначе + + Выполнить(ПКС.ПриВыгрузке); + + КонецЕсли; + + Исключение + + ЗаписатьИнформациюОбОшибкеОбработчикиПКС(56, ОписаниеОшибки(), ПКО, ПКС, Источник, + "ПриВыгрузкеСвойства", Значение); + + КонецПопытки; + + Если Отказ Тогда // Отказ от выгрузки свойства + + Продолжить; + + КонецЕсли; + + КонецЕсли; + + + // Инициализируем еще раз переменную Пусто, может быть Значение было изменено + // в обработчике "При выгрузке". + Если СтароеЗначениеДоОбработчикаПриВыгрузке <> Значение Тогда + + Пусто = одПустое(Значение, ЭтоNULL); + + КонецЕсли; + + Если Пусто Тогда + + Если ЭтоNULL + Или Значение = Неопределено Тогда + + Продолжить; + + КонецЕсли; + + Если ПустаяСтрока(ТипПриемника) Тогда + + ТипПриемника = ОпределитьТипДанныхДляПриемника(Значение); + + Если Не ПустаяСтрока(ТипПриемника) Тогда + + УстановитьАтрибут(УзелСвойства, "Тип", ТипПриемника); + + КонецЕсли; + + КонецЕсли; + + // Если тип множественный, то возможно это пустая ссылка и выгрузить ее нужно именно с указанием типа. + Если НЕ ВыполнитьОбменДаннымиВОптимизированномФормате Тогда + одЗаписатьЭлемент(УзелСвойства, "Пусто"); + КонецЕсли; + + ДобавитьПодчиненный(УзелКоллекцииСвойств, УзелСвойства); + Продолжить; + + КонецЕсли; + + + УзелСсылки = Неопределено; + + Если (ПКОСвойств <> Неопределено) + Или (Не ПустаяСтрока(ИмяПКО)) Тогда + + УзелСсылки = ВыгрузитьДанныеСсылочногоОбъекта(Значение, ИсходящиеДанные, ИмяПКО, ПКОСвойств, ТипПриемника, УзелСвойства, ВыгрузитьТолькоСсылку); + + Если УзелСсылки = Неопределено Тогда + Продолжить; + КонецЕсли; + + Иначе + + СвойствоУстановлено = Ложь; + ТипЗначения = ТипЗнч(Значение); + ДобавитьЗначениеСвойстваВУзел(Значение, ТипЗначения, ТипПриемника, УзелСвойства, СвойствоУстановлено); + + Если НЕ СвойствоУстановлено Тогда + + МенеджерЗначения = Менеджеры(ТипЗначения); + + Если МенеджерЗначения = Неопределено Тогда + Продолжить; + КонецЕсли; + + ПКОСвойств = МенеджерЗначения.ПКО; + + Если ПКОСвойств = Неопределено Тогда + Продолжить; + КонецЕсли; + + ИмяПКО = ПКОСвойств.Имя; + + УзелСсылки = ВыгрузитьДанныеСсылочногоОбъекта(Значение, ИсходящиеДанные, ИмяПКО, ПКОСвойств, ТипПриемника, УзелСвойства, ВыгрузитьТолькоСсылку); + + Если УзелСсылки = Неопределено Тогда + Продолжить; + КонецЕсли; + + КонецЕсли; + + КонецЕсли; + + + + // Обработчик ПослеВыгрузки + + Если ПКС.ЕстьОбработчикПослеВыгрузки Тогда + + Отказ = Ложь; + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(ПКС, "ПослеВыгрузки")); + + Иначе + + Выполнить(ПКС.ПослеВыгрузки); + + КонецЕсли; + + Исключение + + ЗаписатьИнформациюОбОшибкеОбработчикиПКС(57, ОписаниеОшибки(), ПКО, ПКС, Источник, + "ПослеВыгрузкиСвойства", Значение); + + КонецПопытки; + + Если Отказ Тогда // Отказ от выгрузки свойства + + Продолжить; + + КонецЕсли; + + КонецЕсли; + + + ДобавитьПодчиненный(УзелКоллекцииСвойств, УзелСвойства); + + КонецЦикла; // по ПКС + +КонецПроцедуры + +// Производит выгрузку объекта выборки в соответствии с указанным правилом. +// +// Параметры: +// Объект - выгружаемый объект выборки. +// Правило - ссылка на правило выгрузки данных. +// Свойства - свойства объекта метаданного выгружаемого объекта. +// ВходящиеДанные - произвольные вспомогательные данные. +// +Процедура ВыгрузкаОбъектаВыборки(Объект, Правило, Свойства=Неопределено, ВходящиеДанные=Неопределено, ВыборкаДляВыгрузкиДанных = Неопределено) + + Если БезопасныйРежим Тогда + УстановитьБезопасныйРежим(Истина); + Для Каждого ИмяРазделителя Из РазделителиКонфигурации Цикл + УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина); + КонецЦикла; + КонецЕсли; + + Если ФлагКомментироватьОбработкуОбъектов Тогда + + ОписаниеТипов = Новый ОписаниеТипов("Строка"); + ОбъектСтрока = ОписаниеТипов.ПривестиЗначение(Объект); + Если Не ПустаяСтрока(ОбъектСтрока) Тогда + ПрОбъекта = ОбъектСтрока + " (" + ТипЗнч(Объект) + ")"; + Иначе + ПрОбъекта = ТипЗнч(Объект); + КонецЕсли; + + СтрокаСообщения = ПодставитьПараметрыВСтроку(НСтр("ru = 'Выгрузка объекта: %1'"), ПрОбъекта); + ЗаписатьВПротоколВыполнения(СтрокаСообщения, , Ложь, 1, 7); + + КонецЕсли; + + ИмяПКО = Правило.ПравилоКонвертации; + Отказ = Ложь; + ИсходящиеДанные = Неопределено; + + // Глобальный обработчик ПередВыгрузкойОбъекта. + Если ЕстьГлобальныйОбработчикПередВыгрузкойОбъекта Тогда + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(Конвертация, "ПередВыгрузкойОбъекта")); + + Иначе + + Выполнить(Конвертация.ПередВыгрузкойОбъекта); + + КонецЕсли; + + Исключение + ЗаписатьИнформациюОбОшибкеОбработчикиПВД(65, ОписаниеОшибки(), Правило.Имя, НСтр("ru = 'ПередВыгрузкойОбъектаВыборки (глобальный)'"), Объект); + КонецПопытки; + + Если Отказ Тогда + Возврат; + КонецЕсли; + + КонецЕсли; + + // Обработчик ПередВыгрузкой + Если Не ПустаяСтрока(Правило.ПередВыгрузкой) Тогда + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(Правило, "ПередВыгрузкой")); + + Иначе + + Выполнить(Правило.ПередВыгрузкой); + + КонецЕсли; + + Исключение + ЗаписатьИнформациюОбОшибкеОбработчикиПВД(33, ОписаниеОшибки(), Правило.Имя, "ПередВыгрузкойОбъектаВыборки", Объект); + КонецПопытки; + + Если Отказ Тогда + Возврат; + КонецЕсли; + + КонецЕсли; + + УзелСсылки = Неопределено; + + ВыгрузитьПоПравилу(Объект, , ИсходящиеДанные, , ИмяПКО, УзелСсылки, , , , ВыборкаДляВыгрузкиДанных); + + // Глобальный обработчик ПослеВыгрузкиОбъекта. + Если ЕстьГлобальныйОбработчикПослеВыгрузкиОбъекта Тогда + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(Конвертация, "ПослеВыгрузкиОбъекта")); + + Иначе + + Выполнить(Конвертация.ПослеВыгрузкиОбъекта); + + КонецЕсли; + + Исключение + ЗаписатьИнформациюОбОшибкеОбработчикиПВД(69, ОписаниеОшибки(), Правило.Имя, НСтр("ru = 'ПослеВыгрузкиОбъектаВыборки (глобальный)'"), Объект); + КонецПопытки; + + КонецЕсли; + + // Обработчик ПослеВыгрузки + Если Не ПустаяСтрока(Правило.ПослеВыгрузки) Тогда + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(Правило, "ПослеВыгрузки")); + + Иначе + + Выполнить(Правило.ПослеВыгрузки); + + КонецЕсли; + + Исключение + ЗаписатьИнформациюОбОшибкеОбработчикиПВД(34, ОписаниеОшибки(), Правило.Имя, "ПослеВыгрузкиОбъектаВыборки", Объект); + КонецПопытки; + + КонецЕсли; + +КонецПроцедуры + +// Параметры: +// МетаданныеОбъекта - ОбъектМетаданных - +// +Функция ПолучитьИмяПервогоРеквизитаМетаданных(МетаданныеОбъекта) + + НаборРеквизитов = МетаданныеОбъекта.Реквизиты; // КоллекцияОбъектовМетаданных + + Если НаборРеквизитов.Количество() = 0 Тогда + Возврат ""; + КонецЕсли; + + Возврат НаборРеквизитов.Получить(0).Имя; + +КонецФункции + +Функция ПолучитьВыборкуДляВыгрузкиСОграничениями(Правило, ВыборкаДляПодстановкиВПКО = Неопределено, Свойства = Неопределено) + + ИмяМетаданных = Правило.ИмяОбъектаДляЗапроса; + + СтрокаРазрешения = ?(ВыгружатьТолькоРазрешенные, " РАЗРЕШЕННЫЕ ", ""); + + ПоляВыборки = ""; + + ЭтоВыгрузкаРегистра = (Правило.ИмяОбъектаДляЗапроса = Неопределено); + + Если ЭтоВыгрузкаРегистра Тогда + + Непериодический = НЕ Свойства.Периодический; + ПодчиненныйРегистратору = Свойства.ПодчиненныйРегистратору; + + СтрокаДополненияПолейВыборкиПодчиненРегистратору = ?(НЕ ПодчиненныйРегистратору, ", NULL КАК Активность, + | NULL КАК Регистратор, + | NULL КАК НомерСтроки", ""); + + СтрокаДополненияПолейВыборкиПериодичность = ?(Непериодический, ", NULL КАК Период", ""); + + ИтоговоеОграничениеПоДате = ПолучитьСтрокуОграниченияПоДатеДляЗапроса(Свойства, Свойства.ИмяТипа, Правило.ИмяОбъектаДляЗапросаРегистра, Ложь); + + ПостроительОтчета.Текст = "ВЫБРАТЬ " + СтрокаРазрешения + + "| * + | + | " + СтрокаДополненияПолейВыборкиПодчиненРегистратору + + " | " + СтрокаДополненияПолейВыборкиПериодичность + + " | + | ИЗ " + Правило.ИмяОбъектаДляЗапросаРегистра + + " | + |" + ИтоговоеОграничениеПоДате; + + ПостроительОтчета.ЗаполнитьНастройки(); + + Иначе + + Если Правило.ВыбиратьДанныеДляВыгрузкиОднимЗапросом Тогда + + // Выбираем все поля объекта при выгрузке. + ПоляВыборки = "*"; + + Иначе + + ПоляВыборки = "Ссылка КАК Ссылка"; + + КонецЕсли; + + ИтоговоеОграничениеПоДате = ПолучитьСтрокуОграниченияПоДатеДляЗапроса(Свойства, Свойства.ИмяТипа,, Ложь); + + ПостроительОтчета.Текст = "ВЫБРАТЬ " + СтрокаРазрешения + " " + ПоляВыборки + " ИЗ " + ИмяМетаданных + " + | + |" + ИтоговоеОграничениеПоДате + " + | + |{ГДЕ Ссылка.* КАК " + СтрЗаменить(ИмяМетаданных, ".", "_") + "}"; + + КонецЕсли; + + ПостроительОтчета.Отбор.Сбросить(); + //УИ++ + // +// Если Правило.НастройкиПостроителя <> Неопределено Тогда +// ПостроительОтчета.УстановитьНастройки(Правило.НастройкиПостроителя); +// КонецЕсли; + + Если Правило.Отбор<>Неопределено Тогда + ТекстЗапросаНовый = ПолучитьТекстЗапросаПоСтроке(Правило,Правило.Отбор <> Неопределено,"*"); + + СхемаКомпоновкиДанных = СхемаКомпоновкиДанных(ТекстЗапросаНовый); + КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных; + КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных)); + КомпоновщикНастроек.ЗагрузитьНастройки(СхемаКомпоновкиДанных.НастройкиПоУмолчанию); + УИ_ОбщегоНазначенияКлиентСервер.СкопироватьЭлементы(КомпоновщикНастроек.Настройки.Отбор, Правило.Отбор); + УстановитьНастройкуСтруктурыВыводаРезультата(КомпоновщикНастроек.Настройки); + + УИ_ОбщегоНазначенияКлиентСервер.УстановитьЗначениеПараметраСКД(КомпоновщикНастроек, "ДатаНачала", ДатаНачала); + УИ_ОбщегоНазначенияКлиентСервер.УстановитьЗначениеПараметраСКД(КомпоновщикНастроек, "ДатаОкончания", ДатаОкончания); + // Компоновка макета компоновки данных. + ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных; + КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных; +// УИ_._От(СхемаКомпоновкиДанных, КомпоновщикНастроек + + МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить( СхемаКомпоновкиДанных, КомпоновщикНастроек.Настройки, ДанныеРасшифровки, , Тип("ГенераторМакетаКомпоновкиДанных")); + ЗапросВременный = Новый Запрос(МакетКомпоновкиДанных.НаборыДанных.НаборДанных1.Запрос); + ПостроительОтчета.Текст = ЗапросВременный.Текст; + + Для Каждого Параметр Из МакетКомпоновкиДанных.ЗначенияПараметров Цикл + ПостроительОтчета.Параметры.Вставить(Параметр.Имя, Параметр.Значение); + КонецЦикла; + КонецЕсли; + //УИ-- + + ПостроительОтчета.Параметры.Вставить("ДатаНачала", ДатаНачала); + ПостроительОтчета.Параметры.Вставить("ДатаОкончания", ДатаОкончания); + + ПостроительОтчета.Выполнить(); + Выборка = ПостроительОтчета.Результат.Выбрать(); + + Если Правило.ВыбиратьДанныеДляВыгрузкиОднимЗапросом Тогда + ВыборкаДляПодстановкиВПКО = Выборка; + КонецЕсли; + + Возврат Выборка; + +КонецФункции + +Функция ПолучитьВыборкуДляВыгрузкиПоПроизвольномуАлгоритму(ВыборкаДанных) + + Выборка = Неопределено; + + Если ТипЗнч(ВыборкаДанных) = Тип("ВыборкаИзРезультатаЗапроса") Тогда + + Выборка = ВыборкаДанных; + + ИначеЕсли ТипЗнч(ВыборкаДанных) = Тип("РезультатЗапроса") Тогда + + Выборка = ВыборкаДанных.Выбрать(); + + ИначеЕсли ТипЗнч(ВыборкаДанных) = Тип("Запрос") Тогда + + РезультатЗапроса = ВыборкаДанных.Выполнить(); + Выборка = РезультатЗапроса.Выбрать(); + + КонецЕсли; + + Возврат Выборка; + +КонецФункции + +Функция ПолучитьСтрокуНабораКонстантДляВыгрузки(ТаблицаДанныхКонстантДляВыгрузки) + + СтрокаНабораКонстант = ""; + + Для Каждого СтрокаТаблицы Из ТаблицаДанныхКонстантДляВыгрузки Цикл + + Если Не ПустаяСтрока(СтрокаТаблицы.Источник) Тогда + + СтрокаНабораКонстант = СтрокаНабораКонстант + ", " + СтрокаТаблицы.Источник; + + КонецЕсли; + + КонецЦикла; + + Если Не ПустаяСтрока(СтрокаНабораКонстант) Тогда + + СтрокаНабораКонстант = Сред(СтрокаНабораКонстант, 3); + + КонецЕсли; + + Возврат СтрокаНабораКонстант; + +КонецФункции + +Процедура ВыгрузитьНаборКонстант(Правило, Свойства, ИсходящиеДанные) + + Если Свойства.ПКО <> Неопределено Тогда + + СтрокаИменНабораКонстант = ПолучитьСтрокуНабораКонстантДляВыгрузки(Свойства.ПКО.Свойства); + + Иначе + + СтрокаИменНабораКонстант = ""; + + КонецЕсли; + + НаборКонстант = Константы.СоздатьНабор(СтрокаИменНабораКонстант); + НаборКонстант.Прочитать(); + ВыгрузкаОбъектаВыборки(НаборКонстант, Правило, Свойства, ИсходящиеДанные); + +КонецПроцедуры + +Функция ОпределитьНужноВыбиратьВсеПоля(Правило) + + НужныВсеПоляДляВыборки = НЕ ПустаяСтрока(Конвертация.ПередВыгрузкойОбъекта) + ИЛИ НЕ ПустаяСтрока(Правило.ПередВыгрузкой) + ИЛИ НЕ ПустаяСтрока(Конвертация.ПослеВыгрузкиОбъекта) + ИЛИ НЕ ПустаяСтрока(Правило.ПослеВыгрузки); + + Возврат НужныВсеПоляДляВыборки; + +КонецФункции + +// Выгружает данные по указанному правилу. +// +// Параметры: +// Правило - ссылка на правило выгрузки данных. +// +Процедура ВыгрузитьДанныеПоПравилу(Правило) + + Если БезопасныйРежим Тогда + УстановитьБезопасныйРежим(Истина); + Для Каждого ИмяРазделителя Из РазделителиКонфигурации Цикл + УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина); + КонецЦикла; + КонецЕсли; + + ИмяПКО = Правило.ПравилоКонвертации; + + Если Не ПустаяСтрока(ИмяПКО) Тогда + + ПКО = Правила[ИмяПКО]; + + КонецЕсли; + + Если ФлагКомментироватьОбработкуОбъектов Тогда + + СтрокаСообщения = ПодставитьПараметрыВСтроку(НСтр("ru = 'Правило выгрузки данных: %1 (%2)'"), СокрЛП(Правило.Имя), СокрЛП(Правило.Наименование)); + ЗаписатьВПротоколВыполнения(СтрокаСообщения, , Ложь, , 4); + + КонецЕсли; + + // Обработчик ПередОбработкой + Отказ = Ложь; + ИсходящиеДанные = Неопределено; + ВыборкаДанных = Неопределено; + + Если Не ПустаяСтрока(Правило.ПередОбработкой) Тогда + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(Правило, "ПередОбработкой")); + + Иначе + + Выполнить(Правило.ПередОбработкой); + + КонецЕсли; + + Исключение + + ЗаписатьИнформациюОбОшибкеОбработчикиПВД(31, ОписаниеОшибки(), Правило.Имя, "ПередОбработкойВыгрузкиДанных"); + + КонецПопытки; + + Если Отказ Тогда + + Возврат; + + КонецЕсли; + + КонецЕсли; + + // Стандартная выборка с отбором. + Если Правило.СпособОтбораДанных = "СтандартнаяВыборка" И Правило.ИспользоватьОтбор Тогда + + Свойства = Менеджеры[Правило.ОбъектВыборки]; + ИмяТипа = Свойства.ИмяТипа; + + ВыборкаДляПКО = Неопределено; + Выборка = ПолучитьВыборкуДляВыгрузкиСОграничениями(Правило, ВыборкаДляПКО, Свойства); + + ЭтоНеСсылочныйТип = ИмяТипа = "РегистрСведений" Или ИмяТипа = "РегистрБухгалтерии"; + + Пока Выборка.Следующий() Цикл + + Если ЭтоНеСсылочныйТип Тогда + ВыгрузкаОбъектаВыборки(Выборка, Правило, Свойства, ИсходящиеДанные); + Иначе + ВыгрузкаОбъектаВыборки(Выборка.Ссылка, Правило, Свойства, ИсходящиеДанные, ВыборкаДляПКО); + КонецЕсли; + + КонецЦикла; + + // Стандартная выборка без отбора. + ИначеЕсли (Правило.СпособОтбораДанных = "СтандартнаяВыборка") Тогда + + Свойства = Менеджеры(Правило.ОбъектВыборки); + ИмяТипа = Свойства.ИмяТипа; + + Если ИмяТипа = "Константы" Тогда + + ВыгрузитьНаборКонстант(Правило, Свойства, ИсходящиеДанные); + + Иначе + + ЭтоНеСсылочныйТип = ИмяТипа = "РегистрСведений" + ИЛИ ИмяТипа = "РегистрБухгалтерии"; + + Если ЭтоНеСсылочныйТип Тогда + + ВыбиратьВсеПоля = ОпределитьНужноВыбиратьВсеПоля(Правило); + + Иначе + + // получаем только ссылку + ВыбиратьВсеПоля = Правило.ВыбиратьДанныеДляВыгрузкиОднимЗапросом; + + КонецЕсли; + + Выборка = ПолучитьВыборкуДляВыгрузкиОчисткиДанных(Свойства, ИмяТипа, , , ВыбиратьВсеПоля); + ВыборкаДляПКО = ?(Правило.ВыбиратьДанныеДляВыгрузкиОднимЗапросом, Выборка, Неопределено); + + Если Выборка = Неопределено Тогда + Возврат; + КонецЕсли; + + Пока Выборка.Следующий() Цикл + + Если ЭтоНеСсылочныйТип Тогда + + ВыгрузкаОбъектаВыборки(Выборка, Правило, Свойства, ИсходящиеДанные); + + Иначе + + ВыгрузкаОбъектаВыборки(Выборка.Ссылка, Правило, Свойства, ИсходящиеДанные, ВыборкаДляПКО); + + КонецЕсли; + + КонецЦикла; + + КонецЕсли; + + ИначеЕсли Правило.СпособОтбораДанных = "ПроизвольныйАлгоритм" Тогда + + Если ВыборкаДанных <> Неопределено Тогда + + Выборка = ПолучитьВыборкуДляВыгрузкиПоПроизвольномуАлгоритму(ВыборкаДанных); + + Если Выборка <> Неопределено Тогда + + Пока Выборка.Следующий() Цикл + + ВыгрузкаОбъектаВыборки(Выборка, Правило, , ИсходящиеДанные); + + КонецЦикла; + + Иначе + + Для каждого Объект Из ВыборкаДанных Цикл + + ВыгрузкаОбъектаВыборки(Объект, Правило, , ИсходящиеДанные); + + КонецЦикла; + + КонецЕсли; + + КонецЕсли; + + КонецЕсли; + + + // Обработчик ПослеОбработки + + Если Не ПустаяСтрока(Правило.ПослеОбработки) Тогда + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(Правило, "ПослеОбработки")); + + Иначе + + Выполнить(Правило.ПослеОбработки); + + КонецЕсли; + + Исключение + + ЗаписатьИнформациюОбОшибкеОбработчикиПВД(32, ОписаниеОшибки(), Правило.Имя, "ПослеОбработкиВыгрузкиДанных"); + + КонецПопытки; + + КонецЕсли; + +КонецПроцедуры + +// Обходит дерево правил выгрузки данных и выполняет выгрузку. +// +// Параметры: +// Строки - Коллекция строк дерева значений. +// +Процедура ОбработатьПравилаВыгрузки(Строки, СоответствиеУзловПланаОбменаИСтрокВыгрузки) + + Для каждого ПравилоВыгрузки Из Строки Цикл + + Если ПравилоВыгрузки.Включить = 0 Тогда + + Продолжить; + + КонецЕсли; + + Если (ПравилоВыгрузки.СсылкаНаУзелОбмена <> Неопределено + И НЕ ПравилоВыгрузки.СсылкаНаУзелОбмена.Пустая()) Тогда + + МассивПравилВыгрузки = СоответствиеУзловПланаОбменаИСтрокВыгрузки.Получить(ПравилоВыгрузки.СсылкаНаУзелОбмена); + + Если МассивПравилВыгрузки = Неопределено Тогда + + МассивПравилВыгрузки = Новый Массив(); + + КонецЕсли; + + МассивПравилВыгрузки.Добавить(ПравилоВыгрузки); + + СоответствиеУзловПланаОбменаИСтрокВыгрузки.Вставить(ПравилоВыгрузки.СсылкаНаУзелОбмена, МассивПравилВыгрузки); + + Продолжить; + + КонецЕсли; + + Если ПравилоВыгрузки.ЭтоГруппа Тогда + + ОбработатьПравилаВыгрузки(ПравилоВыгрузки.Строки, СоответствиеУзловПланаОбменаИСтрокВыгрузки); + Продолжить; + + КонецЕсли; + + ВыгрузитьДанныеПоПравилу(ПравилоВыгрузки); + + КонецЦикла; + +КонецПроцедуры + +Функция СкопироватьМассивПравилВыгрузки(ИсходныйМассив) + + РезультирующийМассив = Новый Массив(); + + Для Каждого Элемент Из ИсходныйМассив Цикл + + РезультирующийМассив.Добавить(Элемент); + + КонецЦикла; + + Возврат РезультирующийМассив; + +КонецФункции + +// Возвращаемое значение: +// СтрокаДереваЗначений - строка дерева правил выгрузки данных: +// * Имя - Строка - +// * Наименование - Строка - +// +Функция НайтиСтрокуДереваПравилВыгрузкиПоТипуВыгрузки(МассивСтрок, ТипВыгрузки) + + Для Каждого СтрокаМассива Из МассивСтрок Цикл + + Если СтрокаМассива.ОбъектВыборки = ТипВыгрузки Тогда + + Возврат СтрокаМассива; + + КонецЕсли; + + КонецЦикла; + + Возврат Неопределено; + +КонецФункции + +Процедура УдалитьСтрокуДереваПравилВыгрузкиПоТипуВыгрузкиИзМассива(МассивСтрок, ЭлементУдаления) + + Счетчик = МассивСтрок.Количество() - 1; + Пока Счетчик >= 0 Цикл + + СтрокаМассива = МассивСтрок[Счетчик]; + + Если СтрокаМассива = ЭлементУдаления Тогда + + МассивСтрок.Удалить(Счетчик); + Возврат; + + КонецЕсли; + + Счетчик = Счетчик - 1; + + КонецЦикла; + +КонецПроцедуры + +// Параметры: +// Данные - ЛюбаяСсылка, РегистрСведенийНаборЗаписей, и т.п. - +// +Процедура ПолучитьСтрокуПравилВыгрузкиПоОбъектуОбмена(Данные, МетаданныеПоследнегоОбъекта, МетаданныеОбъектаВыгрузки, + ПоследняяСтрокаПравилВыгрузки, ТекущаяСтрокаПравилаВыгрузки, ВременныйМассивПравилКонвертации, ОбъектДляПравилВыгрузки, + ВыгружаетсяРегистр, ВыгружаютсяКонстанты, КонстантыБылиВыгружены) + + ТекущаяСтрокаПравилаВыгрузки = Неопределено; + ОбъектДляПравилВыгрузки = Неопределено; + ВыгружаетсяРегистр = Ложь; + ВыгружаютсяКонстанты = Ложь; + + Если МетаданныеПоследнегоОбъекта = МетаданныеОбъектаВыгрузки + И ПоследняяСтрокаПравилВыгрузки = Неопределено Тогда + + Возврат; + + КонецЕсли; + + СтруктураДанных = МенеджерыДляПлановОбмена[МетаданныеОбъектаВыгрузки]; + + Если СтруктураДанных = Неопределено Тогда + + ВыгружаютсяКонстанты = Метаданные.Константы.Содержит(МетаданныеОбъектаВыгрузки); + + Если КонстантыБылиВыгружены + ИЛИ НЕ ВыгружаютсяКонстанты Тогда + + Возврат; + + КонецЕсли; + + // Нужно найти правило для констант. + Если МетаданныеПоследнегоОбъекта <> МетаданныеОбъектаВыгрузки Тогда + + ТекущаяСтрокаПравилаВыгрузки = НайтиСтрокуДереваПравилВыгрузкиПоТипуВыгрузки(ВременныйМассивПравилКонвертации, Тип("КонстантыНабор")); + + Иначе + + ТекущаяСтрокаПравилаВыгрузки = ПоследняяСтрокаПравилВыгрузки; + + КонецЕсли; + + Возврат; + + КонецЕсли; + + Если СтруктураДанных.ЭтоСсылочныйТип = Истина Тогда + + Если МетаданныеПоследнегоОбъекта <> МетаданныеОбъектаВыгрузки Тогда + + ТекущаяСтрокаПравилаВыгрузки = НайтиСтрокуДереваПравилВыгрузкиПоТипуВыгрузки(ВременныйМассивПравилКонвертации, СтруктураДанных.ТипСсылки); + + Иначе + + ТекущаяСтрокаПравилаВыгрузки = ПоследняяСтрокаПравилВыгрузки; + + КонецЕсли; + + ОбъектДляПравилВыгрузки = Данные.Ссылка; + + ИначеЕсли СтруктураДанных.ЭтоРегистр = Истина Тогда + + Если МетаданныеПоследнегоОбъекта <> МетаданныеОбъектаВыгрузки Тогда + + ТекущаяСтрокаПравилаВыгрузки = НайтиСтрокуДереваПравилВыгрузкиПоТипуВыгрузки(ВременныйМассивПравилКонвертации, СтруктураДанных.ТипСсылки); + + Иначе + + ТекущаяСтрокаПравилаВыгрузки = ПоследняяСтрокаПравилВыгрузки; + + КонецЕсли; + + ОбъектДляПравилВыгрузки = Данные; + + ВыгружаетсяРегистр = Истина; + + КонецЕсли; + +КонецПроцедуры + +Функция ВыполнитьВыгрузкуИзмененныхДанныхДляУзлаОбмена(УзелОбмена, МассивПравилКонвертации, СтруктураДляУдаленияРегистрацииИзменений) + + Если БезопасныйРежим Тогда + УстановитьБезопасныйРежим(Истина); + Для Каждого ИмяРазделителя Из РазделителиКонфигурации Цикл + УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина); + КонецЦикла; + КонецЕсли; + + СтруктураДляУдаленияРегистрацииИзменений.Вставить("МассивПКО", Неопределено); + СтруктураДляУдаленияРегистрацииИзменений.Вставить("НомерСообщения", Неопределено); + + ЗаписьXML = Новый ЗаписьXML(); + ЗаписьXML.УстановитьСтроку(); + + // Создаем новое сообщение + ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения(); + + ЗаписьСообщения.НачатьЗапись(ЗаписьXML, УзелОбмена); + + // Считаем количество записанных объектов. + КоличествоНайденныхДляЗаписиОбъектов = 0; + + ПоследнийОбъектМетаданных = Неопределено; + ПоследняяСтрокаПравилаВыгрузки = Неопределено; // см. НайтиСтрокуДереваПравилВыгрузкиПоТипуВыгрузки + + ТекущийОбъектМетаданных = Неопределено; + ТекущаяСтрокаПравилаВыгрузки = Неопределено; // см. НайтиСтрокуДереваПравилВыгрузкиПоТипуВыгрузки + + ИсходящиеДанные = Неопределено; + + ВременныйМассивПравилКонвертации = СкопироватьМассивПравилВыгрузки(МассивПравилКонвертации); + + Отказ = Ложь; + ИсходящиеДанные = Неопределено; + ВыборкаДанных = Неопределено; + + ОбъектДляПравилВыгрузки = Неопределено; + КонстантыБылиВыгружены = Ложь; + // начинаем транзакцию + Если ИспользоватьТранзакцииПриВыгрузкеДляПлановОбмена Тогда + НачатьТранзакцию(); + КонецЕсли; + + Попытка + + // Получаем выборку измененных данных. + МассивВыгружаемыхМетаданных = Новый Массив(); + + // Дополняем массив только теми метаданными по которым есть правила выгрузки - остальные метаданные нас не интересуют. + Для Каждого СтрокаПравилаВыгрузки Из ВременныйМассивПравилКонвертации Цикл + + МетаданныеПВД = Метаданные.НайтиПоТипу(СтрокаПравилаВыгрузки.ОбъектВыборки); + МассивВыгружаемыхМетаданных.Добавить(МетаданныеПВД); + + КонецЦикла; + + ВыборкаИзменений = ПланыОбмена.ВыбратьИзменения(ЗаписьСообщения.Получатель, ЗаписьСообщения.НомерСообщения, МассивВыгружаемыхМетаданных); + + СтруктураДляУдаленияРегистрацииИзменений.НомерСообщения = ЗаписьСообщения.НомерСообщения; + + Пока ВыборкаИзменений.Следующий() Цикл + + Данные = ВыборкаИзменений.Получить(); + КоличествоНайденныхДляЗаписиОбъектов = КоличествоНайденныхДляЗаписиОбъектов + 1; + + ТипДанныхДляВыгрузки = ТипЗнч(Данные); + + Удаление = (ТипДанныхДляВыгрузки = одТипУдалениеОбъекта); + + // удаление не отрабатываем + Если Удаление Тогда + Продолжить; + КонецЕсли; + + ТекущийОбъектМетаданных = Данные.Метаданные(); + + // Работа с данными полученными из узла обмена + // по данным определяем правило конвертации и производим выгрузку данных. + + ВыгружаетсяРегистр = Ложь; + ВыгружаютсяКонстанты = Ложь; + + ПолучитьСтрокуПравилВыгрузкиПоОбъектуОбмена(Данные, ПоследнийОбъектМетаданных, ТекущийОбъектМетаданных, + ПоследняяСтрокаПравилаВыгрузки, ТекущаяСтрокаПравилаВыгрузки, ВременныйМассивПравилКонвертации, ОбъектДляПравилВыгрузки, + ВыгружаетсяРегистр, ВыгружаютсяКонстанты, КонстантыБылиВыгружены); + + Если ПоследнийОбъектМетаданных <> ТекущийОбъектМетаданных Тогда + + // после обработки + Если ПоследняяСтрокаПравилаВыгрузки <> Неопределено Тогда + + Если Не ПустаяСтрока(ПоследняяСтрокаПравилаВыгрузки.ПослеОбработки) Тогда + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(ПоследняяСтрокаПравилаВыгрузки, "ПослеОбработки")); + + Иначе + + Выполнить(ПоследняяСтрокаПравилаВыгрузки.ПослеОбработки); + + КонецЕсли; + + Исключение + + ЗаписатьИнформациюОбОшибкеОбработчикиПВД(32, ОписаниеОшибки(), ПоследняяСтрокаПравилаВыгрузки.Имя, "ПослеОбработкиВыгрузкиДанных"); + + КонецПопытки; + + КонецЕсли; + + КонецЕсли; + + // перед обработкой + Если ТекущаяСтрокаПравилаВыгрузки <> Неопределено Тогда + + Если ФлагКомментироватьОбработкуОбъектов Тогда + + СтрокаСообщения = ПодставитьПараметрыВСтроку(НСтр("ru = 'Правило выгрузки данных: %1 (%2)'"), + СокрЛП(ТекущаяСтрокаПравилаВыгрузки.Имя), СокрЛП(ТекущаяСтрокаПравилаВыгрузки.Наименование)); + ЗаписатьВПротоколВыполнения(СтрокаСообщения, , Ложь, , 4); + + КонецЕсли; + + // Обработчик ПередОбработкой + Отказ = Ложь; + ИсходящиеДанные = Неопределено; + ВыборкаДанных = Неопределено; + + Если Не ПустаяСтрока(ТекущаяСтрокаПравилаВыгрузки.ПередОбработкой) Тогда + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(ТекущаяСтрокаПравилаВыгрузки, "ПередОбработкой")); + + Иначе + + Выполнить(ТекущаяСтрокаПравилаВыгрузки.ПередОбработкой); + + КонецЕсли; + + Исключение + + ЗаписатьИнформациюОбОшибкеОбработчикиПВД(31, ОписаниеОшибки(), ТекущаяСтрокаПравилаВыгрузки.Имя, "ПередОбработкойВыгрузкиДанных"); + + КонецПопытки; + + КонецЕсли; + + Если Отказ Тогда + + // Удаляем правило из массива правил. + ТекущаяСтрокаПравилаВыгрузки = Неопределено; + УдалитьСтрокуДереваПравилВыгрузкиПоТипуВыгрузкиИзМассива(ВременныйМассивПравилКонвертации, ТекущаяСтрокаПравилаВыгрузки); + ОбъектДляПравилВыгрузки = Неопределено; + + КонецЕсли; + + КонецЕсли; + + КонецЕсли; + + // Есть правило по которому нужно делать выгрузку данных. + Если ТекущаяСтрокаПравилаВыгрузки <> Неопределено Тогда + + Если ВыгружаетсяРегистр Тогда + + Для Каждого СтрокаРегистра Из ОбъектДляПравилВыгрузки Цикл + ВыгрузкаОбъектаВыборки(СтрокаРегистра, ТекущаяСтрокаПравилаВыгрузки, , ИсходящиеДанные); + КонецЦикла; + + ИначеЕсли ВыгружаютсяКонстанты Тогда + + Свойства = Менеджеры[ТекущаяСтрокаПравилаВыгрузки.ОбъектВыборки]; + ВыгрузитьНаборКонстант(ТекущаяСтрокаПравилаВыгрузки, Свойства, ИсходящиеДанные); + + Иначе + + ВыгрузкаОбъектаВыборки(ОбъектДляПравилВыгрузки, ТекущаяСтрокаПравилаВыгрузки, , ИсходящиеДанные); + + КонецЕсли; + + КонецЕсли; + + ПоследнийОбъектМетаданных = ТекущийОбъектМетаданных; + ПоследняяСтрокаПравилаВыгрузки = ТекущаяСтрокаПравилаВыгрузки; + + Если КоличествоОбработанныхОбъектовДляОбновленияСтатуса > 0 + И КоличествоНайденныхДляЗаписиОбъектов % КоличествоОбработанныхОбъектовДляОбновленияСтатуса = 0 Тогда + + Попытка + ИмяМетаданных = ТекущийОбъектМетаданных.ПолноеИмя(); + Исключение + ИмяМетаданных = ""; + КонецПопытки; + + КонецЕсли; + + Если ИспользоватьТранзакцииПриВыгрузкеДляПлановОбмена + И (КоличествоЭлементовВТранзакцииПриВыгрузкеДляПлановОбмена > 0) + И (КоличествоНайденныхДляЗаписиОбъектов = КоличествоЭлементовВТранзакцииПриВыгрузкеДляПлановОбмена) Тогда + + // Промежуточную транзакцию закрываем и открываем новую. + ЗафиксироватьТранзакцию(); + НачатьТранзакцию(); + + КоличествоНайденныхДляЗаписиОбъектов = 0; + КонецЕсли; + + КонецЦикла; + + // Завершаем запись сообщения + ЗаписьСообщения.ЗакончитьЗапись(); + + ЗаписьXML.Закрыть(); + + Если ИспользоватьТранзакцииПриВыгрузкеДляПлановОбмена Тогда + ЗафиксироватьТранзакцию(); + КонецЕсли; + + Исключение + + Если ИспользоватьТранзакцииПриВыгрузкеДляПлановОбмена Тогда + ОтменитьТранзакцию(); + КонецЕсли; + + ЗП = ПолучитьСтруктуруЗаписиПротокола(72, ОписаниеОшибки()); + ЗП.УзелПланаОбмена = УзелОбмена; + ЗП.Объект = Данные; + ЗП.ТипОбъекта = ТипДанныхДляВыгрузки; + + ЗаписатьВПротоколВыполнения(72, ЗП, Истина); + + ЗаписьXML.Закрыть(); + + Возврат Ложь; + + КонецПопытки; + + // событие после обработки + Если ПоследняяСтрокаПравилаВыгрузки <> Неопределено Тогда + + Если Не ПустаяСтрока(ПоследняяСтрокаПравилаВыгрузки.ПослеОбработки) Тогда + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(ПоследняяСтрокаПравилаВыгрузки, "ПослеОбработки")); + + Иначе + + Выполнить(ПоследняяСтрокаПравилаВыгрузки.ПослеОбработки); + + КонецЕсли; + + Исключение + ЗаписатьИнформациюОбОшибкеОбработчикиПВД(32, ОписаниеОшибки(), ПоследняяСтрокаПравилаВыгрузки.Имя, "ПослеОбработкиВыгрузкиДанных"); + + КонецПопытки; + + КонецЕсли; + + КонецЕсли; + + СтруктураДляУдаленияРегистрацииИзменений.МассивПКО = ВременныйМассивПравилКонвертации; + + Возврат Не Отказ; + +КонецФункции + +Функция ОбработатьВыгрузкуДляПлановОбмена(СоответствиеУзловИПравилВыгрузки, СтруктураДляУдаленияРегистрацииИзменений) + + УдачнаяВыгрузка = Истина; + + Для Каждого СтрокаСоответствия Из СоответствиеУзловИПравилВыгрузки Цикл + + УзелОбмена = СтрокаСоответствия.Ключ; + МассивПравилКонвертации = СтрокаСоответствия.Значение; + + ЛокальнаяСтруктураДляУдаленияРегистрацииИзменений = Новый Структура(); + + ТекущаяУдачнаяВыгрузка = ВыполнитьВыгрузкуИзмененныхДанныхДляУзлаОбмена(УзелОбмена, МассивПравилКонвертации, ЛокальнаяСтруктураДляУдаленияРегистрацииИзменений); + + УдачнаяВыгрузка = УдачнаяВыгрузка И ТекущаяУдачнаяВыгрузка; + + Если ЛокальнаяСтруктураДляУдаленияРегистрацииИзменений.МассивПКО <> Неопределено + И ЛокальнаяСтруктураДляУдаленияРегистрацииИзменений.МассивПКО.Количество() > 0 Тогда + + СтруктураДляУдаленияРегистрацииИзменений.Вставить(УзелОбмена, ЛокальнаяСтруктураДляУдаленияРегистрацииИзменений); + + КонецЕсли; + + КонецЦикла; + + Возврат УдачнаяВыгрузка; + +КонецФункции + +Процедура ОбработатьИзменениеРегистрацииДляУзловОбмена(СоответствиеУзловИПравилВыгрузки) + + Для Каждого Элемент Из СоответствиеУзловИПравилВыгрузки Цикл + + Если ТипУдаленияРегистрацииИзмененийДляУзловОбменаПослеВыгрузки = 0 Тогда + + Возврат; + + ИначеЕсли ТипУдаленияРегистрацииИзмененийДляУзловОбменаПослеВыгрузки = 1 Тогда + + // Для всех изменений которые были в плане обмена отменяем регистрацию. + ПланыОбмена.УдалитьРегистрациюИзменений(Элемент.Ключ, Элемент.Значение.НомерСообщения); + + ИначеЕсли ТипУдаленияРегистрацииИзмененийДляУзловОбменаПослеВыгрузки = 2 Тогда + + // Удаление изменений только для метаданных выгруженных объектов первого уровня. + + Для Каждого ВыгруженноеПКО Из Элемент.Значение.МассивПКО Цикл + + Правило = Правила[ВыгруженноеПКО.ПравилоКонвертации]; // см. НайтиПравило + + Если ЗначениеЗаполнено(Правило.Источник) Тогда + + Менеджер = Менеджеры[Правило.Источник]; + + ПланыОбмена.УдалитьРегистрациюИзменений(Элемент.Ключ, Менеджер.ОбъектМД); + + КонецЕсли; + + КонецЦикла; + + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + +Функция УдалитьНедопустимыеСимволыXML(Знач Текст) + + Возврат ЗаменитьНедопустимыеСимволыXML(Текст, ""); + +КонецФункции + +#КонецОбласти + +#Область ЭкспортируемыеПроцедурыИФункции + +// Открывает файл обмена, читает атрибуты корневого узла файла в соответствии с форматом обмена. +// +// Параметры: +// ТолькоПрочитатьШапку - Булево. если Истина, то после прочтения шапки файла обмена +// (корневой узел), файл закрывается. +// +Процедура ОткрытьФайлЗагрузки(ТолькоПрочитатьШапку=Ложь, ДанныеФайлаОбмена = "") Экспорт + + Если ПустаяСтрока(ИмяФайлаОбмена) И ТолькоПрочитатьШапку Тогда + ДатаНачала = ""; + ДатаОкончания = ""; + ДатаВыгрузкиДанных = ""; + ВерсияПравилОбмена = ""; + Комментарий = ""; + Возврат; + КонецЕсли; + + + ИмяФайлаЗагрузкиДанных = ИмяФайлаОбмена; + + + // Архивные файлы будем идентифицировать по расширению ".zip". + Если СтрНайти(ИмяФайлаОбмена, ".zip") > 0 Тогда + + ИмяФайлаЗагрузкиДанных = РаспаковатьZipФайл(ИмяФайлаОбмена); + + КонецЕсли; + + + ФлагОшибки = Ложь; + ФайлОбмена = Новый ЧтениеXML(); + + Попытка + Если НЕ ПустаяСтрока(ДанныеФайлаОбмена) Тогда + ФайлОбмена.УстановитьСтроку(ДанныеФайлаОбмена); + Иначе + ФайлОбмена.ОткрытьФайл(ИмяФайлаЗагрузкиДанных); + КонецЕсли; + Исключение + ЗаписатьВПротоколВыполнения(5); + Возврат; + КонецПопытки; + + ФайлОбмена.Прочитать(); + + + мАтрибутыФайлаОбмена = Новый Структура; + + + Если ФайлОбмена.ЛокальноеИмя = "ФайлОбмена" Тогда + + мАтрибутыФайлаОбмена.Вставить("ВерсияФормата", одАтрибут(ФайлОбмена, одТипСтрока, "ВерсияФормата")); + мАтрибутыФайлаОбмена.Вставить("ДатаВыгрузки", одАтрибут(ФайлОбмена, одТипДата, "ДатаВыгрузки")); + мАтрибутыФайлаОбмена.Вставить("НачалоПериодаВыгрузки", одАтрибут(ФайлОбмена, одТипДата, "НачалоПериодаВыгрузки")); + мАтрибутыФайлаОбмена.Вставить("ОкончаниеПериодаВыгрузки", одАтрибут(ФайлОбмена, одТипДата, "ОкончаниеПериодаВыгрузки")); + мАтрибутыФайлаОбмена.Вставить("ИмяКонфигурацииИсточника", одАтрибут(ФайлОбмена, одТипСтрока, "ИмяКонфигурацииИсточника")); + мАтрибутыФайлаОбмена.Вставить("ИмяКонфигурацииПриемника", одАтрибут(ФайлОбмена, одТипСтрока, "ИмяКонфигурацииПриемника")); + мАтрибутыФайлаОбмена.Вставить("ИдПравилКонвертации", одАтрибут(ФайлОбмена, одТипСтрока, "ИдПравилКонвертации")); + + ДатаНачала = мАтрибутыФайлаОбмена.НачалоПериодаВыгрузки; + ДатаОкончания = мАтрибутыФайлаОбмена.ОкончаниеПериодаВыгрузки; + ДатаВыгрузкиДанных = мАтрибутыФайлаОбмена.ДатаВыгрузки; + Комментарий = одАтрибут(ФайлОбмена, одТипСтрока, "Комментарий"); + + Иначе + + ЗаписатьВПротоколВыполнения(9); + Возврат; + + КонецЕсли; + + + ФайлОбмена.Прочитать(); + + ИмяУзла = ФайлОбмена.ЛокальноеИмя; + + Если ИмяУзла = "ПравилаОбмена" Тогда + Если БезопаснаяЗагрузка И ЗначениеЗаполнено(ИмяФайлаПравилОбмена) Тогда + ЗагрузитьПравилаОбмена(ИмяФайлаПравилОбмена, "XMLФайл"); + ФайлОбмена.Пропустить(); + Иначе + ЗагрузитьПравилаОбмена(ФайлОбмена, "ЧтениеXML"); + КонецЕсли; + Иначе + ФайлОбмена.Закрыть(); + ФайлОбмена = Новый ЧтениеXML(); + Попытка + + Если НЕ ПустаяСтрока(ДанныеФайлаОбмена) Тогда + ФайлОбмена.УстановитьСтроку(ДанныеФайлаОбмена); + Иначе + ФайлОбмена.ОткрытьФайл(ИмяФайлаЗагрузкиДанных); + КонецЕсли; + + Исключение + + ЗаписатьВПротоколВыполнения(5); + Возврат; + + КонецПопытки; + + ФайлОбмена.Прочитать(); + + КонецЕсли; + + мБылиПрочитаныПравилаОбменаПриЗагрузке = Истина; + + Если ТолькоПрочитатьШапку Тогда + + ФайлОбмена.Закрыть(); + Возврат; + + КонецЕсли; + +КонецПроцедуры + +Процедура ОбновитьПометкиВсехРодителейУПравилВыгрузки(СтрокиДереваПравилВыгрузки, НужноУстанавливатьПометки = Истина) + + Если СтрокиДереваПравилВыгрузки.Строки.Количество() = 0 Тогда + + Если НужноУстанавливатьПометки Тогда + УстановитьПометкиРодителей(СтрокиДереваПравилВыгрузки, "Включить"); + КонецЕсли; + + Иначе + + НужныПометки = Истина; + + Для Каждого СтрокаДереваПравил Из СтрокиДереваПравилВыгрузки.Строки Цикл + + ОбновитьПометкиВсехРодителейУПравилВыгрузки(СтрокаДереваПравил, НужныПометки); + Если НужныПометки = Истина Тогда + НужныПометки = Ложь; + КонецЕсли; + + КонецЦикла; + + КонецЕсли; + +КонецПроцедуры + +Процедура ЗаполнитьСвойстваДляПоиска(СтруктураДанных, ПКС) + + Для Каждого СтрокаПолей Из ПКС Цикл + + Если СтрокаПолей.ЭтоГруппа Тогда + + Если СтрокаПолей.ВидПриемника = "ТабличнаяЧасть" + ИЛИ СтрНайти(СтрокаПолей.ВидПриемника, "НаборДвижений") > 0 Тогда + + ИмяСтруктурыПриемника = СтрокаПолей.Приемник + ?(СтрокаПолей.ВидПриемника = "ТабличнаяЧасть", "ТабличнаяЧасть", "НаборЗаписей"); + + ВнутренняяСтруктура = СтруктураДанных[ИмяСтруктурыПриемника]; + + Если ВнутренняяСтруктура = Неопределено Тогда + ВнутренняяСтруктура = Новый Соответствие(); + КонецЕсли; + + СтруктураДанных[ИмяСтруктурыПриемника] = ВнутренняяСтруктура; + + Иначе + + ВнутренняяСтруктура = СтруктураДанных; + + КонецЕсли; + + ЗаполнитьСвойстваДляПоиска(ВнутренняяСтруктура, СтрокаПолей.ПравилаГруппы); + + Иначе + + Если ПустаяСтрока(СтрокаПолей.ТипПриемника) Тогда + + Продолжить; + + КонецЕсли; + + СтруктураДанных[СтрокаПолей.Приемник] = СтрокаПолей.ТипПриемника; + + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + +Процедура УдалитьЛишниеЭлементыИзСоответствия(СтруктураДанных) + + Для Каждого Элемент Из СтруктураДанных Цикл + + Если ТипЗнч(Элемент.Значение) = одТипСоответствие Тогда + + УдалитьЛишниеЭлементыИзСоответствия(Элемент.Значение); + + Если Элемент.Значение.Количество() = 0 Тогда + СтруктураДанных.Удалить(Элемент.Ключ); + КонецЕсли; + + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + +Процедура ЗаполнитьИнформациюПоТипамДанныхПриемника(СтруктураДанных, Правила) + + Для Каждого Строка Из Правила Цикл + + Если ПустаяСтрока(Строка.Приемник) Тогда + Продолжить; + КонецЕсли; + + ДанныеСтруктуры = СтруктураДанных[Строка.Приемник]; + Если ДанныеСтруктуры = Неопределено Тогда + + ДанныеСтруктуры = Новый Соответствие(); + СтруктураДанных[Строка.Приемник] = ДанныеСтруктуры; + + КонецЕсли; + + // Обходим поля поиска и ПКС и запоминаем типы данных. + ЗаполнитьСвойстваДляПоиска(ДанныеСтруктуры, Строка.СвойстваПоиска); + + // Свойства + ЗаполнитьСвойстваДляПоиска(ДанныеСтруктуры, Строка.Свойства); + + КонецЦикла; + + УдалитьЛишниеЭлементыИзСоответствия(СтруктураДанных); + +КонецПроцедуры + +Процедура СоздатьСтрокуСТипамиСвойств(ЗаписьXML, ТипыСвойств) + + Если ТипЗнч(ТипыСвойств.Значение) = одТипСоответствие Тогда + + Если ТипыСвойств.Значение.Количество() = 0 Тогда + Возврат; + КонецЕсли; + + ЗаписьXML.ЗаписатьНачалоЭлемента(ТипыСвойств.Ключ); + + Для Каждого Элемент Из ТипыСвойств.Значение Цикл + СоздатьСтрокуСТипамиСвойств(ЗаписьXML, Элемент); + КонецЦикла; + + ЗаписьXML.ЗаписатьКонецЭлемента(); + + Иначе + + одЗаписатьЭлемент(ЗаписьXML, ТипыСвойств.Ключ, ТипыСвойств.Значение); + + КонецЕсли; + +КонецПроцедуры + +Функция СоздатьСтрокуСТипамиДляПриемника(СтруктураДанных) + + ЗаписьXML = Новый ЗаписьXML; + ЗаписьXML.УстановитьСтроку(); + ЗаписьXML.ЗаписатьНачалоЭлемента("ИнформацияОТипахДанных"); + + Для Каждого Строка Из СтруктураДанных Цикл + + ЗаписьXML.ЗаписатьНачалоЭлемента("ТипДанных"); + УстановитьАтрибут(ЗаписьXML, "Имя", Строка.Ключ); + + Для Каждого СтрокаПодчинения Из Строка.Значение Цикл + + СоздатьСтрокуСТипамиСвойств(ЗаписьXML, СтрокаПодчинения); + + КонецЦикла; + + ЗаписьXML.ЗаписатьКонецЭлемента(); + + КонецЦикла; + + ЗаписьXML.ЗаписатьКонецЭлемента(); + + СтрокаРезультата = ЗаписьXML.Закрыть(); + Возврат СтрокаРезультата; + +КонецФункции + +Процедура ЗагрузитьОдинТипДанных(ПравилаОбмена, СоответствиеТипа, ИмяЛокальногоЭлемента) + + ИмяУзла = ИмяЛокальногоЭлемента; + + ПравилаОбмена.Прочитать(); + + Если (ПравилаОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + + ПравилаОбмена.Прочитать(); + Возврат; + + ИначеЕсли ПравилаОбмена.ТипУзла = одТипУзлаXML_НачалоЭлемента Тогда + + // это новый элемент + НовоеСоответствие = Новый Соответствие; + СоответствиеТипа.Вставить(ИмяУзла, НовоеСоответствие); + + ЗагрузитьОдинТипДанных(ПравилаОбмена, НовоеСоответствие, ПравилаОбмена.ЛокальноеИмя); + ПравилаОбмена.Прочитать(); + + Иначе + СоответствиеТипа.Вставить(ИмяУзла, Тип(ПравилаОбмена.Значение)); + ПравилаОбмена.Прочитать(); + КонецЕсли; + + ЗагрузитьСоответствиеТиповДляОдногоТипа(ПравилаОбмена, СоответствиеТипа); + +КонецПроцедуры + +Процедура ЗагрузитьСоответствиеТиповДляОдногоТипа(ПравилаОбмена, СоответствиеТипа) + + Пока ПравилаОбмена.Прочитать() Цикл + + ИмяУзла = ПравилаОбмена.ЛокальноеИмя; + + Если (ПравилаОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + + Прервать; + + КонецЕсли; + + // прочитали начало элемента + ПравилаОбмена.Прочитать(); + + Если ПравилаОбмена.ТипУзла = одТипУзлаXML_НачалоЭлемента Тогда + + // это новый элемент + НовоеСоответствие = Новый Соответствие; + СоответствиеТипа.Вставить(ИмяУзла, НовоеСоответствие); + + ЗагрузитьОдинТипДанных(ПравилаОбмена, НовоеСоответствие, ПравилаОбмена.ЛокальноеИмя); + + Иначе + СоответствиеТипа.Вставить(ИмяУзла, Тип(ПравилаОбмена.Значение)); + ПравилаОбмена.Прочитать(); + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + +Процедура ЗагрузитьИнформациюОТипахДанных() + + Пока ФайлОбмена.Прочитать() Цикл + + ИмяУзла = ФайлОбмена.ЛокальноеИмя; + + Если ИмяУзла = "ТипДанных" Тогда + + ИмяТипа = одАтрибут(ФайлОбмена, одТипСтрока, "Имя"); + + СоответствиеТипа = Новый Соответствие; + мСоответствиеТиповДанныхДляЗагрузки.Вставить(Тип(ИмяТипа), СоответствиеТипа); + + ЗагрузитьСоответствиеТиповДляОдногоТипа(ФайлОбмена, СоответствиеТипа); + + ИначеЕсли (ИмяУзла = "ИнформацияОТипахДанных") И (ФайлОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + + Прервать; + + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + +Процедура ЗагрузитьЗначенияПараметровОбменаДанными() + + Если БезопасныйРежим Тогда + УстановитьБезопасныйРежим(Истина); + Для Каждого ИмяРазделителя Из РазделителиКонфигурации Цикл + УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина); + КонецЦикла; + КонецЕсли; + + Имя = одАтрибут(ФайлОбмена, одТипСтрока, "Имя"); + + ТипСвойства = ПолучитьТипСвойстваПоДополнительнымДанным(Неопределено, Имя); + + Значение = ПрочитатьСвойство(ТипСвойства); + + Параметры.Вставить(Имя, Значение); + + АлгоритмПослеЗагрузкиПараметра = ""; + Если СобытияПослеЗагрузкиПараметров.Свойство(Имя, АлгоритмПослеЗагрузкиПараметра) + И Не ПустаяСтрока(АлгоритмПослеЗагрузкиПараметра) Тогда + + Если ФлагРежимОтладкиОбработчиков Тогда + + ВызватьИсключение НСтр("ru = 'Отладка обработчика ""После загрузки параметра"" не поддерживается.'"); + + Иначе + + Выполнить(АлгоритмПослеЗагрузкиПараметра); + + КонецЕсли; + + КонецЕсли; + +КонецПроцедуры + +Функция ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена) + + ТекстОбработчика = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + + Если СтрНайти(ТекстОбработчика, Символы.ПС) = 0 Тогда + Возврат ТекстОбработчика; + КонецЕсли; + + ТекстОбработчика = СтрЗаменить(ТекстОбработчика, Символ(10), Символы.ПС); + + Возврат ТекстОбработчика; + +КонецФункции + +// Осуществляет загрузку правил обмена в соответствии с форматом. +// +// Параметры: +// Источник - Объект, из которого осуществляется загрузка правил обмена; +// ТипИсточника - Строка, указывающая тип источника: "XMLФайл", "ЧтениеXML", "Строка". +// +Процедура ЗагрузитьПравилаОбмена(Источник="", ТипИсточника="XMLФайл") Экспорт + + ИнициализироватьМенеджерыИСообщения(); + + ЕстьГлобальныйОбработчикПередВыгрузкойОбъекта = Ложь; + ЕстьГлобальныйОбработчикПослеВыгрузкиОбъекта = Ложь; + + ЕстьГлобальныйОбработчикПередКонвертациейОбъекта = Ложь; + + ЕстьГлобальныйОбработчикПередЗагрузкойОбъекта = Ложь; + ЕстьГлобальныйОбработчикПослеЗагрузкиОбъекта = Ложь; + + СоздатьСтруктуруКонвертации(); + + мТаблицаПравилКонвертацииСвойств = Новый ТаблицаЗначений; + ИнициализацияТаблицыПравилКонвертацииСвойств(мТаблицаПравилКонвертацииСвойств); + ДополнитьСлужебныеТаблицыКолонками(); + + // Возможно выбраны встроенные правила обмена (один из макетов). + + ИмяВременногоФайлаПравилОбмена = ""; + Если ПустаяСтрока(Источник) Тогда + + Источник = ИмяФайлаПравилОбмена; + Если мСписокМакетовПравилОбмена.НайтиПоЗначению(Источник) <> Неопределено Тогда + Для каждого Макет Из Метаданные().Макеты Цикл + Если Макет.Синоним = Источник Тогда + Источник = Макет.Имя; + Прервать; + КонецЕсли; + КонецЦикла; + МакетПравилОбмена = ПолучитьМакет(Источник); + ИмяВременногоФайлаПравилОбмена = ПолучитьИмяВременногоФайла("xml"); + МакетПравилОбмена.Записать(ИмяВременногоФайлаПравилОбмена); + Источник = ИмяВременногоФайлаПравилОбмена; + КонецЕсли; + + КонецЕсли; + + + Если ТипИсточника="XMLФайл" Тогда + + Если ПустаяСтрока(Источник) Тогда + ЗаписатьВПротоколВыполнения(12); + Возврат; + КонецЕсли; + + Файл = Новый Файл(Источник); + Если Не Файл.Существует() Тогда + ЗаписатьВПротоколВыполнения(3); + Возврат; + КонецЕсли; + + ФайлПравилЗапакован = (Файл.Расширение = ".zip"); + + Если ФайлПравилЗапакован Тогда + + // распаковка файла правил + Источник = РаспаковатьZipФайл(Источник); + + КонецЕсли; + + ПравилаОбмена = Новый ЧтениеXML(); + ПравилаОбмена.ОткрытьФайл(Источник); + ПравилаОбмена.Прочитать(); + + ИначеЕсли ТипИсточника="Строка" Тогда + + ПравилаОбмена = Новый ЧтениеXML(); + ПравилаОбмена.УстановитьСтроку(Источник); + ПравилаОбмена.Прочитать(); + + ИначеЕсли ТипИсточника="ЧтениеXML" Тогда + + ПравилаОбмена = Источник; + + КонецЕсли; + + + Если Не ((ПравилаОбмена.ЛокальноеИмя = "ПравилаОбмена") И (ПравилаОбмена.ТипУзла = одТипУзлаXML_НачалоЭлемента)) Тогда + ЗаписатьВПротоколВыполнения(6); + Возврат; + КонецЕсли; + + + ЗаписьXML = Новый ЗаписьXML; + ЗаписьXML.УстановитьСтроку(); + ЗаписьXML.Отступ = Истина; + ЗаписьXML.ЗаписатьНачалоЭлемента("ПравилаОбмена"); + + + Пока ПравилаОбмена.Прочитать() Цикл + + ИмяУзла = ПравилаОбмена.ЛокальноеИмя; + + // Реквизиты конвертации + Если ИмяУзла = "ВерсияФормата" Тогда + Значение = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + Конвертация.Вставить("ВерсияФормата", Значение); + одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение); + ИначеЕсли ИмяУзла = "Ид" Тогда + Значение = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + Конвертация.Вставить("Ид", Значение); + одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение); + ИначеЕсли ИмяУзла = "Наименование" Тогда + Значение = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + Конвертация.Вставить("Наименование", Значение); + одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение); + ИначеЕсли ИмяУзла = "ДатаВремяСоздания" Тогда + Значение = одЗначениеЭлемента(ПравилаОбмена, одТипДата); + Конвертация.Вставить("ДатаВремяСоздания", Значение); + одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение); + ВерсияПравилОбмена = Конвертация.ДатаВремяСоздания; + ИначеЕсли ИмяУзла = "Источник" Тогда + Значение = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + Конвертация.Вставить("Источник", Значение); + одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение); + ИначеЕсли ИмяУзла = "Приемник" Тогда + + ВерсияПлатформыПриемника = ПравилаОбмена.ПолучитьАтрибут ("ВерсияПлатформы"); + ПлатформаПриемника = ОпределитьПоВерсииПлатформыПриемникаПлатформу(ВерсияПлатформыПриемника); + + Значение = одЗначениеЭлемента(ПравилаОбмена, одТипСтрока); + Конвертация.Вставить("Приемник", Значение); + одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение); + + ИначеЕсли ИмяУзла = "УдалятьСопоставленныеОбъектыВПриемникеПриИхУдаленииВИсточнике" Тогда + одПропустить(ПравилаОбмена); + + ИначеЕсли ИмяУзла = "Комментарий" Тогда + одПропустить(ПравилаОбмена); + + ИначеЕсли ИмяУзла = "ОсновнойПланОбмена" Тогда + одПропустить(ПравилаОбмена); + + ИначеЕсли ИмяУзла = "Параметры" Тогда + ЗагрузитьПараметры(ПравилаОбмена, ЗаписьXML) + + // События конвертации + + ИначеЕсли ИмяУзла = "" Тогда + + ИначеЕсли ИмяУзла = "ПослеЗагрузкиПравилОбмена" Тогда + Если РежимОбмена = "Загрузка" Тогда + ПравилаОбмена.Пропустить(); + Иначе + Конвертация.Вставить("ПослеЗагрузкиПравилОбмена", ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена)); + КонецЕсли; + ИначеЕсли ИмяУзла = "ПередВыгрузкойДанных" Тогда + Конвертация.Вставить("ПередВыгрузкойДанных", ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена)); + + ИначеЕсли ИмяУзла = "ПослеВыгрузкиДанных" Тогда + Конвертация.Вставить("ПослеВыгрузкиДанных", ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена)); + + ИначеЕсли ИмяУзла = "ПередВыгрузкойОбъекта" Тогда + Конвертация.Вставить("ПередВыгрузкойОбъекта", ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена)); + ЕстьГлобальныйОбработчикПередВыгрузкойОбъекта = Не ПустаяСтрока(Конвертация.ПередВыгрузкойОбъекта); + + ИначеЕсли ИмяУзла = "ПослеВыгрузкиОбъекта" Тогда + Конвертация.Вставить("ПослеВыгрузкиОбъекта", ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена)); + ЕстьГлобальныйОбработчикПослеВыгрузкиОбъекта = Не ПустаяСтрока(Конвертация.ПослеВыгрузкиОбъекта); + + ИначеЕсли ИмяУзла = "ПередЗагрузкойОбъекта" Тогда + + Значение = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + + Если РежимОбмена = "Загрузка" Тогда + + Конвертация.Вставить("ПередЗагрузкойОбъекта", Значение); + ЕстьГлобальныйОбработчикПередЗагрузкойОбъекта = Не ПустаяСтрока(Значение); + + Иначе + + одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение); + + КонецЕсли; + + ИначеЕсли ИмяУзла = "ПослеЗагрузкиОбъекта" Тогда + + Значение = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + + Если РежимОбмена = "Загрузка" Тогда + + Конвертация.Вставить("ПослеЗагрузкиОбъекта", Значение); + ЕстьГлобальныйОбработчикПослеЗагрузкиОбъекта = Не ПустаяСтрока(Значение); + + Иначе + + одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение); + + КонецЕсли; + + ИначеЕсли ИмяУзла = "ПередКонвертациейОбъекта" Тогда + Конвертация.Вставить("ПередКонвертациейОбъекта", ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена)); + ЕстьГлобальныйОбработчикПередКонвертациейОбъекта = Не ПустаяСтрока(Конвертация.ПередКонвертациейОбъекта); + + ИначеЕсли ИмяУзла = "ПередЗагрузкойДанных" Тогда + + Значение = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + + Если РежимОбмена = "Загрузка" Тогда + + Конвертация.ПередЗагрузкойДанных = Значение; + + Иначе + + одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение); + + КонецЕсли; + + ИначеЕсли ИмяУзла = "ПослеЗагрузкиДанных" Тогда + + Значение = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + + Если РежимОбмена = "Загрузка" Тогда + + Конвертация.ПослеЗагрузкиДанных = Значение; + + Иначе + + одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение); + + КонецЕсли; + + ИначеЕсли ИмяУзла = "ПослеЗагрузкиПараметров" Тогда + Конвертация.Вставить("ПослеЗагрузкиПараметров", ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена)); + + ИначеЕсли ИмяУзла = "ПередОтправкойИнформацииОбУдалении" Тогда + Конвертация.Вставить("ПередОтправкойИнформацииОбУдалении", одЗначениеЭлемента(ПравилаОбмена, одТипСтрока)); + + ИначеЕсли ИмяУзла = "ПередПолучениемИзмененныхОбъектов" Тогда + Конвертация.Вставить("ПередПолучениемИзмененныхОбъектов", одЗначениеЭлемента(ПравилаОбмена, одТипСтрока)); + + ИначеЕсли ИмяУзла = "ПриПолученииИнформацииОбУдалении" Тогда + + Значение = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + + Если РежимОбмена = "Загрузка" Тогда + + Конвертация.Вставить("ПриПолученииИнформацииОбУдалении", Значение); + + Иначе + + одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение); + + КонецЕсли; + + ИначеЕсли ИмяУзла = "ПослеПолученияИнформацииОбУзлахОбмена" Тогда + + Значение = ПолучитьИзТекстаЗначениеОбработчика(ПравилаОбмена); + + Если РежимОбмена = "Загрузка" Тогда + + Конвертация.Вставить("ПослеПолученияИнформацииОбУзлахОбмена", Значение); + + Иначе + + одЗаписатьЭлемент(ЗаписьXML, ИмяУзла, Значение); + + КонецЕсли; + + // Правила + + ИначеЕсли ИмяУзла = "ПравилаВыгрузкиДанных" Тогда + + Если РежимОбмена = "Загрузка" Тогда + одПропустить(ПравилаОбмена); + Иначе + ЗагрузитьПравилаВыгрузки(ПравилаОбмена); + КонецЕсли; + + ИначеЕсли ИмяУзла = "ПравилаКонвертацииОбъектов" Тогда + ЗагрузитьПравилаКонвертации(ПравилаОбмена, ЗаписьXML); + + ИначеЕсли ИмяУзла = "ПравилаОчисткиДанных" Тогда + ЗагрузитьПравилаОчистки(ПравилаОбмена, ЗаписьXML) + + ИначеЕсли ИмяУзла = "ПравилаРегистрацииОбъектов" Тогда + одПропустить(ПравилаОбмена); // Правила регистрации объектов загружаем другой обработкой. + + // Алгоритмы, Запросы, Обработки. + + ИначеЕсли ИмяУзла = "Алгоритмы" Тогда + ЗагрузитьАлгоритмы(ПравилаОбмена, ЗаписьXML); + + ИначеЕсли ИмяУзла = "Запросы" Тогда + ЗагрузитьЗапросы(ПравилаОбмена, ЗаписьXML); + + ИначеЕсли ИмяУзла = "Обработки" Тогда + ЗагрузитьОбработки(ПравилаОбмена, ЗаписьXML); + + // Выход + ИначеЕсли (ИмяУзла = "ПравилаОбмена") И (ПравилаОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + + Если РежимОбмена <> "Загрузка" Тогда + ПравилаОбмена.Закрыть(); + КонецЕсли; + Прервать; + + + // Ошибка формата + Иначе + СтруктураЗаписи = Новый Структура("ИмяУзла", ИмяУзла); + ЗаписатьВПротоколВыполнения(7, СтруктураЗаписи); + Возврат; + КонецЕсли; + КонецЦикла; + + + ЗаписьXML.ЗаписатьКонецЭлемента(); + мXMLПравила = ЗаписьXML.Закрыть(); + + Для Каждого СтрокаПравилВыгрузки Из ТаблицаПравилВыгрузки.Строки Цикл + ОбновитьПометкиВсехРодителейУПравилВыгрузки(СтрокаПравилВыгрузки, Истина); + КонецЦикла; + + // Удаляем временный файл правил. + Если Не ПустаяСтрока(ИмяВременногоФайлаПравилОбмена) Тогда + Попытка + УдалитьФайлы(ИмяВременногоФайлаПравилОбмена); + Исключение + ЗаписьЖурналаРегистрации(НСтр("ru = 'Универсальный обмен данными в формате XML'", КодОсновногоЯзыка()), + УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())); + КонецПопытки; + КонецЕсли; + + Если ТипИсточника="XMLФайл" + И ФайлПравилЗапакован Тогда + + Попытка + УдалитьФайлы(Источник); + Исключение + ЗаписьЖурналаРегистрации(НСтр("ru = 'Универсальный обмен данными в формате XML'", КодОсновногоЯзыка()), + УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())); + КонецПопытки; + + КонецЕсли; + + // Дополнительно нужна информация по типам данных приемника для быстрой загрузки данных. + СтруктураДанных = Новый Соответствие(); + ЗаполнитьИнформациюПоТипамДанныхПриемника(СтруктураДанных, ТаблицаПравилКонвертации); + + мСтрокаТиповДляПриемника = СоздатьСтрокуСТипамиДляПриемника(СтруктураДанных); + + Если БезопасныйРежим Тогда + УстановитьБезопасныйРежим(Истина); + Для Каждого ИмяРазделителя Из РазделителиКонфигурации Цикл + УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина); + КонецЦикла; + КонецЕсли; + + // Нужно вызвать событие после загрузки правил обмена. + ТекстСобытияПослеЗагрузкиПравилОбмена = ""; + Если Конвертация.Свойство("ПослеЗагрузкиПравилОбмена", ТекстСобытияПослеЗагрузкиПравилОбмена) + И Не ПустаяСтрока(ТекстСобытияПослеЗагрузкиПравилОбмена) Тогда + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + ВызватьИсключение НСтр("ru = 'Отладка обработчика ""После загрузки правил обмена"" не поддерживается.'"); + + Иначе + + Выполнить(ТекстСобытияПослеЗагрузкиПравилОбмена); + + КонецЕсли; + + Исключение + + Текст = НСтр("ru = 'Обработчик: ""ПослеЗагрузкиПравилОбмена"": %1'"); + Текст = ПодставитьПараметрыВСтроку(Текст, КраткоеПредставлениеОшибки(ИнформацияОбОшибке())); + + ЗаписьЖурналаРегистрации(НСтр("ru = 'Универсальный обмен данными в формате XML'", КодОсновногоЯзыка()), + УровеньЖурналаРегистрации.Ошибка,,, Текст); + + СообщитьПользователю(Текст); + + КонецПопытки; + + КонецЕсли; + +КонецПроцедуры + +Процедура ОбработатьОкончаниеЧтенияНовогоЭлемента(ПоследнийОбъектЗагрузки) + + мСчетчикЗагруженныхОбъектов = 1 + мСчетчикЗагруженныхОбъектов; + + Если ЗапоминатьЗагруженныеОбъекты + И мСчетчикЗагруженныхОбъектов % 100 = 0 Тогда + + Если ЗагруженныеОбъекты.Количество() > ЧислоХранимыхЗагруженныхОбъектов Тогда + ЗагруженныеОбъекты.Очистить(); + КонецЕсли; + + КонецЕсли; + + Если мСчетчикЗагруженныхОбъектов % 100 = 0 + И мГлобальныйСтекНеЗаписанныхОбъектов.Количество() > 100 Тогда + + ПровестиЗаписьНеЗаписанныхОбъектов(); + + КонецЕсли; + + Если ИспользоватьТранзакции + И КоличествоОбъектовНаТранзакцию > 0 + И мСчетчикЗагруженныхОбъектов % КоличествоОбъектовНаТранзакцию = 0 Тогда + + ЗафиксироватьТранзакцию(); + НачатьТранзакцию(); + + КонецЕсли; + +КонецПроцедуры + +// Выполняет последовательное чтение файла сообщения обмена и записывает данные в информационную базу. +// +// Параметры: +// РезультирующаяСтрокаСИнформациейОбОшибке - Строка - результирующая строка с информацией об ошибке. +// +Процедура ПроизвестиЧтениеДанных(РезультирующаяСтрокаСИнформациейОбОшибке = "") Экспорт + + Если БезопасныйРежим Тогда + УстановитьБезопасныйРежим(Истина); + Для Каждого ИмяРазделителя Из РазделителиКонфигурации Цикл + УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина); + КонецЦикла; + КонецЕсли; + + Попытка + + Пока ФайлОбмена.Прочитать() Цикл + + ИмяУзла = ФайлОбмена.ЛокальноеИмя; + + Если ИмяУзла = "Объект" Тогда + + ПоследнийОбъектЗагрузки = ПрочитатьОбъект(); + + ОбработатьОкончаниеЧтенияНовогоЭлемента(ПоследнийОбъектЗагрузки); + + ИначеЕсли ИмяУзла = "ЗначениеПараметра" Тогда + + ЗагрузитьЗначенияПараметровОбменаДанными(); + + ИначеЕсли ИмяУзла = "АлгоритмПослеЗагрузкиПараметров" Тогда + + Отказ = Ложь; + ПричинаОтказа = ""; + + ТекстАлгоритма = ""; + Конвертация.Свойство("ПослеЗагрузкиПараметров", ТекстАлгоритма); + + // При загрузке в безопасном режиме текст алгоритма получен при чтении правил. + // В противном случае его следует получать из файла обмена. + Если ПустаяСтрока(ТекстАлгоритма) Тогда + ТекстАлгоритма = одЗначениеЭлемента(ФайлОбмена, одТипСтрока); + Иначе + ФайлОбмена.Пропустить(); + КонецЕсли; + + Если Не ПустаяСтрока(ТекстАлгоритма) Тогда + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + ВызватьИсключение НСтр("ru = 'Отладка обработчика ""После загрузки параметров"" не поддерживается.'"); + + Иначе + + Выполнить(ТекстАлгоритма); + + КонецЕсли; + + Если Отказ = Истина Тогда + + Если Не ПустаяСтрока(ПричинаОтказа) Тогда + СтрокаИсключения = ПодставитьПараметрыВСтроку(НСтр("ru = 'Загрузка данных отменена по причине: %1'"), ПричинаОтказа); + ВызватьИсключение СтрокаИсключения; + Иначе + ВызватьИсключение НСтр("ru = 'Загрузка данных отменена'"); + КонецЕсли; + + КонецЕсли; + + Исключение + + ЗП = ПолучитьСтруктуруЗаписиПротокола(75, ОписаниеОшибки()); + ЗП.Обработчик = "ПослеЗагрузкиПараметров"; + СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(75, ЗП, Истина); + + Если Не ФлагРежимОтладки Тогда + ВызватьИсключение СтрокаСообщенияОбОшибке; + КонецЕсли; + + КонецПопытки; + + КонецЕсли; + + ИначеЕсли ИмяУзла = "Алгоритм" Тогда + + ТекстАлгоритма = одЗначениеЭлемента(ФайлОбмена, одТипСтрока); + + Если Не ПустаяСтрока(ТекстАлгоритма) Тогда + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + ВызватьИсключение НСтр("ru = 'Отладка глобального алгоритма не поддерживается.'"); + + Иначе + + Выполнить(ТекстАлгоритма); + + КонецЕсли; + + Исключение + + ЗП = ПолучитьСтруктуруЗаписиПротокола(39, ОписаниеОшибки()); + ЗП.Обработчик = "АлгоритмФайлаОбмена"; + СтрокаСообщенияОбОшибке = ЗаписатьВПротоколВыполнения(39, ЗП, Истина); + + Если Не ФлагРежимОтладки Тогда + ВызватьИсключение СтрокаСообщенияОбОшибке; + КонецЕсли; + + КонецПопытки; + + КонецЕсли; + + ИначеЕсли ИмяУзла = "ПравилаОбмена" Тогда + + мБылиПрочитаныПравилаОбменаПриЗагрузке = Истина; + + Если ТаблицаПравилКонвертации.Количество() = 0 Тогда + ЗагрузитьПравилаОбмена(ФайлОбмена, "ЧтениеXML"); + Иначе + одПропустить(ФайлОбмена); + КонецЕсли; + + ИначеЕсли ИмяУзла = "ИнформацияОТипахДанных" Тогда + + ЗагрузитьИнформациюОТипахДанных(); + + ИначеЕсли (ИмяУзла = "ФайлОбмена") И (ФайлОбмена.ТипУзла = одТипУзлаXML_КонецЭлемента) Тогда + + Иначе + СтруктураЗаписи = Новый Структура("ИмяУзла", ИмяУзла); + ЗаписатьВПротоколВыполнения(9, СтруктураЗаписи); + КонецЕсли; + + КонецЦикла; + + Исключение + + СтрокаОшибки = ПодставитьПараметрыВСтроку(НСтр("ru = 'Ошибка при загрузке данных: %1'"), ОписаниеОшибки()); + + РезультирующаяСтрокаСИнформациейОбОшибке = ЗаписатьВПротоколВыполнения(СтрокаОшибки, Неопределено, Истина, , , Истина); + + ЗавершитьВедениеПротоколаОбмена(); + ФайлОбмена.Закрыть(); + Возврат; + + КонецПопытки; + +КонецПроцедуры + +// Перед началом чтения данных из файла выполняем инициализацию переменных, +// загрузку правил обмена из файла данных, +// открываем транзакцию на запись данных в ИБ, +// выполняем необходимые обработчики событий. +// +// Параметры: +// СтрокаДанных - имя файла для загрузки данных или строка-XML, содержащая данные для загрузки. +// +// Возвращаемое значение: +// Булево - Истина - загрузка данных из файла возможна; Ложь - нет. +// +Функция ВыполнитьДействияПередЧтениемДанных(СтрокаДанных = "") Экспорт + + РежимОбработкиДанных = мРежимыОбработкиДанных.Загрузка; + + мСоответствиеДопПараметровПоиска = Новый Соответствие; + мСоответствиеПравилКонвертации = Новый Соответствие; + + Правила.Очистить(); + + ИнициализироватьКомментарииПриВыгрузкеИЗагрузкеДанных(); + + ИнициализироватьВедениеПротоколаОбмена(); + + ЗагрузкаВозможна = Истина; + + Если ПустаяСтрока(СтрокаДанных) Тогда + + Если ПустаяСтрока(ИмяФайлаОбмена) Тогда + ЗаписатьВПротоколВыполнения(15); + ЗагрузкаВозможна = Ложь; + КонецЕсли; + + КонецЕсли; + + // Инициализируем внешнюю обработку с экспортными обработчиками. + ИнициализацияВнешнейОбработкиОбработчиковСобытий(ЗагрузкаВозможна, ЭтотОбъект); + + Если Не ЗагрузкаВозможна Тогда + Возврат Ложь; + КонецЕсли; + + СтрокаСообщения = ПодставитьПараметрыВСтроку(НСтр("ru = 'Начало загрузки: %1'"), ТекущаяДатаСеанса()); + ЗаписатьВПротоколВыполнения(СтрокаСообщения, , Ложь, , , Истина); + + Если ФлагРежимОтладки Тогда + ИспользоватьТранзакции = Ложь; + КонецЕсли; + + Если КоличествоОбработанныхОбъектовДляОбновленияСтатуса = 0 Тогда + + КоличествоОбработанныхОбъектовДляОбновленияСтатуса = 100; + + КонецЕсли; + + мСоответствиеТиповДанныхДляЗагрузки = Новый Соответствие; + мГлобальныйСтекНеЗаписанныхОбъектов = Новый Соответствие; + + мСчетчикЗагруженныхОбъектов = 0; + ФлагОшибки = Ложь; + ЗагруженныеОбъекты = Новый Соответствие; + ЗагруженныеГлобальныеОбъекты = Новый Соответствие; + + ИнициализироватьМенеджерыИСообщения(); + + ОткрытьФайлЗагрузки(,СтрокаДанных); + + Если ФлагОшибки Тогда + ЗавершитьВедениеПротоколаОбмена(); + Возврат Ложь; + КонецЕсли; + + // Определяем интерфейсы обработчиков. + Если ФлагРежимОтладкиОбработчиков Тогда + + ДополнитьПравилаИнтерфейсамиОбработчиков(Конвертация, ТаблицаПравилКонвертации, ТаблицаПравилВыгрузки, ТаблицаПравилОчистки); + + КонецЕсли; + + // Обработчик ПередЗагрузкойДанных + Отказ = Ложь; + + Если БезопасныйРежим Тогда + УстановитьБезопасныйРежим(Истина); + Для Каждого ИмяРазделителя Из РазделителиКонфигурации Цикл + УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина); + КонецЦикла; + КонецЕсли; + + Если Не ПустаяСтрока(Конвертация.ПередЗагрузкойДанных) Тогда + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(Конвертация, "ПередЗагрузкойДанных")); + + Иначе + + Выполнить(Конвертация.ПередЗагрузкойДанных); + + КонецЕсли; + + Исключение + ЗаписатьИнформациюОбОшибкеОбработчикиКонвертации(22, ОписаниеОшибки(), НСтр("ru = 'ПередЗагрузкойДанных (конвертация)'")); + Отказ = Истина; + КонецПопытки; + + Если Отказ Тогда // Отказ от загрузки данных + ЗавершитьВедениеПротоколаОбмена(); + ФайлОбмена.Закрыть(); + ДеструкторВнешнейОбработкиОбработчиковСобытий(); + Возврат Ложь; + КонецЕсли; + + КонецЕсли; + + // Очистка информационной базы по правилам. + ОбработатьПравилаОчистки(ТаблицаПравилОчистки.Строки); + + Возврат Истина; + +КонецФункции + +// Процедура выполняет действия после итерации загрузки данных: +// - фиксация транзакции (при необходимости) +// - закрытие файла сообщения обмена +// - выполнение обработчика конвертации ПослеЗагрузкиДанных +// - завершение ведения протокола обмена (при необходимости). +// +// Параметры: +// Нет. +// +Процедура ВыполнитьДействияПослеЗавершенияЧтенияДанных() Экспорт + + Если БезопасныйРежим Тогда + УстановитьБезопасныйРежим(Истина); + Для Каждого ИмяРазделителя Из РазделителиКонфигурации Цикл + УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина); + КонецЦикла; + КонецЕсли; + + ФайлОбмена.Закрыть(); + + // Обработчик ПослеЗагрузкиДанных + Если Не ПустаяСтрока(Конвертация.ПослеЗагрузкиДанных) Тогда + + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(Конвертация, "ПослеЗагрузкиДанных")); + + Иначе + + Выполнить(Конвертация.ПослеЗагрузкиДанных); + + КонецЕсли; + + Исключение + ЗаписатьИнформациюОбОшибкеОбработчикиКонвертации(23, ОписаниеОшибки(), НСтр("ru = 'ПослеЗагрузкиДанных (конвертация)'")); + КонецПопытки; + + КонецЕсли; + + ДеструкторВнешнейОбработкиОбработчиковСобытий(); + + ЗаписатьВПротоколВыполнения(ПодставитьПараметрыВСтроку( + НСтр("ru = 'Окончание загрузки: %1'"), ТекущаяДатаСеанса()), , Ложь, , , Истина); + ЗаписатьВПротоколВыполнения(ПодставитьПараметрыВСтроку( + НСтр("ru = 'Загружено объектов: %1'"), мСчетчикЗагруженныхОбъектов), , Ложь, , , Истина); + + ЗавершитьВедениеПротоколаОбмена(); + + Если ЭтоИнтерактивныйРежим Тогда + СообщитьПользователю(НСтр("ru = 'Загрузка данных завершена.'")); + КонецЕсли; + +КонецПроцедуры + +// Выполняет загрузку данных в соответствии с установленными режимами (правилами обмена). +// +// Параметры: +// Нет. +// +Процедура ВыполнитьЗагрузку() Экспорт + + РаботаВозможна = ВыполнитьДействияПередЧтениемДанных(); + + Если Не РаботаВозможна Тогда + Возврат; + КонецЕсли; + + Если ИспользоватьТранзакции Тогда + НачатьТранзакцию(); + КонецЕсли; + + Попытка + ПроизвестиЧтениеДанных(); + // Отложенная запись того, что не записали с самого начала. + ПровестиЗаписьНеЗаписанныхОбъектов(); + Если ИспользоватьТранзакции Тогда + ЗафиксироватьТранзакцию(); + КонецЕсли; + Исключение + Если ИспользоватьТранзакции Тогда + ОтменитьТранзакцию(); + КонецЕсли; + КонецПопытки; + + ВыполнитьДействияПослеЗавершенияЧтенияДанных(); + +КонецПроцедуры + +Процедура СжатьРезультирующийФайлОбмена() + + Попытка + + ИмяИсходногоФайлаОбмена = ИмяФайлаОбмена; + Если АрхивироватьФайл Тогда + ИмяФайлаОбмена = СтрЗаменить(ИмяФайлаОбмена, ".xml", ".zip"); + КонецЕсли; + + Архиватор = Новый ЗаписьZipФайла(ИмяФайлаОбмена, ПарольДляСжатияФайлаОбмена, НСтр("ru = 'Файл обмена данными'")); + Архиватор.Добавить(ИмяИсходногоФайлаОбмена); + Архиватор.Записать(); + + УдалитьФайлы(ИмяИсходногоФайлаОбмена); + + Исключение + ЗаписьЖурналаРегистрации(НСтр("ru = 'Универсальный обмен данными в формате XML'", КодОсновногоЯзыка()), + УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())); + КонецПопытки; + +КонецПроцедуры + +Функция РаспаковатьZipФайл(ИмяФайлаДляРаспаковки) + + КаталогДляРаспаковки = ВременныйКаталогРаботыСФайлами; + СоздатьКаталог(КаталогДляРаспаковки); + + ИмяРаспакованногоФайла = ""; + + Попытка + + Архиватор = Новый ЧтениеZipФайла(ИмяФайлаДляРаспаковки, ПарольДляРаспаковкиФайлаОбмена); + + Если Архиватор.Элементы.Количество() > 0 Тогда + + ЭлементАрхива = Архиватор.Элементы.Получить(0); + + Архиватор.Извлечь(ЭлементАрхива, КаталогДляРаспаковки, РежимВосстановленияПутейФайловZIP.НеВосстанавливать); + ИмяРаспакованногоФайла = ПолучитьИмяФайлаОбмена(КаталогДляРаспаковки, ЭлементАрхива.Имя); + + Иначе + + ИмяРаспакованногоФайла = ""; + + КонецЕсли; + + Архиватор.Закрыть(); + + Исключение + + ЗП = ПолучитьСтруктуруЗаписиПротокола(2, ОписаниеОшибки()); + ЗаписатьВПротоколВыполнения(2, ЗП, Истина); + + Возврат ""; + + КонецПопытки; + + Возврат ИмяРаспакованногоФайла; + +КонецФункции + +Функция ВыполнитьПередачуИнформацииОНачалеОбменаВПриемник(ТекущаяСтрокаДляЗаписи) + + Если НЕ НепосредственноеЧтениеВИБПриемнике Тогда + Возврат Истина; + КонецЕсли; + + ТекущаяСтрокаДляЗаписи = ТекущаяСтрокаДляЗаписи + Символы.ПС + мXMLПравила + Символы.ПС + "ФайлОбмена>" + Символы.ПС; + + РаботаВозможна = мОбработкаДляЗагрузкиДанных.ВыполнитьДействияПередЧтениемДанных(ТекущаяСтрокаДляЗаписи); + + Возврат РаботаВозможна; + +КонецФункции + +Функция ВыполнитьПередачуИнформацииПриЗавершенииПередачиДанных() + + Если НЕ НепосредственноеЧтениеВИБПриемнике Тогда + Возврат Истина; + КонецЕсли; + + мОбработкаДляЗагрузкиДанных.ВыполнитьДействияПослеЗавершенияЧтенияДанных(); + +КонецФункции + +Процедура ПередатьДополнительныеПараметрыВПриемник() + + Для Каждого Параметр Из ТаблицаНастройкиПараметров Цикл + + Если Параметр.ПередаватьПараметрПриВыгрузке = Истина Тогда + + ПередатьОдинПараметрВПриемник(Параметр.Имя, Параметр.Значение, Параметр.ПравилоКонвертации); + + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + +Процедура ПередатьИнформациюОТипахВПриемник() + + Если Не ПустаяСтрока(мСтрокаТиповДляПриемника) Тогда + ЗаписатьВФайл(мСтрокаТиповДляПриемника); + КонецЕсли; + +КонецПроцедуры + +// Выполняет выгрузку данных в соответствии с установленными режимами (правилами обмена). +// +// Параметры: +// Нет. +// +Процедура ВыполнитьВыгрузку() Экспорт + + РежимОбработкиДанных = мРежимыОбработкиДанных.Выгрузка; + + ИнициализироватьВедениеПротоколаОбмена(); + + ИнициализироватьКомментарииПриВыгрузкеИЗагрузкеДанных(); + + ВыгрузкаВозможна = Истина; + ТекущийУровеньВложенностиВыгрузитьПоПравилу = 0; + + мСтекВызововВыгрузкиДанных = Новый ТаблицаЗначений; + мСтекВызововВыгрузкиДанных.Колонки.Добавить("Ссылка"); + мСтекВызововВыгрузкиДанных.Индексы.Добавить("Ссылка"); + + Если мБылиПрочитаныПравилаОбменаПриЗагрузке = Истина Тогда + + ЗаписатьВПротоколВыполнения(74); + ВыгрузкаВозможна = Ложь; + + КонецЕсли; + + Если ПустаяСтрока(ИмяФайлаПравилОбмена) Тогда + ЗаписатьВПротоколВыполнения(12); + ВыгрузкаВозможна = Ложь; + КонецЕсли; + + Если НЕ НепосредственноеЧтениеВИБПриемнике Тогда + + Если ПустаяСтрока(ИмяФайлаОбмена) Тогда + ЗаписатьВПротоколВыполнения(10); + ВыгрузкаВозможна = Ложь; + КонецЕсли; + + Иначе + + мОбработкаДляЗагрузкиДанных = ВыполнитьПодключениеКИБПриемнику(); + + ВыгрузкаВозможна = мОбработкаДляЗагрузкиДанных <> Неопределено; + + КонецЕсли; + + // Инициализируем внешнюю обработку с экспортными обработчиками. + ИнициализацияВнешнейОбработкиОбработчиковСобытий(ВыгрузкаВозможна, ЭтотОбъект); + + Если Не ВыгрузкаВозможна Тогда + мОбработкаДляЗагрузкиДанных = Неопределено; + Возврат; + КонецЕсли; + + ЗаписатьВПротоколВыполнения(ПодставитьПараметрыВСтроку( + НСтр("ru = 'Начало выгрузки: %1'"), ТекущаяДатаСеанса()), , Ложь, , , Истина); + + ИнициализироватьМенеджерыИСообщения(); + + мСчетчикВыгруженныхОбъектов = 0; + мСчетчикНПП = 0; + ФлагОшибки = Ложь; + + // Загрузка правил обмена + Если Конвертация.Количество() = 9 Тогда + + ЗагрузитьПравилаОбмена(); + Если ФлагОшибки Тогда + ЗавершитьВедениеПротоколаОбмена(); + мОбработкаДляЗагрузкиДанных = Неопределено; + Возврат; + КонецЕсли; + + Иначе + + Для каждого Правило Из ТаблицаПравилКонвертации Цикл + Правило.Выгруженные.Очистить(); + Правило.ВыгруженныеТолькоСсылки.Очистить(); + КонецЦикла; + + КонецЕсли; + + // Присваиваем параметры установленные в диалоге. + УстановитьПараметрыИзДиалога(); + + // Открываем файл обмена + ТекущаяСтрокаДляЗаписи = ОткрытьФайлВыгрузки() + Символы.ПС; + + Если ФлагОшибки Тогда + ФайлОбмена = Неопределено; + ЗавершитьВедениеПротоколаОбмена(); + мОбработкаДляЗагрузкиДанных = Неопределено; + Возврат; + КонецЕсли; + + // Определяем интерфейсы обработчиков. + Если ФлагРежимОтладкиОбработчиков Тогда + + ДополнитьПравилаИнтерфейсамиОбработчиков(Конвертация, ТаблицаПравилКонвертации, ТаблицаПравилВыгрузки, ТаблицаПравилОчистки); + + КонецЕсли; + + Если ИспользоватьТранзакции Тогда + НачатьТранзакцию(); + КонецЕсли; + + Отказ = Ложь; + + Попытка + + // Включаем правила обмена в файл. + ФайлОбмена.ЗаписатьСтроку(мXMLПравила); + + Отказ = Не ВыполнитьПередачуИнформацииОНачалеОбменаВПриемник(ТекущаяСтрокаДляЗаписи); + + Если Не Отказ Тогда + + Если БезопасныйРежим Тогда + УстановитьБезопасныйРежим(Истина); + Для Каждого ИмяРазделителя Из РазделителиКонфигурации Цикл + УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина); + КонецЦикла; + КонецЕсли; + + // Обработчик ПередВыгрузкойДанных + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Если Не ПустаяСтрока(Конвертация.ПередВыгрузкойДанных) Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(Конвертация, "ПередВыгрузкойДанных")); + + КонецЕсли; + + Иначе + + Выполнить(Конвертация.ПередВыгрузкойДанных); + + КонецЕсли; + + Исключение + ЗаписатьИнформациюОбОшибкеОбработчикиКонвертации(62, ОписаниеОшибки(), НСтр("ru = 'ПередВыгрузкойДанных (конвертация)'")); + Отказ = Истина; + КонецПопытки; + + Если Не Отказ Тогда + + Если ВыполнитьОбменДаннымиВОптимизированномФормате Тогда + ПередатьИнформациюОТипахВПриемник(); + КонецЕсли; + + // Нужно параметры передать в приемник. + ПередатьДополнительныеПараметрыВПриемник(); + + ТекстСобытияПослеЗагрузкиПараметров = ""; + Если Конвертация.Свойство("ПослеЗагрузкиПараметров", ТекстСобытияПослеЗагрузкиПараметров) + И Не ПустаяСтрока(ТекстСобытияПослеЗагрузкиПараметров) Тогда + + ЗаписьСобытия = Новый ЗаписьXML; + ЗаписьСобытия.УстановитьСтроку(); + одЗаписатьЭлемент(ЗаписьСобытия, "АлгоритмПослеЗагрузкиПараметров", ТекстСобытияПослеЗагрузкиПараметров); + ЗаписатьВФайл(ЗаписьСобытия); + + КонецЕсли; + + СоответствиеУзловИПравилВыгрузки = Новый Соответствие(); + СтруктураДляУдаленияРегистрацииИзменений = Новый Соответствие(); + + ОбработатьПравилаВыгрузки(КоллекцияПравилаВыгрузки().Строки, СоответствиеУзловИПравилВыгрузки); + + УдачноВыгруженоПоПланамОбмена = ОбработатьВыгрузкуДляПлановОбмена(СоответствиеУзловИПравилВыгрузки, СтруктураДляУдаленияРегистрацииИзменений); + + Если УдачноВыгруженоПоПланамОбмена Тогда + + ОбработатьИзменениеРегистрацииДляУзловОбмена(СтруктураДляУдаленияРегистрацииИзменений); + + КонецЕсли; + + // Обработчик ПослеВыгрузкиДанных + Попытка + + Если ФлагРежимОтладкиОбработчиков Тогда + + Если Не ПустаяСтрока(Конвертация.ПослеВыгрузкиДанных) Тогда + + Выполнить(ПолучитьСтрокуВызоваОбработчика(Конвертация, "ПослеВыгрузкиДанных")); + + КонецЕсли; + + Иначе + + Выполнить(Конвертация.ПослеВыгрузкиДанных); + + КонецЕсли; + + Исключение + ЗаписатьИнформациюОбОшибкеОбработчикиКонвертации(63, ОписаниеОшибки(), НСтр("ru = 'ПослеВыгрузкиДанных (конвертация)'")); + КонецПопытки; + + ПровестиЗаписьНеЗаписанныхОбъектов(); + + Если ТранзакцияАктивна() Тогда + ЗафиксироватьТранзакцию(); + КонецЕсли; + + КонецЕсли; + + КонецЕсли; + + Если Отказ Тогда + + Если ТранзакцияАктивна() Тогда + ОтменитьТранзакцию(); + КонецЕсли; + + ВыполнитьПередачуИнформацииПриЗавершенииПередачиДанных(); + + ЗавершитьВедениеПротоколаОбмена(); + мОбработкаДляЗагрузкиДанных = Неопределено; + ФайлОбмена = Неопределено; + + ДеструкторВнешнейОбработкиОбработчиковСобытий(); + + КонецЕсли; + + Исключение + + Если ТранзакцияАктивна() Тогда + ОтменитьТранзакцию(); + КонецЕсли; + + Отказ = Истина; + СтрокаОшибки = ОписаниеОшибки(); + + ЗаписатьВПротоколВыполнения(ПодставитьПараметрыВСтроку( + НСтр("ru = 'Ошибка при выгрузке данных: %1'"), СтрокаОшибки), Неопределено, Истина, , , Истина); + + ВыполнитьПередачуИнформацииПриЗавершенииПередачиДанных(); + + ЗавершитьВедениеПротоколаОбмена(); + ЗакрытьФайл(); + мОбработкаДляЗагрузкиДанных = Неопределено; + + КонецПопытки; + + Если Отказ Тогда + Возврат; + КонецЕсли; + + // Закрываем файл обмена + ЗакрытьФайл(); + + Если АрхивироватьФайл Тогда + СжатьРезультирующийФайлОбмена(); + КонецЕсли; + + ВыполнитьПередачуИнформацииПриЗавершенииПередачиДанных(); + + ЗаписатьВПротоколВыполнения(ПодставитьПараметрыВСтроку( + НСтр("ru = 'Окончание выгрузки: %1'"), ТекущаяДатаСеанса()), , Ложь, , ,Истина); + ЗаписатьВПротоколВыполнения(ПодставитьПараметрыВСтроку( + НСтр("ru = 'Выгружено объектов: %1'"), мСчетчикВыгруженныхОбъектов), , Ложь, , , Истина); + + ЗавершитьВедениеПротоколаОбмена(); + + мОбработкаДляЗагрузкиДанных = Неопределено; + + ДеструкторВнешнейОбработкиОбработчиковСобытий(); + + Если ЭтоИнтерактивныйРежим Тогда + СообщитьПользователю(НСтр("ru = 'Выгрузка данных завершена.'")); + КонецЕсли; + +КонецПроцедуры + +#КонецОбласти + +#Область УстановкаЗначенийРеквизитовИМодальныхПеременныхОбработки + +// Процедура установки значения глобальной переменной "ФлагОшибки". +// +// Параметры: +// Значение - Булево, новое значение переменной "ФлагОшибки". +// +Процедура УстановитьФлагОшибки(Значение) + + ФлагОшибки = Значение; + + Если ФлагОшибки Тогда + + ДеструкторВнешнейОбработкиОбработчиковСобытий(ФлагРежимОтладки); + + КонецЕсли; + +КонецПроцедуры + +// Возвращает текущее значение версии обработки. +// +// Параметры: +// Нет. +// +// Возвращаемое значение: +// Текущее значение версии обработки. +// +Функция ВерсияОбъектаСтрокой() Экспорт + + Возврат "2.1.8"; + +КонецФункции + +#КонецОбласти + +#Область ИнициализацияТаблицПравилОбмена + +Процедура ДобавитьНедостающиеКолонки(Колонки, Имя, Типы = Неопределено) + + Если Колонки.Найти(Имя) <> Неопределено Тогда + Возврат; + КонецЕсли; + + Колонки.Добавить(Имя, Типы); + +КонецПроцедуры + +// Инициализирует колонки таблицы правил конвертации объектов. +// +// Параметры: +// Нет. +// +Процедура ИнициализацияТаблицыПравилКонвертации() + + Колонки = ТаблицаПравилКонвертации.Колонки; + + ДобавитьНедостающиеКолонки(Колонки, "Имя"); + ДобавитьНедостающиеКолонки(Колонки, "Наименование"); + ДобавитьНедостающиеКолонки(Колонки, "Порядок"); + + ДобавитьНедостающиеКолонки(Колонки, "СинхронизироватьПоИдентификатору"); + ДобавитьНедостающиеКолонки(Колонки, "НеСоздаватьЕслиНеНайден", одОписаниеТипа("Булево")); + ДобавитьНедостающиеКолонки(Колонки, "НеВыгружатьОбъектыСвойствПоСсылкам", одОписаниеТипа("Булево")); + ДобавитьНедостающиеКолонки(Колонки, "ПродолжитьПоискПоПолямПоискаЕслиПоИдентификаторуНеНашли", одОписаниеТипа("Булево")); + ДобавитьНедостающиеКолонки(Колонки, "ПриПереносеОбъектаПоСсылкеУстанавливатьТолькоGIUD", одОписаниеТипа("Булево")); + ДобавитьНедостающиеКолонки(Колонки, "ИспользоватьБыстрыйПоискПриЗагрузке", одОписаниеТипа("Булево")); + ДобавитьНедостающиеКолонки(Колонки, "ГенерироватьНовыйНомерИлиКодЕслиНеУказан", одОписаниеТипа("Булево")); + ДобавитьНедостающиеКолонки(Колонки, "МаленькоеКоличествоОбъектов", одОписаниеТипа("Булево")); + ДобавитьНедостающиеКолонки(Колонки, "КоличествоОбращенийДляВыгрузкиСсылки", одОписаниеТипа("Число")); + ДобавитьНедостающиеКолонки(Колонки, "КоличествоЭлементовВИБ", одОписаниеТипа("Число")); + + ДобавитьНедостающиеКолонки(Колонки, "СпособВыгрузки"); + + ДобавитьНедостающиеКолонки(Колонки, "Источник"); + ДобавитьНедостающиеКолонки(Колонки, "Приемник"); + + ДобавитьНедостающиеКолонки(Колонки, "ТипИсточника", одОписаниеТипа("Строка")); + + ДобавитьНедостающиеКолонки(Колонки, "ПередВыгрузкой"); + ДобавитьНедостающиеКолонки(Колонки, "ПриВыгрузке"); + ДобавитьНедостающиеКолонки(Колонки, "ПослеВыгрузки"); + ДобавитьНедостающиеКолонки(Колонки, "ПослеВыгрузкиВФайл"); + + ДобавитьНедостающиеКолонки(Колонки, "ЕстьОбработчикПередВыгрузкой", одОписаниеТипа("Булево")); + ДобавитьНедостающиеКолонки(Колонки, "ЕстьОбработчикПриВыгрузке", одОписаниеТипа("Булево")); + ДобавитьНедостающиеКолонки(Колонки, "ЕстьОбработчикПослеВыгрузки", одОписаниеТипа("Булево")); + ДобавитьНедостающиеКолонки(Колонки, "ЕстьОбработчикПослеВыгрузкиВФайл", одОписаниеТипа("Булево")); + + ДобавитьНедостающиеКолонки(Колонки, "ПередЗагрузкой"); + ДобавитьНедостающиеКолонки(Колонки, "ПриЗагрузке"); + ДобавитьНедостающиеКолонки(Колонки, "ПослеЗагрузки"); + + ДобавитьНедостающиеКолонки(Колонки, "ПоследовательностьПолейПоиска"); + ДобавитьНедостающиеКолонки(Колонки, "ПоискПоТабличнымЧастям"); + + ДобавитьНедостающиеКолонки(Колонки, "ЕстьОбработчикПередЗагрузкой", одОписаниеТипа("Булево")); + ДобавитьНедостающиеКолонки(Колонки, "ЕстьОбработчикПриЗагрузке", одОписаниеТипа("Булево")); + ДобавитьНедостающиеКолонки(Колонки, "ЕстьОбработчикПослеЗагрузки", одОписаниеТипа("Булево")); + + ДобавитьНедостающиеКолонки(Колонки, "ЕстьОбработчикПоследовательностьПолейПоиска", одОписаниеТипа("Булево")); + + ДобавитьНедостающиеКолонки(Колонки, "СвойстваПоиска", одОписаниеТипа("ТаблицаЗначений")); + ДобавитьНедостающиеКолонки(Колонки, "Свойства", одОписаниеТипа("ТаблицаЗначений")); + + ДобавитьНедостающиеКолонки(Колонки, "Значения", одОписаниеТипа("Соответствие")); + + ДобавитьНедостающиеКолонки(Колонки, "Выгруженные", одОписаниеТипа("Соответствие")); + ДобавитьНедостающиеКолонки(Колонки, "ВыгруженныеТолькоСсылки", одОписаниеТипа("Соответствие")); + ДобавитьНедостающиеКолонки(Колонки, "ВыгружатьПредставлениеИсточника", одОписаниеТипа("Булево")); + + ДобавитьНедостающиеКолонки(Колонки, "НеЗамещать", одОписаниеТипа("Булево")); + + ДобавитьНедостающиеКолонки(Колонки, "ЗапоминатьВыгруженные", одОписаниеТипа("Булево")); + ДобавитьНедостающиеКолонки(Колонки, "ВсеОбъектыВыгружены", одОписаниеТипа("Булево")); + +КонецПроцедуры + +// Инициализирует колонки таблицы правил выгрузки данных. +// +// Параметры: +// Нет +// +Процедура ИнициализацияТаблицыПравилВыгрузки() + + Колонки = ТаблицаПравилВыгрузки.Колонки; + + ДобавитьНедостающиеКолонки(Колонки, "Включить", одОписаниеТипа("Число")); + ДобавитьНедостающиеКолонки(Колонки, "ЭтоГруппа", одОписаниеТипа("Булево")); + + ДобавитьНедостающиеКолонки(Колонки, "Имя"); + ДобавитьНедостающиеКолонки(Колонки, "Наименование"); + ДобавитьНедостающиеКолонки(Колонки, "Порядок"); + + ДобавитьНедостающиеКолонки(Колонки, "СпособОтбораДанных"); + ДобавитьНедостающиеКолонки(Колонки, "ОбъектВыборки"); + + ДобавитьНедостающиеКолонки(Колонки, "ПравилоКонвертации"); + + ДобавитьНедостающиеКолонки(Колонки, "ПередОбработкой"); + ДобавитьНедостающиеКолонки(Колонки, "ПослеОбработки"); + + ДобавитьНедостающиеКолонки(Колонки, "ПередВыгрузкой"); + ДобавитьНедостающиеКолонки(Колонки, "ПослеВыгрузки"); + + // Колонки для поддержки отбора с помощью построителя. + ДобавитьНедостающиеКолонки(Колонки, "ИспользоватьОтбор", одОписаниеТипа("Булево")); + ДобавитьНедостающиеКолонки(Колонки, "НастройкиПостроителя"); + ДобавитьНедостающиеКолонки(Колонки, "ИмяОбъектаДляЗапроса"); + ДобавитьНедостающиеКолонки(Колонки, "ИмяОбъектаДляЗапросаРегистра"); + + ДобавитьНедостающиеКолонки(Колонки, "ВыбиратьДанныеДляВыгрузкиОднимЗапросом", одОписаниеТипа("Булево")); + + ДобавитьНедостающиеКолонки(Колонки, "СсылкаНаУзелОбмена"); + + //УИ + ДобавитьНедостающиеКолонки(Колонки, "ИмяМетаданных"); + ДобавитьНедостающиеКолонки(Колонки, "Отбор"); + +КонецПроцедуры + +// Инициализирует колонки таблицы правил очистки данных. +// +// Параметры: +// Нет. +// +Процедура ИнициализацияТаблицыПравилОчистки() + + Колонки = ТаблицаПравилОчистки.Колонки; + + ДобавитьНедостающиеКолонки(Колонки, "Включить", одОписаниеТипа("Булево")); + ДобавитьНедостающиеКолонки(Колонки, "ЭтоГруппа", одОписаниеТипа("Булево")); + + ДобавитьНедостающиеКолонки(Колонки, "Имя"); + ДобавитьНедостающиеКолонки(Колонки, "Наименование"); + ДобавитьНедостающиеКолонки(Колонки, "Порядок", одОписаниеТипа("Число")); + + ДобавитьНедостающиеКолонки(Колонки, "СпособОтбораДанных"); + ДобавитьНедостающиеКолонки(Колонки, "ОбъектВыборки"); + + ДобавитьНедостающиеКолонки(Колонки, "УдалятьЗаПериод"); + ДобавитьНедостающиеКолонки(Колонки, "Непосредственно", одОписаниеТипа("Булево")); + + ДобавитьНедостающиеКолонки(Колонки, "ПередОбработкой"); + ДобавитьНедостающиеКолонки(Колонки, "ПослеОбработки"); + ДобавитьНедостающиеКолонки(Колонки, "ПередУдалением"); + +КонецПроцедуры + +// Инициализирует колонки таблицы настройки параметров. +// +// Параметры: +// Нет. +// +Процедура ИнициализацияТаблицыНастройкиПараметров() + + Колонки = ТаблицаНастройкиПараметров.Колонки; + + ДобавитьНедостающиеКолонки(Колонки, "Имя"); + ДобавитьНедостающиеКолонки(Колонки, "Наименование"); + ДобавитьНедостающиеКолонки(Колонки, "Значение"); + ДобавитьНедостающиеКолонки(Колонки, "ПередаватьПараметрПриВыгрузке"); + ДобавитьНедостающиеКолонки(Колонки, "ПравилоКонвертации"); + +КонецПроцедуры + +#КонецОбласти + +#Область ИнициализацияРеквизитовИМодульныхПеременных + +Процедура ИнициализироватьКомментарииПриВыгрузкеИЗагрузкеДанных() + + КомментарийПриВыгрузкеДанных = ""; + КомментарийПриЗагрузкеДанных = ""; + +КонецПроцедуры + +// Инициализирует переменную одСообщения, содержащую соответствия кодов сообщений их описаниям. +// +// Параметры: +// Нет. +// +Процедура ИнициализацияСообщений() + + одСообщения = Новый Соответствие; + + одСообщения.Вставить(2, НСтр("ru = 'Ошибка распаковки файла обмена. Файл заблокирован'")); + одСообщения.Вставить(3, НСтр("ru = 'Указанный файл правил обмена не существует'")); + одСообщения.Вставить(4, НСтр("ru = 'Ошибка при создании COM-объекта Msxml2.DOMDocument'")); + одСообщения.Вставить(5, НСтр("ru = 'Ошибка открытия файла обмена'")); + одСообщения.Вставить(6, НСтр("ru = 'Ошибка при загрузке правил обмена'")); + одСообщения.Вставить(7, НСтр("ru = 'Ошибка формата правил обмена'")); + одСообщения.Вставить(8, НСтр("ru = 'Некорректно указано имя файла для выгрузки данных'")); + одСообщения.Вставить(9, НСтр("ru = 'Ошибка формата файла обмена'")); + одСообщения.Вставить(10, НСтр("ru = 'Не указано имя файла для выгрузки данных (Имя файла данных)'")); + одСообщения.Вставить(11, НСтр("ru = 'Ссылка на несуществующий объект метаданных в правилах обмена'")); + одСообщения.Вставить(12, НСтр("ru = 'Не указано имя файла с правилами обмена (Имя файла правил)'")); + + одСообщения.Вставить(13, НСтр("ru = 'Ошибка получения значения свойства объекта (по имени свойства источника)'")); + одСообщения.Вставить(14, НСтр("ru = 'Ошибка получения значения свойства объекта (по имени свойства приемника)'")); + + одСообщения.Вставить(15, НСтр("ru = 'Не указано имя файла для загрузки данных (Имя файла для загрузки)'")); + + одСообщения.Вставить(16, НСтр("ru = 'Ошибка получения значения свойства подчиненного объекта (по имени свойства источника)'")); + одСообщения.Вставить(17, НСтр("ru = 'Ошибка получения значения свойства подчиненного объекта (по имени свойства приемника)'")); + + одСообщения.Вставить(19, НСтр("ru = 'Ошибка в обработчике события ПередЗагрузкойОбъекта'")); + одСообщения.Вставить(20, НСтр("ru = 'Ошибка в обработчике события ПриЗагрузкеОбъекта'")); + одСообщения.Вставить(21, НСтр("ru = 'Ошибка в обработчике события ПослеЗагрузкиОбъекта'")); + одСообщения.Вставить(22, НСтр("ru = 'Ошибка в обработчике события ПередЗагрузкойДанных (конвертация)'")); + одСообщения.Вставить(23, НСтр("ru = 'Ошибка в обработчике события ПослеЗагрузкиДанных (конвертация)'")); + одСообщения.Вставить(24, НСтр("ru = 'Ошибка при удалении объекта'")); + одСообщения.Вставить(25, НСтр("ru = 'Ошибка при записи документа'")); + одСообщения.Вставить(26, НСтр("ru = 'Ошибка записи объекта'")); + одСообщения.Вставить(27, НСтр("ru = 'Ошибка в обработчике события ПередОбработкойПравилаОчистки'")); + одСообщения.Вставить(28, НСтр("ru = 'Ошибка в обработчике события ПослеОбработкиПравилаОчистки'")); + одСообщения.Вставить(29, НСтр("ru = 'Ошибка в обработчике события ПередУдалениемОбъекта'")); + + одСообщения.Вставить(31, НСтр("ru = 'Ошибка в обработчике события ПередОбработкойПравилаВыгрузки'")); + одСообщения.Вставить(32, НСтр("ru = 'Ошибка в обработчике события ПослеОбработкиПравилаВыгрузки'")); + одСообщения.Вставить(33, НСтр("ru = 'Ошибка в обработчике события ПередВыгрузкойОбъекта'")); + одСообщения.Вставить(34, НСтр("ru = 'Ошибка в обработчике события ПослеВыгрузкиОбъекта'")); + + одСообщения.Вставить(39, НСтр("ru = 'Ошибка при выполнении алгоритма, содержащегося в файле обмена'")); + + одСообщения.Вставить(41, НСтр("ru = 'Ошибка в обработчике события ПередВыгрузкойОбъекта'")); + одСообщения.Вставить(42, НСтр("ru = 'Ошибка в обработчике события ПриВыгрузкеОбъекта'")); + одСообщения.Вставить(43, НСтр("ru = 'Ошибка в обработчике события ПослеВыгрузкиОбъекта'")); + + одСообщения.Вставить(45, НСтр("ru = 'Не найдено правило конвертации объектов'")); + + одСообщения.Вставить(48, НСтр("ru = 'Ошибка в обработчике события ПередОбработкойВыгрузки группы свойств'")); + одСообщения.Вставить(49, НСтр("ru = 'Ошибка в обработчике события ПослеОбработкиВыгрузки группы свойств'")); + одСообщения.Вставить(50, НСтр("ru = 'Ошибка в обработчике события ПередВыгрузкой (объекта коллекции)'")); + одСообщения.Вставить(51, НСтр("ru = 'Ошибка в обработчике события ПриВыгрузке (объекта коллекции)'")); + одСообщения.Вставить(52, НСтр("ru = 'Ошибка в обработчике события ПослеВыгрузки (объекта коллекции)'")); + одСообщения.Вставить(53, НСтр("ru = 'Ошибка в глобальном обработчике события ПередЗагрузкойОбъекта (конвертация)'")); + одСообщения.Вставить(54, НСтр("ru = 'Ошибка в глобальном обработчике события ПослеЗагрузкиОбъекта (конвертация)'")); + одСообщения.Вставить(55, НСтр("ru = 'Ошибка в обработчике события ПередВыгрузкой (свойства)'")); + одСообщения.Вставить(56, НСтр("ru = 'Ошибка в обработчике события ПриВыгрузке (свойства)'")); + одСообщения.Вставить(57, НСтр("ru = 'Ошибка в обработчике события ПослеВыгрузки (свойства)'")); + + одСообщения.Вставить(62, НСтр("ru = 'Ошибка в обработчике события ПередВыгрузкойДанных (конвертация)'")); + одСообщения.Вставить(63, НСтр("ru = 'Ошибка в обработчике события ПослеВыгрузкиДанных (конвертация)'")); + одСообщения.Вставить(64, НСтр("ru = 'Ошибка в глобальном обработчике события ПередКонвертациейОбъекта (конвертация)'")); + одСообщения.Вставить(65, НСтр("ru = 'Ошибка в глобальном обработчике события ПередВыгрузкойОбъекта (конвертация)'")); + одСообщения.Вставить(66, НСтр("ru = 'Ошибка получения коллекции подчиненных объектов из входящих данных'")); + одСообщения.Вставить(67, НСтр("ru = 'Ошибка получения свойства подчиненного объекта из входящих данных'")); + одСообщения.Вставить(68, НСтр("ru = 'Ошибка получения свойства объекта из входящих данных'")); + + одСообщения.Вставить(69, НСтр("ru = 'Ошибка в глобальном обработчике события ПослеВыгрузкиОбъекта (конвертация)'")); + + одСообщения.Вставить(71, НСтр("ru = 'Не найдено соответствие для значения Источника'")); + + одСообщения.Вставить(72, НСтр("ru = 'Ошибка при выгрузке данных для узла плана обмена'")); + + одСообщения.Вставить(73, НСтр("ru = 'Ошибка в обработчике события ПоследовательностьПолейПоиска'")); + + одСообщения.Вставить(74, НСтр("ru = 'Необходимо перезагрузить правила обмена для выгрузки данных'")); + + одСообщения.Вставить(75, НСтр("ru = 'Ошибка при выполнении алгоритма после загрузки значений параметров'")); + + одСообщения.Вставить(76, НСтр("ru = 'Ошибка в обработчике события ПослеВыгрузкиОбъектаВФайл'")); + + одСообщения.Вставить(77, НСтр("ru = 'Не указан файл внешней обработки с подключаемыми процедурами обработчиков событий'")); + + одСообщения.Вставить(78, НСтр("ru = 'Ошибка создания внешней обработки из файла с процедурами обработчиков событий'")); + + одСообщения.Вставить(79, НСтр("ru = 'Код алгоритмов не может быть интегрирован в обработчик из-за обнаруженного рекурсивного вызова алгоритмов. + |Если в процессе отладки нет необходимости отлаживать код алгоритмов, то укажите режим ""не отлаживать алгоритмы"" + |Если необходимо выполнять отладку алгоритмов с рекурсивным вызовом, то укажите режим ""алгоритмы отлаживать как процедуры"" + |и повторите выгрузку.'")); + + одСообщения.Вставить(80, НСтр("ru = 'Обмен данными можно проводить только под полными правами'")); + + одСообщения.Вставить(1000, НСтр("ru = 'Ошибка при создании временного файла выгрузки данных'")); + +КонецПроцедуры + +Процедура ДополнитьМассивМенеджеровСсылочнымТипом(Менеджеры, МенеджерыДляПлановОбмена, ОбъектМД, ИмяТипа, Менеджер, ПрефиксИмениТипа, ВозможенПоискПоПредопределенным = Ложь) + + Имя = ОбъектМД.Имя; + ТипСсылкиСтрокой = ПрефиксИмениТипа + "." + Имя; + СтрокаПоиска = "ВЫБРАТЬ Ссылка ИЗ " + ИмяТипа + "." + Имя + " ГДЕ "; + ТипСсылки = Тип(ТипСсылкиСтрокой); + Структура = СтруктураПараметровМенеджера(Имя, ИмяТипа, ТипСсылкиСтрокой, Менеджер, ОбъектМД); + Структура.Вставить("ВозможенПоискПоПредопределенным", ВозможенПоискПоПредопределенным); + Структура.Вставить("СтрокаПоиска", СтрокаПоиска); + Менеджеры.Вставить(ТипСсылки, Структура); + + + СтруктураДляПланаОбмена = СтруктураПараметровПланаОбмена(Имя, ТипСсылки, Истина, Ложь); + МенеджерыДляПлановОбмена.Вставить(ОбъектМД, СтруктураДляПланаОбмена); + +КонецПроцедуры + +Процедура ДополнитьМассивМенеджеровТипомРегистра(Менеджеры, ОбъектМД, ИмяТипа, Менеджер, ПрефиксИмениТипаЗапись, ПрефиксИмениТипаВыборка) + + Периодический = Неопределено; + + Имя = ОбъектМД.Имя; + ТипСсылкиСтрокой = ПрефиксИмениТипаЗапись + "." + Имя; + ТипСсылки = Тип(ТипСсылкиСтрокой); + Структура = СтруктураПараметровМенеджера(Имя, ИмяТипа, ТипСсылкиСтрокой, Менеджер, ОбъектМД); + + Если ИмяТипа = "РегистрСведений" Тогда + + Периодический = (ОбъектМД.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический); + ПодчиненныйРегистратору = (ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору); + + Структура.Вставить("Периодический", Периодический); + Структура.Вставить("ПодчиненныйРегистратору", ПодчиненныйРегистратору); + + КонецЕсли; + + Менеджеры.Вставить(ТипСсылки, Структура); + + + СтруктураДляПланаОбмена = СтруктураПараметровПланаОбмена(Имя, ТипСсылки, Ложь, Истина); + + МенеджерыДляПлановОбмена.Вставить(ОбъектМД, СтруктураДляПланаОбмена); + + + ТипСсылкиСтрокой = ПрефиксИмениТипаВыборка + "." + Имя; + ТипСсылки = Тип(ТипСсылкиСтрокой); + Структура = СтруктураПараметровМенеджера(Имя, ИмяТипа, ТипСсылкиСтрокой, Менеджер, ОбъектМД); + + Если Периодический <> Неопределено Тогда + + Структура.Вставить("Периодический", Периодический); + Структура.Вставить("ПодчиненныйРегистратору", ПодчиненныйРегистратору); + + КонецЕсли; + + Менеджеры.Вставить(ТипСсылки, Структура); + +КонецПроцедуры + +// Инициализирует переменную Менеджеры, содержащую соответствия типов объектов их свойствам. +// +// Параметры: +// Нет. +// +Процедура ИнициализацияМенеджеров() + + Менеджеры = Новый Соответствие; + + МенеджерыДляПлановОбмена = Новый Соответствие; + + // ССЫЛКИ + + Для каждого ОбъектМД Из Метаданные.Справочники Цикл + + ДополнитьМассивМенеджеровСсылочнымТипом(Менеджеры, МенеджерыДляПлановОбмена, ОбъектМД, "Справочник", Справочники[ОбъектМД.Имя], "СправочникСсылка", Истина); + + КонецЦикла; + + Для каждого ОбъектМД Из Метаданные.Документы Цикл + + ДополнитьМассивМенеджеровСсылочнымТипом(Менеджеры, МенеджерыДляПлановОбмена, ОбъектМД, "Документ", Документы[ОбъектМД.Имя], "ДокументСсылка"); + + КонецЦикла; + + Для каждого ОбъектМД Из Метаданные.ПланыВидовХарактеристик Цикл + + ДополнитьМассивМенеджеровСсылочнымТипом(Менеджеры, МенеджерыДляПлановОбмена, ОбъектМД, "ПланВидовХарактеристик", ПланыВидовХарактеристик[ОбъектМД.Имя], "ПланВидовХарактеристикСсылка", Истина); + + КонецЦикла; + + Для каждого ОбъектМД Из Метаданные.ПланыСчетов Цикл + + ДополнитьМассивМенеджеровСсылочнымТипом(Менеджеры, МенеджерыДляПлановОбмена, ОбъектМД, "ПланСчетов", ПланыСчетов[ОбъектМД.Имя], "ПланСчетовСсылка", Истина); + + КонецЦикла; + + Для каждого ОбъектМД Из Метаданные.ПланыВидовРасчета Цикл + + ДополнитьМассивМенеджеровСсылочнымТипом(Менеджеры, МенеджерыДляПлановОбмена, ОбъектМД, "ПланВидовРасчета", ПланыВидовРасчета[ОбъектМД.Имя], "ПланВидовРасчетаСсылка", Истина); + + КонецЦикла; + + Для каждого ОбъектМД Из Метаданные.ПланыОбмена Цикл + + ДополнитьМассивМенеджеровСсылочнымТипом(Менеджеры, МенеджерыДляПлановОбмена, ОбъектМД, "ПланОбмена", ПланыОбмена[ОбъектМД.Имя], "ПланОбменаСсылка"); + + КонецЦикла; + + Для каждого ОбъектМД Из Метаданные.Задачи Цикл + + ДополнитьМассивМенеджеровСсылочнымТипом(Менеджеры, МенеджерыДляПлановОбмена, ОбъектМД, "Задача", Задачи[ОбъектМД.Имя], "ЗадачаСсылка"); + + КонецЦикла; + + Для каждого ОбъектМД Из Метаданные.БизнесПроцессы Цикл + + ДополнитьМассивМенеджеровСсылочнымТипом(Менеджеры, МенеджерыДляПлановОбмена, ОбъектМД, "БизнесПроцесс", БизнесПроцессы[ОбъектМД.Имя], "БизнесПроцессСсылка"); + + ИмяТипа = "ТочкаМаршрутаБизнесПроцесса"; + // ссылка на точки маршрута + Имя = ОбъектМД.Имя; + Менеджер = БизнесПроцессы[Имя].ТочкиМаршрута; + СтрокаПоиска = ""; + ТипСсылкиСтрокой = "ТочкаМаршрутаБизнесПроцессаСсылка." + Имя; + ТипСсылки = Тип(ТипСсылкиСтрокой); + Структура = СтруктураПараметровМенеджера(Имя, ИмяТипа, ТипСсылкиСтрокой, Менеджер, ОбъектМД); + Структура.Вставить("ПустаяСсылка", Неопределено); + Структура.Вставить("СтрокаПоиска", СтрокаПоиска); + Менеджеры.Вставить(ТипСсылки, Структура); + + КонецЦикла; + + // РЕГИСТРЫ + + Для каждого ОбъектМД Из Метаданные.РегистрыСведений Цикл + + ДополнитьМассивМенеджеровТипомРегистра(Менеджеры, ОбъектМД, "РегистрСведений", РегистрыСведений[ОбъектМД.Имя], "РегистрСведенийЗапись", "РегистрСведенийВыборка"); + + КонецЦикла; + + Для каждого ОбъектМД Из Метаданные.РегистрыБухгалтерии Цикл + + ДополнитьМассивМенеджеровТипомРегистра(Менеджеры, ОбъектМД, "РегистрБухгалтерии", РегистрыБухгалтерии[ОбъектМД.Имя], "РегистрБухгалтерииЗапись", "РегистрБухгалтерииВыборка"); + + КонецЦикла; + + Для каждого ОбъектМД Из Метаданные.РегистрыНакопления Цикл + + ДополнитьМассивМенеджеровТипомРегистра(Менеджеры, ОбъектМД, "РегистрНакопления", РегистрыНакопления[ОбъектМД.Имя], "РегистрНакопленияЗапись", "РегистрНакопленияВыборка"); + + КонецЦикла; + + Для каждого ОбъектМД Из Метаданные.РегистрыРасчета Цикл + + ДополнитьМассивМенеджеровТипомРегистра(Менеджеры, ОбъектМД, "РегистрРасчета", РегистрыРасчета[ОбъектМД.Имя], "РегистрРасчетаЗапись", "РегистрРасчетаВыборка"); + + КонецЦикла; + + ИмяТипа = "Перечисление"; + + Для каждого ОбъектМД Из Метаданные.Перечисления Цикл + + Имя = ОбъектМД.Имя; + Менеджер = Перечисления[Имя]; + ТипСсылкиСтрокой = "ПеречислениеСсылка." + Имя; + ТипСсылки = Тип(ТипСсылкиСтрокой); + Структура = СтруктураПараметровМенеджера(Имя, ИмяТипа, ТипСсылкиСтрокой, Менеджер, ОбъектМД); + Структура.Вставить("ПустаяСсылка", Перечисления[Имя].ПустаяСсылка()); + + Менеджеры.Вставить(ТипСсылки, Структура); + + КонецЦикла; + + // Константы + ИмяТипа = "Константы"; + ОбъектМД = Метаданные.Константы; + Имя = "Константы"; + Менеджер = Константы; + ТипСсылкиСтрокой = "КонстантыНабор"; + ТипСсылки = Тип(ТипСсылкиСтрокой); + Структура = СтруктураПараметровМенеджера(Имя, ИмяТипа, ТипСсылкиСтрокой, Менеджер, ОбъектМД); + Менеджеры.Вставить(ТипСсылки, Структура); + +КонецПроцедуры + +// Выполняет инициализация менеджеров объектов и всех сообщений протокола обмена данными. +// +// Параметры: +// Нет. +// +Процедура ИнициализироватьМенеджерыИСообщения() Экспорт + + Если Менеджеры = Неопределено Тогда + ИнициализацияМенеджеров(); + КонецЕсли; + + Если одСообщения = Неопределено Тогда + ИнициализацияСообщений(); + КонецЕсли; + +КонецПроцедуры + +// Возвращаемое значение: +// Структура - поля: +// * ВерсияФормата - Строка - +// * Ид - Строка - +// * Наименование - Строка - +// * ДатаВремяСоздания - Дата - +// * ВерсияПлатформыИсточника - Строка - +// * СинонимКонфигурацииИсточника - Строка - +// * ВерсияКонфигурацииИсточника - Строка - +// * Источник - Строка - +// * ВерсияПлатформыПриемника - Строка - +// * СинонимКонфигурацииПриемника - Строка - +// * ВерсияКонфигурацииПриемника - Строка - +// * Приемник - Строка - +// * ПослеЗагрузкиПравилОбмена - Строка - +// * ПередВыгрузкойДанных - Строка - +// * ПередПолучениемИзмененныхОбъектов - Строка - +// * ПослеПолученияИнформацииОбУзлахОбмена - Строка - +// * ПослеВыгрузкиДанных - Строка - +// * ПередОтправкойИнформацииОбУдалении - Строка - +// * ПередВыгрузкойОбъекта - Строка - +// * ПослеВыгрузкиОбъекта - Строка - +// * ПередЗагрузкойОбъекта - Строка - +// * ПослеЗагрузкиОбъекта - Строка - +// * ПередКонвертациейОбъекта - Строка - +// * ПередЗагрузкойДанных - Строка - +// * ПослеЗагрузкиДанных - Строка - +// * ПослеЗагрузкиПараметров - Строка - +// * ПриПолученииИнформацииОбУдалении - Строка - +// +Функция Конвертация() + Возврат Конвертация; +КонецФункции + +// Возвращаемое значение: +// Структура - содержит поля: +// * Имя - Строка - +// * ИмяТипа - Строка - +// * ТипСсылкиСтрокой - Строка - +// * Менеджер - СправочникМенеджер, ДокументМенеджер, РегистрСведенийМенеджер, и т.п. - +// * ОбъектМД - ОбъектМетаданныхСправочник, ОбъектМетаданныхДокумент, ОбъектМетаданныхРегистрСведений, и т.п. - +// * ПКО - см. НайтиПравило +// +Функция Менеджеры(Тип) + Возврат Менеджеры[Тип]; +КонецФункции + +Процедура СоздатьСтруктуруКонвертации() + + Конвертация = Новый Структура("ПередВыгрузкойДанных, ПослеВыгрузкиДанных, ПередВыгрузкойОбъекта, ПослеВыгрузкиОбъекта, ПередКонвертациейОбъекта, ПередЗагрузкойОбъекта, ПослеЗагрузкиОбъекта, ПередЗагрузкойДанных, ПослеЗагрузкиДанных"); + +КонецПроцедуры + +// Инициализирует реквизиты обработки и модульные переменные. +// +// Параметры: +// Нет. +// +Процедура ИнициализацияРеквизитовИМодульныхПеременных() + + КоличествоОбработанныхОбъектовДляОбновленияСтатуса = 100; + + ЗапоминатьЗагруженныеОбъекты = Истина; + ЧислоХранимыхЗагруженныхОбъектов = 5000; + + ПараметрыИнициализированы = Ложь; + + ВестиДополнительныйКонтрольЗаписиВXML = Ложь; + НепосредственноеЧтениеВИБПриемнике = Ложь; + НеВыводитьНикакихИнформационныхСообщенийПользователю = Ложь; + + Менеджеры = Неопределено; + одСообщения = Неопределено; + + ФлагОшибки = Ложь; + + СоздатьСтруктуруКонвертации(); + + Правила = Новый Структура; + Алгоритмы = Новый Структура; + ДопОбработки = Новый Структура; + Запросы = Новый Структура; + + Параметры = Новый Структура; + СобытияПослеЗагрузкиПараметров = Новый Структура; + + ПараметрыДопОбработок = Новый Структура; + + // Типы + одТипСтрока = Тип("Строка"); + одТипБулево = Тип("Булево"); + одТипЧисло = Тип("Число"); + одТипДата = Тип("Дата"); + одТипХранилищеЗначения = Тип("ХранилищеЗначения"); + одТипУникальныйИдентификатор = Тип("УникальныйИдентификатор"); + одТипДвоичныеДанные = Тип("ДвоичныеДанные"); + одТипВидДвиженияНакопления = Тип("ВидДвиженияНакопления"); + одТипУдалениеОбъекта = Тип("УдалениеОбъекта"); + одТипВидСчета = Тип("ВидСчета"); + одТипТип = Тип("Тип"); + одТипСоответствие = Тип("Соответствие"); + + ЗначениеПустаяДата = Дата('00010101'); + + мXMLПравила = Неопределено; + + // Типы узлов xml + + одТипУзлаXML_КонецЭлемента = ТипУзлаXML.КонецЭлемента; + одТипУзлаXML_НачалоЭлемента = ТипУзлаXML.НачалоЭлемента; + одТипУзлаXML_Текст = ТипУзлаXML.Текст; + + + мСписокМакетовПравилОбмена = Новый СписокЗначений; + + Для каждого Макет Из Метаданные().Макеты Цикл + мСписокМакетовПравилОбмена.Добавить(Макет.Синоним); + КонецЦикла; + + мФайлПротоколаДанных = Неопределено; + + ТипИнформационнойБазыДляПодключения = Истина; + АутентификацияWindowsИнформационнойБазыДляПодключения = Ложь; + ВерсияПлатформыИнформационнойБазыДляПодключения = "V8"; + ОткрыватьПротоколыОбменаПослеВыполненияОпераций = Ложь; + ЗагружатьДанныеВРежимеОбмена = Истина; + ЗаписыватьВИнформационнуюБазуТолькоИзмененныеОбъекты = Истина; + ЗаписыватьРегистрыНаборамиЗаписей = Истина; + ОптимизированнаяЗаписьОбъектов = Истина; + ВыгружатьТолькоРазрешенные = Истина; + ОбъектыПоСсылкеЗагружатьБезПометкиУдаления = Истина; + ИспользоватьОтборПоДатеДляВсехОбъектов = Истина; + + мСоответствиеПустыхЗначенийТипов = Новый Соответствие; + мСоответствиеОписаниеТипов = Новый Соответствие; + + мБылиПрочитаныПравилаОбменаПриЗагрузке = Ложь; + + ОбработчикиСобытийЧитаемИзФайлаПравилОбмена = Истина; + + мРежимыОбработкиДанных = Новый Структура; + мРежимыОбработкиДанных.Вставить("Выгрузка", 0); + мРежимыОбработкиДанных.Вставить("Загрузка", 1); + мРежимыОбработкиДанных.Вставить("ЗагрузкаПравилОбмена", 2); + мРежимыОбработкиДанных.Вставить("ЭкспортОбработчиковСобытий", 3); + + РежимОбработкиДанных = мРежимыОбработкиДанных.Выгрузка; + + мРежимыОтладкиАлгоритмов = Новый Структура; + мРежимыОтладкиАлгоритмов.Вставить("НеИспользовать", 0); + мРежимыОтладкиАлгоритмов.Вставить("ПроцедурныйВызов", 1); + мРежимыОтладкиАлгоритмов.Вставить("ИнтеграцияКода", 2); + + РежимОтладкиАлгоритмов = мРежимыОтладкиАлгоритмов.НеИспользовать; + + // Модули стандартных подсистем. + Попытка + // Вызов ВычислитьВБезопасномРежиме не требуется, т.к. для вычисления передается строковый литерал. + МодульДатыЗапретаИзменения = Вычислить("ДатыЗапретаИзменения"); + Исключение + МодульДатыЗапретаИзменения = Неопределено; + КонецПопытки; + + РазделителиКонфигурации = Новый Массив; + Для Каждого ОбщийРеквизит Из Метаданные.ОбщиеРеквизиты Цикл + Если ОбщийРеквизит.РазделениеДанных = Метаданные.СвойстваОбъектов.РазделениеДанныхОбщегоРеквизита.Разделять Тогда + РазделителиКонфигурации.Добавить(ОбщийРеквизит.Имя); + КонецЕсли; + КонецЦикла; + РазделителиКонфигурации = Новый ФиксированныйМассив(РазделителиКонфигурации); + + ВременныйКаталогРаботыСФайлами = ПолучитьИмяВременногоФайла(); + УдалитьФайлы(ВременныйКаталогРаботыСФайлами); + +КонецПроцедуры + +Функция ОпределитьДостаточностьПараметровДляПодключенияКИнформационнойБазе(СтруктураПодключения, СтрокаПодключения = "", СтрокаСообщенияОбОшибке = "") + + НаличиеОшибок = Ложь; + + Если СтруктураПодключения.ФайловыйРежим Тогда + + Если ПустаяСтрока(СтруктураПодключения.КаталогИБ) Тогда + + СтрокаСообщенияОбОшибке = НСтр("ru = 'Не задан каталог информационной базы-приемника'"); + + СообщитьПользователю(СтрокаСообщенияОбОшибке); + + НаличиеОшибок = Истина; + + КонецЕсли; + + СтрокаПодключения = "File=""" + СтруктураПодключения.КаталогИБ + """"; + Иначе + + Если ПустаяСтрока(СтруктураПодключения.ИмяСервера) Тогда + + СтрокаСообщенияОбОшибке = НСтр("ru = 'Не задано имя сервера 1С:Предприятия информационной базы-приемника'"); + + СообщитьПользователю(СтрокаСообщенияОбОшибке); + + НаличиеОшибок = Истина; + + КонецЕсли; + + Если ПустаяСтрока(СтруктураПодключения.ИмяИБНаСервере) Тогда + + СтрокаСообщенияОбОшибке = НСтр("ru = 'Не задано имя информационной базы-приемника на сервере 1С:Предприятия'"); + + СообщитьПользователю(СтрокаСообщенияОбОшибке); + + НаличиеОшибок = Истина; + + КонецЕсли; + + СтрокаПодключения = "Srvr = """ + СтруктураПодключения.ИмяСервера + """; Ref = """ + СтруктураПодключения.ИмяИБНаСервере + """"; + + КонецЕсли; + + Возврат НЕ НаличиеОшибок; + +КонецФункции + +Функция ПодключитсяКИнформационнойБазе(СтруктураПодключения, СтрокаСообщенияОбОшибке = "") + + Перем СтрокаПодключения; + + ПараметровДостаточно = ОпределитьДостаточностьПараметровДляПодключенияКИнформационнойБазе(СтруктураПодключения, СтрокаПодключения, СтрокаСообщенияОбОшибке); + + Если Не ПараметровДостаточно Тогда + Возврат Неопределено; + КонецЕсли; + + Если Не СтруктураПодключения.АутентификацияWindows Тогда + Если НЕ ПустаяСтрока(СтруктураПодключения.Пользователь) Тогда + СтрокаПодключения = СтрокаПодключения + ";Usr = """ + СтруктураПодключения.Пользователь + """"; + КонецЕсли; + Если НЕ ПустаяСтрока(СтруктураПодключения.Пароль) Тогда + СтрокаПодключения = СтрокаПодключения + ";Pwd = """ + СтруктураПодключения.Пароль + """"; + КонецЕсли; + КонецЕсли; + + // "V82" или "V83" + ОбъектПодключения = СтруктураПодключения.ВерсияПлатформы; + + СтрокаПодключения = СтрокаПодключения + ";"; + + Попытка + + ОбъектПодключения = ОбъектПодключения +".COMConnector"; + ТекCOMПодключение = Новый COMОбъект(ОбъектПодключения); + ТекCOMОбъект = ТекCOMПодключение.Connect(СтрокаПодключения); + + Исключение + + СтрокаСообщенияОбОшибке = НСтр("ru = 'При попытке соединения с COM-сервером произошла следующая ошибка: + |%1'"); + СтрокаСообщенияОбОшибке = ПодставитьПараметрыВСтроку(СтрокаСообщенияОбОшибке, ОписаниеОшибки()); + + СообщитьПользователю(СтрокаСообщенияОбОшибке); + + Возврат Неопределено; + + КонецПопытки; + + Возврат ТекCOMОбъект; + +КонецФункции + +// Функция возвращает часть строки после последнего встреченного символа в строке. +Функция ПолучитьСтрокуОтделеннойСимволом(Знач ИсходнаяСтрока, Знач СимволПоиска) + + ПозицияСимвола = СтрДлина(ИсходнаяСтрока); + Пока ПозицияСимвола >= 1 Цикл + + Если Сред(ИсходнаяСтрока, ПозицияСимвола, 1) = СимволПоиска Тогда + + Возврат Сред(ИсходнаяСтрока, ПозицияСимвола + 1); + + КонецЕсли; + + ПозицияСимвола = ПозицияСимвола - 1; + КонецЦикла; + + Возврат ""; + +КонецФункции + +// Выделяет из имени файла его расширение (набор символов после последней точки). +// +// Параметры: +// ИмяФайла - Строка, содержащая имя файла, неважно с именем каталога или без. +// +// Возвращаемое значение: +// Строка - расширение файла. +// +Функция ПолучитьРасширениеИмениФайла(Знач ИмяФайла) Экспорт + + Расширение = ПолучитьСтрокуОтделеннойСимволом(ИмяФайла, "."); + Возврат Расширение; + +КонецФункции + +Функция ПолучитьИмяПротоколаДляВторойИнформационнойБазыComСоединения() Экспорт + + Если Не ПустаяСтрока(ИмяФайлаПротоколаОбменаЗагрузка) Тогда + + Возврат ИмяФайлаПротоколаОбменаЗагрузка; + + ИначеЕсли Не ПустаяСтрока(ИмяФайлаПротоколаОбмена) Тогда + + РасширениеФайлаПротокола = ПолучитьРасширениеИмениФайла(ИмяФайлаПротоколаОбмена); + + Если Не ПустаяСтрока(РасширениеФайлаПротокола) Тогда + + ИмяФайлаПротоколаВыгрузки = СтрЗаменить(ИмяФайлаПротоколаОбмена, "." + РасширениеФайлаПротокола, ""); + + КонецЕсли; + + ИмяФайлаПротоколаВыгрузки = ИмяФайлаПротоколаВыгрузки + "_Загрузка"; + + Если Не ПустаяСтрока(РасширениеФайлаПротокола) Тогда + + ИмяФайлаПротоколаВыгрузки = ИмяФайлаПротоколаВыгрузки + "." + РасширениеФайлаПротокола; + + КонецЕсли; + + Возврат ИмяФайлаПротоколаВыгрузки; + + КонецЕсли; + + Возврат ""; + +КонецФункции + +// Выполняет подключение к базе-приемнику по заданным параметрам. +// Возвращает проинициализированную обработку УниверсальныйОбменДаннымиXML базы-приемника, +// которая будет использоваться для загрузки данных в базу-приемник. +// +// Параметры: +// Нет. +// +// Возвращаемое значение: +// ОбработкаОбъект - УниверсальныйОбменДаннымиXML - обработка базы-приемника для загрузки данных в базу-приемник. +// +Функция ВыполнитьПодключениеКИБПриемнику() Экспорт + + РезультатПодключения = Неопределено; + + СтруктураПодключения = Новый Структура(); + СтруктураПодключения.Вставить("ФайловыйРежим", ТипИнформационнойБазыДляПодключения); + СтруктураПодключения.Вставить("АутентификацияWindows", АутентификацияWindowsИнформационнойБазыДляПодключения); + СтруктураПодключения.Вставить("КаталогИБ", КаталогИнформационнойБазыДляПодключения); + СтруктураПодключения.Вставить("ИмяСервера", ИмяСервераИнформационнойБазыДляПодключения); + СтруктураПодключения.Вставить("ИмяИБНаСервере", ИмяИнформационнойБазыНаСервереДляПодключения); + СтруктураПодключения.Вставить("Пользователь", ПользовательИнформационнойБазыДляПодключения); + СтруктураПодключения.Вставить("Пароль", ПарольИнформационнойБазыДляПодключения); + СтруктураПодключения.Вставить("ВерсияПлатформы", ВерсияПлатформыИнформационнойБазыДляПодключения); + + ОбъектПодключения = ПодключитсяКИнформационнойБазе(СтруктураПодключения); + + Если ОбъектПодключения = Неопределено Тогда + Возврат Неопределено; + КонецЕсли; + + Попытка + РезультатПодключения = ОбъектПодключения.Обработки.УниверсальныйОбменДаннымиXML.Создать(); + Исключение + + Текст = НСтр("ru = 'При попытке создания обработки УниверсальныйОбменДаннымиXML произошла ошибка: %1'"); + Текст = ПодставитьПараметрыВСтроку(Текст, КраткоеПредставлениеОшибки(ИнформацияОбОшибке())); + СообщитьПользователю(Текст); + РезультатПодключения = Неопределено; + КонецПопытки; + + Если РезультатПодключения <> Неопределено Тогда + + РезультатПодключения.ИспользоватьТранзакции = ИспользоватьТранзакции; + РезультатПодключения.КоличествоОбъектовНаТранзакцию = КоличествоОбъектовНаТранзакцию; + + РезультатПодключения.ФлагРежимОтладки = ФлагРежимОтладки; + + РезультатПодключения.ИмяФайлаПротоколаОбмена = ПолучитьИмяПротоколаДляВторойИнформационнойБазыComСоединения(); + + РезультатПодключения.ДописыватьДанныеВПротоколОбмена = ДописыватьДанныеВПротоколОбмена; + РезультатПодключения.ВыводВПротоколИнформационныхСообщений = ВыводВПротоколИнформационныхСообщений; + + РезультатПодключения.РежимОбмена = "Загрузка"; + + КонецЕсли; + + Возврат РезультатПодключения; + +КонецФункции + +// Выполняет удаление объектов заданного типа по правилам очистки данных +// (физическое удаление или пометка на удаление). +// +// Параметры: +// ИмяТипаДляУдаления - Строка - имя типа в строковом представлении. +// +Процедура УдалитьОбъектыТипа(ИмяТипаДляУдаления) Экспорт + + ТипДанныхДляУдаления = Тип(ИмяТипаДляУдаления); + + Менеджер = Менеджеры[ТипДанныхДляУдаления]; + ИмяТипа = Менеджер.ИмяТипа; + Свойства = Менеджеры[ТипДанныхДляУдаления]; + + Правило = Новый Структура("Имя,Непосредственно,ПередУдалением", "УдалениеОбъекта", Истина, ""); + + Выборка = ПолучитьВыборкуДляВыгрузкиОчисткиДанных(Свойства, ИмяТипа, Истина, Истина, Ложь); + + Пока Выборка.Следующий() Цикл + + Если ИмяТипа = "РегистрСведений" Тогда + + МенеджерЗаписи = Свойства.Менеджер.СоздатьМенеджерЗаписи(); + ЗаполнитьЗначенияСвойств(МенеджерЗаписи, Выборка); + + УдалениеОбъектаВыборки(МенеджерЗаписи, Правило, Свойства, Неопределено); + + Иначе + + УдалениеОбъектаВыборки(Выборка.Ссылка.ПолучитьОбъект(), Правило, Свойства, Неопределено); + + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + +Процедура ДополнитьСлужебныеТаблицыКолонками() + + ИнициализацияТаблицыПравилКонвертации(); + ИнициализацияТаблицыПравилВыгрузки(); + ИнициализацияТаблицыПравилОчистки(); + ИнициализацияТаблицыНастройкиПараметров(); + +КонецПроцедуры + +Функция ПолучитьНовоеУникальноеИмяВременногоФайла(СтароеИмяВременногоФайла, Расширение = "txt") + + УдалитьВременныеФайлы(СтароеИмяВременногоФайла); + + Возврат ПолучитьИмяВременногоФайла(Расширение); + +КонецФункции + +Процедура ИнициализацияСтруктурыИменОбработчиков() + + // Обработчики Конвертации. + ИменаОбработчиковКонвертации = Новый Структура; + ИменаОбработчиковКонвертации.Вставить("ПередВыгрузкойДанных"); + ИменаОбработчиковКонвертации.Вставить("ПослеВыгрузкиДанных"); + ИменаОбработчиковКонвертации.Вставить("ПередВыгрузкойОбъекта"); + ИменаОбработчиковКонвертации.Вставить("ПослеВыгрузкиОбъекта"); + ИменаОбработчиковКонвертации.Вставить("ПередКонвертациейОбъекта"); + ИменаОбработчиковКонвертации.Вставить("ПередОтправкойИнформацииОбУдалении"); + ИменаОбработчиковКонвертации.Вставить("ПередПолучениемИзмененныхОбъектов"); + + ИменаОбработчиковКонвертации.Вставить("ПередЗагрузкойОбъекта"); + ИменаОбработчиковКонвертации.Вставить("ПослеЗагрузкиОбъекта"); + ИменаОбработчиковКонвертации.Вставить("ПередЗагрузкойДанных"); + ИменаОбработчиковКонвертации.Вставить("ПослеЗагрузкиДанных"); + ИменаОбработчиковКонвертации.Вставить("ПриПолученииИнформацииОбУдалении"); + ИменаОбработчиковКонвертации.Вставить("ПослеПолученияИнформацииОбУзлахОбмена"); + + ИменаОбработчиковКонвертации.Вставить("ПослеЗагрузкиПравилОбмена"); + ИменаОбработчиковКонвертации.Вставить("ПослеЗагрузкиПараметров"); + + // Обработчики ПКО. + ИменаОбработчиковПКО = Новый Структура; + ИменаОбработчиковПКО.Вставить("ПередВыгрузкой"); + ИменаОбработчиковПКО.Вставить("ПриВыгрузке"); + ИменаОбработчиковПКО.Вставить("ПослеВыгрузки"); + ИменаОбработчиковПКО.Вставить("ПослеВыгрузкиВФайл"); + + ИменаОбработчиковПКО.Вставить("ПередЗагрузкой"); + ИменаОбработчиковПКО.Вставить("ПриЗагрузке"); + ИменаОбработчиковПКО.Вставить("ПослеЗагрузки"); + + ИменаОбработчиковПКО.Вставить("ПоследовательностьПолейПоиска"); + + // Обработчики ПКС. + ИменаОбработчиковПКС = Новый Структура; + ИменаОбработчиковПКС.Вставить("ПередВыгрузкой"); + ИменаОбработчиковПКС.Вставить("ПриВыгрузке"); + ИменаОбработчиковПКС.Вставить("ПослеВыгрузки"); + + // Обработчики ПКГС. + ИменаОбработчиковПКГС = Новый Структура; + ИменаОбработчиковПКГС.Вставить("ПередВыгрузкой"); + ИменаОбработчиковПКГС.Вставить("ПриВыгрузке"); + ИменаОбработчиковПКГС.Вставить("ПослеВыгрузки"); + + ИменаОбработчиковПКГС.Вставить("ПередОбработкойВыгрузки"); + ИменаОбработчиковПКГС.Вставить("ПослеОбработкиВыгрузки"); + + // Обработчики ПВД. + ИменаОбработчиковПВД = Новый Структура; + ИменаОбработчиковПВД.Вставить("ПередОбработкой"); + ИменаОбработчиковПВД.Вставить("ПослеОбработки"); + ИменаОбработчиковПВД.Вставить("ПередВыгрузкой"); + ИменаОбработчиковПВД.Вставить("ПослеВыгрузки"); + + // Обработчики ПОД. + ИменаОбработчиковПОД = Новый Структура; + ИменаОбработчиковПОД.Вставить("ПередОбработкой"); + ИменаОбработчиковПОД.Вставить("ПослеОбработки"); + ИменаОбработчиковПОД.Вставить("ПередУдалением"); + + // Глобальная структура с именами обработчиков. + ИменаОбработчиков = Новый Структура; + ИменаОбработчиков.Вставить("Конвертация", ИменаОбработчиковКонвертации); + ИменаОбработчиков.Вставить("ПКО", ИменаОбработчиковПКО); + ИменаОбработчиков.Вставить("ПКС", ИменаОбработчиковПКС); + ИменаОбработчиков.Вставить("ПКГС", ИменаОбработчиковПКГС); + ИменаОбработчиков.Вставить("ПВД", ИменаОбработчиковПВД); + ИменаОбработчиков.Вставить("ПОД", ИменаОбработчиковПОД); + +КонецПроцедуры + +// Возвращаемое значение: +// Структура - описание менеджера типа значения: +// * Имя - Строка - +// * ИмяТипа - Строка - +// * ТипСсылкиСтрокой - Строка - +// * Менеджер - Произвольный - +// * ОбъектМД - ОбъектМетаданных - +// * ВозможенПоискПоПредопределенным - Булево - +// * ПКО - Произвольный - +// +Функция СтруктураПараметровМенеджера(Имя, ИмяТипа, ТипСсылкиСтрокой, Менеджер, ОбъектМД) + Структура = Новый Структура(); + Структура.Вставить("Имя", Имя); + Структура.Вставить("ИмяТипа", ИмяТипа); + Структура.Вставить("ТипСсылкиСтрокой", ТипСсылкиСтрокой); + Структура.Вставить("Менеджер", Менеджер); + Структура.Вставить("ОбъектМД", ОбъектМД); + Структура.Вставить("ВозможенПоискПоПредопределенным", Ложь); + Структура.Вставить("ПКО"); + Возврат Структура; +КонецФункции + +Функция СтруктураПараметровПланаОбмена(Имя, ТипСсылки, ЭтоСсылочныйТип, ЭтоРегистр) + Структура = Новый Структура(); + Структура.Вставить("Имя",Имя); + Структура.Вставить("ТипСсылки",ТипСсылки); + Структура.Вставить("ЭтоСсылочныйТип",ЭтоСсылочныйТип); + Структура.Вставить("ЭтоРегистр",ЭтоРегистр); + Возврат Структура; +КонецФункции + +//////////////////////////////////////////////////////////////////////////////// +// Процедуры и функции из базовой функциональности для обеспечения автономности. + +Функция ПодсистемаСуществует(ПолноеИмяПодсистемы) Экспорт + + ИменаПодсистем = ИменаПодсистем(); + Возврат ИменаПодсистем.Получить(ПолноеИмяПодсистемы) <> Неопределено; + +КонецФункции + +Функция ИменаПодсистем() Экспорт + + Возврат Новый ФиксированноеСоответствие(ИменаПодчиненныхПодсистем(Метаданные)); + +КонецФункции + +Функция ИменаПодчиненныхПодсистем(РодительскаяПодсистема) + + Имена = Новый Соответствие; + + Для Каждого ТекущаяПодсистема Из РодительскаяПодсистема.Подсистемы Цикл + + Имена.Вставить(ТекущаяПодсистема.Имя, Истина); + ИменаПодчиненных = ИменаПодчиненныхПодсистем(ТекущаяПодсистема); + + Для каждого ИмяПодчиненной Из ИменаПодчиненных Цикл + Имена.Вставить(ТекущаяПодсистема.Имя + "." + ИмяПодчиненной.Ключ, Истина); + КонецЦикла; + КонецЦикла; + + Возврат Имена; + +КонецФункции + +Функция ОбщийМодуль(Имя) Экспорт + + Если Метаданные.ОбщиеМодули.Найти(Имя) <> Неопределено Тогда + Модуль = Вычислить(Имя); + Иначе + Модуль = Неопределено; + КонецЕсли; + + Если ТипЗнч(Модуль) <> Тип("ОбщийМодуль") Тогда + ВызватьИсключение ПодставитьПараметрыВСтроку(НСтр("ru = 'Общий модуль ""%1"" не найден.'"), Имя); + КонецЕсли; + + Возврат Модуль; + +КонецФункции + +Процедура СообщитьПользователю(ТекстСообщенияПользователю) Экспорт + + Сообщение = Новый СообщениеПользователю; + Сообщение.Текст = ТекстСообщенияПользователю; + Сообщение.Сообщить(); + +КонецПроцедуры + +Функция ПодставитьПараметрыВСтроку(Знач СтрокаПодстановки, + Знач Параметр1, Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено) + + СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%1", Параметр1); + СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%2", Параметр2); + СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%3", Параметр3); + + Возврат СтрокаПодстановки; + +КонецФункции + +Функция ЭтоВнешняяОбработка() + + Возврат ?(СтрНайти(ИмяФайлаВнешнейОбработкиОбработчиковСобытий, ".") <> 0, Истина, Ложь); + +КонецФункции + +Функция ИмяПредопределенного(Ссылка) + + Запрос = Новый Запрос; + Запрос.УстановитьПараметр("Ссылка", Ссылка); + Запрос.Текст = + "ВЫБРАТЬ + | ИмяПредопределенныхДанных КАК ИмяПредопределенныхДанных + |ИЗ + | " + Ссылка.Метаданные().ПолноеИмя() + " КАК ПсевдонимЗаданнойТаблицы + |ГДЕ + | ПсевдонимЗаданнойТаблицы.Ссылка = &Ссылка + |"; + Выборка = Запрос.Выполнить().Выбрать(); + Выборка.Следующий(); + + Возврат Выборка.ИмяПредопределенныхДанных; + +КонецФункции + +Функция ЗначениеСсылочногоТипа(Значение) + + Тип = ТипЗнч(Значение); + + Возврат Тип <> Тип("Неопределено") + И (Справочники.ТипВсеСсылки().СодержитТип(Тип) + ИЛИ Документы.ТипВсеСсылки().СодержитТип(Тип) + ИЛИ Перечисления.ТипВсеСсылки().СодержитТип(Тип) + ИЛИ ПланыВидовХарактеристик.ТипВсеСсылки().СодержитТип(Тип) + ИЛИ ПланыСчетов.ТипВсеСсылки().СодержитТип(Тип) + ИЛИ ПланыВидовРасчета.ТипВсеСсылки().СодержитТип(Тип) + ИЛИ БизнесПроцессы.ТипВсеСсылки().СодержитТип(Тип) + ИЛИ БизнесПроцессы.ТипВсеСсылкиТочекМаршрутаБизнесПроцессов().СодержитТип(Тип) + ИЛИ Задачи.ТипВсеСсылки().СодержитТип(Тип) + ИЛИ ПланыОбмена.ТипВсеСсылки().СодержитТип(Тип)); + +КонецФункции + +Функция КодОсновногоЯзыка() + Если ПодсистемаСуществует("СтандартныеПодсистемы.БазоваяФункциональность") Тогда + МодульОбщегоНазначения = ОбщийМодуль("ОбщегоНазначения"); + Возврат МодульОбщегоНазначения.КодОсновногоЯзыка(); + КонецЕсли; + Возврат Метаданные.ОсновнойЯзык.КодЯзыка; +КонецФункции + +#КонецОбласти + +#КонецОбласти + +#Область УИ + +// Для внутреннего использования +// +Функция ПолучитьТекстЗапросаПоСтроке(СтрокаДереваМетаданных, ЕстьДопОтборы, СтрокаПолейДляВыборки = "") Экспорт + + ОбъектМетаданных = Метаданные.НайтиПоПолномуИмени(СтрокаДереваМетаданных.ИмяМетаданных); + + ИмяМетаданных = СтрокаДереваМетаданных.ИмяМетаданных; + + Если Метаданные.РегистрыСведений.Содержит(ОбъектМетаданных) Тогда + + ТекстЗапроса = ПолучитьТекстЗапросаДляРегистраСведений(ИмяМетаданных, ОбъектМетаданных, ЕстьДопОтборы, СтрокаПолейДляВыборки); + Возврат ТекстЗапроса; + + ИначеЕсли Метаданные.РегистрыНакопления.Содержит(ОбъектМетаданных) + ИЛИ Метаданные.РегистрыБухгалтерии.Содержит(ОбъектМетаданных) Тогда + + ТекстЗапроса = ПолучитьТекстЗапросаДляРегистра(ИмяМетаданных, ОбъектМетаданных, ЕстьДопОтборы, СтрокаПолейДляВыборки); + Возврат ТекстЗапроса; + + КонецЕсли; + + ЕстьОграничениеПоДатам = ЗначениеЗаполнено(ДатаНачала) Или ЗначениеЗаполнено(ДатаОкончания); + + Если НЕ ЗначениеЗаполнено(СтрокаПолейДляВыборки) Тогда + СтрокаПолейДляВыборки = "_.*"; + КонецЕсли; + + ТекстЗапроса = "ВЫБРАТЬ Разрешенные " + СтрокаПолейДляВыборки + " ИЗ " + ИмяМетаданных + " КАК _ "; + + // возможно нужно ограничение по датам установить + Если ЕстьОграничениеПоДатам Тогда + + Если ЕстьДопОтборы И + НЕ ИспользоватьОтборПоДатеДляВсехОбъектов Тогда + + Возврат ТекстЗапроса; + + КонецЕсли; + + ДопОграничениеПоДате = ""; + + // можно ли для данного объекта МД строить ограничения по датам + Если Метаданные.Документы.Содержит(ОбъектМетаданных) Тогда + + ДопОграничениеПоДате = ПолучитьСтрокуОграниченияПоДатеДляЗапроса(ОбъектМетаданных, "Документ"); + + ИначеЕсли Метаданные.РегистрыБухгалтерии.Содержит(ОбъектМетаданных) + ИЛИ Метаданные.РегистрыНакопления.Содержит(ОбъектМетаданных) Тогда + + ДопОграничениеПоДате = ПолучитьСтрокуОграниченияПоДатеДляЗапроса(ОбъектМетаданных, "Регистр"); + + КонецЕсли; + + ТекстЗапроса = ТекстЗапроса + Символы.ПС + ДопОграничениеПоДате; + + КонецЕсли; + + Возврат ТекстЗапроса; + +КонецФункции + +Функция ПолучитьТекстЗапросаДляРегистраСведений(ИмяМетаданных, ОбъектМетаданных, ЕстьДопОтборы, СтрокаПолейДляВыборки = "") + + ЕстьОграничениеПоДатам = ЗначениеЗаполнено(ДатаНачала) Или ЗначениеЗаполнено(ДатаОкончания); + + Если НЕ ЗначениеЗаполнено(СтрокаПолейДляВыборки) Тогда + СтрокаПолейДляВыборки = "_.*"; + Иначе + СтрокаПолейДляВыборки = " Различные " + СтрокаПолейДляВыборки; + КонецЕсли; + + ТекстЗапроса = "ВЫБРАТЬ Разрешенные " + СтрокаПолейДляВыборки + " ИЗ " + ИмяМетаданных + " КАК _ "; + + Если ОбъектМетаданных.ПериодичностьРегистраСведений = Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда + Возврат ТекстЗапроса; + КонецЕсли; + + // 0 - отбор за период + // 1 - срез последних на дату окончания + // 2 - срез первых на дату начала + // 3 - срез последних на дату начала + отбор за период + Если ЕстьДопОтборы И Не ИспользоватьОтборПоДатеДляВсехОбъектов Тогда + + Возврат ТекстЗапроса; + + КонецЕсли; + + ДопОграничениеПоДате = ПолучитьСтрокуОграниченияПоДатеДляЗапроса(ОбъектМетаданных, "РегистрСведений"); + + ТекстЗапроса = ТекстЗапроса + Символы.ПС + ДопОграничениеПоДате; + + + Возврат ТекстЗапроса; + +КонецФункции + +Функция ПолучитьТекстЗапросаДляРегистра(ИмяМетаданных, ОбъектМетаданных, ЕстьДопОтборы, СтрокаПолейДляВыборки = "") + + ЕстьОграничениеПоДатам = ЗначениеЗаполнено(ДатаНачала) Или ЗначениеЗаполнено(ДатаОкончания); + + Если НЕ ЗначениеЗаполнено(СтрокаПолейДляВыборки) Тогда + СтрокаПолейДляВыборки = "_.*"; + Иначе + СтрокаПолейДляВыборки = " РАЗЛИЧНЫЕ " + СтрокаПолейДляВыборки; + КонецЕсли; + + ТекстЗапроса = "ВЫБРАТЬ Разрешенные " + СтрокаПолейДляВыборки + " ИЗ " + ИмяМетаданных + " КАК _ "; + + // возможно нужно ограничение по датам установить + Если ЕстьОграничениеПоДатам Тогда + + Если ЕстьДопОтборы И + НЕ ИспользоватьОтборПоДатеДляВсехОбъектов Тогда + + Возврат ТекстЗапроса; + + КонецЕсли; + + ДопОграничениеПоДате = ПолучитьСтрокуОграниченияПоДатеДляЗапроса(ОбъектМетаданных, "Регистр"); + + ТекстЗапроса = ТекстЗапроса + Символы.ПС + ДопОграничениеПоДате; + + КонецЕсли; + + Возврат ТекстЗапроса; + +КонецФункции + + +Функция СхемаКомпоновкиДанных(ТекстЗапроса) Экспорт + + СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных; + + ИсточникДанных = СхемаКомпоновкиДанных.ИсточникиДанных.Добавить(); + ИсточникДанных.Имя = "ИсточникДанных1"; + ИсточникДанных.ТипИсточникаДанных = "local"; + + НаборДанных = СхемаКомпоновкиДанных.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных")); + НаборДанных.ИсточникДанных = "ИсточникДанных1"; + НаборДанных.АвтоЗаполнениеДоступныхПолей = Истина; + НаборДанных.Запрос = ТекстЗапроса; + НаборДанных.Имя = "НаборДанных1"; + + Возврат СхемаКомпоновкиДанных; + +КонецФункции + +Процедура УстановитьНастройкуСтруктурыВыводаРезультата(Настройки, ВыводВТабличныйДокумент = Ложь) Экспорт + + ГруппировкаКомпоновкиДанных = Настройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных")); + + ПолеГруппировки = ГруппировкаКомпоновкиДанных.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных")); + ПолеГруппировки.Использование = Истина; + + Если ВыводВТабличныйДокумент + И Настройки.Выбор.ДоступныеПоляВыбора.НайтиПоле(Новый ПолеКомпоновкиДанных("Ссылка")) <> Неопределено Тогда + ПолеВыбора = ГруппировкаКомпоновкиДанных.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных")); + ПолеВыбора.Поле = Новый ПолеКомпоновкиДанных("Ссылка"); + ПолеВыбора.Использование = Истина; + Иначе + Для Каждого ДоступноеПолеВыбора Из Настройки.Выбор.ДоступныеПоляВыбора.Элементы Цикл + Если ДоступноеПолеВыбора.Поле = Новый ПолеКомпоновкиДанных("СистемныеПоля") + Или ДоступноеПолеВыбора.Поле = Новый ПолеКомпоновкиДанных("ПараметрыДанных") Тогда + Продолжить; + КонецЕсли; + ПолеВыбора = ГруппировкаКомпоновкиДанных.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных")); + ПолеВыбора.Поле = ДоступноеПолеВыбора.Поле; + ПолеВыбора.Использование = Истина; + КонецЦикла; + КонецЕсли; + +КонецПроцедуры + + +#КонецОбласти + +#Область Инициализация + +ИнициализацияРеквизитовИМодульныхПеременных(); +ДополнитьСлужебныеТаблицыКолонками(); +ИнициализацияСтруктурыИменОбработчиков(); + +#КонецОбласти + +#Иначе +ВызватьИсключение НСтр("ru = 'Недопустимый вызов объекта на клиенте.'"); +#КонецЕсли \ No newline at end of file diff --git "a/\320\230\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/src/DataProcessors/\320\243\320\230_\320\243\320\275\320\270\320\262\320\265\321\200\321\201\320\260\320\273\321\214\320\275\321\213\320\271\320\236\320\261\320\274\320\265\320\275\320\224\320\260\320\275\320\275\321\213\320\274\320\270XML/Templates/\320\236\320\261\321\211\320\270\320\265\320\237\321\200\320\276\321\206\320\265\320\264\321\203\321\200\321\213\320\244\321\203\320\275\320\272\321\206\320\270\320\270/Template.txt" "b/\320\230\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/src/DataProcessors/\320\243\320\230_\320\243\320\275\320\270\320\262\320\265\321\200\321\201\320\260\320\273\321\214\320\275\321\213\320\271\320\236\320\261\320\274\320\265\320\275\320\224\320\260\320\275\320\275\321\213\320\274\320\270XML/Templates/\320\236\320\261\321\211\320\270\320\265\320\237\321\200\320\276\321\206\320\265\320\264\321\203\321\200\321\213\320\244\321\203\320\275\320\272\321\206\320\270\320\270/Template.txt" new file mode 100644 index 00000000..2d77bb51 --- /dev/null +++ "b/\320\230\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/src/DataProcessors/\320\243\320\230_\320\243\320\275\320\270\320\262\320\265\321\200\321\201\320\260\320\273\321\214\320\275\321\213\320\271\320\236\320\261\320\274\320\265\320\275\320\224\320\260\320\275\320\275\321\213\320\274\320\270XML/Templates/\320\236\320\261\321\211\320\270\320\265\320\237\321\200\320\276\321\206\320\265\320\264\321\203\321\200\321\213\320\244\321\203\320\275\320\272\321\206\320\270\320\270/Template.txt" @@ -0,0 +1,670 @@ +#Область Шапка_Комментарий +//////////////////////////////////////////////////////////////////////////////// +// +// Данный модуль содержит экспортные процедуры обработчиков событий конвертации +// и предназначен для отладки правил обмена. +// После отладки рекомендуется внести соответствующие исправления обработчиков +// в базе «Конвертация данных 2.0» и заново сформировать файл правил. +// +//////////////////////////////////////////////////////////////////////////////// +// ИСПОЛЬЗУЕМЫЕ СОКРАЩЕНИЯ ИМЕН ПЕРЕМЕННЫХ (АББРЕВИАТУРЫ) +// +// ПКО - правило конвертации объектов +// ПКС - правило конвертации свойств объектов +// ПКГС - правило конвертации группы свойств объектов +// ПКЗ - правило конвертации значений объектов +// ПВД - правило выгрузки данных +// ПОД - правило очистки данных +#Область Конвертация_Комментарий +//////////////////////////////////////////////////////////////////////////////// +// ОБРАБОТЧИКИ КОНВЕРТАЦИИ (ГЛОБАЛЬНЫЕ) +#Область ПКО_Комментарий +//////////////////////////////////////////////////////////////////////////////// +// ОБРАБОТЧИКИ КОНВЕРТАЦИИ ОБЪЕКТОВ +#Область ПКС_Комментарий +//////////////////////////////////////////////////////////////////////////////// +// ОБРАБОТЧИКИ КОНВЕРТАЦИИ СВОЙСТВ И ГРУПП СВОЙСТВ ОБЪЕКТОВ +#Область ПВД_Комментарий +//////////////////////////////////////////////////////////////////////////////// +// ОБРАБОТЧИКИ ВЫГРУЗКИ ДАННЫХ +#Область ПОД_Комментарий +//////////////////////////////////////////////////////////////////////////////// +// ОБРАБОТЧИКИ ОЧИСТКИ ДАННЫХ +#Область Предупреждение_Комментарий +//////////////////////////////////////////////////////////////////////////////// +// ВНИМАНИЕ +// ИЗМЕНЯТЬ КОД В ЭТОМ БЛОКЕ (НИЖЕ) ЗАПРЕЩЕНО! +//////////////////////////////////////////////////////////////////////////////// +#Область ОбщиеПроцедурыФункции_Комментарий +//////////////////////////////////////////////////////////////////////////////// +// ВЫЗОВ ОБЩИХ ПРОЦЕДУР И ФУНКЦИЙ +#Область ПеременныеОбработки_Комментарий +//////////////////////////////////////////////////////////////////////////////// +// ПЕРЕМЕННЫЕ ОБРАБОТКИ +#Область Алгоритмы_Комментарий +//////////////////////////////////////////////////////////////////////////////// +// АЛГОРИТМЫ +#Область Конструктор_Комментарий +//////////////////////////////////////////////////////////////////////////////// +// КОНСТРУКТОР И ДЕСТРУКТОР ОБРАБОТКИ + +#Область ПеременныеОбработки +//////////////////////////////////////////////////////////////////////////////// +// ВСПОМОГАТЕЛЬНЫЕ ПЕРЕМЕННЫЕ МОДУЛЯ ДЛЯ НАПИСАНИЯ АЛГОРИТМОВ (ОБЩИЕ ДЛЯ ВЫГРУЗКИ И ЗАГРУЗКИ) + +Перем Параметры; +Перем Правила; +Перем Алгоритмы; +Перем Запросы; +Перем ТаблицаПравилВыгрузки; +Перем ТаблицаНастройкиПараметров; +Перем УзелДляОбмена; // только для on-line обмена +Перем ОбщиеПроцедурыФункции; +Перем ДатаНачала; +Перем ДатаОкончания; +Перем ДатаВыгрузкиДанных; // только для on-line обмена +Перем КомментарийПриВыгрузкеДанных; +Перем КомментарийПриЗагрузкеДанных; + + +//////////////////////////////////////////////////////////////////////////////// +// ПЕРЕМЕННЫЕ ОБРАБОТОК ОБМЕНА (ОБЩИЕ ДЛЯ ВЫГРУЗКИ И ЗАГРУЗКИ) + +Перем одТипСтрока; // Тип("Строка") +Перем одТипБулево; // Тип("Булево") +Перем одТипЧисло; // Тип("Число") +Перем одТипДата; // Тип("Дата") +Перем одТипХранилищеЗначения; // Тип("ХранилищеЗначения") +Перем одТипДвоичныеДанные; // Тип("ДвоичныеДанные") +Перем одТипВидДвиженияНакопления; // Тип("ВидДвиженияНакопления") +Перем одТипУдалениеОбъекта; // Тип("УдалениеОбъекта") +Перем одТипВидСчета; // Тип("ВидСчета") +Перем одТипТип; // Тип("Тип") +Перем одТипСоответствие; // Тип("Соответствие") + +Перем одТипУзлаXML_КонецЭлемента; +Перем одТипУзлаXML_НачалоЭлемента; +Перем одТипУзлаXML_Текст; + +Перем ЗначениеПустаяДата; + +#Область Конструктор_ТелоПроцедуры +ОбщиеПроцедурыФункции = Владелец; +Параметры = Владелец.Параметры; +Запросы = Владелец.Запросы; +Правила = Владелец.Правила; +ТаблицаПравилВыгрузки = Владелец.ТаблицаПравилВыгрузки; +ТаблицаНастройкиПараметров = Владелец.ТаблицаНастройкиПараметров; + +КомментарийПриВыгрузкеДанных = Владелец.КомментарийПриВыгрузкеДанных; +КомментарийПриЗагрузкеДанных = Владелец.КомментарийПриЗагрузкеДанных; + + +//переменная для универсального обмена +Попытка + ДатаНачала = Владелец.ДатаНачала; +Исключение +КонецПопытки; + +//переменная для универсального обмена +Попытка + ДатаОкончания = Владелец.ДатаОкончания; +Исключение +КонецПопытки; + +//переменная для on-line обмена +Попытка + ДатаВыгрузкиДанных = Владелец.ДатаВыгрузкиДанных; +Исключение +КонецПопытки; + +//переменная для on-line обмена +Попытка + УзелДляОбмена = Владелец.УзелДляОбмена; +Исключение +КонецПопытки; + +// Типы +одТипСтрока = Тип("Строка"); +одТипБулево = Тип("Булево"); +одТипЧисло = Тип("Число"); +одТипДата = Тип("Дата"); +одТипХранилищеЗначения = Тип("ХранилищеЗначения"); +одТипДвоичныеДанные = Тип("ДвоичныеДанные"); +одТипВидДвиженияНакопления = Тип("ВидДвиженияНакопления"); +одТипУдалениеОбъекта = Тип("УдалениеОбъекта"); +одТипВидСчета = Тип("ВидСчета"); +одТипТип = Тип("Тип"); +одТипСоответствие = Тип("Соответствие"); + +ЗначениеПустаяДата = Дата('00010101'); + +// Типы узлов xml +одТипУзлаXML_КонецЭлемента = ТипУзлаXML.КонецЭлемента; +одТипУзлаXML_НачалоЭлемента = ТипУзлаXML.НачалоЭлемента; +одТипУзлаXML_Текст = ТипУзлаXML.Текст; + +#Область Конструктор_ТелоПроцедуры_ПроцедурныйВызовАлгоритмов +Алгоритмы = Новый Структура; + +#Область Конструктор_ТелоПроцедуры_ИнтеграцияКодаАлгоритмов +Алгоритмы = Владелец.Алгоритмы; + +#Область Конструктор_ТелоПроцедуры_НеИспользоватьОтладкуАлгоритмов +Алгоритмы = Владелец.Алгоритмы; + +#Область Деструктор +Процедура Деструктор() Экспорт + + ОбщиеПроцедурыФункции = Неопределено; + +КонецПроцедуры + +#Область ОбщиеПроцедурыФункции +// Производит выгрузку объекта в соответствии с указанным правилом конвертации +// +// Параметры: +// Источник - произвольный источник данных +// Приемник - xml-узел объекта приемника +// ВходящиеДанные - произвольные вспомогательные данные, передаваемые правилу +// для выполнения конвертации +// ИсходящиеДанные - произвольные вспомогательные данные, передаваемые правилам +// конвертации свойств +// ИмяПКО - имя правила конвертации, согласно которому осуществляется выгрузка +// УзелСсылки - xml-узел ссылки объекта приемника +// ТолькоПолучитьУзелСсылки - если Истина, то выгрузка объекта не производится, только формируется +// xml-узел ссылки +// ПКО - ссылка на правило конвертации +// +// Возвращаемое значение: +// xml-узел ссылки или значение приемника +// +Функция ВыгрузитьПоПравилу(Источник = Неопределено, + Приемник = Неопределено, + ВходящиеДанные = Неопределено, + ИсходящиеДанные = Неопределено, + ИмяПКО = "") Экспорт + + Возврат ОбщиеПроцедурыФункции.ВыгрузитьПоПравилу(Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, ИмяПКО); + +КонецФункции + +// Создает новый xml-узел +// Функция может быть использована в обработчиках событий, программный код +// которых хранится в правила обмена данными. Вызывается методом Выполнить() +// +// Параметры: +// Имя - Имя узла +// +// Возвращаемое значение: +// Объект нового xml-узла +// +Функция СоздатьУзел(Имя) Экспорт + + Возврат ОбщиеПроцедурыФункции.СоздатьУзел(Имя); + +КонецФункции + +// Добавляет новый xml-узел к указанному узлу-родителю +// Функция может быть использована в обработчиках событий, программный код +// которых хранится в правила обмена данными. Вызывается методом Выполнить() +// Сообщение "Не обнаружено ссылок на функцию" при проверке конфигурации +// не является ошибкой проверки конфигурации +// +// Параметры: +// УзелРодитель - xml-узел-родитель +// Имя - имя добавляемого узла +// +// Возвращаемое значение: +// Новый xml-узел, добавленный к указанному узлу-родителю +// +Функция ДобавитьУзел(УзелРодитель, Имя) Экспорт + + Возврат ОбщиеПроцедурыФункции.ДобавитьУзел(УзелРодитель, Имя); + +КонецФункции + +// Копирует указанный xml-узел +// Функция может быть использована в обработчиках событий, программный код +// которых хранится в правила обмена данными. Вызывается методом Выполнить() +// Сообщение "Не обнаружено ссылок на функцию" при проверке конфигурации +// не является ошибкой проверки конфигурации +// +// Параметры: +// Узел - копируемый узел +// +// Возвращаемое значение: +// Новый xml - копия указанного узла +// +Функция КопироватьУзел(Узел) Экспорт + + Возврат ОбщиеПроцедурыФункции.КопироватьУзел(Узел); + +КонецФункции + +// Устанавливает значение параметра "Загрузка" для свойства объекта "ОбменДанными". +// +// Параметры: +// Объект - объект, для которого устанавливается свойство +// Значение - значение устанавливаемого свойства "Загрузка" +// +Процедура УстановитьОбменДаннымиЗагрузка(Объект, Значение = Истина) Экспорт + + ОбщиеПроцедурыФункции.УстановитьОбменДаннымиЗагрузка(Объект, Значение); + +КонецПроцедуры + +// Устанавливает атрибут указанного xml-узла +// +// Параметры: +// Узел - xml-узел +// Имя - имя атрибута +// Значение - устанавливаемое значение +// +Процедура УстановитьАтрибут(Узел, Имя, Значение) Экспорт + + ОбщиеПроцедурыФункции.УстановитьАтрибут(Узел, Имя, Значение); + +КонецПроцедуры + +// Подчиняет xml-узел указанному узлу-родителю +// +// Параметры: +// УзелРодитель - xml-узел-родитель +// Узел - подчиняемый узел +// +Процедура ДобавитьПодчиненный(УзелРодитель, Узел) Экспорт + + ОбщиеПроцедурыФункции.ДобавитьПодчиненный(УзелРодитель, Узел); + +КонецПроцедуры + +//////////////////////////////////////////////////////////////////////////////// +// ПРОЦЕДУРЫ И ФУНКЦИИ ДЛЯ РАБОТЫ С ОБЪЕКТОМ XMLЧтение + +// Осуществляет запись элемента и его значения в указанный объект +// +// Параметры: +// Объект - объект типа XMLЗапись +// Имя - Строка. Имя элемента +// Значение - Значение элемента +// +Процедура одЗаписатьЭлемент(Объект, Имя, Значение="") Экспорт + + ОбщиеПроцедурыФункции.одЗаписатьЭлемент(Объект, Имя, Значение); + +КонецПроцедуры + +// Читает значение атрибута по имени из указанного объекта, приводит значение +// к указанному примитивному типу +// +// Параметры: +// Объект - объект типа XMLЧтение, спозиционированный на начале элемента, +// атрибут которого требуется получить +// Тип - Значение типа Тип. Тип атрибута +// Имя - Строка. Имя атрибута +// +// Возвращаемое значение: +// Значение атрибута полученное по имени и приведенное к указанному типу +// +Функция одАтрибут(Объект, Тип, Имя) Экспорт + + Возврат ОбщиеПроцедурыФункции.одАтрибут(Объект, Тип, Имя); + +КонецФункции + +// Пропускает узлы xml до конца указанного элемента (по умолчанию текущего) +// +// Параметры: +// Объект - объект типа XMLЧтение +// Имя - имя узла, до конца которого пропускаем элементы +// +Процедура одПропустить(Объект, Имя = "") Экспорт + + ОбщиеПроцедурыФункции.одПропустить(Объект, Имя); + +КонецПроцедуры + +// Читает текст элемента и приводит значение к указанному типу +// +// Параметры: +// Объект - объект типа XMLЧтение, из которого осуществляется чтение +// Тип - тип получаемого значения +// ИскатьПоСвойству - для ссылочных типов может быть указано свойство, по которому +// следует искать объект: "Код", "Наименование", <ИмяРеквизита>, "Имя" (предопределенного значения) +// +// Возвращаемое значение: +// Значение xml-элемента, приведенное к соответствующему типу +// +Функция одЗначениеЭлемента(Объект, Тип, ИскатьПоСвойству = "", ОбрезатьСтрокуСправа = Истина) Экспорт + + Возврат ОбщиеПроцедурыФункции.одЗначениеЭлемента(Объект, Тип, ИскатьПоСвойству, ОбрезатьСтрокуСправа); + +КонецФункции + +//////////////////////////////////////////////////////////////////////////////// +// РАБОТА С ДАННЫМИ + +// Возвращает строку - имя переданного значения перечисления. +// Функция может быть использована в обработчиках событий, программный код +// которых хранится в правила обмена данными. Вызывается методом Выполнить() +// Сообщение "Не обнаружено ссылок на функцию" при проверке конфигурации +// не является ошибкой проверки конфигурации +// +// Параметры: +// Значение - значение перечисления +// +// Возвращаемое значение: +// Строка - имя переданного значения перечисления. +// +Функция одИмяЗначенияПеречисления(Значение) Экспорт + + Возврат ОбщиеПроцедурыФункции.одИмяЗначенияПеречисления(Значение); + +КонецФункции + +// Определяет заполнено ли переданное значение +// +// Параметры: +// Значение - значение, заполнение которого надо проверить +// +// Возвращаемое значение: +// Истина - значение не заполнено, ложь - иначе. +// +Функция одПустое(Значение, ЭтоNULL=Ложь) Экспорт + + Возврат ОбщиеПроцедурыФункции.одПустое(Значение, ЭтоNULL); + +КонецФункции + +// Возвращает объект ОписаниеТипов, содержащий указанный тип. +// +// Параметры: +// ЗначениеТипа - строка с именем типа или значение типа Тип. +// +// Возвращаемое значение: +// ОписаниеТипов +// +Функция одОписаниеТипа(ЗначениеТипа) Экспорт + + Возврат ОбщиеПроцедурыФункции.одОписаниеТипа(ЗначениеТипа); + +КонецФункции + +// Возвращает пустое (дефолтное) значение указанного типа +// +// Параметры: +// Тип - строка с именем типа или значение типа Тип. +// +// Возвращаемое значение: +// Пустое значение указанного типа. +// +Функция одПолучитьПустоеЗначение(Тип) Экспорт + + Возврат ОбщиеПроцедурыФункции.одПолучитьПустоеЗначение(Тип); + +КонецФункции + +// Осуществляет простой поиск объекта информационной базы по указанному свойству. +// +// Параметры: +// Менеджер - менеджер искомого объекта; +// Свойство - свойство, по которому осуществляем поиск: Имя, Код, +// Наименование или Имя индексируемого реквизита; +// Значение - значение свойства, по которому ищем объект. +// +// Возвращаемое значение: +// Найденный объект информационной базы. +// +Функция одНайтиОбъектПоСвойству(Менеджер, Свойство, Значение, + НайденныйОбъектПоУникальномуИдентификатору = Неопределено, + ОбщаяСтруктураСвойств = Неопределено, ОбщиеСвойстваПоиска = Неопределено, + РежимПоискаОсновногоОбъекта = Истина, + СтрокаЗапросаПоискаПоУникальномуИдентификатору = "") Экспорт + + Возврат ОбщиеПроцедурыФункции.одНайтиОбъектПоСвойству(Менеджер, Свойство, Значение, + НайденныйОбъектПоУникальномуИдентификатору, + ОбщаяСтруктураСвойств, ОбщиеСвойстваПоиска, + РежимПоискаОсновногоОбъекта, СтрокаЗапросаПоискаПоУникальномуИдентификатору); + +КонецФункции + +// Осуществляет простой поиск объекта информационной базы по указанному свойству. +// +// Параметры: +// Стр - Строка - значение свойства, по которому осуществляется поиск объекта; +// Тип - тип искомого объекта; +// Свойство - Строка - имя свойства, по-которому ищем объект. +// +// Возвращаемое значение: +// Найденный объект информационной базы +// +Функция одПолучитьЗначениеПоСтроке(Стр, Тип, Свойство = "") Экспорт + + Возврат ОбщиеПроцедурыФункции.одПолучитьЗначениеПоСтроке(Стр, Тип, Свойство); + +КонецФункции + +// Возвращает строковое представление типа значения +// +// Параметры: +// ЗначениеИлиТип - произвольное значение или значение типа тип +// +// Возвращаемое значение: +// Строка - строковое представление типа значения +// +Функция одТипЗначенияСтрокой(ЗначениеИлиТип) Экспорт + + Возврат ОбщиеПроцедурыФункции.одТипЗначенияСтрокой(ЗначениеИлиТип); + +КонецФункции + +// Возвращает XML представление объекта ОписаниеТипов +// Функция может быть использована в обработчиках событий, программный код +// которых хранится в правила обмена данными. Вызывается методом Выполнить() +// Сообщение "Не обнаружено ссылок на функцию" при проверке конфигурации +// не является ошибкой проверки конфигурации +// +// Параметры: +// ОписаниеТипов - объект ОписаниеТипов, XML представление которого требуется получить +// +// Возвращаемое значение: +// Строка - XML представление переданного объекта ОписаниеТипов +// +Функция одПолучитьXMLПредставлениеОписанияТипов(ОписаниеТипов) Экспорт + + Возврат ОбщиеПроцедурыФункции.одПолучитьXMLПредставлениеОписанияТипов(ОписаниеТипов); + +КонецФункции + +//////////////////////////////////////////////////////////////////////////////// +// РАБОТА СО СТРОКАМИ + +// Разбирает строку на две части: до подстроки разделителя и после. +// +// Параметры: +// Стр - разбираемая строка; +// Разделитель - подстрока-разделитель: +// Режим - 0 - разделитель в возвращаемые подстроки не включается; +// 1 - разделитель включается в левую подстроку; +// 2 - разделитель включается в правую подстроку. +// +// Возвращаемое значение: +// Правая часть строки - до символа-разделителя. +// +Функция ОтделитьРазделителем(Стр, Знач Разделитель, Режим=0) Экспорт + + Возврат ОбщиеПроцедурыФункции.ОтделитьРазделителем(Стр, Разделитель, Режим); + +КонецФункции + +// Преобразует значения из строки в массив, используя указанный разделитель +// +// Параметры: +// Стр - Разбираемая строка +// Разделитель - подстрока разделитель +// +// Возвращаемое значение: +// Массив значений +// +Функция МассивИзСтроки(Знач Стр, Разделитель=",") Экспорт + + Возврат ОбщиеПроцедурыФункции.МассивИзСтроки(Стр, Разделитель); + +КонецФункции + +// Возвращает строку номера без символьных префиксов +// Например: +// ПолучитьСтроковыйНомерБезПрефиксов("УТ0000001234") = "0000001234" +// +// Параметры: +// Номер - Строка - номер, из которого необходимо вычислить результат функции +// +// Возвращаемое значение: +// Строка номера без символьных префиксов +// +Функция ПолучитьСтроковыйНомерБезПрефиксов(Номер) Экспорт + + Возврат ОбщиеПроцедурыФункции.ПолучитьСтроковыйНомерБезПрефиксов(Номер); + +КонецФункции + +// Разбирает строку, выделяя из нее префикс и числовую часть. +// +// Параметры: +// Стр - Строка. Разбираемая строка; +// ЧисловаяЧасть - Число. Переменная, в которую возвратится числовая часть строки; +// Режим - Строка. Если "Число", то возвратит числовую часть, иначе - префикс. +// +// Возвращаемое значение: +// Префикс строки +// +Функция ПолучитьПрефиксЧислоНомера(Знач Стр, ЧисловаяЧасть = "", Режим = "") Экспорт + + Возврат ОбщиеПроцедурыФункции.ПолучитьПрефиксЧислоНомера(Стр, ЧисловаяЧасть, Режим); + +КонецФункции + +// Приводит номер (код) к требуемой длине. При этом выделяется префикс +// и числовая часть номера, остальное пространство между префиксом и +// номером заполняется нулями. +// Функция может быть использована в обработчиках событий, программный код +// которых хранится в правила обмена данными. Вызывается методом Выполнить() +// Сообщение "Не обнаружено ссылок на функцию" при проверке конфигурации +// не является ошибкой проверки конфигурации +// +// Параметры: +// Стр - преобразовываемая строка; +// Длина - требуемая длина строки. +// +// Возвращаемое значение: +// Строка - код или номер, приведенная к требуемой длине. +// +Функция ПривестиНомерКДлине(Знач Стр, Длина, ДобавлятьНулиЕслиДлинаНеМеньшеТекущейДлиныНомера = Истина, + Префикс = "") Экспорт + + Возврат ОбщиеПроцедурыФункции.ПривестиНомерКДлине(Стр, Длина, + ДобавлятьНулиЕслиДлинаНеМеньшеТекущейДлиныНомера, Префикс); + +КонецФункции + +// Добавляет к префиксу номера или кода подстроку +// Функция может быть использована в обработчиках событий, программный код +// которых хранится в правила обмена данными. Вызывается методом Выполнить() +// Сообщение "Не обнаружено ссылок на функцию" при проверке конфигурации +// не является ошибкой проверки конфигурации +// +// Параметры: +// Стр - Строка. Номер или код; +// Добавок - добавляемая к префиксу подстрока; +// Длина - требуемая результирующая длина строки; +// Режим - "Слева" - подстрока добавляется слева к префиксу, иначе - справа. +// +// Возвращаемое значение: +// Строка - номер или код, к префиксу которого добавлена указанная подстрока. +// +Функция ДобавитьКПрефиксу(Знач Стр, Добавок = "", Длина = "", Режим = "Слева") Экспорт + + Возврат ОбщиеПроцедурыФункции.ДобавитьКПрефиксу(Стр, Добавок, Длина, Режим); + +КонецФункции + +// Дополняет строку указанным символом до указанной длины. +// +// Параметры: +// Стр - дополняемая строка; +// Длина - требуемая длина результирующей строки; +// Чем - символ, которым дополняется строка. +// +// Возвращаемое значение: +// Строка, дополненная указанным символом до указанной длины. +// +Функция одДополнитьСтроку(Стр, Длина, Чем = " ") Экспорт + + Возврат ОбщиеПроцедурыФункции.одДополнитьСтроку(Стр, Длина, Чем); + +КонецФункции + +//////////////////////////////////////////////////////////////////////////////// +// ПРОЦЕДУРЫ И ФУНКЦИИ РАБОТЫ С ФАЙЛОМ ОБМЕНА + +// Сохраняет в файл указанный xml-узел +// +// Параметры: +// Узел - xml-узел, сохраняемый в файл +// +Процедура ЗаписатьВФайл(Узел) Экспорт + + ОбщиеПроцедурыФункции.ЗаписатьВФайл(Узел); + +КонецПроцедуры + +//////////////////////////////////////////////////////////////////////////////// +// ПРОЦЕДУРЫ И ФУНКЦИИ РАБОТЫ С ПРАВИЛАМИ ОБМЕНА + +// Осуществляет поиск правила конвертации по имени или в соответствии с типом +// переданного объекта +// +// Параметры: +// Объект - Объект-источник, для которого ищем правило конвертации +// ИмяПравила - имя правила конвертации +// +// Возвращаемое значение: +// Ссылка на правило конвертации (строка в таблице правил) +// +Функция НайтиПравило(Объект, ИмяПравила="") Экспорт + + Возврат ОбщиеПроцедурыФункции.НайтиПравило(Объект, ИмяПравила); + +КонецФункции + +//////////////////////////////////////////////////////////////////////////////// +// + +// Выполняет передачу строки данных для загрузки в базе-приемнике +// +// Параметры: +// ИнформацияДляЗаписиВФайл - Строка (текст XML) - строка с данными +// СтрокаОшибкиВБазеПриемнике - Строка - содержит описание ошибки при загрузке в базе-приемнике +// +Процедура ПередатьИнформациюОЗаписиВПриемник(ИнформацияДляЗаписиВФайл, СтрокаОшибкиВБазеПриемнике = "") Экспорт + + ОбщиеПроцедурыФункции.ПередатьИнформациюОЗаписиВПриемник(ИнформацияДляЗаписиВФайл, СтрокаОшибкиВБазеПриемнике); + +КонецПроцедуры + +// Выполняет запись имени, типа и значения параметра в файл сообщения обмена для передачи в базу-приемник +// +Процедура ПередатьОдинПараметрВПриемник(Имя, ИсходноеЗначениеПараметра, ПравилоКонвертации = "") Экспорт + + ОбщиеПроцедурыФункции.ПередатьОдинПараметрВПриемник(Имя, ИсходноеЗначениеПараметра, ПравилоКонвертации); + +КонецПроцедуры + +// Передает все дополнительные параметры в приемник +// +Процедура ПередатьДополнительныеПараметрыВПриемник() Экспорт + + ОбщиеПроцедурыФункции.ПередатьДополнительныеПараметрыВПриемник(); + +КонецПроцедуры diff --git "a/\320\230\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/src/DataProcessors/\320\243\320\230_\320\243\320\275\320\270\320\262\320\265\321\200\321\201\320\260\320\273\321\214\320\275\321\213\320\271\320\236\320\261\320\274\320\265\320\275\320\224\320\260\320\275\320\275\321\213\320\274\320\270XML/Templates/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\276\320\262/Template.mxlx" "b/\320\230\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/src/DataProcessors/\320\243\320\230_\320\243\320\275\320\270\320\262\320\265\321\200\321\201\320\260\320\273\321\214\320\275\321\213\320\271\320\236\320\261\320\274\320\265\320\275\320\224\320\260\320\275\320\275\321\213\320\274\320\270XML/Templates/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\276\320\262/Template.mxlx" new file mode 100644 index 00000000..7a660d41 --- /dev/null +++ "b/\320\230\320\275\321\201\321\202\321\200\321\203\320\274\320\265\320\275\321\202\321\213/src/DataProcessors/\320\243\320\230_\320\243\320\275\320\270\320\262\320\265\321\200\321\201\320\260\320\273\321\214\320\275\321\213\320\271\320\236\320\261\320\274\320\265\320\275\320\224\320\260\320\275\320\275\321\213\320\274\320\270XML/Templates/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\276\320\262/Template.mxlx" @@ -0,0 +1,6148 @@ + +Русский
+