Как выгрузить большой объем данных из 1С в Excel?

Программист 1С v8.3 (Управляемые формы) Управленческий учет Торговля и дистрибуция
← На главную

При разработке отчетов и выгрузок остатков товаров разработчики часто сталкиваются с задачей передачи сотен тысяч строк в файл электронной таблицы. При этом возникают трудности: выгрузка зависает, завершается аварийно из-за нехватки оперативной памяти или сохраняет пустой документ. Рассмотрим основные причины таких сбоев и разберем наиболее надежные варианты решения этой задачи.

Анализ типичных ошибок при работе через COM-объект

В исходном коде часто встречается принципиальная ошибка: одновременное создание объекта ТабличныйДокумент и вызов COM-объекта Excel.Application. Проанализируем, почему такой подход не работает:

  1. Метод ТаблицаСохранение.Вывести(ОбластьСтрока) формирует документ исключительно во внутренней памяти платформы 1С. В открытую книгу Excel через COM-соединение эти строки не передаются автоматически.
  2. Созданный COM-объект Excel остается пустым, так как ячейки Лист.Cells не заполняются данными.
  3. Вызов оператора Возврат внутри цикла прерывает выполнение процедуры на первой же тысяче строк, не доходя до этапа фактического сохранения файла.
  4. Построчное заполнение ячеек через COM работает крайне медленно из-за постоянного межпроцессного взаимодействия между 1С и Microsoft Excel.

Решение 1. Штатное сохранение через ТабличныйДокумент

Самый простой и быстрый способ, не требующий наличия установленного Microsoft Office на компьютере или сервере, — использование встроенных методов платформы 1С. Для версий файлов XLSX лимит составляет 1 048 576 строк, в то время как старый формат XLS ограничен 65 535 строками.

Сначала заполним табличный документ стандартным выводом областей макета, после чего сохраним его встроенным методом Записать с указанием типа файла ТипФайлаТабличногоДокумента.XLSX:


ТаблицаСохранение = Новый ТабличныйДокумент;
Макет = ЭтотОбъект.ПолучитьМакет("ТаблицаВыгрузки");
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");

ТаблицаСохранение.Вывести(ОбластьШапка);

Для Каждого Стр Из ДанныеВыгрузки Цикл
    ЗаполнитьЗначенияСвойств(ОбластьСтрока.Параметры, Стр);
    ТаблицаСохранение.Вывести(ОбластьСтрока);
КонецЦикла;

ТаблицаСохранение.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX);

Важно: Метод ТабличныйДокумент.Записать() выгружает данные только на один лист. Если вам требуется строго многостраничная книга Excel или объем данных превышает 1 миллион строк, потребуется использовать другие подходы.

Решение 2. Корректная выгрузка через COM-соединение

Если необходимо распределить данные по нескольким листам одной книги Excel средствами COM-автоматизации, данные следует записывать непосредственно в объект листа. Чтобы избежать зависаний, обязательно отключаем обновление экрана и автопересчет формул.

Разберем пример создания листов и заполнения ячеек с разделением по страницам (например, по 500 000 строк на лист):


Попытка
    Эксель = Новый COMОбъект("Excel.Application");
Исключение
    Сообщить("Не удалось запустить Excel: " + ОписаниеОшибки());
    Возврат;
КонецПопытки;

Эксель.ScreenUpdating = Ложь;
Эксель.DisplayAlerts = Ложь;
Эксель.EnableEvents = Ложь;

Книга = Эксель.Workbooks.Add();
Лист = Книга.Worksheets(1);
Лист.Name = "Остатки_1";

НомерСтроки = 1;
ЛимитСтрокНаЛисте = 500000;
НомерЛиста = 1;

Для Каждого Стр Из ДанныеВыгрузки Цикл
    Если НомерСтроки > ЛимитСтрокНаЛисте Тогда
        НомерЛиста = НомерЛиста + 1;
        Лист = Книга.Worksheets.Add(, Лист);
        Лист.Name = "Остатки_" + Строка(НомерЛиста);
        НомерСтроки = 1;
    КонецЕсли;

    Лист.Cells(НомерСтроки, 1).Value = Стр.Номенклатура;
    Лист.Cells(НомерСтроки, 2).Value = Стр.Количество;
    Лист.Cells(НомерСтроки, 3).Value = Стр.Склад;

    НомерСтроки = НомерСтроки + 1;
КонецЦикла;

Попытка
    Книга.SaveAs(ПутьКФайлу);
Исключение
    Сообщить("Ошибка при сохранении: " + ОписаниеОшибки());
КонецПопытки;

Эксель.ScreenUpdating = Истина;
Эксель.DisplayAlerts = Истина;
Книга.Close(Ложь);
Эксель.Quit();

Лист = Неопределено;
Книга = Неопределено;
Эксель = Неопределено;

Обратите внимание на очистку переменных в конце кода: присвоение значения Неопределено гарантирует закрытие фонового процесса EXCEL.EXE в диспетчере задач.

Решение 3. Потоковая выгрузка в CSV для сверхбольших объемов

Если объем выгрузки превышает сотни тысяч записей, генерация через COM или ТабличныйДокумент может вызвать ошибку Недостаточно памяти (особенно в 32-разрядных клиентах 1С). В таких ситуациях оптимально использовать потоковую запись в текстовый файл с разделителями (CSV) с помощью объекта ЗаписьТекста.

Файлы CSV без проблем открываются в Excel и не требуют промежуточного хранения всей таблицы в оперативной памяти:


Запись = Новый ЗаписьТекста(ПутьКФайлуCSV, КодировкаТекста.UTF8);

// Записываем заголовок
Запись.ЗаписатьСтроку("Номенклатура;Количество;Склад");

Для Каждого Стр Из ДанныеВыгрузки Цикл
    СтрокаДанных = Стр.Номенклатура + ";" + Формат(Стр.Количество, "ЧГ=0") + ";" + Стр.Склад;
    Запись.ЗаписатьСтроку(СтрокаДанных);
КонецЦикла;

Запись.Закрыть();

Такой подход обеспечивает максимальную скорость формирования и минимальную нагрузку на оперативную память сервера и клиентского приложения.

← На главную