Создание множественного дополнительного реквизита. Управление торговлей 11

20.03.18

Интеграция - Файловый обмен (TXT, XML, DBF), FTP

Создание механизма множественного дополнительного реквизита для выгрузки в битрикс.

Здравствуйте, уважаемые читатели! 

Хочу поделиться своей реализацией множественного выбора дополнительного реквизита в Управлении торговлей 11 (проверено на 11.4.1.261) для последующей выгрузки его в интернет-магазин под управлением 1С битрикс. Для чего это потребовалось? В определенный момент менеджер интернет-магазина мне сказал: хочу увидеть весь ассортимент выбранного товара (условно назовем его Товар№1) красного, синего и зеленого цветов, как?. Сразу оговорюсь, что по ряду внутренних причин характеристики мы не используем, возможно, с ними будет совсем другая история, но поскольку данный вопрос возникает периодически, я решил написать эту статью. Так вот, в УТ цвет это у нас дополнительный реквизит и соответственно он может принимать только одно значение. На сайте это выглядит как выбор из списка, а требуется чтобы можно было отмечать галочкой несколько значений.

з.ы. это моя первая публикация (не только на ИС, но и вообще), не судите строго :)

Итак, начнем. Весь процесс доработки можно разделить на 3 этапа:

  1. Доработка механизма создания и вывода на форму дополнительных реквизитов.
  2. Доработка xsd схемы.
  3. Доработка выгрузки на сайт.

1. Доработка механизма создания и вывода на форму дополнительных реквизитов.

Перед выводом доп. реквизитов на форму создается таблица значений содержащая нужные нам реквизиты и их значения (далее будем называть их свойствами, по скольку везде в коде они так и именуются). Но она содержит только уникальные свойства и каждое представлено одной строкой. Поэтому необходимо позаботиться о копировании нашего свойства.

Чтобы получать ссылку на нужный элемент ПВХ, я добавил функцию в модуль УправлениеСвойствамиСлужебный

Функция ПолучитьУИДМножественногоСвойства() Экспорт
    Возврат "859484ef-7e0a-11e7-8111-3863bb43122b";
КонецФункции

возвращающую уникальный идентификатор. Затем, в этом же модуле, находим функцию ЗначенияСвойств, которая и формирует вышеописанную таблицу дополнительных реквизитов для вывода на форму. В самом ее конце есть цикл, который выглядит вот так:

Перед ним добавим следующий код:

лУИД = Новый УникальныйИдентификатор(ПолучитьУИДМножественногоСвойства());
МножественноеСвойство = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.ПолучитьСсылку(лУИД);
ЭтоПервый = Истина;

А в теле цикла будем отлавливать наше свойство следующим образом:

Если Строка.Свойство = МножественноеСвойство Тогда
    Если ЭтоПервый Тогда
        ЭтоПервый = Ложь;
    Иначе 
        фКэшОписания = ОписаниеСвойства;
        ОписаниеСвойства = ОписаниеСвойств.Добавить();
        ЗаполнитьЗначенияСвойств(ОписаниеСвойства, фКэшОписания);
    КонецЕсли;
КонецЕсли;

В итоге должна получится следующая картина:

После этого переходим к созданию элементов на форме. Тут логика следующая, каждый дополнительный реквизит в своем наименовании имеет уникальный идентификатор и тем самым обеспечивается уникальность (простите за тавтологию) имен элементов формы. Поэтому нам необходимо пронумеровать наш реквизит в момент создания. За это отвечает процедура ЗаполнитьДополнительныеРеквизитыВФорме общего модуля УправлениеСвойствами.

Находим в ней строку

Для каждого ОписаниеСвойства Из ОписаниеСвойств Цикл

Перед началом этого цикла вставим счетчик, например:

СчСвойств = 1;

А в теле цикла, после строки

ОписаниеСвойства.ИмяУникальнаяЧасть = ...

добавим наш код:

Если СтрНайти(Строка(ОписаниеСвойства.Свойство.УникальныйИдентификатор()), УправлениеСвойствамиСлужебный.ПолучитьУИДМножественногоСвойства()) > 0 Тогда             
    ОписаниеСвойства.ИмяУникальнаяЧасть = ОписаниеСвойства.ИмяУникальнаяЧасть    +"_"+ Строка(СчСвойств);            
    СчСвойств = СчСвойств + 1;                                                  
КонецЕсли;

Получается такая картина:

Дальше, чтобы не заморачиваться с формой при обновлении, добавляем ее в расширение. Добавляем событие ПриСозданииНаСервере с типом вызова "После", в нем создаем кнопку для копирования и заполним технические реквизиты. На форму потребуется добавить 2 реквизита:

1. МножВыборИмя - тип строка, хранит имя дополнительного реквизита без индекса

2. СчСвойств - тип число, хранит текущий индекс дополнительного реквизита.

 
 Полный текст модуля формы в расширении

После этих действий у вас должно получиться что-то подобное:

Если нужно добавить кнопку удаления реквизитов, то, думаю, у вас не возникнет с этим больших проблем :)

2. Доработка xsd схемы.

Если вы не знакомы с этой темой, то в интернете полно информации с подробным описанием, расписывать детально тут не буду. Схема находится в плане обмена Б_ОбменССайтом в макете СхемаXSDОбмена. Сохраняем в файл, открываем и находим там строку

<xs:complexType name="ЗначенияСвойства">

после элемента "Значение" добавляем следующий код

