Имя: Пароль:
1C
 
Сохранение присоединенных файлов
0 Trezvy
 
26.07.24
10:26
Добрый день!

Есть задача выгрузки присоединенных файлов в к выбранным документам и сохранение реквизитов документов. Реквизиты документов сохраняю в таблице, для выгрузки файлов пробую использовать стандартные функции из РаботаСФайламиКлиент или ФайловаяСиситемаКлиент. Не совсем понятно, какую информацию о сохраняемых файлах нужно передавать с серверной процедуры в клиентскую.

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

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

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

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

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



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

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

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

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

КонецФункции
1 Chameleon1980
 
27.07.24
20:14
с серверной процедуры в клиентскую ?
2 Мимохожий Однако
 
28.07.24
08:09
(0) Что не получается?
3 Chameleon1980
 
28.07.24
09:20
ну перейди к функции и почитай описание или примеры посмотри в типовой.
4 Trezvy
 
29.07.24
07:09
(1) Мне нужно сохранить присоединенные файлы на локальном диске пользователя. А серверная процедура, как я понимаю, сохраняет файлы на сервере. Поэтому я пытаюсь, получив данные о присоединенных файлах на сервере, передать их в клиентскую процедуру.

Получаю список присоединенных файлов и формирую массив, вопрос, что передавать в массиве на клиента, чтобы успешно сохранить файл? Объект, структуру? Пока получаю ДанныеФайла функцией ДанныеДляСохранения из РаботаСФайламиСлужебныйВызовСервера.

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


5 d4rkmesa
 
29.07.24
08:27
(4) См. НачатьПолучениеФайловССервера(...)
6 Trezvy
 
31.07.24
06:11
(5) Работает так:

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



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

Осталось настроить передачу на клиента еще имени файла.
7 Мультук
 
31.07.24
07:50
(6)

Интересно, а можно ли вместо

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


делать так

МассивВыгружаемыхФайлов.Добавить(Новый Структура("Адрес, ИмяФайла", Адрес, ИмяФайла));
8 Trezvy
 
31.07.24
09:59
Получилось такое решение:

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




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

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