Как исправить ошибку «Значение не является значением объектного типа (Close)» при импорте Excel в 1С?

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

При переходе с файлового режима работы базы данных на клиент-серверный (MSSQL) разработчики часто сталкиваются с тем, что привычный импорт данных из Excel перестает работать. Ошибка «Значение не является значением объектного типа (Close)» является лишь следствием того, что объект Excel.Application или его методы не инициализировались должным образом на стороне сервера. Проанализируем причины этой проблемы и разберем по шагам способы ее решения.

Почему возникает ошибка на методе Close?

Когда мы работаем в файловом режиме, код выполняется на стороне клиента под учетной записью текущего пользователя Windows. В клиент-серверном режиме процедура загрузки чаще всего переносится на сервер. Рассмотрим ситуацию: программа пытается открыть файл, но по какой-то причине (права доступа, отсутствие папок профиля, неверный путь) метод Open() не срабатывает. Если код не содержит должных проверок, программа идет дальше и пытается выполнить Excel.ActiveWorkbook.Close(). Поскольку рабочая книга не была открыта, ActiveWorkbook возвращает Неопределено, что и вызывает ошибку. Выясним, как это исправить.

Решение 1. Проблема путей и временного хранилища

Проанализируем ситуацию, описанную в сообщениях форума: клиент и сервер 1С находятся на разных машинах. Когда пользователь выбирает файл на своем компьютере (например, C:\Import\data.xlsx), и этот путь передается на сервер, сервер пытается найти этот файл у себя локально. Разумеется, файла там нет.

Правильный алгоритм работы в клиент-серверном режиме:

  1. На клиенте пользователь выбирает файл.
  2. Файл помещается во временное хранилище с помощью метода ПоместитьФайл() или ПоместитьФайлы().
  3. Адрес во временном хранилище передается на сервер.
  4. На сервере файл извлекается из хранилища во временный файл сеанса.
  5. Excel открывает этот временный файл, путь к которому понятен серверу.

Решение 2. Создание необходимых системных папок

Одной из самых «загадочных» причин сбоя COM-объектов Excel на сервере является отсутствие папок профиля для системной службы. Даже если Excel установлен, ему требуются папки Desktop для инициализации интерфейсов автоматизации. Рассмотрим, что нужно сделать:

Необходимо вручную создать папку Desktop по следующим путям (в зависимости от разрядности вашей системы и сервера 1С):

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

Решение 3. Настройка прав DCOM

Если создание папок не помогло, проанализируем настройки компонентов Windows. Сервер 1С обращается к Excel через механизм DCOM. Разберем процесс настройки:

  1. Нажмите Win+R, введите dcomcnfg и нажмите Enter.
  2. Перейдите в Службы компонентов -> Компьютеры -> Мой компьютер -> Настройка DCOM.
  3. Найдите в списке Microsoft Excel Application.
  4. В свойствах на вкладке «Безопасность» добавьте пользователя службы 1С в разделы «Права на запуск и активацию» и «Права на доступ».
  5. На вкладке «Удостоверение» иногда требуется выбрать «Текущий пользователь», но это зависит от конкретной конфигурации сервера.

Решение 4. Переход на нативное чтение Excel (рекомендуется)

Рассмотрим самый надежный способ, который избавляет от необходимости устанавливать Microsoft Office на сервер и мучиться с правами DCOM. Начиная с версии платформы 8.3.6, 1С умеет читать файлы Excel (xlsx) нативно через объект ТабличныйДокумент. Посмотрим на пример кода:


// Создаем объект табличного документа
ТабДок = Новый ТабличныйДокумент;

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

// Теперь мы можем работать с данными как с обычной таблицей 1С
Для НомерСтроки = 1 По ТабДок.ВысотаТаблицы Цикл
    Значение = ТабДок.Область(НомерСтроки, 1).Текст;
    // Обработка данных...
КонецЦикла;

Если ваш файл содержит несколько листов, мы можем проанализировать их следующим образом:


ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать(ИмяФайла, СпособЧтенияЗначенийТабличногоДокумента.Значение);

// Перебор именованных областей (листов)
Для Каждого ОбластьТД ИЗ ТабДок.Области Цикл
    Сообщить("Обработка листа: " + ОбластьТД.Имя);
    ТекущийЛист = ТабДок.ПолучитьОбласть(ОбластьТД.Имя);
    
    КоличествоСтрок = ТекущийЛист.ПолучитьРазмерОбластиДанныхПоВертикали();
    // Дальнейшая загрузка...
КонецЦикла;

Решение 5. Использование Построителя Запроса для быстрой выгрузки

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


ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать(ИмяФайла, СпособЧтенияЗначенийТабличногоДокумента.Значение);

ПЗ = Новый ПостроительЗапроса;
// Указываем область данных табличного документа как источник
ПЗ.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабДок.Область());
ПЗ.ЗаполнитьНастройки();
ПЗ.Выполнить();

// Получаем готовую таблицу значений
ТаблицаРезультат = ПЗ.Результат.Выгрузить();

Подведем итог: ошибка Close — это симптом «падения» Excel при открытии. Если вы можете отказаться от COM-объектов в пользу ТабличногоДокумента, сделайте это. Это повысит стабильность системы, уберет зависимость от установленного Office и решит проблемы с правами доступа в клиент-серверном режиме.

← На главную