При переносе данных между платформой 1С 8.х и устаревшей, но все еще актуальной 1С 7.7 через конфигурацию «Конвертация данных 2.0», программисты часто сталкиваются с проблемой идентификации объектов. Одной из специфических задач является поиск элемента в справочнике приемника (7.7) по его полному коду, который хранится в источнике (8.х) в виде отдельного реквизита. Рассмотрим подробно, как правильно реализовать такой поиск, какие подводные камни нас ожидают и какие альтернативные подходы существуют.
Прежде чем приступать к написанию правил, разберем техническое ограничение платформы 1С 7.7. В отличие от 1С 8.х, где метод НайтиПоКоду может принимать полный путь, встроенный язык 1С 7.7 работает иначе. Метод НайтиПоКоду(Код, Флаг) принимает два параметра:
Важно понимать: если мы передадим в этот метод строку вида "001/002/005", система 7.7 не будет пытаться найти элемент «005» внутри папок «001» и «002». Она будет искать элемент, чей непосредственный код буквально равен строке со слешами. Так как в 7.7 символы разделителей (обычно /) не входят в сам код элемента, такой поиск вернет 0 (объект не найден).
Если в вашем справочнике приемнике (7.7) установлена уникальность кода во всем справочнике (а не только в пределах группы), задача значительно упрощается. Как выяснил автор темы в процессе обсуждения, наличие «полного кода» в источнике может быть избыточным наследством старой архитектуры. Если уникальность глобальная, нам достаточно извлечь последнюю значащую часть кода.
Проанализируем ситуацию: если полный код имеет формат 0001/0002/0003, то искомым кодом элемента в 7.7 будет именно 0003. В этом случае в ПКС (Правиле конвертации свойств) для реквизита Код в обработчике «Перед выгрузкой» или «При загрузке» (в зависимости от логики) можно выполнить простое преобразование строки.
Однако помните о формате кода в 1С 7.7. Если в конфигураторе 7.7 задана длина кода 10 символов и тип «Текстовый», то код 5 и код 0000000005 для системы — это разные сущности. Рассмотрим пример кода для нормализации значения:
// Пример на языке 1С 8 для ПКС "Код" (Перед выгрузкой)
ПолныйКод = Источник.РеквизитСПолнымКодом;
ЧастиКода = СтрРазделить(ПолныйКод, "/."); // учитываем возможные разделители
Значение = ЧастиКода[ЧастиКода.Количество() - 1]; // берем последний сегмент
Если уникальность кодов в 7.7 соблюдается только в пределах группы, то поиск по «чистому» коду выдаст первый попавшийся элемент с таким номером, что приведет к ошибкам в данных. Здесь нам на помощь приходит обработчик «ПоляПоиска» в ПКО (Правила конвертации объектов).
Разберем алгоритм поиска по шагам:
ВходящиеДанные) или через дополнительный реквизит, который не сопоставлен напрямую.Проанализируем пример логики для 1С 7.7:
// Логика поиска в 7.7 (псевдокод для понимания алгоритма)
Спр = СоздатьОбъект("Справочник.Номенклатура");
ТекРодитель = ""; // начинаем с корня
Для и=1 По КоличествоСегментов Цикл
ТекКод = ПолучитьСегмент(ПолныйКод, и);
Если Спр.НайтиПоКоду(ТекКод, ?(ПустоеЗначение(ТекРодитель)=1, 0, 1)) = 1 Тогда
ТекРодитель = Спр.ТекущийОбъект();
Спр.ИспользоватьРодителя(ТекРодитель);
Иначе
// Элемент или группа не найдены
Прервать;
КонецЕсли;
КонецЦикла;
Если иерархия (родители) в источнике и приемнике совпадает, это самый надежный метод для «Конвертации данных». Мы просто устанавливаем галочку «Поиск» у двух свойств: Код и Родитель. Система сначала попытается найти или создать родителя, а затем выполнит поиск элемента по коду внутри этого родителя.
Однако, как указано в сообщении 6, часто родители в приемнике и источнике не совпадают. В такой ситуации стандартный механизм поиска «Код + Родитель» не сработает, так как система не сможет сопоставить владельцев. Единственным выходом остается либо поиск по уникальному коду (если он уникален глобально), либо сложный поиск по текстовому пути, описанный в Решении 2.
Рассмотрим ситуацию, когда коды могут меняться пользователями вручную. Поиск по коду (даже полному) в 7.7 — это всегда риск. Профессиональный подход заключается в следующем:
ID_V8 (длина 36 символов).УникальныйИдентификатор() объекта из 1С 8.ID_V8).Это гарантирует 100% точность сопоставления, даже если в 7.7 элемент переименовали, переместили в другую папку или изменили ему код.
Выясним причины возможных неудач при поиске, которые часто упускают из виду:
"005" может не сработать. Если стоит «Текстовый» с длиной 10, то при передаче кода "5" из 8-ки, в 7.7 нужно программно дополнить его лидирующими нулями до "0000000005", иначе НайтиПоКоду провалится.ПолныйКод() в качестве разделителя используются точки. В 1С 7.7 стандартным разделителем является прямой слеш /. При передаче строки убедитесь, что вы привели разделители к единому стандарту.Подведем итог: Если вы уверены в глобальной уникальности кодов, используйте Решение 1 (выделение короткого кода). Если важна иерархия, но родители отличаются — используйте Решение 2 через обработчик ПоляПоиска. Для долгосрочных проектов и стабильного обмена лучшим выбором будет Решение 4 с внедрением идентификатора GUID в базу 7.7.