Как исправить ошибку «Server Busy» при работе с Excel через COM-объект в 1С

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

При автоматизации выгрузки данных из 1С:Предприятия в формат Microsoft Excel разработчики часто используют COM-соединение через объект Excel.Application. Однако в серверных сценариях (особенно после обновлений операционной системы Windows Server или пакета Microsoft Office) этот механизм может внезапно дать сбой. Процессы EXCEL.EXE начинают бесконтрольно накапливаться в диспетчере задач сервера, а сама платформа 1С аварийно завершает работу или выводит неприятное системное окно Windows с заголовком «Server Busy» и текстом «Это действие не может быть выполнено, так как другое приложение занято».

В этой статье мы подробно разберем, почему возникает эта ошибка, проанализируем неочевидные системные причины ее появления в среде Windows Server и рассмотрим по шагам методы борьбы с зависанием процессов Excel. Также мы изучим современную и стабильную альтернативу использованию COM-объектов, которая работает на сервере в разы быстрее.

Выясняем техническую причину ошибки «Server Busy»

Для начала проанализируем ситуацию изнутри. Когда код в 1С инициализирует COM-сервер и пытается создать новую рабочую книгу, управление передается программному интерфейсу Microsoft Excel:


Эксель = Новый COMОбъект("Excel.Application");
Эксель.Visible = 0;    
Эксель.DisplayAlerts = 0;
Книга = Эксель.WorkBooks.Add(); // Именно здесь происходит зависание!

Окно «Server Busy» генерируется механизмом OLE/COM на уровне операционной системы Windows (через интерфейс IMessageFilter). В момент вызова метода Workbooks.Add() программа 1С отправляет запрос в COM-сервер Excel. Если Excel в этот момент занят внутренними вычислениями, обработкой фонового процесса или ожидает реакции пользователя (показывает скрытое модальное окно), он возвращает COM-клиенту статус «занят» (код ответа SERVERCALL_RETRYLATER). Операционная система Windows честно пытается повторить запрос в течение определенного тайм-аута (обычно около 8 секунд). Если ответа от Excel так и не поступает, ОС выводит пользователю предупреждение «Server Busy».

Давайте подробно рассмотрим основные триггеры, которые переводят невидимый процесс Excel в состояние бесконечного ожидания.

Решение 1. Отключение скрытых окон приветствия и активации Microsoft Office

Это наиболее частая причина сбоев после установки обновлений или первого развертывания системы на сервере. При запуске Excel пытается отобразить различные диалоговые окна:

Так как в коде 1С мы явно указываем Эксель.Visible = 0;, эти окна создаются в памяти Windows, но физически не отображаются на экране. Процесс Excel блокирует выполнение любых внешних команд и бесконечно ожидает, пока пользователь нажмет кнопку «Принять» или «Далее» в невидимом окне. В результате процесс «вешается», а в диспетчере задач начинают скапливаться сиротские процессы EXCEL.EXE.

Как решить эту проблему по шагам:

  1. Временный запуск в видимом режиме. На этапе отладки закомментируйте строку скрытия окна: замените Эксель.Visible = 0; на Эксель.Visible = 1;. При выполнении кода вы сразу увидите, какое именно модальное окно блокирует работу программы, и сможете закрыть его вручную.
  2. Интерактивная настройка под учетной записью службы. Подключитесь к серверу через RDP именно под той учетной записью, под которой запущена служба сервера 1С:Предприятия (например, USR1CV8). Запустите MS Excel вручную из меню «Пуск». Пройдите все стартовые диалоги, подтвердите лицензионное соглашение, закройте окно активации и убедитесь, что Excel открывается мгновенно и без лишних вопросов.
  3. Отключение стартовых экранов через реестр Windows. Можно принудительно запретить показ экранов приветствия. Для этого в ветке реестра пользователя службы 1С HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Common\General (версия 15.0 соответствует Office 2013) необходимо установить параметры типа DWORD ShownFirstRunOptin со значением 1 и OptIn со значением 0.

Решение 2. Создание системных папок Desktop (настройка окружения сервера)

Если служба сервера 1С:Предприятия работает под системной учетной записью (например, Network Service или Local System), графический движок Microsoft Excel при инициализации в фоновом режиме может вести себя некорректно. Для создания временных файлов при вызове метода Workbooks.Add() программе Excel жизненно необходимы папки рабочего стола в профиле системы. Если их нет, Excel генерирует скрытую внутреннюю ошибку и зависает.

Для решения этой системной проблемы выполните следующие действия:

  1. Зайдите на сервер с правами администратора.
  2. Проверьте наличие и при необходимости вручную создайте пустые папки Desktop по следующим путям:
    • Для 32-разрядных систем и 32-битного Office: C:\Windows\System32\config\systemprofile\Desktop
    • Для 64-разрядных систем (обязательно создайте в обеих директориях): C:\Windows\SysWOW64\config\systemprofile\Desktop
  3. Убедитесь, что у пользователя, от имени которого запущена служба сервера 1С (например, USR1CV8), есть полные права (Чтение, Запись, Изменение) на эти папки.

Решение 3. Проблема принтера по умолчанию на сервере

