Как скопировать файл с локального компьютера в папку на сервере в управляемых формах 1С

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

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

Разбор основной ошибки: Почему код «не видит» файл?

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


&НаСервере
Процедура СохранитьФайлНаСервере()
    // Объект.Файл содержит путь "C:\Users\Documents\report.pdf"
    ДвоичныеДанные = Новый ДвоичныеДанные(Объект.Файл); 
    // Здесь возникает ошибка: Каталог не обнаружен
КонецПроцедуры

Выясним причину этой ошибки. Когда код выполняется с директивой &НаСервере, он исполняется на компьютере, где установлена служба 1C:Enterprise Server. Когда вы передаете туда строку с путем C:\Users\..., сервер пытается найти этот файл на своем собственном жестком диске. Естественно, сервер «не видит» файлы на диске «C:» вашего локального компьютера. Для сервера локальный диск пользователя — это чужая, недоступная территория.

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

Решение №1: Классический метод через Временное хранилище

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

Шаг 1: Работа на клиенте. Мы должны превратить файл в объект типа ДвоичныеДанные и поместить его во временное хранилище. Метод ПоместитьВоВременноеХранилище возвращает уникальный адрес (строку), по которому сервер сможет найти эти данные.


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

Шаг 2: Работа на сервере. Теперь, когда данные находятся в «облаке» сервера, мы можем их извлечь и записать в нужную нам папку.


&НаСервере
Процедура ЗаписатьФайлНаСервере(АдресХранилища, ИмяФайла)
    
    // Получаем данные из хранилища по адресу
    ДанныеДляЗаписи = ПолучитьИзВременногоХранилища(АдресХранилища);
    
    Если ДанныеДляЗаписи <> Неопределено Тогда
        // Формируем полный путь на сервере
        // ВАЖНО: Путь должен быть доступен для пользователя, под которым запущен сервер 1С
        ПутьНаСервере = "D:\FileStorage\" + ИмяФайла;
        
        Попытка
            ДанныеДляЗаписи.Записать(ПутьНаСервере);
            Сообщить("Файл успешно сохранен на сервере!");
        Исключение
            Сообщить("Ошибка записи: " + ОписаниеОшибки());
        КонецПопытки;
    КонецЕсли;
    
КонецПроцедуры

Решение №2: Использование асинхронных методов (Рекомендуется)

Начиная с версии платформы 8.3.15, компания 1С рекомендует отказываться от синхронных методов работы с файлами. Метод Новый ДвоичныеДанные(Путь) блокирует интерфейс, если файл большой. Разберем, как сделать это правильно через НачатьПомещениеФайлаНаСервер. Это особенно актуально для веб-клиента, где прямой доступ к файлам ограничен.


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

&НаКлиенте
Процедура ПослеПомещенияФайла(Результат, ДополнительныеПараметры) Экспорт
    
    Если Результат <> Неопределено Тогда
        // Результат.Адрес - это уже готовый адрес во временном хранилище
        ЗаписатьНаДискСервера(Результат.Адрес, Результат.СсылкаНаФайл.Имя);
    КонецЕсли;
    
КонецПроцедуры

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

Важные технические нюансы при записи на сервере

Проанализируем сопутствующие проблемы, которые могут возникнуть, даже если ваш код логически верен.

  1. Права доступа службы 1С. Это самая частая причина неудач. Сервер 1С работает не от вашего имени, а от имени системной службы (обычно это пользователь USR1CV8). Убедитесь, что у этого системного пользователя есть права «Запись» и «Изменение» на папку D:\FileStorage\ (или ту, которую вы используете).
  2. Кроссплатформенность путей. Если ваш сервер 1С работает под управлением Linux, а вы пишете пути в стиле Windows (C:\Folder\), код работать не будет. Рекомендуем использовать функцию ПолучитьРазделительПути() или проверять операционную систему через СистемнаяИнформация.
  3. Проверка существования каталога. Перед вызовом метода Записать(), обязательно проверьте, существует ли целевая папка на сервере. Если нет — создайте её.

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


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

Подведем итоги

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

← На главную