1с управляемые формы хранилище значений

Ситуация

У нас есть справочник “Товры”, в реквизите “Данные” которого сохраняется информация в виде двоичных данных. Сам реквизит имеет тип значения “ХранилищеЗначения”. На следующем скриншоте представлена стркутура метаданных справочника.

Для прикрепления произвольного файла с диска в форме элемента реализована команда “ПрикрепитьФайл”. Ее программный код представлен на следующем листинге:

Если описать алгоритм в общих чертах, то сначала на клиенте выбирается файл с диска. Полученные двоичные данные файла отправляются на сервер, где записываются в информационную базу, а именно в реквизит “Данные” текущего элемента справочника.

В принципе все работает. При открытии элемента мы можем считывать эти данные по необходимости. Если, например, в реквизите сохранено изображение, то мы можетм получить его и вывести в поле формы. Такое решение имеет место быть, но в большинстве задач использовать реквизит с типом значения “ХранилищеЗначения” в справочниках и документах не оптимально. И вот почему.

Влияние на производительность

Проведем несколько тестов на производительность. В тестах будут использоваться два элемента справочника “Товары” с прикрепленным файлом и без. Размер прикрепленного файла составляет 5 мегабайт.

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

Замерим время открытие элементов справочника “Товары”. Для открытия элемента используется метод глобального контекста “ОткрытьЗначение()”, в качестве параметра которому передается ссылка на элемент. Выполним замер времени открытия с помощью стандартного интруемента замера производительности. Результаты представлены на следующем скриншоте:

Как мы видим, время открытия элемента с прикрепленным файлом больше в 10 раз! Сделаем другой тест. Выполним метод “ПолучитьОбъект()” для ссылки на элемент справочника товары. Результат теста Вы можете видеть на следующем скриншоте.

Читайте также:  1с вывод в ворд

Разница весьма существенная. Получение элемента без прикрепленного файла отрабатывает быстре в 194 раза!

Происходит это потому, что метод “ПолучитьОбъект()” получает все данные из реквизитов элемента справочника по ссылке. Соответственно, метод получает значения не только реквизитов “Код” и “Наименование”, но и значение реквизита “Данные”. Если в нем хранятся двоичные данные размером 5 мегабайт (как в нашем примере), то при получении объекта эти данные помещаются в оперативную память (как и остальные реквизиты) и затем передаются на клиентскую сторону. Именно получение данных из этого реквизита увеличивает время получения объекта элемента. Если же используется тонкий канал связи, то время открытия увеличится еще более значительно из-за передачи большого объема информации по сети.

Примечание: при выполнении метода “ОткрытьЗначение()” также сначала получается объект элемента справочника, а затем трансформируется в объект формы и передается на клиент (для управляемых форм). То есть, при открытии элемента по ссылке получение объекта также выполняется.

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

Закономерный результат. Время получения и, затем, записи для элемента справочника с прикрепленным файлом оказалось в

19 раз больше. Как было сказано выше, при получении объекта получаются значения всех его реквизитов, в том числе и реквизита “Данные” в котором сохранены 5 мегабайт информации. При записи элемента этот объем данных вновь записывается в информационную базу. Следовательно, хранение данных в реквизите справочника (или документа) с типом “ХранилищеЗначения” отрицательно влияет на производительность как при получении объекта, так и при помещении его в информационную базу.

Какой же способ решения задачи по хранению данных для объектов информационной базы наиболее правильный?

Читайте также:  dir 620 открыть порты

Правильное решение

Если мы посмотрим на реализацию данного механизма в типовых конфигурациях, то увидим, что для объектов дополнительная информация хранится в отдельной таблице регистра сведений. Вот так, например, выглядит механизм присоединенных файлов в типовой конфигурациии “Управление торговлей” версии 11.

Справочник “Номенклатура” является владельцем для справочника “НоменклатураПрисоединенныеФайлы”. Тот в свою очередь связан с регистрам сведений “ПрисоединенныеФайлы”, измерение которого “ПрисоединенныйФайл” ссылается на его элемент. Таким образом, данные, прикрепляемые к объектам информационной базы, фактически хранится в таблице регистра сведений, на работу которого объекм хранимых данных в ресурсе практически не влияет. Промежуточный справочник “НоменклатураПрисоединенныеФайлы” необходим для хранения дополнительной информации для присоединенного файла, а тажке для поддержки обращения к присоединенному файлу по ссылке.

Все выше сказанное еще раз подтверждает огромное влияние на производительность правильно разработанной структуры метаданных конфигурации.

Тестовая конфигурация с примером из статьи: LINK .

ХранилищеЗначения (хранилище значений 1С) – это объект в языке 1С, который позволяет хранить в базе данных прочие значения, например картинки и файлы, структуры и таблицы значений.

Сначала мы создаем значение, например:
Знч = Новый ТаблицаЗначений();
Потом помещаем его в хранилище значений 1С:
Хранилище = Новый ХранилищеЗначения(Знч, Новый СжатиеДанных(9));
Сжатие данных в хранилище значений 1С с параметром «9» означает, что данные будут храниться в архивированном виде, с максимальной степенью сжатия.

Чтобы сохранить такое значение в базу данных, нужно создать объект конфигурации (справочник, документ и т.п.), у которого добавить реквизит с типом ХранилищеЗначения.
СправочникСсылка = Справочники.Хранилище.СоздатьЭлемент();
СправочникСсылка.ХранилищеЗначения = Хранилище;
СправочникСсылка.Записать();
Кроме хранения таких значений в базе данных, с помощью хранилища значений 1С, мы также можем сохранить такое значение в файл, например:
Настройки = Новый Структура();
Настройки.Вставить(“ПоУмолчанию”, Истина);
Настройки.Вставить(“Наименование”, “Наименование1”);

Читайте также:  dead space 3 где взять вольфрам

Хранилище = Новый ХранилищеЗначения(Настройки, Новый СжатиеДанных(9));
ЗначениеВФайл(“C:”, Хранилище);

Пример – сохранение значения из файла
//Значение – картинка из файла
Файл = Новый Картинка(“C:ФайлКартинки.jpg”);
Хранилище = Новый ХранилищеЗначения(Файл, Новый СжатиеДанных(9));

//Значение – произвольный файл
Файл = Новый ДвоичныеДанные(“C:ИсполняемыйФайл.exe”);
Хранилище = Новый ХранилищеЗначения(Файл, Новый СжатиеДанных(9));

//Значение – текстовый файл
Файл = Новый ЧтениеТекста(“C:ТекстовыйФайл.txt”);
ТекстовыеДанные = Файл.Прочитать();
Хранилище = Новый ХранилищеЗначения(ТекстовыеДанные, Новый СжатиеДанных(9));
Значение, помещенное в хранилище значений 1С нельзя использовать, пока оно там находится. Чтобы работать с ним, его нужно «распаковать» обратно, например:
Знч = Хранилище.Получить();
Если Знч = Неопределено Тогда
Сообщить(“Ошибка получения значения из хранилища”);
КонецЕсли;

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

Оцените статью
Все о Windows 10
Добавить комментарий

Adblock
detector