Малоизвестный, но крайне важный факт: при создании новой книги (метод Add()) или открытии существующей, Excel обращается к установленному в системе принтеру по умолчанию. Это требуется ему для правильного расчета разметки страниц, шрифтов, масштабирования и полей листа.

Если служба 1С работает под учетной записью, у которой не настроен принтер по умолчанию, либо если настроен сетевой принтер, который в данный момент недоступен, Excel уходит в длительный тайм-аут ожидания ответа от подсистемы печати Windows. Это гарантированно вызывает ошибку «Server Busy».

Решение проблемы с принтером:

Зайдите в систему под пользователем службы 1С и установите в качестве принтера по умолчанию локальный виртуальный принтер, не требующий сетевых запросов. Отлично подойдут стандартные «Microsoft Print to PDF» или «Microsoft XPS Document Writer». Никогда не оставляйте сетевые или физические принтеры по умолчанию для серверных учетных записей.

Решение 4. Написание надежного кода 1С с гарантированным закрытием процессов

Даже если системные ошибки устранены, некорректно написанный код в 1С может приводить к утечке памяти и постепенному накоплению десятков процессов EXCEL.EXE на сервере. Если лимит системных ресурсов будет исчерпан, новые процессы просто перестанут запускаться, вызывая ту самую ошибку занятости сервера.

Рассмотрим пример правильного написания кода с использованием конструкции Попытка — Исключение и обязательной очисткой памяти в блоке закрытия:


Эксель = Неопределено;
Книга = Неопределено;

Попытка
    Эксель = Новый COMОбъект("Excel.Application");
    Эксель.Visible = Истина; // Во время отладки ставим Истина, для продакшна - Ложь
    Эксель.DisplayAlerts = Ложь;
    
    Книга = Эксель.WorkBooks.Add();
    
    // Здесь выполняем полезную работу, например, заполняем ячейки
    Лист = Книга.WorkSheets(1);
    Лист.Cells(1, 1).Value = "Привет, коллеги!";
    
    // Сохраняем файл
    Книга.SaveAs("C:\temp\report.xlsx");
    
Исключение
    ЗаписьЖурналаРегистрации("ОшибкиЭкспорта", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
    Предупреждение("Произошла ошибка при работе с Excel: " + ОписаниеОшибки());
КонецПопытки;

// Раздел гарантированного уничтожения COM-объектов
Попытка
    Если Книга <> Неопределено Тогда
        Книга.Close(Ложь); // Закрываем без сохранения изменений, если уже сохранили ранее
    КонецЕсли;
КонецПопытки;

Попытка
    Если Эксель <> Неопределено Тогда
        // Проверяем, нет ли других открытых книг у пользователя
        Если Эксель.WorkBooks.Count() = 0 Тогда 
            Эксель.Quit();
        КонецЕсли;
    КонецЕсли;
КонецПопытки;

// Полностью освобождаем переменные в 1С
Книга = Неопределено;
Лист = Неопределено;
Эксель = Неопределено;

// Принудительно запускаем сборку мусора платформы 1С
ИнициализироватьВызовСистемногоСборщикаМусора();

Обратите внимание на явное присвоение переменным значения Неопределено в конце алгоритма. До тех пор, пока в памяти 1С удерживается хотя бы одна ссылка на любой дочерний объект Excel (будь то область ячеек Range, рабочий лист WorkSheet или сама книга Workbook), операционная система не сможет завершить процесс EXCEL.EXE, даже если вы вызвали метод Quit().

Решение 5. Современная альтернатива без использования COM (Native-подход)

Использование технологии OLE/COM на стороне сервера считается устаревшим, медленным и крайне небезопасным подходом. Сама компания Microsoft официально не рекомендует использовать пакет Office в неинтерактивных сессиях служб Windows (сервер 1С). Любое обновление безопасности может снова сломать интеграцию.

Давайте рассмотрим, как решить задачу записи формул и данных напрямую средствами платформы 1С:Предприятие 8.3, вообще не устанавливая Microsoft Excel на сервере.

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

Посмотрим на практический пример программного создания формул в 1С:


ТабДок = Новый ТабличныйДокумент;

// Заполняем исходные данные
ОбластьА1 = ТабДок.Область("R1C1");
ОбластьА1.Текст = 150; // Число в ячейке A1

ОбластьB1 = ТабДок.Область("R1C2");
ОбластьB1.Текст = 350; // Число в ячейке B1

// Прописываем формулу сложения в ячейку C1 (формат R1C1)
// Формула "RC[-2]+RC[-1]" означает: сложить значение ячейки на 2 столбца левее и на 1 столбец левее
ОбластьC1 = ТабДок.Область("R1C3");
ОбластьC1.Формула = "RC[-2]+RC[-1]"; 

// Сохраняем табличный документ напрямую в формат XLSX
ПутьКФайлу = "C:\temp\native_report.xlsx";
ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX);

Преимущества Native-подхода 1С:

Резюмируя: если вам досталось в наследство приложение с COM-интеграцией, в первую очередь проверьте наличие папок Desktop в профиле systemprofile, настройте локальный принтер по умолчанию и убедитесь в успешной активации пакета MS Office под учетной записью службы. Однако при проектировании новых интеграций и отчетов всегда отдавайте предпочтение штатным возможностям объекта ТабличныйДокумент платформы 1С.

← На главную