Разработка и Конфигурация · 10 мин
Как получить файл с сервера на клиент в 1С
Разбираем способы передачи файла с сервера 1С на клиент: ПолучитьФайл, временное хранилище, НачатьПолучениеФайлов. Примеры кода, ошибки и проверка результата.
Задача передать файл с сервера 1С на клиентскую машину возникает постоянно: выгрузка отчёта в Excel, скачивание печатной формы, сохранение архива с данными, получение файла из присоединённого хранилища. В клиент-серверном режиме код выполняется на сервере, а диск пользователя находится на другой машине, поэтому простое «скопировать файл» не работает — нужен специальный механизм передачи.
В платформе 1С:Предприятие 8.3 для этого есть три основных подхода: устаревший метод ПолучитьФайл(), современные асинхронные методы НачатьПолучениеФайла() и НачатьПолучениеФайлов(), а также универсальный механизм временного хранилища, через который файл сначала помещается в память сервера, а затем забирается клиентом. Выбор зависит от режима работы (тонкий клиент, веб-клиент, толстый), размера файла и требований к модальности.
Ниже разобраны все три сценария с готовым кодом, типичными ошибками и способами проверить, что файл действительно дошёл до пользователя без повреждений.
Почему нельзя просто скопировать файл с сервера
В клиент-серверной архитектуре сервер 1С и клиентское приложение — это разные процессы, чаще всего на разных компьютерах. Когда серверный код пишет Записать("C:\Отчеты\файл.xlsx"), файл создаётся на диске сервера, и пользователь его никогда не увидит. Прямого доступа клиента к файловой системе сервера нет, и это сделано намеренно — из соображений безопасности.
Поэтому передача всегда идёт по схеме «сервер отдал данные → платформа передала их по каналу связи → клиент сохранил на свой диск». Роль транспорта выполняет либо временное хранилище, либо встроенные методы файловой передачи. Понимание этой схемы избавляет от главной ошибки новичков — попытки работать с серверным путём на клиенте.
Способ 1. Классический ПолучитьФайл()
Метод ПолучитьФайл(Адрес, ИмяФайла, Интерактивно) существует давно и встречается в большинстве старых конфигураций. Он принимает адрес во временном хранилище, целевое имя файла на клиенте и признак интерактивности — показывать ли пользователю диалог выбора места сохранения.
Типовой код выглядит так: сначала серверная процедура формирует файл и помещает его в хранилище, затем клиентская процедура вызывает ПолучитьФайл. Важный нюанс: если параметр «Интерактивно» установлен в Истина, появится модальный диалог, который заблокирует интерфейс и вызовет предупреждение в конфигурациях с отключённой модальностью.
&НаСервере
Функция СформироватьФайлНаСервере()
ИмяФайла = ПолучитьИмяВременногоФайла("xlsx");
ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
ДвоичныеДанные = Новый ДвоичныеДанные(ИмяФайла);
Адрес = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);
УдалитьФайлы(ИмяФайла);
Возврат Адрес;
КонецФункции
&НаКлиенте
Процедура СохранитьФайл(Команда)
Адрес = СформироватьФайлНаСервере();
ПолучитьФайл(Адрес, "Отчет.xlsx", Истина);
КонецПроцедурыГлавные ограничения метода: он синхронный, не работает в веб-клиенте без установленного расширения работы с файлами и не соответствует современным стандартам разработки, где требуются асинхронные вызовы. Для поддержки старого кода метод подходит, для новых разработок — нет.
Способ 2. Асинхронное получение через НачатьПолучениеФайлаИзВременногоХранилища
Современный вариант — метод НачатьПолучениеФайлаИзВременногоХранилища(ОписаниеОповещения, Адрес, ИмяФайла, ПараметрыДиалога). Он не блокирует интерфейс, корректно работает в тонком и веб-клиенте и соответствует требованиям стандартов разработки 1С. Результат приходит в процедуру оповещения.
Логика такая: вызываете метод, передаёте описание оповещения с именем процедуры-обработчика, и платформа сама вызовет её, когда файл будет сохранён. В обработчике проверяете массив полученных файлов — если он пуст, пользователь отменил операцию или произошла ошибка.
&НаКлиенте
Процедура СохранитьФайл(Команда)
Адрес = СформироватьФайлНаСервере();
Оповещение = Новый ОписаниеОповещения("ПослеПолученияФайла", ЭтотОбъект);
НачатьПолучениеФайлаИзВременногоХранилища(Оповещение, Адрес, "Отчет.xlsx");
КонецПроцедуры
&НаКлиенте
Процедура ПослеПолученияФайла(ПолученныеФайлы, ДопПараметры) Экспорт
Если ПолученныеФайлы = Неопределено Тогда
ПоказатьПредупреждение(, "Файл не был сохранен");
Возврат;
КонецЕсли;
ПоказатьОповещениеПользователя("Файл сохранен: " + ПолученныеФайлы[0].ПолноеИмя);
КонецПроцедурыСпособ 3. Передача нескольких файлов и файлов с диска сервера
Если нужно отдать пользователю не один файл, а пакет — например, комплект печатных форм или выгрузку из нескольких документов, — используйте НачатьПолучениеФайлов(). Метод принимает массив описаний передаваемых файлов, где для каждого указано либо физическое расположение на сервере, либо адрес в хранилище.
Отдельный сценарий — файл уже лежит на диске сервера (например, сформирован регламентным заданием). Тогда его можно не гонять через хранилище вручную: в описании передаваемого файла указывается серверный путь, и платформа сама организует передачу. Но помните: серверный путь доступен только серверу, поэтому такой код должен инициироваться с пониманием, где физически лежит файл.
ОписанияФайлов = Новый Массив;
ОписанияФайлов.Добавить(Новый ОписаниеПередаваемогоФайла("Акт.pdf", АдресАкта));
ОписанияФайлов.Добавить(Новый ОписаниеПередаваемогоФайла("Счет.pdf", АдресСчета));
НачатьПолучениеФайлов(Оповещение, ОписанияФайлов, , Истина);
Как выбрать подходящий способ
Выбор зависит от трёх факторов: клиентское приложение, требования к модальности и количество файлов. Для новых разработок практически всегда правильный ответ — асинхронные методы. Синхронный ПолучитьФайл оправдан только при доработке старых конфигураций, где уже используется модальный режим.
Как выбрать действие
Проверка результата и типичные ошибки
После передачи убедитесь, что файл реально сохранён и не повреждён. Минимальная проверка — в обработчике оповещения посмотреть массив полученных файлов и их размер. Если пользователь отменил диалог сохранения, массив будет неопределён — это не ошибка, а штатная ситуация, которую нужно обрабатывать отдельно, без аварийных сообщений.
Как проверить результат
Массив заполнен, у элемента есть ПолноеИмя
Неопределено — пользователь отменил или сбой передачи
Совпадает с размером двоичных данных на сервере
Нулевой или меньше — файл обрезан, проверяйте хранилище
Файл открывается в соответствующей программе
Ошибка формата — вероятно, файл не был записан на сервере до помещения в хранилище
Очистка временных данных и безопасность
Каждый помещённый в хранилище файл занимает память сервера. Если адрес привязан к форме (передан УникальныйИдентификатор формы), данные освободятся при её закрытии. Если привязки нет — вызовите УдалитьИзВременногоХранилища(Адрес) после того, как клиент забрал файл. Временные файлы на диске сервера удаляйте сразу через УдалитьФайлы() в том же серверном вызове.
С точки зрения безопасности проверяйте права: пользователь, не имеющий доступа к документу, не должен получить его присоединённый файл подбором адреса хранилища. Формируйте адрес только после проверки прав на объект-владелец, а не доверяйте адресу, пришедшему с клиента.
Что важно запомнить
Сервер формирует файл и кладёт его во временное хранилище, клиент забирает его асинхронным методом НачатьПолучениеФайлаИзВременногоХранилища. Обработчик делается с Экспорт, отмена пользователем обрабатывается штатно, временные файлы и хранилище очищаются после передачи.
Частые вопросы
Почему ПолучитьФайл не работает в веб-клиенте?
Веб-клиент работает в браузере и не имеет прямого доступа к файловой системе. Для синхронных файловых операций требуется расширение работы с файлами, которое пользователь должен установить отдельно. Асинхронные методы через оповещения работают без расширения — браузер просто инициирует скачивание файла.
Можно ли сохранить файл без диалога, сразу в заданную папку?
Да, если передать в параметрах диалога конкретное имя и не вызывать интерактивный режим. Но в веб-клиенте браузер сам решает, куда сохранять скачанный файл — обычно это папка «Загрузки», и повлиять на это из кода 1С нельзя.
Как передать файл, сформированный фоновым заданием?
Фоновое задание должно поместить результат во временное хранилище и вернуть адрес в своём результате. Клиент после завершения задания получает адрес и забирает файл стандартным НачатьПолучениеФайлаИзВременногоХранилища. Адрес лучше привязать к форме, чтобы данные не потерялись до окончания ожидания.
Что делать, если файл приходит пустым?
Чаще всего двоичные данные были прочитаны до того, как файл физически записался на диск сервера, либо табличный документ записан с ошибкой типа файла. Проверьте размер ДвоичныеДанные.Размер() на сервере сразу после чтения — если он нулевой, проблема на этапе формирования, а не передачи.
Есть ли ограничение на размер передаваемого файла?
Жёсткого лимита платформа не задаёт, но фактическое ограничение — память сервера: файл целиком размещается в оперативной памяти рабочего процесса. При файлах в сотни мегабайт и параллельной работе пользователей это может привести к нехватке памяти, поэтому большие выгрузки лучше разбивать или отдавать через сетевые каталоги.