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