При формировании и выгрузке табелей учета рабочего времени из 1С в Microsoft Excel разработчики часто сталкиваются с существенным замедлением работы: выгрузка одного документа может занимать от 60 до 90 секунд. Проанализируем, почему возникает эта проблема, и разберем практические способы ускорения процесса в десятки раз.
Основная причина медленной работы кроется в архитектуре взаимодействия 1С с Microsoft Excel через COM-соединение:
Cells(i, j).Value = ... каждый вызов из среды 1С в отдельный процесс EXCEL.EXE создает накладные расходы. В табеле за месяц на десятки сотрудников с учетом всех дней, видов времени и форматирования количество таких обращений достигает десятков тысяч.Если логика выгрузки жестко завязана на COM-объект Excel, оптимизируем код без изменения общей архитектуры. Разберем необходимые шаги:
Range.Посмотрим на пример правильной организации пакетной выгрузки:
Попытка
Эксель = Новый COMОбъект("Excel.Application");
Книга = Эксель.Workbooks.Add();
Лист = Книга.Worksheets(1);
// Отключаем лишние обработчики для ускорения работы
Эксель.ScreenUpdating = Ложь;
Эксель.Calculation = -4135; // xlCalculationManual
Эксель.EnableEvents = Ложь;
Эксель.DisplayAlerts = Ложь;
// Формируем двумерный массив данных в памяти 1С
// КоличествоСтрок и КоличествоКолонок определяются по данным табеля
МассивДанных = Новый COMSafeArray("VT_VARIANT", КоличествоСтрок, КоличествоКолонок);
Для НомерСтроки = 0 По КоличествоСтрок - 1 Цикл
Для НомерКолонки = 0 По КоличествоКолонок - 1 Цикл
МассивДанных.SetValue(НомерСтроки, НомерКолонки, ПолучитьЗначениеТабеля(НомерСтроки, НомерКолонки));
КонецЦикла;
КонецЦикла;
// Записываем весь массив данных одним вызовом
Диапазон = Лист.Range(Лист.Cells(1, 1), Лист.Cells(КоличествоСтрок, КоличествоКолонок));
Диапазон.Value = МассивДанных;
// Применяем групповое форматирование к диапазону
Диапазон.Borders.LineStyle = 1; // xlContinuous
// Устанавливаем защиту на лист
Лист.Protect("ПарольЗащиты");
// Включаем параметры обратно перед сохранением
Эксель.ScreenUpdating = Истина;
Эксель.Calculation = -4105; // xlCalculationAutomatic
Эксель.EnableEvents = Истина;
Эксель.DisplayAlerts = Истина;
Книга.SaveAs(ПутьКФайлу);
Книга.Close(Ложь);
Эксель.Quit();
Исключение
Если Эксель <> Неопределено Тогда
Эксель.Quit();
КонецЕсли;
ВызватьИсключение;
КонецПопытки;
// Очищаем COM-переменные для освобождения процесса в памяти
Лист = Неопределено;
Книга = Неопределено;
Эксель = Неопределено;
Рассмотрим наиболее производительный и простой в поддержке вариант. Платформа 1С умеет формировать сложные печатные формы с любым оформлением за доли секунды. Если требуется сохранить форматирование и запаролить лист, разделим задачу на два этапа:
ТабличныйДокумент с макетом, объединением ячеек, шрифтами и цветами, после чего сохраняем его в файл XLSX.Protect, сохраняем и закрываем книгу.Разберем по шагам реализацию данного подхода:
// Этап 1: Формирование и сохранение табличного документа средствами 1С
ТабДокумент = Новый ТабличныйДокумент;
// ... Заполнение табеля данными и оформлением через макет ...
ИмяФайла = "C:\Temp\Табель.xlsx";
ТабДокумент.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
// Этап 2: Наложение пароля на готовый файл через COM
Попытка
Эксель = Новый COMОбъект("Excel.Application");
Эксель.DisplayAlerts = Ложь;
Эксель.ScreenUpdating = Ложь;
Книга = Эксель.Workbooks.Open(ИмяФайла);
Лист = Книга.Worksheets(1);
// Установка защиты листа
Лист.Protect("СекретныйПароль");
Книга.Save();
Книга.Close(Ложь);
Эксель.Quit();
Исключение
Если Эксель <> Неопределено Тогда
Эксель.Quit();
КонецЕсли;
ВызватьИсключение;
КонецПопытки;
Лист = Неопределено;
Книга = Неопределено;
Эксель = Неопределено;
Данный подход сокращает общее время выгрузки с 75 секунд до 1–2 секунд, так как отрисовка документа полностью выполняется внутри платформы 1С без накладных расходов на COM-вызовы.
Проанализируем альтернативный вариант, который позволяет полностью отказаться от наличия Microsoft Excel на компьютере пользователя или сервере. Формат XML Spreadsheet представляет собой файл с разметкой XML, который открывается в Excel как полноценная таблица.
ЗаписьXML или ЗаписьТекста с расширением .xml (или .xls).<WorksheetOptions><ProtectObjects>True</ProtectObjects></WorksheetOptions>.Такой способ формируется мгновенно в оперативной памяти и не создает фоновых процессов в операционной системе.
При работе с COM-объектами важно предотвращать зависание процессов EXCEL.EXE в диспетчере задач. Обратим внимание на обязательные правила:
Попытка ... Исключение.Эксель.Quit().Эксель = Неопределено), чтобы сборщик мусора платформы 1С освободил COM-дескриптор.