Обмен 1С с Битрикс: пошаговая настройка обмена с сайтом

Дата: 06.10.2026 16:54:16
Обмен с сайтом
Битрикс
CommerceML
Интернет-магазин
Регламентные задания
УТ 11
Комментарий:
0
Платформа:
8.3
Конфигурация:
1С: УТ 11.5
Формы:
Управляемые

Обмен 1С с Битрикс — это выгрузка каталога, цен и остатков из 1С на сайт и загрузка заказов обратно. В УТ 11, КА 2 и ERP он встроен: план обмена «Обмен с сайтом» формирует XML в формате CommerceML и сам отправляет его по HTTP, а Битрикс принимает файлы модулем интернет-магазина. Ниже — настройка обмена 1С и Битрикс по шагам и пять листингов для диагностики.

Пути и подписи даны по УТ 11.4. В КА 2.5 механизм тот же, в УТ 11.5 названия могут отличаться.

Как устроен обмен 1С с Битрикс

Инициатор всегда 1С. Типовая обращается к скрипту /bitrix/admin/1c_exchange.php (если в адресе сайта нет пути, подставляет его сама) и проходит одни и те же шаги.

Запрос 1СЧто происходит
type=catalog&mode=checkauthВход по логину и паролю. Ответ: success, имя и значение cookie сессии, иногда sessid=….
mode=initПринимает ли сайт архив (zip=yes) и предельный размер части файла (file_limit=…).
mode=file&filename=…Отправка файлов POST-запросами, больших — частями.
mode=import&filename=…Разбор файла: на progress 1С повторяет запрос, success — готово, failure — ошибка с текстом.
type=sale&mode=query, mode=successЗаказы: сайт отдаёт новые, 1С подтверждает загрузку.

Каталог уходит файлами import*.xml (картинки — в папке import_files), цены и остатки — offers*.xml; версия схемы CommerceML в УТ 11.4 — 2.07. Формат подробно — в статье CommerceML в 1С.

«Модулем обмена Битрикс с 1С» называют и этот типовой механизм, и отдельный модуль от 1С-Битрикс, который ставят в базу 1С. Ниже — типовой.

Шаг 1. Настройка обмена на стороне Битрикс

  1. Заведите на сайте отдельного пользователя и группу для обмена — не администратора.
  2. Откройте «Магазин → Настройки → Интеграция с 1С». На вкладке «Каталог» добавьте группу в «Разрешить загрузку группам пользователей», на вкладке «Заказы» — в «Группы, пользователям которых разрешена выгрузка».
  3. Проверьте параметры из таблицы.
ПараметрЧто выбрать
«Загружать предложения (характеристики) в отдельный инфоблок»Включайте, если выгружаете характеристики: на сайте они станут торговыми предложениями.
«Интервал одного шага в секундах»0 — разбор за один шаг. На слабом хостинге задайте, например, 30, чтобы шаг не упирался в лимит времени PHP.
«Размер единовременно загружаемой части файла (в байтах)»Этот предел 1С получает в ответе на init; он должен укладываться в лимит PHP на размер POST-запроса.
«Что делать с товарами, отсутствующими в файле импорта» (и с группами)Безопаснее «деактивировать», чем «удалить»: удалённый товар теряет отзывы и SEO-поля.
«Выгружать заказы начиная со статуса», «Менять статусы заказов по информации из 1С» (вкладка «Заказы»)Какие заказы заберёт 1С и обновит ли сайт их статусы.

Шаг 2. Узел обмена с сайтом в 1С

В УТ 11.4: «НСИ и администрирование → Настройка интеграции → Обмен с сайтом», флажок «Использовать обмен с сайтом», затем «Настройки обмена с сайтом» — откроется список узлов. У каждого узла своя очередь изменений и своё расписание. К синхронизации данных между базами этот механизм отношения не имеет.

Вкладка «Основные настройки»:

  • «Режим обмена данными» — «Выгрузка товаров» и/или «Обмен заказами», иначе узел не запишется: «Режим обмена не выбран.»
  • «Способ обмена данными» — «Выгружать на сайт». Вариант «Выгружать в каталог на диске» пригодится для отладки: XML ляжет в подпапку webdata.
  • «Адрес сайта» — https://shop.example.ru: по https включается защищённое соединение и порт 443.
  • «Имя пользователя» и «Пароль» — из шага 1. Пароль хранится в безопасном хранилище, а не в реквизите узла.
  • «Выгружать файлы без ожидания подтверждения импорта сервером» оставьте снятым: с ним 1С не шлёт mode=import, а Битрикс разбирает файлы именно по этим запросам.

