Налаштування масового переміщення товарів між розділами 1С-Бітрікс

Наша компанія займається розробкою, підтримкою та обслуговуванням рішень на Бітрікс та Бітрікс24 будь-якої складності. Від простих односторінкових сайтів до складних інтернет-магазинів, CRM систем з інтеграцією 1С та телефонії. Досвід розробників підтверджено сертифікатами від вендора.
Пропоновані послуги
Показано 1 з 1 послугУсі 1626 послуг
Налаштування масового переміщення товарів між розділами 1С-Бітрікс
Проста
~1 робочий день
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Розробка на базі Бітрікс, Бітрікс24, 1С для компанії Development of an Online
    585
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    751
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    989

Налаштування масового переміщення товарів між розділами у 1С-Бітрікс

Реструктуризація каталогу: розділ «Смартфони» розбивається на «Смартфони Apple», «Смартфони Samsung», «Смартфони Xiaomi». 800 товарів потрібно розподілити за новими розділами. Або поставщик змінив структуру категорій, і 400 позицій потрібно перенести з одного розділу в інший.

Структура розділів та прив'язка товарів

Розділи інфоблока зберігаються в b_iblock_section. Прив'язка елемента до розділу — поле IBLOCK_SECTION_ID у b_iblock_element (основний розділ). Додаткова прив'язка до кількох розділів — таблиця b_iblock_section_element: IBLOCK_ELEMENT_ID, IBLOCK_SECTION_ID, ADDITIONAL_PROPERTY_ID.

При переміщенні товару потрібно оновити обидва місця:

  1. IBLOCK_SECTION_ID у b_iblock_element — основний розділ.
  2. Запис у b_iblock_section_element — для коректної роботи фільтрів.

Переміщення через CIBlockElement::Update

Стандартний метод оновлення зі зміною розділу:

\CIBlockElement::Update($elementId, false, [
    'IBLOCK_SECTION_ID' => $newSectionId,
]);

Після Update() Бітрікс автоматично оновлює b_iblock_section_element. Але метод повільний при масовому застосуванні — кожен вызов проходить через події, кеш, права доступу.

Пряме SQL-оновлення для швидкості:

global $DB;

$elementIds = implode(',', array_map('intval', $productIds));
$newSection  = (int)$newSectionId;

$DB->Query("
    UPDATE b_iblock_element
    SET IBLOCK_SECTION_ID = {$newSection}
    WHERE ID IN ({$elementIds})
");

$DB->Query("
    DELETE FROM b_iblock_section_element
    WHERE IBLOCK_ELEMENT_ID IN ({$elementIds})
    AND ADDITIONAL_PROPERTY_ID IS NULL
");

foreach ($productIds as $id) {
    $DB->Query("
        INSERT INTO b_iblock_section_element
            (IBLOCK_ELEMENT_ID, IBLOCK_SECTION_ID)
        VALUES
            ({$id}, {$newSection})
    ");
}

Прямий SQL працює в 50-100 разів швидше за CIBlockElement::Update() для масових операцій, але вимагає ручного скидання кешу.

Багаторозділова прив'язка

Якщо товар повинен відображатися в кількох розділах одночасно (наприклад, «Смартфони» та «Акції»), у b_iblock_section_element додається кілька рядків для одного IBLOCK_ELEMENT_ID:

// Видалити старі прив'язки до розділів
\Bitrix\Iblock\SectionElementTable::deleteByFilter([
    'IBLOCK_ELEMENT_ID' => $elementId,
    'ADDITIONAL_PROPERTY_ID' => false,
]);

// Додати нові
foreach ($sectionIds as $secId) {
    \Bitrix\Iblock\SectionElementTable::add([
        'IBLOCK_ELEMENT_ID' => $elementId,
        'IBLOCK_SECTION_ID' => $secId,
    ]);
}

Основний розділ (IBLOCK_SECTION_ID у b_iblock_element) при цьому залишається один — той, який вважається «головним» для хлібних крошок та URL.

Скидання кешу після переміщення

Після масового переміщення кеш компонентів каталогу протухає не відразу. Примусовий скидання:

\Bitrix\Main\Application::getInstance()->getTaggedCache()->clearByTag('iblock_id_' . $iblockId);

// Для конкретних розділів
foreach (array_unique(array_merge($oldSectionIds, [$newSectionId])) as $secId) {
    \Bitrix\Main\Application::getInstance()->getTaggedCache()
        ->clearByTag('iblock_section_' . $secId);
}

Переміщення за умовою

Для автоматичного розподілу товарів за розділами на основі властивостей — наприклад, за брендом:

$brandSectionMap = [
    'Apple'   => 125,
    'Samsung' => 126,
    'Xiaomi'  => 127,
];

$res = \CIBlockElement::GetList(
    [],
    ['IBLOCK_ID' => $iblockId, 'IBLOCK_SECTION_ID' => $sourceSection],
    false,
    false,
    ['ID', 'PROPERTY_BRAND']
);

while ($item = $res->GetNext()) {
    $brand    = $item['PROPERTY_BRAND_VALUE'];
    $targetId = $brandSectionMap[$brand] ?? null;
    if ($targetId) {
        \CIBlockElement::Update($item['ID'], false, ['IBLOCK_SECTION_ID' => $targetId]);
    }
}

При великих обсягах цей скрипт запускається як агент Бітрікса пакетами по 100-200 елементів з збереженням прогресу в b_option.