Добрый день!

Подскажите, как сохранить на локальный диск пользователя присоединенные к документу файлы в 1С:Документооборот.

Пробую сделать так:

```1c
    &НаКлиенте
    Процедура Выгрузить(Команда)

    КаталогКаталогВыгрузки = "D:\Выгрузка\"

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

    Для Счетчик = 0 по СписокДокументов.ВГраница() Цикл

    Документ = СписокДокументов[Счетчик].Ссылка;
    ФайловаяСистемаКлиент.СохранитьФайл(Неопределено, Документ, КаталогВыгрузки, Неопределено);

    КонецЦикла;
    КонецПроцедуры

    &НаСервере
    Функция СписокДокументовДляВыгрузки(ТабДок) Экспорт

    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    | ВнутренниеДокументы.Ссылка КАК Ссылка,
    | ВнутренниеДокументы.Код КАК Код,
    | ВнутренниеДокументы.Наименование КАК Наименование,
    | ВнутренниеДокументы.ВидДокумента КАК ВидДокумента
    |ИЗ
    | Справочник.ВнутренниеДокументы КАК ВнутренниеДокументы
    |ГДЕ
    | ВнутренниеДокументы.ВидДокумента = &ВидДокумента
    | И ВнутренниеДокументы.ДатаРегистрации МЕЖДУ &ДатаС И &ДатаПо";

    Запрос.УстановитьПараметр("ВидДокумента", ЭтаФорма.ВыборВидаДокумента);
    Запрос.УстановитьПараметр("ДатаС", ЭтаФорма.ДатаНачала );
    Запрос.УстановитьПараметр("ДатаПо", ЭтаФорма.ДатаКонца);

    РезультатЗапроса = Запрос.Выполнить();

    ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();

    МассивВыгружаемыхФайлов = Новый Массив;

    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

    Документ = ВыборкаДетальныеЗаписи.Ссылка;

    // получить список файлов документа
    СписокФайлов = Новый Массив;
    СписокФайлов = РаботаСФайламиСлужебный.ВсеПодчиненныеФайлы(ВыборкаДетальныеЗаписи.Ссылка);

    Для Счетчик = 0 по СписокФайлов.ВГраница() Цикл

    ФайлОбъект = СписокФайлов[Счетчик].Ссылка.ПолучитьОбъект();

    СтруктураФайла = РаботаСФайламиСлужебный.ФайлОбъект(СписокФайлов[Счетчик]);

    МассивВыгружаемыхФайлов.Добавить(СтруктураФайла);
    //МассивВыгружаемыхФайлов.Добавить(ФайлОбъект);

    КонецЦикла;

    КонецЦикла;

    Возврат(МассивВыгружаемыхФайлов);

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

Какие данные правильнее передавать из серверной процедуры, какие функции лучше использовать в клиентской для сохранения файлов на локальном диске пользователя?

Документооборот 2.1.28.14
1C:Предприятие 8.3.18.1741
---
Используйте НачатьПолучениеФайловССервера() вместо цикла и НачатьПолучениеФайлаССервера.

Там как раз нужно на сервере подготовить массив объектов ОписаниеПередаваемогоФайла, каждый такой объект содержит адрес во временном хранилище и имя файла.
---
См. синтакс помощник

Имя - либо полный путь к файлу, либо относительный путь к файлу. Относительный путь будет объединен со значением параметра <БазовыйКаталог>.

Т.е. можете не просто имя файла туда писать, а <Подкаталог>/<ИмяФайла>
---
Чем не устраивает типовой способ?
---
Имеется в виду выгрузка файлов через интерфейс 1С? Понятно, что это тоже вариант.
Я пытаюсь задействовать штатные функции выгрузки в своей обработке.
---
Я понял, что вы изобретаете велосипед, но для чего, если есть типовой механизм сохранения файлов, причем он там еще и более функциональный?
---
Помимо сохранения присоединенных файлов к документам требуется сохранить реквизиты документов, а сами файлы при выгрузке разнести по каталогам - отдельным для разных документов. Реквизиты сохраняю в таблице, а файлы от нескольких документов типовой механизм сохранения файлов грузит в общую "братскую могилу".
---
В таком случае гляньте, как реализован типовой функционал.
---
Да, пытаюсь разобраться, спасибо.
---
Присоединенные файлы получаю в серверной процедуре функцией РаботаСФайламиСлужебныйВызовСервера.ДанныеФайлаДляСохранения, возвращаю в клиентскую процедуру. Как правильнее сохранять файлы на клиенте?

```1c
    СписокФайлов = РаботаСФайламиСлужебный.ВсеПодчиненныеФайлы(ВыборкаДетальныеЗаписи.Ссылка);

    Для Счетчик = 0 по СписокФайлов.ВГраница() Цикл
    Если СписокФайлов[Счетчик].ПометкаУдаления = Ложь Тогда

    // получаем данные файла
    ДанныеФайла = РаботаСФайламиСлужебныйВызовСервера.ДанныеФайлаДляСохранения(СписокФайлов[Счетчик].Ссылка, Неопределено, Неопределено);

    МассивВыгружаемыхФайлов.Добавить(ДанныеФайла);

    КонецЕсли;
    КонецЦикла;
