Как исправить ошибку открытия Excel регламентным заданием в 1С и настроить чтение файлов на сервере

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

Разберем типичную и крайне неприятную проблему, с которой часто сталкиваются разработчики при переносе кода из клиентского контекста на сервер. Ситуация стандартная: в тонком клиенте код импорта прайс-листов или любых других данных из Excel работает идеально, но при попытке запустить его в фоновом или регламентном задании (которое по определению выполняется на сервере) система выдает критическую ошибку.

Проанализируем текст ошибки, с которой столкнулся автор темы:

{ОбщийМодуль.ЗагрузкаПрайсов.Модуль(20)}: Ошибка при вызове метода контекста (ПолучитьCOMОбъект)... Ошибка получения объекта COM: -2147221018(0x800401E6): Расширение имени файла задано неверно

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

Причина возникновения ошибки 0x800401E6 (MK_E_INVALIDEXTENSION)

Давайте разберемся, почему операционная система Windows возвращает ошибку с кодом 0x800401E6 (в системных библиотеках она расшифровывается как MK_E_INVALIDEXTENSION — неверное расширение файла).

Когда мы вызываем метод ПолучитьCOMОбъект(ВременныйФайл), платформа 1С обращается к подсистеме OLE/COM операционной системы Windows. ОС пытается автоматически определить, какое приложение должно обработать этот файл. Для этого она считывает расширение файла и ищет его в системном реестре среди зарегистрированных ассоциаций файлов.

Если временный файл был создан с помощью стандартной функции ПолучитьИмяВременногоФайла() без указания конкретного расширения, платформа 1С по умолчанию генерирует имя со случайным набором символов и расширением .tmp. Поскольку расширение .tmp не связано ни с одним COM-сервером (и уж тем более с MS Excel), операционная система Windows выдает ошибку о неверном расширении файла и аварийно прерывает выполнение кода.

Способ 1. Быстрое исправление ошибки в исходном коде 1С

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

Вариант А: Явное указание расширения временного файла. При генерации имени временного файла методом ПолучитьИмяВременногоФайла() мы можем передать в качестве параметра желаемое расширение. Посмотрим на пример реализации:


ВременныйФайл = ПолучитьИмяВременногоФайла("xlsx"); // или "xls"
// Выполняем запись присланных двоичных данных во временный файл...
ДвоичныеДанныеФайла.Записать(ВременныйФайл);
Док = ПолучитьCOMОбъект(ВременныйФайл);

В этом случае операционная система сразу поймет, что файл с расширением .xlsx сопоставлен с приложением Microsoft Excel, и вызов метода ПолучитьCOMОбъект завершится успешно.

Вариант Б: Явное указание имени COM-класса. Функция ПолучитьCOMОбъект() принимает второй необязательный параметр — имя COM-класса. Если мы передадим его, операционная система не будет пытаться угадать программу по расширению файла. Проанализируем пример кода:


ВременныйФайл = ПолучитьИмяВременногоФайла(); // Будет расширение .tmp
// Записываем данные в файл...
ДвоичныеДанныеФайла.Записать(ВременныйФайл);
Док = ПолучитьCOMОбъект(ВременныйФайл, "Excel.Sheet");

Это заставит систему напрямую инициализировать объект Excel для обработки нашего файла, проигнорировав расширение .tmp.

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


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

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

Способ 2. Системная настройка DCOM на сервере приложений

Даже если мы исправим код и укажем верное расширение файла, запуск MS Excel регламентным заданием часто завершается другими системными ошибками. Причина кроется в том, что регламентные задания выполняются в фоновом режиме в контексте службы «Агент сервера 1С:Предприятия» под учетной записью (например, USR1CV8), у которой нет интерактивного сеанса пользователя.

Чтобы предоставить серверной службе возможность бесконфликтно использовать COM-объекты Microsoft Office, нам необходимо выполнить две системные настройки на сервере Windows.

Шаг 1: Создание системных папок Desktop. Приложения Microsoft Office жестко завязаны на наличие папки Рабочего стола (Desktop) в профиле пользователя, под которым они запускаются. Если этих папок в системе нет, Excel аварийно завершается. Нам необходимо вручную создать эти директории на сервере приложений:

  1. Для 64-битных операционных систем Windows: C:\Windows\SysWOW64\config\systemprofile\Desktop
  2. Для 32-битных операционных систем Windows: C:\Windows\System32\config\systemprofile\Desktop

После создания папок обязательно выдаем пользователю, под которым работает сервер 1С (например, USR1CV8 или NetworkService), полные права доступа (чтение и запись) на эти папки.

Шаг 2: Настройка службы компонентов DCOM. Нам потребуется настроить параметры безопасности для самого приложения Microsoft Excel через утилиту Windows. Разберем этот процесс по шагам:

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

Способ 3. Лучшее решение — полный отказ от COM в пользу встроенных механизмов 1С

Даже после выполнения всех настроек DCOM, использование MS Excel на стороне сервера — это крайне нестабильное и небезопасное архитектурное решение. Офисные приложения Microsoft никогда не проектировались для работы в многопоточном серверном режиме. Процессы EXCEL.EXE будут регулярно "зависать" в памяти сервера, забивать оперативную память и требовать постоянного перезапуска службы.

Более того, если ваша информационная база 1С развернута на облачном хостинге (например, популярном сервисе ServiceCloud, как у автора темы), у вас физически не будет прав администратора для установки Microsoft Office на сервер и настройки DCOM.

К счастью, начиная с версии платформы 1С:Предприятие 8.3.6, у нас больше нет никакой необходимости использовать COM-объекты для чтения или записи файлов Excel. Платформа умеет работать с форматами .xls, .xlsx и .ods напрямую на уровне собственного кроссплатформенного движка табличных документов.

Этот способ работает невероятно быстро, не требует установленного MS Office, не зависит от разрядности сервера (32/64 бит) и стабильно выполняется как под управлением Windows, так и под управлением операционных систем Linux.

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

Пример чтения файла Excel через Табличный Документ на сервере:


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

// Теперь мы можем обойти строки и колонки табличного документа в цикле
КоличествоСтрок = ТабДок.ВысотаТаблицы;
КоличествоКолонок = ТабДок.ШиринаТаблицы;

Для НомерСтроки = 2 По КоличествоСтрок Цикл // Предположим, что первая строка - это шапка таблицы
    Артикул = ТабДок.Область(НомерСтроки, 1).Текст;
    Наименование = ТабДок.Область(НомерСтроки, 2).Текст;
    Цена = ТабДок.Область(НомерСтроки, 3).Значение; // Извлекаем числовое значение напрямую
    
    Если ЗначениеЗаполнено(Артикул) Тогда
        // Выполняем обработку полученных данных прайс-листа
        // Например, поиск номенклатуры по артикулу и обновление цен
    КонецЕсли;
КонецЦикла;

Проанализируем ключевые преимущества этого подхода:

Мы подробно изучили проблему падения регламентных заданий при попытке работы с Excel. Мы выяснили, почему возникает ошибка неверного расширения файла и как исправить её в коде, а также разобрали тонкости настройки DCOM для сервера. Тем не менее, мы настоятельно рекомендуем отказаться от устаревшей технологии OLE/COM и перейти на использование встроенного объекта ТабличныйДокумент. Это сделает вашу систему надежной, масштабируемой и готовой к работе в любых современных облачных инфраструктурах.

← На главную