Кнопка «Проверить соединение...» выполняет только checkauth. Если вход проходит, а выгрузка падает дальше, нужен ответ init — функция ниже повторяет оба запроса типовой. Запускайте её на сервере, когда обмен не идёт.

// Проверяет скрипт обмена Битрикс теми же двумя запросами, с которых
// начинает выгрузку типовая: checkauth (вход) и init (параметры обмена).
// АдресСайта - "https://shop.example.ru" или адрес вместе с путем к скрипту;
// ТипОбмена  - "catalog" (товары) или "sale" (заказы).
Функция ПроверитьСкриптОбменаБитрикс(Знач АдресСайта, Логин, Пароль, ТипОбмена = "catalog") Экспорт

	Результат = Новый Структура;
	Результат.Вставить("Успешно", Ложь);
	Результат.Вставить("ТекстОшибки", "");
	Результат.Вставить("ОтветАвторизации", "");
	Результат.Вставить("ОтветИнициализации", "");
	Результат.Вставить("СтрокВОтветеИнициализации", 0);
	Результат.Вставить("СжатиеZIP", Ложь);
	Результат.Вставить("ЛимитЧастиФайла", 0);

	Попытка

		// Разбор адреса, как в типовой: без пути - стандартный скрипт Битрикс.
		Адрес = СокрЛП(АдресСайта);
		Защищенное = СтрНачинаетсяС(НРег(Адрес), "https://");
		ПозицияСхемы = СтрНайти(Адрес, "://");
		Если ПозицияСхемы > 0 Тогда
			Адрес = Сред(Адрес, ПозицияСхемы + 3);
		КонецЕсли;
		ПозицияПути = СтрНайти(Адрес, "/");
		Если ПозицияПути = 0 Тогда
			Сервер = Адрес;
			Скрипт = "";
		Иначе
			Сервер = Лев(Адрес, ПозицияПути - 1);
			Скрипт = Сред(Адрес, ПозицияПути + 1);
		КонецЕсли;
		Если ПустаяСтрока(Скрипт) Тогда
			Скрипт = "bitrix/admin/1c_exchange.php";
		КонецЕсли;
		Порт = ?(Защищенное, 443, 80);
		ПозицияПорта = СтрНайти(Сервер, ":");
		Если ПозицияПорта > 0 Тогда
			Порт = Число(Сред(Сервер, ПозицияПорта + 1));
			Сервер = Лев(Сервер, ПозицияПорта - 1);
		КонецЕсли;

		ЗащищенноеСоединение = ?(Защищенное, Новый ЗащищенноеСоединениеOpenSSL(), Неопределено);
		Соединение = Новый HTTPСоединение(Сервер, Порт, Логин, Пароль, , 60, ЗащищенноеСоединение);
		АдресСкрипта = "/" + Скрипт + "?type=" + ТипОбмена;

		// 1. checkauth: в ответе success, затем имя и значение cookie сессии.
		Ответ = Соединение.Получить(Новый HTTPЗапрос(АдресСкрипта + "&mode=checkauth"));
		Результат.ОтветАвторизации = Ответ.ПолучитьТелоКакСтроку();
		Если Ответ.КодСостояния <> 200 Тогда
			Результат.ТекстОшибки = СтрШаблон("checkauth: HTTP %1", Ответ.КодСостояния);
			Возврат Результат;
		КонецЕсли;

		Строки = СтрРазделить(СтрЗаменить(Результат.ОтветАвторизации, Символы.ВК, ""), Символы.ПС, Ложь);
		Если Строки.Количество() = 0 Или НРег(СокрЛП(Строки[0])) <> "success" Тогда
			Если СтрНайти(НРег(Результат.ОтветАвторизации), "success") > 0 Тогда
				Результат.ТекстОшибки = "Перед success сайт выводит лишние символы (BOM, пробел, предупреждение PHP)";
			Иначе
				Результат.ТекстОшибки = "Сайт не авторизовал пользователя";
			КонецЕсли;
			Возврат Результат;
		ИначеЕсли Строки.Количество() < 3 Тогда
			Результат.ТекстОшибки = "В ответе checkauth нет cookie сессии";
			Возврат Результат;
		КонецЕсли;

		// Cookie и sessid из ответа передаем в следующий запрос, как типовая.
		Заголовки = Новый Соответствие;
		Заголовки.Вставить("Cookie", СокрЛП(Строки[1]) + "=" + СокрЛП(Строки[2]));
		АдресИнициализации = АдресСкрипта + "&mode=init";
		Если Строки.Количество() > 3 И СтрНачинаетсяС(СокрЛП(Строки[3]), "sessid=") Тогда
			АдресИнициализации = АдресИнициализации + "&" + СокрЛП(Строки[3]);
		КонецЕсли;

		// 2. init: zip=yes или zip=no и file_limit=<байт>.
		Ответ = Соединение.Получить(Новый HTTPЗапрос(АдресИнициализации, Заголовки));
		ТекстОтвета = СтрЗаменить(Ответ.ПолучитьТелоКакСтроку(), Символы.ВК, "");
		Результат.ОтветИнициализации = ТекстОтвета;
		Результат.СтрокВОтветеИнициализации = СтрЧислоСтрок(ТекстОтвета);
		Для Каждого СтрокаОтвета Из СтрРазделить(ТекстОтвета, Символы.ПС, Ложь) Цикл
			Параметр = НРег(СокрЛП(СтрокаОтвета));
			Если Параметр = "zip=yes" Тогда
				Результат.СжатиеZIP = Истина;
			ИначеЕсли СтрНачинаетсяС(Параметр, "file_limit=") Тогда
				Результат.ЛимитЧастиФайла = Число(Сред(Параметр, 12));
			КонецЕсли;
		КонецЦикла;

		Результат.Успешно = СтрНайти(НРег(ТекстОтвета), "file_limit=") > 0;
		Если Не Результат.Успешно Тогда
			Результат.ТекстОшибки = "В ответе на init нет параметров обмена";
		КонецЕсли;

	Исключение
		Результат.ТекстОшибки = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
	КонецПопытки;

	Возврат Результат;

