Почему зависает загрузка из Excel на сервере 1С и как правильно импортировать данные

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

Разработка механизмов загрузки данных из внешних файлов — одна из самых частых задач программиста 1С. Однако многие сталкиваются с ситуацией, когда код, идеально работающий на клиенте, «намертво» зависает при попытке выполнить его на стороне сервера. Особенно часто это происходит при использовании COM-объекта Excel.Application.

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

Причины зависания COM-объекта на стороне сервера

Когда мы выполняем команду Новый COMОбъект("Excel.Application") на стороне сервера, система пытается запустить полноценное приложение Microsoft Excel в неинтерактивном сеансе. Разберем основные факторы, которые приводят к «зависанию» этого процесса:

  1. Отсутствие системных папок профиля: Это самая распространенная причина. Для инициализации COM-объекта Excel под учетной записью службы (например, USR1CV8), операционной системе требуются физические папки Desktop. Если их нет, процесс Excel запускается, но не может завершить инициализацию и «вечно» ждет доступа.
    • Для 64-битных систем создайте папку: C:\Windows\SysWOW64\config\systemprofile\Desktop
    • Для 32-битных систем создайте папку: C:\Windows\System32\config\systemprofile\Desktop
    Важно: После создания папок необходимо дать пользователю, от которого запущена служба 1С, полные права на эти директории.
  2. Интерактивные диалоговые окна: Excel может попытаться вывести сообщение о необходимости активации, предупреждение о безопасности или уведомление о поврежденном файле. В серверном сеансе нет пользователя, который мог бы нажать кнопку «ОК», поэтому процесс блокируется. Чтобы этого избежать, всегда используйте в коде:
    
    Excel = Новый COMОбъект("Excel.Application");
    Excel.DisplayAlerts = Ложь;
    Excel.Visible = Ложь;
    
  3. Разрядность систем: Если сервер 1С имеет разрядность 64 бита, а Microsoft Office установлен 32-битный, прямое обращение может работать некорректно. В таких случаях требуется настройка в консоли «Службы компонентов» (DCOM).

Альтернатива: Использование Табличного документа

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

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

Шаг 1. Передача файла с клиента на сервер

Для начала нам нужно выбрать файл на компьютере пользователя и поместить его во временное хранилище, чтобы сервер смог к нему обратиться.


&НаКлиенте
Процедура ЗагрузитьФайл(Команда)
    Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    Диалог.Фильтр = "Excel файлы (*.xls;*.xlsx)|*.xls;*.xlsx";
    
    Если Диалог.Выбрать() Тогда
        ОписаниеОповещения = Новый ОписаниеОповещения("ПослеПомещенияФайла", ЭтотОбъект);
        НачатьПомещениеФайла(ОписаниеОповещения, , Диалог.ПолноеИмяФайла, Ложь, УникальныйИдентификатор);
    КонецЕсли;
КонецПроцедура

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

Шаг 2. Чтение файла в Табличный документ на сервере

Теперь на сервере мы извлекаем данные из хранилища, записываем их во временный файл и считываем методом Прочитать().


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

Тонкости преобразования типов данных

Многие программисты жалуются, что при использовании ТабличногоДокумента все данные считываются как строки, и их сложно преобразовывать в числа или даты. Выясним, как решать эту проблему профессионально.

1. Проблема неразрывных пробелов. Часто в Excel числа отформатированы с разделителями разрядов. При чтении в 1С там оказывается символ с кодом 160 (неразрывный пробел). Функция Число() выдаст ошибку. Рассмотрим решение:


ТекстЯчейки = ТабДок.Область(НомерСтроки, 2).Текст;
// Удаляем неразрывные пробелы и обычные пробелы
ЧистоеЗначение = СтрЗаменить(ТекстЯчейки, Символы.НПП, "");
ЧистоеЗначение = СтрЗаменить(ЧистоеЗначение, " ", "");

Попытка
    Цена = Число(ЧистоеЗначение);
Исключение
    Цена = 0;
КонецПопытки;

2. Использование свойства «Значение». Вы можете попытаться получить типизированное значение напрямую, если в самом файле Excel ячейка имела правильный формат (Числовой или Дата). Для этого нужно проверить свойство СодержитЗначение.


ОбластьЯчейка = ТабДок.Область(НомерСтроки, 2);
Если ОбластьЯчейка.СодержитЗначение Тогда
    НужноеЗначение = ОбластьЯчейка.Значение; // Здесь уже может быть Тип("Число") или Тип("Дата")
Иначе
    НужноеЗначение = ОбластьЯчейка.Текст;
КонецЕсли;

Подведем итоги

Разберем, какой метод выбрать. Если вам нужно просто прочитать данные из таблицы, использование ТабличногоДокумента — лучший выбор. Он не зависит от установленного Microsoft Office, работает на Linux-серверах и не подвержен зависаниям из-за отсутствия папок профиля.

Если же стоит задача сложного форматирования Excel-файла (создание сводных таблиц, макросов, отрисовка сложных диаграмм), тогда придется использовать COM-объект. В этом случае обязательно проверьте наличие папок Desktop в системных профилях и установите права доступа для пользователя USR1CV8.

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

← На главную