К статье
Практический материал

Разработка и Конфигурация · 8 мин

Как передать файл с сервера на клиент в 1С 8.3

Практическое руководство по передаче файлов с сервера 1С 8.3 на клиент: временное хранилище, ПолучитьФайл, НачатьПолучениеФайлов, примеры кода и типичные ошибки.

В клиент-серверном режиме 1С 8.3 код выполняется на сервере, а пользователь работает на клиентском компьютере. Если файл сформирован на сервере (отчёт в Excel, выгрузка XML, архив), на клиенте его напрямую не видно — нужна явная передача. Платформа предлагает для этого временное хранилище и методы получения файлов.

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

Зачем нужно временное хранилище

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

Адрес хранилища действует ограниченное время — до конца сеанса или до указанного момента. Если нужно, чтобы адрес жил дольше одного вызова формы, используйте ПоместитьВоВременноеХранилище() с указанием уникального идентификатора формы — тогда хранилище привязывается к времени жизни формы.

Шаг 1. Помещаем файл в хранилище на сервере

Серверная процедура читает файл в двоичные данные и помещает их в хранилище. Типичный код:

&НаСервере

Функция ПодготовитьФайлНаСервере(ПутьКФайлу)

ДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлу);

Адрес = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);

Возврат Адрес;

КонецФункции

Если файл формируется программно (например, табличный документ сохраняется в Excel), сначала запишите его во временный файл на сервере или получите данные через поток, затем поместите в хранилище тем же способом.

Важно: серверная функция должна быть доступна для вызова с клиента — в общем модуле включите флажки «Сервер» и «Вызов сервера», а в форме используйте директиву &НаСервере.

1c
ДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлу);
Адрес = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);

Шаг 2. Получаем файл на клиенте

Вариант с расширением работы с файлами: ПолучитьФайл

Если у пользователя подключено расширение работы с файлами (в тонком и толстом клиенте оно обычно есть), используйте синхронный метод:

&НаКлиенте

Процедура СохранитьФайл(Команда)

Адрес = ПодготовитьФайлНаСервере("C:\Temp\otchet.xlsx");

ИмяФайла = "Отчет.xlsx";

Если ПолучитьФайл(Адрес, ИмяФайла, Истина) Тогда

Сообщить("Файл сохранён");

КонецЕсли;

КонецПроцедуры

Третий параметр Истина открывает диалог выбора места сохранения. Если передать Ложь, файл будет сохранён по указанному полному пути без диалога.

Асинхронный вариант: НачатьПолучениеФайлов

В веб-клиенте и при отказе от модальности используйте асинхронный метод с описанием оповещения:

&НаКлиенте

Процедура СохранитьФайлАсинхронно(Команда)

Адрес = ПодготовитьФайлНаСервере("C:\Temp\otchet.xlsx");

ПолучаемыеФайлы = Новый Массив;

ОписаниеФайла = Новый ОписаниеПередаваемогоФайла("Отчет.xlsx", Адрес);

ПолучаемыеФайлы.Добавить(ОписаниеФайла);

Оповещение = Новый ОписаниеОповещения("ПослеПолученияФайлов", ЭтотОбъект);

НачатьПолучениеФайлов(Оповещение, ПолучаемыеФайлы, , Истина);

КонецПроцедуры

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

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

Сравнение способов передачи

СпособГде работаетОсобенности
ПолучитьФайл()Тонкий/толстый клиент с расширениемСинхронный, простой код, не работает в веб-клиенте без ограничений
НачатьПолучениеФайлов()Все клиенты, включая веб-клиентАсинхронный, требует описания оповещения
ПолучитьИзВременногоХранилища()Клиент и серверВозвращает двоичные данные в память, файл нужно записать вручную

Для большинства задач в управляемых формах оптимален НачатьПолучениеФайлов(): он соответствует современным требованиям платформы к асинхронности и не зависит от наличия расширения работы с файлами.

Сравнение вариантов

ПолучитьФайл

Подходит для тонкого клиента с расширением; ограничение — модальность и отсутствие поддержки в веб-клиенте

НачатьПолучениеФайлов

Универсальный асинхронный вариант; требует написания процедуры-обработчика оповещения

ПолучитьИзВременногоХранилища

Когда нужны сами данные для обработки, а не сохранение на диск; файл записывается вручную через Записать()

Проверка результата и типичные ошибки

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

Типичные ошибки
01
Вызов ПолучитьФайл() без расширения работы с файлами — метод завершается с ошибкой, файл не сохраняется
02
Использование адреса хранилища после закрытия формы — хранилище очищено, получение невозможно
03
Серверный путь к файлу указан как на клиенте — на сервере такого пути нет, ДвоичныеДанные не создаются
04
Передача огромных файлов через хранилище без контроля размера — рост потребления памяти сервера и таймауты

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

Ограничения и альтернативы

Временное хранилище не предназначено для долговременного хранения и передачи гигабайтных данных. Если файл велик, храните его на сервере в справочнике с двоичными данными или в томах, а на клиент отдавайте по частям либо через HTTP-сервис.

В файловом режиме работы разделение «сервер/клиент» фактически отсутствует — файл доступен напрямую, и описанная схема не нужна. Проверить режим можно функцией ИнформационнаяБазаФайловая().

Маршрут решения

Как выбрать действие

Работает тонкий клиент с расширением работы с файламиИспользуйте ПолучитьФайл() — код короче и понятнее
Нужна поддержка веб-клиента или немодальный режимИспользуйте НачатьПолучениеФайлов() с описанием оповещения
Файл очень большойНе передавайте целиком через хранилище — используйте HTTP-сервис или части
Информационная база файловаяПередача не нужна, работайте с файлом напрямую

FAQ

Чем ПолучитьИзВременногоХранилища отличается от ПолучитьФайл?

ПолучитьИзВременногоХранилища() возвращает сами данные (например, двоичные данные) в переменную — дальше их нужно обработать или записать на диск вручную. ПолучитьФайл() сразу сохраняет данные из хранилища в файл на клиенте.

Почему ПолучитьФайл() возвращает Ложь или выдаёт ошибку?

Чаще всего не подключено расширение работы с файлами, адрес хранилища недействителен (форма закрыта) или пользователь отменил диалог сохранения. Проверяйте расширение через ПодключитьРасширениеРаботыСФайлами().

Как передать файл в веб-клиенте?

Только асинхронно: НачатьПолучениеФайлов() с описанием оповещения. Синхронные методы в веб-клиенте недоступны.

Сколько живёт адрес временного хранилища?

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

Можно ли передать несколько файлов за один вызов?

Да. НачатьПолучениеФайлов() принимает массив объектов ОписаниеПередаваемогоФайла — добавьте в него несколько элементов с разными адресами хранилища.

Нужна ли передача через хранилище в файловой базе?

Нет. В файловом режиме клиент и «сервер» работают на одной машине, файл доступен по пути напрямую. Схема с хранилищем нужна только в клиент-серверном варианте.

Итог

Что важно запомнить

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