При переносе кода загрузки данных из Excel с клиентского компьютера или файловой базы на серверную версию «1С:Предприятия» разработчики часто сталкиваются с аппаратными и системными сбоями. Самый распространенный из них — критическая ошибка 0x80004002 (Интерфейс не поддерживается) при инициализации COM-объекта EXCEL.Application. В этой статье мы подробно разберем, почему возникает эта ошибка, как настроить системное окружение для работы с COM на сервере, а также изучим современный и надежный альтернативный подход — нативное чтение файлов Excel с помощью встроенного объекта ТабличныйДокумент без использования сторонних библиотек.
Попытка вызвать конструктор Новый COMОбъект("EXCEL.Application") в серверном контексте часто завершается аварийно. Рассмотрим основные технические причины этой проблемы:
USR1CV8). При старте через COM-соединение Excel пытается выполнить инициализацию рабочего стола для этого пользователя. Если папка рабочего стола физически отсутствует в профиле системной учетной записи, операционная система блокирует запуск Excel.EXCEL.EXE в оперативной памяти сервера, утечкам ресурсов и блокировкам файлов.Если вам обязательно нужно настроить работу через COM-объект на Windows-сервере, выполните следующие шаги по конфигурированию операционной системы.
Для исправления ошибки разрядности и прав выполним пошаговую настройку:
Шаг 1. Создание папок рабочего стола для системного профиля. Вам необходимо вручную создать папки Desktop в системных профилях Windows. Это решит проблему инициализации окружения Excel:
C:\Windows\System32\config\systemprofile\DesktopC:\Windows\SysWOW64\config\systemprofile\DesktopПосле создания папок обязательно предоставьте пользователю, от имени которого запущена служба сервера 1С (например, USR1CV8), полные права доступа (Чтение и Запись) на эти директории.
Шаг 2. Настройка компонента DCOM. Если разрядности сервера 1С и MS Excel не совпадают, стандартная консоль настройки компонентов не отобразит Microsoft Excel. Запустите специальную 32-битную версию консоли:
Win + R, введите команду mmc comexp.msc /32 и нажмите Enter.Несмотря на то, что эти настройки позволяют запустить COM-объект, такой метод остается нестабильным и платформозависимым. Он полностью неработоспособен, если ваш сервер 1С работает под управлением операционной системы Linux.
Платформа «1С:Предприятие 8» начиная с версии 8.3.6 умеет читать файлы форматов .xls, .xlsx и .ods напрямую на уровне платформы. Этот метод выполняется полностью в оперативной памяти, не требует установленного Microsoft Office на сервере, работает чрезвычайно быстро и поддерживается как на Windows, так и на Linux.
Проанализируем особенности работы метода Прочитать() объекта ТабличныйДокумент:
ТабличныйДокумент.Области по имени листа Excel.СпособЧтенияЗначенийТабличногоДокумента.Значение.Выясним, как правильно передавать файлы с клиента на сервер. Так как объект ТаблицаЗначений является мутабельным типом и недоступен на тонком клиенте, мы должны передать сам файл на сервер через временное хранилище, прочитать его там во временный табличный документ и сразу же обработать его данные.
Рассмотрим готовую схему асинхронного импорта файлов Excel на сервере без использования COM.
Код на стороне клиента:
&НаКлиенте
Процедура ЗагрузитьФайлExcel(Команда)
// Настраиваем диалог выбора файла
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.Фильтр = "Таблицы Excel (*.xlsx; *.xls)|*.xlsx;*.xls";
Диалог.МножественныйВыбор = Ложь;
Диалог.Заголовок = "Выберите файл для импорта";
ОписаниеОповещения = Новый ОписаниеОповещения("ПослеВыбораФайла", ЭтотОбъект);
Диалог.Показать(ОписаниеОповещения);
КонецПроцедуры
&НаКлиенте
Процедура ПослеВыбораФайла(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
Если ВыбранныеФайлы = Неопределено Или ВыбранныеФайлы.Количество() = 0 Тогда
Возврат; // Пользователь отменил выбор
КонецЕсли;
ПутьКФайлу = ВыбранныеФайлы[0];
ФайлНаКлиенте = Новый Файл(ПутьКФайлу);
// Подготавливаем структуру параметров для передачи на сервер
ПараметрыФайла = Новый Структура;
ПараметрыФайла.Вставить("ИмяФайла", ФайлНаКлиенте.Имя);
ПараметрыФайла.Вставить("Расширение", ФайлНаКлиенте.Расширение);
// Асинхронно помещаем файл во временное хранилище 1С
ОписаниеЗавершения = Новый ОписаниеОповещения("ПослеЗагрузкиФайлаВХранилище", ЭтотОбъект, ПараметрыФайла);
НачатьПомещениеФайлаНаСервер(ОписаниеЗавершения, , , , ПутьКФайлу, УникальныйИдентификатор);
КонецПроцедуры
&НаКлиенте
Процедура ПослеЗагрузкиФайлаВХранилище(Результат, АдресХранилища, ВыбранноеИмяФайла, ДополнительныеПараметры) Экспорт
Если Не Результат Тогда
ПоказатьПредупреждение(, "Не удалось загрузить файл во временное хранилище!");
Возврат;
КонецЕсли;
// Вызываем серверную процедуру для обработки файла
ОбработатьExcelНаСервере(АдресХранилища, ДополнительныеПараметры.Расширение);
ПоказатьОповещениеПользователя("Успешно", , "Загрузка данных из Excel завершена!");
КонецПроцедуры
Код на стороне сервера:
Для быстрого разбора полученного табличного документа в плоскую таблицу значений мы воспользуемся объектом ПостроительЗапроса. Он автоматически проанализирует колонки и строки области табличного документа и мгновенно выгрузит их в готовую коллекцию.
&НаСервере
Процедура ОбработатьExcelНаСервере(АдресХранилища, Расширение)
// Извлекаем двоичные данные из хранилища
ДвоичныеДанныеФайла = ПолучитьИзВременногоХранилища(АдресХранилища);
// Создаем временный файл на диске сервера с соответствующим расширением
ИмяФайлаНаСервере = ПолучитьИмяВременногоФайла(Расширение);
ДвоичныеДанныеФайла.Записать(ИмяФайлаНаСервере);
ТабличныйДокумент = Новый ТабличныйДокумент;
Попытка
// Читаем файл Excel напрямую, сохраняя типы данных ячеек
ТабличныйДокумент.Прочитать(ИмяФайлаНаСервере, СпособЧтенияЗначенийТабличногоДокумента.Значение);
Исключение
// Обязательно удаляем временный файл при ошибке
УдалитьФайлы(ИмяФайлаНаСервере);
ВызватьИсключение "Ошибка чтения файла платформой: " + ОписаниеОшибки();
КонецПопытки;
// Удаляем временный файл с диска сервера, так как он больше не нужен
УдалитьФайлы(ИмяФайлаНаСервере);
// Определяем заполненные границы табличного документа
ВсегоСтрок = ТабличныйДокумент.ВысотаТаблицы;
ВсегоКолонок = ТабличныйДокумент.ШиринаТаблицы;
Если ВсегоСтрок < 2 Тогда
Сообщить("Выбранный файл не содержит строк данных для обработки!");
Возврат;
КонецЕсли;
// Выделяем рабочую область (например, с 1 строки по колонку N)
ОбластьДанных = ТабличныйДокумент.Область(1, 1, ВсегоСтрок, ВсегоКолонок);
// Преобразуем табличный документ в ТаблицуЗначений с помощью ПостроителяЗапроса
Построитель = Новый ПостроительЗапроса;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ОбластьДанных);
Построитель.Выполнить();
ТаблицаДанных = Построитель.Результат.Выгрузить();
// Теперь переменная ТаблицаДанных содержит стандартную ТаблицуЗначений.
// Выполняем обход строк и создаем необходимые объекты в базе данных (например, Номенклатуру)
Для Каждого СтрокаТаблицы Из ТаблицаДанных Цикл
// Предположим, что в первой колонке Excel у нас наименование товара
НаименованиеТовара = СтрокаТаблицы.Колонка1;
Если ПустаяСтрока(НаименованиеТовара) Тогда
Продолжить;
КонецЕсли;
// Выполняем поиск или создание элемента справочника
НайденнаяСсылка = Справочники.Номенклатура.НайтиПоНаименованию(НаименованиеТовара, Истина);
Если НайденнаяСсылка.Пустая() Тогда
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
НовыйЭлемент.Наименование = НаименованиеТовара;
// Заполняем остальные реквизиты из других колонок...
НовыйЭлемент.Записать();
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Если вам необходимо предварительно показать пользователю считанные данные на клиенте перед их проведением, вы можете прочитать файл Excel в объект ТабличныйДокумент непосредственно на клиенте. Данный объект является мутабельным, но он разрешен для передачи между клиентским и серверным контекстом.
Посмотрим, как выглядит эта упрощенная схема:
&НаКлиенте
Процедура ЗагрузитьНаКлиентеБезХранилища(Команда)
ПутьКФайлу = "C:\Техн.xlsx";
ТабДок = Новый ТабличныйДокумент;
Попытка
ТабДок.Прочитать(ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Значение);
Исключение
Предупреждение("Не удалось прочитать файл локально: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
// Передаем готовый ТабличныйДокумент на сервер напрямую
ОбработатьТабДокНаСервере(ТабДок);
КонецПроцедуры
&НаСервере
БезКонтекста Процедура ОбработатьТабДокНаСервере(ТабличныйДокумент)
Построитель = Новый ПостроительЗапроса;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабличныйДокумент.Область());
Построитель.Выполнить();
ТаблицаДанных = Построитель.Result.Выгрузить();
// Обработка таблицы значений на сервере...
КонецПроцедуры
Перевод алгоритмов загрузки на встроенные механизмы чтения платформы «1С:Предприятие 8» обеспечивает ключевые преимущества для стабильности всей информационной системы:
Таким образом, использование метода ТабличныйДокумент.Прочитать() совместно с асинхронной передачей файлов во временное хранилище является наиболее современным стандартом разработки в экосистеме 1С для реализации механизмов интеграции и загрузки данных.