Доработка стандартного модуля обмена от Битрикс для выгрузки произвольных таблиц значений или запросов в Highload-блоки

04.09.24

Интеграция - Сайты и интернет-магазины

Простой и универсальный механизм, позволяющий выгружать любые таблицы значений, включая результаты запросов из 1С, на сайт Bitrix через стандартный механизм - без каких либо доработок модулей на стороне сайта Bitrix.

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Выгрузка любых произвольных запросов и таблиц значений в Hiload блоки Bitrix стандартным обменом.:
.zip 7,84Kb
3
3 Скачать (1 SM) Купить за 1 850 руб.

Привет, коллеги! В своей работе я часто встречаюсь с различными реализациями выгрузок дополнительной информации в Битрикс через всякие кастомные модули для Битрикс, сложные обмены через файлы или фтп папки.  

Хочу поделиться с вами простым и универсальным решением - очень простой доработкой стандартного модуля обмена Битрикс, которая позволит выгружать и главное обновлять ЛЮБЫЕ данные в Highload-блоки Битрикс. 

Возможные кейсы

  • выгрузка дополнительных сведений для карт лояльности
  • выгрузка видов цен контрагентов из договоров 
  • выгрузка исключений цен и расширение механизмов ценообразования
  • выгрузка любых регистров сведений или справочников или других результатов запросов
  • выгрузка резервов, остатков, взаиморасчетов и любых других регистров накоплений
  • выгрузка детализаций документооборота для б2б системы
  • выгрузка дополнительный сведений или контента для товаров
  • выгрузка дополнительных механизмов контроля доступа
  • выгрузка вообще любых сведений, сложных запросов из 1с с ключами и без,
  • выгрузка множества таблиц значений в одном обмене с легким добавлений источников.

Реализация

За основу возьмем и переделаем стандартную процедуру модуля Битрикс "Б_ПроцедурыИФункцииВыгрузкиДанныхНаСайт.ВыгрузитьПользовательскиеСправочникиXDTO"

Эта процедура выгружает любые пользовательские справочники и их автоматически загружает их Highload-блоки в Битрикс, она наиболее близка к нашим целям.

Главная проблема ее использования для отправки произвольных таблиц - это необходимость xmlid-ключа для каждой строки передаваемых в Битрикс данных, этот ключ нужен для обновления уже существующих данных. А у результатов запросов ключа может не быть или быть сразу несколько.

 
 Идея алгоритма генерация общего ключа для нескольких ключевых полей

 

Врезки

можете сделать ее через расширение или через вставку куска кода

 
 Б_ПроцедурыИФункцииВыгрузкиДанныхНаСайт.ФормированиеФайловXMLОбменаДанных

 

Процедура для старых УТ10, КА\ЕРП1.3, БП2 и модулей обмена конфигураций на обычных формах:

 
Б_ПроцедурыИФункцииВыгрузкиДанныхНаСайт.ВыгрузитьПользовательскиеЗапросыXDTOКастом

 

Процедура для УНФ 1.6-3.0, УТ11, КА\ЕРП2.5, БП3, модулей обмена конфигураций на управляемых формах:

 
 Б_ПроцедурыИФункцииВыгрузкиДанныхНаСайт.ВыгрузитьПользовательскиеЗапросыXDTOКастом

 