<xs:element name="ЗначениеСвойства" minOccurs="0" maxOccurs="unbounded" >
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="Значение" type="tns:ЗначениеТип" maxOccurs="1" />
                    </xs:sequence>
                </xs:complexType>
            </xs:element>

В итоге должно получится следующее: 

Далее обновляем макет в плане обмена и сохраняем конфигурацию. Все, xsd схема готова.

3. Доработка выгрузки на сайт.

Итак, мы на финишной прямой. Еще чуточку усилий и все будет готово!

Открываем общий модуль Б_ОбменССайтомСерверВыгрузкаДанных, находим в нем процедуру ВыгрузитьСвойстваXDTO,

в ней ищем строку:

XDTOСвойство.Наименование	= Лев(ТекСвойство.Наименование, 250);

это в цикле по коллекции тзнСвойств. После нее добавляем проверку. Если это наше свойство, то делаем его множественным.

Если СтрНайти(XDTOСвойство.Ид, УправлениеСвойствамиСлужебный.ПолучитьУИДМножественногоСвойства()) Тогда
	XDTOСвойство.Множественное = Истина;
КонецЕсли;

Далее нам нужно подкорректировать процедуру ВыгрузитьСвойстваНоменклатурыXDTO. Она не очень большая, поэтому приведу ее листинг с доработками. 

 
 Процедура ВыгрузитьСвойстваНоменклатурыXDTO

 

Вот и все, после этих манипуляций, xml код файла для битрикса должен выглядеть примерно так:

Битрикс такую структуру понимает и никаких действий со стороны сайта делать не требуется. Если вы все сделали правильно, то все должно работать.

p.s. 

Хочу поблагодарить Сергея Главатских за его идею копирования дополнительных реквизитов, а так же парней из ветки https://dev.1c-bitrix.ru, без них у меня бы ничего не получилось.

доработка обмен xml xsd битрикс множественный реквизит множественный выбор

См. также

SALE! 20%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Россия Платные (руб)

Правила в универсальном формате обмена для ERP 2.5, КА 2.5, УТ 11.5, БП 3.0, Розница, УНФ, для последних версий конфигураций. Ссылки на другие конфигурации в описании публикации. Правила совместимы со всеми другими версиями конфигураций новыми и старыми, поддерживающими обмен и синхронизацию в формате EnterpriseData. Не требуется синхронного обновления правил после обновления другой конфигурации, участвующей в обмене. Типовой обмен через планы обмена кнопкой Синхронизация вручную или автоматически по расписанию, или вручную обработкой.

26280 22338 руб.

12.06.2017    141463    798    297    

419

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 1С:Управление производственным предприятием 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Управленческий учет Платные (руб)

Перенос данных из 1С:Управление производственным предприятием 1.3 в 1С:Бухгалтерия предприятия 3.0 с помощью правил обмена. Переносятся остатки, документы (обороты за период), справочная информация. Правила проверены на конфигурациях УПП 1.3 (1.3.234.x) и БП 3.0 (3.0.161.x). Правила подходят для версии ПРОФ и КОРП.

35000 31500 руб.

15.12.2021    23984    169    51    

127

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 Оперативный учет 1С:Управление торговлей 10 Россия Управленческий учет Платные (руб)

Перенос данных из 1С:Управление торговлей 10.3 в 1С:Управление торговлей 11.5 с помощью правил обмена. Переносятся остатки, документы (обороты за период), справочная информация. Правила проверены на конфигурациях УТ 10.3 (10.3.88.x) и УТ 11.5 (11.5.19.x).

35000 31500 руб.

23.07.2020    51177    228    69    

185

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Россия Бухгалтерский учет Управленческий учет Платные (руб)

Перенос данных из ERP в ЗУП 3 | из КА 2 в ЗУП | Готовые правила конвертации данных (КД 2) для переноса остатков, документов с движениями и справочной информации 3 | Есть перенос начальной задолженности по зарплате и начальной штатной расстановки на выбранную дату | Обороты за прошлые годы (данные для расчета среднего) переносятся свернуто в документ "Перенос данных" | Есть фильтр по организациям | Документы за текущий период переносятся сразу с движениями, поэтому не потребуется делать перерасчеты | Перенос можно проверить перед покупкой, обращайтесь!

53111 47800 руб.

03.12.2020    36568    94    66    

89

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 1С:Комплексная автоматизация 1.х 1С:Управление производственным предприятием 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Платные (руб)

Перенос данных из 1С:Управление производственным предприятием 1.3 в 1С:Бухгалтерия предприятия 3.0 с помощью правил обмена | Можно выполнить переход с УПП на БП 3 или запускать выгрузку данных за выбранный период времени | Переносятся документы, начальные остатки и вся справочная информация | Есть фильтр по организации и множество других параметров выгрузки | Поддерживается несколько сценариев работы: как первичный полный перенос, так и перенос только новых документов | Перенос данных возможен в "1С: Бухгалтерия 3.0" версии ПРОФ, КОРП или базовую | Переход с "1С: УПП1.3" / "1С:КА 1.1" на "1С:БП3.0" с помощью правил конвертации будет максимально комфортным! | Можно бесплатно проверить перенос на вашем сервере!

48278 43450 руб.

25.02.2015    171154    303    257    

378

SALE! 15%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 Платформа 1C v8.2 1С:Комплексная автоматизация 1.х 1С:Управление торговлей 10 1С:Управление производственным предприятием Россия Платные (руб)