КонецФункции

// То же по настройкам узла «Обмен с сайтом» (УТ 11, КА 2, ERP).
// Пароль типовая хранит в безопасном хранилище БСП.
Функция ПроверитьУзелОбменаССайтом(Узел) Экспорт

	Реквизиты = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Узел, "АдресСайта, ИмяПользователя, ОбменТоварами");

	УстановитьПривилегированныйРежим(Истина);
	Пароль = ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища(Узел, "Пароль");
	УстановитьПривилегированныйРежим(Ложь);

	Возврат ПроверитьСкриптОбменаБитрикс(Реквизиты.АдресСайта, Реквизиты.ИмяПользователя,
		?(ЗначениеЗаполнено(Пароль), Пароль, ""), ?(Реквизиты.ОбменТоварами, "catalog", "sale"));

КонецФункции

Если «СтрокВОтветеИнициализации» не равно двум, это и есть причина ошибки «Параметры обмена не получены» (см. ниже).

Шаг 3. Каталог и свойства товаров

Вкладка «Выгрузка товаров» (УТ 11.4):

  • «Использовать узел обмена для»: «Выгрузки на сайт описания товаров, типов цен, остатков» (полный каталог) или «Обновления на сайте цен и остатков товаров» (лёгкий пакет для частых запусков).
  • «Выгружаемые данные»: «Каталог товаров», «Файлы изображений», «Характеристики»; разделы сайта — «иерархия по группам» номенклатуры или по «видам».
  • «Режим выгрузки данных»: «Все данные» или «Изменения» — только то, что попало в очередь узла.
  • «Настройки каталогов товаров»: строка — каталог на сайте. «Группы» — что выгружать, «Идентификатор каталога» — XML_ID инфоблока, «Отбор» — дополнительные условия.

Свойства берутся из дополнительных реквизитов и дополнительных сведений номенклатуры. Битрикс создаёт разделы, свойства и товары при импорте и дальше находит их по XML_ID — не меняйте его вручную, иначе товар задвоится.

