Как обновить элемент инфоблока в Битрикс через CIBlockElement::Update?

Как обновить элемент инфоблока в Битрикс через CIBlockElement::Update?

Ночной импорт из 1С пишет в лог "обновлено 4000 товаров", а утром в каталоге пустые характеристики: артикул, фото, привязки. Разработчик добавил в CIBlockElement::Update три свойства из семи - и остальные исчезли. Это не "баг Битрикса", а контракт ключа PROPERTY_VALUES: если он есть в массиве, ядро считает, что вы передаёте полный набор свойств. Ниже - безопасные паттерны Update для полей, точечное обновление через SetPropertyValuesEx и чек-лист, если свойства слетают без вашего ведома.

CIBlockElement::Update меняет поля элемента (название, активность, сортировку) и при желании свойства. Без ключа PROPERTY_VALUES свойства не трогаются - меняйте NAME и ACTIVE спокойно. Если PROPERTY_VALUES передан, в массиве должны быть все свойства инфоблока, иначе остальные очистятся. Для одного-двух свойств используйте SetPropertyValuesEx. При false смотрите $el->LAST_ERROR и обработчики OnBeforeIBlockElementUpdate в init.php.

Речь про 1С-Битрикс: Управление сайтом на сервере, не про облачную CRM Bitrix24. Элемент инфоблока — запись контента: товар, новость, услуга. Если инфоблок только создаёте — начните с гайда по созданию инфоблока.

Разберите, когда нужен Update в коде, а не правка в админке

Сравнение: когда править в админке, а когда Update или SetPropertyValuesEx в коде

В админке удобно править одну карточку. Update нужен, когда данные приходят пакетом: обмен с 1С, cron, вебхук, импорт CSV. Тогда один PHP-скрипт проходит по сотням ID и меняет цены, остатки или флаг активности.

Ситуация Админка CIBlockElement::Update / SetPropertyValuesEx
Одна правка текста Быстрее и нагляднее Избыточно
Импорт 5000 SKU из 1С Нереально вручную Обязателен; см. также интеграцию 1С с сайтом
Скрыть товар без остатка Можно, но долго на каталоге Update с ACTIVE без PROPERTY_VALUES
Только цена в свойстве Риск человеческой ошибки SetPropertyValuesEx по коду свойства

Делайте: автоматизируйте повторяющиеся массовые правки. Не делайте: не вызывайте Update из визуального редактора - для разовых правок хватит формы элемента.

Подготовьте скрипт: модуль iblock, ID элемента и снимок свойств

Схема подготовки скрипта: модуль iblock, ID элемента и снимок свойств перед Update

Перед любым изменением зафиксируйте "как было". Иначе после отката из бэкапа вы не поймёте, какие свойства затёрлись.

  1. Подключите модуль: Loader::includeModule('iblock') в начале скрипта или агента.
  2. Запишите ELEMENT_ID и IBLOCK_ID - числа из админки или из выборки CIBlockElement::GetList.
  3. Соберите карту свойств: коды PRICE, ARTICLE, BRAND - как в настройках инфоблока, не произвольные имена.
  4. Снимок и объект: GetProperty для состояния «до»; $el = new CIBlockElement; — через него Update и LAST_ERROR.
<?php
use Bitrix\Main\Loader;

Loader::includeModule('iblock');

$elementId = 12345;
$iblockId  = 7;

$before = [];
$rs = CIBlockElement::GetProperty($iblockId, $elementId);
while ($row = $rs->Fetch()) {
    $before[$row['CODE']] = $row['VALUE'];
}

$el = new CIBlockElement;

Делайте: логируйте ID и diff до/после на тестовом элементе. Не делайте: не гоняйте импорт сразу на проде - сначала один элемент в копии каталога.

Обновите NAME, ACTIVE и картинки без затрагивания свойств

Чеклист: безопасное обновление NAME и ACTIVE без затрагивания свойств

Главное правило: если в массиве $arFields нет ключа PROPERTY_VALUES, свойства элемента остаются как были. Меняются только поля самого элемента.

$ok = $el->Update($elementId, [
    'NAME'   => 'Новое название товара',
    'ACTIVE' => 'N',
    'SORT'   => 500,
]);

if (!$ok) {
    echo $el->LAST_ERROR;
}

