Пошаговый скрипт в init.php

При больших количествах элементов во избежание зависания и сброса скрипта лучше запускать его в пошаговом режиме. Данный пример выполняется после прохождения обмена с 1С. Действия могут быть любыми.[spoiler]
AddEventHandler('catalog', 'OnSuccessCatalogImport1C', 'customCatalogImportStep');

function customCatalogImportStep() 
{
    $stepInterval = (int) COption::GetOptionString("catalog", "1C_INTERVAL", "-");
    $startTime = time();
    // Флаг импорта файла торговых предложений
    $isOffers = strpos($_REQUEST['filename'], 'offers') !== false;
    $NS = &$_SESSION["BX_CML2_IMPORT"]["NS"];

    if (!isset($NS['custom']['lastId'])) {
        // Последний отработанный элемент для пошаговости.
        $NS['custom']['lastId'] = 0;
        $NS['custom']['counter'] = 0;
    }

    // Условия выборки элементов для обработки
    $arFilter = array(
    //    'IBLOCK_ID' => 213,
        'ACTIVE' => 'Y', 
     ">QUANTITY_RESERVED" => 0
    );
    if (CModule::IncludeModule("catalog"))
{
  //  $res = CIBlockElement::GetList(array('ID' => 'ASC'), array_merge($arFilter, array('>ID' => $NS['custom']['lastId'])));
    $db_res = CCatalogProduct::GetList(array('ID' => 'ASC'), array_merge($arFilter, array('>ID' => $NS['custom']['lastId'])), false, false);
    $errorMessage = null;

    while ($ar_res = $db_res->Fetch()) { 
 
// Что-нибудь делаем в этом while
      
      $rsStore = CCatalogStoreProduct::GetList(array(), array('PRODUCT_ID' =>$ar_res["ID"]), false, false, array('AMOUNT'));  // данные по всем складам
      $quantity=0;
      while ($arStore = $rsStore->Fetch()){   
      $quantity = $quantity + $arStore['AMOUNT']; // количество товара на всех складах
      }
            // обновим информацию о доступном кол-ве и обнулим резерв
           if(!CCatalogProduct::Update($ar_res["ID"], array("QUANTITY_RESERVED"=>0, 'QUANTITY'=>$quantity))){
            $error = true;
           }
        

        if ($error === true) {
            $errorMessage = 'не удалось обновить ID - '.$ar_res["ID"];
            break;
        } 

// закончили что-нибудь делать 
 

        $NS['custom']['lastId'] = $arItem['ID'];
        $NS['custom']['counter']++;

        // Прерывание по времени шага
        if ($stepInterval > 0 && (time() - $startTime) > $stepInterval) {
            break;
        }
    }
}
    if ($arItem != false) {
        if ($errorMessage === null) {
            print "progress\n";
            print "Обработано " . $NS['custom']['counter'] . ' элементов, осталось ' . $res->SelectedRowsCount();
        } else {
            print "failure\n" . $errorMessage;
        }

        $contents = ob_get_contents();
        ob_end_clean();

        if (toUpper(LANG_CHARSET) != "WINDOWS-1251") {
            $contents = $GLOBALS['APPLICATION']->ConvertCharset($contents, LANG_CHARSET, "windows-1251");
        }

        header("Content-Type: text/html; charset=windows-1251");
        print $contents;
        exit;
    }

}