Как программно реализовать загрузку данных из Excel в 1С:Предприятие 8.3

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

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

Шаг 1: Подготовка интерфейса и выбор файла на клиенте

Прежде чем данные попадут в базу, нам нужно предоставить пользователю возможность выбрать файл на диске. Рассмотрим, как правильно настроить диалог выбора файла в управляемом приложении. Разберем пример создания процедуры ПутьКФайлуНачалоВыбора, которая будет срабатывать при нажатии на кнопку выбора в поле ввода.


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

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

Обратим внимание на важный нюанс: в управляемых формах работа с файловой системой напрямую возможна только на стороне клиента. Однако сама обработка данных должна происходить на сервере. Поэтому следующим этапом станет передача файла на сервер в виде двоичных данных.

Метод 1: Загрузка через COM-объект (Excel.Application)

Это «классический» способ, который использовался десятилетиями. Суть его заключается в том, что 1С запускает установленный в системе Microsoft Excel как внешнее приложение и управляет им через механизм COMОбъект. Рассмотрим пример загрузки справочника «Агенты».


&НаСервере
Процедура ЗагрузитьНаСервере(ДвоичДанные, Расширение)
    // Сохраняем полученные двоичные данные во временный файл на сервере
    ФайлЭксельНаСервере = ПолучитьИмяВременногоФайла(Расширение);
    ДвоичДанные.Записать(ФайлЭксельНаСервере);

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

    Попытка
        Книга = Эксель.Workbooks.Open(ФайлЭксельНаСервере);
        Лист = Книга.Sheets(1); // Работаем с первым листом
        
        // Определяем границы заполненной области
        ВсегоСтрок = Лист.Cells(1,1).SpecialCells(11).Row;
        
        // Начинаем перебор со второй строки (пропуская заголовок)
        Для СчетчикСтрок = 2 По ВсегоСтрок Цикл
            НаименованиеОрганизации = Лист.Cells(СчетчикСтрок, 1).Value;
            ИмяАгента = Лист.Cells(СчетчикСтрок, 2).Value;
            ФИО = Лист.Cells(СчетчикСтрок, 3).Value;

            // Поиск владельца (организации)
            ОрганизацияСсылка = Справочники.Организации.НайтиПоНаименованию(НаименованиеОрганизации);
            
            Если Не ОрганизацияСсылка.Пустая() Тогда
                НовыйАгент = Справочники.Агенты.СоздатьЭлемент();
                НовыйАгент.Владелец = ОрганизацияСсылка;
                НовыйАгент.Наименование = ИмяАгента;
                НовыйАгент.ФИО = ФИО;
                НовыйАгент.Записать();
            КонецЕсли;
        КонецЦикла;
        
        Книга.Close(Ложь);
    Исключение
        Сообщить("Ошибка при чтении файла: " + ОписаниеОшибки());
    КонецПопытки;

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

Важные недостатки этого метода: он требует наличия установленного Microsoft Office на том компьютере, где выполняется код (на сервере или клиенте). Кроме того, этот метод не будет работать, если сервер 1С работает под управлением ОС Linux.

Метод 2: Использование объекта ТабличныйДокумент (Рекомендуемый)

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

Рассмотрим, как реализовать чтение файла через этот механизм:


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

Этот способ является стандартом для современных конфигураций. Он избавляет от зависимости от стороннего ПО и работает значительно стабильнее в многопользовательской среде.

Шаг 3: Оптимизация записи и транзакции

Разберем типичную ошибку начинающих разработчиков: выполнение команды Записать() внутри цикла для каждой строки. Если в вашем файле 10 000 строк, 1С выполнит 10 000 отдельных обращений к базе данных, каждое из которых открывает новую транзакцию. Это крайне медленно.

Рассмотрим правильный подход с использованием транзакций:


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

Обертывание цикла в одну транзакцию ускоряет загрузку в десятки раз, так как база данных фиксирует изменения одним пакетом.

Особенности работы в Веб-клиенте

Если пользователи работают через браузер, классический ДиалогВыбораФайла и прямое создание ДвоичныеДанные по пути не сработают из-за ограничений безопасности браузера. В этом случае мы должны использовать метод НачатьПомещениеФайлаНаСервер(). Программа передаст файл во временное хранилище, вернет адрес, и уже этот адрес мы передадим в серверную процедуру для обработки.

Типизация данных и «пустые хвосты»

Проанализируем ситуацию, когда Excel хранит данные в неожиданных форматах. Например, числа могут считываться как строки с неразрывными пробелами (например, "1 500"), а даты — как внутренние числа Excel (количество дней с 1900 года).

  1. Очистка строк: Используйте функцию СтрЗаменить(Текст, Символы.НПП, "") для удаления неразрывных пробелов перед преобразованием строки в число.
  2. Проверка на заполненность: Всегда проверяйте ключевые колонки. Часто метод SpecialCells(11) в COM-объекте возвращает строку 5000, хотя данные заканчиваются на 100-й строке, просто в 5000-й когда-то стоял пробел или форматирование.
  3. Поиск объектов: Перед созданием нового элемента справочника всегда выполняйте поиск (по артикулу, коду или наименованию), чтобы избежать дублирования данных.

Подводя итог, можно сказать, что выбор метода загрузки зависит от окружения. Если вы гарантируете наличие Windows и Excel на сервере — COM-объект дает гибкость. Во всех остальных случаях — используйте ТабличныйДокумент или возможности Библиотеки стандартных подсистем (БСП), которые предоставляют готовые формы для сопоставления колонок и предварительного просмотра данных.

← На главную