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

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

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

Причина №1: Скрытые диалоговые окна и DisplayAlerts

Проанализируем ситуацию: когда мы открываем файл программно, Excel может посчитать, что в книгу были внесены изменения (даже если мы просто прочитали данные). При попытке закрыть книгу или приложение, Excel «хочет» спросить пользователя: «Сохранить изменения?». Но так как мы установили Visible = False, это окно остается невидимым. Процесс ждет ответа пользователя, который тот не может дать. В результате выполнение кода замирает на методе Close, либо метод отрабатывает, но процесс остается в памяти.

Для решения этой проблемы необходимо отключить вывод предупреждений сразу после создания объекта:


Excel = Новый COMОбъект("Excel.Application");
Excel.DisplayAlerts = 0; // Отключаем все диалоги и подтверждения

Это заставляет Excel принимать решение по умолчанию (обычно — закрытие без сохранения), не задавая вопросов. Как показывает практика, в 90% случаев именно эта строка решает проблему «висящих» процессов.

Причина №2: Неправильный порядок закрытия и очистки ссылок

Рассмотрим технический нюанс: COM-объект в 1С — это ссылка на внешний ресурс. Чтобы Windows позволила закрыть процесс, счетчик ссылок на него должен обнулиться. Если мы просто написали Excel.Quit(), но не очистили переменную в 1С, процесс может продолжать существовать.

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

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

Посмотрим на пример надежного кода:


Попытка
    Excel = Новый COMОбъект("Excel.Application");
    Excel.DisplayAlerts = 0;
    Книга = Excel.Workbooks.Open(ПутьКФайлу);
    
    // ... выполняем чтение данных ...
    
    Книга.Close(Ложь); // Параметр Ложь означает "закрыть без сохранения"
    Excel.Quit();
Исключение
    Сообщить("Ошибка при работе с Excel: " + ОписаниеОшибки());
    Если ЗначениеЗаполнено(Excel) Тогда
        Excel.Quit();
    КонецЕсли;
КонецПопытки;
Excel = Неопределено; // Обязательное обнуление ссылки

Причина №3: "Зависшие" ссылки на дочерние объекты

Выясним еще одну важную деталь. Если в процессе работы вы создавали переменные для листов или диапазонов (например, Лист = Книга.Worksheets(1) или Ячейка = Лист.Cells(1,1)), 1С удерживает ссылки на эти подобъекты. Пока жива переменная Ячейка, объект Excel.Application не будет уничтожен операционной системой, даже если вы вызвали Quit().

Важное правило: Старайтесь либо не создавать промежуточных переменных, обращаясь напрямую через цепочку (Excel.Workbooks(1).Worksheets(1).Cells(1,1).Value), либо явно обнуляйте все созданные переменные в обратном порядке: сначала ячейки, затем листы, затем книги.

Причина №4: Параметры открытия файла

Проанализируем параметры метода Open. Чтобы Excel вел себя максимально «тихо», рекомендуется открывать файлы в режиме «только чтение» и без обновления внешних ссылок. Это предотвращает появление лишних запросов со стороны системы.


// Путь, ОбновлениеСсылок (0 - нет), ТолькоЧтение (True)
Excel.Workbooks.Open(ПутьКФайлу, 0, Истина);

Альтернативный подход: Использование ADO

Если вам нужно только прочитать данные из файла .xls (старого формата), можно вообще избежать использования Excel.Application, обратившись к файлу как к базе данных через ADODB. Этот метод работает в разы быстрее и не создает процессов Excel.

Разберем пример реализации:


лРез = Новый COMОбъект("ADODB.Connection");
СтрокаПодключения = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source = " + ИмяФайла + "; Extended Properties = ""Excel 8.0;HDR=NO;IMEX=1"";";
Попытка
    лРез.Open(СтрокаПодключения);
    лНаборДанных = Новый COMОбъект("ADODB.RecordSet");
    лНаборДанных.Open("SELECT * FROM [Лист1$]", лРез);
    // Чтение данных через лНаборДанных...
    лРез.Close();
Исключение
    // Обработка ошибок
КонецПопытки;

Современный метод: Чтение через Табличный Документ

Начиная с платформы 8.3.6, в 1С появился встроенный механизм чтения файлов Excel без использования установленного Microsoft Office. Это самый стабильный способ, который мы рекомендуем использовать во всех новых разработках. Метод Прочитать объекта ТабличныйДокумент позволяет загрузить данные напрямую.


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

Этот метод полностью исключает проблему «зависших» процессов, так как Excel вообще не запускается. Однако он подходит только для чтения данных, а не для сложного форматирования или вызова макросов.

Специфика работы на сервере

Если ваш код выполняется на сервере (в фоновом задании), проверьте наличие папок Desktop. Это известная особенность Windows: для корректной работы COM-объекта Excel под системной учетной записью должны существовать следующие каталоги (даже если вы их не используете):

Без создания этих папок вручную Excel часто зависает при попытке инициализации или закрытия в сессии серверного процесса 1С.

Резюме

Для гарантированного отсутствия лишних процессов в системе, всегда придерживайтесь правила: отключайте алерты (DisplayAlerts = 0), открывайте файл только на чтение, явно вызывайте Quit и обнуляйте все переменные. Если же стоит задача простого импорта данных, отдавайте предпочтение встроенному методу ТабличныйДокумент.Прочитать() — это сэкономит вам массу времени на отладку серверных зависаний.

← На главную