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

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

Задачи по обмену данными между 1С и внешними файлами, такими как Excel, являются одними из самых распространенных в практике разработчика. Рассмотрим ситуацию, когда нам необходимо дополнить существующий справочник ФизЛица новыми данными (например, идентификаторами пропусков), хранящимися в стороннем файле. Мы разберем по шагам, как организовать выбор файла, его чтение на сервере и корректную запись информации в базу данных.

Шаг 1. Организация выбора файла на клиенте

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

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


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

    ОписаниеОповещения = Новый ОписаниеОповещения("ПослеВыбораФайла", ЭтотОбъект);
    НачатьВыборФайла(ОписаниеОповещения, ПараметрыДиалога);
КонецПроцедуры

&НаКлиенте
Процедура ПослеВыбораФайла(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
    Если ВыбранныеФайлы <> Неопределено Тогда
        Объект.ПутьКФайлу = ВыбранныеФайлы[0];
    КонецЕсли;
КонецПроцедуры

В данном коде мы используем ПараметрыДиалогаВыбораФайла и НачатьВыборФайла. Это позволяет избежать блокировки интерфейса и соответствует актуальным стандартам разработки 1С.

Шаг 2. Передача файла на сервер и чтение данных

Поскольку сама база данных находится на сервере, а файл — на локальном компьютере пользователя, нам нужно передать данные во временное хранилище. Рассмотрим механизм чтения файла без использования COM-объектов (что позволяет обработке работать даже если на сервере не установлен Microsoft Excel).

Выясним, как прочитать данные через ТабличныйДокумент. Этот метод универсален и работает быстрее классического COM-соединения.


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

    КоличествоСтрок = ТабДок.ВысотаТаблицы;
    
    // Предположим, что в Excel: Колонка 1 - ФИО, Колонка 2 - ТабНомер, Колонка 3 - Идентификатор
    Для НомерСтроки = 2 По КоличествоСтрок Цикл // Начинаем со 2-й строки, пропуская заголовок
        
        ТабельныйНомер = СокрЛП(ТабДок.Область(НомерСтроки, 2).Текст);
        ИдентификаторПропуска = СокрЛП(ТабДок.Область(НомерСтроки, 3).Текст);
        
        Если ПустаяСтрока(ТабельныйНомер) Тогда
            Продолжить;
        КонецЕсли;
        
        ОбновитьИдентификаторФизЛица(ТабельныйНомер, ИдентификаторПропуска);
        
    КонецЦикла;
    
    // Удаляем временный файл после обработки
    УдалитьФайлы(ИмяВременногоФайла);
КонецПроцедуры

Важный момент: использование СокрЛП() критично при чтении из Excel, так как в ячейках часто присутствуют невидимые пробелы, которые могут помешать поиску в базе данных 1С.

Шаг 3. Поиск и обновление объекта в справочнике

Теперь проанализируем ситуацию, как найти нужное физическое лицо. В учебном задании поиск удобнее всего производить по реквизиту ТабНомер. Если мы найдем элемент, нам нужно получить его Объект, изменить реквизит и записать изменения.


&НаСервере
Процедура ОбновитьИдентификаторФизЛица(ТабельныйНомер, НовыйИдентификатор)
    
    // Ищем ссылку на элемент справочника по табельному номеру
    СсылкаФизЛицо = Справочники.ФизЛица.НайтиПоРеквизиту("ТабНомер", ТабельныйНомер);
    
    Если Не СсылкаФизЛицо.Пустая() Тогда
        
        // Получаем объект для редактирования
        ОбъектФизЛицо = СсылкаФизЛицо.ПолучитьОбъект();
        
        // Устанавливаем новое значение реквизита
        ОбъектФизЛицо.ИдентификаторПропуска = НовыйИдентификатор;
        
        // Записываем объект в базу данных
        Попытка
            ОбъектФизЛицо.Записать();
        Исключение
            Сообщить("Не удалось записать данные для сотрудника с таб. номером " + ТабельныйНомер);
        КонецПопытки;
        
    Иначе
        Сообщить("Сотрудник с табельным номером " + ТабельныйНомер + " не найден в базе.");
    КонецЕсли;
    
КонецПроцедуры

Шаг 4. Оптимизация процесса через использование запросов

Если в вашем файле Excel содержатся тысячи строк, поиск методом НайтиПоРеквизиту внутри цикла будет работать медленно, так как 1С будет выполнять отдельное обращение к базе на каждой итерации. Рассмотрим более профессиональный подход — использование запроса с временной таблицей.

Алгоритм будет следующим:

  1. Загружаем все данные из Excel в ТаблицуЗначений.
  2. Передаем эту таблицу в Запрос в качестве параметра.
  3. В запросе соединяем нашу таблицу со справочником ФизЛица.
  4. Обходим результат запроса и записываем данные.


// Пример структуры запроса для ускорения поиска
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   ВТ_ДанныеExcel.ТабельныйНомер КАК ТабНомер,
    |   ВТ_ДанныеExcel.ИдентификаторПропуска КАК НовыйИдентификатор
    |ПОМЕСТИТЬ ВТ_Excel
    |ИЗ
    |   &ТаблицаИзExcel КАК ВТ_ДанныеExcel
    |;
    |
    |ВЫБРАТЬ
    |   ФизЛица.Ссылка КАК Ссылка,
    |   ВТ_Excel.НовыйИдентификатор КАК НовыйИдентификатор
    |ИЗ
    |   ВТ_Excel КАК ВТ_Excel
    |       ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ФизЛица КАК ФизЛица
    |       ПО ВТ_Excel.ТабНомер = ФизЛица.ТабНомер";

Запрос.УстановитьПараметр("ТаблицаИзExcel", ТЗ_Данные);
РезультатЗапроса = Запрос.Выполнить();

Такой подход считается стандартом "хорошего тона" в разработке 1С, так как он минимизирует количество транзакций и нагрузку на сервер БД.

Особенности работы с дополнительными реквизитами (БСП)

Стоит отметить, что в типовых конфигурациях (таких как ЗУП или ERP) дополнительные реквизиты часто реализуются через Библиотеку стандартных подсистем (БСП). В этом случае реквизит не является физическим полем в таблице справочника, а хранится в табличной части ДополнительныеРеквизиты.

Если ваше задание подразумевает именно такой механизм, то вместо прямой записи Объект.ИдентификаторПропуска, вам потребуется найти строку в табличной части, где Свойство равно нужному значению из Плана видов характеристик, и обновить поле Значение.

Резюмируем изученное:

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

← На главную