Шаг 4. Цены и склады

Типы цен на сайте в УТ 11 — не виды цен, а типовые соглашения с клиентами: действующие, с флажком «Доступно внешним пользователям и для обмена с сайтом» и пустым сегментом клиентов. Цена берётся из вида цен соглашения или из цен, заданных в нём по товарам и ценовым группам. Нет такого соглашения — на сайте нет цен.

Остаток — свободный (в наличии минус резервы) по каждому складу: в УТ 11.4 из регистра «Свободные остатки», в КА 2.5 — из «Запасов и потребностей». Склады и соглашения для каталога ограничивают в колонке «Отбор».

Функция ниже показывает товары группы, которые уйдут без цены или без свободного остатка, с причиной. Регистр остатков она выбирает по метаданным; при ценообразовании 2.5 (КА 2.5, ERP 2.5) передайте третьим параметром "ЦеныНоменклатуры25".

// Товары группы, которые уйдут на сайт без цены или без свободного остатка.
// Типы цен сайта - типовые соглашения для сайта (отбор как в типовой выгрузке).
// Склады     - массив складов; Неопределено или пустой массив - все склады.
// РегистрЦен - "ЦеныНоменклатуры" или "ЦеныНоменклатуры25" (ценообразование 2.5).
Функция ТоварыБезЦеныИлиОстаткаДляСайта(Группа, Склады = Неопределено, РегистрЦен = "ЦеныНоменклатуры") Экспорт

	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ
	|	Соглашения.Ссылка КАК Соглашение,
	|	Соглашения.ВидЦен КАК ВидЦен
	|ПОМЕСТИТЬ ВтСоглашенияСайта
	|ИЗ
	|	Справочник.СоглашенияСКлиентами КАК Соглашения
	|ГДЕ
	|	Соглашения.Типовое
	|	И Соглашения.ДоступноВнешнимПользователям
	|	И Соглашения.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыСоглашенийСКлиентами.Действует)
	|	И Соглашения.СегментПартнеров = ЗНАЧЕНИЕ(Справочник.СегментыПартнеров.ПустаяСсылка)
	|	И НЕ Соглашения.ПометкаУдаления
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ
	|	Номенклатура.Ссылка КАК Номенклатура
	|ПОМЕСТИТЬ ВтТовары
	|ИЗ
	|	Справочник.Номенклатура КАК Номенклатура
	|ГДЕ
	|	Номенклатура.Ссылка В ИЕРАРХИИ (&Группа)
	|	И НЕ Номенклатура.ЭтоГруппа
	|	И НЕ Номенклатура.ПометкаУдаления
	|	И Номенклатура.ТипНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Товар)
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ
	|	Цены.Номенклатура КАК Номенклатура,
	|	Цены.ВидЦены КАК ВидЦены,
	|	МАКСИМУМ(Цены.Цена) КАК Цена
	|ПОМЕСТИТЬ ВтЦены
	|ИЗ
	|	РегистрСведений.#РегистрЦен.СрезПоследних(
	|			&Дата,
	|			Номенклатура В (ВЫБРАТЬ Т.Номенклатура ИЗ ВтТовары КАК Т)
	|				И ВидЦены В (ВЫБРАТЬ С.ВидЦен ИЗ ВтСоглашенияСайта КАК С)) КАК Цены
	|
	|СГРУППИРОВАТЬ ПО
	|	Цены.Номенклатура,
	|	Цены.ВидЦены
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|#ВтОстатки
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ
	|	Товары.Номенклатура КАК Номенклатура,
	|	Соглашения.Соглашение КАК Соглашение,
	|	ЕСТЬNULL(Цены.Цена, 0) КАК Цена,
	|	ЕСТЬNULL(Остатки.Свободно, 0) КАК Свободно,
	|	ВЫБОР
	|		КОГДА Соглашения.Соглашение ЕСТЬ NULL
	|			ТОГДА ""Нет типового соглашения для сайта""
	|		КОГДА ЕСТЬNULL(Цены.Цена, 0) = 0
	|			ТОГДА ""Нет цены по виду цен соглашения""
	|		ИНАЧЕ ""Нет свободного остатка""
	|	КОНЕЦ КАК Причина
	|ИЗ
	|	ВтТовары КАК Товары
	|		ЛЕВОЕ СОЕДИНЕНИЕ ВтСоглашенияСайта КАК Соглашения
	|		ПО (ИСТИНА)
	|		ЛЕВОЕ СОЕДИНЕНИЕ ВтЦены КАК Цены
	|		ПО Товары.Номенклатура = Цены.Номенклатура
	|			И (Соглашения.ВидЦен = Цены.ВидЦены)
	|		ЛЕВОЕ СОЕДИНЕНИЕ ВтОстатки КАК Остатки
	|		ПО Товары.Номенклатура = Остатки.Номенклатура
	|ГДЕ
	|	(Соглашения.Соглашение ЕСТЬ NULL
	|			ИЛИ ЕСТЬNULL(Цены.Цена, 0) = 0
	|			ИЛИ ЕСТЬNULL(Остатки.Свободно, 0) <= 0)
	|
	|УПОРЯДОЧИТЬ ПО
	|	Товары.Номенклатура.Наименование";

	Запрос.Текст = СтрЗаменить(Запрос.Текст, "#РегистрЦен", РегистрЦен);
	Запрос.Текст = СтрЗаменить(Запрос.Текст, "#ВтОстатки", ТекстВтОстатки());

	// Отбор по складам - в условие виртуальной таблицы остатков.
	ЕстьОтборСкладов = Склады <> Неопределено И Склады.Количество() > 0;
	Запрос.Текст = СтрЗаменить(Запрос.Текст, "&УсловиеСклада",
		?(ЕстьОтборСкладов, "Склад В (&Склады)", "ИСТИНА"));

	Запрос.УстановитьПараметр("Группа", Группа);
	Запрос.УстановитьПараметр("Склады", Склады);
	Запрос.УстановитьПараметр("Дата", ТекущаяДатаСеанса());

	Возврат Запрос.Выполнить().Выгрузить();

