Загрузка, скачивание, удаление файлов с помощью НачатьПомещениеФайлаНаСервер() и НачатьПолучениеФайлаССервера()

25.07.20

Разработка - Механизмы платформы 1С

В платформе 8.3.15 появились новые методы НачатьПомещениеФайлаНаСервер() и НачатьПолучениеФайлаССервера(). В данной статье рассмотрено готовое решение проверенное и прекрасно работающее на тонком и веб-клиенте.

Скачать файлы

Наименование Файл Версия Размер
Загрузка, скачивание, удаление файлов с помощью НачатьПомещениеФайлаНаСервер() и НачатьПолучениеФайлаССервера()
.dt 60,27Kb
58
.dt 60,27Kb 58 Скачать

Можете скачать .dt файл приложенный к статье где есть работающее готовое решение, либо реализовать его самостоятельно с помощью следующего описания.

Реализация выполнена в регистре сведений, что делается немного сложнее чем со справочником или документом. Под справочник или документ вы легко сможете доработать код самостоятельно, всё интуитивно понятно.

Создан регистр сведений "РегистрФайлов":

Измерения:

  • Наименование (строка 50)

Реквизиты:

  • Файл (ХранилищеЗначения)
  • ИмяФайла (Строка 255)
  • РазмерФайла (Число 8,0 Неотрицательное)

У регистра создана форма записи на которую добавлен реквизит АдресФайла (Строка 0).

Добавлены 3 команды - Загрузить файл, Скачать файл и Удалить файл.

Прописан следующий код:

#Область ОбработчикиСобытийФормы

&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)

	Если ЭтоАдресВременногоХранилища(АдресФайла) Тогда
		ТекущийОбъект.Файл = Новый ХранилищеЗначения(ПолучитьИзВременногоХранилища(АдресФайла));
	ИначеЕсли Не ЗначениеЗаполнено(ТекущийОбъект.ИмяФайла) Тогда
		ТекущийОбъект.Файл = Новый ХранилищеЗначения(Неопределено);
	КонецЕсли;

КонецПроцедуры

#КонецОбласти

#Область ОбработчикиКомандФормы

&НаКлиенте
Процедура ЗагрузитьФайл(Команда)

	ПараметрыДиалога = Новый ПараметрыДиалогаПомещенияФайлов;
	ПараметрыДиалога.МножественныйВыбор = Ложь;
	ПараметрыДиалога.Заголовок = НСтр("ru = 'Выберите файл'; en = 'Select file'");
   	ПараметрыДиалога.Фильтр = НСтр("ru = 'Текстовый файл'; en = 'Text file'") + " (*.txt)|*.txt|";
	
    ЗавершениеОбратныйВызов = Новый ОписаниеОповещения("ЗавершениеОбратныйВызов", ЭтотОбъект);
    ПрогрессОбратныйВызов = Новый ОписаниеОповещения("ПрогрессОбратныйВызов", ЭтотОбъект);
    ПередНачаломОбратныйВызов = Новый ОписаниеОповещения("ПередНачаломОбратныйВызов", ЭтотОбъект);
    НачатьПомещениеФайлаНаСервер(ЗавершениеОбратныйВызов, ПрогрессОбратныйВызов, ПередНачаломОбратныйВызов,, ПараметрыДиалога, ЭтаФорма.УникальныйИдентификатор);

КонецПроцедуры

&НаКлиенте
Процедура СкачатьФайл(Команда)

	Если Не ЗначениеЗаполнено(Запись.ИмяФайла) Тогда
		Возврат;
	КонецЕсли;
	
	АдресФайлаДляСкачивания = АдресФайла;
	
	Если Не ЭтоАдресВременногоХранилища(АдресФайлаДляСкачивания) Тогда
		АдресФайлаДляСкачивания = ПолучитьАдресФайлаДляСкачивания();
	КонецЕсли;
	
	Если ЭтоАдресВременногоХранилища(АдресФайлаДляСкачивания) Тогда
		ПараметрыДиалога = Новый ПараметрыДиалогаПолученияФайлов;
		ПараметрыДиалога.Заголовок = НСтр("ru = 'Выберите путь для сохранения файла'; en = 'Select the path to save the file'");
		
		НачатьПолучениеФайлаССервера(АдресФайлаДляСкачивания, Запись.ИмяФайла, ПараметрыДиалога);
	КонецЕсли;

