Импорт/Экспорт элементов любого инфоблока через CSV файл (запуск на Cron), Способ автоматического обмена данными с другими системами при помощи импорта и экспорта элементов инфоблока через CSV файлы с запуском на кроне
В процессе реализации проекта столкнулся с задачей по обмену данными между 1С Битрикс24 и внешней базой данных организации. Самым подходящим вариантом я посчитал использование импорта/экспорта через CSV файлы с запуском скрипта по расписанию на Cron'е. В Интернете, к сожалению, не нашел готовых решений для обмена данными с абсолютно любыми инфоблоками 1С Битрикс, поэтому с радостью поделюсь своим решением и надеюсь оно окажется для кого-то полезным.
В качестве способа управления данными в 1С Битрикс были выбраны "Универсальные списки", так как характер данных был исключительно информационным, например, выгрузка с портала Битрикс24 сведений о командировках сотрудников в автоматическом режиме, каждые 2 часа.
Большая просьба, если Вы знаете более правильный или удобный способ реализации подобных задач, пожалуйста отпишитесь в этой теме.
Импорт/Экспорт пользователей через CSV файлы я описал в этой теме.
Представленные скрипты созданы на основе официальной документации https://dev.1c-bitrix.ru/api_d7/index.php , проверены и работают в актуальных версиях продуктов 1С Битрикс на текущий момент.
Импорт данных из CSV файла в инфоблок
Код
<?php
/* Для запуска на Cron'е (автоматически, по расписанию), нужно добавить этот код в файл.
То есть, создаем файл, например, назовем его data_import_infoblock.php в любой
папке в файловой структуре, помещаем в него весь этот код с тегами <?php ?> и запускаем
исполнение файла на Cron'е через командную строку BitrixVM, с нужным интервалом.
Также можно создать Агента и добавить данный код в /bitrix/php_interface/init.php
Пример создания Агента: https://dev.1c-bitrix.ru/learning/course/index.php?COURSE_ID=43&LESSON_ID=2290&LESSON_PATH=3913.4776.4620.4978.2290
*/
/*
// Для запуска на кроне нужно раскомментировать этот участок кода
$_SERVER["DOCUMENT_ROOT"] = realpath(dirname(__FILE__)."/.." ) ;
$DOCUMENT_ROOT = $_SERVER["DOCUMENT_ROOT"];
define("NO_KEEP_STATISTIC", true);
define("NOT_CHECK_PERMISSIONS",true);
define('CHK_EVENT', true);
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php" ) ;
@set_time_limit(0);
@ignore_user_abort(true);
*/
/* Для запуска через Командную PHP-строку в панели Администратора достаточно кода ниже,
при этом теги <?php ?> в начале и конце кода не ставятся */
require_once($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/classes/general/csv_data.php"); // Подключаем библиотеку CCSVData
$filePath = $_SERVER["DOCUMENT_ROOT"].'/imtest/data_import_infoblock.csv'; // Путь до CSV файла, откуда берем данные (от корня сайта)
$csvFile = new CCSVData('R', false); // Создаём объект – экземпляр класса CCSVData
$csvFile->LoadFile($filePath); // Указываем методу LoadFile путь до CSV файла
$csvFile->SetDelimiter(';'); // Устанавливаем разделитель для CSV файла
CModule::IncludeModule("iblock"); // Модключаем модуль "Информационные блоки"
$el = new CIBlockElement; // Объявляем метод добавления нового элемента
while ($arFields = $csvFile->Fetch()) // Циклом построчно записываем данные из CSV файла в инфоблок
{
$PROP = array();
$PROP['FIO'] = $arFields[0]; // Записываем в элемент инфоблока в свойство FIO данные из первого столбца CSV файла
$PROP['MAIL'] = $arFields[1]; // Записываем в элемент инфоблока в свойство MAIL данные из второго столбца CSV файла
$arLoadProductArray = Array( // Массив параметров элемента инфоблока
"MODIFIED_BY" => 1, // Пользователем с этим ID изменен элемент. Можно передавать из CSV файла, например указать $arFields[5] вместо 1
"IBLOCK_SECTION_ID" => "", // В каком разделе лежит элемент
"CODE" => "", // Символьный код элемента
"IBLOCK_ID" => 17, // ID инфоблока, где хранится элемент
"PROPERTY_VALUES" => $PROP, // Значения свойств элемента
"NAME" => $arFields[0], // Имя элемента, можно передавать из CSV файла.
"ACTIVE" => "Y", // Статус активности элемента
);
if($PRODUCT_ID = $el->Add($arLoadProductArray)) // Добавляем элемент инфоблока
{
// Здесь можно написать сообщение об успешном добавлении
} else {
// Здесь можно написать сообщение об ошибке и сделать вывод ошибки
}
}
?>
Экспорт данных в CSV файл из инфоблока
Код
<?php
/* Для запуска на Cron'е (автоматически, по расписанию), нужно добавить этот код в файл.
То есть, создаем файл, например, назовем его data_export.php в любой
папке в файловой структуре, помещаем в него весь этот код с тегами <?php ?> и запускаем
исполнение файла на Cron'е через командную строку BitrixVM, с нужным интервалом/
Также можно создать Агента и добавить данный код в /bitrix/php_interface/init.php
Пример создания Агента: https://dev.1c-bitrix.ru/learning/course/index.php?COURSE_ID=43&LESSON_ID=2290&LESSON_PATH=3913.4776.4620.4978.2290
*/
/*
// Для запуска на кроне нужно раскомментировать этот участок кода
$_SERVER["DOCUMENT_ROOT"] = realpath(dirname(__FILE__)."/.." ) ;
$DOCUMENT_ROOT = $_SERVER["DOCUMENT_ROOT"];
define("NO_KEEP_STATISTIC", true);
define("NOT_CHECK_PERMISSIONS",true);
define('CHK_EVENT', true);
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php" ) ;
@set_time_limit(0);
@ignore_user_abort(true);
*/
/* Для запуска через Командную PHP-строку в панели Администратора достаточно кода ниже,
при этом теги <?php ?> в начале и конце кода не ставятся */
require_once($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/classes/general/csv_data.php"); // Подключаем библиотеку CCSVData
$filePath = $_SERVER['DOCUMENT_ROOT'] . '/imtest/' . 'data_export_infoblock.csv'; // Путь до файла, куда записываем данные из инфоблока, от корня сайта
$fp = fopen($filePath, 'w+'); // Очищаем файл CSV, иначе записи будут добавляться к уже имеющимся, причем, вместе с шапкой CSV
@fclose($fp); // Закрываем файл CSV
$fields_type = 'R'; // Дописываем строки в файл
$delimiter = ";"; // Устанавливаем разделитель для CSV файла
$csvFile = new CCSVData($fields_type, false); // Создаём объект – экземпляр класса CCSVData
$csvFile->SetFieldsType($fields_type); // Метод класса CCSVData, задающий тип записи в файл R
$csvFile->SetDelimiter($delimiter); // Метод класса CCSVData, устанавливающий разделитель
$csvFile->SetFirstHeader(false); // Метод класса CCSVData, указывающий, что первая строка будет шапкой
//Создаем шапку и записываем в CSV файл (не обязательно)
//$arrHeaderCSV = array("ex_id","ex_fio","ex_mail"); // Задаем поля в шапке в CSV файле
//$csvFile->SaveFile($filePath, $arrHeaderCSV); // Записываем шапку в CSV файл
// Подключам Модуль "Информационные блоки".
CModule::IncludeModule("iblock");
// Подключаемся к нужному нам инфоблоку, к его полям и свойствам
$IBLOCK_ID = 17; // Устанавливаем ID инфоблока, с которым хотим работать
//$arSort= Array("ID"=>"ASC"); // Сортируем элементы инфоблока по возрастанию, по полю ID. Для регулярного экпорта в другую БД можно это поле пропустить и в CIBlockElement::GetList вместо $arSort написать Array()
$arSelect = Array("ID", "PROPERTY_FIO", "PROPERTY_MAIL", "PROPERTY_EXPO"); // Массив возвращаемых полей элемента, где слово PROPERTY_ указывает на свойство элемента инфоблока
$arFilter = Array("IBLOCK_ID"=>$IBLOCK_ID, "ACTIVE_DATE"=>"Y", "ACTIVE"=>"Y"); // Выбираем только активные элементы, которые хранятся в инфоблоке с ID 17
$res = CIBlockElement::GetList(Array(), $arFilter, false, false, $arSelect); // Функция Битрикс API. Возвращает список элементов по фильтру $arFilter
// Получаем нужные данные из выбранных полей и записываем в CSV файл
while($ob = $res->GetNextElement()) // Метод возвращает из выборки объект _CIBElement, и передвигает курсор на следующую запись
{
$arFields = $ob->GetFields(); // Получаем значения полей и свойст инфоблока
if ($arFields[PROPERTY_EXPO_VALUE] == null) // Проверяем, если значение свойства EXPO пустое, то выгружаем элементы (это нужно для того, чтобы не выгружались ранее выгруженные записи, а только новые, затем, в конце кода запишем единичку в соответствующее поле)
{
$exportDATA = array($arFields['ID'],$arFields[PROPERTY_FIO_VALUE],$arFields[PROPERTY_MAIL_VALUE]); // Присваиваем набор полей и свойств инфоблока переменной $exportDATA
$csvFile->SaveFile($filePath, $exportDATA); // Записываем результат из переменной $exportDATA в CSV файл
CIBlockElement::SetPropertyValuesEx($arFields['ID'], false, array("EXPO" => "1")); // Присваиваем значение 1 в свойство EXPO у каждого экспортированного элемента инфоблока, чтобы больше эта строка с данными не попадала в экспорт. Если данный скрипт висит на Cron'e и выполняется по расписанию и если новых записей в инфоблоке нет, будет выгружаться только шапка CSV файла
}
}
?>