Регулярный обмен, выгрузка, перенос из КА 1.1, УПП 1.3, УТ 10.3 для обмена с любыми конфигурациями, поддерживающими обмен в формате EnterpriseData (КД3) - БП 3.0, ERP, КА 2, УТ 11, Розница 2, УНФ 1.6 и другими. Правила для старых и доработанных конфигураций не требуют синхронного обновления и совместимы с новыми и будущими конфигурациями. Обмен по расписанию, через папку, FTP, почту.

15300 13005 руб.

18.02.2016    186854    589    509    

526

SALE! 10%

Перенос данных 1C Взаиморасчеты Оптовая торговля Логистика, склад и ТМЦ Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 1С:Управление торговлей 10 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Управленческий учет Платные (руб)

Можно проверить до покупки, оставьте заявку! Воспользовались более 268 компаний! Перенос данных из УТ 10.3 в УТ 11 | из УТ 10.3 в КА 2 | из УТ 10.3 в ERP. Предлагаем качественное и проверенное временем решение для перехода с УТ 10.3. Можно перенести начальные остатки, нормативно-справочную информацию и все возможные документы. При выгрузке можно установить отбор по периоду, организациям и складам. При выходе новых релизов конфигураций 1C оперативно выпускаем обновление переноса данных.

55778 50200 руб.

24.04.2015    194949    150    243    

280

SALE! 10%

Перенос данных 1C Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Платформа 1С v8.3 1С:Комплексная автоматизация 1.х 1С:Управление торговлей 10 1С:Управление производственным предприятием 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Платные (руб)

Перенос данных из ERP в УПП 1.3 | из КА 2 в КА 1.1 | из КА 2 в УПП 1.3 | из КА 2 в УТ 10.3 | из ERP в КА 1.1 | из ERP в УТ 10.3 | из УТ 11 в УТ 10.3 | из УТ 11 в УПП 1.3 | из УТ 11 в КА 1.1 | Можно переносить только новые объекты, найденные в приемнике перезаписываться не будут | Есть фильтр по организации при выгрузке данных | Оперативно обновляем на новые релизы 1С

53111 47800 руб.

28.11.2015    83235    32    125    

64
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. EmpireSer 21.03.18 00:47 Сейчас в теме
По мне "ЗначениеСвойства" в XSD задан "не красиво". Можно было всё в одном месте указать:
<xs:element name="ЗначениеСвойства" type="tns:ЗначениеТип" minOccurs="0" maxOccurs="unbounded" />

Так же можно было доработать доп. реквизит так, что бы он просто принимал "СписокЗначений", а не делать копирование. По моему мнению это получилось "элегантнее".
shurik_shurik; +1 Ответить
2. bad_wag 51 21.03.18 11:06 Сейчас в теме
(1) В начале я так и пытался сделать, но для этого потребовалось дорабатывать поддержку списков значений доп реквизитами, а это, на мой взгляд, гораздо сложнее данной реализации
3. vis_tmp 32 11.05.18 18:15 Сейчас в теме
Спасибо, очень познавательно про множественные доп. реквизиты.
6. bad_wag 51 06.06.18 02:00 Сейчас в теме
4. mark_oilbass 05.06.18 14:07 Сейчас в теме
5. bad_wag 51 06.06.18 01:59 Сейчас в теме
9. itdvl 28 16.08.18 06:41 Сейчас в теме
(5) не понимаю как сделать кнопку удалить. Не подскажете?
7. mark_oilbass 04.07.18 15:39 Сейчас в теме
Коллеги, подскажите пожалуйста! как быть если множественных реквизитов несколько? Я в плане видов характеристик создал реквизит МножественныйРеквизит и с помощью него получаю все множественные доп свойства. Перед выгрузкой свойств формирую запрос результатом, которого является список всех множественных свойств и дальше делаю такие же проверки как в этой статье. Прикрепляю файл с кодом. Заработает ли такой код?
Прикрепленные файлы:
Код.txt
8. mark_oilbass 05.07.18 11:24 Сейчас в теме
10. EliWalles 27.05.19 10:02 Сейчас в теме
Возможно ли вынести функции в расширение и воспользоваться &Вместо("ЗаполнитьДополнительныеРеквизитыВФорме") такой конструкцией, что бы не менять конфигурацию, будет работать?
УИД - это в XML файле экспорта поле <Ид>?
11. bad_wag 51 27.05.19 13:41 Сейчас в теме
(10) Вынести в расширение можно, работать будет, но при обновлениях конфигурации надо будет следить за изменениями в этой функции. Про УИД сейчас не вспомню, можно посмотреть отладчиком или выгрузить в файл там уже глянуть
12. goodwill 20 02.07.19 15:40 Сейчас в теме
Большое спасибо за выложенный материал, очень помог.

Хочу добавить от себя немного, Мне показалось не очень удачным определять множественный реквизит по GUID, в разных базах они разные и код получается не универсальным. Так же нет возможности добавить несколько множественных реквизитов. Для того что бы это исправить я добавил в ПланВидовХарактеристик.ДополнитеотныеРеквизитыИСведения новый реквизит МножественныйРеквизит

Изменения от первоначальной статьи следующие
1) Функция ПолучитьУИДМножественногоСвойства() не нужна
2) В модуле УправлениСвойствами

Если ОписаниеСвойства.Свойство.МножественныйРеквизит Тогда
	ОписаниеСвойства.ИмяУникальнаяЧасть = ОписаниеСвойства.ИмяУникальнаяЧасть    +"_"+ Строка(СчСвойств);            
	СчСвойств = СчСвойств + 1;                                                  
КонецЕсли;


3) УправлениеСвойствамиСлужебный


