Написал код, запустил — окно Word мелькнуло и пропало. Или вообще не открылось, но файл почему-то изменился. Или открылось, но 1С завис в ожидании чего-то, и пришлось убивать процесс. COM-автоматизация Word из 1С — это один из тех углов платформы, где интуиция подводит почти всегда. Поведение зависит от десятка параметров, которые нигде не описаны вместе.
Корень проблемы: кто владеет объектом
Когда ты пишешь СоздатьОбъект("Word.Application"), 1С создаёт COM-объект и держит на него ссылку. Но Word как приложение имеет собственный жизненный цикл. Если ты не сделал его видимым явно, Word работает в фоновом режиме — без окна, без сообщений пользователю. При этом он всё равно может отображать диалоги (например, «Сохранить изменения?»), которые ты не видишь и не можешь закрыть.
Самое частое: код заканчивается, переменная выходит из области видимости, 1С вызывает деструктор COM-объекта — и Word закрывается, не спросив, сохранять ли документ. Если файл был открыт на запись, он или не сохранится, или сохранится в неполном состоянии.
Правильная структура кода
Перем ПриложениеWord;
Перем Документ;
Попытка
ПриложениеWord = СоздатьОбъект("Word.Application");
ПриложениеWord.Visible = Истина; // показываем окно явно
ПриложениеWord.DisplayAlerts = 0; // wdAlertsNone — убираем диалоги
Документ = ПриложениеWord.Documents.Open(ПутьКФайлу);
// ... работа с документом ...
Документ.Save();
Документ.Close(0); // 0 = wdDoNotSaveChanges — не спрашиваем про сохранение
Исключение
Сообщить("Ошибка: " + ОписаниеОшибки());
КонецПопытки;
// Явно закрываем приложение ПОСЛЕ работы с документом
Если ПриложениеWord <> Неопределено Тогда
ПриложениеWord.Quit();
ПриложениеWord = Неопределено;
КонецЕсли;
Три ключевых момента: Visible = Истина (иначе Word-процесс висит невидимым и может накапливаться), DisplayAlerts = 0 (иначе документ застревает на невидимом диалоге), явный Quit() в конце (иначе процесс WINWORD.EXE остаётся в памяти).
Почему документ «мелькает» и закрывается
Это классика: Visible = Истина, но Quit() вызывается до того, как пользователь что-то сделал. Типичная структура с багом:
// НЕПРАВИЛЬНО
Word = СоздатьОбъект("Word.Application");
Word.Visible = Истина;
Документ = Word.Documents.Open(Путь);
// ... код заканчивается, Word уничтожается
Если цель — показать документ пользователю и не закрывать его немедленно, нужно либо не вызывать Quit() вообще (пользователь закрывает сам), либо дождаться закрытия через цикл проверки:
// Ждём, пока пользователь закроет документ
Пока ПриложениеWord.Documents.Count > 0 Цикл
ОбработкаПрерыванияПользователя();
КонецЦикла;
Скрытые диалоги — самая коварная проблема
DisplayAlerts = 0 убирает большинство диалогов Word, но не все. Диалог «Файл заблокирован другим пользователем» или «Документ содержит макросы» может всё равно появиться. На сервере это катастрофа: WINWORD.EXE висит и ждёт клика, которого никогда не будет.
Для серверной автоматизации (фоновые задания, регламентные операции) COM-автоматизация Word — плохой выбор. Используй вместо этого:
- OpenDocumentFormat через пакет XML — 1С умеет работать с .docx как с ZIP напрямую, без Word
- Шаблоны с заполнением через XML — надёжнее и быстрее в 10 раз
- Сторонние компоненты типа Aspose.Words или LibreOffice в headless-режиме
Если без COM не обойтись (например, сложное форматирование или макросы), запускай его только в клиентском коде, а на сервере никогда.
Если проблема не воспроизводится у тебя локально, но ломается на сервере — проверь, под каким пользователем запущен агент сервера 1С: COM-объекты Word требуют, чтобы у пользователя была настроена интерактивная сессия Windows. Сервисный аккаунт без профиля просто не умеет запускать Word.