Выгрузка товаров из 1С на сайт - настройка, запуск и проверка
Настраиваем выгрузку каталога из 1С в Битрикс и делаем так, чтобы правки сайта переживали обмен.
Решение
Заводим отдельного пользователя обмена и даём ему право на каталог:
$user = new CUser();$id = $user->Add([ 'LOGIN' => 'exchange1c', // отдельная запись только для обмена 'GROUP_ID' => [12], // группа с правами на обмен 'PASSWORD' => $password, 'CONFIRM_PASSWORD' => $password, 'NAME' => 'Обмен с 1С', 'GROUP_ID' => [1], // группа с правом на обмен, не «все пользователи» 'ACTIVE' => 'Y',]);Отдельный пользователь нужен не ради порядка. По его действиям в журнале видно, что изменил обмен, а что человек, и его можно отключить, не трогая администратора.
Указываем адрес приёмника в узле обмена 1С:
http://example.com/bitrix/admin/1c_exchange.php# этот же адрес обслуживает и каталог, и заказы: тип передаётся параметромИнициатор обмена всегда 1С. Со стороны сайта запустить выгрузку нечем, расписание живёт в узле обмена 1С, а не в агентах Битрикса.
Ставим размер пачки под лимит времени PHP:
// Настройки - Настройки модулей - Торговый каталогCOption::SetOptionString('catalog', 'import_interval', '30'); // секунд на шагCOption::SetOptionString('catalog', 'import_size', '20'); // элементов за шагОбмен идёт шагами: сайт обрабатывает пачку и возвращает управление 1С. Если пачка
не укладывается в max_execution_time, процесс обрывается на середине, и часть
каталога остаётся необновлённой.
Защищаем поля, которые правятся на сайте:
AddEventHandler('iblock', 'OnBeforeIBlockElementUpdate', 'protectSiteFields');
function protectSiteFields(&$arFields){ if (($_REQUEST['mode'] ?? '') !== 'import') { return; // правка руками, ничего не трогаем } unset($arFields['NAME'], $arFields['DETAIL_TEXT']);}Признак mode=import в запросе отличает обмен от ручной правки в админке. Всё,
что не пришло из 1С, обмен считает лишним и затирает.
Проверяем результат по логу и числу активных элементов:
tail -n 40 /home/bitrix/www/upload/1c_catalog/*.logЛог называет шаг, на котором обмен остановился, и число обработанных элементов
на каждом шаге. Строку с ошибкой ищем по слову FAILURE.
Сверяем число активных элементов инфоблока:
$count = CIBlockElement::GetList([], ['IBLOCK_ID' => $iblockId, 'ACTIVE' => 'Y'], []);echo "активных элементов: {$count}\n";Пустой каталог при успешном обмене почти всегда означает, что товары приехали в другой инфоблок: в узле обмена 1С указан не тот тип каталога. Расхождение на десяток элементов обычно даёт деактивация - удалённые в 1С позиции остаются в базе, но перестают быть активными.
Проверять надо на копии каталога, а не на боевом. Обмен пишет в базу сразу, отката у него нет, и ошибка в настройке узла разъезжается по всему инфоблоку за один прогон.
Типичные проблемы
Товары после выгрузки приехали дважды.
Сопоставление идёт по полю XML_ID. После переноса базы 1С или смены узла обмена внешние коды меняются, совпадения не находится, и элементы создаются заново. Старые при этом остаются активными.
Названия и описания, поправленные на сайте, вернулись к старым.
Обмен перезаписывает всё, что пришло из 1С. Поля, которые ведёт контент-менеджер, снимают обработчиком на OnBeforeIBlockElementUpdate по признаку mode=import.
Товары, удалённые в 1С, остались на сайте активными.
Деактивацию включает отдельная настройка обмена. Без неё 1С просто не присылает такие элементы, а сайт трактует отсутствие как «не менялось», а не как «удалено».
Обмен обрывается на большом каталоге.
Пачка не укладывается в лимит времени PHP. Уменьшают import_size в настройках модуля catalog, а не увеличивают лимит на весь сайт.
Цены приехали, а товары нет.
Цены и номенклатура идут разными файлами. Файл цен разобрался, файл товаров - нет, и в логе виден именно его шаг.
Частые вопросы
Можно ли запускать обмен со стороны сайта, агентом или по cron?
Нет. Протокол устроен так, что подключается 1С, а сайт только отвечает на её запросы. Расписание задаётся в узле обмена 1С. Единственное, что делают на стороне сайта, - следят, чтобы 1c_exchange.php был доступен и не закрыт авторизацией по IP.
Почему товар приезжает без раздела?
Разделы связываются тем же внешним кодом, что и товары. Если группа номенклатуры в 1С не выгружается или её код изменился, товар приедет в корень инфоблока. Проверяют выгрузку групп отдельно от выгрузки товаров.
Как выгрузить только изменённые товары?
Это режим самой 1С: в узле обмена включается выгрузка только изменений. Сайт в обоих случаях работает одинаково, разница лишь в объёме присланного файла.
Куда попадают картинки товаров?
В /upload/1c_catalog/ вместе с XML, оттуда обмен переносит их в файлы элементов. Если картинки не доехали, смотрят права на этот каталог и свободное место на диске.
Смежное
-
Обмен: выгрузка товаров и номенклатуры - оглавление подтемы
-
Обмен с 1С и HTTP - как устроен обмен целиком
-
Инфоблоки - хранилище, в которое пишет обмен
-
Картинки товара при обмене: детальная, дополнительные, разделы - что происходит с изображениями
-
Деактивация товаров при обмене - что происходит с исчезнувшими позициями
-
Каталог с сайта в 1С: обратное направление выгрузки - что делать с товарами, заведёнными на сайте
-
Импорт каталога из файла: CSV, повторный запуск, свои поля - разовая загрузка вместо обмена
-
Частичный обмен: выгрузка только изменений и её последствия - когда приезжает только часть каталога
-
Обмен каталогом с несколькими сайтами и конфигурациями - когда сайтов или конфигураций больше одного
-
Своя логика при обмене: обработчики, защита правок, журнал - как именно защитить поля обработчиком
-
Ручная загрузка файла обмена: когда 1С не достучится до сайта - схема без прямой связи с сайтом
-
Импорт каталога изнутри: файлы, сопоставление, перезапись - что происходит внутри этого обмена