Имя: Пароль:
1C
1С v8
Странности с реквизитом "Хранилище значений"
0 sdemon72
 
13.09.17
12:25
Здравтвуйте!
Платформа 8.3.9.1850. Имеется некий документ, в котором есть реквизит шапки с типом "Хранилище значений". Перед записью документа производится сравнение значений реквизитов отбъекта со значениями этих же реквизитов ранее сохраненной ссылки (проверка модифицированности объекта).
Так вот, для реквизита с типом "Хранилище значений" сравнение всегда выдает "Ложь". Почему?

Пример кода сравнения:
    Если Источник[Реквизит.Имя] <> Источник.Ссылка[Реквизит.Имя] Тогда
        Возврат Истина;
    КонецЕсли;
1 DrShad
 
13.09.17
12:32
да потому что сравнивать нечего
2 sdemon72
 
13.09.17
12:42
Хотелось бы подробней понять механику процесса.
Потому что условия:

Источник["Хранилише"] = Источник["Хранилише"] // Истина
Источник.Ссылка["Хранилише"] = Источник.Ссылка["Хранилише"] // Истина

И в то же время условие:

Источник["Хранилише"] = Источник.Ссылка["Хранилише"] // Ложь

В какой момент происходит модификация значений?
3 h-sp
 
13.09.17
12:47
(2) всё-таки значений нет там.
4 onetone
 
13.09.17
12:47
(0) Нужно получить значение из хранилища, а потом сравнивать.
5 onetone
 
13.09.17
12:47
на всем известном ресурсе уже выкладывали

Сравнение значений типа Хранилище.
6 DrShad
 
13.09.17
12:49
(4) и даже получив значение не факт что его получится сравнить, ведь там может быть к примеру таблица значений
7 sdemon72
 
13.09.17
12:54
В моем случае в хранилище содержится значение Неопределено.

Я правильно понимаю, что при записи объекта реквизиты с типом "Хранилище значения" всегда неявно модифицируются?
8 h-sp
 
13.09.17
12:55
(6) значит

Источник["Хранилише"] = Источник["Хранилише"]// Истина

Источник.Ссылка["Хранилише"] = Источник.Ссылка["Хранилише"]// Истина

из-за кэша? Второй раз не читает то же самое?
9 catena
 
13.09.17
12:57
" К значению, хранящемуся в объекте, нельзя обращаться, его можно только извлечь из хранилища.
"
10 sdemon72
 
13.09.17
13:01
Могу предположить что в реквизите "Хранилище" по факту содержится некий адрес в БД, по которому располагаются сами хранимые данные. При получении объекта происходит считывание этих данных из БД, а при его записи - обратное размещение в БД этих данных, но уже по другому адресу, поэтому и возникает эффект "модифицированности" реквизита "Хранилище".
11 Tateossian
 
13.09.17
13:43
(10) Ничего такого там не происходит. Вот примерно как выглядит обращение к справочнику с реквизитом хранилище значения.

Сначала получается ВЕРСИЯ объекта

exec sp_executesql N'SELECT
T1._Version
FROM dbo._Reference27364 T1 WITH(NOLOCK)
WHERE T1._IDRRef = P1',N'P1 varbinary(16)',0xBCA0CA82172FE5524FCE0C70286A28A3

Она выглядит вот так: 0x000000004373AA59

А потом выполняется вот такая операция, которая, если объект не изменился, не вернет ничего (так как он есть в кэше сервера и, значит, объект, полученный ранее будет соответствовать этой записи).

exec sp_executesql N'SELECT
T2._IDRRef,
T2._Version,
T2._Marked,
T2._IsMetadata,
T2._ParentIDRRef,
T2._Folder,
T2._Code,
T2._Description,
T2._Fld27365_TYPE,
T2._Fld27365_L,
T2._Fld27365_N,
T2._Fld27365_T,
T2._Fld27365_S,
T2._Fld27365_RTRef,
T2._Fld27365_RRRef,
T2._Fld29097,
T2._Fld31069
FROM dbo._Reference27364 T2 WITH(NOLOCK)
WHERE T2._IDRRef = P1 AND T2._Version <> @P2',N'P1 varbinary(16),@P2 varbinary(8000)',0xBCA0CA82172FE5524FCE0C70286A28A3,0x000000004373AA59

