Добрый день всем!
Вот столкнулся с такой штукой, как "сериализация" фильтра компоновки данных с помощью метода "ЗначениеВСтрокуВнутр" платформы. Суть в том, что платформа сначала сериализует данный объект в XML, а затем этот XML кодирует в base64 и помещает в некий JSON-контейнер с типом и данными. Тип - это некий идентификатор, а данные - это тот самый закодированный в base64 сериализованный XML.
Рассуждать на тему того, почему 1С решили сделать таким образом, особого смысла нет - сделали - и слава Богу!* Но вот решил я все-таки декодировать base64-строку в текст и не нашел соответствующего метода платформы. В двоичные данные - пожалуйста, а в текст - нет. Но в последних релизах платформы объект "ДвоичныеДанные" оброс знатным функционалом, что просто не могло не обрадовать многих специалистов по 1С. В итоге родился такой вот замечательный код:
// Данные - это что-то, что было сериализовано с помощью "ЗначениеВСтрокуВнутр"
Поз = СтрНайти(Данные, "#base64");
ПС = Сред(Данные, поз+8);
Поз2 = СтрНайти(ПС, "}");
ПС = Лев(ПС, Поз2-1);
ЧД = Новый ЧтениеДанных(Base64Значение(ПС));
СтрокаXML = ЧД.ПрочитатьСимволы();
У нас тут есть, допустим, какие-то данные, которые мы откуда-то взяли. Например:
Данные = ЗначениеВСтрокуВнутр(ОтборКомпоновкиДанных);
В итоге у нас получилась какая-то такая строка:
{"#",f6841c6b-6c71-4c82-ae9e-d08b49db326c,
{#base64:77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxGaWx0
ZXIgeG1sbnM9Imh0dHA6Ly92OC4xYy5ydS84LjEvZGF0YS1jb21wb3NpdGlvbi1z
eXN0ZW0vc2V0dGluZ3MiIHhtbG5zOnhzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAx
L1hNTFNjaGVtYSIgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hN
TFNjaGVtYS1pbnN0YW5jZSI+DQoJPGl0ZW0geHNpOnR5cGU9IkZpbHRlckl0ZW1H
cm91cCI+DQoJCTxncm91cFR5cGU+QW5kR3JvdXA8L2dyb3VwVHlwZT4NCgkJPGl0
ZW0geHNpOnR5cGU9IkZpbHRlckl0ZW1Db21wYXJpc29uIj4NCgkJCTxsZWZ0IHht
bG5zOmRjc2Nvcj0iaHR0cDovL3Y4LjFjLnJ1LzguMS9kYXRhLWNvbXBvc2l0aW9u
LXN5c3RlbS9jb3JlIiB4c2k6dHlwZT0iZGNzY29yOkZpZWxkIj7QodGH0LXRgtCU
0YIu0JrQvtC0PC9sZWZ0Pg0KCQkJPGNvbXBhcmlzb25UeXBlPkNvbnRhaW5zPC9j
b21wYXJpc29uVHlwZT4NCgkJCTxyaWdodCB4c2k6dHlwZT0ieHM6c3RyaW5nIj4x
MDYuMDE8L3JpZ2h0Pg0KCQk8L2l0ZW0+DQoJCTxpdGVtIHhzaTp0eXBlPSJGaWx0
ZXJJdGVtQ29tcGFyaXNvbiI+DQoJCQk8bGVmdCB4bWxuczpkY3Njb3I9Imh0dHA6
Ly92OC4xYy5ydS84LjEvZGF0YS1jb21wb3NpdGlvbi1zeXN0ZW0vY29yZSIgeHNp
OnR5cGU9ImRjc2NvcjpGaWVsZCI+0KHRg9Cx0LrQvtC90YLQvtCU0YIxLlvQodC4
0LzQstC+0Lsg0J7QpNCgKyDQktC40LTRiyDQvdC+0LzQtdC90LrQu9Cw0YLRg9GA
0YsgXTwvbGVmdD4NCgkJCTxjb21wYXJpc29uVHlwZT5FcXVhbDwvY29tcGFyaXNv
blR5cGU+DQoJCQk8cmlnaHQgeG1sbnM6ZDRwMT0iaHR0cDovL3Y4LjFjLnJ1Lzgu
MS9kYXRhL2VudGVycHJpc2UvY3VycmVudC1jb25maWciIHhzaTp0eXBlPSJkNHAx
OkNhdGFsb2dSZWYu0L3RhNC+X9CX0L3QsNGH0LXQvdC40Y/QkNC90LDQu9C40YLQ
uNC60LgiPmE1Yzg2MjQwLWRmOTMtMTFlNS05NDU2LTAwMWU2NzU0ODlmNDwvcmln
aHQ+DQoJCTwvaXRlbT4NCgk8L2l0ZW0+DQo8L0ZpbHRlcj4=}
}
Дальше мы из этой строки получаем данные base64, которые обрамлены символами "{#base64:" и "}". Т.е. получаем все, что между этими символами.
После этого мы декодируем строку base64 в двоичные данные давно известной функцией. И вот из этих двоичных данных получить строку не так-то просто. Раньше можно было записать файл и потом прочитать его в виде текста. Но операции ввода-вывода достаточно затратны. В новой платформе (у меня 8.3.10.2168) появились функции работы с потоками двоичных данных. Мы здесь используем объект "ЧтениеДанных", который можно создать на основании двоичных данных, полученных с помощью функции "Base64Значение". У объекта "ЧтениеДанных" есть метод "ПрочитатьСимволы()", который без параметров просто возвращает нам в кодировке по-умолчению все символы из двоичных данных. Таким образом, в переменной "СтрокаXML" будет находиться следующее значение:
<?xml version="1.0" encoding="UTF-8"?>
<Filter xmlns="http://v8.1c.ru/8.1/data-composition-system/settings" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<item xsi:type="FilterItemGroup">
<groupType>AndGroup</groupType>
<item xsi:type="FilterItemComparison">
<left xmlns:dcscor="http://v8.1c.ru/8.1/data-composition-system/core" xsi:type="dcscor:Field">СчетДт.Код</left>
<comparisonType>Contains</comparisonType>
<right xsi:type="xs:string">106.01</right>
</item>
<item xsi:type="FilterItemComparison">
<left xmlns:dcscor="http://v8.1c.ru/8.1/data-composition-system/core" xsi:type="dcscor:Field">СубконтоДт1.[Символ ОФР+ Виды номенклатуры ]</left>
<comparisonType>Equal</comparisonType>
<right xmlns:d4p1="http://v8.1c.ru/8.1/data/enterprise/current-config" xsi:type="d4p1:CatalogRef.нфо_ЗначенияАналитики">a5c86240-df93-11e5-9456-001e675489f4</right>
</item>
</item>
</Filter>
Надеюсь, новый функционал платформы может быть полезен для оптимизации различных операций для работы со строками, находящимися в объекте ДвоичныеДанные.