// < -- xs
СоответствиеСвойствЭтоПервый = Новый Соответствие;
// xs -- > 
	
// Заполнение значений свойств.
Для Каждого Строка Из ДополнительныеСвойстваОбъекта Цикл
	ОписаниеСвойства = ОписаниеСвойств.Найти(Строка.Свойство, "Свойство");
	Если ОписаниеСвойства <> Неопределено Тогда
		
		// < -- xs
		Если СоответствиеСвойствЭтоПервый.Получить(Строка.Свойство) = Неопределено Тогда
			СоответствиеСвойствЭтоПервый.Вставить(Строка.Свойство, Истина);
		КонецЕсли; 
		
		Если Строка.Свойство.МножественныйРеквизит Тогда
			
			Если СоответствиеСвойствЭтоПервый.Получить(Строка.Свойство) Тогда
				СоответствиеСвойствЭтоПервый.Вставить(Строка.Свойство, Ложь);
			Иначе 
				фКэшОписания = ОписаниеСвойства;
				ОписаниеСвойства = ОписаниеСвойств.Добавить();
				ЗаполнитьЗначенияСвойств(ОписаниеСвойства, фКэшОписания);
			КонецЕсли;
		КонецЕсли;
		// xs -- > 

		// Поддержка строк неограниченной длины.
		Если НЕ ЭтоДополнительноеСведение
		   И ИспользоватьНеограниченнуюСтроку(
		         ОписаниеСвойства.ТипЗначения, ОписаниеСвойства.МногострочноеПолеВвода)
		   И НЕ ПустаяСтрока(Строка.ТекстоваяСтрока) Тогда 
			
			ОписаниеСвойства.Значение = Строка.ТекстоваяСтрока;
		Иначе
			ОписаниеСвойства.Значение = Строка.Значение;
			КонецЕсли;
	КонецЕсли;
КонецЦикла;
Показать


4) Форма элемента справочника Номенклатура, так же добавил туда кнопку удаления реквизита.


&НаСервере
Процедура хот_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
	
	НоваяКоманда = ЭтаФорма.Команды.Добавить("СкопироватьСвойство");
	НоваяКоманда.Заголовок = "+";
	НоваяКоманда.Действие = "хот_СкопироватьСвойство";
	
	НоваяКоманда = ЭтаФорма.Команды.Добавить("УдалитьСвойство");
	НоваяКоманда.Заголовок = "-";
	НоваяКоманда.Действие = "хот_УдалитьСвойство"; 
	
	Для каждого стрДополнительногоРеквизита Из ЭтаФорма.Свойства_ОписаниеДополнительныхРеквизитов Цикл
		
		Если НЕ стрДополнительногоРеквизита.Свойство.МножественныйРеквизит Тогда
			Продолжить;
		КонецЕсли; 
			
		Если Элементы.Найти("КнопкаСкопироватьСвойство") = Неопределено Тогда
			НоваяКнопка = Элементы.Добавить("КнопкаСкопироватьСвойство", Тип("КнопкаФормы"),   Элементы.Найти("ГруппаДополнительныеРеквизитыКнопки"));
			НоваяКнопка.ИмяКоманды = "СкопироватьСвойство";
		КонецЕсли; 
		
	КонецЦикла; 
	
	спМножественныхСвойств = ПолучитьСписокМножественныхСвойств();
	Если спМножественныхСвойств.Количество() > 0 Тогда
		НоваяКнопка = Элементы.Добавить("КнопкаУдалитьСвойство", Тип("КнопкаФормы"), Элементы.Найти("ГруппаДополнительныеРеквизитыКнопки"));
		НоваяКнопка.ИмяКоманды = "УдалитьСвойство";
	КонецЕсли;
		
КонецПроцедуры

&НаСервере
Функция ПолучитьСписокМножественныхСвойств()
	
	спМножественныхСвойств = Новый СписокЗначений;
	
	вт_Свойства = ЭтаФорма.Свойства_ОписаниеДополнительныхРеквизитов.Выгрузить();
	вт_Свойства.Колонки.Добавить("Счетчик");
	вт_Свойства.ЗаполнитьЗначения(1, "Счетчик");
	вт_Свойства.Свернуть("Свойство", "Счетчик");
	
	Для Каждого стрСвойство из вт_Свойства Цикл 
		Если стрСвойство.Счетчик > 1 Тогда
			спМножественныхСвойств.Добавить(стрСвойство.Свойство);
		конецЕсли
	КонецЦикла;
	
	Возврат спМножественныхСвойств;
	
КонецФункции

&НаСервере
Функция ПолучитьСписокМножественныхСвойствВсе()
	
	спМножественныхСвойств = Новый СписокЗначений;
	
	Для каждого стрДополнительногоРеквизита Из ЭтаФорма.Свойства_ОписаниеДополнительныхРеквизитов Цикл
		
		Если НЕ спМножественныхСвойств.НайтиПоЗначению(стрДополнительногоРеквизита.Свойство) = Неопределено Тогда
			Продолжить;
		КонецЕсли; 
		
		Если стрДополнительногоРеквизита.Свойство.МножественныйРеквизит Тогда
			спМножественныхСвойств.Добавить(стрДополнительногоРеквизита.Свойство);
		КонецЕсли; 
		
	КонецЦикла;
	
	Возврат спМножественныхСвойств;
	
КонецФункции