Но не будет соответствовать равенству. То есть, все логично: он всегда будет возвращать ложь)))
12 Tateossian
 
13.09.17
13:44
(11) А если изменился, то тоже будет ложь, потому что версия не совпадет
13 sdemon72
 
13.09.17
18:50
(11) А какой из реквизитов соответствует хранилищу значений, и какое значение он содержит?. И что произойдет при записи объекта?
14 kuzyara
 
14.09.17
11:22
sdemon72, ты задаешь слишком много вопросов, 1с этого не любит...
    ПомещаемоеЗначение = "1111";
    СериализуемыйОбъект = Новый ХранилищеЗначения(ПомещаемоеЗначение);
    
    // сериализуем для получения внутреннего представления
    ЗаписьXML = Новый ЗаписьXML;
    ЗаписьXML.УстановитьСтроку();
    ЗаписатьXML(ЗаписьXML, СериализуемыйОбъект);
    СтрокаXML = ЗаписьXML.Закрыть();
    // Сообщить(СтрокаXML);
    //<d1p1:ValueStorage xmlns:d1p1="http://v8.1c.ru/data">AQEPAAAAAAAAAO+7v3siUyIsIjExMTEifQ==</d1p1:ValueStorage>;
    
    ЧтениеХМL = Новый ЧтениеXML;
    ЧтениеХМL.УстановитьСтроку(СтрокаXML);
    
    // получим внутреннее представление ХЗ в виде base64-строки
    Пока ЧтениеХМL.Прочитать() Цикл
        Если ЧтениеХМL.ТипУзла = ТипУзлаXML.Текст Тогда
            СтрокаBase64 =  ЧтениеХМL.Значение;
        КонецЕсли;
    КонецЦикла;
    // Сообщить(СтрокаXML);
    //AQEPAAAAAAAAAO+7v3siUyIsIjExMTEifQ==
    
    // раскодируем base64-строку в двоичные данные
    ДвоичныеДанные = Base64Значение(СтрокаBase64);
    //Сообщить(ДвоичныеДанные);
    //01 01 0F 00 00 00 00 00 00 00 EF BB BF 7B 22 53 22 2C 22 31 31 31 31 22 7D
    
    // если хранилище со сжатием - пропустить двоичные данные через unzip (deflate)
    ФайлДанных = ПолучитьИмяВременногоФайла();
    ДвоичныеДанные.записать(ФайлДанных);
    
    // прочитаем двоичные данные в строку
    ТекстовыйДокумент = Новый ТекстовыйДокумент;
    ТекстовыйДокумент.Прочитать(ФайлДанных, "ISO-8859-1", "");
    ТекстФайла = ТекстовыйДокумент.ПолучитьТекст();
    
    // первые 14 байт - версия данных
    СтрокаСимволов = Сред(ТекстФайла, 14);
    //Сообщить(СтрокаСимволов);
    //{"S","1111"}
    
    // получим значение, находящееся в хранилище значения
    ВосстановленноеЗначение = ЗначениеИзСтрокиВнутр(СтрокаСимволов);

    //Сообщить(ПомещаемоеЗначение=ВосстановленноеЗначение);
    //истина
15 kuzyara
 
14.09.17
16:59
Процедура ПриОткрытии()
    Картинка = хзКартинка.Получить();
    хзКартинка2 = Новый ХранилищеЗначения(Картинка);
    Сообщить(хзКартинка = хзКартинка2);
    // Ложь
КонецПроцедуры
Кaк может человек ожидaть, что его мольбaм о снисхождении ответит тот, кто превыше, когдa сaм он откaзывaет в милосердии тем, кто ниже его? Петр Трубецкой