КонецФункции

// Свободный остаток: в УТ 11.4 - регистр «Свободные остатки»,
// в КА 2.5 типовой обмен считает его по «Запасам и потребностям».
Функция ТекстВтОстатки()

	Если Метаданные.РегистрыНакопления.Найти("СвободныеОстатки") <> Неопределено Тогда
		Текст =
		"ВЫБРАТЬ
		|	Остатки.Номенклатура КАК Номенклатура,
		|	СУММА(Остатки.ВНаличииОстаток - Остатки.ВРезервеСоСкладаОстаток
		|		- Остатки.ВРезервеПодЗаказОстаток) КАК Свободно
		|ПОМЕСТИТЬ ВтОстатки
		|ИЗ
		|	РегистрНакопления.СвободныеОстатки.Остатки(
		|			,
		|			Номенклатура В (ВЫБРАТЬ Т.Номенклатура ИЗ ВтТовары КАК Т)
		|				И &УсловиеСклада) КАК Остатки
		|
		|СГРУППИРОВАТЬ ПО
		|	Остатки.Номенклатура";
	Иначе
		Текст =
		"ВЫБРАТЬ
		|	Остатки.Номенклатура КАК Номенклатура,
		|	СУММА(Остатки.ВНаличииОстаток - Остатки.РезервироватьНаСкладеОстаток
		|		- Остатки.РезервироватьПоМереПоступленияОстаток) КАК Свободно
		|ПОМЕСТИТЬ ВтОстатки
		|ИЗ
		|	РегистрНакопления.ЗапасыИПотребности.Остатки(
		|			,
		|			Назначение = ЗНАЧЕНИЕ(Справочник.Назначения.ПустаяСсылка)
		|				И Склад ССЫЛКА Справочник.Склады
		|				И Номенклатура В (ВЫБРАТЬ Т.Номенклатура ИЗ ВтТовары КАК Т)
		|				И &УсловиеСклада) КАК Остатки
		|
		|СГРУППИРОВАТЬ ПО
		|	Остатки.Номенклатура";
	КонецЕсли;

	Возврат Текст;

КонецФункции

Цены, заданные в самом соглашении по товарам и ценовым группам, функция не учитывает: для таких товаров причина «Нет цены по виду цен соглашения» может быть ложной.

