При настройке интеграции 1С с интернет-магазинами (например, на платформе «1С-Битрикс») нередко возникает ситуация, когда дополнительные реквизиты характеристик или номенклатуры (вес, цвет, размер, производитель) изначально создаются с типом Строка. Однако для корректной фильтрации товаров и построения фасетного поиска в каталоге сайта требуется тип Дополнительное значение (ссылка на справочник ЗначенияСвойствОбъектов). Разберем, как правильно изменить тип свойства, не потеряв уже введенную информацию, и программно преобразовать строки в элементы справочника.
Рассмотрим, как ведет себя платформа и библиотека стандартных подсистем (БСП) при смене типа:
Проанализируем поэтапный план решения задачи:
ДополнительныеРеквизитыИСведения) изменяем тип со «Строка» на «Дополнительное значение».ЗначенияСвойствОбъектов и перезаписывает реквизит новыми ссылочными данными.Посмотрим на пример кода, выполняющего поиск и создание элементов справочника с последующей привязкой к характеристике:
// Получаем ссылку на наш дополнительный реквизит
Проверка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Проверка");
// В цикле выборки по характеристикам номенклатуры считываем текущее строковое значение
ТекущееЗначениеВВидеСтроки = УправлениеСвойствами.ЗначениеСвойства(Выборка.Ссылка, Проверка);
Если ЗначениеЗаполнено(ТекущееЗначениеВВидеСтроки) И ТипЗнч(ТекущееЗначениеВВидеСтроки) = Тип("Строка") Тогда
// Очищаем строку от лишних пробельных символов и нормализуем длину
СтрокаПоиска = СокрЛП(ТекущееЗначениеВВидеСтроки);
СтрокаПоиска = Лев(СтрокаПоиска, 150); // Учитываем лимит длины наименования справочника
// Выполняем точный поиск значения среди подчиненных текущему свойству
ЗначениеВВидеСправочника = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию(СтрокаПоиска, Истина, , Проверка);
Если Не ЗначениеЗаполнено(ЗначениеВВидеСправочника) Тогда
НовоеЗначение = Справочники.ЗначенияСвойствОбъектов.СоздатьЭлемент();
НовоеЗначение.Владелец = Проверка;
НовоеЗначение.Наименование = СтрокаПоиска;
НовоеЗначение.Записать();
ЗначениеВВидеСправочника = НовоеЗначение.Ссылка;
КонецЕсли;
// Записываем новое ссылочное значение в объект
ОбъектХарактеристика = Выборка.Ссылка.ПолучитьОбъект();
ОбъектХарактеристика.ОбменДанными.Загрузка = Истина;
// Находим строку в табличной части дополнительных реквизитов и обновляем значение
СтрокаТЧ = ОбъектХарактеристика.ДополнительныеРеквизиты.Найти(Проверка, "Свойство");
Если СтрокаТЧ <> Неопределено Тогда
СтрокаТЧ.Значение = ЗначениеВВидеСправочника;
ОбъектХарактеристика.Записать();
КонецЕсли;
КонецЕсли;
Рассмотрим подробнее неочевидные проблемы, которые могут возникнуть при выполнении конвертации:
ЗначенияСвойствОбъектов реквизит Наименование имеет фиксированную длину (как правило, до 100–150 символов). Если строковый реквизит содержал длинный текст, запись нового элемента вызовет исключение. Всегда используйте функцию Лев(...) для безопасного усечения строки до допустимой длины.СокрЛП не удаляет неразрывные пробелы (Символы.НПП), табуляции или случайные переносы строк. Если пользователи вводили одинаковые по смыслу названия с разным регистром или невидимыми спецсимволами, при поиске через НайтиПоНаименованию возникнут дубли. Рекомендуется предварительно заменять неразрывные пробелы на стандартные.XML_ID, чтобы модуль обмена CommerceML не выдал ошибку импорта.