Разработано на 8.3.6.2041. Минимальная версия 8.3.3.641.
Для понимания механизма достаточно воспользоваться следующими новыми методами: НачатьПомещениеФайла, НачатьПолучениеКаталогаДокументов, НачатьПолучениеФайлов. Вспомогательными будут: ОписаниеОповещения, Файл, ПолучитьИзВременногоХранилища.
В свойствах конфигурации установлено:
Режим использования модальности - Не использовать
Режим использования синхронных вызовов - Не использовать (Свойство доступно начиная с версии 8.3.6.1760)
Режим совместимости - Не использовать.
Настройки БД:
Для реализации примера создал константу "Данные файла" (тип ХранилищеЗначения) общую форму "Сохранение файла". Через общую форму (где все реализовано) выполняется сохранение файла в константу, выгрузка и открытие загруженного ранее файла.
Спросите "Почему данные записываются в константу, а не в справочник или регистр сведений?". Тут все просто. Я посчитал что для упрощения понимания механизма использовать константу самое то :). Главное понять суть механизма, а вариант реализации программист уже выбирает исходя из структуры своей БД.
Почему не прикрепил конфигурацию, а выложил листинг кода?
Я считаю, что публикацию будет читать пользователь, уже имеющий опыт программирования в среде платформы 8.3 (умеет создавать объекты конфигурации, знает, что такое СП и как пользоваться встроенной справкой). Поэтому создать рабочий пример у себя в БД не составит особых проблем. Нужно: создать константу, создать общую форму, в новую форму вставить листинги кода (ниже в публикации), создать команды на форме (СохранитьФайл, ОткрытьФайл, УдалитьФайл) и подвязать обработчики.
Краткое описание используемых методов (копипаст СП не делал :) ):
НачатьПомещениеФайла - Вызывается диалог выбора файла. Выбранный файл помещается во временное хранилище.
НачатьПолучениеФайлов - Выполняется получение данных файла с БД и сохранение файла в указанный пользователем каталог.
Файл - Доступ к свойствам файла по полному пути к файлу.
ПолучитьИзВременногоХранилища, ПоместитьВоВременноеХранилище - В данном примере это методы работы с двоичными данными файла.
НачатьПолучениеКаталогаДокументов (КаталогДокументов) - Получение каталога документов пользователя (аналог КаталогДокументов).
ОписаниеПередаваемогоФайла - Определение полного имени файла в ОС по которому будет сохранен файл из ИБ.
ОписаниеОповещения - Описание вызова процедуры которая будет вызвана после какого-то действия пользователя (Пример: После действия пользователя НачатьПолучениеКаталогаДокументов будет вызвана процедура, где в параметре "ИмяКаталогаДокументов" будет строка в полным адресом к каталогу документов пользоватя: "C:\Users\Имя пользователя\Documents").
НачатьЗапускПриложения - Открытие файла ассоциированным приложением.
Примечание: Основные методы используются с 8.3.3.641. А НачатьПолучениеКаталогаДокументов с 8.3.6.1760.
Листинги:
Сохранение файла
#Область Сохранение_файла
&НаКлиенте
Процедура СохранитьФайл(Команда)
НачатьПомещениеФайла(Новый ОписаниеОповещения("СохранитьФайлЗавершение", ЭтотОбъект),,, Истина, УникальныйИдентификатор);
КонецПроцедуры
&НаКлиенте
Процедура СохранитьФайлЗавершение(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры) Экспорт
Если Не Результат Тогда
Возврат;
КонецЕсли;
// Используется для определения имени файла. Что бы потом можно было сохранить файл в ОС и потом его открыть.
Файл = Новый Файл(ВыбранноеИмяФайла);
СохранитьФайлВКонстантуНаСервереБезКонтекста(Адрес, Файл.Имя);
КонецПроцедуры // СохранитьФайлЗавершение
&НаСервереБезКонтекста
Процедура СохранитьФайлВКонстантуНаСервереБезКонтекста(Адрес, ИмяФайла)
ДанныеФайла = ПолучитьИзВременногоХранилища(Адрес);
СтруктураДанныхФайла = Новый Структура;
СтруктураДанныхФайла.Вставить("ИмяФайла", ИмяФайла);
СтруктураДанныхФайла.Вставить("ДанныеФайла", ДанныеФайла);
Константы.ДанныеФайла.Установить(Новый ХранилищеЗначения(СтруктураДанныхФайла));
КонецПроцедуры // СохранитьФайлВКонстантуНаСервереБезКонтекста
#КонецОбласти
#Область Открытие_файла
&НаКлиенте
Процедура ОткрытьФайл(Команда)
Если ПроверитьНаличиеФайлаВКонстантеНаСервереБезКонтекста() Тогда
// Начиная с версии 8.3.6.1760 (отказ от асинхронных методов)
НачатьПолучениеКаталогаДокументов(Новый ОписаниеОповещения("КаталогДокументовЗавершение", ЭтотОбъект));
// До 8.3.6.1760
//КаталогДокументов = КаталогДокументов();
//КаталогДокументовЗавершение(КаталогДокументов, "");
Иначе
СообщениеПользователю = Новый СообщениеПользователю;
СообщениеПользователю.Текст = "Файл не был загружен в константу.";
СообщениеПользователю.Сообщить();
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура КаталогДокументовЗавершение(ИмяКаталогаДокументов, ДополнительныеПараметры) Экспорт
Адрес = ПоместитьВоВременноеХранилище(Неопределено, УникальныйИдентификатор);
ИмяФайла = "";
ПолучитьДанныеФайлаНаСервереБезКонтекста(Адрес, ИмяФайла);
ПолноеИмяФайла = ИмяКаталогаДокументов + ИмяФайла;
МассивПолучаемыхФайлов = Новый Массив;
МассивПолучаемыхФайлов.Добавить(Новый ОписаниеПередаваемогоФайла(ПолноеИмяФайла, Адрес));
НачатьПолучениеФайлов(Новый ОписаниеОповещения("ОткрытьФайлЗавершение", ЭтотОбъект), МассивПолучаемыхФайлов,, Ложь);
КонецПроцедуры // КаталогДокументовЗавершение
&НаКлиенте
Процедура ОткрытьФайлЗавершение(ПолученныеФайлы, ДополнительныеПараметры) Экспорт
Если ПолученныеФайлы = Неопределено
И Не (ТипЗнч(ПолученныеФайлы) = Тип("Массив")
И ПолученныеФайлы.Количество()) Тогда
Возврат;
КонецЕсли;
НачатьЗапускПриложения(Новый ОписаниеОповещения("НачатьЗапускПриложенияЗавершение", ЭтотОбъект), ПолученныеФайлы[0].Имя);
КонецПроцедуры // ОткрытьФайлЗавершение
&НаКлиенте
Процедура НачатьЗапускПриложенияЗавершение(КодВозврата, ДополнительныеПараметры) Экспорт
// Заглушка
КонецПроцедуры // НачатьЗапускПриложенияЗавершение
&НаСервереБезКонтекста
Процедура ПолучитьДанныеФайлаНаСервереБезКонтекста(Адрес, ИмяФайла)
СтруктураФайла = Константы.ДанныеФайла.Получить().Получить();
ИмяФайла = СтруктураФайла.ИмяФайла;
ПоместитьВоВременноеХранилище(СтруктураФайла.ДанныеФайла, Адрес);
КонецПроцедуры // ПолучитьДанныеФайлаНаСервереБезКонтекста
#КонецОбласти
Удаление файла
#Область Удаление_файла
&НаКлиенте
Процедура УдалитьФайл(Команда)
Если ПроверитьНаличиеФайлаВКонстантеНаСервереБезКонтекста() Тогда
ПоказатьВопрос(Новый ОписаниеОповещения("УдалитьФайлЗавершение", ЭтотОбъект),
"Данные файла будут безвозвратно удалены.
|Продолжить?", РежимДиалогаВопрос.ДаНет, 30, КодВозвратаДиалога.Да,, КодВозвратаДиалога.Нет);
Иначе
СообщениеПользователю = Новый СообщениеПользователю;
СообщениеПользователю.Текст = "Файл не был загружен в константу.";
СообщениеПользователю.Сообщить();
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура УдалитьФайлЗавершение(РезультатВопроса, ДополнительныеПараметры) Экспорт
Если Не РезультатВопроса = КодВозвратаДиалога.Да Тогда
Возврат;
КонецЕсли;
УдалитьФайлНаСервереБезКонтекста();
КонецПроцедуры // УдалитьФайлЗавершение
&НаСервереБезКонтекста
Процедура УдалитьФайлНаСервереБезКонтекста()
Константы.ДанныеФайла.Установить(Неопределено);
КонецПроцедуры // УдалитьФайлНаСервереБезКонтекста
#КонецОбласти
Служебная процедура (в которой выполняется проверка наличия данных константы)
// Служебная процедура для проверки наличия загруженного файла
&НаСервереБезКонтекста
Функция ПроверитьНаличиеФайлаВКонстантеНаСервереБезКонтекста()
ДанныеФайла = Константы.ДанныеФайла.Получить();
Возврат Не ДанныеФайла.Получить() = Неопределено;
КонецФункции // ПроверитьНаличиеФайлаВКонстантеНаСервереБезКонтекста
P.S.: публикацию //infostart.ru/public/396459/ видел. В ней немного другой подход к реализации подобной задачи.
теги: НачатьПомещениеФайла, НачатьПолучениеФайлов, ОписаниеПереданногоФайла