////infostart.ru/profile/540760/, hands.center  просим при любом копировании сохранять авторство идеи и решения
Процедура ВыгрузитьПользовательскиеЗапросыXDTOКастом(ПараметрыОбмена,МассивДанных, Операция)
	
	лКоличествоСтрок = МассивДанных.Количество();
	КоличествоПакетов = ?(лКоличествоСтрок > 0, МассивДанных[лКоличествоСтрок - 1].Пакет, 0); 
	
	Пакет = КоличествоПакетов + 1;
	
	Б_ОбменССайтомСервер.СообщитьПодробно("Начало выгрузки пакета " + Строка(Пакет) + " пользовательскиих запросов", ПараметрыОбмена);
	
	ПараметрыОбмена.МояФабрикаXDTO 		= СоздатьФабрикуXDTO(ПараметрыОбмена.ФайлСхемы); 
	
	XDTOКоммерческаяИнформацияТип 		= Б_ОбменССайтомСервер.ПолучениеТипОбъектаXDTO(ПараметрыОбмена,  "КоммерческаяИнформация");  
	XDTOКоммерческаяИнформация 			= Б_ОбменССайтомСервер.ПолучитьXDTOКоммерческаяИнформация(ПараметрыОбмена, XDTOКоммерческаяИнформацияТип);
	
	XDTOПользовательскиеСправочникиТип	= Б_ОбменССайтомСервер.ПолучениеТипОбъектаXDTO(ПараметрыОбмена,  "ПользовательскиеСправочники", Истина, XDTOКоммерческаяИнформацияТип);
	XDTOСправочникТип					= Б_ОбменССайтомСервер.ПолучениеТипОбъектаXDTO(ПараметрыОбмена,  "Справочник"); 
	
	XDTOЭлементыСправочникаТип	= Б_ОбменССайтомСервер.ПолучениеТипОбъектаXDTO(ПараметрыОбмена,  "ЭлементыСправочника", Истина, XDTOСправочникТип);
	XDTOЭлементСправочникаТип	= Б_ОбменССайтомСервер.ПолучениеТипОбъектаXDTO(ПараметрыОбмена,  "ЭлементСправочника");
	
	ТипpЗначенийРеквизитов	= Б_ОбменССайтомСервер.ПолучениеТипОбъектаXDTO(ПараметрыОбмена,  "ЗначенияРеквизитов", Истина, XDTOЭлементСправочникаТип);
	ТипpЗначенияРеквизита	= Б_ОбменССайтомСервер.ПолучениеТипОбъектаXDTO(ПараметрыОбмена,  "ЗначениеРеквизита");
	
	XDTOРеквизитыТип		= Б_ОбменССайтомСервер.ПолучениеТипОбъектаXDTO(ПараметрыОбмена,  "Реквизиты", Истина, XDTOСправочникТип);
	XDTOРеквизитТип			= Б_ОбменССайтомСервер.ПолучениеТипОбъектаXDTO(ПараметрыОбмена,  "Реквизит", Истина, XDTOРеквизитыТип);
	
	//результирующая таблица выгружаемых данных
	ВыгружаемыеСправочники = Новый ТаблицаЗначений;
	ВыгружаемыеСправочники.Колонки.Добавить("Справочник");
	ВыгружаемыеСправочники.Колонки.Добавить("Таблица");
	
	//поля с синонимами _XMLID будут определены как ключи для записи
	//Абсолютно любой запрос, любой сложности  
	ПользовательскиеЗапросы = Новый Запрос;                                

	ПользовательскиеЗапросы.Текст = "ВЫБРАТЬ ПЕРВЫЕ 100
	                                |	Контрагенты.Ссылка КАК Контрагент_XMLID,
	                                |	Контрагенты.Наименование КАК Наименование,
	                                |	Контрагенты.Наименование КАК НаименованиеЛат,
	                                |	Контрагенты.ИНН КАК КонтрагентИНН,
	                                |	Контрагенты.КПП КАК КонтрагентКПП,
	                                |	РасчетыСПокупателями.Договор КАК Договор_XMLID,
	                                |	РасчетыСПокупателями.СуммаОстаток КАК СуммаОстаток,
	                                |	РасчетыСПокупателями.СуммаРегОстаток КАК СуммаОстатокРег
	                                |ИЗ
	                                |	РегистрНакопления.РасчетыСПокупателями.Остатки КАК РасчетыСПокупателями
	                                |		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты
	                                |		ПО РасчетыСПокупателями.Контрагент = Контрагенты.Ссылка";
	
	

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

	НСтр = ВыгружаемыеСправочники.Добавить();
    //определяем имя HiLoad блока в битрикс
    //Имя сущности не может заканчиваться на "Table", в то же время в вызовах API этот постфикс добавляется автоматически
	НСтр.Справочник = "DemoCustomerBalances"; 
	НСтр.Таблица = ТаблицаРезультат.Скопировать();
	
	//поля с синонимами _XMLID будут определены как ключи для записи
	//Абсолютно любой запрос, любой сложности  
	ПользовательскиеЗапросы = Новый Запрос;
	ПользовательскиеЗапросы.Текст = "ВЫБРАТЬ  ПЕРВЫЕ 100
	                                |	ЗапасыОстатки.Номенклатура КАК Номенклатура_XMLID,
	                                |	ЗапасыОстатки.Характеристика КАК Характеристика_XMLID,
	                                |	ЗапасыОстатки.СтруктурнаяЕдиница КАК Склад_XMLID,
	                                |	ЗапасыОстатки.СуммаОстаток КАК СуммаОстаток
	                                |ИЗ
	                                |	РегистрНакопления.Запасы.Остатки(, ) КАК ЗапасыОстатки";
	
	
	ТаблицаРезультат = ПользовательскиеЗапросы.Выполнить().Выгрузить();
	
	НСтр = ВыгружаемыеСправочники.Добавить();
    //определяем имя HiLoad блока в битрикс
    //Имя сущности не может заканчиваться на "Table", в то же время в вызовах API этот постфикс добавляется автоматически
	НСтр.Справочник = "DemoGoodsBalances";
	НСтр.Таблица = ТаблицаРезультат.Скопировать();

	//поля с синонимами _XMLID будут определены как ключи для записи
	//Абсолютно любой запрос, любой сложности  
	ПользовательскиеЗапросы = Новый Запрос;
	ПользовательскиеЗапросы.Текст = "ВЫБРАТЬ ПЕРВЫЕ 100
	                                |	РасчетыСКонтрагентамиОбороты.Организация КАК Организация_XMLID,
	                                |	РасчетыСКонтрагентамиОбороты.Контрагент КАК Контрагент_XMLID,
	                                |	РасчетыСКонтрагентамиОбороты.Договор КАК Договор_XMLID,
	                                |	ПРЕДСТАВЛЕНИЕ(РасчетыСКонтрагентамиОбороты.Регистратор) КАК Документ,
	                                |	РасчетыСКонтрагентамиОбороты.СуммаПриход КАК СуммаПриход,
	                                |	РасчетыСКонтрагентамиОбороты.СуммаРасход КАК СуммаРасход
	                                |ИЗ
	                                |	РегистрНакопления.РасчетыСПокупателями.Обороты(, , Регистратор, ) КАК РасчетыСКонтрагентамиОбороты";
	
	
	ТаблицаРезультат = ПользовательскиеЗапросы.Выполнить().Выгрузить();
	
	НСтр = ВыгружаемыеСправочники.Добавить(); 
    //определяем имя HiLoad блока в битрикс
    //Имя сущности не может заканчиваться на "Table", в то же время в вызовах API этот постфикс добавляется автоматически
	НСтр.Справочник = "DemoCustomerDocuments";
	НСтр.Таблица = ТаблицаРезультат.Скопировать();
	

	//поля с синонимами _XMLID будут определены как ключи для записи
	//просто произвольная таблица  
	ТаблицаРезультат = новый ТаблицаЗначений;
	ТаблицаРезультат.Колонки.Добавить("Ключ1__XMLID");
	ТаблицаРезультат.Колонки.Добавить("Ключ2__XMLID");
	ТаблицаРезультат.Колонки.Добавить("Данные");
	Для ключ1 = 1 по 100 цикл 
		Для ключ2 = 1 по 100 цикл 
			стрТаблицаРезультат = ТаблицаРезультат.Добавить();
			стрТаблицаРезультат.Ключ1__XMLID = Строка(ключ1);
			стрТаблицаРезультат.Ключ2__XMLID = Строка(ключ2);
			стрТаблицаРезультат.Данные = ключ1 * ключ2;
		КонецЦикла;
	КонецЦикла;

	НСтр = ВыгружаемыеСправочники.Добавить();
    //определяем имя HiLoad блока в битрикс
    //Имя сущности не может заканчиваться на "Table", в то же время в вызовах API этот постфикс добавляется автоматически
	НСтр.Справочник = "DemoMultiplication";//определяем имя HiLoad блока в битрикс
	НСтр.Таблица = ТаблицаРезультат.Скопировать();
	
	//Обработка и отправка запросов в битрикс
	Итератор = 0;
	XDTOПользовательскиеСправочники		= ПараметрыОбмена.МояФабрикаXDTO.Создать(XDTOПользовательскиеСправочникиТип); 
	
	Если (ПараметрыОбмена.ВыгружатьТолькоИзменения И НЕ ПараметрыОбмена.ВыполнятьПолнуюВыгрузкуПринудительно) ИЛИ (ПараметрыОбмена.КоличествоЭлементовСправочникаВПакете <> 0) тогда
		XDTOПользовательскиеСправочники.СодержитТолькоИзменения = XMLСтрока(Истина);
	Иначе
		XDTOПользовательскиеСправочники.СодержитТолькоИзменения = XMLСтрока(Ложь);
	КонецЕсли;
	
	Для каждого ТекСпр из ВыгружаемыеСправочники Цикл
		ТаблицаЗапросов = ТекСпр.Таблица;
		
		лЕстьЭлементыСправочника = Ложь;
		
		XDTOСправочник				= ПараметрыОбмена.МояФабрикаXDTO.Создать(XDTOСправочникТип); 
		XDTOСправочник.Ид 			= ТекСпр.Справочник;	
		XDTOСправочник.Наименование = ТекСпр.Справочник;	
		
		лРеквезитыСпр 	= ТаблицаЗапросов.Колонки;
		
		XDTOРеквизитыСправочника	= ПараметрыОбмена.МояФабрикаXDTO.Создать(XDTOРеквизитыТип); 
		МассивКолонокСсылок = Новый Массив;
		Для каждого ТекРек из лРеквезитыСпр Цикл 
			
			//собираем названия полей для создания ключей
			Если Найти(ТекРек.Имя,"_XMLID") тогда     
				МассивКолонокСсылок.Добавить(ТекРек.Имя);
			КонецЕсли;
			
			XDTOРеквизитСправочника	= ПараметрыОбмена.МояФабрикаXDTO.Создать(XDTOРеквизитТип); 
			
			XDTOРеквизитСправочника.Ид = ТекРек.Имя;
			
			лТипыРеквизита 	= ТекРек.ТипЗначения.Типы();
			XDTOРеквизитСправочника.Наименование = ТекРек.Имя;

			//определяем типы выгружаемых данных
			Если лТипыРеквизита.Количество() > 0 тогда
				
				лТипРеквизита = лТипыРеквизита[0];
				
				Если лТипРеквизита = Тип("Число") тогда
					XDTOРеквизитСправочника.ТипЗначений = "Число";	
				ИначеЕсли лТипРеквизита = Тип("Дата") тогда
					XDTOРеквизитСправочника.ТипЗначений = "Дата";	
				ИначеЕсли лТипРеквизита = Тип("Булево") тогда
					XDTOРеквизитСправочника.ТипЗначений = "Булево";	
				Иначе
					XDTOРеквизитСправочника.ТипЗначений = "Строка";	
				КонецЕсли;  									
			Иначе
				XDTOРеквизитСправочника.ТипЗначений = "Строка";	
			КонецЕсли;
			
			XDTOРеквизитыСправочника.Реквизит.Добавить(XDTOРеквизитСправочника);
		КонецЦикла;
		
		XDTOСправочник.Реквизиты	= XDTOРеквизитыСправочника;
		
		XDTOЭлементыСправочника		= ПараметрыОбмена.МояФабрикаXDTO.Создать(XDTOЭлементыСправочникаТип); 
		
		// заполняем данные из отправляемых таблиц значений
		Для каждого ТекЭлСпр из ТаблицаЗапросов Цикл 
			
			лЕстьЭлементыСправочника = Истина;
			Итератор = Итератор + 1;
			
			XDTOЭлементСправочника	= ПараметрыОбмена.МояФабрикаXDTO.Создать(XDTOЭлементСправочникаТип); 
			
			//генерируем ключ записи для битрикс
			Наименование = "";
			если МассивКолонокСсылок.Количество() = 0 тогда
				Б_ОбменССайтомСервер.СообщитьПодробно("Выгрузка запроса " + Строка(ТекСпр.Справочник) + " пропущена. Нет ключевой колонки.", ПараметрыОбмена);
				продолжить;
			Иначеесли МассивКолонокСсылок.Количество() = 1 тогда   
				//Если в отправляемой таблице только одна ключевая колонка то мы ее идентификатор отправляем как есть
				КлючЗаписи = XMLСтрока(ТекЭлСпр[МассивКолонокСсылок[0]]);
				Наименование = Строка(ТекЭлСпр[МассивКолонокСсылок[0]]);
			Иначеесли МассивКолонокСсылок.Количество() > 1 тогда
				//Если в отправляемой таблице несколько ключевых колонок то мы генерируем их совокупный идентификатор через md5
				//такой подход позволяем получить один постоянный ключ из нескольких идентификаторов
				Хеш = Новый ХешированиеДанных(ХешФункция.MD5);
				Для каждого КолонкаСсылки из МассивКолонокСсылок цикл
					Хеш.Добавить(XMLСтрока(ТекЭлСпр[КолонкаСсылки]));
					Наименование = Наименование + "#" + СокрЛП(Строка(ТекЭлСпр[КолонкаСсылки]));
				КонецЦикла;
				КлючЗаписи = СтрЗаменить(строка(Хеш.ХешСумма)," ", "");
			КонецЕсли;
			
			XDTOЭлементСправочника.Ид 			= КлючЗаписи;
			//принудительное обновление записей в битрикс пустем передачи в версию дату в формате Unix Timestamp
			XDTOЭлементСправочника.НомерВерсии 	= Формат(Число(ТекущаяДата()-Дата("19700101")),"ЧН=0; ЧГ=0"); 

			
			ЗначенияРеквизитов 		= ПараметрыОбмена.МояФабрикаXDTO.Создать(ТипpЗначенийРеквизитов);
			//Предопределяем наименование
			Б_ОбменССайтомСервер.ДобавитьЗначениеРеквизитаXDTO(ПараметрыОбмена, ЗначенияРеквизитов, ТипpЗначенияРеквизита, "Наименование", Наименование);
			
			Для каждого ТекРек из лРеквезитыСпр Цикл
				лЗначРек 	= ТекЭлСпр[ТекРек.Имя];
				Если ЗначениеЗаполнено(лЗначРек) тогда
					Если МассивКолонокСсылок.Найти(ТекРек.Имя) <> Неопределено тогда     
						лЗначВХМЛ = XMLСтрока(лЗначРек);
					Иначе
						лЗначВХМЛ = Строка(лЗначРек);
					КонецЕсли;
					Б_ОбменССайтомСервер.ДобавитьЗначениеРеквизитаXDTO(ПараметрыОбмена, ЗначенияРеквизитов, ТипpЗначенияРеквизита, ТекРек.Имя, лЗначВХМЛ);
				Иначе
					Б_ОбменССайтомСервер.ДобавитьЗначениеРеквизитаXDTO(ПараметрыОбмена, ЗначенияРеквизитов, ТипpЗначенияРеквизита, ТекРек.Имя, "");
				КонецЕсли;
				
			КонецЦикла;
			
			XDTOЭлементСправочника.ЗначенияРеквизитов = ЗначенияРеквизитов; 
			XDTOЭлементыСправочника.ЭлементСправочника.Добавить(XDTOЭлементСправочника);	
		КонецЦикла;
		
		Если лЕстьЭлементыСправочника тогда
			XDTOСправочник.ЭлементыСправочника = XDTOЭлементыСправочника;
			
			XDTOПользовательскиеСправочники.Справочник.Добавить(XDTOСправочник);
		КонецЕсли;
		
	КонецЦикла;
	
	XDTOКоммерческаяИнформация.ПользовательскиеСправочники = XDTOПользовательскиеСправочники; 
	
	ИмяКаталога = Б_ОбщиеПроцедурыИФункцииСервер.ПолучитьПутьДляПлатформы(ПараметрыОбмена.ПлатформаWindows, ПараметрыОбмена.КаталогНаДиске + "\references\" +  Строка(Пакет)); 
	
	Успешно = ЗаписьИОтправкаXMLДанныхНаСайт(ПараметрыОбмена, XDTOКоммерческаяИнформация, ИмяКаталога, "references", "reference", Пакет);		
	
	Если Успешно  Или НЕ ПараметрыОбмена.ВыгружатьНаСайт тогда
		Б_ОбменССайтомСервер.СообщитьПодробно("Выгрузка пакета " + Строка(Пакет) + " пользовательскиих запросов завершена. Выгружено " + Строка(Итератор) + " элементов.", ПараметрыОбмена);
	Иначе
		Б_ОбменССайтомСервер.СообщитьПодробно("Выгрузка пакета " + Строка(Пакет) + " пользовательскиих запросов НЕ завершена или завершена с ошибками. НЕ Выгружено " + Строка(Итератор) + " элементов.", ПараметрыОбмена);
	КонецЕсли;

КонецПроцедуры 
////infostart.ru/profile/540760/, hands.center  просим при любом копировании сохранять авторство идеи и решения

 

 

Результаты

При обмене вы увидите сообщения о создание новых справочников Highload с их идентификатором  в Битрикс

 
 часть лога обмена

После обмена вы увидите в вашем Битрикс новые Highload-блоки с указанными вами именами.

 
 скрины из админки Битрикс

 

с интересом почитаю ваши комментарии )

 