&НаКлиенте
Процедура хот_СкопироватьСвойство()
	
	спМножественныхСвойств = ПолучитьСписокМножественныхСвойствВсе();
	
	Оповещение = Новый ОписаниеОповещения("хот_ПослеВыбораИзМеню", ЭтотОбъект);
	ПоказатьВыборИзМеню(Оповещение, спМножественныхСвойств, Элементы.КнопкаСкопироватьСвойство);
	
КонецПроцедуры

&НаКлиенте
Процедура хот_УдалитьСвойство()
	
	//Список свойств, для которых есть несколько значений
	спМножественныхСвойств = ПолучитьСписокМножественныхСвойств();
	
	спМножественныхСвойствВыбор = Новый СписокЗначений;
	Для каждого стрДополнительногоРеквизита Из ЭтаФорма.Свойства_ОписаниеДополнительныхРеквизитов Цикл
		
		Если спМножественныхСвойств.НайтиПоЗначению(стрДополнительногоРеквизита.Свойство) = Неопределено Тогда
			Продолжить;
		КонецЕсли; 
		
		спМножественныхСвойствВыбор.Добавить(стрДополнительногоРеквизита, СокрЛП(стрДополнительногоРеквизита.Свойство) + " " + СокрЛП(ЭтаФорма[стрДополнительногоРеквизита.ИмяРеквизитаЗначение]));
				
	КонецЦикла;
	
	Оповещение = Новый ОписаниеОповещения("хот_ПослеВыбораИзМенюУдалитьСвойство", ЭтотОбъект);
	ПоказатьВыборИзМеню(Оповещение, спМножественныхСвойствВыбор, Элементы.КнопкаУдалитьСвойство);
	
КонецПроцедуры

&НаКлиенте
Процедура хот_ПослеВыбораИзМеню(ВыбранныйЭлемент, Параметры) Экспорт
	Если НЕ ВыбранныйЭлемент = Неопределено Тогда
		хот_ДобавитьРеквизиты(ВыбранныйЭлемент.Значение)
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура хот_ПослеВыбораИзМенюУдалитьСвойство(ВыбранныйЭлемент, Параметры) Экспорт
	Если НЕ ВыбранныйЭлемент = Неопределено Тогда
		УдалитьСвойство(ВыбранныйЭлемент.Значение.ИмяРеквизитаЗначение);
	КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура УдалитьСвойство(ИмяРеквизитаЗначение)
	Элементы.Удалить(Элементы.Найти(ИмяРеквизитаЗначение));
	
	НайденныеСтроки = ЭтаФорма.Свойства_ОписаниеДополнительныхРеквизитов.НайтиСтроки(Новый Структура("ИмяРеквизитаЗначение", ИмяРеквизитаЗначение));
	Для Каждого стрСвойство Из НайденныеСтроки Цикл 
		ЭтаФорма.Свойства_ОписаниеДополнительныхРеквизитов.Удалить(стрСвойство);
	КонецЦикла;
	
Конецпроцедуры

&НаСервере
Процедура хот_ДобавитьРеквизиты(ДопРеквизит)
	
	ОписаниеТипа = Новый ОписаниеТипов("СправочникСсылка.ЗначенияСвойствОбъектов");
	Для каждого стрДополнительногоРеквизита Из ЭтаФорма.Свойства_ОписаниеДополнительныхРеквизитов Цикл
		Если стрДополнительногоРеквизита.Свойство = ДопРеквизит Тогда
			ОписаниеТипа = стрДополнительногоРеквизита.ТипЗначения;		
			Прервать;
		КонецЕсли; 
	КонецЦикла;
	
	ИмяРеквизита = СтандартныеПодсистемыСервер.ПреобразоватьСтрокуВДопустимоеНаименованиеКолонки("ДополнительныйРеквизит_" + Строка(Новый УникальныйИдентификатор));
	лСвойство = ДопРеквизит;
	
	лМассив = Новый Массив;
	лМассив.Добавить(Новый РеквизитФормы(ИмяРеквизита, ОписаниеТипа,,ДопРеквизит.Наименование, Истина));
	ИзменитьРеквизиты(лМассив);
	
	НовЭлемент = Элементы.Вставить(ИмяРеквизита, Тип("ПолеФормы"), Элементы.Найти("ГруппаДополнительныеРеквизиты"));
	НовЭлемент.ПутьКДанным = ИмяРеквизита;
	НовЭлемент.Вид = ВидПоляФормы.ПолеВвода;
	
	МассивПараметров = Новый Массив;
	МассивПараметров.Добавить(Новый ПараметрВыбора("Отбор.Владелец", лСвойство));
	
	Элементы[ИмяРеквизита].ПараметрыВыбора = Новый ФиксированныйМассив(МассивПараметров);
	
	ДобавитьСвойство(ЭтаФорма, ИмяРеквизита, лСвойство);
	
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ДобавитьСвойство(лФорма, ИмяРеквизита, Свойство)

	лШаблон = лФорма.Свойства_ОписаниеДополнительныхРеквизитов.НайтиСтроки(Новый Структура("Свойство", Свойство));
	НовоеСвойство = лФорма.Свойства_ОписаниеДополнительныхРеквизитов.Добавить();
	
	Если лШаблон.Количество() > 0 Тогда
		ЗаполнитьЗначенияСвойств(НовоеСвойство, лШаблон[0]);
		НовоеСвойство.ИмяРеквизитаЗначение = ИмяРеквизита;
	КонецЕсли;
	
КонецПроцедуры


Показать


5) Модуль Б_ОбменССайтомСерверВыгрузкаДанных

Процедура ВыгрузитьСвойстваXDTO

