Имя: Пароль:
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'. Значение данного типа невозможно преобразовать для передачи как файл. (Неопределено)"

Почему иногда появляется ошибка? Как ее устранить?
Проблемы невозможно решaть нa том же уровне компетентности, нa котором они возникaют. Альберт Эйнштейн