Обмен 1С с Битрикс — это выгрузка каталога, цен и остатков из 1С на сайт и загрузка заказов обратно. В УТ 11, КА 2 и ERP он встроен: план обмена «Обмен с сайтом» формирует XML в формате CommerceML и сам отправляет его по HTTP, а Битрикс принимает файлы модулем интернет-магазина. Ниже — настройка обмена 1С и Битрикс по шагам и пять листингов для диагностики.
Пути и подписи даны по УТ 11.4. В КА 2.5 механизм тот же, в УТ 11.5 названия могут отличаться.
Инициатор всегда 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С. Ниже — типовой.
| Параметр | Что выбрать |
|---|---|
| «Загружать предложения (характеристики) в отдельный инфоблок» | Включайте, если выгружаете характеристики: на сайте они станут торговыми предложениями. |
| «Интервал одного шага в секундах» | 0 — разбор за один шаг. На слабом хостинге задайте, например, 30, чтобы шаг не упирался в лимит времени PHP. |
| «Размер единовременно загружаемой части файла (в байтах)» | Этот предел 1С получает в ответе на init; он должен укладываться в лимит PHP на размер POST-запроса. |
| «Что делать с товарами, отсутствующими в файле импорта» (и с группами) | Безопаснее «деактивировать», чем «удалить»: удалённый товар теряет отзывы и SEO-поля. |
| «Выгружать заказы начиная со статуса», «Менять статусы заказов по информации из 1С» (вкладка «Заказы») | Какие заказы заберёт 1С и обновит ли сайт их статусы. |
В УТ 11.4: «НСИ и администрирование → Настройка интеграции → Обмен с сайтом», флажок «Использовать обмен с сайтом», затем «Настройки обмена с сайтом» — откроется список узлов. У каждого узла своя очередь изменений и своё расписание. К синхронизации данных между базами этот механизм отношения не имеет.
Вкладка «Основные настройки»:
webdata.https://shop.example.ru: по https включается защищённое соединение и порт 443.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"));
КонецФункции
Если «СтрокВОтветеИнициализации» не равно двум, это и есть причина ошибки «Параметры обмена не получены» (см. ниже).
Вкладка «Выгрузка товаров» (УТ 11.4):
Свойства берутся из дополнительных реквизитов и дополнительных сведений номенклатуры. Битрикс создаёт разделы, свойства и товары при импорте и дальше находит их по XML_ID — не меняйте его вручную, иначе товар задвоится.
Типы цен на сайте в УТ 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 типовой обмен считает его по «Запасам и потребностям».
Функция ТекстВтОстатки()
Если Метаданные.РегистрыНакопления.Найти("СвободныеОстатки") <> Неопределено Тогда
Текст =
"ВЫБРАТЬ
| Остатки.Номенклатура КАК Номенклатура,
| СУММА(Остатки.ВНаличииОстаток - Остатки.ВРезервеСоСкладаОстаток
| - Остатки.ВРезервеПодЗаказОстаток) КАК Свободно
|ПОМЕСТИТЬ ВтОстатки
|ИЗ
| РегистрНакопления.СвободныеОстатки.Остатки(
| ,
| Номенклатура В (ВЫБРАТЬ Т.Номенклатура ИЗ ВтТовары КАК Т)
| И &УсловиеСклада) КАК Остатки
|
|СГРУППИРОВАТЬ ПО
| Остатки.Номенклатура";
Иначе
Текст =
"ВЫБРАТЬ
| Остатки.Номенклатура КАК Номенклатура,
| СУММА(Остатки.ВНаличииОстаток - Остатки.РезервироватьНаСкладеОстаток
| - Остатки.РезервироватьПоМереПоступленияОстаток) КАК Свободно
|ПОМЕСТИТЬ ВтОстатки
|ИЗ
| РегистрНакопления.ЗапасыИПотребности.Остатки(
| ,
| Назначение = ЗНАЧЕНИЕ(Справочник.Назначения.ПустаяСсылка)
| И Склад ССЫЛКА Справочник.Склады
| И Номенклатура В (ВЫБРАТЬ Т.Номенклатура ИЗ ВтТовары КАК Т)
| И &УсловиеСклада) КАК Остатки
|
|СГРУППИРОВАТЬ ПО
| Остатки.Номенклатура";
КонецЕсли;
Возврат Текст;
КонецФункции
Цены, заданные в самом соглашении по товарам и ценовым группам, функция не учитывает: для таких товаров причина «Нет цены по виду цен соглашения» может быть ложной.
Группа «Автоматический обмен»: флажок «Использовать регламентное задание», «Пользователь регламентного задания» и кнопка «Настроить расписание обмена» (список «Интервал обмена с сайтом» типовая показывает только в режиме сервиса). У каждого узла своё задание «Обмен с сайтом №…» — см. «НСИ и администрирование → Обслуживание → Регламентные операции → Регламентные и фоновые задания».
Удобная схема — два узла с одной таблицей каталогов: каталог раз в сутки ночью, цены и остатки каждые 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.НайтиПоУникальномуИдентификатору — узел хранит УИД задания строкой; в режиме сервиса там ключ очереди, и сводка покажет «задание не найдено».ПО (ИСТИНА) — каждый товар сверяется с каждым соглашением; без соглашений строка всё равно попадёт в результат с причиной.Для УТ 11, КА 2 и ERP — нет: типовой механизм выгружает каталог, свойства, характеристики, картинки, цены, остатки и забирает заказы. Модуль нужен, когда этого не хватает.
Да: инфоблоки — это строки «Настроек каталогов товаров» с разными идентификаторами, сайты — отдельные узлы.
Очередь — «Показать зарегистрированные изменения» в форме узла или сводка из шага 5. Ошибки — в журнале регистрации, событие «Обмен с сайтами». Сам XML увидите, переключив узел на «Выгружать в каталог на диске».
Если обмен падает на стороне сайта, нужно связать с 1С уже наполненный каталог без дублей или выгружать то, чего нет в типовой, проще отдать задачу программисту, который делал такие связки. Опишите её на странице обмена 1С с сайтом или разместите задание бесплатно — оценка бесплатная, ответ в течение рабочего дня.
Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.