КонецПроцедуры

&НаСервере
Функция ПолучитьАдресФайлаДляСкачивания()

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

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

&НаКлиенте
Процедура УдалитьФайл(Команда)

	Если Не ЗначениеЗаполнено(Запись.ИмяФайла) Тогда
		Возврат;
	КонецЕсли; 
	
	ТекстВопроса = НСтр("ru = 'Удалить файл?'; en = 'Delete file?'");
	ОписаниеОповещения = Новый ОписаниеОповещения("УдалитьФайлЗавершение", ЭтотОбъект);
	ПоказатьВопрос(ОписаниеОповещения, ТекстВопроса, РежимДиалогаВопрос.ДаНет, 60);

КонецПроцедуры

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

&НаКлиенте
Процедура ЗавершениеОбратныйВызов(ОписаниеПомещенногоФайла, ДополнительныеПараметры) Экспорт

	Если ОписаниеПомещенногоФайла = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если Не ФайлКорректный(ОписаниеПомещенногоФайла.Адрес) Тогда
		ТекстСообщения = НСтр("ru = 'Файл пустой'; en = 'File is empty'");
		
		Сообщение = Новый СообщениеПользователю;
		Сообщение.Текст = ТекстСообщения;
		Сообщение.Сообщить(); 
		
		// ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения);
		Возврат;
	КонецЕсли;
	
	Запись.ИмяФайла = ОписаниеПомещенногоФайла.СсылкаНаФайл.Имя;
	Запись.РазмерФайла = ОписаниеПомещенногоФайла.СсылкаНаФайл.Размер();
	АдресФайла = ОписаниеПомещенногоФайла.Адрес;
	
	Модифицированность = Истина;

КонецПроцедуры

&НаСервереБезКонтекста
Функция ФайлКорректный(АдресФайлаВоВременномХранилище)

	ПутьКФайлу = ПолучитьИмяВременногоФайла("txt");
	
	ДанныеИзХранилища = ПолучитьИзВременногоХранилища(АдресФайлаВоВременномХранилище);
	Если ТипЗнч(ДанныеИзХранилища) = Тип("ДвоичныеДанные") Тогда
		ДанныеИзХранилища.Записать(ПутьКФайлу);
	КонецЕсли;
	
	// Проверка на то что файл корректный
	ЧтениеТекста = Новый ЧтениеТекста;
	ЧтениеТекста.Открыть(ПутьКФайлу);
	Текст = ЧтениеТекста.Прочитать();
	
	Возврат ЗначениеЗаполнено(Текст);
	
КонецФункции

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

	ТекстСообщения = СтрШаблон(НСтр("ru = 'Загрузка файла %1'; en = 'Uploading file %1'"), ПомещаемыйФайл.Имя);
	РазмерФайла = СтрШаблон(Нстр("ru = 'Размер файла %1 байт'; en = 'File size %1 bytes'"), ПомещаемыйФайл.Размер());
	
	Состояние(ТекстСообщения, Помещено, РазмерФайла, БиблиотекаКартинок.Документ);