Шаг 5. Расписание обмена

Группа «Автоматический обмен»: флажок «Использовать регламентное задание», «Пользователь регламентного задания» и кнопка «Настроить расписание обмена» (список «Интервал обмена с сайтом» типовая показывает только в режиме сервиса). У каждого узла своё задание «Обмен с сайтом №…» — см. «НСИ и администрирование → Обслуживание → Регламентные операции → Регламентные и фоновые задания».

Удобная схема — два узла с одной таблицей каталогов: каталог раз в сутки ночью, цены и остатки каждые 15–30 минут. Пользователю задания нужны права на номенклатуру, цены и заказы. Сводка ниже показывает по узлам очередь, расписание и итог последнего запуска; её запрос можно выполнить и в консоли запросов.

// Сводка по узлам «Обмен с сайтом»: сколько товаров и заказов ждет выгрузки,
// включено ли регламентное задание и чем закончился его последний запуск.
Функция СостояниеОбменаССайтами() Экспорт

	УстановитьПривилегированныйРежим(Истина);

	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ
	|	Изменения.Узел КАК Узел,
	|	КОЛИЧЕСТВО(Изменения.Ссылка) КАК Количество
	|ПОМЕСТИТЬ ВтТовары
	|ИЗ
	|	Справочник.Номенклатура.Изменения КАК Изменения
	|ГДЕ
	|	Изменения.Узел ССЫЛКА ПланОбмена.ОбменССайтом
	|
	|СГРУППИРОВАТЬ ПО
	|	Изменения.Узел
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ
	|	Изменения.Узел КАК Узел,
	|	КОЛИЧЕСТВО(Изменения.Ссылка) КАК Количество
	|ПОМЕСТИТЬ ВтЗаказы
	|ИЗ
	|	Документ.ЗаказКлиента.Изменения КАК Изменения
	|ГДЕ
	|	Изменения.Узел ССЫЛКА ПланОбмена.ОбменССайтом
	|
	|СГРУППИРОВАТЬ ПО
	|	Изменения.Узел
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ
	|	Узлы.Ссылка КАК Узел,
	|	Узлы.Наименование КАК Наименование,
	|	Узлы.АдресСайта КАК АдресСайта,
	|	Узлы.ВыгружатьИзменения КАК ТолькоИзменения,
	|	Узлы.ИдентификаторРегламентногоЗадания КАК ИдентификаторЗадания,
	|	ЕСТЬNULL(Товары.Количество, 0) КАК ТоваровВОчереди,
	|	ЕСТЬNULL(Заказы.Количество, 0) КАК ЗаказовВОчереди
	|ИЗ
	|	ПланОбмена.ОбменССайтом КАК Узлы
	|		ЛЕВОЕ СОЕДИНЕНИЕ ВтТовары КАК Товары
	|		ПО Узлы.Ссылка = Товары.Узел
	|		ЛЕВОЕ СОЕДИНЕНИЕ ВтЗаказы КАК Заказы
	|		ПО Узлы.Ссылка = Заказы.Узел
	|ГДЕ
	|	НЕ Узлы.ЭтотУзел
	|	И НЕ Узлы.ПометкаУдаления";

	Таблица = Запрос.Выполнить().Выгрузить();
	Таблица.Колонки.Добавить("Расписание", Новый ОписаниеТипов("Строка"));
	Таблица.Колонки.Добавить("ЗаданиеВключено", Новый ОписаниеТипов("Булево"));
	Таблица.Колонки.Добавить("ПоследнийЗапуск", Новый ОписаниеТипов("Дата"));
	Таблица.Колонки.Добавить("СостояниеЗапуска", Новый ОписаниеТипов("Строка"));
	Таблица.Колонки.Добавить("Ошибка", Новый ОписаниеТипов("Строка"));

	Для Каждого СтрокаУзла Из Таблица Цикл

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

		Если Задание = Неопределено Тогда
			СтрокаУзла.Расписание = "задание не найдено";
			Продолжить;
		КонецЕсли;

		СтрокаУзла.ЗаданиеВключено = Задание.Использование;
		СтрокаУзла.Расписание = Строка(Задание.Расписание);

		Последнее = Задание.ПоследнееЗадание;
		Если Последнее <> Неопределено Тогда
			СтрокаУзла.ПоследнийЗапуск = Последнее.Начало;
			СтрокаУзла.СостояниеЗапуска = Строка(Последнее.Состояние);
			Если Последнее.ИнформацияОбОшибке <> Неопределено Тогда
				СтрокаУзла.Ошибка = КраткоеПредставлениеОшибки(Последнее.ИнформацияОбОшибке);
			КонецЕсли;
		КонецЕсли;

	КонецЦикла;

	Возврат Таблица;

