Используемые конфигурации: Управление торговлей 10.3.57.3.
Модуль обмена битрикс 7.0.1.8 (https://1c.1c-bitrix.ru/ecommerce/download.php).
В справочнике номенклатуры заведено несколько позиций, добавлено дополнительное свойство «Тип одежды», с типом значения «Значения свойств объектов», в типовой конфигурации «Тип одежды» может принимать только одно значение и выгрузку попадает только одно значение, необходимо настроить выгрузку нескольких значений.
С настройками по умолчанию выгрузка дополнительных свойств из 1с в файле import будет иметь следующий вид
Где ИД – Уникальный идентификатор Свойства «Тип Одежды»
Значение - Уникальный идентификатор значения свойства «Спортивная».
Один из способ решения данной задачи, приведен на форуме Битрикса https://dev.1c-bitrix.ru/community/forums/messages/forum26/topic19114/message335911/#message335911
Я сделаю немного по - другому, для этого мне придется внести изменения в типовую конфигурацию УТ 10.3, изменить xsd схему обмена и подправить процедуру выгрузки доп. свойств на сайт в модуле обмена Битрикс.
1. Изменения в типовой конфигурации УТ 10.3
В конфигураторе в плане видов характеристик «Свойства объектов» добавляем реквизит мультивыбор тип Булево.
В пользовательском режиме, проставляем галочку, и делаем Тип значения составной. «Строка» и «Значения свойств объектов»
В конфигураторе в карточке номенклатуры, на вкладке «Свойства» в колонке "Значение" активируем кнопку Открытия, в процедуре открытия вставляем следующий код
Процедура СвойстваИЗначенияЗначениеОткрытие(Элемент, СтандартнаяОбработка)
Если ЭтаФорма.ЭлементыФормы.СвойстваИЗначения.ТекущиеДанные.Свойство.Мультивыбор Тогда
СтандартнаяОбработка = Ложь;
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| ЗначенияСвойствОбъектов.Ссылка
|ИЗ
| Справочник.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
|ГДЕ
| ЗначенияСвойствОбъектов.Владелец = &Владелец";
Запрос.УстановитьПараметр("Владелец",ЭтаФорма.ЭлементыФормы.СвойстваИЗначения.ТекущиеДанные.Свойство);
СП = Новый СписокЗначений();
СП.ЗагрузитьЗначения(Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка"));
ЭлементыФормы.СвойстваИЗначения.Колонки["Значение"].ЭлементУправления.СписокВыбора = СП;
Иначе
СП = Новый СписокЗначений();
ЭлементыФормы.СвойстваИЗначения.Колонки["Значение"].ЭлементУправления.СписокВыбора = Новый СписокЗначений();
КонецЕсли;
МассивПодстрок = ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(Элемент.Значение,";");
Для Каждого ЭлементСписка Из ЭлементыФормы.СвойстваИЗначения.Колонки["Значение"].ЭлементУправления.СписокВыбора Цикл
НайденноеЗначение = МассивПодстрок.Найти(ЭлементСписка.Значение.Наименование);
ЭлементСписка.Пометка = НайденноеЗначение <> Неопределено;
КонецЦикла;
ИтоговаяСтрока = "";
Если ЭлементыФормы.СвойстваИЗначения.Колонки["Значение"].ЭлементУправления.СписокВыбора.ОтметитьЭлементы() Тогда
Для Каждого ЭлементСписка Из ЭлементыФормы.СвойстваИЗначения.Колонки["Значение"].ЭлементУправления.СписокВыбора Цикл
Если ЭлементСписка.Пометка Тогда
ИтоговаяСтрока = ?(ИтоговаяСтрока ="",?(ЭлементСписка.Значение=""," ",ЭлементСписка.Значение),""+ИтоговаяСтрока +";" + ?(ЭлементСписка.Значение=""," ",ЭлементСписка.Значение));
КонецЕсли;
КонецЦикла;
Элемент.Значение = ИтоговаяСтрока;
КонецЕсли;
КонецПроцедуры
После открытия в режиме предприятия, и нажатии на кнопку открытия, открывается окно с внесенными значениями, остается галочками отметить нужные свойств
В базе данное свойство будет храниться как строка, и в дальнейшем мы будем работать с этим свойство как со строкой. Это не совсем удобно, в частности накладывает ограничения, на переименования значений, поэтому дополнительно будем хранить в отдельном реквизите, значения уникальных идентификаторов, чтобы обращаться к значениям свойств не по наименованию, а по ГУИД
В регистр сведений Значения свойств объектов добавляем реквизит УИД тип строка (1024)
В обработку "Значения свойств объекта" в табличную часть «СвойстваИЗначения» добавляем реквизит УИД тип строка (1024)
Следует учитывать, что при такой длине строки плюс разделители, можно будет хранить порядка 27 значений. Если требуется больше значений, строку лучше сделать неограниченной длины, но для это придется сильнее модифицировать запрос, который приведен ниже.
В обработке "Значения свойств объекта" проводим следующие модификации:
в модуле объекта в процедуре ПрочитатьТаблицуСвойствИЗначений() в запрос добавляем строку
| СвойстваОбъектов.Наименование КАК Наименование,
| ЗначенияСвойствОбъектов.УИД КАК УИД
|ИЗ
| (ВЫБРАТЬ
В процедуру ЗаписатьЗначенияСвойств()
Добавляем строку кода Запись.УИД = Строка.УИД;
Если ЗначениеЗаполнено(Строка.Значение) Тогда
Запись = НаборЗаписейЗначенияСвойств.Добавить();
Запись.Объект = ОбъектОтбораЗначений;
Запись.Свойство = Строка.Свойство;
Запись.Значение = Строка.Значение;
Запись.УИД = Строка.УИД;
КонецЕсли;
В форму элемента Справочника номенклатуры, на закладке Свойства, добавляем скрытую колонку УИД, в качестве данных указываем колонку «УИД» из обработки ЗначенияСвойствОбъекта.
Модифицируем нашу процедуру в форме элемента номенклатуры, по кнопке открытия значения свойства, с учетом реквизита УИД.
Если ЭтаФорма.ЭлементыФормы.СвойстваИЗначения.ТекущиеДанные.Свойство.Мультивыбор Тогда
СтандартнаяОбработка = Ложь;
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| ЗначенияСвойствОбъектов.Ссылка
|ИЗ
| Справочник.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
|ГДЕ
| ЗначенияСвойствОбъектов.Владелец = &Владелец";
Запрос.УстановитьПараметр("Владелец",ЭтаФорма.ЭлементыФормы.СвойстваИЗначения.ТекущиеДанные.Свойство);
СП = Новый СписокЗначений();
СП.ЗагрузитьЗначения(Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка"));
ЭлементыФормы.СвойстваИЗначения.Колонки["Значение"].ЭлементУправления.СписокВыбора = СП;
Иначе
СП = Новый СписокЗначений();
ЭлементыФормы.СвойстваИЗначения.Колонки["Значение"].ЭлементУправления.СписокВыбора = Новый СписокЗначений();
КонецЕсли;
ТекСТрока = ЭлементыФормы.СвойстваИЗначения.ТекущаяСтрока;
МассивПодстрок = ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(ТекСТрока.УИД,";");
МассивЭлементов = Новый Массив();
Для Каждого ЭлементМассиваПодстрок Из МассивПодстрок Цикл
Если ЭлементМассиваПодстрок = "" Тогда
Продолжить;
КонецЕсли;
МассивЭлементов.Добавить(XMLЗначение(Тип("СправочникСсылка.ЗначенияСвойствОбъектов"), ЭлементМассиваПодстрок));
КонецЦикла;
Для Каждого ЭлементСписка Из ЭлементыФормы.СвойстваИЗначения.Колонки["Значение"].ЭлементУправления.СписокВыбора Цикл
НайденноеЗначение = МассивЭлементов.Найти(ЭлементСписка.Значение);
ЭлементСписка.Пометка = НайденноеЗначение <> Неопределено;
КонецЦикла;
ИтоговаяСтрока = "";
ИтоговаяСтрокаУИД = "";
Если ЭлементыФормы.СвойстваИЗначения.Колонки["Значение"].ЭлементУправления.СписокВыбора.ОтметитьЭлементы() Тогда
Для Каждого ЭлементСписка Из ЭлементыФормы.СвойстваИЗначения.Колонки["Значение"].ЭлементУправления.СписокВыбора Цикл
Если ЭлементСписка.Пометка Тогда
ИтоговаяСтрока = ?(ИтоговаяСтрока ="",?(ЭлементСписка.Значение=""," ",ЭлементСписка.Значение),""+ИтоговаяСтрока +";" +?(ЭлементСписка.Значение=""," ",ЭлементСписка.Значение));
ИтоговаяСтрокаУИД = ?(ИтоговаяСтрокаУИД ="",?(ЭлементСписка.Значение=""," ",XMLСТрока(ЭлементСписка.Значение)),""+ИтоговаяСтрокаУИД +";" +?(ЭлементСписка.Значение=""," ",XMLСТрока(ЭлементСписка.Значение)));
КонецЕсли;
КонецЦикла;
Элемент.Значение = ИтоговаяСтрока;
ТекСТрока.УИД =ИтоговаяСтрокаУИД;
КонецЕсли;
2. Корректировка xsd схемы выгрузки.
В Разделе Типы Объектов ЗначенияСвойства Добавляем новое свойство ЗначениеСвойства, и в него добавляем свойство Значение
3. Корректировка процедуры выгрузки доп. свойств на сайт в модуле обмена Битрикс.
В модуле Б_ПроцедурыИФункцииВыгрузкиДанныхНаСайт В процедуре СформироватьВременныеТаблицыПоИнформацииОТоварахПакета()
В подзапросе
ЗапросПоСвойствам = "ВЫБРАТЬ РАЗРЕШЕННЫЕ
| СвойстваОбъектов.Ссылка КАК СвойствоНоменклатуры,
Добавляем строки
|ЗначенияСвойствОбъектов.УИД КАК УИД,
|ЕСТЬNULL(ЗначенияСвойствОбъектов.Свойство.МультиВыбор, ЛОЖЬ) КАК МультиВыбор
|ПОМЕСТИТЬ ВремЗначенияСвойствТовара
В модуле Б_ОбменССайтомСерверВыгрузкаДанных В процедуре ВыгрузитьСвойстваXDTO() для нашего свойства с признаком мультивыбор, удаляем лишний тип значения с типом "Строка"
XDTOСвойство.ТипЗначений = "Строка";
Если ТекСвойство.СвойствоНоменклатуры.Мультивыбор И Типы.Количество() = 2 Тогда
//Типы.Удалить(0)
КолвоЭлементовКоллекции = Типы.Количество();
Для ОбратныйИндекс = 1 По КолвоЭлементовКоллекции Цикл
ЭлементКоллекции = Типы[КолвоЭлементовКоллекции - ОбратныйИндекс];
Если ЭлементКоллекции = Тип("Строка") Тогда
Типы.Удалить(КолвоЭлементовКоллекции - ОбратныйИндекс);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если НЕ Типы.Количество() <> 1 Тогда
Меняем Процедуру ВыгрузитьСвойстваНоменклатурыXDTO(). Привожу процедуру целиком
Процедура ВыгрузитьСвойстваНоменклатурыXDTO(ПараметрыОбмена, Владелец, ВладелецТип, ВыборкаНоменклатуры, лМенеджерВременныхТаблиц);
XDTOЗначенияСвойствТип = Б_ОбщиеПроцедурыИФункцииОбменаССайтом.ПолучениеТипОбъектаXDTO(ПараметрыОбмена, "ЗначенияСвойств", Истина, ВладелецТип);
XDTOЗначенияСвойстваТип = Б_ОбщиеПроцедурыИФункцииОбменаССайтом.ПолучениеТипОбъектаXDTO(ПараметрыОбмена, "ЗначенияСвойства");
XDTOЗначенияСвойствМножТип = Б_ОбщиеПроцедурыИФункцииОбменаССайтом.ПолучениеТипОбъектаXDTO(ПараметрыОбмена, "ЗначениеСвойства", Истина, XDTOЗначенияСвойстваТип);
Запрос = Новый Запрос;
запрос.МенеджерВременныхТаблиц = лМенеджерВременныхТаблиц;
запрос.Текст = "ВЫБРАТЬ *
|ИЗ
| ВремЗначенияСвойствТовара КАК ВремЗначенияСвойствТовара
|ГДЕ
| (ВремЗначенияСвойствТовара.Номенклатура = &Номенклатура)";
Запрос.УстановитьПараметр("Номенклатура", ВыборкаНоменклатуры.Номенклатура);
Выборка = Запрос.Выполнить();
Если НЕ Выборка.Пустой() тогда
ВыборкаСвойств = Выборка.Выбрать();
XDTOЗначенияСвойств = ПараметрыОбмена.МояФабрикаXDTO.Создать(XDTOЗначенияСвойствТип);
Пока ВыборкаСвойств.Следующий() Цикл
XDTOЗначенияСвойства = ПараметрыОбмена.МояФабрикаXDTO.Создать(XDTOЗначенияСвойстваТип);
XDTOЗначенияСвойства.Ид = XMLСтрока(ВыборкаСвойств.ИдентификаторСвойства);
МассивТипов = ВыборкаСвойств.ИдентификаторСвойства.ТипЗначения.Типы();
Если ВыборкаСвойств.МультиВыбор
И ТипЗНЧ(ВыборкаСвойств.Значение) = Тип("Строка") Тогда
МассивПодстрок = ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(ВыборкаСвойств.УИД,";");
Для Каждого ЗначениеЭлемента Из МассивПодстрок Цикл
//ЭлементСвойства = Справочники.ЗначенияСвойствОбъектов.НайтиПоНаименованию(ЗначениеЭлемента,Истина);
//Для каждого Свойство из ВыборкаСвойств.Значение Цикл
XDTOЗначенияМножСвойств = ПараметрыОбмена.МояФабрикаXDTO.Создать(XDTOЗначенияСвойствМножТип);
XDTOЗначенияМножСвойств.Значение = ЗначениеЭлемента;
XDTOЗначенияСвойства.ЗначениеСвойства.Добавить(XDTOЗначенияМножСвойств);
//КонецЦикла;
КонецЦикла;
XDTOЗначенияСвойств.ЗначенияСвойства.Добавить(XDTOЗначенияСвойства);
Иначе
//XDTOЗначенияСвойства = ПараметрыОбмена.МояФабрикаXDTO.Создать(XDTOЗначенияСвойстваТип);
//
//XDTOЗначенияСвойства.Ид = XMLСтрока(ВыборкаСвойств.ИдентификаторСвойства);
XDTOЗначенияСвойства.Значение.Добавить(XMLСтрока(ВыборкаСвойств.ИдентификаторЗначения));
XDTOЗначенияСвойств.ЗначенияСвойства.Добавить(XDTOЗначенияСвойства);
КонецЕсли;
КонецЦикла;
Владелец.ЗначенияСвойств = XDTOЗначенияСвойств;
КонецЕсли;
КонецПроцедуры
С вышеприведенными доработками выгрузка дополнительных свойств из 1с в файле import будет иметь следующий вид
На стороне Битрикс ничего дорабатывать не надо, значения должны встать автоматом.
Основной недостаток данного решения - это отсутствие контроля ссылочной целостности, при удалении значений свойств. Чтобы не пропали данные необходимо предусмотреть дополнительные механизмы