// < -- xs
XDTOСвойство.Множественное = ТекСвойство.СвойствоНоменклатуры.МножественныйРеквизит;
// xs -- > 


Процедура ВыгрузитьСвойстваНоменклатурыXDTO


Процедура ВыгрузитьСвойстваНоменклатурыXDTO(ПараметрыОбмена, Владелец, ВладелецТип, ВыборкаНоменклатуры, МенеджерВременныхТаблиц);
	
	XDTOЗначенияСвойствТип 	= Б_ОбменССайтомСервер.ПолучениеТипОбъектаXDTO(ПараметрыОбмена,  "ЗначенияСвойств", Истина, ВладелецТип);
	XDTOЗначенияСвойстваТип = Б_ОбменССайтомСервер.ПолучениеТипОбъектаXDTO(ПараметрыОбмена,  "ЗначенияСвойства");
	
	// < -- xs
	XDTOЗначениеСвойства_МножТип = Б_ОбменССайтомСервер.ПолучениеТипОбъектаXDTO(ПараметрыОбмена,  "ЗначениеСвойства", Истина, XDTOЗначенияСвойстваТип);
	// xs -- > 
	
	Запрос = Новый Запрос;
	запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
	запрос.Текст =  "ВЫБРАТЬ *
	|ИЗ
	|	ВремЗначенияСвойствТовара КАК ВремЗначенияСвойствТовара
	|ГДЕ
	|	(ВремЗначенияСвойствТовара.Номенклатура = &Номенклатура	
	|И НЕ ВремЗначенияСвойствТовара.НеВыгружатьВСвойстваТоваров)";
	
	Запрос.УстановитьПараметр("Номенклатура", ВыборкаНоменклатуры.Номенклатура);
	Выборка = Запрос.Выполнить();
	
	Если НЕ Выборка.Пустой() тогда	
		ВыборкаСвойств = Выборка.Выбрать();
		XDTOЗначенияСвойств = ПараметрыОбмена.МояФабрикаXDTO.Создать(XDTOЗначенияСвойствТип);
		
		// < -- xs
		XDTOЗначенияСвойства_Множ = ПараметрыОбмена.МояФабрикаXDTO.Создать(XDTOЗначенияСвойстваТип);
		// xs -- > 
		
		Пока ВыборкаСвойств.Следующий() Цикл
			
			XDTOЗначенияСвойства = ПараметрыОбмена.МояФабрикаXDTO.Создать(XDTOЗначенияСвойстваТип);
			
			XDTOЗначенияСвойства.Ид = XMLСтрока(ВыборкаСвойств.ИдентификаторСвойства);
			
			// < -- xs
			Если ВыборкаСвойств.Свойство.МножественныйРеквизит Тогда
				XDTOЗначениеСвойстваМнож = ПараметрыОбмена.МояФабрикаXDTO.Создать(XDTOЗначениеСвойства_МножТип);
				XDTOЗначениеСвойстваМнож.Значение = XMLСтрока(ВыборкаСвойств.ИдентификаторЗначения);
				
			    XDTOЗначенияСвойства_Множ.Ид = XMLСтрока(ВыборкаСвойств.ИдентификаторСвойства);
				XDTOЗначенияСвойства_Множ.ЗначениеСвойства.Добавить(XDTOЗначениеСвойстваМнож);
				XDTOЗначенияСвойства_Множ.Значение.Добавить(XMLСтрока(ВыборкаСвойств.ИдентификаторЗначения));
				Продолжить;
			КонецЕсли;
			// xs -- > 
			
			XDTOЗначенияСвойства.Значение.Добавить(XMLСтрока(ВыборкаСвойств.ИдентификаторЗначения));
			
			XDTOЗначенияСвойств.ЗначенияСвойства.Добавить(XDTOЗначенияСвойства);	
			
		КонецЦикла;
		
		// < -- xs	
		XDTOЗначенияСвойств.ЗначенияСвойства.Добавить(XDTOЗначенияСвойства_Множ);
		// xs -- >

		Владелец.ЗначенияСвойств = XDTOЗначенияСвойств;
	КонецЕсли;
	
КонецПроцедуры

Показать
Прикрепленные файлы:
2711640; nemec; Varozh; Buхter; bonya_by; chng; user1136006; +7 Ответить
13. bad_wag 51 02.07.19 18:09 Сейчас в теме
(12) Спасибо! Ну я решал свою задачу, по этому об универсальности не думал, но вы развернулись на широкую ногу! Хоть в типовую переноси :) Отличное дополнение
14. Djo82 12 04.07.19 15:17 Сейчас в теме
с кнопками не разобрался, если не сложно поясните подробнее
15. Djo82 12 04.07.19 16:51 Сейчас в теме
16. user1136006 07.08.19 11:54 Сейчас в теме
(12) Прекрасное решение, спасибо! Но обнаружил проблему: если было выбрано несколько значений, а потом меньшее количество - предыдущий выбор сохраняется. Наверное, надо каким-то образом очищать реквизиты во время загрузки, может быть проблема только у меня...
17. RSTR 07.09.19 13:16 Сейчас в теме
bad_wag, просьба-вопрос к вам. Можете ли вы сделать настройку данной доработки в нашей базе? Сделали всё по инструкции, в УТ множественный реквизит появился, но в файл обмена с Битриксом этот реквизит не попадает.. УТ (11.4.6.174), Битрикс 7.0.1.21
Сколько это будет стоить?
18. Djo82 12 31.01.20 19:33 Сейчас в теме
Статья помогла решить задачу. Спасибо!