Так безопасно выключать товары без остатка или менять заголовок после выгрузки из 1С. Картинки — через DETAIL_PICTURE и PREVIEW_PICTURE с CFile::MakeFileArray.

Делайте: для смены только ACTIVE передавайте один ключ ACTIVE. Не делайте: не добавляйте пустой PROPERTY_VALUES = array() "на всякий случай" - это уже сигнал ядру перезаписать свойства.

Избегите ловушки PROPERTY_VALUES: полная перезапись, не "добавить три из семи"

Официальная справка CIBlockElement::Update прямо говорит: если в вызове есть PROPERTY_VALUES, в массиве должны быть все свойства инфоблока. Неуказанное свойство удаляется (кроме типа "файл" - файлы не стираются молча, их удаляют явно через del => Y).

На практике типичная ошибка после примера с Habr: разработчик передаёт PRICE и три характеристики, четыре остальных пропадают — кейс на ftask.ru. Значение false в PROPERTY_VALUES не означает «не трогать» — свойство участвует в полной перезаписи.

Задача Метод Риск для остальных свойств
Только NAME / ACTIVE Update без PROPERTY_VALUES Нет - свойства не меняются
Одно свойство PRICE SetPropertyValuesEx Нет - неуказанные сохраняются
Полная синхронизация из файла 1С Update с полным PROPERTY_VALUES Да, если массив неполный
Список (select) ID enum, не текст "Да" Неверный ID - пустое значение

Для списка найдите ID варианта через CIBlockPropertyEnum::GetList или в HTML option value в админке. Для файлового свойства удаление: ['VALUE' => ['del' => 'Y']].

// ОПАСНО: обновили 2 свойства из 5 - остальные 3 очистятся
$el->Update($elementId, [
    'PROPERTY_VALUES' => [
        'PRICE'    => 1990,
        'ARTICLE'  => 'SKU-001',
    ],
]);

// БЕЗОПАСНО: полная выгрузка - сначала GetProperty, потом весь массив
$fullProps = /* собрать все коды из GetProperty */;
$el->Update($elementId, ['PROPERTY_VALUES' => $fullProps]);

Делайте: для частичного изменения свойств не используйте Update. Не делайте: не копируйте PROPERTY_VALUES из Habr-примера с тремя ключами на боевой каталог.

Примените SetPropertyValuesEx и отладьте сбой по LAST_ERROR

SetPropertyValuesEx - статический метод для точечного обновления: передаёте только нужные коды, остальные не трогаете.

CIBlockElement::SetPropertyValuesEx($elementId, $iblockId, [
    'PRICE' => 2490,
    'BRAND' => 'Acme',
]);

// Список: передаём ID варианта enum, не строку
CIBlockElement::SetPropertyValuesEx($elementId, $iblockId, [
    'IN_STOCK' => 42, // ID значения "Да" из CIBlockPropertyEnum
]);

Если Update вернул false, сразу выводите $el->LAST_ERROR - там текст валидации, права или отмены через событие. В реальном проекте свойства могут исчезнуть и без PROPERTY_VALUES в вашем вызове: в init.php обработчик OnBeforeIBlockElementUpdate иногда создаёт пустой PROPERTY_VALUES без проверки isset. Попросите разработчика найти такие обработчики по проекту.

Массовый импорт: Update($id, $fields, false, false) отключает переиндексацию; после цикла переиндексируйте отдельно. После SetPropertyValuesEx сбросьте кэш — иначе на витрине старые значения, см. карточку товара.

Схема безопасного импорта:
GetProperty (снимок) → Update полей без PROPERTY_VALUES → SetPropertyValuesEx по изменившимся кодам → проверка GetProperty → лог LAST_ERROR
  1. При false: echo $el->LAST_ERROR и ID элемента в лог агента.
  2. При "пустых" свойствах: grep OnBeforeIBlockElementUpdate в local/php_interface.
  3. Для справочников миллионов строк смотрите Highload-блоки, не классический инфоблок.
  4. После правок на проде зафиксируйте задачу в регламенте поддержки сайта.

Делайте: разделяйте обновление полей и свойств на два вызова. Не делайте: не смешивайте неполный PROPERTY_VALUES с боевым каталогом без бэкапа.