См. также

Сайты и интернет-магазины Платформа 1С v8.3 1С:Розница 2 Розничная и сетевая торговля (FMCG) Россия Платные (руб)

Готовое интеграционное решение для оплаты покупок Долями в 1C:Розница 2.3. Реализовано в виде расширения. Интеграция сервиса dolyame.ru для приема платежей в рассрочку. Поддерживает работу от разных юридических лиц. Работа: в составе РИБ, отдельно от РИБ, тонкий, толстый клиент, web-клиент (через интернет-браузер).

20400 руб.

19.12.2023    3915    27    8    

26

Сайты и интернет-магазины Программист Пользователь Платформа 1С v8.3 Бухгалтерский учет 1С:Бухгалтерия 3.0 Россия Платные (руб)

Данный модуль предоставляет возможность выгружать заказы из 1С: Управление торговлей 11 версии в "MEASOFT" (ранее "Курьерская служба 2008").

9600 руб.

27.04.2022    11195    19    3    

9

Оптовая торговля Розничная торговля Сайты и интернет-магазины Системный администратор Программист Платформа 1С v8.3 Оперативный учет 1С:Управление торговлей 10 1С:Управление нашей фирмой 1.6 1С:Управление торговлей 11 Управленческий учет Платные (руб)

Внешняя обработка для обмена данными с интернет-магазином OpenCart. Позволяет быстро наполнить магазин товарами, затем обновлять цены и добавлять новые товары. Далее можно средствами OpenCart настраивать и дополнять карточки товаров как надо для магазина, при этом связь товаров с 1С не теряется.

3840 руб.

30.03.2018    45000    86    139    

89

Оптовая торговля Розничная торговля Сайты и интернет-магазины Программист Платформа 1С v8.3 Оперативный учет 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Управленческий учет Платные (руб)

ВАЖНО: расширения не предназначены для модуля обмена Битрикс 8.х. Полный список ограничений см. ниже в разделе ОГРАНИЧЕНИЯ. Расширение предназначено для выгрузки на сайт Битрикс сопутствующих товаров, аналогов, рекомендованных и прочих связанных товаров.

3600 руб.

25.07.2018    45583    86    72    

94
Оставьте свое сообщение