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