Обработка собирает все константы базы в один список и показывает то, чего не видно без кода: что лежит внутри константы типа ХранилищеЗначения. Содержимое хранилища раскрывается деревом до любой вложенности, выгружается в файл и загружается обратно. Обычная константа правится прямо под списком. Пишет обработка в базу только по кнопке «Записать» или при загрузке файла в хранилище.
Что умеет
- Список всех констант — имя, синоним, тип, значение и функциональная опция, если константа её хранит. Поиск по имени, синониму и типу, отбор по типу и по заполненности.
- Содержимое хранилища деревом — структуры, соответствия, массивы, списки, таблицы и деревья значений, хранилище внутри хранилища. У каждого узла значение и тип.
- Выгрузка в файл — файл из константы уходит как есть (картинка, двоичные данные, текст, табличный документ), коллекции — в XML.
- Загрузка из файла — положить в константу сертификат или картинку; вернуть поправленный XML обратно значением.
- Правка значения — поле с типом самой константы, пределы длины и разрядности подписаны рядом.
- Функциональная опция — какую опцию хранит константа и какими объектами эта опция управляет.
Список констант: имя, синоним, тип и значение, отбор по типу и по заполненности
Значения всех констант читаются одним набором — Константы.СоздатьНабор(""), а не обращением к базе на каждую. Отбор «Пустые» сравнивает значение с пустым значением его типа — Тип.ПривестиЗначение(Неопределено): ЗначениеЗаполнено здесь не годится, у булева он и на Ложь отвечает «заполнено».
Что внутри хранилища
Хранилище при открытии не читается. Ни размера, ни типа содержимого у ХранилищеЗначения до вызова Получить() не узнать, а внутри бывает и строка, и файл на десятки мегабайт. Поэтому в списке у хранилища стоит «содержимое по кнопке», а раскрывается оно кнопкой «Показать содержимое».
Дерево строится рекурсией. Корень — само значение, под ним элементы коллекции, под каждым элементом — снова его содержимое:
&НаСервере
Процедура ДобавитьУзел(Строки, Имя, Значение, Глубина = 0)
Узел = Строки.Добавить();
Узел.Что = Имя;
Узел.Содержимое = ПредставлениеСодержимого(Значение);
Узел.ТипУзла = ?(Значение = Неопределено, "Неопределено", Строка(ТипЗнч(Значение)));
Если Глубина >= ПределГлубины() Тогда
Край = Узел.Строки.Добавить();
Край.Что = "…";
Край.Содержимое = "глубже не разбираем: предел " + ПределГлубины() + " уровней";
Возврат;
КонецЕсли;
РазвернутьКоллекцию(Узел, Значение, Глубина);
КонецПроцедуры
Предел глубины обязателен: структура может лежать сама в себе (Кольцо.Вставить("Сама", Кольцо)), и без счётчика уровней обход такого значения не закончится никогда.
Каждая коллекция разворачивается по-своему, а для элементов снова вызывается ДобавитьУзел:
ТипКоллекции = ТипЗнч(Значение);
Если ТипКоллекции = Тип("Структура") ИЛИ ТипКоллекции = Тип("ФиксированнаяСтруктура")
ИЛИ ТипКоллекции = Тип("Соответствие") ИЛИ ТипКоллекции = Тип("ФиксированноеСоответствие") Тогда
Для Каждого Элемент Из Значение Цикл
ДобавитьУзел(Узел.Строки, Строка(Элемент.Ключ), Элемент.Значение, Глубина + 1);
КонецЦикла;
ИначеЕсли ТипКоллекции = Тип("Массив") ИЛИ ТипКоллекции = Тип("ФиксированныйМассив") Тогда
Для Индекс = 0 По Значение.ВГраница() Цикл
ДобавитьУзел(Узел.Строки, "[" + Индекс + "]", Значение[Индекс], Глубина + 1);
КонецЦикла;
ИначеЕсли ТипКоллекции = Тип("ТаблицаЗначений") Тогда
Номер = 0;
Для Каждого СтрокаТаблицы Из Значение Цикл
Номер = Номер + 1;
СтрокаУзел = Узел.Строки.Добавить();
СтрокаУзел.Что = "строка " + Номер;
СтрокаУзел.Содержимое = "колонок: " + Значение.Колонки.Количество();
СтрокаУзел.ТипУзла = "СтрокаТаблицыЗначений";
Для Каждого Колонка Из Значение.Колонки Цикл
ДобавитьУзел(СтрокаУзел.Строки, Колонка.Имя, СтрокаТаблицы[Колонка.Имя], Глубина + 2);
КонецЦикла;
КонецЦикла;
ИначеЕсли ТипКоллекции = Тип("ХранилищеЗначения") Тогда
ДобавитьУзел(Узел.Строки, "внутри", Значение.Получить(), Глубина + 1);
КонецЕсли;
Список значений и дерево значений разбираются так же, у строк дерева номер идёт с путём — «строка 2.1.3», чтобы было видно, какая кому подчинена. У коллекции в колонке «Значение» стоит её размер — «полей: 2», «строк: 12», у файла — размер в байтах.
Содержимое хранилища деревом: структура, в ней соответствие, в нём массив структур — у каждого узла значение и тип
Выгрузка в файл и загрузка обратно
Кнопки «Сохранить в файл» и «Загрузить из файла» закрывают три задачи:
- достать файл из константы — сертификат, логотип, печатную форму: они уходят в своём формате,
.bin,.png,.txt,.mxl; - посмотреть и поправить — коллекции выгружаются в XML, правятся в редакторе и загружаются обратно значением;
- положить файл в константу — выбором файла, без строчки кода.
Коллекцию обработка выгружает сериализатором XDTO прямо в поток в памяти, без временного файла на диске:
Поток = Новый ПотокВПамяти;
Запись = Новый ЗаписьXML;
Запись.ОткрытьПоток(Поток);
Попытка
СериализаторXDTO.ЗаписатьXML(Запись, Внутри);
Исключение
Запись.Закрыть();
Ответ.Причина = "В файл не выгружается: " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
Возврат Ответ;
КонецПопытки;
Запись.Закрыть();
Двоичные = Поток.ЗакрытьИПолучитьДвоичныеДанные();
Двоичные данные кладутся во временное хранилище, а клиент забирает их асинхронным НачатьПолучениеФайлаССервера — в веб-клиенте файл уходит в загрузки браузера. Принимает файл так же асинхронный НачатьПомещениеФайлаНаСервер.
Загруженный XML обработка молча в структуру не превращает. Если файл похож на выгрузку значения, она спрашивает, загрузить его значением или положить файлом как есть: настоящий XML-файл — обмен, лицензия, конфиг — иначе превратился бы в структуру. Похож ли файл на выгрузку, отвечает сам сериализатор:
Значение = Неопределено;
Чтение = Новый ЧтениеXML;
Попытка
Чтение.ОткрытьПоток(Двоичные.ОткрытьПотокДляЧтения());
Чтение.Прочитать();
Если СериализаторXDTO.ВозможностьЧтенияXML(Чтение) Тогда
Значение = СериализаторXDTO.ПрочитатьXML(Чтение);
КонецЕсли;
Исключение
Значение = Неопределено;
КонецПопытки;
Строка Чтение.Прочитать() перед ВозможностьЧтенияXML обязательна. Сразу после открытия позиция стоит перед документом, и сериализатор отвечает «читать не могу» даже на собственную выгрузку — без ошибки, просто ложью. Чужой XML он читать не берётся, и такой файл ложится в хранилище как есть.
Ссылки в XML выгружаются идентификатором. В своей базе файл загрузится и вернёт тот же элемент справочника, в чужой — ссылку на несуществующий объект. Переносить так значения со ссылками между базами нельзя.
Правка значения
Значение правится в поле под списком, а не в ячейке: колонка одна на константы всех типов, а поле под списком подстраивается под тип выбранной — ПолеПравки.ОграничениеТипа = КонстантаМД.Тип. Вместе с типом поле берёт из метаданных и разрядность: у пятиразрядной числовой константы шестую цифру не ввести. Пределы подписаны рядом словами. Пока не нажата «Записать», база не меняется.
Правка значения: поле принимает только тип константы, рядом — ограничения по длине и разрядности
Очищенное поле отдаёт Неопределено, а константе нужно значение своего типа, поэтому перед записью оно приводится: КонстантаМД.Тип.ПривестиЗначение(ЭтотОбъект.Правка) — пустая ссылка, ноль или пустая строка.
Функциональная опция константы
Если константа хранит функциональную опцию, это видно в списке, а под ним — какими объектами опция управляет. Где лежит значение опции, говорит её свойство Хранение (не Хранилище), а на что она влияет — коллекция Состав, у элемента которой значимо свойство Объект.
Функциональная опция константы и объекты, на которые она влияет
Сценарии
- Константа-хранилище с настройками или токеном: «Показать содержимое» раскрывает структуру до последнего поля.
- Сертификат или картинка в константе: «Сохранить в файл» отдаёт файл, «Загрузить из файла» кладёт новый.
- Настройки в хранилище нужно поправить: выгрузили в XML, исправили в редакторе, загрузили значением.
- Отбор «Пустые» по типу «Булево» — какие признаки в базе выключены.
- Перед тем как трогать константу функциональной опции — какими объектами эта опция управляет.
Поставка
Konstanty.epf — внешняя обработка; расширений и внешних компонент не требует. Код открыт и лежит в модуле формы.
Проверено на следующих конфигурациях и релизах:
- Управление нашей фирмой, редакция 3.0, релизы 3.0.14.143
Вступайте в нашу телеграмм-группу Инфостарт



