1с тип не определен хранилищезначения

Обновлено: 06.07.2024

Объект "ХранилищеЗначения" известен в 1С, начиная с 8.0 и, казалось бы, прост, понятен, изучен вдоль и поперёк. Но иногда возникают вопросы, касающиеся работы с хранилищем, и данная публикация (по сути, краткий антисклерозник) призвана зафиксировать ответы на некоторые из них.


Хранилище значения (далее ХЗ) представляет собой данные, полученные кодированием и, при необходимости, сжатием входных данных с помощью 32-х битного алгоритма // из строки в ХЗ хз=XMLЗначение(Тип("ХранилищеЗначения"),ИсходнаяСтрокаBase64); // из ХЗ в строку ИтоговаяСтрокаBase64=XMLСтрока(ХЗ);

Важно понимать, что ХЗ это не значение, а указатель на область памяти. Они всегда разные, поэтому ни сравнение, ни поиск, ни отбор (в т.ч. в запросах) применять нельзя. Указатель равен сам себе лишь в рамках конкретного оператора-конструктора (и, кстати, в этом случае по нему работает, например, поиск в универсальных коллекциях). Так, например, если "А=хз; Б=А;", то А будет равно Б. А для сравнения именно значений следует действовать так (причём это не будет распаковкой как "расжатием"):

и это не зависит от наличия и степени сжатия в их конструкторах. Кстати, после применения конструктора определить степень сжатия можно лишь преобразованием в двоичные данные и анализом первых битов потока.

Так вот, размер "как есть" мы можем узнать, либо создав объект метаданных (например, справочник с единственным реквизитом типа ХЗ) и получив размер таблицы методом ПолучитьРазмерДанныхБазыДанных, либо опосредованно, через строку и двоичные данные (учитывая неизбежно прибавляемое), так:

Это не годится для абсолютных замеров (так, один символ латиницы, т.е. по идее 1 байт, и символ кириллицы, 2 байта, дают одинаковые 32 байта на выходе), но годится для относительных прикидок. Так, вызов без прямого указания "СжатиеДанных" всегда даёт значение большего (и иногда существенно большего, в разы) размера, чем с любым сжатием. На малых размерах сжатие не даёт заметного эффекта при любом аргументе. В СП сказано, что аргумент по умолчанию для объекта "СжатиеДанных" равен 1, но сжатие без его указания и с явным указанием даёт разные размеры, до десятков и сотен байт. На средних объектах (например, строки 500-1000 символов) сжатие со степенью выше 3-4 даёт примерно одинаковые итоговые размеры, т.е. эффективность одинаковая. Наряду с этим, в ряде старых релизов конструктор без сжатия даёт меньший итоговый размер.

Деструкция этого указателя тоже имеет нюансы.

В таблицах/деревьях значений с явно объявленной колонкой может использоваться везде, кроме запроса (не помещается в ВТ), не воспринимается как аргумент запроса, даже как &ПараметрТипаХЗ в секции "ВЫБРАТЬ". Что, учитывая известное про СУБД, не вполне логично.

При копировании объекта с реквизитами, содержащими ХЗ, ни интерфейсно, ни программно, эти значения НЕ наследуются, не копируются.

Если некое значение, упакованное в ХЗ, подпадает под RLS, то логика следующая - платформа всегда вначале выполняет неявную распаковку, либо рассматривает сделанную в коде явную; а затем накладывает ограничение, так что RLS применится именно для уже распакованного значения, спровоцировать тут ошибку ни разу не удалось.

Из интересных публикаций рекомендую эту.

Поскольку в современных метаданных конфигураций реквизит типа ХЗ где-нибудь точно наличествует, а также фигурирует в коде, то вопрос занимаемого им места актуален. В связи с этим было бы интересно исследовать рост места, занимаемого таблицей, состоящей исключительно из ХЗ, а также сравнить эффективность работы "СжатиеДанных" и основанного на том же Deflation объекта "ЗаписьZipФайла", пробуя разные значения УровеньСжатияZIP (естественно, при МетодСжатияZIP = "Сжатие").

Возможно, этот привычный и вроде бы простой объект, Хранилище значения, преподнесёт (особенно на больших данных и нагрузках) ещё некоторые удивительные сюрпризы.

Читайте также: