При переносе данных из конфигураций на платформе 1С:Предприятие 7.7 в современные базы 1С:Предприятие 8 часто возникает задача трансформации простых типов данных в ссылочные. Типичный пример — перенос кадровых данных, когда в исходной базе 7.7 должность сотрудника хранится как обычная строка фиксированной длины (нередко периодическая), а в приемнике 1С 8 для должностей предусмотрен отдельный ссылочный справочник СправочникСсылка.Должности.
Разберем, почему стандартное правило конвертации свойств может не сработать напрямую, как правильно передать значение в подчиненное правило конвертации объектов и какие нюансы платформы 1С 7.7 следует обязательно учесть.
Проанализируем ситуацию. Если в правиле конвертации свойств (ПКС) для реквизита «Должность» просто указать в качестве правила конвертации подчиненное ПКО «Должности» (где объект-источник не задан, а объект-приемник — справочник ссылочного типа), механизм конвертации данных не сможет автоматически понять, какие именно данные из строки должны сформировать новый элемент справочника.
По умолчанию механизм конвертации ожидает, что источником для ПКО выступает объект или выборка данных. Если же передается строковое поле, обработчики подчиненного правила могут либо вовсе не сработать, либо сформировать пустую ссылку, так как поля поиска (например, Наименование) останутся незаполненными.
Рассмотрим наиболее простое и эффективное решение. Логика заключается в том, чтобы явно переопределить выгружаемое значение в свойстве родительского объекта, а в подчиненном ПКО направить это значение в наименование нового элемента.
В поле «Источник» оставляем реквизит источника или оставляем его пустым. В поле «Правило конвертации» выбираем ПКО «Должности».
В обработчике события ПередВыгрузкой данного ПКС пишем следующий код (с обязательным удалением хвостовых пробелов с помощью функции СокрЛП):
ЗначениеДолжности = СокрЛП(Источник.Должность.Получить(ТекущаяДата()));
Если ПустаяСтрока(ЗначениеДолжности) = 1 Тогда
Отказ = 1;
Иначе
Значение = ЗначениеДолжности;
КонецЕсли;
Обратите внимание на проверку заполненности: если в базе 7.7 должность не указана, вызов Отказ = 1; отменяет выгрузку свойства, предотвращая создание пустых элементов в справочнике приемника.
Поле «Объект-источник» оставляем пустым, в поле «Объект-приемник» указываем справочник СправочникСсылка.Должности.
В настройках самого ПКО обязательно включаем флаг «Автоматически генерировать номер или код, если он не задан», чтобы при создании нового элемента платформа 8.2 автоматически присвоила ему уникальный код.
Поле «Источник» оставляем пустым, поле «Приемник» — Наименование.
Обязательно устанавливаем флаг «Поиск» (по этому полю база-приемник будет искать существующую должность, чтобы не создавать дубли).
В обработчике ПередВыгрузкой свойства Наименование связываем полученную строку со значением реквизита:
Значение = Источник;
Так как в родительском ПКС переменной Значение была присвоена строка, в подчиненном ПКО эта строка стала значением переменной Источник.
Рассмотрим альтернативный, более гибкий вариант передачи параметров через предопределенные коллекции ИсходящиеДанные и ВходящиеДанные. Этот способ отлично подходит, когда помимо наименования требуется передать дополнительные реквизиты (например, признак группы или комментарий).
В ПКО «ФизическиеЛица» в обработчике ПередВыгрузкой ПКС «Должность» формируем структуру данных с помощью объекта СписокЗначений (так как выгрузка выполняется из 1С 7.7):
СтрДолжность = СокрЛП(Источник.Должность.Получить(ТекущаяДата()));
Если ПустаяСтрока(СтрДолжность) = 0 Тогда
ИсходящиеДанные = СоздатьОбъект("СписокЗначений");
ИсходящиеДанные.ДобавитьЗначение(СтрДолжность, "Наименование");
ИсходящиеДанные.ДобавитьЗначение(0, "ЭтоГруппа");
Иначе
Отказ = 1;
КонецЕсли;
В настройках ПКО «Должности» отмечаем флаг «Получить из входящих данных».
В ПКС «Наименование» ПКО «Должности» также взводим флаг «Получить из входящих данных» и отмечаем его как свойство поиска.
Разберем еще один способ, позволяющий полностью контролировать процесс выгрузки в коде. Метод ВыгрузитьПоПравилу возвращает ссылку на выгруженный объект, которую можно сразу присвоить реквизиту:
СтрДолжность = СокрЛП(Источник.Должность.Получить(ТекущаяДата()));
Если ПустаяСтрока(СтрДолжность) = 0 Тогда
Значение = ВыгрузитьПоПравилу(СтрДолжность, , , , "Должности");
Иначе
Отказ = 1;
КонецЕсли;
В этом случае в ПКС «Наименование» правила «Должности» по-прежнему должно быть прописано Значение = Источник; и установлен признак поиска по наименованию.
Выясним частые причины, из-за которых обработчики могут не отрабатывать или приводить к ошибкам:
Строка фиксированной длины в 7.7 всегда дополняются пробелами справа до максимальной длины поля (например, 25 символов). Если не использовать функцию СокрЛП(), строка вида "Директор " не сможет сопоставиться с существующей должностью "Директор" в 1С 8. Это приведет к дублированию справочников.V77Exp.ert (или не подключили сгенерированный текстовый файл), изменения в базе 7.7 выполняться не будут.