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

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

Перенос внешних обработок из файлового варианта базы данных в клиент-серверный часто преподносит неприятные сюрпризы. Классический сценарий: обработка загрузки данных из Excel, которая годами отлично работала на локальном компьютере пользователя, при попытке выполнить её на сервере 1С просто «зависает» или завершается без видимых ошибок. При этом визуально ничего не происходит, а стандартная отладка «не заходит» в серверный код.

В этой статье мы подробно разберем, почему возникает эта проблема, как правильно настроить окружение сервера для работы с COM-объектами MS Office, и как полностью избавиться от этой зависимости, переписав код на современные нативные механизмы платформы 1С:Предприятие.

Выясняем причину: почему код «падает» на сервере

Давайте проанализируем исходный код серверной функции, предоставленный автором темы:


&НаСервере
Функция ВыполнитьЗагрузкуНаСервере(АдресХранения);
    Путь = КаталогВременныхФайлов + "temp1.xls";
    Файл = ПолучитьИзВременногоХранилища(АдресХранения);
    Файл.Записать(Путь);
    Попытка
        ОбъектExcel = Новый COMОбъект("Excel.Application");
    Исключение
        Возврат "Ошибка открытия MS Excel";
    КонецПопытки;
    ...
КонецФункции

В ходе обсуждения на форуме было установлено, что обработка прекращает свою работу именно на строке инициализации COM-объекта: Новый COMОбъект("Excel.Application").

Когда вы запускаете обработку на локальном компьютере (на клиенте), 1С работает под управлением вашей учетной записи Windows. У вас есть права администратора (или пользователя), запущен интерактивный сеанс, настроен профиль, и Excel без проблем открывается в фоновом режиме. Но как только выполнение переходит на сервер приложений 1С:Предприятия, ситуация кардинально меняется:

  1. Неинтерактивный режим: Служба сервера 1С (обычно под пользователем USR1CV8) работает в изолированном системном сеансе (Session 0). MS Excel изначально не проектировался для работы в качестве серверного компонента без пользовательского интерфейса. При запуске в неинтерактивной среде он часто блокируется операционной системой.
  2. Разрядность приложений (32-бит против 64-бит): Если ваш сервер 1С работает в 64-разрядном режиме (что стандартно для большинства современных СУБД), а на сервере установлен 32-битный Microsoft Office, то операционная система просто не сможет напрямую связать 64-битный процесс rphost.exe с 32-битным COM-сервером Excel.
  3. Отсутствие необходимых папок в профиле системы: Excel при инициализации требует физического наличия папки «Рабочий стол» (Desktop) внутри системного профиля пользователя, из-под которого запущена служба. У системного пользователя USR1CV8 этой папки по умолчанию нет.

Рассмотрим по шагам, как решить каждую из этих проблем.

Шаг 1. Включаем отладку на сервере 1С

Для того чтобы точно локализовать ошибку и видеть, что происходит в процедурах с директивой &НаСервере, нам необходимо активировать отладку на сервере приложений. Давайте разберем, как это сделать:

  1. Остановите службу 1C:Enterprise 8.3 Server Agent (Агент сервера 1С:Предприятия) через оснастку «Службы» (services.msc).
  2. Откройте редактор системного реестра Windows. Для этого нажмите сочетание клавиш Win + R, введите regedit и нажмите Enter.
  3. Перейдите по следующему пути (для версии 8.3):
    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\1C:Enterprise 8.3 Server Agent\]
    Примечание: Если вы используете другую версию платформы, имя ветки может незначительно отличаться.
  4. Найдите строковый параметр ImagePath. Он содержит команду запуска службы.
  5. Добавьте в самый конец этой строки флаг -debug.
    Пример до изменения:
    "C:\Program Files\1cv8\8.3.22.1709\bin\ragent.exe" -srvc -agent -regport 1541 -port 1540 -range 1560:1591 -d "C:\Program Files\1cv8\srvinfo"
    Пример после изменения:
    "C:\Program Files\1cv8\8.3.22.1709\bin\ragent.exe" -srvc -agent -regport 1541 -port 1540 -range 1560:1591 -d "C:\Program Files\1cv8\srvinfo" -debug
  6. Запустите службу сервера 1С заново.
  7. В Конфигураторе 1С перейдите в меню Отладка -> Подключение, найдите в списке доступных предметов отладки ваш серверный сеанс и нажмите Подключить.

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