Но не отработала процедура "ВыгрузитьСвойстваНоменклатурыXDTO" при условии, что присутствует несколько множественных свойств. Подсмотрел исходники от партнеров с Битрикс. Немного подправил процедуру и файл "СхемаXSDОбмена". Вдруг кому поможет.

Процедура ВыгрузитьСвойстваНоменклатурыXDTO(ПараметрыОбмена, Владелец, ВладелецТип, ВыборкаНоменклатуры, МенеджерВременныхТаблиц);
	
	XDTOЗначенияСвойствТип 	= Б_ОбменССайтомСервер.ПолучениеТипОбъектаXDTO(ПараметрыОбмена,  "ЗначенияСвойств", Истина, ВладелецТип);
	XDTOЗначенияСвойстваТип = Б_ОбменССайтомСервер.ПолучениеТипОбъектаXDTO(ПараметрыОбмена,  "ЗначенияСвойства");
	
	//++все отлично
	XDTOЗначенияСвойствМножТип   = Б_ОбменССайтомСервер.ПолучениеТипОбъектаXDTO(ПараметрыОбмена, "ЗначениеСвойства", Истина, XDTOЗначенияСвойстваТип);
	//все отлично++
	
	Запрос = Новый Запрос;
	запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
	запрос.Текст =  "ВЫБРАТЬ *
	|ИЗ
	|	ВремЗначенияСвойствТовара КАК ВремЗначенияСвойствТовара
	|ГДЕ
	|	(ВремЗначенияСвойствТовара.Номенклатура = &Номенклатура	
	|И НЕ ВремЗначенияСвойствТовара.НеВыгружатьВСвойстваТоваров)";
	
	Запрос.УстановитьПараметр("Номенклатура", ВыборкаНоменклатуры.Номенклатура);
	Выборка = Запрос.Выполнить();
	
	//Если НЕ Выборка.Пустой() тогда	
	//	ВыборкаСвойств = Выборка.Выбрать();
	//	XDTOЗначенияСвойств = ПараметрыОбмена.МояФабрикаXDTO.Создать(XDTOЗначенияСвойствТип);
	//	
	//	Пока ВыборкаСвойств.Следующий() Цикл
	//		
	//		XDTOЗначенияСвойства = ПараметрыОбмена.МояФабрикаXDTO.Создать(XDTOЗначенияСвойстваТип);
	//		
	//		XDTOЗначенияСвойства.Ид = XMLСтрока(ВыборкаСвойств.ИдентификаторСвойства);
	//		XDTOЗначенияСвойства.Значение.Добавить(XMLСтрока(ВыборкаСвойств.ИдентификаторЗначения));
	//		
	//		XDTOЗначенияСвойств.ЗначенияСвойства.Добавить(XDTOЗначенияСвойства);	
	//		
	//	КонецЦикла;
	//	Владелец.ЗначенияСвойств = XDTOЗначенияСвойств;
	//КонецЕсли;
	ТаблицаСвойств = Выборка.Выгрузить();
	
СвернутьТаблицуПодСписокЗначений(ТаблицаСвойств,"ИдентификаторСвойства","Значение");
	
	Если НЕ ТаблицаСвойств.Количество() = 0 Тогда
		XDTOЗначенияСвойств = ПараметрыОбмена.МояФабрикаXDTO.Создать(XDTOЗначенияСвойствТип);
		Для Каждого ВыборкаСвойств из ТаблицаСвойств Цикл

				XDTOЗначенияСвойства = ПараметрыОбмена.МояФабрикаXDTO.Создать(XDTOЗначенияСвойстваТип);
				
				XDTOЗначенияСвойства.Ид = XMLСтрока(ВыборкаСвойств.ИдентификаторСвойства);
				Если НЕ ВыборкаСвойств.БулевоЗначение тогда
					Если НЕ ТипЗнч(ВыборкаСвойств.Значение) = Тип("СписокЗначений") Тогда
						XDTOЗначенияСвойства.Значение.Добавить(XMLСтрока(ВыборкаСвойств.ИдентификаторЗначения));
					Иначе
						Для каждого Свойство из ВыборкаСвойств.Значение Цикл
							XDTOЗначенияМножСвойств = ПараметрыОбмена.МояФабрикаXDTO.Создать(XDTOЗначенияСвойствМножТип);
							XDTOЗначенияМножСвойств.Значение = XMLСтрока(Свойство.Значение);
							XDTOЗначенияСвойства.ЗначениеСвойства.Добавить(XDTOЗначенияМножСвойств);
						КонецЦикла;
					КонецЕсли;
				Иначе
					XDTOЗначенияСвойства.Значение.Добавить(Строка(ВыборкаСвойств.ИдентификаторЗначения));
				КонецЕсли;
				
				XDTOЗначенияСвойств.ЗначенияСвойства.Добавить(XDTOЗначенияСвойства);
				
		КонецЦикла;
		Владелец.ЗначенияСвойств = XDTOЗначенияСвойств;
	КонецЕсли;
КонецПроцедуры

