Работа с файлами в управляемых формах клиент серверной версии 8.3 и выше

24.08.18

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

При попытке работать с файлами по аналогии с толстым клиентом наткнулся на грабли. В 8.3 изменили подход к работе с файлами. Постараюсь кратко его описать.

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

Наименование Файл Версия Размер
Работа с файлами в тонком клиенте в клиент серверной версии 8.3 и выше:
.cf 16,50Kb
45
.cf 16,50Kb 45 Скачать

Для работы с файлами требуется понимание работы платформы и некоторых новшеств.

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

Файлы будем хранить в конфигурации в клиент серверной версии 8.3.
Для хранения файлов будем использовать реквизит с типом "ХранилищеЗначения".
Особенностью данного реквизита является его недоступность на клиенте, поэтому работу с ним необходимо проводить только на сервере.

Концепция загрузки с клиента на сервер следующая:
1. Загружаем файлы от клиента на сервер помещая их во временное хранилище
2. На клиенте сохраняем адрес
3. При записи объекта на сервере сохраняем файл в базу данных

Пройдем более детально:
Загрузка файла происходит во временное хранилище на сервере и не передается с контекстом на клиент.
Для передачи адреса файла создадим отдельную переменную формы типа строка, назовем ее "АдресЗагруженногоФайла".

Перед загрузкой нужно получить от пользователя разрешение на работу с его файловой системой.

Если НЕ ПодключитьРасширениеРаботыСФайлами() Тогда
    УстановитьРасширениеРаботыСФайлами();
КонецЕсли;

Для загрузки с клиента на сервер файла используем типовой метод "НачатьПомещениеФайла".
При работе с ним нужно учесть один момент - файл загружается во временное хранилище на сервер и на клиент передается адрес этого хранилища.
Этот адрес необходимо сохранить чтобы файл можно было найти на сервере.
Для этого используем переменную формы "АдресЗагруженногоФайла".

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

    Если НЕ ПодключитьРасширениеРаботыСФайлами() Тогда
        УстановитьРасширениеРаботыСФайлами();
    КонецЕсли;

    Адрес = "";
    НачальноеИмяФайла = "";
    ОписаниеОповещения = Новый ОписаниеОповещения("ЗагрузитьЗавершение", ЭтаФорма);
    НачатьПомещениеФайла(ОписаниеОповещения, Адрес, НачальноеИмяФайла, Истина, УникальныйИдентификатор);
	
КонецПроцедуры

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

    Файл = Новый Файл(ВыбранныйФайл);
    Объект.Имяфайла = Файл.ИмяБезРасширения;
    Объект.РасшриениеФайла = Файл.Расширение;
    Объект.Наименование = Файл.ИмяБезРасширения;
    // для записи в реквизит с типом хранилище значения
    АдресЗагруженногоФайла = Адрес;
			
КонецПроцедуры

У нас есть адрес файла на сервере но нет доступа к реквизиту с типом "ХранилищеЗначений" на клиенте.
Для записи в этот реквизит перед записью на сервере получим файл из временного хранилище и положим в реквизит.

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

Загрузка файла в базу данных готова.

Концепция выгрузки с сервера на клиента следующая:
1. Файл достаем с реквизита и ложим во временное хранилище
2. Передаем с сервера на клиент адрес
3. Сохраняем файл на клиенте

Для работы с файлами на клиенте нужно получить от пользователя разрешение на работу с его файловой системой.

Если НЕ ПодключитьРасширениеРаботыСФайлами() Тогда
    УстановитьРасширениеРаботыСФайлами();
КонецЕсли;

На сервере готовим метод который вытащит файл из реквизита и положит во временное хранилще

&НаСервере
Функция ПоместитьШаблонВоВременноеХранилище()
	
    Реквизит = РеквизитФормыВЗначение("Объект");
    ДвоичныйФайл = Реквизит.Файл.Получить();
    Адрес = ПоместитьВоВременноеХранилище(ДвоичныйФайл, УникальныйИдентификатор);
	
    возврат Адрес;
	
КонецФункции

Используем типовой метод "НачатьПолучениеФайлов" для передачи файла с сервера на клиента.
В него необходимо передать массив получаемых файлов.
В этом массиве необходимо указать адреса нахождения файлов на сервере или адреса временных хранилищ файлов.
Во время работы файлы будут загружены по этим адресам и положены в массиве "ПолученныеФайлы" во временные хранилища.
На клиенте из этих хранилищ достаем файлы и сохраняем.

