Разработка кастомных импорт/экспорт модулей 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Разработка кастомных импорт/экспорт модулей 1С-Битрикс
Средняя
~1-2 недели
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1177
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    811
  • 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 Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    747
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Разработка кастомных импорт/экспорт модулей 1С-Битрикс

Стандартный обмен данными Битрикс — CommerceML для 1С, CSV-импорт в инфоблоки — покрывает типовые задачи. Когда источник данных нестандартен, структура данных сложная или нужна двусторонняя синхронизация в реальном времени — пишем собственный модуль.

Архитектура кастомного модуля

Модуль Битрикс — это директория в /local/modules/{vendor}.{modulename}/, зарегистрированная через RegisterModule. Структура:

local/modules/company.import/
├── install/
│   ├── index.php          # InstallDB(), UnInstallDB(), DoInstall()
│   └── db/mysql/install.sql
├── lib/
│   ├── Importer.php       # основная логика
│   ├── Parser/
│   │   ├── XmlParser.php
│   │   └── CsvParser.php
│   └── Queue/
│       └── ImportQueue.php
├── admin/
│   └── import_settings.php  # административный интерфейс
├── include.php
└── .settings.php

Импорт из произвольных источников

Импорт из XML (кастомная схема, не CommerceML):

namespace Company\Import;

use Bitrix\Main\Loader;
use Bitrix\Catalog\ProductTable;

class Importer {
    private \SimpleXMLElement $xml;

    public function __construct(string $filePath) {
        Loader::includeModule('iblock');
        Loader::includeModule('catalog');
        $this->xml = simplexml_load_file($filePath);
    }

    public function run(): array {
        $stats = ['created' => 0, 'updated' => 0, 'errors' => 0];

        foreach ($this->xml->products->product as $product) {
            try {
                $this->processProduct($product, $stats);
            } catch (\Throwable $e) {
                \Bitrix\Main\Diag\Debug::writeToFile($e->getMessage(), 'IMPORT ERROR', '/bitrix/modules/company.import/error.log');
                $stats['errors']++;
            }
        }
        return $stats;
    }

    private function processProduct(\SimpleXMLElement $p, array &$stats): void {
        $externalId = (string)$p->id;
        $existing   = $this->findByExternalId($externalId);

        $fields = [
            'IBLOCK_ID'       => IMPORT_IBLOCK_ID,
            'NAME'            => (string)$p->name,
            'CODE'            => \CUtil::translit((string)$p->name, 'ru'),
            'ACTIVE'          => (string)$p->is_active === '1' ? 'Y' : 'N',
            'PROPERTY_VALUES' => [
                'EXTERNAL_ID'  => $externalId,
                'VENDOR_CODE'  => (string)$p->sku,
                'DESCRIPTION'  => (string)$p->description,
            ],
        ];

        if ($existing) {
            \CIBlockElement::Update($existing, $fields);
            $stats['updated']++;
        } else {
            $el = new \CIBlockElement();
            $newId = $el->Add($fields);
            if (!$newId) throw new \RuntimeException($el->LAST_ERROR);
            $stats['created']++;
        }

        // Обновляем цену и остаток
        \CPrice::SetBasePrice($newId ?? $existing, (float)$p->price, 'RUB');
        \CCatalogProduct::Update($newId ?? $existing, ['QUANTITY' => (int)$p->stock]);
    }
}

Пакетная обработка и прогресс

При большом объёме данных (100 000+ записей) обработка через веб-запрос невозможна — timeout. Используем агент Битрикс с сохранением прогресса:

// В таблице хранится: файл, текущая позиция, статистика
class ImportQueue {
    public static function processChunk(int $jobId, int $offset, int $limit = 500): array {
        $job = ImportJobTable::getById($jobId)->fetch();
        // ... читаем $limit строк начиная с $offset
        // ... обрабатываем
        // ... обновляем прогресс в БД
        return ['processed' => $count, 'total' => $job['total_rows']];
    }
}

// Агент вызывается каждую минуту, обрабатывает следующий чанк
function ImportAgent(): string {
    $activeJob = getActiveImportJob();
    if (!$activeJob) return '';

    $result = ImportQueue::processChunk($activeJob['id'], $activeJob['offset']);
    if ($activeJob['offset'] + $result['processed'] >= $result['total']) {
        markJobComplete($activeJob['id']);
        return ''; // агент завершён
    }
    return 'ImportAgent();'; // агент продолжает
}

Экспорт данных

Экспорт в произвольный формат для внешней системы:

class Exporter {
    public function exportOrders(\DateTime $from, \DateTime $to): string {
        $orders = \Bitrix\Sale\OrderTable::getList([
            'filter' => [
                '>=DATE_INSERT' => $from->format('d.m.Y H:i:s'),
                '<=DATE_INSERT' => $to->format('d.m.Y H:i:s'),
                'CANCELED'      => 'N',
            ],
            'select' => ['ID', 'ACCOUNT_NUMBER', 'PRICE', 'CURRENCY', 'DATE_INSERT', 'USER_ID'],
        ])->fetchAll();

        $xml = new \XMLWriter();
        $xml->openMemory();
        $xml->startDocument('1.0', 'UTF-8');
        $xml->startElement('orders');

        foreach ($orders as $order) {
            $xml->startElement('order');
            $xml->writeElement('id',      $order['ID']);
            $xml->writeElement('number',  $order['ACCOUNT_NUMBER']);
            $xml->writeElement('amount',  $order['PRICE']);
            $xml->writeElement('date',    $order['DATE_INSERT']->format(\DateTime::ATOM));
            // ... позиции заказа
            $xml->endElement();
        }

        $xml->endElement();
        return $xml->outputMemory();
    }
}

Двусторонняя синхронизация

Самое сложное — синхронизация без потерь при одновременных изменениях в обеих системах.

Решение: timestamp-based sync с полем SYNC_HASH:

ALTER TABLE b_iblock_element ADD COLUMN sync_hash VARCHAR(32);
ALTER TABLE b_iblock_element ADD COLUMN synced_at DATETIME;

При экспорте записываем хеш состояния. При следующем импорте: если хеш изменился в источнике — обновляем в Битрикс. Если хеш изменился в Битрикс (пользователь отредактировал) — отправляем изменения обратно в источник. Если оба изменились — конфликт, логируем для ручного разбора.

Административный интерфейс модуля

// admin/import_settings.php
require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_admin_before.php';

$APPLICATION->SetTitle('Настройки импорта');

// Форма настроек: путь к FTP, расписание агента, маппинг полей
// Лог последних запусков с результатами (создано/обновлено/ошибки)
// Кнопка "Запустить сейчас"

Форматы и источники

Формат/Источник Инструменты Особенности
XML (кастомный) SimpleXML, XMLReader XMLReader для файлов > 100 МБ
CSV/XLSX PhpSpreadsheet, fgetcsv XLSX — бинарный, требует библиотеку
JSON REST API curl, Guzzle Пагинация, rate limiting
FTP/SFTP phpseclib Автоматическая загрузка файлов
1С CommerceML Встроенный обмен Битрикс Кастомизация через события
Google Sheets Google Sheets API v4 Для небольших объёмов

Сроки

Этап Срок
Анализ форматов и маппинг полей 1–2 дня
Разработка парсера/экспортера 3–5 дней
Пакетная обработка, агент Битрикс 2–3 дня
Административный интерфейс 2–3 дня
Двусторонняя синхронизация (если нужна) 3–5 дней
Тестирование на реальных данных 2–3 дня

Итого: 2–3 недели для одностороннего импорта; 3–4 недели для двусторонней синхронизации.