Имя: Пароль:
1C
1С v8
Получение файлов, прикрепленных к объектам 1С. Вопросы.
0 Saari
 
30.03.23
14:01
Здравствуйте!
Помогите, пожалуйста, разобраться в вопросе получения файлов, прикрепленных к объектам 1С.
Есть конфигурация Бухгалтерия предприятия, 8. К некоторым документам и справочникам штатным способом подкреплены файлы (pdf, jpg).
Пытаюсь написать обработку, которая скачивала бы эти файлы на диск в указанную папку. Не получается...

Вот код обработки:
&НаКлиенте
Процедура ВыгрузитьФайлы(Команда)
	
  СписокФайлов = Новый СписокЗначений;
  ВыгрузитьФайлыНаСервере(СписокФайлов);
	
  ИмяФайлов = Новый Массив();
	
  Для Каждого ТекФайл Из СписокФайлов Цикл
	ДанныеФайла = ТекФайл.Значение;
	ИмяФайлов.Добавить(ДанныеФайла);
  КонецЦикла;
	
  МассивФайловДляСкачивания = ПодготовитьФайлы(ПутьКФайлу, ИмяФайлов);
		
  НачатьПолучениеФайловССервера(, МассивФайловДляСкачивания, ПутьКФайлу + "\", );
	
КонецПроцедуры


&НаСервере
Процедура ВыгрузитьФайлыНаСервере(СписокФайлов)
	
 Если ЕстьВыбранныеОбъекты() ИЛИ ЕстьНастроенныеОтборы() Тогда
		
   ВыбранныеОбъекты = ВыбранныеОбъекты();
   Если ВыбранныеОбъекты.Строки.Количество() > 0 Тогда
			
	 НужныйМассивСсылок = ВыбранныеОбъекты.Строки.ВыгрузитьКолонку("Ссылка");
			
	 Для Каждого ЭлементМассива Из НужныйМассивСсылок Цикл
				
	СтруктураДляПолученияФайлов = мЕстьФайлыУВладельца(ЭлементМассива);
	Если СтруктураДляПолученияФайлов.ЕстьФайлы Тогда
	  Таб = СтруктураДляПолученияФайлов.Таб;
	  Для Каждого Стр Из Таб Цикл
		   Если НЕ Стр.Ссылка.ПометкаУдаления Тогда
		СтруктураДанныхФайла = РаботаСФайлами.ДанныеФайла(Стр.Ссылка);
		СписокФайлов.Добавить(СтруктураДанныхФайла);
		 КонецЕсли;
		 КонецЦикла;
			
		Иначе
	  Сообщить(Строка(ЭлементМассива) + " - нет присоединенного файла!");
	КонецЕсли;
				
	 КонецЦикла;
			
   Иначе
	 Сообщить("Нет данных для выгрузки файлов!");
   КонецЕсли;
		
 Иначе
   Сообщить("Не задан отбор данных!");
 КонецЕсли;
	
КонецПроцедуры

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


&НаКлиенте
Функция ПодготовитьФайлы(ПутьКФайлу_, ИмяФайлов_)
		
	ИмяФайловДляСкачивания = Новый Массив();
	
	Для Каждого ИмяФайла Из ИмяФайлов_ Цикл
	Путь = ПутьКФайлу_ + "\" + ИмяФайла.ИмяФайла;
	Адрес = ПоместитьВоВременноеХранилище(Новый ДвоичныеДанные(Путь));
		
	ИмяФайлаФ = ИмяФайла.ИмяФайла;
	ИмяФайловДляСкачивания.Добавить(Новый ОписаниеПередаваемогоФайла(ИмяФайлаФ, Адрес));
	КонецЦикла;
	
	Возврат ИмяФайловДляСкачивания;
	
КонецФункции


В процедуре ПодготовитьФайлы() при помещении во временное хранилище выдает ошибку о том, что файл не найден.

Как правильно это реализовать?
1 Волшебник
 
модератор
30.03.23
14:05
Как стать программистом

Запись лесенкой очень-очень полезная и практичная вещь. Оформлять код лесенкой это первое, что каждый может сделать на пути избежания ошибок в коде своих программ и повышения удобочитаемости.

http://www.youngcoder.net/2011/11/oformleniekodanac.html?m=1
2 shuhard
 
30.03.23
14:07
(0)[Как правильно это реализовать?]
использовать БСП
3 Saari
 
30.03.23
14:09
(2) хочется в примерах...
4 shuhard
 
30.03.23
14:10
(3) борись
5 Saari
 
30.03.23
14:11
Файлы расположены в томах на диске.
6 Saari
 
30.03.23
14:18
Первый вариант был таким:
Процедура ВыгрузитьФайлы(Команда)
   СписокФайлов = Новый СписокЗначений;
   ВыгрузитьФайлыНаСервере(СписокФайлов);
    
   ИмяФайлов = Новый Массив();
   Для Каждого ТекФайл Из СписокФайлов Цикл
      ДанныеФайла = ТекФайл.Значение;
      НачатьПолучениеФайлаССервера(, ДанныеФайла.СсылкаНаДвоичныеДанныеФайла, ПутьКФайлу + "\" + ДанныеФайла.Наименование + "." + ДанныеФайла.Расширение);
   КонецЦикла;
КонецПроцедуры

Он работает, но иногда появляется сообщение:
"Ошибка при выполнении файловой операции  '/e1cib/tempstorage/4507f143-d20a-4ebb-88f7-e173739b45ea?seanceId=4c20eb1b-4703-4608-96be-addef04c2e46'. Значение данного типа невозможно преобразовать для передачи как файл. (Неопределено)"

Почему иногда появляется ошибка? Как ее устранить?