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

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

Работа с внешними приложениями через механизм COM-соединения — одна из самых распространенных задач в 1С, особенно когда речь идет об импорте данных из электронных таблиц. Однако многие разработчики сталкиваются с неприятной ситуацией: после завершения работы обработки в диспетчере задач Windows продолжают висеть процессы Excel.exe. Это не только потребляет оперативную память, но и может привести к блокировке файлов или невозможности запуска новых сессий Excel при достижении лимита. В этой статье мы подробно разберем, почему так происходит и как гарантированно закрыть процесс.

Анализ типичной ошибки: «Двойная инициализация»

Рассмотрим ситуацию, с которой столкнулся автор темы. Зачастую корень проблемы кроется в невнимательности при написании кода. Проанализируем фрагмент, который привел к «подвисанию» процесса:


Попытка 
    Excel = Новый COMОбъект("Excel.Application"); 
    Excel.WorkBooks.Open(ИмяФайла); 
Исключение 
    // Обработка ошибки
КонецПопытки; 

// ... какой-то код ...

Попытка 
    Excel = Новый COMОбъект("Excel.Application"); 
    Excel.WorkBooks.Open(ИмяФайла); 
Исключение 
    // Обработка ошибки
КонецПопытки;

В данном примере разработчик дважды инициализирует переменную Excel новым COM-объектом. При втором вызове Новый COMОбъект ссылка на первый экземпляр приложения теряется, но сам процесс в операционной системе остается активным. Поскольку 1С больше «не видит» первый объект, она не может отправить ему команду на закрытие. Вывод: всегда следите за тем, чтобы объект создавался единожды, либо корректно закрывался перед повторным использованием переменной.

Правильный алгоритм закрытия COM-объекта

Для того чтобы Excel корректно завершил свою работу, недостаточно просто обнулить переменную. Процесс закрытия должен быть многоступенчатым. Разберем по шагам, как это реализовать в коде 1С:

  1. Закрытие рабочих книг: Сначала нужно закрыть все открытые файлы без сохранения изменений (или с сохранением, если это требуется).
  2. Выход из приложения: Вызов метода Quit().
  3. Освобождение ссылки: Присваивание переменной значения 0 или Неопределено.

Пример надежного кода для завершения работы:


Попытка
    Если Excel <> Неопределено Тогда
        Excel.DisplayAlerts = Ложь; // Отключаем системные сообщения Excel
        Excel.Workbooks.Close();
        Excel.Quit();
        Excel = 0;
    КонецЕсли;
Исключение
    Excel = 0; // В случае ошибки просто обнуляем ссылку
КонецПопытки;

Важно помнить: метод Excel.Quit() — это лишь «просьба» к приложению закрыться. Если в этот момент открыто модальное окно (например, с вопросом о сохранении файла), Excel будет ждать ответа пользователя и процесс останется в памяти. Именно поэтому использование DisplayAlerts = Ложь является критически важным.

Проблема «неявных» ссылок и иерархия объектов

Выясним причину, по которой даже после Quit() процесс может не исчезнуть. Механизм COM работает на основе счетчика ссылок. Процесс завершается только тогда, когда счетчик равен нулю. Если вы обращаетесь к ячейкам или листам напрямую через длинные цепочки, 1С создает промежуточные неявные объекты.

Например, в строке Значение = Excel.Workbooks(1).Sheets(1).Cells(1,1).Value; создаются объекты для книги, листа и ячейки. Рекомендуется назначать каждый уровень отдельной переменной и очищать их в обратном порядке:


Книги = Excel.Workbooks;
Книга = Книги.Open(ИмяФайла);
Лист = Книга.Sheets(1);

// ... работа с листом ...

Лист = Неопределено;
Книга.Close(Ложь);
Книга = Неопределено;
Книги = Неопределено;
Excel.Quit();
Excel = Неопределено;

Принудительное завершение через Taskkill

Если штатные методы не помогают (например, при критическом сбое самого Excel), можно воспользоваться средствами операционной системы. Посмотрим на пример использования системной утилиты taskkill через объект WScript.Shell:


WshShell = Новый COMОбъект("WScript.Shell");
// Ключ /f означает принудительное завершение, /im - поиск по имени процесса
WshShell.Run("taskkill /f /im excel.exe", 0, Истина);

Внимание: этот метод крайне радикален. Он закроет все запущенные процессы Excel на компьютере. Если в этот момент менеджер заполняет важный отчет вручную, его данные будут потеряны. Используйте этот способ только на серверах в ночное время или если вы уверены, что Excel используется только вашей обработкой.

Особенности работы на сервере (папки Desktop)

Проанализируем ситуацию, когда обработка запускается в фоновом задании на сервере. Часто Excel «виснет» из-за отсутствия необходимых системных папок в профиле пользователя, под которым работает служба 1С. Для корректной работы COM-объекта системе требуются папки Desktop.

Попробуйте вручную создать следующие директории:

Это старый, но до сих пор актуальный «лайфхак» для серверных ОС (Windows Server 2012/2016/2019), который решает проблемы инициализации графического интерфейса Excel в невидимом режиме.

Современная альтернатива COM-объекту

Рассмотрим подробнее: стоит ли вообще использовать COM? Начиная с версии платформы 8.3.6, в 1С встроен мощный инструмент для работы с файлами Excel без установки самого офисного пакета. Это объект ТабличныйДокумент.

Разберем пример чтения файла современным способом:


ТабДок = Новый ТабличныйДокумент;
Попытка
    ТабДок.Прочитать(ИмяФайла, СпособЧтенияЛистовТабличногоДокумента.ЗагружатьЛистыПоОтдельности);
Исключение
    Сообщить("Ошибка чтения файла: " + ОписаниеОшибки());
    Возврат;
КонецПопытки;

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

Использование Прочитать() полностью исключает проблему «зависших» процессов, так как Excel вообще не запускается. Это работает быстрее, стабильнее и не требует лицензии Microsoft Office на сервере.

Подведем итоги: для стабильной работы необходимо избегать повторных инициализаций объектов в коде, всегда использовать Try...Finally (Попытка...Исключение) для гарантированного закрытия через Quit(), а в идеале — переходить на встроенные средства платформы 1С для работы с форматом XLSX.

← На главную