В теме форма: v8: Получение данных из ХралищаЗначений
Bell в управляемом интерфейсе пробует сохранить выбранные картинки в базу 1С, но возникли сложности с сохранением в хранилище значений. как пример Bell приложил CF файл с мини конфигурацией, за что ему большое спасибо, т.к. большая часть материалов этой статьи написана им, я лишь поправил небольшие участки кода связанные с передачей файлов и сохранение в хранилище значений.
Так как везде уже Такси, то CF я перевел в этот режим и в нем демонстрирую.
Имеется справочник Хранилище данных :
Основная Форма Элемента:
Ее код:
Код 1C v 8.3 // ПРОЦЕДУРЫ ФОРМЫ
//======================================================================================================
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Объект.Ссылка.Пустая() Тогда
Объект.Наименование = ".";
КонецЕсли;
Если НЕ Параметры.Ключ.Пустая() Тогда
ДанныеАдрес = ПолучитьНавигационнуюСсылку(Объект.Ссылка, "ДанныеХЗ");
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Если Объект.Ссылка.Пустая() Тогда
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
Если ЭтоАдресВременногоХранилища(ДанныеАдрес) Тогда
РежимСжатия = Новый СжатиеДанных(9);
ДанныеСохранения = ПолучитьИзВременногоХранилища(ДанныеАдрес);
ТекущийОбъект.ДанныеХЗ = Новый ХранилищеЗначения(ДанныеСохранения, РежимСжатия);
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ПриЗаписиНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
Если ЭтоАдресВременногоХранилища(ДанныеАдрес) Тогда
УдалитьИзВременногоХранилища(ДанныеАдрес);
ДанныеАдрес = ПолучитьНавигационнуюСсылку(ТекущийОбъект.Ссылка, "ДанныеХЗ");
КонецЕсли;
КонецПроцедуры
// ПРОЦЕДУРЫ ЭЛЕМЕНТОВ ФОРМЫ
//======================================================================================================
&НаКлиенте
Процедура ВыбратьДанные(Команда)
ДанныеВыбрать();
КонецПроцедуры
&НаКлиенте
Процедура СохранитьДанные(Команда)
Если НЕ ЗначениеЗаполнено(Объект.Ссылка) Тогда
Предупреждение(НСтр("ru = 'Элемент не записан !!!'"));
Возврат;
КонецЕсли;
ДанныеСохранения = ПолучитьНавигационнуюСсылку(Объект.Ссылка, "ДанныеХЗ");
ИмяСохранения = Объект.Наименование;
//ИмяСохранения = Объект.Наименование + Объект.ДанныеРасширение;
ПолучитьФайл(ДанныеСохранения, ИмяСохранения, Истина);
КонецПроцедуры
// ПРОЦЕДУРЫ ПРОЧИЕ
//======================================================================================================
&НаКлиенте
Процедура ДанныеВыбрать()
ПолученныеДанныеАдрес = "";
Если ПоместитьФайл(ПолученныеДанныеАдрес, , Объект.ДанныеПуть, Истина, УникальныйИдентификатор)Тогда
ДанныеАдрес = ПолученныеДанныеАдрес;
ВыбранныйФайл = Новый Файл(Объект.ДанныеПуть);
Объект.Наименование = ВыбранныйФайл.Имя;
Объект.ДанныеТекущаяДата = ТекущаяДата();
Модифицированность = Истина;
КонецЕсли;
КонецПроцедуры
так же имеется общая форма ФормаЗагрузкиФайлов
При помощи ее выбираются файлы изображений и загружаются в справочник - одновременно можно загружать несколько файлов
код формы:
Код 1C v 8.3 // ПРОЦЕДУРЫ ЭЛЕМЕНТОВ ФОРМЫ
//======================================================================================================
&НаКлиенте
Процедура СписокФайловПередНачаломДобавления(Элемент, Отказ, Копирование, Родитель, Группа)
Отказ = Истина;
ДобавитьФайлы();
КонецПроцедуры
// ПРОЦЕДУРЫ ПРОЧИЕ
//======================================================================================================
&НаКлиенте
Процедура ДобавитьФайлы()
ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
ВыборФайла.МножественныйВыбор = Истина;
ВыборФайла.Заголовок = НСтр("ru = 'Выбор файла'", "ru");
ВыборФайла.Фильтр = НСтр("ru = 'Все файлы'", "ru") + " (*.*)|*.*";
ВыборФайла.ПредварительныйПросмотр = Истина;
Если ВыборФайла.Выбрать() Тогда
Для каждого СтрокаФайл Из ВыборФайла.ВыбранныеФайлы Цикл
ОписаниеФайла = Новый Файл(СтрокаФайл);
НВС = СписокФайлов.Добавить();
НВС.ПолноеИмяФайла = СтрокаФайл;
НВС.РазмерФайла = ОписаниеФайла.Размер();
КонецЦикла;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура Загрузить()
Если НЕ ПроверитьЗаполнение() Тогда
Возврат;
КонецЕсли;
ОчиститьСообщения();
Если СписокФайлов.Количество() = 0 Тогда
Сообщить("Файлы не выбраны !!!'");
Возврат;
КонецЕсли;
ПомещаемыеФайлы = Новый Массив;
Для каждого СтрокаФайл Из СписокФайлов Цикл
Описание = Новый ОписаниеПередаваемогоФайла(СтрокаФайл.ПолноеИмяФайла, "");
ПомещаемыеФайлы.Добавить(Описание);
КонецЦикла;
// -------------------------------------------------------------------------------
ПомещенныеФайлы = Новый Массив;
СписокЗагруженныхФайлов = Новый СписокЗначений;
Если ПоместитьФайлы(ПомещаемыеФайлы, ПомещенныеФайлы, , Ложь, УникальныйИдентификатор) Тогда
Закрыть(Истина);
Иначе
Сообщение = Новый СообщениеПользователю();
Сообщение.Текст = НСтр("ru = 'Файлы не загружены'", "ru");
Сообщение.Сообщить();
КонецЕсли;
ОповеститьОВыборе(ПомещенныеФайлы);
КонецПроцедуры
&НаСервере
Функция ПоместитьВыбранныеФайлыВХранилище(ПомещаемыеФайлы)
АдресХЗ = ПоместитьВоВременноеХранилище(ПомещаемыеФайлы, УникальныйИдентификатор);
Возврат АдресХЗ;
КонецФункции
в коде вызывается ОповеститьОВыборе(ПомещенныеФайлы) и срабатывает обработчик в ФормаСпискаДополнительно
Код 1C v 8.3 &НаКлиенте
Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
Если ИсточникВыбора.ИмяФормы = "ОбщаяФорма.ФормаЗагрузкиФайлов" Тогда
ОбработкаВыбораПодборНаСервере(ВыбранноеЗначение);
КонецЕсли;
КонецПроцедуры
и следующим кодом идет создание элементов справочника и загрузка изображений из временного хранилища
Код 1C v 8.3 &НаСервере
Процедура ОбработкаВыбораПодборНаСервере(ВыбранноеЗначение)
Для Каждого СтрокаФайл Из ВыбранноеЗначение Цикл
Файл = Новый Файл(СтрокаФайл.Имя);
ХранимыйФайл = Справочники.ХранилищеДанныхСправочники.СоздатьЭлемент();
ХранимыйФайл.Наименование = Файл.Имя;
ХранимыйФайл.ДанныеПуть = Файл.Путь;
ХранимыйФайл.ДанныеТекущаяДата = ТекущаяДата();
ХранимыйФайл.ДанныеХЗ = Новый ХранилищеЗначения(ПолучитьИзВременногоХранилища(СтрокаФайл.Хранение), Новый СжатиеДанных());
ХранимыйФайл.Записать();
КонецЦикла;
Элементы.Список.Обновить();
КонецПроцедуры
Скачать DT - Платформа 8.3.4
Подключается к 1с82 web-сервису, получает от него описание типа
Создает переменную этого типа, Создает файл (dbf обмена).
Помещает файл в переменную и отдает на web-сервис для обработки, получает от него результат обработки
Код 1C v 8.х Определение = Новый WSОпределения(Server, User, Pass);
Прокси = Новый WSПрокси(Определение, "http://www.anton.fly7.ru", "Obmen", "ObmenSoap");
Прокси.Пользователь = User;
Прокси.Пароль = Pass;
Тип = Прокси.ФабрикаXDTO.Тип("http://www.anton.fly7.ru", "ФайлОбмена");
ФайлОбмена = Прокси.ФабрикаXDTO.Создать(Тип);
Файл = Новый Файл(КаталогВременныхФайлов() + "dat.dbf"); i=1;
Пока Файл.Существует() Цикл
Файл = Новый Файл(КаталогВременныхФайлов() + "dat" + i + ".dbf");
i=i+1;
КонецЦикла;
ДБ = Новый XBase;
ЗаполнитьПоляДБ(ДБ, ТабСвойств);
ДБ.СоздатьФайл(Файл.ПолноеИмя);
ДБ.АвтоСохранение = Истина;
ДБ.Добавить();
ДБ.Artik = Номенклатура.Артикул;
ДБ.Name = Строка(Номенклатура);
ДБ.NomGrup = Строка(Номенклатура.ТипНоменклатуры);
ДБ.VidNom = Строка(Номенклатура.ВидНоменклатуры);
ДБ.Group = ПолучитьГруппу(Номенклатура);
ДБ.Strana = "";
ДБ.Pol = "";
ДБ.Записать();
ДБ.ЗакрытьФайл();
ФайлДвоичныеДанные = Новый ДвоичныеДанные(Файл.ПолноеИмя);
ФайлаХранилищеЗначения = Новый ХранилищеЗначения(ФайлДвоичныеДанные, Новый СжатиеДанных(9));
ФайлОбмена.ТипФайла = 1;
ФайлОбмена.ИмяФайла = "data_" + СокрЛП(СсылкаНаОбъект.Номер) + ".dbf";
ФайлОбмена.Данные = ФайлаХранилищеЗначения.Получить();
УдалитьФайлы(Файл.ПолноеИмя);
Результат = Прокси.LoadDocs(ФайлОбмена);
Если ЗначениеЗаполнено(Результат) Тогда
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(Результат);
КонецЕсли;
Автор:
Абазин Антон Хранилище значений - это тип, который появился в 8-ой версии 1С позволяющий сохранять прямо в базе различные данные, включая двоичные данные (произвольные файлы). Например, так можно хранить в базе данных JPG-картинки, Word-документы и т.д. Причем данные будут храниться в самой базе (файле 1CD или в таблицах на SQL-сервере) и будут включены в штатную выгрузку базы или резервную копию средствами SQL Server.
Тип Хранилище значения может быть назначен реквизиту справочника, документа, ресурсу регистра сведений и т.д.
Примеры:
Код 1C v 8.х //Изображение, картинки (фотки):
ТекИзображение.Объект = СпрТкани.Ссылка;
ТекИзображение.ВидДанных = Перечисления.ВидыДополнительнойИнформацииОбъектов.Изображение;
Хранилище = Новый ХранилищеЗначения(НоваяКартинка, Новый СжатиеДанных());
ТекИзображение.Хранилище = Хранилище.Получить();
// в этом месте он все выводит ...
ЭлементыФормы.ПолеКартинки1.Картинка = Хранилище.Получить();
ТекИзображение.Записать();
Код 1C v 8.х
//Табличный документ:
Процедура СохранитьВХранилищеНажатие(Элемент)
ТабДок=Новый ТабличныйДокумент;
ТабДок.Вывести(ЭлементыФормы.ПолеТабличногоДокумента1);
Хранилище=Новый ХранилищеЗначения(ТабДок);
Записать();
КонецПроцедуры
Процедура ВосстановитьИзХранилищаНажатие(Элемент)
ТабДок=Хранилище.Получить();
Если ТабДок<>Неопределено Тогда
ЭлементыФормы.ПолеТабличногоДокумента1.Вывести(ТабДок);
КонецЕсли;
КонецПроцедуры
Код 1C v 8.х //Произвольные файлы (двоичные данные):
ХЗ = Новый ХранилищеЗначения(Новый ДвоичныеДанные(файл));
Восьмерка поддерживает сжатие данных, помещаемых в хранилище:
Код 1C v 8.х ХЗ = Новый ХранилищеЗначения(Новый ДвоичныеДанные(файл),Новый СжатиеДанных(9));
Код 1C v 8.х //Внешние обработки и отчеты:
Процедура ЗагрузитьОбработкуВХранилище(РеквизитТипХранилище)
СтепеньСжатия = Новый СжатиеДанных(9); //9 максимум
РеквизитТипХранилище = Новый ХранилищеЗначения(Новый ДвоичныеДанные("c:\отчеты\отчет.epf", СтепеньСжатия));
КонецПроцедуры
Процедура ЗапуститьОбработкуИзХранилища(РеквизитТипХранилище)
ИмяВременногоФайла = КаталогВременныхФайлов()+"отчет.epf";
ДвоичныеДанные = РеквизитТипХранилище.Получить();
ДвоичныеДанные.Записать(ИмяВременногоФайла);
ВнешняяОбработка = ВнешниеОбработки.Создать(ИмяВременногоФайла);
ВнешняяОбработка.ПолучитьФорму().Открыть();
КонецПроцедуры
Если это были ДвоичныеДанные, то их можно восстановить из хранилища значения методом Получить и записать в файл методом Записать().
Код 1C v 8.х Если ТипЗнч(Хранилище) <> Тип("ДвоичныеДанные") Тогда
ДвоичныеДанные = Хранилище.Получить();
Иначе
ДвоичныеДанные = Хранилище;
КонецЕсли;
ДвоичныеДанные.Записать(ИмяФайла);
Если это был, например, Word-документ (doc-файл, или другой файл зарегистрированного типа), то его можно открыть так:
Код 1C v 8.х ЗапуститьПриложение(ИмяФайла);
Чтобы очистить поле типа Хранилище значения, нужно присвоить ему Неопределено:
Код 1C v 8.х РеквизитХранилище = Неопределено;
Если в Хранилище значений содержались какие-то ссылки, то они не будут контролироваться при контроле ссылочной целостности (операция Удаление помеченных объектов или метод НайтиПоСсылкам).
К сожалению, 1С не содержит встроенных методов для проверки того, заполнено хранилище или нет.
Такой вариант не работает:
Код 1C v 8.х фл=Хранилище<>Неопределено;
Работает только такой вариант:
Код 1C v 8.х фл=Хранилище.Получить()<>Неопределено;
Но он требует затрат времени на извлечение данных из хранилища.
Поэтому, если это критично, нужно заводить еще один флаг, который указывает, содержит ли хранилище значение.
Источник