&НаКлиенте
Процедура Выгрузить(Команда)
	
    Если НЕ ПодключитьРасширениеРаботыСФайлами() Тогда
        УстановитьРасширениеРаботыСФайлами();
    КонецЕсли;
	
    ВременнойФайл = ПолучитьИмяВременногоФайла();
    Адрес = ПоместитьШаблонВоВременноеХранилище();

    ИмяСРасширением = Объект.ИмяФайла + Объект.РасшриениеФайла;
	
    ОписаниеОповещения = Новый ОписаниеОповещения("ВыгрузитьЗавершение", ЭтаФорма);
    ПолучаемыеФайлы = Новый Массив;
    ОписаниеПередаваемогоФайла = Новый ОписаниеПередаваемогоФайла(ИмяСРасширением, Адрес);
    ПолучаемыеФайлы.Добавить(ОписаниеПередаваемогоФайла);
	
    ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
    ДиалогВыбораФайла.МножественныйВыбор = Ложь;
	
    НачатьПолучениеФайлов(ОписаниеОповещения, ПолучаемыеФайлы, ДиалогВыбораФайла, Истина);
	
КонецПроцедуры

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

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

 

См. также

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

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

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

11.03.2024    4547    dsdred    53    

72

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

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

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

24.01.2024    5298    YA_418728146    25    

63

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

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

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

11.12.2023    6412    dsdred    36    

112

1С-ная магия

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

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

06.10.2023    18480    SeiOkami    46    

118

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

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

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

14.09.2023    12094    human_new    27    

74

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

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

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

28.08.2023    8831    YA_418728146    6    

141

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

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

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

20.08.2023    6283    sebekerga    54    

94

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

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

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

27.06.2023    15989    SeiOkami    31    

103
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Dream_kz 129 24.08.18 11:00 Сейчас в теме
Ну есть же поиск, ну зачем очередной клон того, что уже есть?
5. СергейКа 669 25.08.18 08:32 Сейчас в теме
(1) Пфф... Зачем нам поиск? Написать свое же всегда круче? Тем более что составить правильно поисковый запрос а потом просмотреть результаты - это дольше чем набрость на коленке.
(0) Пиши исчо! Столько тем неразобранных в синтаксис-помощнике осталось!
2. pashamak 268 24.08.18 12:26 Сейчас в теме
Есть, только перегруженные или не совсем понятно описанные.
3. kirillkr 29 24.08.18 19:36 Сейчас в теме
Это все красиво для тонкого клиента с разрешенными синхронными вызовами, но абсолютно не работает в асинхронной работе тонкого или веб-клиента
SAnatoliy; Xershi; +2 Ответить
7. pashamak 268 20.08.20 07:29 Сейчас в теме
В веб клиенте не проверял, но предполагаю что будет работать или потребуются небольшие доработки по замене методов на более подходящие. В чем видите проблему при асинхронной работе?
11. Altone1976 26.08.21 18:04 Сейчас в теме
(7)проверил в Web клиенте , работает
4. Xershi 1475 24.08.18 20:40 Сейчас в теме
Надо наверное свою статью выложить с блекджеком и ш......, т.е. с полной асинхронностью, для вебклиента и универсально для любого реквизита, если именовать так как элемент формы=))
acanta; BigB; +2 Ответить
6. Xershi 1475 09.06.19 18:39 Сейчас в теме
(4) Наконец написал свою публикацию с блекджеком и ш...... Работа с файлами (обычная и управляемая форма) все структурировано и методы все актуализированы!
voneska7; +1 Ответить
8. pashamak 268 20.08.20 07:43 Сейчас в теме
(6)
Хорошая статья, побольше бы подобных.
Есть пожелания дополнить статью.
1. Нет особенностей работы с реквизитами типа ХранилищеЗначений, которые надо понимать если пишешь код сам.
2. Нет общей концепции работы (в основном код, без описания проблемных моментов), что затрудняет понимание написания подобного кода самому.
3. Статья больше напоминает справочник кода вместо описания и обучения новым механизмам.
9. Xershi 1475 20.08.20 10:13 Сейчас в теме
(8) это не статья, а публикация. Она содержит обработки, которые вы можете скачать и протестировать работу, чтобы вам стало все понятно. А код приведен для тех, кто уже делал подобное, но нужно искать где он это сделал, а так скопировал и вперед.
Потратить кучу времени, чтобы написать по новой спагетти это еще тот мазахизм.
Работа с ХранилищеЗначений это отдельная тема и к файлам в том понимании, в каком сделана публикация, отношения не имеет.
10. sly2k 11.12.20 14:50 Сейчас в теме

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

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

Кусок с сохранением файла оказался лишним, НачатьПолучениеФайлов( и так помещает эти файлы в папку
12. Scroudge 3 07.09.22 14:39 Сейчас в теме
.....никак тёщу отучить не могу...
всё одно.. ложит и ложит... навеяло..)
Оставьте свое сообщение