К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как закрыть файл Excel из 1С

Как корректно закрыть файл Excel из 1С: методы Close и Quit, освобождение COM-объектов, завершение процесса EXCEL.EXE и решение проблемы зависших файлов.

Работа с Excel через COM-объекты — стандартный способ обмена данными между 1С и таблицами. Но если файл не закрыть правильно, процесс EXCEL.EXE остаётся висеть в памяти, файл блокируется для других пользователей, а при массовой обработке сервер 1С быстро исчерпывает ресурсы. Корректное закрытие — это не одна команда, а последовательность: закрыть книгу, завершить приложение, обнулить переменные.

Проблема обычно проявляется так: после обработки файла из 1С его нельзя удалить или переименовать, в диспетчере задач копятся процессы EXCEL.EXE, а повторное открытие того же файла выдаёт ошибку «файл занят». Причина почти всегда одна — объектная переменная Excel.Application не была завершена методом Quit или потерялась раньше времени из-за исключения в коде.

Ниже разобраны все рабочие способы закрытия файла Excel из 1С: от штатного закрытия книги до аварийного снятия процесса, а также типовые ошибки, из-за которых файлы «зависают».

Как устроено взаимодействие 1С и Excel через COM

1С обращается к Excel через COM-интерфейс: создаётся объект Excel.Application, через него открывается книга Workbooks.Open(), далее идёт чтение или запись данных. Пока существует хотя бы одна живая ссылка на любой из этих объектов, процесс Excel продолжает работать — даже если окна не видно.

Важно понимать иерархию: Application (приложение) → Workbooks (коллекция книг) → Workbook (книга) → Sheets (листы). Закрывать нужно в обратном порядке — сначала книгу, потом приложение. Если вызвать только Quit без Close, Excel может запросить сохранение изменений и «повиснуть» в ожидании невидимого диалога.

Штатное закрытие книги и приложения

Базовый сценарий выглядит так: после завершения работы с данными вызывается метод Close у книги, затем Quit у приложения. Параметр Ложь в Close означает «не сохранять изменения» — это важно, если файл открывался только для чтения.

Excel = Новый COMОбъект("Excel.Application");

Excel.Visible = Ложь;

Excel.DisplayAlerts = Ложь;

Книга = Excel.Workbooks.Open("C:\Данные\Отчет.xlsx");

// ... чтение данных ...

Книга.Close(Ложь);

Excel.Quit();

Книга = Неопределено;

Excel = Неопределено;

Строка Excel.DisplayAlerts = Ложь отключает диалоговые окна Excel. Без неё при попытке закрыть изменённую книгу Excel покажет запрос «Сохранить изменения?», который никто не увидит (окно скрыто), и процесс зависнет навсегда. Это самая частая причина «залипших» процессов EXCEL.EXE.

Обнуление переменных (= Неопределено) освобождает COM-ссылки со стороны 1С. Формально сборщик мусора сделает это сам, но на практике освобождение может затянуться, и файл останется заблокированным ещё несколько минут после окончания процедуры.

Правильная последовательность закрытия
  1. 1
    Установите Excel.DisplayAlerts = Ложь до начала работы
  2. 2
    Завершите все операции чтения/записи с книгой
  3. 3
    Вызовите Книга.Close(Ложь) — или Close(Истина), если нужно сохранить
  4. 4
    Вызовите Excel.Quit() для завершения приложения
  5. 5
    Присвойте обеим переменным значение Неопределено
  6. 6
    Проверьте в диспетчере задач, что процесс EXCEL.EXE завершился

Закрытие с сохранением изменений

Если 1С формирует файл и нужно сохранить результат, есть два пути. Первый — явный вызов Книга.Save() или Книга.SaveAs(Путь) перед закрытием, затем Книга.Close(Ложь). Второй — Книга.Close(Истина), который сохраняет изменения при закрытии. Первый вариант предпочтительнее: он даёт контроль над именем файла и форматом.

При SaveAs в существующий файл Excel выдаст запрос на перезапись — снова спасает DisplayAlerts = Ложь. Также учтите: если файл открыт другим пользователем по сети, сохранение завершится ошибкой, и без обработки исключения процедура прервётся до вызова Quit, оставив процесс висеть.

Попытка

Книга.SaveAs(ИмяФайлаРезультата);

Исключение

Сообщить("Не удалось сохранить файл: " + ОписаниеОшибки());

КонецПопытки;

Книга.Close(Ложь);

Excel.Quit();

Защита от зависших процессов: Попытка...Исключение

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

Excel = Новый COMОбъект("Excel.Application");

Excel.DisplayAlerts = Ложь;

Попытка

Книга = Excel.Workbooks.Open(ИмяФайла);

// ... обработка ...

Книга.Close(Ложь);

Исключение

Сообщить(ОписаниеОшибки());

Попытка

Книга.Close(Ложь);

Исключение

КонецПопытки;

КонецПопытки;

Excel.Quit();

Excel = Неопределено;

Обратите внимание: Quit вызывается вне блока Попытка, поэтому приложение завершится в любом случае. Вложенная Попытка вокруг Close в секции Исключение нужна на случай, если книга так и не была открыта — тогда переменная Книга не определена, и обращение к ней вызовет новую ошибку.

Аварийное завершение зависшего процесса Excel

Если процесс EXCEL.EXE уже завис и файл заблокирован, штатные методы не помогут — ссылка на объект потеряна. Остаётся завершить процесс операционной системой. Вручную это делается через диспетчер задач: вкладка «Процессы» или «Подробности» → EXCEL.EXE → «Снять задачу».

Из командной строки или пакетного сценария используется taskkill:

