Как изменить тип дополнительного реквизита со «Строки» на «Дополнительное значение» без потери данных в 1С?

Программист 1С v8.3 (Управляемые формы) 1С:Управление нашей фирмой IT и автоматизация бизнеса
← На главную

При настройке интеграции 1С с интернет-магазинами (например, на платформе «1С-Битрикс») нередко возникает ситуация, когда дополнительные реквизиты характеристик или номенклатуры (вес, цвет, размер, производитель) изначально создаются с типом Строка. Однако для корректной фильтрации товаров и построения фасетного поиска в каталоге сайта требуется тип Дополнительное значение (ссылка на справочник ЗначенияСвойствОбъектов). Разберем, как правильно изменить тип свойства, не потеряв уже введенную информацию, и программно преобразовать строки в элементы справочника.

Особенности изменения типа и поведение подсистемы БСП

Рассмотрим, как ведет себя платформа и библиотека стандартных подсистем (БСП) при смене типа:

  1. Блокировка редактирования: Если для свойства уже введены данные, подсистема БСП блокирует смену типа в пользовательском интерфейсе. Для изменения типа потребуется интерактивно нажать «Разрешить редактирование реквизитов» в карточке дополнительного реквизита либо изменить тип программно.
  2. Сохранение старых значений: Платформа не очищает значения в табличных частях объектов автоматически при смене типа реквизита в плане видов характеристик (ПВХ). Старое значение остается физически записанным в базе данных, и его можно прочитать стандартными методами БСП.
  3. Валидация типов при стандартной записи: При попытке интерактивно переписать объект система управления свойствами проверяет соответствие типов. Если в объекте все еще сохраняется примитивная строка вместо ссылки, запись может завершиться ошибкой или значение очистится. Поэтому перезапись необходимо выполнять программно.

Алгоритм конвертации строковых значений в справочник

Проанализируем поэтапный план решения задачи:

  1. Обязательно создаем резервную копию информационной базы перед проведением массовых операций.
  2. В карточке дополнительного реквизита (план видов характеристик ДополнительныеРеквизитыИСведения) изменяем тип со «Строка» на «Дополнительное значение».
  3. Пишем и запускаем внешнюю обработку, которая обходит характеристики номенклатуры, считывает строковое представление, находит или создает элемент справочника ЗначенияСвойствОбъектов и перезаписывает реквизит новыми ссылочными данными.

Посмотрим на пример кода, выполняющего поиск и создание элементов справочника с последующей привязкой к характеристике:


// Получаем ссылку на наш дополнительный реквизит
Проверка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Проверка");

// В цикле выборки по характеристикам номенклатуры считываем текущее строковое значение
ТекущееЗначениеВВидеСтроки = УправлениеСвойствами.ЗначениеСвойства(Выборка.Ссылка, Проверка);

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

Подводные камни и важные нюансы реализации

Рассмотрим подробнее неочевидные проблемы, которые могут возникнуть при выполнении конвертации:

  1. Ограничение длины наименования: В справочнике ЗначенияСвойствОбъектов реквизит Наименование имеет фиксированную длину (как правило, до 100–150 символов). Если строковый реквизит содержал длинный текст, запись нового элемента вызовет исключение. Всегда используйте функцию Лев(...) для безопасного усечения строки до допустимой длины.
  2. Дублирование значений: Метод СокрЛП не удаляет неразрывные пробелы (Символы.НПП), табуляции или случайные переносы строк. Если пользователи вводили одинаковые по смыслу названия с разным регистром или невидимыми спецсимволами, при поиске через НайтиПоНаименованию возникнут дубли. Рекомендуется предварительно заменять неразрывные пробелы на стандартные.
  3. Массовая регистрация изменений на узлах обмена: Запись большого количества характеристик приведет к тому, что все они попадут в очередь изменений плана обмена с интернет-магазином. При следующем регламентном задании выгрузится весь каталог, что создаст высокую нагрузку на сайт. Если выгрузку нужно провести поэтапно, временно очистите зарегистрированные изменения для узла обмена.
  4. Синхронизация со стороны «1С-Битрикс»: Изменение типа свойства в 1С не преобразует тип свойства в инфоблоке сайта автоматически. В Битриксе строковое свойство имеет тип S («Строка»), а ссылочное — тип L («Список»). До запуска первого обмена после конвертации необходимо вручную изменить тип инфоблока на сайте или пересоздать свойство с сохранением внешнего кода XML_ID, чтобы модуль обмена CommerceML не выдал ошибку импорта.
← На главную