КонецФункции

// Пример вывода сводки в окно сообщений.
Процедура СообщитьСостояниеОбменаССайтами() Экспорт

	Для Каждого СтрокаУзла Из СостояниеОбменаССайтами() Цикл
		Сообщить(СтрШаблон("%1 (%2): товаров в очереди %3, заказов %4. Расписание: %5, включено: %6. Последний запуск %7: %8 %9",
			СтрокаУзла.Наименование, СтрокаУзла.АдресСайта, СтрокаУзла.ТоваровВОчереди, СтрокаУзла.ЗаказовВОчереди,
			СтрокаУзла.Расписание, Формат(СтрокаУзла.ЗаданиеВключено, "БЛ=нет; БИ=да"),
			Формат(СтрокаУзла.ПоследнийЗапуск, "ДЛФ=DT"), СтрокаУзла.СостояниеЗапуска, СтрокаУзла.Ошибка));
	КонецЦикла;

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

Расписание можно задать и кодом: процедура вызывает тот же метод узла, что и форма при записи. Общие приёмы — в статье о расписании регламентного задания.

// Включает обмен по расписанию: каждые ИнтервалМинут с 8:00 до 22:00 ежедневно.
// Задание создает типовой метод узла - тот же, что вызывает форма при записи.
Процедура УстановитьРасписаниеОбменаССайтом(Узел, ИнтервалМинут = 15) Экспорт

	Расписание = Новый РасписаниеРегламентногоЗадания;
	Расписание.ПериодПовтораДней = 1;
	Расписание.ПериодПовтораВТечениеДня = ИнтервалМинут * 60;
	Расписание.ВремяНачала = Дата(1, 1, 1, 8, 0, 0);
	Расписание.ВремяКонца = Дата(1, 1, 1, 22, 0, 0);

	УстановитьПривилегированныйРежим(Истина);
	УзелОбъект = Узел.ПолучитьОбъект();
	УзелОбъект.ИспользоватьРегламентноеЗадание = Истина;
	УзелОбъект.ВключитьОтключитьРегламентноеЗадание(Расписание);
	УзелОбъект.Записать();

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

Повторная выгрузка группы и запуск обмена из кода

В режиме «Изменения» уходят только товары из очереди. В УТ 11.4 их ставят туда подписки «ОбменССайтомПриЗаписиОбъекта» (номенклатура, характеристики, заказы) и «ОбменССайтомПередЗаписьюРегистра» (цены, свободные остатки, состояния заказов). Правка дополнительных сведений или соглашения и запись с ОтключитьМеханизмРегистрацииОбъектов в дополнительных свойствах в очередь не попадают — поставьте группу в очередь сами и запустите обмен (код серверный, под администратором).

// Ставит товары группы (с подгруппами) в очередь выгрузки всех узлов
// «Обмен с сайтом», в которых включена выгрузка товаров.
Процедура ЗарегистрироватьГруппуДляСайта(Группа) Экспорт

	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ
	|	Узлы.Ссылка КАК Узел
	|ИЗ
	|	ПланОбмена.ОбменССайтом КАК Узлы
	|ГДЕ
	|	Узлы.ОбменТоварами
	|	И НЕ Узлы.ЭтотУзел
	|	И НЕ Узлы.ПометкаУдаления
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ
	|	Номенклатура.Ссылка КАК Ссылка
	|ИЗ
	|	Справочник.Номенклатура КАК Номенклатура
	|ГДЕ
	|	Номенклатура.Ссылка В ИЕРАРХИИ (&Группа)
	|	И НЕ Номенклатура.ЭтоГруппа";
	Запрос.УстановитьПараметр("Группа", Группа);
	Результаты = Запрос.ВыполнитьПакет();

	Узлы = Результаты[0].Выгрузить().ВыгрузитьКолонку("Узел");
	Если Узлы.Количество() = 0 Тогда
		ВызватьИсключение "Нет узлов обмена с сайтом с включенной выгрузкой товаров";
	КонецЕсли;

	Выборка = Результаты[1].Выбрать();
	Пока Выборка.Следующий() Цикл
		ПланыОбмена.ЗарегистрироватьИзменения(Узлы, Выборка.Ссылка);
	КонецЦикла;

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

