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

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

Часто в процессе автоматизации возникает задача обновить данные в существующем документе 1С (например, в «Заказе клиента»), используя данные из внешнего файла Excel. Основная сложность заключается в выборе оптимального метода: делать это на клиенте, чтобы не нагружать сервер лишними файлами, или на сервере, чтобы обеспечить стабильность и скорость обработки больших данных. В этой статье мы разберем по шагам несколько способов реализации этой задачи, проанализируем их плюсы и минусы, а также изучим примеры кода.

Способ 1: Использование временного хранилища и серверной обработки

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

Проанализируем алгоритм действий:

  1. Выбор файла пользователем на клиенте.
  2. Помещение двоичных данных файла во временное хранилище.
  3. Передача адреса хранилища на сервер.
  4. Воссоздание файла из двоичных данных во временном каталоге сервера.
  5. Чтение данных с помощью объекта ТабличныйДокумент.

Посмотрим на пример кода, реализующий эту логику:


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

&НаКлиенте
Процедура РезультатВыбораФайла(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
    Если ВыбранныеФайлы = Неопределено Тогда Возврат; КонецЕсли;
    
    // Помещаем файл в хранилище
    ФайлДД = Новый ДвоичныеДанные(ВыбранныеФайлы[0]);
    АдресХранилища = ПоместитьВоВременноеХранилище(ФайлДД, УникальныйИдентификатор);
    
    // Вызываем серверную процедуру
    ОбработатьФайлНаСервере(АдресХранилища);
КонецПроцедуры

&НаСервере
Процедура ОбработатьФайлНаСервере(Адрес)
    ИмяФайла = ПолучитьИмяВременногоФайла(".xlsx");
    ДвоичныеДанные = ПолучитьИзВременногоХранилища(Адрес);
    ДвоичныеДанные.Записать(ИмяФайла);
    
    ТабДок = Новый ТабличныйДокумент;
    Попытка
        ТабДок.Прочитать(ИмяФайла, СпособЧтенияЗначенийТабличногоДокумента.Текст);
    Исключение
        Сообщить("Ошибка чтения файла!");
        Возврат;
    КонецПопытки;
    
    // Обход строк табличного документа
    Для НомерСтроки = 4 По ТабДок.ВысотаТаблицы Цикл
        НоменклатураТекст = ТабДок.Область("R" + Формат(НомерСтроки, "ЧГ=0") + "C1").Текст;
        КоличествоХЗ = ТабДок.Область("R" + Формат(НомерСтроки, "ЧГ=0") + "C16").Текст;
        
        // Здесь должна быть логика поиска в ТЧ документа и обновления
        Для каждого СтрокаТЧ Из Объект.Товары Цикл
            Если СтрокаТЧ.Номенклатура.Наименование = НоменклатураТекст Тогда
                СтрокаТЧ.Количество = Число(КоличествоХЗ);
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
    
    УдалитьФайлы(ИмяФайла);
КонецПроцедуры

Важный нюанс: Обратите внимание, что в современных версиях платформы (8.3.15+) рекомендуется использовать асинхронные методы, такие как ПоместитьФайлыНаСерверАсинхр, чтобы интерфейс пользователя не блокировался во время загрузки файла.

Способ 2: Работа через COM-объект на клиенте

Если на компьютере пользователя установлен Microsoft Excel, мы можем прочитать данные напрямую на клиенте, не перекидывая файл на сервер. Это реализуется через COMОбъект.

Рассмотрим преимущества этого метода:

Пример реализации на клиенте:


&НаКлиенте
Функция ЗагрузитьЧерезCOM(ИмяФайла)
    Попытка
        Excel = Новый COMОбъект("Excel.Application");
    Исключение
        Сообщить("Excel не установлен!");
        Возврат Ложь;
    КонецПопытки;

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

Однако помните, что COM-объект работает медленно и сильно зависит от версии установленного ПО. Для тонкого клиента в веб-браузере этот метод не подойдет вовсе.

Способ 3: Парсинг XLSX как ZIP-архива (Native-подход)

Выясним интересную особенность формата .xlsx. На самом деле это обычный ZIP-архив, внутри которого находятся XML-файлы с данными. Мы можем распаковать его средствами 1С (объект ЧтениеZipФайла) и прочитать данные напрямую.

Разберем структуру:

  1. Данные листов хранятся в xl/worksheets/sheet1.xml.
  2. Все текстовые строки вынесены в отдельный словарь xl/sharedStrings.xml.

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

Оптимизация поиска данных (Повышение производительности)

Проанализируем ситуацию: в коде автора используется вложенный цикл (перебор строк Excel внутри перебора строк документа). Если в заказе 500 позиций и в Excel 500 позиций, система выполнит 250 000 сравнений. Это очень медленно.

Как оптимизировать:

  1. Создайте на сервере объект Соответствие или Индексированную Таблицу Значений.
  2. Заполните её данными из документа, где Ключ — это Наименование (или Артикул), а Значение — ссылка на строку ТЧ.
  3. При обходе Excel просто получайте строку из соответствия одним вызовом метода Получить(). Это сократит время обработки до миллисекунд.

Пример оптимизированного поиска:


// Создаем карту поиска
КартаТоваров = Новый Соответствие;
Для каждого СтрТЧ Из Объект.ТоварыЗаказ Цикл
    КартаТоваров.Вставить(СтрТЧ.Номенклатура.Наименование, СтрТЧ);
КонецЦикла;

// В цикле по Excel
СтрокаДокумента = КартаТоваров.Получить(НоменклатураИзФайла);
Если СтрокаДокумента <> Неопределено Тогда
    СтрокаДокумента.Количество = ГотовитьсяКОтправке;
КонецЕсли;

Резюме

Мы рассмотрели различные подходы к проверке и загрузке данных Excel. Если вам нужна стабильность и простота — используйте серверный метод с временным файлом и ТабличнымДокументом. Если вы ограничены в ресурсах сервера или работаете только на Windows с гарантированно установленным Office — подойдет COM-объект. А для самых высокопроизводительных задач стоит посмотреть в сторону прямого парсинга XML внутри XLSX-архива.

← На главную