Почему зависает или вылетает 1С при загрузке данных из Excel через COM-объект на сервере?

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

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

В этой статье мы проанализируем, почему создание объекта Excel.Application на стороне сервера является плохой практикой, выясним истинные причины зависаний и рассмотрим современную альтернативу, которая работает быстрее и стабильнее.

Причина зависания: почему COM-объект «молчит» на сервере?

Проанализируем ситуацию с технической точки зрения. Когда мы выполняем команду Excel = Новый COMОбъект("Excel.Application") в процедуре с директивой &НаСервере, происходит следующее:

  1. Отсутствие интерактивного рабочего стола. Сервер 1С:Предприятия работает как служба Windows, обычно от имени специальной учетной записи (например, USR1CV8). У этой службы нет графического интерфейса. Microsoft Excel же спроектирован как десктопное приложение. При запуске он может попытаться вывести окно приветствия, сообщение об активации, предложение восстановить файлы или предупреждение о безопасности. Поскольку «экрана» у службы нет, это окно зависает в невидимой области, ожидая нажатия кнопки «ОК» от пользователя, которого не существует.
  2. Проблемы прав DCOM. Даже если Excel установлен на сервере, у системной учетной записи 1С часто нет прав на запуск и активацию COM-компонентов Microsoft Office. Система безопасности Windows блокирует попытку, и процесс входит в бесконечный цикл ожидания ответа от подсистемы DCOM.
  3. Отсутствие профиля пользователя. Для инициализации Excel требуются определенные папки в профиле пользователя, в частности папка Desktop. Если сервер 1С запущен под системной учетной записью, этих папок по умолчанию нет в системных путях, что вызывает критический сбой.

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


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

Решение №1: Использование объекта ТабличныйДокумент (Рекомендуемое)

Начиная с версии платформы 8.3.6, у объекта ТабличныйДокумент появился мощный метод Прочитать(). Это решение является наиболее правильным, так как оно не требует установленного Microsoft Excel на сервере и работает напрямую с файловой структурой. Это избавляет нас от всех проблем с правами доступа и зависаниями интерфейса.

Рассмотрим, как реализовать загрузку через ТабличныйДокумент:


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

    // Определяем границы заполненной области
    ВсегоСтрок = ТабДок.ВысотаТаблицы;
    ВсегоКолонок = ТабДок.ШиринаТаблицы;

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

КонецПроцедуры

Преимущества этого метода очевидны: высокая скорость, отсутствие зависимости от стороннего ПО и стабильная работа в 64-битных версиях сервера 1С.

Решение №2: Настройка сервера для работы с COM (если COM необходим)

Если ваша задача требует специфических функций Excel (например, выполнение сложных макросов внутри файла или чтение свойств форматирования, которые не поддерживает ТабличныйДокумент), придется настраивать сервер. Выясним, как устранить ошибку APPCRASH и зависание.

Шаг 1. Создание системных папок. Выясним разрядность вашей операционной системы. Для корректной работы COM-объектов необходимо вручную создать папки Desktop по следующим путям:

Без наличия этих папок Excel часто завершается аварийно при попытке инициализации из-под службы.

Шаг 2. Настройка службы компонентов (DCOM). Запустите утилиту dcomcnfg. Перейдите в «Службы компонентов» — «Компьютеры» — «Мой компьютер» — «Настройка DCOM». Найдите в списке Microsoft Excel Application. В свойствах на вкладке «Безопасность» необходимо добавить пользователя, под которым работает сервер 1С (например, USR1CV8), и предоставить ему полные права на «Запуск и активацию».

Шаг 3. Соответствие разрядности. Если у вас установлен 64-битный сервер 1С, крайне желательно использовать 64-битную версию Microsoft Office. Использование 32-битного COM-объекта в 64-битном процессе 1С часто приводит к ошибкам в core83.dll из-за несовместимости адресного пространства памяти.

Решение №3: Перенос выполнения на сторону клиента

Если настройка сервера невозможна, а ТабличныйДокумент по каким-то причинам не подходит, проанализируем вариант выполнения кода &НаКлиенте. На компьютере пользователя Excel запускается в интерактивном сеансе, где у него есть доступ к графическому интерфейсу и правам текущего пользователя Windows.

Алгоритм действий будет следующим:

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

Пример реализации передачи данных:


&НаКлиенте
Процедура Загрузить(Команда)
    
    ДанныеДляЗагрузки = Новый Массив;
    
    // Работа с COM на клиенте
    Попытка
        Excel = Новый COMОбъект("Excel.Application");
        Книга = Excel.Workbooks.Open(ПутьКФайлу);
        Лист = Книга.Sheets(1);
        
        Для Стр = 1 По 100 Цикл // Пример для первых 100 строк
            СтруктураСтроки = Новый Структура("Артикул, Цена");
            СтруктураСтроки.Артикул = Лист.Cells(Стр, 1).Value;
            СтруктураСтроки.Цена = Лист.Cells(Стр, 2).Value;
            ДанныеДляЗагрузки.Добавить(СтруктураСтроки);
        КонецЦикла;
        
        Excel.Quit();
    Исключение
        Сообщить("Ошибка на клиенте: " + ОписаниеОшибки());
        Возврат;
    КонецПопытки;
    
    // Передаем массив на сервер
    ЗагрузитьДанныеНаСервере(ДанныеДляЗагрузки);
    
КонецПроцедуры

&НаСервере
Процедура ЗагрузитьДанныеНаСервере(МассивДанных)
    Для Каждого Строка Из МассивДанных Цикл
        // Поиск номенклатуры и установка цен в базе
    КонецЦикла;
КонецПроцедуры

Выводы и рекомендации

Подведем итог нашему анализу. Использование COMОбъект("Excel.Application") на стороне сервера — это устаревший метод, который несет в себе риски нестабильности всей системы 1С. В большинстве случаев ошибка core83.dll и зависания связаны именно с несовместимостью серверной среды и интерактивного приложения Microsoft Excel.

Рекомендованный путь развития:

Соблюдение этих правил позволит вам создавать надежные механизмы загрузки данных, которые не будут приводить к падению сервера и жалобам пользователей на «зависшую» программу.

← На главную