1с очистить хранилище значений
В связи с новым подходом в программировании на платформе 8.2 возникла необходимость передачи данных между клиентом и сервером при этом прямая передача в виде параметров имеет ряд ограничений. И тогда был введен объект «Временное хранилище».
Чем полезно временное хранилище:
- Не надо создавать объекты в конфигурации
- Доступно и с сервера и с клиента
- Можно записать любой объект
Временное хранилище это не объект конфигурации, а объект платформы поэтому для разработчика он выглядит как черный ящик. Можно туда положить что-то получив псевдоним(адрес) и получить из него что-то указав псевдоним(адрес). Но узнать что находится во временном хранилище и сколько нельзя. В ниже рассмотренных примерах помещение в хранилище происходит на клиенте, а чтение на сервере. Хотя можно передавать данные и в обратном направлении.
Синтаксис работы с хранилищем простой:
Передав параметром, данные которые хотим поместить(Посылка) и УникальныйИдентификатор получаем Адрес, по которому потом можно будет обратиться. Причем передаваемый идентификатор не является получаемым в последствии адресом. Вместо идентификатора можно передать строку Адреса, по которому и будет помещено наше значение, но это не любая строка! Строка Адреса выглядит примерно вот так «e1cib/tempstorage/ae5c5472-0266-4892-9073-20392dd5a6a6» .
УникальныйИдентификатор может быть как новый так и существующей формы, в последнем случае значение в хранилище будет храниться пока существует форма. Если не передать уникальный идентификатор, то при следующем серверном вызове значение уже будет удалено.
Чтобы получить из хранилища нужно только указать адрес:
Также можно удалить помещенный объект, используя адрес
Если помещаемые данные не являются объектами конфигурации, то для того чтобы их поместить нужно перевести в доступный тип — «ДвоичныеДанные»
Помещение в хранилище
Здесь мы сначала преобразуем файл в формат двоичных данных и только потом помещаем их в хранилище
Чтение из хранилища
В интернете есть множество примеров как на сервере записать полученные данные в базу, поэтому ниже приводится другой пример, когда файл полученный на сервере открывается для работы. В качестве такого файла используется XML.
Если мы имеем дело с файлами, то может оказаться удобным метод ПоместитьФайл. Он преобразует файл в двоичные данные и записывает их во ВременноеХранилище. При этом параметром можно настроить открытие диалогового окна для выбора файла. Сделаю оговорку, этот метод нельзя использовать на сервере.
В параметре Адрес, можно указать Адрес в который нужно записать файл, если нужен новый адрес, то нужно передать пустую строку.
Истина – открывает окно для выбора папки и имени файла, при значении Истина есть возможность открыть файл."КопияФайла.xml" – Имя файла под которым будет сохранен файл.Адрес – это адрес в хранилище,ПолучитьФайл(Адрес,"Копияфайла.xml" , Истина);Чтобы сохранить файл из временного хранилища на Клиенте можно использовать метод
Временное Хранилище
Приветствую.
В последнее время перестал работать обмен данными между сервером (фоновое задание) и клиентом через временное хранилище.
на клиенте делаю
АдресПараметров = ПоместитьВоВременноеХранилище(Неопределено)
передаю параметром фоновому заданию
на сервере в фоновом задании чё-то делаю, выкладываю результат в
ПоместитьВоВременноеХранилище(Результат, АдресПараметров)
на клиенте обработчик ожидания смотрит завершение задания и
Результат = ПолучитьИзВременногоХранилища(АдресПараметров)
И если в начале день, два всё работает, то потом результат получается из хранилища на второй третий раз, а сейчас постоянно "неопределено". Одну обработку перевёл на хранилище настроек, всё заработало отлично, но это же не правильно.
Платформа 1С:Предприятие 8.3 (8.3.10.2580) УПП 1.3.100.1 SQL 2008
(9)пардон не принят, результат = неопреледено постоянно
В СП на тему ВХ и фоновых заданий довольно длинный текст с кучей сюрпризов.
Временное хранилище, сформированное в одном сеансе, недоступно из другого сеанса.
Исключением является возможность передачи данных из фонового задания в сеанс, инициировавший фоновое задание, с помощью временного хранилища. Для такой передачи следует в родительском сеансе поместить во временное хранилище пустое значение, передав идентификатор формы. Затем полученный адрес передать в фоновое задание через параметры фонового задания. Далее, если этот адрес использовать в параметре , то результат будет скопирован в сеанс, из которого было запущено фоновое задание.
Данные, помещенные во временное хранилище в фоновом задании, не будут доступны из родительского сеанса до момента завершения фонового задания.
Данные, помещенные в фоновом сеансе в хранилище по сформированному в родительском сеансе адресу, сразу после помещения становятся недоступными в фоновом сеансе. "
Временное хранилище в 1С 8.3
Временное хранилище позволяет временно хранить какие-то данные в служебных файлах 1С. Эти данные не будут записаны в базу данных и не будут доступны после завершения сеанса. Обычно временное хранилище используют для передачи файла с клиента на сервер, для передачи больших массивов данных и т.п.
С временным хранилищем можно работать как на сервере, так и на клиенте. Но обращение к хранилищу на клиенте выполняет неявное обращение к серверу.
Для помещения данных во временное хранилище используется метод ПоместитьВоВременноеХранилище. Первым параметром нужно передать данные, которые нужно поместить во временное хранилище. Данный метод вернет адрес во временном хранилище, где будут храниться данные. Адрес имеет тип Строка:
Объект "ХранилищеЗначения" известен в 1С, начиная с 8.0 и, казалось бы, прост, понятен, изучен вдоль и поперёк. Но иногда возникают вопросы, касающиеся работы с хранилищем, и данная публикация (по сути, краткий антисклерозник) призвана зафиксировать ответы на некоторые из них.
Хранилище значения (далее ХЗ) представляет собой данные, полученные кодированием и, при необходимости, сжатием входных данных с помощью 32-х битного алгоритма // из строки в ХЗ хз=XMLЗначение(Тип("ХранилищеЗначения"),ИсходнаяСтрокаBase64); // из ХЗ в строку ИтоговаяСтрокаBase64=XMLСтрока(ХЗ);
Важно понимать, что ХЗ это не значение, а указатель на область памяти. Они всегда разные, поэтому ни сравнение, ни поиск, ни отбор (в т.ч. в запросах) применять нельзя. Указатель равен сам себе лишь в рамках конкретного оператора-конструктора (и, кстати, в этом случае по нему работает, например, поиск в универсальных коллекциях). Так, например, если "А=хз; Б=А;", то А будет равно Б. А для сравнения именно значений следует действовать так (причём это не будет распаковкой как "расжатием"):
и это не зависит от наличия и степени сжатия в их конструкторах. Кстати, после применения конструктора определить степень сжатия можно лишь преобразованием в двоичные данные и анализом первых битов потока.
Так вот, размер "как есть" мы можем узнать, либо создав объект метаданных (например, справочник с единственным реквизитом типа ХЗ) и получив размер таблицы методом ПолучитьРазмерДанныхБазыДанных, либо опосредованно, через строку и двоичные данные (учитывая неизбежно прибавляемое), так:
Это не годится для абсолютных замеров (так, один символ латиницы, т.е. по идее 1 байт, и символ кириллицы, 2 байта, дают одинаковые 32 байта на выходе), но годится для относительных прикидок. Так, вызов без прямого указания "СжатиеДанных" всегда даёт значение большего (и иногда существенно большего, в разы) размера, чем с любым сжатием. На малых размерах сжатие не даёт заметного эффекта при любом аргументе. В СП сказано, что аргумент по умолчанию для объекта "СжатиеДанных" равен 1, но сжатие без его указания и с явным указанием даёт разные размеры, до десятков и сотен байт. На средних объектах (например, строки 500-1000 символов) сжатие со степенью выше 3-4 даёт примерно одинаковые итоговые размеры, т.е. эффективность одинаковая. Наряду с этим, в ряде старых релизов конструктор без сжатия даёт меньший итоговый размер.
Деструкция этого указателя тоже имеет нюансы.
В таблицах/деревьях значений с явно объявленной колонкой может использоваться везде, кроме запроса (не помещается в ВТ), не воспринимается как аргумент запроса, даже как &ПараметрТипаХЗ в секции "ВЫБРАТЬ". Что, учитывая известное про СУБД, не вполне логично.
При копировании объекта с реквизитами, содержащими ХЗ, ни интерфейсно, ни программно, эти значения НЕ наследуются, не копируются.
Если некое значение, упакованное в ХЗ, подпадает под RLS, то логика следующая - платформа всегда вначале выполняет неявную распаковку, либо рассматривает сделанную в коде явную; а затем накладывает ограничение, так что RLS применится именно для уже распакованного значения, спровоцировать тут ошибку ни разу не удалось.
Из интересных публикаций рекомендую эту.
Поскольку в современных метаданных конфигураций реквизит типа ХЗ где-нибудь точно наличествует, а также фигурирует в коде, то вопрос занимаемого им места актуален. В связи с этим было бы интересно исследовать рост места, занимаемого таблицей, состоящей исключительно из ХЗ, а также сравнить эффективность работы "СжатиеДанных" и основанного на том же Deflation объекта "ЗаписьZipФайла", пробуя разные значения УровеньСжатияZIP (естественно, при МетодСжатияZIP = "Сжатие").
Возможно, этот привычный и вроде бы простой объект, Хранилище значения, преподнесёт (особенно на больших данных и нагрузках) ещё некоторые удивительные сюрпризы.
Хранилище значений в 1С 8.3 это объект, который позволяет хранить в сериализованном виде почти любые типы данных (включая двоичные). Хранение происходит в самой базе данных (файле 1Cv8.1CD или на SQL-сервере в таблицах). Соответственно при выгрузки конфигурации, данные используемые хранилищем значений будут включены в архив базы (резервную копию). С помощью этого объекта можно хранить такие данные как: файлы, картинки (фотографии), внешние обработки, таблицы значений, структуры. Важно понимать, что хранение данных в таком виде будет существенно замедлять работу базы данных. Поэтому данную технологию хранения рекомендуется использовать в крайних случаях, если отсутствует альтернатива решения для имеющейся задачи.
// *** 1.Пример (Таблица значений):
ЗначенияТЗ = Новый ТаблицаЗначений (); // Создание значения "ТЗ"
// Вставка в хранилище значений
Хранилище_Зн = Новый ХранилищеЗначения ( ЗначенияТЗ , Новый СжатиеДанных ( 9 )); // "9" - макс.степень сжатия
// Сохранение значения в реквизит объекта конфигурации (тип: ХранилищеЗначения)
СправочникСтранаСсылка = Справочники . Страны . НайтиПоНаименованию ( "Испания" );
СправочникСтранаСсылка . ХранилищеЗначения = Хранилище_Зн ;
СправочникСтранаСсылка . Записать ();
// *** 2.Пример (Табличный документ):
ЗначенияТабДок =Новый ТабличныйДокумент ;
ЗначенияТабДок . Вывести ( ЭлементыФормы . ПолеТабличногоДокумента1 );
Хранилище_ТабДок =Новый ХранилищеЗначения ( ЗначенияТабДок );
// *** 3.Пример (Структура):
ЗначенияСтр = Новый Структура (); // Создание значения "Структура"
ЗначенияСтр . Вставить ( "Код" , "34" );
ЗначенияСтр . Вставить ( "Наименование" , "Испания" );
ЗначенияСтр . Вставить ( "Описание" , "Европейская страна, расположенная на Пиренейском полуострове" );
ЗначенияСтр . Вставить ( "Население" , 46600000 );
// Вставка в хранилище значений
Хранилище_Стр = Новый ХранилищеЗначения ( ЗначенияСтр , Новый СжатиеДанных ( 9 )); // "9" - макс.степень сжатия
ЗначениеВФайл ( "D:\import\" , Хранилище_Стр ); // Сохранение значения в файл
// *** 4.Пример (Любой файл) :
ФайлДвоичныеДанные = Новый ДвоичныеДанные ( "D:\import\КлиентБанк_РБ.exe" );
Хранилище_Файл = Новый ХранилищеЗначения ( ФайлДвоичныеДанные , Новый СжатиеДанных ( 0 )); // "0" - без сжатия
// *** 5.Пример (Файл картинка) :
ФайлФото = Новый Картинка ( "D:\import\ФотоСотрудника.jpg" );
Хранилище_Фото = Новый ХранилищеЗначения ( ФайлФото , Новый СжатиеДанных ( 5 )); // "5" - средн.степень сжатия
// *** 6.Пример (Текстовый файл) :
ФайлТекст = Новый ЧтениеТекста ( "D:\import\Война_и_мир.txt" );
ТекстИзФайла = ФайлТекст . Прочитать ();
Хранилище_Текст = Новый ХранилищеЗначения ( ТекстИзФайла , Новый СжатиеДанных ( 1 )); // "1" - мин.степень сжатия
// *** 7.Пример (Отчет/обработка 1С) :
Хранилище_Epf = Новый ХранилищеЗначения (Новый ДвоичныеДанные ( "D:\import\Otchet_realizacija_2020.epf" , СтепеньСжатия ));
// Двоичные данные можно восстановить из хранилища значения методом Получить и записать в файл методом Записать()
Если ТипЗнч ( РеквизитХранилище ) = Тип ( "ДвоичныеДанные" ) Тогда
// Хранилище.Получить()<>Неопределено Тогда // Процедура извлекает данные из хранилища (требует времени)
// Для больших объемов данных рекомендуется использовать доп.реквизит (Например: Булево) Содержит данные - Истина
ДанныеХранилища = РеквизитХранилище . Получить ();
Если ДанныеХранилища = Неопределено Тогда
Сообщить ( "Ошибка получения данных из хранилища значений 1С" );
КонецЕсли;
ДанныеХранилища . Записать ( ИмяФайла ); // Записываем восстановленые данные в файл
// Восстановление Табличного документа
ЭлементыФормы . ПолеТабличногоДокумента1 . Вывести ( ДанныеХранилища );
// Восстановление и запуск Отчета/обработки 1С
ИмяФайла_Epf = "D:\import\Otchet_realizacija_2020.epf" ;
ДвоичныеДанные = РеквизитХранилище . Получить ();
ДвоичныеДанные . Записать ( ИмяФайла_Epf );
Epf = ВнешниеОбработки . Создать ( ИмяФайла_Epf );
Epf . ПолучитьФорму (). Открыть ();
Иначе
ДанныеХранилища = РеквизитХранилище ;
КонецЕсли;
ХранилищеЗначения (хранилище значений 1С) – это объект в языке 1С, который позволяет хранить в базе данных прочие значения, например картинки и файлы, структуры и таблицы значений.
Сначала мы создаем значение, например:
Знч = Новый ТаблицаЗначений();
Потом помещаем его в хранилище значений 1С:
Хранилище = Новый ХранилищеЗначения(Знч, Новый СжатиеДанных(9));
Сжатие данных в хранилище значений 1С с параметром «9» означает, что данные будут храниться в архивированном виде, с максимальной степенью сжатия.
Чтобы сохранить такое значение в базу данных, нужно создать объект конфигурации (справочник, документ и т.п.), у которого добавить реквизит с типом ХранилищеЗначения.
СправочникСсылка = Справочники.Хранилище.СоздатьЭлемент();
СправочникСсылка.ХранилищеЗначения = Хранилище;
СправочникСсылка.Записать();
Кроме хранения таких значений в базе данных, с помощью хранилища значений 1С, мы также можем сохранить такое значение в файл, например:
Настройки = Новый Структура();
Настройки.Вставить("ПоУмолчанию", Истина);
Настройки.Вставить("Наименование", "Наименование1");
Хранилище = Новый ХранилищеЗначения(Настройки, Новый СжатиеДанных(9));
ЗначениеВФайл("C:\", Хранилище);
Пример – сохранение значения из файла
//Значение - картинка из файла
Файл = Новый Картинка("C:\ФайлКартинки.jpg");
Хранилище = Новый ХранилищеЗначения(Файл, Новый СжатиеДанных(9));
//Значение - произвольный файл
Файл = Новый ДвоичныеДанные("C:\ИсполняемыйФайл.exe");
Хранилище = Новый ХранилищеЗначения(Файл, Новый СжатиеДанных(9));
//Значение - текстовый файл
Файл = Новый ЧтениеТекста("C:\ТекстовыйФайл.txt");
ТекстовыеДанные = Файл.Прочитать();
Хранилище = Новый ХранилищеЗначения(ТекстовыеДанные, Новый СжатиеДанных(9));
Значение, помещенное в хранилище значений 1С нельзя использовать, пока оно там находится. Чтобы работать с ним, его нужно «распаковать» обратно, например:
Знч = Хранилище.Получить();
Если Знч = Неопределено Тогда
Сообщить("Ошибка получения значения из хранилища");
КонецЕсли;
Платформа 1С:Предприятия предоставляет массу возможностей для хранения данных всевозможных типов.
Но зачастую этих возможностей не хватает. И тогда нам на помощь приходит специальный объект — ХранилищеЗначения. Этот объект позволяет хранить в специальном формате как стандартные объекты 1С:Предприятия, например, таблица значений, так и нестандартные, для которых тип в платформе не предусмотрен. К нестандартным типам могут быть отнесены файлы. Так, например, с помощью хранилища значений в базе данных 1С можно хранить фотографии сотрудников, сканы документов, внешние обработки и т.д. Преимуществом здесь является то, что все эти объекты храняться в самой базе. Соответственно при развертывании новой базы из резервной копии все эти объекты также будут присутствовать в новой базе. С другой стороны если хранить в базе файлы большого размера это может значительно увеличить ее объем и отрицательно сказаться на работоспособности. Поэтому здесь необходимо соблюдать разумный баланс.
Рассмотрим работу с хранилищем значений на примере. Создадим в конфигураторе специальный справочник — назовем его ВнешниеОбъекты, а у справочника в свою очередь создадим реквизит Объект с типом ХранилищеЗначения
И теперь мы можем создавать в этом справочнике элементы, а в реквизит Объект каждого элемента записывать файл.
Работа с хранилищем значений очень проста. Если мы заглянем в синтакс-помощник, то увидим, что у этого объекта всего лишь один метод и один конструктор.
А теперь для демонстрации напишем простейший код, который будет записывать файл в реквизит Объект ранее созданного элемента справочника, а затем читать этот файл из реквизита и записывать его на диск, но уже под другим именем.
И несколько пояснений к коду.
-
Объект помещается в хранилище непосредственно при создании хранилища с помощью конструктора.
Нельзя просто прочитать объект из хранилища просто обратившись к реквизиту справочника как мы всегда привыкли это делать с другими типами данных. Вместо этого нужно использовать метод Получить() хранилища значений.
Чтобы сохранять в хранилище другие типы файлов, отличные от картинок, можно использовать объект ДвоичныеДанные. Чисто теоретически в хранилище значений можно даже хранить элементы справочников, документы и т.д. Но на практике это не имеет никакого смысла. А вот использовать хранилище значений для хранения таблицы значений, дерева значений и других универсальных коллекций иногда можно.
Читайте также: