Как прочитать файл с клиентского компьютера на сервере 1С?

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

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

Проблема разграничения клиентской и серверной логики

Рассмотрим ситуацию: вы получили путь к файлу на клиенте, например, "C:\Users\Admin\Desktop\data.xlsx". Если вы передадите эту строку в серверную процедуру и попытаетесь открыть файл, система выдаст ошибку «Файл не найден». Это происходит потому, что сервер ищет этот путь на своем локальном диске или в своей сетевой среде, где такого файла не существует. Чтобы решить эту задачу, нам необходимо физически переместить данные файла во Временное хранилище.

Способ 1: Использование временного хранилища (стандарт 8.3)

Проанализируем самый современный и правильный подход. Мы не передаем «путь», мы передаем «содержимое». Разберем этот процесс по шагам:

  1. На клиенте пользователь выбирает файл.
  2. Файл помещается во временное хранилище, и мы получаем уникальный адрес (навигационную ссылку).
  3. Этот адрес передается на сервер.
  4. Сервер извлекает данные по адресу и выполняет обработку.

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


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

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

Способ 2: Чтение Excel через COM-объект

Если задача заключается в чтении данных из Excel, часто используется COMОбъект. Выясним причину популярности этого метода: он позволяет гибко управлять листами, форматированием и формулами. Однако помните, что для его работы на сервере (или клиенте) должен быть установлен Microsoft Office.

Разберем пример кода, который открывает книгу и ищет последнюю заполненную строку. Это критически важный момент, так как стандартные методы не всегда корректно определяют конец данных.


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

Нюансы определения границ данных

Проанализируем ситуацию, упомянутую на форуме: какой метод лучше для поиска последней строки? Существует несколько подходов:

Способ 3: Чтение без Excel (объект ТабличныйДокумент)

Рассмотрим более производительный и кроссплатформенный вариант. Начиная с версии 8.3, 1С умеет читать файлы .xlsx напрямую через ТабличныйДокумент. Это работает значительно быстрее, чем COM, и не требует установленного Microsoft Office (что крайне важно для серверов на Linux).

Выясним, как это реализовать на сервере:


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

Безопасность и производительность

При реализации загрузки файлов следует учитывать несколько важных моментов:

  1. Права доступа: Если вы решите использовать прямой путь (например, сетевой диск), убедитесь, что у пользователя, под которым запущен Агент сервера 1С (обычно USR1CV8), есть права на чтение этой сетевой папки.
  2. Веб-клиент: Если пользователи работают через браузер, использование COM-объектов на стороне клиента невозможно. В этом случае единственным рабочим вариантом будет помещение файла во временное хранилище через метод НачатьПомещениеФайлаНаСервер.
  3. Фоновое выполнение: Если файл содержит десятки тысяч строк, интерфейс пользователя заблокируется на время обработки. Рекомендуется передавать АдресХранилища в фоновое задание, чтобы пользователь мог продолжать работу, пока сервер обрабатывает данные.

Таким образом, мы выяснили, что наиболее универсальным и стабильным способом является передача данных через Временное хранилище с последующей обработкой на сервере либо встроенными средствами 1С (через ТабличныйДокумент), либо через COMОбъект, если требуется специфический функционал Excel.

← На главную