cmd
taskkill /F /IM EXCEL.EXE

Ключ /F принудительно завершает процесс, /IM задаёт имя образа. Команда снимает все экземпляры Excel сразу, поэтому на сервере 1С, где обработки выполняются автоматически и никто не работает с Excel вручную, её иногда добавляют в регламентное обслуживание. На пользовательских машинах так делать нельзя.

Более аккуратный вариант — перезапуск службы агента сервера 1С, если зависший процесс принадлежит ему, либо настройка отдельной учётной записи для COM-вызовов, чтобы зависшие процессы можно было отличить от пользовательских.

Способы закрытия файла

Close + Quit в коде

Штатный и единственно правильный способ. Требует, чтобы переменные не потерялись до конца процедуры.

Обнуление переменных без Quit

Процесс завершится, когда сборщик мусора освободит ссылки. Ненадёжно: файл может оставаться заблокированным минутами.

taskkill /F /IM EXCEL.EXE

Аварийный вариант для зависших процессов. Закрывает все окна Excel, включая открытые пользователями документы.

Типичные ошибки и их последствия

Большинство проблем с незакрывающимися файлами сводится к нескольким повторяющимся ошибкам в коде и организации обмена.

Типичные ошибки
01
Не установлен DisplayAlerts = Ложь — Excel ждёт ответа на невидимый диалог и процесс висит бесконечно
02
Вызов только Quit без Close — при наличии несохранённых изменений приложение не завершается
03
Переменная Excel объявлена локально внутри Попытка, а Quit вызывается снаружи — при ошибке ссылка теряется
04
Промежуточные объекты вида Excel.Workbooks(1).Sheets(1).Cells(1,1) создают скрытые COM-ссылки, которые не освобождаются — разбивайте цепочки на отдельные переменные
05
Цикл обработки сотен файлов без Close внутри цикла — память растёт, сервер падает

Отдельно стоит сказать про «цепочечные» обращения вроде Excel.ActiveWorkbook.ActiveSheet.Cells(1,1).Value. Каждое звено такой цепочки создаёт промежуточный COM-объект, на который в 1С нет именованной ссылки. Эти объекты держат процесс Excel живым даже после Quit. Правильный приём — сохранять каждый уровень в отдельную переменную и обнулять их все в конце.

Проверка результата и альтернативы COM

После доработки кода проверьте результат: запустите обработку, дождитесь завершения и откройте диспетчер задач. Процессов EXCEL.EXE, запущенных обработкой, быть не должно. Затем попробуйте переименовать или удалить обработанный файл — если операция проходит, блокировок нет.

Контрольные точки

Как проверить результат

Процесс EXCEL.EXE в диспетчере задач
Норма

Процесс исчезает сразу после окончания обработки

Тревожный признак

Процессы накапливаются с каждым запуском

Доступность файла
Норма

Файл удаляется и переименовывается без ошибок

Тревожный признак

Ошибка «файл используется другой программой»

Повторный запуск обработки
Норма

Файл открывается повторно без ошибок

Тревожный признак

Ошибка открытия или файл открывается в режиме чтения

Если COM-подход доставляет постоянные проблемы, рассмотрите альтернативы. Для чтения xlsx без установленного Excel используют построитель DOM или сторонние библиотеки, работающие с форматом Open XML напрямую — xlsx-файл это zip-архив с XML внутри. Для выгрузки из 1С табличный документ сохраняется методом Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX) вообще без участия Excel. Эти способы не создают процессов и не требуют закрытия файлов.

Итог

Что важно запомнить

Закрытие Excel из 1С — это всегда три шага: Close для книги, Quit для приложения, обнуление переменных. DisplayAlerts = Ложь обязателен, иначе процесс зависнет на невидимом диалоге. Код закрытия размещайте так, чтобы он выполнился и при ошибке. Зависшие процессы снимайте taskkill только там, где Excel не используется людьми.

Частые вопросы

Файл закрывается, но процесс EXCEL.EXE остаётся в диспетчере задач. Почему?

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

Можно ли закрыть конкретный файл, если открыто несколько книг?

Да. Метод Close вызывается у конкретного объекта книги: Excel.Workbooks("ИмяФайла.xlsx").Close(Ложь). Остальные книги и само приложение при этом продолжат работать. Quit завершает приложение целиком со всеми книгами.

Как закрыть файл Excel, открытый другим пользователем по сети?

Из 1С это невозможно — COM управляет только тем экземпляром Excel, который создала сама 1С. Чужой сеанс закрывает либо сам пользователь, либо администратор через управление открытыми файлами на файловом сервере. Принудительный сброс чужой сессии может привести к потере несохранённых данных.

Работает ли закрытие через COM на сервере 1С под Linux?

Нет. COM-технология существует только в Windows. На Linux-сервере для работы с xlsx используют сохранение табличного документа через Записать() или разбор файла как zip-архива средствами 1С — в этих сценариях вопрос закрытия процесса Excel не возникает в принципе.

Что передать в Close, чтобы Excel не спрашивал о сохранении?

Передайте Ложь — изменения будут отброшены без вопросов, или Истина — изменения сохранятся. Дополнительно заранее установите Excel.DisplayAlerts = Ложь, чтобы подавить любые диалоги, включая запросы о перезаписи существующего файла при SaveAs.

Безопасно ли добавлять taskkill /F /IM EXCEL.EXE в регламентное задание?

Только на выделенном сервере, где Excel используется исключительно автоматическими обработками 1С и никто не работает с таблицами вручную. На терминальном сервере или рабочей станции команда закроет документы пользователей без сохранения. Правильнее исправить код обработки, чем маскировать проблему периодическим снятием процессов.