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

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

Чтение данных из внешних файлов Excel — одна из самых частых задач в практике разработчика 1С. Однако новички часто сталкиваются с ситуацией, когда код, написанный по всем правилам синтаксиса, выдает ошибку: «Ошибка при выполнении файловой операции». В этой статье мы подробно разберем, почему это происходит, проанализируем разницу в контекстах выполнения кода и рассмотрим несколько надежных способов загрузки данных из .xls и .xlsx.

Причина ошибки: разница между клиентом и сервером

Проанализируем типичную ситуацию. Программист пишет код на сервере, указывая путь к файлу, расположенному на рабочем столе его компьютера (например, C:\Users\home\Desktop\СписокКонтрагентов.xls). При запуске метода ТабДок.Прочитать() система выдает ошибку. Выясним причину этого сбоя.

Секрет кроется в физическом расположении ресурсов. Когда мы запускаем код в процедуре &НаСервере, он исполняется на компьютере, где установлена серверная часть 1С (кластер серверов). Для этого компьютера путь C:\Users\home\Desktop\... либо вообще не существует, либо ведет в папку «Рабочий стол» пользователя, под которым запущен сам сервер 1С (обычно это системная учетная запись USR1CV8), а не в папку пользователя на его локальном ПК.

Важно понимать: сервер 1С «не видит» локальные диски вашего рабочего компьютера напрямую. Он живет в своем собственном пространстве имен и путей.

Способ №1: Использование COM-объекта на стороне клиента

Если на рабочем месте пользователя установлен пакет Microsoft Office, мы можем использовать механизм COMОбъект. Этот метод позволяет запустить Excel в фоновом режиме на стороне клиента, открыть файл и прочитать его содержимое построчно. Рассмотрим пример кода:


&НаКлиенте
Процедура ПрочитатьФайлExcel(Команда)
    НомерЛистаExcel = 1;
    Попытка
        Excel = Новый COMОбъект("Excel.Application");
        // Открываем книгу. Путь берется из реквизита объекта на клиенте
        Excel.WorkBooks.Open(Объект.ПутьКФайлу);
        ExcelЛист = Excel.Sheets(НомерЛистаExcel);
    Исключение
        Сообщить("Ошибка при открытии Excel. Возможно, файл занят или Excel не установлен.");
        Возврат;
    КонецПопытки;

    // Определяем границы заполненной области
    ActiveCell = Excel.ActiveCell.SpecialCells(11);
    КоличествоСтрок = ActiveCell.Row;

    Для НомерСтроки = 2 По КоличествоСтрок Цикл
        НоваяСтрока = Объект.ДанныеФайла.Добавить();
        // Читаем значения из ячеек (строка, колонка)
        НоваяСтрока.Наименование = СокрЛП(ExcelЛист.Cells(НомерСтроки, 1).Text);
        НоваяСтрока.УНП = СокрЛП(ExcelЛист.Cells(НомерСтроки, 2).Value);
    КонецЦикла;

    // Обязательно закрываем приложение, чтобы процесс не висел в памяти
    Excel.Quit();
    Excel = 0;
КонецПроцедуры

Преимущества: Высокая гибкость, возможность работы с любыми форматами, которые поддерживает установленный Excel.

Недостатки: Низкая скорость работы на больших объемах данных, зависимость от установленного стороннего ПО (Excel должен быть на каждом компьютере пользователя).

Способ №2: Передача файла во временное хранилище (рекомендуемый метод)

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

  1. Сначала мы выбираем файл на клиенте и помещаем его во временное хранилище.
  2. Передаем адрес этого хранилища на сервер.
  3. На сервере извлекаем файл в локальную временную папку сервера.
  4. Читаем файл методом ТабличныйДокумент.Прочитать().

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

Использование параметра СпособЧтенияЗначенийТабличногоДокумента.Текст позволяет избежать проблем с неявным преобразованием типов, когда 1С пытается угадать формат данных в ячейке Excel.

Проблемы прав доступа и блокировок

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

1. Файл открыт в Excel.

Многие версии 1С не могут прочитать файл, если он заблокирован другой программой для редактирования. Убедитесь, что файл закрыт перед началом загрузки. Для проверки можно попробовать переименовать файл в Windows: если система не дает этого сделать, значит, файл занят процессом.

2. Права службы USR1CV8.

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

3. Формат файла.

Бывают случаи, когда файл имеет расширение .xls, но внутри представляет собой HTML-разметку или CSV. В таких ситуациях метод ТабличныйДокумент.Прочитать() может выдать ошибку. Выходом будет предварительное пересохранение файла в «честный» формат Excel (Книга Excel) или использование специализированных библиотек.

Особенности 64-битных систем

Если ваш сервер 1С имеет разрядность 64 бит, а вы пытаетесь использовать COMОбъект("Excel.Application"), может возникнуть ошибка «Класс не зарегистрирован». Это происходит потому, что 32-битные COM-компоненты Excel не могут быть напрямую вызваны 64-битным процессом сервера 1С. В этом случае единственным стабильным решением будет использование встроенного метода ТабличныйДокумент.Прочитать(), который не зависит от наличия установленного Excel на сервере, либо выполнение кода строго &НаКлиенте (где установлена 32-битная версия Office).

Подведем итог: для стабильной работы всегда старайтесь передавать файл через временное хранилище на сервер и использовать нативный объект ТабличныйДокумент. Это обеспечит максимальную производительность и независимость от настроек окружения на рабочих станциях пользователей.

← На главную