Как передать путь к файлу из клиентского диалога в серверную процедуру в 1С 8.3

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

При разработке на управляемых формах в платформе 1С:Предприятие 8.3 разработчики часто сталкиваются с разделением контекстов выполнения кода: &НаКлиенте и &НаСервере. Классическая задача — предоставить пользователю интерактивный выбор файла на его компьютере через диалог и затем обработать данные этого файла (например, загрузить таблицу DBF) в серверной процедуре.

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

Почему не работает переменная модуля через Перем

Посмотрим на частую ошибку начинающих разработчиков: объявление переменной в начале модуля формы через ключевое слово Перем ИмяФайла; в надежде, что значение, присвоенное на клиенте, будет доступно на сервере.

Проанализируем причину, почему этот подход не работает:

  1. Разделение контекстов: Клиентский и серверный контексты управляемой формы работают изолированно. Переменные модуля, объявленные через Перем, создаются отдельно для экземпляра формы на клиенте и отдельно для вызова на сервере.
  2. Отсутствие синхронизации: Платформа 1С не передает значения неэкспортируемых локальных переменных модуля при контекстных серверных вызовах.
  3. Ограничения интерактивности: Объект ДиалогВыбораФайла доступен исключительно в контексте &НаКлиенте, тогда как тяжелая обработка данных и чтение справочников обычно выполняются в блоке &НаСервере.

Способ 1. Передача пути к файлу через параметры серверной процедуры

Если база данных работает в файловом режиме или клиент и сервер физически расположены на одном компьютере (а также если файл расположен в общедоступном сетевом ресурсе с одинаковым UNC-путем), путь к файлу можно передать строкой в качестве параметра серверной процедуры.

Разберем по шагам правильную реализацию вызова:

  1. На клиенте открываем ДиалогВыбораФайла и получаем свойство ПолноеИмяФайла.
  2. Передаем полученную строку аргументом в вызов серверной процедуры.
  3. В сигнатуре серверной процедуры объявляем параметр с тем же или произвольным именем переменной.
  4. Используем полученную переменную в методе ОткрытьФайл объекта XBase.

Посмотрим на рабочий пример кода:


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

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

Ошибки при работе с объектом XBase

При выполнении чтения DBF-файлов часто возникает исключение: «Перед выполнением операции нужно закрыть базу».

Выясним причину этой ошибки: метод ОткрытьФайл() вызывается у экземпляра объекта XBase, который уже содержит открытую таблицу базы данных. Чтобы избежать этой ошибки:

  1. Всегда создавайте новый экземпляр через Новый XBase перед открытием файла.
  2. Если объект переиспользуется, проверяйте его состояние методом ФайлDBF.Открыта() и вызывайте метод ФайлDBF.ЗакрытьФайл() перед повторным открытием.
  3. Следите за кодировкой: для файлов DOS используется КодировкаXBase.OEM, а для файлов Windows — КодировкаXBase.ANSI.

Способ 2. Универсальная передача файла через Временное хранилище

Рассмотрим ограничение первого способа: в клиент-серверном варианте (SQL) служба сервера 1С:Предприятия работает на отдельном физическом сервере и не имеет доступа к локальному диску C:\ клиентского компьютера пользователя. В этом случае передача строкового пути вызовет ошибку отсутствия файла на сервере.

Для создания универсального решения, которое работает в любом режиме (включая веб-клиент и клиент-сервер), разберем передачу содержимого файла через Временное хранилище:

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

Посмотрим на пример универсального кода:


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

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

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

← На главную