Сохранение присоединенных файлов

1. GusevSI 26.07.24 06:10 Сейчас в теме
Добрый день!

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

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

&НаКлиенте
Процедура Выгрузить(Команда)
     
     КаталогКаталогВыгрузки = "D:\Выгрузка\"	 

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

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

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



&НаСервере
Функция СписокДокументовДляВыгрузки(ТабДок) Экспорт
    
    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |  ВнутренниеДокументы.Ссылка КАК Ссылка,
    |	ВнутренниеДокументы.Код КАК Код,
    |	ВнутренниеДокументы.Наименование КАК Наименование,
    |	ВнутренниеДокументы.ВидДокумента КАК ВидДокумента
    |ИЗ
    |	Справочник.ВнутренниеДокументы КАК ВнутренниеДокументы
    |ГДЕ
    |	ВнутренниеДокументы.ВидДокумента = &ВидДокумента
    |	И ВнутренниеДокументы.ДатаРегистрации МЕЖДУ &ДатаС И &ДатаПо";    
    
    Запрос.УстановитьПараметр("ВидДокумента", ЭтаФорма.ВыборВидаДокумента);
    Запрос.УстановитьПараметр("ДатаС", ЭтаФорма.ДатаНачала );
    Запрос.УстановитьПараметр("ДатаПо", ЭтаФорма.ДатаКонца);
    
    РезультатЗапроса = Запрос.Выполнить();
    
    ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
    
    МассивВыгружаемыхФайлов = Новый Массив;
    
    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
        
        Документ = ВыборкаДетальныеЗаписи.Ссылка;
        
        // получить список файлов документа
        СписокФайлов = Новый Массив;
        СписокФайлов = РаботаСФайламиСлужебный.ВсеПодчиненныеФайлы(ВыборкаДетальныеЗаписи.Ссылка);
        
        Для Счетчик = 0 по СписокФайлов.ВГраница() Цикл 					

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

            СтруктураФайла = РаботаСФайламиСлужебный.ФайлОбъект(СписокФайлов[Счетчик]);
            
            МассивВыгружаемыхФайлов.Добавить(СтруктураФайла);
            //МассивВыгружаемыхФайлов.Добавить(ФайлОбъект);
            
        КонецЦикла;	
        
    КонецЦикла;

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

КонецФункции
Показать


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

Документооборот 2.1.28.14
1C:Предприятие 8.3.18.1741
По теме из базы знаний
Найденные решения
10. laperuz 46 31.07.24 06:54 Сейчас в теме
(9) Используйте НачатьПолучениеФайловССервера() вместо цикла и НачатьПолучениеФайлаССервера.

Там как раз нужно на сервере подготовить массив объектов ОписаниеПередаваемогоФайла, каждый такой объект содержит адрес во временном хранилище и имя файла.
12. laperuz 46 31.07.24 07:39 Сейчас в теме
(11) См. синтакс помощник


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


Т.е. можете не просто имя файла туда писать, а <Подкаталог>/<ИмяФайла>
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. nomad_irk 76 26.07.24 07:45 Сейчас в теме
(1) Чем не устраивает типовой способ?
Прикрепленные файлы:
3. GusevSI 26.07.24 08:57 Сейчас в теме
(2) Имеется в виду выгрузка файлов через интерфейс 1С? Понятно, что это тоже вариант.
Я пытаюсь задействовать штатные функции выгрузки в своей обработке.
4. nomad_irk 76 26.07.24 09:00 Сейчас в теме
(3) Я понял, что вы изобретаете велосипед, но для чего, если есть типовой механизм сохранения файлов, причем он там еще и более функциональный?
5. GusevSI 26.07.24 10:04 Сейчас в теме
Помимо сохранения присоединенных файлов к документам требуется сохранить реквизиты документов, а сами файлы при выгрузке разнести по каталогам - отдельным для разных документов. Реквизиты сохраняю в таблице, а файлы от нескольких документов типовой механизм сохранения файлов грузит в общую "братскую могилу".
6. nomad_irk 76 26.07.24 10:35 Сейчас в теме
(5) В таком случае гляньте, как реализован типовой функционал.
7. GusevSI 26.07.24 10:45 Сейчас в теме
(6) Да, пытаюсь разобраться, спасибо.
8. GusevSI 29.07.24 08:00 Сейчас в теме
Присоединенные файлы получаю в серверной процедуре функцией РаботаСФайламиСлужебныйВызовСервера.ДанныеФайлаДляСохранения, возвращаю в клиентскую процедуру. Как правильнее сохранять файлы на клиенте?

            СписокФайлов = РаботаСФайламиСлужебный.ВсеПодчиненныеФайлы(ВыборкаДетальныеЗаписи.Ссылка);
            
            Для Счетчик = 0 по СписокФайлов.ВГраница() Цикл
                Если СписокФайлов[Счетчик].ПометкаУдаления = Ложь Тогда
                    
                    // получаем данные файла
                    ДанныеФайла = РаботаСФайламиСлужебныйВызовСервера.ДанныеФайлаДляСохранения(СписокФайлов[Счетчик].Ссылка, Неопределено, Неопределено);
                    
                    МассивВыгружаемыхФайлов.Добавить(ДанныеФайла);
                    
                КонецЕсли;
            КонецЦикла;	
Показать
9. GusevSI 31.07.24 06:12 Сейчас в теме
Работает так:

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



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


Осталось настроить передачу на клиента имени файла...
10. laperuz 46 31.07.24 06:54 Сейчас в теме
(9) Используйте НачатьПолучениеФайловССервера() вместо цикла и НачатьПолучениеФайлаССервера.

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

ОписаниеПередаваемогоФайла позволит выполнить такую настройку?
12. laperuz 46 31.07.24 07:39 Сейчас в теме
(11) См. синтакс помощник


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


Т.е. можете не просто имя файла туда писать, а <Подкаталог>/<ИмяФайла>
13. GusevSI 31.07.24 09:56 Сейчас в теме
(12) Работает, спасибо!
Код теперь выглядит так:

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




&НаСервере
Функция СписокДокументовДляВыгрузки() Экспорт
    
    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
   ...";    
    
    РезультатЗапроса = Запрос.Выполнить();
    ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
    
    МассивВыгружаемыхФайлов = Новый Массив;
        
    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

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

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот