Как исправить ошибку загрузки из Excel в 1С и почему ТабличныйДокумент лучше COM-объекта?

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

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

Анализируем причину ошибки: почему Excel не открывается?

Рассмотрим ситуацию, когда при выполнении кода ЭксельКнига = Эксель.Workbooks.Open(ПутьКФайлу); система выдает исключение. Если код выполняется на стороне сервера, основной причиной является то, что Microsoft Excel — это интерактивное приложение, которое «ожидает» наличия пользовательского окружения (рабочего стола, временных папок профиля). Когда сервер 1С (служба USR1CV8) пытается запустить Excel в фоновом режиме, он не находит необходимых директорий и завершает работу с ошибкой.

Проанализируем основные факторы, блокирующие работу:

  1. Отсутствие папок Desktop: Для работы COM-объекта Excel требуются папки рабочего стола в профиле системного пользователя.
  2. Права доступа: Пользователь, под которым запущена служба сервера 1С, должен иметь полные права на чтение и запись в папку с файлом и во временные директории.
  3. Разрядность систем: Конфликт между 64-битным сервером 1С и 32-битным пакетом Microsoft Office.

Решение 1: Настройка серверного окружения для COM-объекта

Если вам критически важно использовать именно COM-соединение (например, для сложного форматирования или использования специфических макросов), выполним следующие шаги для настройки сервера.

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

После создания папок убедитесь, что пользователь USR1CV8 (или тот, под которым работает сервер 1С) имеет к ним полный доступ. Также рассмотрим настройку через Службы компонентов (DCOM). Найдите в списке Microsoft Excel Application, перейдите в свойства и на вкладке «Удостоверение» попробуйте установить переключатель в положение «Текущий пользователь» или укажите данные конкретной учетной записи администратора.

Решение 2: Использование COM-объекта в коде 1С

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


СтандартнаяОбработка = Ложь;
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.Заголовок = "Выбор файла Excel";
Диалог.Фильтр = "Excel файлы(*.xls;*.xlsx)|*.xls;*.xlsx";

Если Диалог.Выбрать() Тогда
    ПутьКФайлу = Диалог.ПолноеИмяФайла;
Иначе
    Возврат;
КонецЕсли;

Попытка
    // Пытаемся создать объект Excel
    Эксель = Новый COMОбъект("Excel.Application");
    Эксель.DisplayAlerts = 0; // Отключаем уведомления
    Эксель.Visible = 0;       // Делаем окно невидимым
Исключение
    Сообщить("Ошибка при запуске Excel: " + ОписаниеОшибки());
    Возврат;
КонецПопытки;

Попытка
    ЭксельКнига = Эксель.Workbooks.Open(ПутьКФайлу);
    Лист = ЭксельКнига.Sheets(1); // Работаем с первым листом
    
    // Определяем количество строк через SpecialCells(11) - это последняя ячейка
    КоличествоСтрок = Лист.Cells(1, 1).SpecialCells(11).Row;
    
    Для НомерСтроки = 1 По КоличествоСтрок Цикл
        // Читаем значения ячеек
        ЗначениеИНН = Лист.Cells(НомерСтроки, 1).Value;
        ЗначениеКПП = Лист.Cells(НомерСтроки, 2).Value;
        
        Если ЗначениеЗаполнено(ЗначениеИНН) Тогда
            НоваяСтрока = Объект.ТЧКлиенты.Добавить();
            НоваяСтрока.ИНН = СокрЛП(ЗначениеИНН);
            НоваяСтрока.КПП = СокрЛП(ЗначениеКПП);
        КонецЕсли;
    КонецЦикла;
    
    ЭксельКнига.Close(Ложь);
    Эксель.Quit();
Исключение
    Сообщить("Ошибка при чтении файла: " + ОписаниеОшибки());
    Эксель.Quit();
КонецПопытки;

Важный совет: Всегда используйте блоки Попытка ... Исключение и обязательно вызывайте Эксель.Quit(), иначе в памяти сервера будут накапливаться «зависшие» процессы excel.exe, что со временем приведет к сбою всей системы.

Решение 3: Загрузка через ТабличныйДокумент (Рекомендуемый способ)

Современная платформа 1С позволяет читать файлы Excel напрямую, без установленного Microsoft Office на компьютере или сервере. Этот метод гораздо быстрее, стабильнее и работает даже на серверах под управлением Linux. Проанализируем, как это реализовать.

Выясним преимущества этого метода: он не требует регистрации COM-компонентов и не зависит от прав доступа к системным профилям Windows. Мы читаем файл в объект ТабличныйДокумент, а затем преобразуем его в ТаблицаЗначений.


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

// 2. Определяем область данных (весь лист)
Область = ТабДок.Область(1, 1, ТабДок.ВысотаТаблицы, ТабДок.ШиринаТаблицы);

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

ТЗРезультат = Построитель.Результат.Выгрузить();

// 4. Загружаем данные в табличную часть объекта
// Важно: имена колонок в ТЗ будут Колонка1, Колонка2 и т.д.
Для Каждого СтрокаДанных Из ТЗРезультат Цикл
    НоваяСтрока = Объект.ТЧКлиенты.Добавить();
    ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаДанных, "ИНН, КПП");
    // Если имена колонок не совпадают, используем прямое присваивание:
    НоваяСтрока.ИНН = СтрокаДанных.Колонка1;
    НоваяСтрока.КПП = СтрокаДанных.Колонка2;
КонецЦикла;

Особенности загрузки в Табличную Часть

При работе с экранными формами начинающие разработчики часто совершают ошибку, пытаясь напрямую присвоить таблицу значений переменной табличной части: ТЧКлиенты = ТЗРезультат;. Рассмотрим, почему это не работает. В 1С табличная часть — это объект коллекции, и для работы с ней нужно использовать специальные методы.

Если вам нужно полностью заменить данные в табличной части, используйте метод Загрузить():


// Имена колонок в ТЗРезультат должны СТРОГО совпадать с именами колонок ТЧ
Объект.ТЧКлиенты.Загрузить(ТЗРезультат);

Если же вы хотите добавить данные к уже существующим, лучше использовать цикл с методом Добавить(), как показано в предыдущих примерах. Это позволит вам дополнительно валидировать данные (например, проверять ИНН на корректность) перед записью.

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

← На главную