Процедура СвернутьТаблицуПодСписокЗначений(Таблица,ПолеДляАнализа,ПолеДляСвертки) Экспорт
	Если Ложь Тогда Таблица = Новый ТаблицаЗначений; КонецЕсли;
	СписокСвойств = Новый Соответствие;
	Для каждого Строка из Таблица Цикл
		НайденноеСвойство = СписокСвойств.Получить(Строка[ПолеДляАнализа]);
		Если НЕ НайденноеСвойство = неопределено Тогда
			Если НЕ ТипЗнч(НайденноеСвойство) = Тип("СписокЗначений") Тогда
				Список = Новый СписокЗначений;
				Список.Добавить(НайденноеСвойство);
				Список.Добавить(Строка[ПолеДляСвертки]);
				СписокСвойств.Вставить(Строка[ПолеДляАнализа], Список);
			Иначе
				НайденноеСвойство.Добавить(Строка[ПолеДляСвертки]);
			КонецЕсли;
		Иначе			
			СписокСвойств.Вставить(Строка[ПолеДляАнализа], Строка[ПолеДляСвертки]);
		КонецЕсли;
	КонецЦикла;
	КолонкиКопия = Таблица.ВыгрузитьКолонку("Значение");
	ОписаниеТипов = Новый ОписаниеТипов(Таблица.Колонки.Значение.ТипЗначения,"СписокЗначений");
	ШиринаКопия = Таблица.Колонки.Значение.Ширина;
	
	Таблица.Колонки.Удалить("Значение");
	Таблица.Колонки.Добавить("Значение",ОписаниеТипов,"Значение",ШиринаКопия);
	Таблица.ЗагрузитьКолонку(КолонкиКопия, "Значение");
	
	Для каждого Свойство из СписокСвойств Цикл
		Если ТипЗнч(Свойство.Значение) = Тип("СписокЗначений") Тогда
			НайденныеСтроки = Таблица.НайтиСтроки(Новый Структура(ПолеДляАнализа,Свойство.Ключ));
			Н = 0;
			Для Каждого Строка из НайденныеСтроки Цикл
				Н = Н + 1;
				Если Н = 1 Тогда
					Строка.Значение = Свойство.Значение;
				Иначе
					Таблица.Удалить(Строка);
				КонецЕсли;
			КонецЦикла;
		КонецЕсли;
	КонецЦикла;

КонецПроцедуры


Показать


Немного другой текст в "СхемаXSDОбмена"

<xs:complexType name="ЗначенияСвойства">
        <xs:sequence>
            <xs:element name="Ид" type="tns:ИдентификаторГлобальныйТип" />
            <xs:element name="Наименование" type="tns:НаименованиеТип" minOccurs="0" />
            <xs:element name="Значение" type="tns:ЗначениеТип" minOccurs="0" maxOccurs="unbounded" />
            <xs:element name="ЗначениеСвойства" minOccurs="0" maxOccurs="unbounded" >
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="Значение" type="tns:ЗначениеТип" maxOccurs="1" />
                    </xs:sequence>
				</xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
Показать
19. user691380_bel4enkin 18.04.20 14:18 Сейчас в теме
А случайно никто не выкладывал подобное расширение под УТ11.4 чтобы не изучать все тонкости? Интересует множественный реквизит с выгрузкой на сайт Opencart
20. ArturShaibakov 09.02.21 20:47 Сейчас в теме
Для 1с Розница, редакция 2.3 (2.3.5.35), дальше первого пункта делать ничего не нужно, все работает.
21. user1375596 20.08.21 20:08 Сейчас в теме
вы уверены, что Битрикс умеет парсить такую конструкцию?

					<ЗначенияСвойства>
						<Ид>e94be4ad-fb60-11eb-80e2-c643fff9747c</Ид>
						<Значение>
							<Значение>f237f346-fb60-11eb-80e2-c643fff9747c</Значение>
							<Значение>f237f347-fb60-11eb-80e2-c643fff9747c</Значение>
							<ЗначенияСвойства>
								<Значение>f237f346-fb60-11eb-80e2-c643fff9747c</Значение>
							</ЗначенияСвойства>
							<ЗначенияСвойства>
								<Значение>f237f347-fb60-11eb-80e2-c643fff9747c</Значение>
							</ЗначенияСвойства>
						</Значение>
					</ЗначенияСвойства>
Показать



У меня БУС 21.400.300 не воспринимает такой массив.
22. user1375596 21.08.21 08:54 Сейчас в теме
23. sderzhu 10.11.22 16:30 Сейчас в теме
Если СтрНайти(XDTOЗначенияСвойства.Ид, УправлениеСвойствамиСлужебный.ПолучитьУИДМножественногоСвойства()) > 0 Тогда
				XDTOЗначениеСвойстваМнож = ПараметрыОбмена.МояФабрикаXDTO.Создать(XDTOЗначениеСвойства_МножТип);
				XDTOЗначениеСвойстваМнож.Значение = XMLСтрока(ВыборкаСвойств.ИдентификаторЗначения);
				
			    XDTOЗначенияСвойства_Множ.Ид = XMLСтрока(ВыборкаСвойств.ИдентификаторСвойства);
				XDTOЗначенияСвойства_Множ.ЗначениеСвойства.Добавить(XDTOЗначениеСвойстваМнож);
				//XDTOЗначенияСвойства_Множ.Значение.Добавить(XMLСтрока(ВыборкаСвойств.ИдентификаторЗначения));
				Продолжить;
			КонецЕсли;
Показать

Закоменченная строка не нужна - лишнее это...

И, кстати, если нужно полностью очистить множественное значение, нужно обязательно послать пустое значение:

XDTOЗначениеСвойстваМнож = ПараметрыОбмена.МояФабрикаXDTO.Создать(XDTOЗначениеСвойства_МножТип);
				XDTOЗначениеСвойстваМнож.Значение = XMLСтрока("");
24. Rustamilyok 08.10.24 13:36 Сейчас в теме
Что за модуль для выгрузки в битрикс дорабатывался?
Оставьте свое сообщение