// Запускает обмен по узлу в фоне тем же методом, что и регламентное задание.
// Если обмен с сайтом уже выполняется, второй экземпляр не запускаем.
Функция ЗапуститьОбменССайтомСейчас(Узел) Экспорт

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

	// Метод регламентного задания принимает код узла, а не ссылку.
	ПараметрыЗадания = Новый Массив;
	ПараметрыЗадания.Добавить(ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Узел, "Код"));

	Задание = ФоновыеЗадания.Выполнить(ИмяМетода, ПараметрыЗадания, , "Обмен с сайтом: ручной запуск");
	Возврат Задание.УникальныйИдентификатор;

КонецФункции

Разбор ключевых строк

  • Новый HTTPСоединение(…, 60, ЗащищенноеСоединение) — как в типовой: логин и пароль в конструкторе, cookie из checkauth — в следующем запросе.
  • СтрокВОтветеИнициализации — типовая УТ 11.4 и КА 2.5 ждёт ровно две строки ответа init.
  • НайтиПоУникальномуИдентификатору — узел хранит УИД задания строкой; в режиме сервиса там ключ очереди, и сводка покажет «задание не найдено».
  • ПО (ИСТИНА) — каждый товар сверяется с каждым соглашением; без соглашений строка всё равно попадёт в результат с причиной.

Типичные ошибки

  • «Авторизация не выполнена. Не удалось установить соединение с сервером. Проверьте имя пользователя и пароль.» Ответ checkauth не начинается с success: неверный пароль, пользователь не в разрешённой группе, лишний вывод перед success (BOM, предупреждение PHP) или PHP в режиме CGI/FastCGI не видит заголовок авторизации.
  • «Не удалось прочитать ответ сервера. Параметры обмена не получены.» В ответе на init не две строки — обычно к нему подмешан вывод PHP. Отключите показ ошибок на экран.
  • «Произошла ошибка на стороне сервера.» и текст после «Ответ сервера:» — сайт вернул failure при приёме или разборе файла; причину ищите в этом тексте и в журнале PHP. Сетевые ошибки (таймаут, SSL, 401) разобраны в статье об ошибках HTTP-запроса.
  • Флажок «Использовать регламентное задание» снимается сам — форма узла снимает его при записи, если расписание не задано.
  • Нулевая цена на сайте — причину по каждому товару покажет функция из шага 4.
  • Товар изменили, а на сайте старые данные — правка не встала в очередь узла. Поставьте группу в очередь или выполните «Выполнить полный обмен данными».

Частые вопросы

Нужно ли ставить модуль обмена 1С-Битрикс, если в 1С есть «Обмен с сайтом»?

Для УТ 11, КА 2 и ERP — нет: типовой механизм выгружает каталог, свойства, характеристики, картинки, цены, остатки и забирает заказы. Модуль нужен, когда этого не хватает.

Можно ли выгружать в несколько инфоблоков или на два сайта?

Да: инфоблоки — это строки «Настроек каталогов товаров» с разными идентификаторами, сайты — отдельные узлы.

Где посмотреть, что уходит на сайт и почему обмен упал?

Очередь — «Показать зарегистрированные изменения» в форме узла или сводка из шага 5. Ошибки — в журнале регистрации, событие «Обмен с сайтами». Сам XML увидите, переключив узел на «Выгружать в каталог на диске».

Когда проще заказать

Если обмен падает на стороне сайта, нужно связать с 1С уже наполненный каталог без дублей или выгружать то, чего нет в типовой, проще отдать задачу программисту, который делал такие связки. Опишите её на странице обмена 1С с сайтом или разместите задание бесплатно — оценка бесплатная, ответ в течение рабочего дня.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.


1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.