При разработке внешних обработок для загрузки данных часто начинают с жестко заданного пути к файлу в коде. Однако при переносе обработки на другой компьютер или при изменении каталога жесткая привязка приводит к сбоям. Разберем, как сделать выбор файла динамическим, связать его с реквизитом формы и устранить типичные ошибки, возникающие при открытии книги Excel через COM-соединение.
Чтобы путь к файлу можно было задавать интерактивно, перенесем его из жесткого кода в реквизиты внешней обработки. Проанализируем порядок действий:
ПутьКФайлу с типом данных Строка (длину рекомендуется установить не менее 255 символов, чтобы помещались длинные пути).НачалоВыбора для этого поля, чтобы вызывать стандартный системный диалог выбора файла.Посмотрим на пример кода клиентской процедуры выбора файла для управляемой формы:
&НаКлиенте
Процедура ПутьКФайлуНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Режим = РежимДиалогаВыбораФайла.Открытие;
Диалог = Новый ДиалогВыбораФайла(Режим);
Диалог.ПолноеИмяФайла = Объект.ПутьКФайлу;
Диалог.Фильтр = "Файлы Excel (*.xlsx;*.xls)|*.xlsx;*.xls|Все файлы (*.*)|*.*";
Диалог.Заголовок = "Выберите файл Excel для загрузки";
Если Диалог.Выбрать() Тогда
Объект.ПутьКФайлу = Диалог.ПолноеИмяФайла;
КонецЕсли;
КонецПроцедуры
Нередко после добавления реквизита разработчики сталкиваются с исключением: Ошибка при вызове метода контекста (Open): Типы не совпадают (0). Выясним основные причины этой ошибки:
"", Неопределено или Null. Метод Open библиотеки Excel ожидает непустую строку с корректным путем. При передаче пустого значения COM-сервер генерирует ошибку несовпадения типов.СокрЛП().WorkBooks.Open выполняется в серверном контексте (&НаСервере), сервер 1С не имеет доступа к локальному диску клиентской машины (например, C:\Users\...). Путь к файлу на клиенте не существует на сервере.Рассмотрим, как правильно организовать проверку пути и безопасное открытие книги Excel через COM:
&НаКлиенте
Процедура ЗагрузитьДанныеИзExcel()
// Проверяем заполнение пути
Если ПустаяСтрока(Объект.ПутьКФайлу) Тогда
Сообщить("Укажите путь к файлу перед загрузкой!");
Возврат;
КонецЕсли;
ФайлНаДиске = Новый Файл(Объект.ПутьКФайлу);
Если Не ФайлНаДиске.Существует() Тогда
Сообщить("Указанный файл не найден на диске: " + Объект.ПутьКФайлу);
Возврат;
КонецЕсли;
Попытка
ExcelПриложение = Новый COMОбъект("Excel.Application");
Исключение
Сообщить("Не удалось запустить Excel. Проверьте, установлено ли приложение на компьютере.");
Возврат;
КонецПопытки;
Попытка
// Отключаем экранные оповещения для ускорения работы
ExcelПриложение.DisplayAlerts = Ложь;
// Передаем явно приведенную и очищенную строку
ЧистыйПуть = СокрЛП(Строка(Объект.ПутьКФайлу));
Книга = ExcelПриложение.WorkBooks.Open(ЧистыйПуть);
Лист = Книга.Sheets(1);
// Чтение необходимых ячеек...
ЗначениеЯчейки = Лист.Cells(2, 1).Value;
// Корректное закрытие книги
Книга.Close(Ложь);
Исключение
Сообщить("Произошла ошибка при обработке файла Excel: " + ОписаниеОшибки());
КонецПопытки;
// Обязательно выгружаем процесс из оперативной памяти
ExcelПриложение.Quit();
ExcelПриложение = Неопределено;
КонецПроцедуры
Работа с COM-объектом Excel.Application имеет ряд существенных технологических ограничений, о которых важно помнить:
Quit() не будет вызван, процесс EXCEL.EXE останется висеть в памяти операционной системы. При множественных запусках это приводит к исчерпанию системных ресурсов. Блок выгрузки приложения всегда следует помещать так, чтобы он гарантированно отрабатывал.Для универсальной и быстрой загрузки файлов формата .xlsx и .xls платформа 1С предоставляет встроенный механизм, не требующий установки MS Excel и не зависящий от операционной системы. Разберем использование метода Прочитать() объекта ТабличныйДокумент:
&НаКлиенте
Процедура ПрочитатьБезCOM()
Если ПустаяСтрока(Объект.ПутьКФайлу) Тогда
Сообщить("Файл не выбран!");
Возврат;
КонецЕсли;
ТабДок = Новый ТабличныйДокумент;
Попытка
// Читаем файл напрямую средствами платформы 1С
ТабДок.Прочитать(Объект.ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Текст);
Исключение
Сообщить("Не удалось прочитать файл: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
КоличествоСтрок = ТабДок.ВысотаТаблицы;
КоличествоКолонок = ТабДок.ШиринаТаблицы;
// Обходим строки со второй, пропуская шапку
Для НомерСтроки = 2 По КоличествоСтрок Цикл
ТекстКолонки1 = ТабДок.ПолучитьОбласть(НомерСтроки, 1).Текст;
ТекстКолонки2 = ТабДок.ПолучитьОбласть(НомерСтроки, 2).Текст;
Если ПустаяСтрока(ТекстКолонки1) Тогда
Продолжить;
КонецЕсли;
// Обработка полученных значений
КонецЦикла;
КонецПроцедуры
Использование встроенного ТабличногоДокумента избавляет от проблем с разрядностью приложений, зависанием процессов EXCEL.EXE и ошибками несоответствия типов данных COM-библиотек.