При работе с инструментом «Конвертация данных 2.1» часто возникает классическая задача: необходимо управлять процессом загрузки объектов (например, документов) непосредственно в базе-приемнике. Стандартный механизм КД предполагает передачу параметров через файл обмена, когда значения устанавливаются еще на этапе выгрузки. Однако на практике часто требуется решить обратную задачу — предоставить пользователю выбор в обработке загрузки: перезаписывать существующие документы или оставить их без изменений.
В этой статье мы подробно разберем, как реализовать механизм передачи параметров при загрузке, проанализируем работу встроенных обработчиков и выясним, как правильно использовать флаг НеЗамещатьОбъект для гибкого управления данными.
Представим ситуацию: у нас есть готовая обработка на базе «Универсального обмена данными XML». На форму этой обработки мы добавили флажок (галку) «Не перезаписывать существующие документы». Наша цель — сделать так, чтобы правила конвертации «увидели» этот флажок в момент чтения XML-файла и применили соответствующую логику.
Основная сложность заключается в том, что стандартная структура Параметры в правилах обычно заполняется из заголовка XML-файла, сформированного при выгрузке. Если нам нужно передать значение именно на этапе загрузки, придется задействовать программные возможности обработки обмена и специфические обработчики правил.
Самый правильный и чистый с точки зрения архитектуры способ — это принудительное заполнение коллекции параметров в объекте обработки перед тем, как будет запущен процесс загрузки. Если вы вызываете загрузку программно или модифицируете форму «Универсального обмена», вы можете напрямую обратиться к коллекции Параметры.
Разберем этот процесс по шагам:
ВыполнитьЗагрузку() (или аналогичного системного кода) добавьте инициализацию параметра.Пример программного кода в модуле формы обработки загрузки:
// Предположим, на форме обработки есть реквизит НеПерезаписыватьДокументы (Булево)
ОбъектОбработки = РеквизитФормыВЗначение("Объект");
// Если используется обычная форма, то работаем напрямую с 'ЭтаФорма.Объект'
// Наполняем структуру параметров загрузки
ОбъектОбработки.Параметры.Вставить("НеПерезаписыватьОбъекты", НеПерезаписыватьДокументы);
// Теперь можно запускать загрузку
ОбъектОбработки.ВыполнитьЗагрузку();
После этого в любом обработчике правил (ПКО или глобальных) этот параметр станет доступен через стандартную коллекцию Параметры.НеПерезаписыватьОбъекты.
Если вы не хотите сильно менять код самой обработки загрузки, мы можем проанализировать ситуацию в глобальном обработчике самих правил конвертации. Рассмотрим ситуацию, когда нам нужно инициализировать параметр в самом начале процесса чтения файла.
Перейдите в конфигурацию «Конвертация данных», откройте ваши правила и найдите вкладку «Алгоритмы/Параметры» -> «Глобальные обработчики» -> «Перед загрузкой данных». Этот код выполняется один раз, когда файл уже открыт, но объекты еще не начали создаваться.
Здесь мы можем проверить наличие параметров или даже вызвать диалог (хотя вызов диалогов в этом месте крайне не рекомендуется, если обмен может идти в фоновом режиме):
// Инициализируем значение по умолчанию, если оно не было передано программно
Если Параметры.Найти("НеПерезаписыватьОбъекты") = Неопределено Тогда
Параметры.Вставить("НеПерезаписыватьОбъекты", Ложь);
КонецЕсли;
Теперь выясним, как использовать переданный параметр для достижения цели — запрета перезаписи. Для этого идеально подходит обработчик ПКО «Перед загрузкой» или глобальный обработчик «Перед загрузкой объекта».
Проанализируем логику работы системы: когда программа находит объект в базе данных по полям поиска, она по умолчанию обновляет его реквизиты данными из файла. Чтобы это предотвратить, нужно установить специальный флаг НеЗамещатьОбъект в значение Истина.
Рассмотрим пример кода в обработчике «Перед загрузкой объекта» (глобальный уровень):
// Проверяем, является ли текущий объект документом
Если Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(Объект)) Тогда
// Проверяем наш параметр, переданный из формы загрузки
ЗначениеПараметра = Ложь;
Параметры.Свойство("НеПерезаписыватьОбъекты", ЗначениеПараметра);
Если ЗначениеПараметра = Истина Тогда
// Если объект уже существует в базе (найден по ссылке или коду/номеру)
// установка НеЗамещатьОбъект = Истина предотвратит его перезапись
НеЗамещатьОбъект = Истина;
КонецЕсли;
КонецЕсли;
Важный нюанс: использование НеЗамещатьОбъект не отменяет поиск объекта. Программа все равно попытается найти его в базе. Если объект не будет найден, он будет создан. Если объект будет найден, он останется в прежнем состоянии, а данные из файла загружены не будут.
Иногда разработчики используют «быстрый», но менее надежный способ — прямое обращение к объекту обработки загрузки из кода правил. В обработчиках загрузки переменная Объект часто указывает на саму обработку «Универсальный обмен данными XML» (или вашу кастомную).
Разберем, как это может выглядеть в коде обработчика:
// В обработчике 'Перед загрузкой объекта' переменная 'ПараметрыОбъекта'
// или контекст могут позволить достучаться до реквизитов формы.
// Однако этот путь зависит от версии обработки и платформы.
// Рекомендуется все же передавать данные через структуру 'Параметры'.
Посмотрим на более надежный способ передачи данных между разными событиями одного и того же объекта. Если вы определили необходимость пропуска записи в начале, но вам нужно выполнить какие-то действия в конце, используйте ДополнительныеСвойства объекта базы данных:
// В обработчике "При загрузке"
Объект.ДополнительныеСвойства.Вставить("ТолькоДляНовых", Истина);
Для наглядности проанализируем, какие инструменты за что отвечают в процессе загрузки:
Истина, то существующий в базе объект не будет обновлен данными из XML.Истина, объект не будет загружен вовсе (даже не будет создан новый).Подводя итог, разберем оптимальный алгоритм действий для вашей задачи:
1. В правилах конвертации (КД 2.1) на закладке «Параметры» создайте параметр с идентификатором НеПерезаписыватьДокументы и типом Булево.
2. В обработке загрузки, которой вы пользуетесь, обеспечьте заполнение этого параметра. Если это самописная загрузка, используйте Объект.Параметры.Вставить(...) перед началом обмена.
3. В правилах конвертации в ПКО нужных вам документов (или в глобальном обработчике) напишите лаконичный код:
Если Параметры.НеПерезаписыватьДокументы = Истина Тогда
НеЗамещатьОбъект = Истина;
КонецЕсли;
Такой подход обеспечит стабильную работу обмена и даст пользователю желаемую гибкость при импорте данных. Помните, что тестирование подобных механизмов лучше проводить на копии базы, проверяя как создание новых элементов, так и попытку обновления уже существующих документов с разными значениями флажка.