КонецПроцедуры

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

	МегабайтВБайтах = 1000000;
	Если ПомещаемыйФайл.Размер() > МегабайтВБайтах Тогда
		ОтказОтПомещенияФайла = Истина;
		ТекстСообщения = СтрШаблон(НСтр("ru = 'Отказ. Загружаемый файл «%1» имеет размер более 1 мегабайта';
		|en = 'Failure. The uploaded file «%1» is larger than 1 megabyte'"), ПомещаемыйФайл.Имя);
		
		Сообщение = Новый СообщениеПользователю;
		Сообщение.Текст = ТекстСообщения;
		Сообщение.Сообщить();
		ОтказОтПомещенияФайла = Истина;
		
		//ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения,,,, ОтказОтПомещенияФайла);
	Иначе
		ПоказатьОповещениеПользователя(НСтр("ru = 'Загрузка файла'; en = 'Uploading file'"),, ПомещаемыйФайл.Имя);
	КонецЕсли;  

КонецПроцедуры

&НаКлиенте
Процедура УдалитьФайлЗавершение(РезультатВопроса, ДополнительныеПараметры) Экспорт

	Если РезультатВопроса = КодВозвратаДиалога.Да Тогда
		АдресФайла = "";
		Запись.ИмяФайла = "";
		Запись.РазмерФайла = 0;
		Модифицированность = Истина;
	КонецЕсли;

КонецПроцедуры

#КонецОбласти

НачатьПомещениеФайлаНаСервер НачатьПомещениеФайловНаСервер НачатьПолучениеФайлаССервера НачатьПолучениеФайловССервера

См. также

Поинтегрируем: сервисы интеграции – новый стандарт или просто коннектор?

Обмен между базами 1C Администрирование СУБД Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

В платформе 8.3.17 появился замечательный механизм «Сервисы интеграции». Многие считают, что это просто коннектор 1С:Шины. Так ли это?

11.03.2024    3584    dsdred    48    

66

Как готовить и есть массивы

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Все мы используем массивы в своем коде. Это один из первых объектов, который дают ученикам при прохождении обучения программированию. Но умеем ли мы ими пользоваться? В этой статье я хочу показать все методы массива, а также некоторые фишки в работе с массивами.

24.01.2024    5034    YA_418728146    25    

62

Планы обмена VS История данных

Обмен между базами 1C Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    6163    dsdred    36    

110

1С-ная магия

Механизмы платформы 1С Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    18199    SeiOkami    46    

116

Дефрагментация и реиндексация после перехода на платформу 8.3.22

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Начиная с версии платформы 8.3.22 1С снимает стандартные блокировки БД на уровне страниц. Делаем рабочий скрипт, как раньше.

14.09.2023    11767    human_new    27    

72

Валидация JSON через XDTO (включая массивы)

WEB-интеграция Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    8561    YA_418728146    6    

139

Внешние компоненты Native API на языке Rust - Просто!

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Внешние компоненты для 1С можно разработывать очень просто, пользуясь всеми преимуществами языка Rust - от безопасности и кроссплатформенности до удобного менеджера библиотек.

20.08.2023    6198    sebekerga    54    

93

Все скопируем и вставим! (Буфер обмена в 1С 8.3.24)

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Рассмотрим новую возможность 8.3.24 и как её можно эффективно использовать

27.06.2023    15531    SeiOkami    31    

103
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Xershi 1473 25.07.20 17:10 Сейчас в теме
2. Flashill 989 25.07.20 18:01 Сейчас в теме
(1) Ваше решение скачивал и смотрел, оно очень объемное.
И у вас используются методы для множества файлов, а не одиночных.
Вторая статья на Инфостарте на эту же тему но с другим подходом никому не повредит.
DivS; orfos; EvgeTrofi; daMaster; +4 Ответить
3. Xershi 1473 25.07.20 18:36 Сейчас в теме
(2) весь объем это ассинхронность. Сами методы простые.
4. Vasvas05 22 25.07.20 20:11 Сейчас в теме
5. Vasvas05 22 25.07.20 20:14 Сейчас в теме
при записи удаления файла, при выполнение вашего кода - не надо записать или удалить запись регистра?
6. Flashill 989 26.07.20 09:06 Сейчас в теме
(5) при нажатии "Удалить файл" очищается реквизит "ИмяФайла" и возводится флаг модифицированности, а в процедуре "ПередЗаписьюНаСервере" файл удаляется. Таким образом если пользователь случайно нажмет "Удалить файл", он сможет закрыть форму не сохраняя и заново её открыть. Файл при этом сохранится.
7. GROOVY 2503 04.08.20 10:52 Сейчас в теме
Уже Асинх появилось!
В веб клиенте без расширений браузера работает.
Flashill; +1 Ответить
8. user849098 05.08.20 11:04 Сейчас в теме
А как быть если файл размером 50мб?
9. Flashill 989 06.08.20 09:29 Сейчас в теме
(8) исправить в процедуре ПередНачаломОбратныйВызов() значение переменной МегабайтВБайтах с 1000000 на 51200000;
10. oooo800 29.08.20 14:18 Сейчас в теме
Прикольно, что у метода "НачатьПомещениеФайлаНаСервер" есть возможность подключить индикатор загрузки (прогресс).
Только вот на Web клиенте он "работает" 2 раза - в начале и в окончании "процесса" , жаль.
"Обработчик <ОписаниеОповещенияОХодеВыполнения> в веб-клиенте вызовется только дважды: когда количество помещенных во временное хранилище байт равно 0 и полному размеру файла".
И, на Web клиенте запаривает вопрос доступа к файлу, каждый раз при выборе файла..
Жаль нет параметра, установить "автоответ" (в параметрах метода).

Есть еще вариант с "НачатьСозданиеДвоичныхДанныхИзФайла" .

Уже по мотивам файловых операций дописываю конфигурацию - "Хранилище файлов" .
С регистром сведений - с реквизитом типа "ХранилищеЗначений".
С предпросмотром (графических и текстовых файлов) и уже сканированием (правда пока не из Web) .
P.S.: Файловая часть (моей конфигурации) была написана до этой публикации.
11. etmarket 888 04.04.21 17:38 Сейчас в теме
Большое спасибо автору публикации!
Flashill; +1 Ответить
12. burgomister 59 18.05.21 15:45 Сейчас в теме
В начале 20 века один известный французский математик объявил о том, что будет читать лекцию "Математические принципы моделирования одежды". На эту лекцию собрались, журналисты, модельеры, математики и любопытствующие. Математик начал лекцию словами: "Предположим, что человек имеет форму шара". После этих слов почти весь зал опустел.
К чему это я? После слов "Создан регистр сведений "РегистрФайлов":" - читать дальше не стал. Менять конфу для работы с файлами?
user1446119; JOJ73; +2 Ответить
13. Flashill 989 24.05.21 23:37 Сейчас в теме
(12) Интересная подводка, но в статье рассматривается возможность реализовать хранение файлов в реквизите типа "Хранилище значения" в любом объекте (на примере регистра сведений), а не в типовых справочниках для хранения файлов. А так конечно лучше по возможности использовать типовые справочники.
14. mkk 31.07.21 22:07 Сейчас в теме
Доброго времени суток. По версии предложенного автором алгоритма, если при загрузке файла - тут же его скачать - все норм. Даже, если создать на форме реквизит (строка) и "подсунуть" в него адрес файла (например для графики) - мона получить изображение этого файла. Очень даже удобно в прикладном смысле. Все бы хорошо. Но вот если записать и закрыть форму, а потом заново открыть и повторить скачивание - постоянно вылетает ошибка о сбое в адресе хранилища. Соответственно никакого просмотра графики. Найти-то нашел эту фичу, а вот где проблема: в хранилище или адресе, и исправить, чтобы не сбивалась "адресация" - не могу, слаб еще в 8-ке. Можно сие как-то подправить?
15. mkk 01.08.21 11:56 Сейчас в теме
В продолжение проблемы. Пытался занести поле с адресом с формы в реквизиты - проблемы не решает.
16. Bad_Aleks 17.03.23 15:27 Сейчас в теме
17. Moyses 05.04.23 22:52 Сейчас в теме
пишу вот такой код:

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

	
	ВыгрузитьФаилНаСервере();
КонецПроцедуры

&НаСервере
Процедура ВыгрузитьФаилНаСервере()
	
		СправочникОбъект = ДанныеФормыВЗначение(Объект, Тип("СправочникОбъект.ХранилищеФайлов"));

		ДанныеИзСправочника = СправочникОбъект.ПроизвольныйФаил.Получить();  
		
		ВременноеХранилище  = ПоместитьВоВременноеХранилище(ДанныеИзСправочника);
		
				
		НачатьПолучениеФайлаССервера(ВременноеХранилище,"ВозращенныйФаил.bmp");

		ЗначениеВДанныеФормы(СправочникОбъект, Объект);
 	
 	
КонецПроцедуры
Показать


При сохранении выдает ошибку:
"" Процедура или функция с указанным именем не определена (НачатьПолучениеФайлаССервера)
<<?>>НачатьПолучениеФайлаССервера(ВременноеХранилище,"ВозращенныйФаил.bmp"); (Проверка: Сервер) "



Подскажите, что не так?
Спасибо.
19. shoy 19 21.07.23 09:06 Сейчас в теме
(17)
При сохранении выдает ошибку:
"" Процедура или функция с указанным именем не определена (НачатьПолучениеФайлаССервера)
>НачатьПолучениеФайлаССервера(ВременноеХранилище,"ВозращенныйФаил.bmp"); (Проверка: Сервер) "


Процедура то у вас на сервере ...
так смотрите синтаксис-помощник. Знаете как его вызывать? ;)

Глобальный контекст (Global context)
НачатьПомещениеФайлаНаСервер (BeginPutFileToServer)

Доступность:
Тонкий клиент, веб-клиент, мобильный клиент, толстый клиент, мобильное приложение (клиент).
18. aibasoft 10 02.05.23 20:38 Сейчас в теме
Подскажите, вы в коде написали ПараметрыДиалога, но сейчас я в редакторе, в процедуре НачатьПомещениеФайлаНаСервер такого параметра нет, то есть не может принять ПараметрыДиалога. Хотя в синтакс помощнике тоже пишут что есть. Как cделать чтобы был параметр?

UPD: нашел, пишу "НачатьПомещениеФайлаНаСервер(" зажимаю Ctrl и вверх\вниз. Получается выбираешь варианты
20. RussXXX 02.09.23 16:03 Сейчас в теме
Добрый день,

Вариант синтаксиса: С диалогом выбора файла
Синтаксис:
НачатьПомещениеФайлаНаСервер(<ОписаниеОповещенияОЗавершении>, <ОписаниеОповещенияОХодеВыполнения>, <ОписаниеОповещенияПередНачалом>, <Адрес>, <ПараметрыДиалога>, <УникальныйИдентификаторФормы>)

Интересует этот момент
<ОписаниеОповещенияПередНачалом> (необязательный)
Тип: ОписаниеОповещения.
Содержит описание процедуры, которая будет вызвана непосредственно перед началом....

Код автора

 &НаКлиенте
Процедура ЗагрузитьФайл(Команда)

	ПараметрыДиалога = Новый ПараметрыДиалогаПомещенияФайлов;
	ПараметрыДиалога.МножественныйВыбор = Ложь;
	ПараметрыДиалога.Заголовок = НСтр("ru = 'Выберите файл'; en = 'Select file'");
   	ПараметрыДиалога.Фильтр = НСтр("ru = 'Текстовый файл'; en = 'Text file'") + " (*.txt)|*.txt|";
	
    ЗавершениеОбратныйВызов = Новый ОписаниеОповещения("ЗавершениеОбратныйВызов", ЭтотОбъект);
    ПрогрессОбратныйВызов = Новый ОписаниеОповещения("ПрогрессОбратныйВызов", ЭтотОбъект);
    ПередНачаломОбратныйВызов = Новый ОписаниеОповещения("ПередНачаломОбратныйВызов", ЭтотОбъект);
    НачатьПомещениеФайлаНаСервер(ЗавершениеОбратныйВызов, ПрогрессОбратныйВызов, ПередНачаломОбратныйВызов,, ПараметрыДиалога, ЭтаФорма.УникальныйИдентификатор);

КонецПроцедуры
Показать


Странно, не заходит в отладчике в процедуру

&НаКлиенте
Процедура ПередНачаломОбратныйВызов(ПомещаемыйФайл, ОтказОтПомещенияФайла, ДополнительныеПараметры) Экспорт
21. Surushi 01.02.24 15:01 Сейчас в теме
Зачем указывать метку "НачатьПолучениеФайловССервера", если у Вас эта функция не не описана и не использована?
user865160; +1 Ответить
22. Flashill 989 15.02.24 16:04 Сейчас в теме
Оставьте свое сообщение