При разработке отчетов, выгрузок и механизмов логирования часто возникает необходимость не создавать новый файл Excel каждый раз с нуля, а дописывать порции данных в уже существующий документ за определенный период (например, за текущий день). Традиционный подход с использованием COMОбъект("Excel.Application") работает медленно, требует наличия установленного пакета Microsoft Office на сервере или клиенте и потребляет значительные ресурсы системы.
Разберем подробно, как решить эту задачу быстро и встроенными средствами платформы 1С:Предприятие, а также рассмотрим нюансы и альтернативные варианты реализации.
Начиная с версии платформы 8.3.6, объект ТабличныйДокумент получил полноценную встроенную поддержку чтения и записи файлов форматов XLS и XLSX без необходимости обращения к внешним COM-библиотекам. Это позволяет быстро прочитать существующую таблицу в память, вывести в нее новые области макета или строки и сохранить обратно на диск.
Рассмотрим типовой алгоритм работы:
Файл.ТабличныйДокумент.Прочитать().Записать().Посмотрим на пример программного кода:
ДатаВыгр = Формат(ТекущаяДата(), "ДФ=""ддММММгггг""");
КаталогВыгрузки = "C:\Logs\";
ИмяФайла = КаталогВыгрузки + "Отладка_" + ДатаВыгр + ".xlsx";
ФайлПроверки = Новый Файл(ИмяФайла);
ТабДок = Новый ТабличныйДокумент;
// Если файл уже был создан ранее в течение дня, загружаем его содержимое
Если ФайлПроверки.Существует() Тогда
ТабДок.Прочитать(ИмяФайла);
КонецЕсли;
// Получаем макет с нужной строкой для вывода
Макет = ПолучитьМакет("МакетОтладки");
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
ОбластьСтрока.Параметры.Время = ТекущаяДата();
ОбластьСтрока.Параметры.Сообщение = "Выполнена операция обработки данных";
// Выводим новую строку в конец существующего табличного документа
ТабДок.Вывести(ОбластьСтрока);
// Сохраняем обновленный документ на диск
Попытка
ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
Исключение
ЗаписьЖурналаРегистрации("ВыгрузкаВExcel", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
КонецПопытки;
Несмотря на простоту и скорость реализации через ТабличныйДокумент, необходимо учитывать ряд технических ограничений:
Прочитать() загружает только первый (или активный) лист Excel. Если исходный документ содержал несколько вкладок, макросы VBA, сложные формулы или диаграммы, то при последующем выполнении метода Записать() все эти элементы будут утеряны, а в файле останется только один сохраненный лист.ТипФайлаТабличногоДокумента.XLS аппаратно ограничен 65 536 строками. Если данные дописываются непрерывно в течение длительного времени, файл быстро переполнится. Рекомендуется использовать современный формат ТипФайлаТабличногоДокумента.XLSX, поддерживающий более 1 миллиона строк.Попытка ... Исключение.Если файл создается исключительно для логирования, протоколирования отладочной печати или фиксации журналов, наиболее производительным решением является использование формата CSV. Файлы с расширением .csv автоматически ассоциируются с Microsoft Excel и открываются в виде привычной таблицы.
Главный плюс такого подхода — возможность потоковой дозаписи данных в конец файла без необходимости считывать весь существующий документ в память. Для этого используется объект ЗаписьТекста с параметром дозаписи.
Разберем пример реализации через ЗаписьТекста:
ДатаВыгр = Формат(ТекущаяДата(), "ДФ=""ддММММгггг""");
ИмяФайла = "C:\Logs\Журнал_" + ДатаВыгр + ".csv";
ФайлВывода = Новый Файл(ИмяФайла);
// Четвертый параметр "Истина" включает режим добавления строк в конец файла
Запись = Новый ЗаписьТекста(ИмяФайла, КодировкаТекста.ANSI, Символы.ПС, Истина);
// Если файл только что создан, можно вывести заголовок колонок
Если НЕ ФайлВывода.Существует() Тогда
Запись.ЗаписатьСтроку("Время;Документ;Сумма;Статус");
КонецЕсли;
// Формируем строку данных с разделителем точка с запятой
СтрокаЛога = СтрШаблон("%1;%2;%3;%4",
Формат(ТекущаяДата(), "ДЛФ=T"),
"Счет на оплату № 123",
"15000.00",
"Успешно проведено");
Запись.ЗаписатьСтроку(СтрокаЛога);
Запись.Закрыть();
В среде Windows при необходимости дописывать данные именно в форматированную книгу Excel (сохраняя все вкладки и не читая файл целиком) можно использовать технологию OLE DB через COM-объект ADODB.Connection.
Этот способ позволяет работать с листом Excel как с таблицей реляционной базы данных и отправлять SQL-запрос на вставку строк INSERT INTO.
Посмотрим, как выглядит подключение и вставка:
ИмяФайла = "C:\Data\Выгрузка.xlsx";
Connection = Новый COMОбъект("ADODB.Connection");
СтрокаПодключения = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ИмяФайла + ";Extended Properties=""Excel 12.0 Xml;HDR=YES;"";";
Попытка
Connection.Open(СтрокаПодключения);
// Выполняем добавление строки в лист "Лист1"
ТекстЗапроса = "INSERT INTO [Лист1$] (Номер, Дата, Комментарий) VALUES ('001', '12.05.2025', 'Тестовая запись')";
Connection.Execute(ТекстЗапроса);
Connection.Close();
Исключение
Сообщить("Ошибка добавления через OLE DB: " + ОписаниеОшибки());
КонецПопытки;
Подведем итоги: для типовых задач дополнения документов в 1С наиболее удобным и кроссплатформенным решением остается связка методов ТабличныйДокумент.Прочитать() и ТабличныйДокумент.Записать(). Для системного логирования оптимально использовать формат CSV с дозаписью через ЗаписьТекста.