Что дальше

  1. Прогоните сценарий на одном тестовом элементе с GetProperty до и после.
  2. Замените неполные Update с PROPERTY_VALUES на SetPropertyValuesEx.
  3. Проверьте init.php на обработчики, трогающие PROPERTY_VALUES и сверьте карту свойств с модулем обмена 1С.
  4. Если импорт ломает каталог регулярно - обсудите аудит обмена с разработчиком до следующей выгрузки.
Автор: Максим Мольков, разработчик 1С-Битрикс.
Источники: CIBlockElement::Update, SetPropertyValuesEx, форум dev.1c-bitrix.ru (темы про затирание свойств), практика внедрений на CMS.

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

Почему после Update пропали свойства элемента?

Чаще всего в массиве был ключ PROPERTY_VALUES с неполным набором кодов: ядро удаляет неуказанные свойства. Реже виноват обработчик OnBeforeIBlockElementUpdate, который подставляет пустой PROPERTY_VALUES. Проверьте вызов и init.php, затем восстановите из бэкапа или полного GetProperty.

Как обновить одно свойство, не трогая остальные?

Используйте CIBlockElement::SetPropertyValuesEx($elementId, $iblockId, ['CODE' => $value]). Не передавайте PROPERTY_VALUES в Update, если нужно изменить только одно поле свойства. После вызова сверьте результат через GetProperty.

Чем Update отличается от SetPropertyValuesEx?

Update меняет поля элемента и при наличии PROPERTY_VALUES перезаписывает все свойства целиком. SetPropertyValuesEx меняет только переданные коды свойств, остальные сохраняет. Для ACTIVE и NAME достаточно Update без PROPERTY_VALUES.

Как передать значение списка (select) в PROPERTY_VALUES?

Передавайте числовой ID варианта enum из CIBlockPropertyEnum::GetList, не текст "Да" или "Нет". Текст в админке и ID в базе - разные вещи; неверный ID даст пустое значение в карточке.

Update вернул false - где смотреть причину?

Сразу после вызова выведите $el->LAST_ERROR у объекта CIBlockElement. Там будет текст про права, валидацию списка или отмену в обработчике события. Добавьте ID элемента в лог, чтобы найти проблемную запись в массовом импорте.

Можно ли обновлять элемент без PHP, только из админки?

Да, для разовых правок форма элемента в Контент → ваш инфоблок безопаснее: свойства не затрутся из-за API-контракта. Update нужен для скриптов, cron и обмена с 1С, когда правок сотни и тысячи.

Читайте также

Интеграции с 1С и API
949 6 мин.

Как настроить регистрацию и личный кабинет покупателя на 1С-Битрикс?

Пошаговая настройка регистрации на сайте битрикс: Главный модуль, main.register, system.auth.form и sale.personal.section с историей заказов и 152-ФЗ.
Интеграции с 1С и API
679 15 мин.

Что такое компонент в Битриксе и как он работает

Каждый разработчик, впервые столкнувшийся с Битриксом, проходит через своеобразный обряд посвящения. Вначале кажется, что это просто CMS, где можно поправить HTML в визуальном редакторе или дописать пару строк CSS. Но однажды наступает момент, когда нужно изменить логику вывода новостей, отфильтровать товары по хитрому свойству или добавить на страницу нечто совершенно новое. И тут он впервые слышит это слово — «компонент». Для многих этот момент становится стеной. Система, казавшаяся понятной, вдруг превращается в черный ящик, полный непонятных файлов и странных переменных. Но стоит лишь раз заглянуть под капот, как эта стена рассыпается, превращаясь в набор удивительно логичных и мощных строительных блоков. Понимание компонентов — это тот самый щелчок, после которого разработка на Битрикс из мучения превращается в творчество.

Эта статья — ваш проводник в мир компонентов «1С-Битрикс». Мы не будем сыпать сухими терминами из документации. Вместо этого мы совершим путешествие: от философии, заложенной в эту архитектуру, до мельчайших деталей её работы. Мы разберем компонент на атомы — его файлы, логику, шаблон, параметры — и соберем обратно, чтобы вы не просто знали, что это, но и глубоко понимали, почему это работает именно так. Это знание — ключ к эффективной и профессиональной разработке на Битрикс.

Интеграции с 1С и API
605 2 мин.

Установка Composer в 1С-Битрикс

Установка Composer в проекте на 1С-Битрикс требует учета особенностей платформы, чтобы обеспечить корректную работу и интеграцию с системой.