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