Как организовать работу с Excel на сервере 1С и создавать многолистовые документы без OLE

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

Работа с файлами Microsoft Excel на стороне сервера 1С — это классическая задача, которая часто сопровождается трудностями. Основные проблемы возникают из-за различий в правах доступа, разрядности систем (x86 против x64) и ограничений самой службы сервера 1С, которая работает в неинтерактивном сеансе. Разберем подробно, почему возникают ошибки при использовании OLE, как правильно настроить сервер и какие современные альтернативы предлагает платформа 1С для создания сложных многолистовых книг Excel.

Проблема 1: Ошибки доступа и окружения при использовании OLE/COM

Когда мы запускаем код на клиенте, Excel открывается от имени текущего пользователя в его интерактивном окружении. На сервере же ситуация иная. Проанализируем основные причины отказа серверного кода:

  1. Учетная запись службы: Служба сервера 1С (обычно usr1cv8) не имеет прав на доступ к сетевым ресурсам или папкам других пользователей. Если ваш файл лежит по пути типа C:\Users\Admin\Desktop, сервер его просто не увидит.
  2. Отсутствие необходимых папок: Microsoft Excel для инициализации через COM-объект требует наличия определенных системных папок, которые по умолчанию отсутствуют у системных служб. Без них вызов Новый COMОбъект("Excel.Application") вернет ошибку.
  3. Сетевые пути: Использование логических дисков (например, Z:\) на сервере недопустимо. Необходимо использовать только UNC-пути вида \\ServerName\ShareName\File.xlsx.

Для исправления ситуации с OLE на сервере, в первую очередь, необходимо создать папки Desktop вручную. Рассмотрим пути для разных систем:

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

Решение 2: Использование Пакета отображаемых документов (Native 1С)

Наиболее надежный и современный способ создания многолистовых файлов Excel — использование встроенного объекта 1С ПакетОтображаемыхДокументов. Этот метод не требует установки Microsoft Excel на сервер и работает значительно быстрее. Проанализируем процесс создания файла по шагам.

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


// Создаем объект пакета
КнигаЭксель = Новый ПакетОтображаемыхДокументов;

// Формируем первый лист
ТабДок1 = Новый ТабличныйДокумент;
ТабДок1.Область("R1C1").Текст = "Это данные первого листа";
// Добавляем лист в пакет
НовыйЛист1 = КнигаЭксель.Состав.Добавить();
НовыйЛист1.Наименование = "Отчет по продажам"; // Имя листа в Excel
НовыйЛист1.Данные = ПоместитьВоВременноеХранилище(ТабДок1);

// Формируем второй лист
ТабДок2 = Новый ТабличныйДокумент;
ТабДок2.Область("R1C1").Текст = "Это данные второго листа";
// Добавляем второй лист
НовыйЛист2 = КнигаЭксель.Состав.Добавить();
НовыйЛист2.Наименование = "Аналитика";
НовыйЛист2.Данные = ПоместитьВоВременноеХранилище(ТабДок2);

// Записываем итоговый файл в формате XLSX
ПутьКФайлу = "C:\Temp\МноголистовойОтчет.xlsx";
КнигаЭксель.Записать(ПутьКФайлу, ТипФайлаПакетаОтображаемыхДокументов.XLSX);

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

Решение 3: Передача файлов между клиентом и сервером

Часто задача звучит так: "Пользователь выбирает файл на своем компьютере, а обработать его должен сервер". Выясним, как правильно организовать этот процесс без использования сетевых шар. Рассмотрим стандартную схему через временное хранилище:

  1. На клиенте пользователь выбирает файл, который считывается в ДвоичныеДанные.
  2. Файл помещается во временное хранилище, и адрес передается на сервер.
  3. На сервере данные извлекаются, сохраняются во временный файл через ПолучитьИмяВременногоФайла() и обрабатываются.

Пример реализации передачи файла для последующего чтения на сервере:


&НаКлиенте
Процедура ЗагрузитьФайл(Команда)
    Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    Если Диалог.Выбрать() Тогда
        ДанныеФайла = Новый ДвоичныеДанные(Диалог.ПолноеИмяФайла);
        АдресХранилища = ПоместитьВоВременноеХранилище(ДанныеФайла, УникальныйИдентификатор);
        ОбработатьФайлНаСервере(АдресХранилища);
    КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ОбработатьФайлНаСервере(АдресХранилища)
    Данные = ПолучитьИзВременногоХранилища(АдресХранилища);
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xlsx");
    Данные.Записать(ИмяВременногоФайла);
    
    // Теперь файл доступен серверу локально
    // Можно использовать ПакетОтображаемыхДокументов или ADO для чтения
    // ...
    УдалитьФайлы(ИмяВременногоФайла);
КонецПроцедуры

Оптимизация производительности и кэширование

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

Использование фоновых заданий: Не заставляйте пользователя ждать окончания формирования файла. Запустите ФоновыеЗадания.Выполнить(). Пока сервер формирует Excel, пользователь может продолжать работу. По окончании фонового процесса система может вывести оповещение.

Кэширование промежуточных результатов: Если одни и те же данные (листы для конкретных остановок) используются в разных отчетах, имеет смысл кэшировать их. Для этого подойдет таблица значений в реквизитах формы или специализированный регистр сведений. Вместо повторного формирования ТабличныйДокумент, мы просто извлекаем его из кэша и добавляем в новый ПакетОтображаемыхДокументов.

Посмотрим на пример кэширования сформированных листов в структуре:


&НаСервере
Функция СформироватьПакетСИспользованиемКэша(Маршруты)
    КнигаЭксель = Новый ПакетОтображаемыхДокументов;
    
    Для Каждого Маршрут Из Маршруты Цикл
        // Проверяем, есть ли уже готовый ТабДок в кэше (например, в Соответствии)
        Если Не Объект.КэшЛистов.Свойство(Маршрут.ID, ТекущийТабДок) Тогда
            ТекущийТабДок = СформироватьЛистМаршрута(Маршрут);
            Объект.КэшЛистов.Вставить(Маршрут.ID, ТекущийТабДок);
        КонецЕсли;
        
        НовыйЛист = КнигаЭксель.Состав.Добавить();
        НовыйЛист.Наименование = Маршрут.Имя;
        НовыйЛист.Данные = ПоместитьВоВременноеХранилище(ТекущийТабДок);
    КонецЦикла;
    
    Возврат КнигаЭксель;
КонецФункции

Итоги и рекомендации

Подводя итог, можно выделить следующие правила работы с Excel в 1С:

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

← На главную