Шаг 2. Решаем конфликт разрядности (32-bit и 64-bit)

Если на сервере установлен 64-битный сервер 1С и 32-битный Microsoft Office (или наоборот), вам необходимо настроить связь между ними на уровне системных служб компонентов DCOM.

Для настройки взаимодействия откройте консоль управления службами компонентов. Если у вас разная разрядность ПО, обычный запуск через dcomcnfg может не показать Microsoft Excel в списке. Поэтому запустите консоль принудительно в 32-битном режиме с помощью команды:

mmc comexp.msc /32

После открытия консоли выполните следующие действия:

  1. Перейдите в ветку: Службы компонентов -> Компьютеры -> Мой компьютер -> Настройка DCOM.
  2. Найдите в списке элемент Microsoft Excel Application (или Документ Microsoft Excel).
  3. Кликните по нему правой кнопкой мыши и выберите Свойства.
  4. На вкладке Удостоверение (Identity) вместо значения «Запускающий пользователь» выберите Указанный пользователь и пропишите туда данные учетной записи локального администратора сервера (или пользователя с полными правами) и его пароль. Это заставит систему всегда запускать Excel с необходимыми правами, игнорируя ограничения бесправной учетной записи USR1CV8.
  5. На вкладке Безопасность (Security) в разделах «Разрешения на запуск и активацию» и «Разрешения на доступ» выберите пункт «Настроить», добавьте пользователя службы сервера 1С (например, USR1CV8) и предоставьте ему полные права (Локальный запуск, Локальная активация).

Шаг 3. Создаем обязательные системные папки «Desktop»

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

Нам необходимо вручную создать эти папки на сервере приложений 1С. Создайте следующие каталоги в зависимости от архитектуры вашей операционной системы:

Для 64-разрядной операционной системы Windows:

  1. Создайте папку: C:\Windows\SysWOW64\config\systemprofile\Desktop
  2. Создайте папку: C:\Windows\System32\config\systemprofile\Desktop

Для 32-разрядной операционной системы Windows:

  1. Создайте папку: C:\Windows\System32\config\systemprofile\Desktop

Важно: После создания этих папок обязательно кликните по ним правой кнопкой мыши, перейдите в свойства безопасности и предоставьте учетной записи, под которой запускается сервер приложений 1С (например, USR1CV8 или Служба сетевого сервиса), права на чтение, запись и изменение данных в этих папках.

Шаг 4. Нативное чтение Excel через «ТабличныйДокумент» — лучший способ решения

Использование COM-объекта Excel.Application на стороне сервера 1С считается устаревшим и крайне нестабильным подходом. Процессы excel.exe часто зависают в оперативной памяти сервера, блокируют файлы, вызывают утечки памяти и требуют покупки дорогостоящих серверных лицензий Microsoft Office.

Начиная с версии платформы 8.3.6, в 1С встроен мощный и быстрый механизм прямого чтения файлов форматов XLS, XLSX, ODS напрямую без использования установленного Microsoft Office. Это работает в десятки раз быстрее и абсолютно стабильно на любом сервере (включая Linux-серверы!).

Давайте перепишем серверный метод автора темы, исключив использование COM-объектов. Мы будем использовать объект платформы ТабличныйДокумент.

Ниже представлен готовый пример безопасного и быстрого чтения файла Excel на сервере:


&НаСервере
Функция ВыполнитьЗагрузкуНаСервереНативно(АдресХранения)
    
    // Получаем файл из временного хранилища во временный каталог сервера
    ПутьКФайлу = КаталогВременныхФайлов() + ПолучитьУникальныйИдентификатор() + ".xlsx";
    ДвоичныеДанныеФайла = ПолучитьИзВременногоХранилища(АдресХранения);
    ДвоичныеДанныеФайла.Записать(ПутьКФайлу);
    
    // Создаем объект ТабличныйДокумент для чтения файла без Excel
    ТабДок = Новый ТабличныйДокумент;
    Попытка
        // Читаем файл. Платформа сама определит формат (XLS или XLSX)
        ТабДок.Прочитать(ПутьКФайлу, СпособЧтенияДвумерныхДанных.ИмяФормата);
    Исключение
        УдалитьФайлы(ПутьКФайлу);
        Возврат "Не удалось прочитать файл. Ошибка: " + ОписаниеОшибки();
    КонецПопытки;
    
    // Получаем размеры таблицы
    ВсегоСтрок = ТабДок.ВысотаТаблицы;
    ВсегоКолонок = ТабДок.ШиринаТаблицы;
    
    Если ВсегоСтрок < 2 Тогда
        УдалитьФайлы(ПутьКФайлу);
        Возврат "Файл пуст или содержит недостаточно данных для загрузки.";
    КонецЕсли;
    
    // Формируем структуру колонок по первой строке (заголовкам)
    СоответствиеКолонок = Новый Соответствие;
    Для НомерКолонки = 1 По ВсегоКолонок Цикл
        ИмяКолонки = СокрЛП(ТабДок.Область(1, НомерКолонки).Текст);
        Если ЗначениеЗаполнено(ИмяКолонки) Тогда
            СоответствиеКолонок.Вставить(ВРег(ИмяКолонки), НомерКолонки);
        КонецЕсли;
    КонецЦикла;
    
    // Обходим строки данных, начиная со 2-й строки
    Для НомерСтроки = 2 По ВсегоСтрок Цикл
        
        // Пример получения данных из конкретных колонок по их имени
        ИндексОС = СоответствиеКолонок.Получить(ВРег("Основное средство"));
        Если ИндексОС <> Неопределено Тогда
            ЗначениеОС = ТабДок.Область(НомерСтроки, ИндексОС).Текст;
        КонецЕсли;
        
        ИндексДата = СоответствиеКолонок.Получить(ВРег("Дата принятия к учету"));
        Если ИндексДата <> Неопределено Тогда
            ЗначениеДатыТекст = ТабДок.Область(НомерСтроки, ИндексДата).Текст;
            // Преобразуем текст в дату безопасным способом
        КонецЕсли;
        
        // Здесь выполняется логика создания документов и справочников, аналогичная исходному коду...
        // Например:
        // ДокОстаток = Документы.ВводНачальныхОстатковОС.СоздатьДокумент();
        // ... заполнение и запись объекта ...
        
    КонецЦикла;
    
    // Обязательно удаляем временный файл после завершения работы
    Попытка
        УдалитьФайлы(ПутьКФайлу);
    Исключение
        // Игнорируем ошибку удаления, если файл занят
    КонецПопытки;
    
    Возврат "Загрузка успешно завершена!";
    
КонецФункции

Подведем итоги

Мы подробно проанализировали системные проблемы, препятствующие нормальной работе COM-соединения с Excel на сервере 1С. Если архитектура вашего решения жестко требует использования именно Excel.Application, то обязательным условием является создание папок Desktop в профиле systemprofile и тонкая настройка прав пользователей в утилите dcomcnfg.

Тем не менее, в рамках стандартов разработки 1С мы настоятельно рекомендуем отказаться от использования внешних COM-библиотек в пользу встроенного метода ТабличныйДокумент.Прочитать(). Это сделает вашу обработку кроссплатформенной, повысит скорость выполнения операций загрузки в несколько раз и гарантированно убережет сервер приложений от зависших фоновых процессов Excel.

← На главную