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

24.08.18

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 

См. также

1С-ная магия

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

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

06.10.2023    14610    SeiOkami    46    

112

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

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

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

14.09.2023    8888    human_new    27    

68

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

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

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

28.08.2023    5471    YA_418728146    6    

119

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

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

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

20.08.2023    5051    sebekerga    54    

88

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

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

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

27.06.2023    11078    SeiOkami    24    

90

Методы работы с универсальным отчетом в подсистеме "Варианты отчетов" на БСП

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

В данной статье рассмотрим типовую подсистему "Варианты отчетов" БСП на примере применения в универсальном отчете любой современной конфигурации.

30.05.2023    4009    quazare    4    

85

Расширение глобального поиска 1С, или Глобальный поиск "на максималках"

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

Мало кто знает, что поле "Глобального поиска" в 1С можно доработать. Добавить свои варианты поиска, кнопочки в результатах и даже целые пользовательские меню.

27.03.2023    6056    SeiOkami    10    

133

Версионирование объектов VS История данных

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

Давайте разберемся в механизме «История данных» и поэкспериментируем для наглядности. Сравним «Версионирование объектов» и «Историю данных».

06.03.2023    13266    dsdred    48    

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

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

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

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