Почему не завершается процесс Excel при работе из 1С и как его правильно закрыть?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При программной работе с документами Microsoft Excel из 1С с помощью механизмов COM (Excel.Application) программисты часто сталкиваются с ситуацией, когда после выполнения кода процесс EXCEL.EXE продолжает висеть в диспетчере задач Windows. Это может приводить к блокировке файлов, нехватке оперативной памяти и сбоям при повторном запуске обменов.

В этой статье мы подробно проанализируем причины возникновения этой проблемы и разберем практические способы корректного завершения работы с Excel в 1С.

Причины зависания процесса Excel.exe

Рассмотрим, почему операционная система не завершает процесс Excel даже после вызова метода Quit():

  1. Подсчет ссылок COM (COM Reference Counting): Если в коде 1С создаются переменные, ссылающиеся на дочерние объекты Excel (например, Workbooks, Worksheets, Cells, Range), система удерживает эти COM-объекты в памяти. Пока счетчик ссылок на каждый объект не обнулится, процесс EXCEL.EXE не закроется.
  2. Ошибки и интерактивные диалоги: Если при сохранении или закрытии файла Excel пытается задать вопрос пользователю (например, о перезаписи существующего файла или сохранении изменений), а отображение предупреждений не отключено (DisplayAlerts = 0), процесс зависает в ожидании ответа.
  3. Удержание объектов в области видимости: Пока процедура или функция 1С не завершила работу, локальные переменные, содержащие COM-объекты, сохраняются в контексте выполнения.

Способ 1. Явное обнуление ссылок на COM-объекты

Проанализируем базовый способ решения проблемы. Недостаточно просто вызвать метод Quit() для главного объекта приложения. Необходимо последовательно очистить ссылки на все созданные промежуточные объекты — листы, книги и сам COM-объект, присвоив им значение Неопределено.

Разберем по шагам правильную последовательность действий в коде:


Эксель = Новый COMОбъект("Excel.Application"); 
Книга = Эксель.WorkBooks.Add();
Лист = Книга.WorkSheets(1); 

// Выполнение операций с файлом
Лист.Cells(1, 1).Value = "Заголовок";

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

// Отключаем интерактивные предупреждения
Эксель.DisplayAlerts = 0;

// Закрываем рабочую книгу без сохранения повторных запросов
Книга.Close(Ложь);

// Завершаем работу приложения Excel
Эксель.Quit();

// Обязательно обнуляем все переменные COM-объектов
Лист = Неопределено;
Книга = Неопределено;
Эксель = Неопределено;

Важный момент: Присвоение 0 вместо Неопределено (как в выражении Эксель = 0) не всегда приводит к немедленному уничтожению COM-ссылки в платформе 1С. Используйте именно Неопределено.

Способ 2. Вынос работы с COM в отдельную процедуру или функцию

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

Спроектируем архитектуру взаимодействия через отдельные функции подключения и отключения связей:


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

Процедура EXCELРазорватьСвязь(СоответствиеCOM) Экспорт
    Попытка
        СоответствиеCOM["EXCEL"].DisplayAlerts = 0;
        СоответствиеCOM["ExcelФайл"].Close(Ложь);
        СоответствиеCOM["EXCEL"].Quit(); 
        
        СоответствиеCOM.Вставить("ExcelФайл", Неопределено);
        СоответствиеCOM.Вставить("EXCEL", Неопределено);
    Исключение
        Сообщить(ОписаниеОшибки());
    КонецПопытки;                  
КонецПроцедуры

Особенности выполнения на сервере 1С

Если код с Excel.Application выполняется в серверном модуле под системной учетной записью (например, SYSTEM или usr1cv8), вы можете столкнуться с тем, что Excel не может корректно инициализировать пользовательский профиль.

Для устранения подвисаний на 64-разрядных серверах Windows необходимо убедиться в наличии следующих системных каталогов:

  1. C:\Windows\System32\config\systemprofile\Desktop
  2. C:\Windows\SysWOW64\config\systemprofile\Desktop

Учетная запись, от имени которой запущен сервис 1С (rphost), должна иметь полные права на чтение и запись в эти папки.

Альтернативное решение: Работа без COM-объектов

Чтобы гарантированно избежать проблем с висящими процессами EXCEL.EXE, рекомендуем по возможности отказаться от технологии COM в пользу штатных возможностей платформы 1С. Объект ТабличныйДокумент позволяет формировать и сохранять файлы формата XLSX на любых операционных системах (включая Linux) без установки Microsoft Office.

Пример сохранения через табличный документ:


ТабДок = Новый ТабличныйДокумент;
// Заполнение табличного документа данными...

// Сохранение в файл Excel без использования COM
ТабДок.Записать(Путь_SRC_OUT_PAYMENT, ТипФайлаТабличногоДокумента.XLSX);

Этот способ работает намного быстрее, не требует управления сторонними процессами в ОС и полностью исключает утечки ресурсов.

← На главную