Загрузка больших объемов данных из внешних файлов — это классическая задача для разработчика 1С. Ситуация, когда файл из 120 тысяч строк обрабатывается 30 минут, является сигналом о наличии серьезных «узких мест» в алгоритме. Проанализируем, почему это происходит и как сократить время обработки с получаса до нескольких секунд.
Выясним причину, по которой стандартные методы могут работать медленно. Чаще всего проблема кроется в двух аспектах:
COMОбъект("Excel.Application") требует запуска полноценного приложения Excel в фоновом режиме. Обращение к каждой ячейке через COM-соединение — это крайне ресурсоемкая операция.НайтиПоКоду() или НайтиПоНаименованию() внутри цикла по 120 000 итераций порождает 120 000 отдельных запросов к базе данных. Это создает колоссальную нагрузку на СУБД.Рассмотрим пошагово способы оптимизации каждого этапа загрузки.
Начиная с современных версий платформы 8.3, объект ТабличныйДокумент научился читать файлы форматов .xlsx и .xls напрямую, без установленного Microsoft Excel. Это работает значительно быстрее, чем COM.
Разберем пример кода для быстрого чтения данных в таблицу значений:
ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать(ПутьКФайлу);
// Определяем область данных
ОбластьЯчеек = ТабДок.Область(1, 1, ТабДок.ВысотаТаблицы, ТабДок.ШиринаТаблицы);
// Используем ПостроительОтчета для максимально быстрой конвертации в ТЗ
ИсточникДанных = Новый ОписаниеИсточникаДанных(ОбластьЯчеек);
ПостроительОтчета = Новый ПостроительОтчета;
ПостроительОтчета.ИсточникДанных = ИсточникДанных;
ПостроительОтчета.Выполнить();
ТЗ_Данные = ПостроительОтчета.Результат.Выгрузить();
Этот метод позволяет прочитать 100-120 тысяч строк всего за 10–15 секунд, так как платформа считывает данные бинарно, минуя тяжелые интерфейсы автоматизации.
После того как данные попали в таблицу значений ТЗ_Данные, нам необходимо найти соответствия в справочниках (например, «Номенклатура»). Никогда не делайте это в цикле! Правильный подход — использование временных таблиц в запросе.
Проанализируем алгоритм:
Посмотрим на пример такого запроса:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВТ_Данные.Артикул КАК Артикул,
| ВТ_Данные.Цена КАК Цена
|ПОМЕСТИТЬ ВТ_Исходник
|ИЗ
| &ТЗ_Данные КАК ВТ_Данные
|;
|
|ВЫБРАТЬ
| ВТ_Исходник.Артикул,
| ВТ_Исходник.Цена,
| Номенклатура.Ссылка КАК НоменклатураСсылка
|ИЗ
| ВТ_Исходник КАК ВТ_Исходник
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
| ПО ВТ_Исходник.Артикул = Номенклатура.Артикул";
Запрос.УстановитьПараметр("ТЗ_Данные", ТЗ_Данные);
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
Вместо 120 000 запросов мы выполняем один. Это сокращает время поиска с минут до долей секунды.
Запись объектов в базу также требует оптимизации. Если вы записываете данные в регистр сведений, используйте наборы записей. Если создаете новые элементы справочников, обязательно отключайте лишние проверки.
Рассмотрим важный механизм — использование свойства ОбменДанными.Загрузка. Установка этого флага в значение Истина сообщает системе, что данные загружаются извне, и большинство подписок на события и проверок в модулях объекта (например, проверка заполнения, контроль уникальности) будут пропущены. Это ускоряет запись в разы.
Для Каждого Строка Из РезультатЗапроса Цикл
// Если объект найден — обновляем, если нет — создаем
ОбъектНоменклатура = Строка.НоменклатураСсылка.ПолучитьОбъект();
Если ОбъектНоменклатура = Неопределено Тогда
ОбъектНоменклатура = Справочники.Номенклатура.СоздатьЭлемент();
КонецЕсли;
// Заполняем данные
ОбъектНоменклатура.Наименование = Строка.Артикул;
// ВАЖНО: Ускоряем запись
ОбъектНоменклатура.ОбменДанными.Загрузка = Истина;
ОбъектНоменклатура.Записать();
КонецЦикла;
Как отмечают эксперты, формат Excel (особенно современный .xlsx) — это сложная XML-структура внутри ZIP-архива. Если у вас есть возможность влиять на формат выгрузки из сторонней системы, всегда выбирайте CSV.
Разберем, почему это быстрее. Объект ЧтениеТекста в 1С работает с потоком данных. Ему не нужно строить модель документа в памяти или парсить сложные XML-схемы форматирования. Чтение 120 000 строк из текстового файла занимает считанные секунды даже на слабом железе.
Проанализируем влияние аппаратной части. Загрузка больших файлов — это однопоточная операция в 1С. Это означает, что 1С задействует только одно ядро процессора. Поэтому для быстрой обработки критически важна высокая частота ядра (от 3.5 ГГц и выше), а не общее количество ядер сервера.
Также помните:
Мы рассмотрели несколько стратегий оптимизации. Подведем итог: нормальное время загрузки 120 000 строк при использовании ТабличногоДокумента и пакетных запросов должно составлять от 1 до 3 минут (включая запись в базу), но никак не 30 минут. Использование метода ПостроительОтчета для выгрузки ТабличногоДокумента в ТаблицуЗначений на сегодняшний день является одним из самых быстрых способов получения данных из Excel внутри платформы 1С.