```
---
Работает так:

```1c
    &НаКлиенте
    Процедура Выгрузить(Команда)
    СписокДокументов = СписокДокументовДляВыгрузки(ТабДок);
    Для Счетчик = 0 по СписокДокументов.ВГраница() Цикл
    Адрес = СписокДокументов[Счетчик];
    НачатьПолучениеФайлаССервера(Неопределено, Адрес, КаталогВыгрузки + <<имя_файла>>);
    КонецЦикла;
    КонецПроцедуры

    &НаСервере
    Функция СписокДокументовДляВыгрузки() Экспорт

    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    | ... ";

    РезультатЗапроса = Запрос.Выполнить();
    ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();

    МассивВыгружаемыхФайлов = Новый Массив;

    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
    СписокФайлов = Новый Массив;
    СписокФайлов = РаботаСФайламиСлужебный.ВсеПодчиненныеФайлы(ВыборкаДетальныеЗаписи.Ссылка);
    Для Счетчик = 0 по СписокФайлов.ВГраница() Цикл
    Если СписокФайлов[Счетчик].ПометкаУдаления = Ложь Тогда
    ДвоичныеДанные = РаботаСФайлами.ДвоичныеДанныеФайла(СписокФайлов[Счетчик]);
    Адрес = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);
    МассивВыгружаемыхФайлов.Добавить(Адрес);
    КонецЕсли;
    КонецЦикла;
    КонецЦикла;

    Возврат(МассивВыгружаемыхФайлов);
    КонецЕсли;
    КонецФункции
```

Осталось настроить передачу на клиента имени файла...
---
Используйте НачатьПолучениеФайловССервера() вместо цикла и НачатьПолучениеФайлаССервера.

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

ОписаниеПередаваемогоФайла позволит выполнить такую настройку?
---
См. синтакс помощник

Имя - либо полный путь к файлу, либо относительный путь к файлу. Относительный путь будет объединен со значением параметра <БазовыйКаталог>.

Т.е. можете не просто имя файла туда писать, а <Подкаталог>/<ИмяФайла>
---
Работает, спасибо!
Код теперь выглядит так:

```1c
    &НаКлиенте
    Процедура Выгрузить(Команда)
    СписокДокументов = СписокДокументовДляВыгрузки();
    НачатьПолучениеФайловССервера(Неопределено, СписокДокументов, КаталогВыгрузки);
    КонецПроцедуры

    &НаСервере
    Функция СписокДокументовДляВыгрузки() Экспорт

    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    ...";

    РезультатЗапроса = Запрос.Выполнить();
    ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();

    МассивВыгружаемыхФайлов = Новый Массив;

    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

    СписокФайлов = Новый Массив;
    СписокФайлов = РаботаСФайламиСлужебный.ВсеПодчиненныеФайлы(ВыборкаДетальныеЗаписи.Ссылка);

    Для Счетчик = 0 по СписокФайлов.ВГраница() Цикл
    Если СписокФайлов[Счетчик].ПометкаУдаления = Ложь Тогда
    ДвоичныеДанные = РаботаСФайлами.ДвоичныеДанныеФайла(СписокФайлов[Счетчик]);
    Адрес = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);
    ИмяСРасширением = ВыборкаДетальныеЗаписи.Код + "\" + СписокФайлов[Счетчик].ПолноеНаименование + "." + СписокФайлов[Счетчик].ТекущаяВерсияРасширение;
    ОписаниеПередаваемогоФайла = Новый ОписаниеПередаваемогоФайла(ИмяСРасширением, Адрес);
    МассивВыгружаемыхФайлов.Добавить(ОписаниеПередаваемогоФайла);
    КонецЕсли;
    КонецЦикла;

    КонецЦикла;

    Возврат(МассивВыгружаемыхФайлов);

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