Highload-блоки (HL-блоки) в Битрикс — мощный инструмент для работы с большими объемами структурированных данных. В этой статье разберем, как программно создавать HL-блоки с кастомными полями, проверять их существование и избегать дублирования.
1. Подготовка среды
Перед началом убедитесь, что:
- Установлены модули 
highloadblockиiblock - Доступно ядро Битрикс (для выполнения PHP-кода)
 - Есть права администратора/разработчика
 
Рекомендуется выполнять код:
- В init.php
 - В отдельном PHP-скрипте
 - Через административный раздел (напр., в результате работы модуля)
 
2. Базовый алгоритм создания
Основные этапы работы:
- Проверка существования HL-блока
 - Создание блока (при отсутствии)
 - Добавление пользовательских полей
 - Валидация и логирование процесса
 
3. Практический пример: Создадим HL-блок «Контакты клиентов»
<?php
use Bitrix\Main\Loader;
use Bitrix\Highloadblock\HighloadBlockTable as HLBT;
use Bitrix\Main\Diag\Debug;
function createClientContactsHL() {
    // Проверка обязательных модулей
    if (!Loader::includeModule('highloadblock') || !Loader::includeModule('iblock')) {
        Debug::dumpToFile("Ошибка: необходимые модули не установлены", 'hl_errors.log');
        return false;
    }
    // Конфигурация HL-блока
    $blockName = 'ClientContacts';
    $tableName = 'client_contacts_hl';
    $entityName = 'Контакты клиентов';
    // Поиск существующего блока
    $hlblock = HLBT::getList(['filter' => ['=NAME' => $blockName]])->fetch();
    if ($hlblock) {
        Debug::dumpToFile("HL-блок '$blockName' существует (ID: {$hlblock['ID']})", 'hl_info.log');
        $hlId = $hlblock['ID'];
    } else {
        // Создание нового HL-блока
        $result = HLBT::add([
            'NAME' => $blockName,
            'TABLE_NAME' => $tableName,
        ]);
        if (!$result->isSuccess()) {
            Debug::dumpToFile("Ошибка создания: ".implode(', ', $result->getErrorMessages()), 'hl_errors.log');
            return false;
        }
        $hlId = $result->getId();
        Debug::dumpToFile("Создан HL-блок ID: $hlId", 'hl_info.log');
    }
    // Конфигурация полей
    $fields = [
        [
            'FIELD_NAME' => 'UF_CLIENT_ID',
            'USER_TYPE_ID' => 'integer',
            'XML_ID' => 'UF_CLIENT_ID',
            'MANDATORY' => 'Y',
            'EDIT_FORM_LABEL' => ['ru' => 'ID клиента', 'en' => 'Client ID'],
            'SETTINGS' => ['SIZE' => 20]
        ],
        [
            'FIELD_NAME' => 'UF_PHONE',
            'USER_TYPE_ID' => 'string',
            'EDIT_FORM_LABEL' => ['ru' => 'Телефон', 'en' => 'Phone'],
            'SETTINGS' => ['SIZE' => 25]
        ],
        [
            'FIELD_NAME' => 'UF_EMAIL',
            'USER_TYPE_ID' => 'string',
            'EDIT_FORM_LABEL' => ['ru' => 'Email', 'en' => 'Email'],
            'SETTINGS' => ['SIZE' => 50]
        ],
        [
            'FIELD_NAME' => 'UF_REG_DATE',
            'USER_TYPE_ID' => 'datetime',
            'EDIT_FORM_LABEL' => ['ru' => 'Дата регистрации', 'en' => 'Registration Date']
        ]
    ];
    // Добавление полей
    foreach ($fields as $field) {
        $field['ENTITY_ID'] = 'HLBLOCK_'.$hlId;
        // Проверка существования поля
        $existingField = CUserTypeEntity::GetList(
            [],
            ['FIELD_NAME' => $field['FIELD_NAME'], 
            'ENTITY_ID' => $field['ENTITY_ID']
        )->Fetch();
        if (!$existingField) {
            $utm = new CUserTypeEntity();
            $fieldId = $utm->Add($field);
            if (!$fieldId) {
                Debug::dumpToFile("Ошибка создания поля {$field['FIELD_NAME']}: ".$utm->LAST_ERROR, 'hl_errors.log');
            }
        }
    }
    return $hlId;
}
// Запуск создания
$hlId = createClientContactsHL();
if ($hlId) {
    echo "HL-блок успешно создан/обновлен. ID: $hlId";
} else {
    echo "Произошла ошибка. Проверьте логи.";
}
?>4. Разбор ключевых элементов
4.1 Проверка модулей
Loader::includeModule('highloadblock');Обязательный этап — активация необходимых модулей перед работой с API.
4.2 Создание HL-блока
HLBT::add([...]);Используем метод HighloadBlockTable для создания новой сущности. Основные параметры:
NAME— системное название (латиница)TABLE_NAME— имя таблицы в БД
4.3 Работа с полями
CUserTypeEntity::Add();Для добавления полей используем стандартный API Битрикс:
ENTITY_IDв форматеHLBLOCK_[ID]USER_TYPE_ID— тип данных (string, integer, datetime и др.)MANDATORY— обязательность заполнения
5. Проверка результата
После выполнения кода проверьте:
- В админке: Контент -> Highload-блоки
 - В структуре БД: появление таблицы 
b_hlbd_[table_name] - В списке полей сущности
 
6. Особенности и рекомендации
- Именование:
 
- Для HL-блоков используйте только латиницу
 - Префикс 
UF_обязателен для полей - Имена таблиц должны быть уникальными
 
- Типы данных:
 
- string — строка до 255 символов
 - integer — целые числа
 - double — числа с плавающей точкой
 - datetime — дата и время
 - boolean — флаги
 - enum — списки
 
- Безопасность:
 
- Всегда проверяйте существование блока/полей
 - Используйте транзакции для критических операций
 - Ограничивайте доступ к исполнению кода
 
- Производительность:
 
- Для массовых операций используйте пакетное добавление
 - Кэшируйте ID HL-блоков
 - Оптимизируйте структуру полей
 
7. Типовые ошибки
- Неверный формат 
ENTITY_ID 
- Правильно: 
HLBLOCK_1 - Неправильно: 
HL1,HL_BLOCK_1 
- Дублирование названий таблиц
 
- Убедитесь в уникальности 
TABLE_NAME 
- Попытка создать поле без 
UF_префикса 
- Битрикс автоматически отклонит такие поля
 
- Неправильные права доступа
 
- Для выполнения операций нужны права разработчика
 
8. Расширение функционала
Дополнительные возможности:
- Связь с элементами инфоблоков через привязку (iblock_element)
 - Использование сложных типов: пользовательские справочники
 - Интеграция с бизнес-процессами
 - Создание композитных индексов
 
Заключение
Программное создание HL-блоков — мощный инструмент в руках разработчика Битрикс. Приведенный пример можно адаптировать для любых задач, связанных с хранением структурированных данных. Главные преимущества подхода:
- Автоматизация развертывания
 - Контроль версий
 - Повторяемость результатов
 - Легкость поддержки
 
Всегда тестируйте код на staging-окружении перед использованием в production и соблюдайте рекомендации по безопасности.