# JSON DSL для схемы компоновки данных (СКД) Компактный JSON-формат для описания `DataCompositionSchema` (Template.xml). Компилируется навыком `/skd-compile` в XML, валидируется `/skd-validate`. --- ## 1. Корневая структура ```json { "dataSources": [...], "dataSets": [...], "dataSetLinks": [...], "calculatedFields": [...], "totalFields": [...], "parameters": [...], "templates": [...], "groupTemplates": [...], "settingsVariants": [...] } ``` **Умолчания:** - `dataSources` опущен → авто-создаётся `{ "name": "ИсточникДанных1", "type": "Local" }` - `source` в наборе опущен → первый dataSource - `name` набора опущен → "НаборДанных1", "НаборДанных2"... - `settingsVariants` опущен → один вариант "Основной" с детальной группировкой и `selection: ["Auto"]` --- ## 2. Источники данных (dataSources) ```json "dataSources": [ { "name": "ИсточникДанных1", "type": "Local" } ] ``` | Поле | Обязат. | Умолчание | XML-маппинг | |------|---------|-----------|-------------| | `name` | да | — | `` | | `type` | нет | `"Local"` | `` | Значения `type`: `"Local"`, `"External"`. --- ## 3. Наборы данных (dataSets) Тип определяется по ключу-дискриминатору: | Ключ | Тип | xsi:type | |------|-----|----------| | `query` | Запрос | `DataSetQuery` | | `objectName` | Объект | `DataSetObject` | | `items` | Объединение | `DataSetUnion` | ### DataSetQuery (самый частый) ```json { "name": "Продажи", "query": "ВЫБРАТЬ ...", "fields": [...], "autoFillFields": false } ``` ### DataSetObject ```json { "name": "ТаблицаПроверки", "objectName": "ТаблицаПроверки", "fields": [...] } ``` ### DataSetUnion ```json { "name": "Объединение", "items": [ { "name": "Набор1", "query": "...", "fields": [...] }, { "name": "Набор2", "query": "...", "fields": [...] } ], "fields": [...] } ``` | Поле | Обязат. | Описание | |------|---------|----------| | `name` | нет | Авто: "НаборДанных1"... | | `source` | нет | Имя dataSource (авто: первый) | | `query` | да* | Текст запроса (DataSetQuery). Поддерживает `@file` — см. ниже | | `objectName` | да* | Имя объекта (DataSetObject) | | `items` | да* | Вложенные наборы (DataSetUnion) | | `fields` | нет | Массив полей | | `autoFillFields` | нет | `false` — отключить автозаполнение (по умолчанию не выводится = true) | ### Ссылка на внешний файл запроса (@file) Вместо inline-текста запроса можно указать путь к внешнему файлу с префиксом `@`: ```json { "query": "@queries/sales.sql" } ``` Порядок разрешения пути: 1. Абсолютный путь — используется как есть 2. Относительно директории JSON-файла определения 3. Относительно текущей рабочей директории (CWD) 4. Если файл не найден — ошибка компиляции --- ## 4. Поля — shorthand и объектная форма ### Shorthand-строка ``` "[: ] [@role...] [#restrict...]" ``` Примеры: ```json "fields": [ "Наименование", "Количество: decimal(15,2)", "Организация: CatalogRef.Организации @dimension", "Служебное: string #noFilter #noOrder", "Счёт: CatalogRef.Хозрасчетный @account", "Сумма: decimal(15,2) @balance", "СуммаНач: decimal(15,2) @balance balanceGroupName=Сумма balanceType=OpeningBalance" ] ``` ### Объектная форма ```json { "dataPath": "Сумма", "field": "Сумма", "title": "Сумма продаж", "type": "decimal(15,2)", "role": { "dimension": true }, "restrict": ["noFilter", "noGroup"], "attrRestrict": ["noFilter"], "appearance": { "Формат": "ЧДЦ=2" }, "presentationExpression": "Формат(Сумма, \"ЧДЦ=2\")", "orderExpression": { "expression": "ЕстьNULL(Поле.Порядок, 10000)", "orderType": "Asc", "autoOrder": false }, // или массив (если на поле несколько для multi-sort fallback): // "orderExpression": [{...}, {...}] "availableValues": [ { "value": 1, "presentation": { "ru": "Доход", "en": "Income" } }, { "value": 2, "presentation": { "ru": "Расход", "en": "Expense" } } ] } ``` `availableValues` — список допустимых значений поля с (опциональной multilang) подписью. Типы значений автоопределяются (`bool`/`decimal`/`dateTime`/`string`); можно указать `valueType` явно. Аналогичное поле существует на `parameters` — см. раздел 6. ### Парсинг shorthand 1. Извлечь `@`-роли (regex `@(\w+)`), `#`-ограничения (`#(\w+)`), KV-пары роли (`(\w+)=(\S+)`) 2. Остаток до первого `:` — `dataPath` (и `field` по умолчанию) 3. После `:` — тип ### Типы | DSL | XML v8:Type | Квалификатор | |-----|-------------|--------------| | `string` | `xs:string` | Length=0, AllowedLength=Variable | | `string(N)` | `xs:string` | Length=N, AllowedLength=Variable | | `decimal(D,F)` | `xs:decimal` | Digits=D, FractionDigits=F, AllowedSign=Any | | `decimal(D,F,nonneg)` | `xs:decimal` | Digits=D, FractionDigits=F, AllowedSign=Nonnegative | | `boolean` | `xs:boolean` | — | | `date` | `xs:dateTime` | DateFractions=Date | | `dateTime` | `xs:dateTime` | DateFractions=DateTime | | `CatalogRef.XXX` | `d5p1:CatalogRef.XXX` | inline xmlns:d5p1 | | `DocumentRef.XXX` | `d5p1:DocumentRef.XXX` | inline xmlns:d5p1 | | `EnumRef.XXX` | `d5p1:EnumRef.XXX` | inline xmlns:d5p1 | | `ChartOfAccountsRef.XXX` | `d5p1:ChartOfAccountsRef.XXX` | inline xmlns:d5p1 | | `StandardPeriod` | `v8:StandardPeriod` | — | | `DocumentRef` (без `.XXX`) | `d5p1:DocumentRef` | композитный тип-набор (все ссылки указанного класса) | > **Ссылочные типы** (`CatalogRef.XXX`, `DocumentRef.XXX` и др.) эмитируются с inline namespace declaration: `d5p1:CatalogRef.XXX`. Использование префикса `cfg:` вместо `d5p1:` с объявлением namespace приводит к ошибке XDTO. Сборка EPF со ссылочными типами требует базу с соответствующей конфигурацией (не пустую). > **TypeSet (тип-набор)** — голое имя без точки (`CatalogRef`, `DocumentRef`, `EnumRef`, `ChartOfAccountsRef`, `ChartOfCharacteristicTypesRef`, `ChartOfCalculationTypesRef`, `BusinessProcessRef`, `TaskRef`, `ExchangePlanRef`, `InformationRegisterRef`, `AnyRef`) — указывает на **все** ссылки этого класса конфигурации (а не на конкретный объект). Эмитится как `` вместо ``. Используется в параметрах типа «исключаемые документы» и подобных. ### Синонимы типов Все имена типов регистронезависимые. Поддерживаются русские и альтернативные имена: | Синоним | Канонический тип | |---------|-----------------| | `число`, `Число` | `decimal` | | `строка`, `Строка` | `string` | | `булево`, `Булево`, `bool` | `boolean` | | `дата`, `Дата` | `date` | | `датаВремя`, `ДатаВремя` | `dateTime` | | `СтандартныйПериод` | `StandardPeriod` | | `int`, `integer`, `number`, `num` | `decimal` | | `СправочникСсылка.XXX` | `CatalogRef.XXX` | | `ДокументСсылка.XXX` | `DocumentRef.XXX` | | `ПеречислениеСсылка.XXX` | `EnumRef.XXX` | | `ПланСчетовСсылка.XXX` | `ChartOfAccountsRef.XXX` | | `ПланВидовХарактеристикСсылка.XXX` | `ChartOfCharacteristicTypesRef.XXX` | Параметризованные: `число(15,2)` → `decimal(15,2)`, `строка(100)` → `string(100)`. ### Роли Принимаются четыре формы: ```json "role": "dimension" // одиночный флаг "role": ["dimension", "required"] // массив флагов "role": "balance balanceGroupName=Сумма balanceType=OpeningBalance" // shorthand "role": { "balance": true, "balanceGroupName": "Сумма", "balanceType": "OpeningBalance" } ``` Shorthand-формат может быть встроен прямо в shorthand поля: ``` "Сумма: decimal(15,2) @balance balanceGroupName=Сумма balanceType=OpeningBalance" ``` **Парсинг shorthand**: `@(\w+)` → boolean флаги; `(\w+)=(\S+)` → строковые KV; остаток — `dataPath[: type]`. **Поддерживаемые ключи**: | Категория | Ключи | |-----------|-------| | `@`-флаги (boolean) | `@dimension`, `@account`, `@balance`, `@period`, `@required`, `@autoOrder`, `@ignoreNullValues` | | Строковые KV | `balanceGroupName`, `balanceType` (`OpeningBalance`/`ClosingBalance`), `parentDimension`, `accountTypeExpression`, `expression`, `orderType` (`Asc`/`Desc`), `periodNumber`, `periodType` | Whitelist'а нет — любой `` принимается; перечисленные — типичные. `@period` — sugar для `periodNumber=1` + `periodType=Main` (можно переопределить явно). **XML-выход**: `true` для флагов; `VALUE` для KV. > Устаревший ключ `balanceGroup` в object-форме принимается как alias для `balanceGroupName` (имя элемента в реальном XML — `balanceGroupName`). ### Ограничения | DSL shorthand | Объектная форма | XML useRestriction | |---------------|----------------|-----| | `#noField` | `"noField"` | `true` | | `#noFilter` / `#noCondition` | `"noFilter"` | `true` | | `#noGroup` | `"noGroup"` | `true` | | `#noOrder` | `"noOrder"` | `true` | ### Оформление (appearance) ```json "appearance": { "Формат": "ЧДЦ=2", "ГоризонтальноеПоложение": "Center" } ``` Маппинг на XML: ```xml Формат ЧДЦ=2 ``` Значения `ГоризонтальноеПоложение` → `xsi:type="v8ui:HorizontalAlign"`. --- ## 5. Итоговые поля (totalFields) ### Shorthand ``` ": <Функция>" ": <Функция>(<выражение>)" ``` Примеры: ```json "totalFields": [ "Количество: Сумма", "Цена: Максимум", "Стоимость: Сумма(Кол * Цена)" ] ``` **Парсинг:** `"A: Func"` → `dataPath=A`, `expression=Func(A)`. `"A: Func(expr)"` → `dataPath=A`, `expression=Func(expr)`. Функции (русские): `Сумма`, `Количество`, `Максимум`, `Минимум`, `Среднее`. ### Объектная форма ```json { "dataPath": "X", "expression": "Максимум(X)", "group": "Группа1" } ``` ### Привязка к группировкам (group) В объектной форме поле `group` может быть строкой или массивом строк. Каждая строка задаёт имя группировки, для которой вычисляется итог: ```json "totalFields": [ { "dataPath": "Кол", "expression": "Сумма(Кол)", "group": ["ГруппаПользователей", "ГруппаПользователей Иерархия", "ОбщийИтог"] } ] ``` XML-маппинг — по `` на каждый элемент: ```xml Кол Сумма(Кол) ГруппаПользователей ГруппаПользователей Иерархия ОбщийИтог ``` --- ## 6. Параметры (parameters) ### Shorthand ``` ": [= ] [@autoDates] [@valueList] [@hidden]" ``` Примеры: ```json "parameters": [ "Период: StandardPeriod = LastMonth @autoDates", "Организация: CatalogRef.Организации", "ДатаОтчета: date" ] ``` **Парсинг:** `"A: T = V"` → `name=A`, `type=T`, `value=V`. Значение `LastMonth` и другие варианты периодов → `v8:StandardPeriod` с `v8:variant`. `` может быть **списком** — несколько значений через запятую (с `'...'` для запятой внутри значения). В этом случае эмитятся несколько ``, а `valueListAllowed=true` выводится автоматически (явный `@valueList` не нужен). Эквивалент объектной формы `"value": [ ... ]`. ```json "parameters": ["Виды: ChartOfCharacteristicTypesRef.ВидыСубконтоХозрасчетные = ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты, ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры"] ``` ### @autoDates Флаг `@autoDates` в shorthand параметра автоматически генерирует два дополнительных параметра: - `ДатаНачала` (date, expression=`&<Имя>.ДатаНачала`, availableAsField=false) - `ДатаОкончания` (date, expression=`&<Имя>.ДатаОкончания`, availableAsField=false) Заменяет типовой бойлерплейт из 5 строк на 1: ```json // Было: "parameters": [ "Период: StandardPeriod = LastMonth", { "name": "ДатаНачала", "type": "date", "expression": "&Период.ДатаНачала", "availableAsField": false }, { "name": "ДатаОкончания", "type": "date", "expression": "&Период.ДатаОкончания", "availableAsField": false } ] // Стало: "parameters": ["Период: StandardPeriod = LastMonth @autoDates"] ``` ### @valueList Флаг `@valueList` генерирует `true` — разрешает передавать список значений в параметр: ```json "parameters": ["Организации: CatalogRef.Организации @valueList"] ``` ### @hidden Флаг `@hidden` — скрытый параметр. Автоматически ставит `availableAsField=false` и исключает параметр из автогенерируемых `dataParameters` при `"dataParameters": "auto"`: ```json "parameters": [ { "name": "Счет43", "type": "ChartOfAccountsRef.Хозрасчетный", "value": "...", "hidden": true }, "СкрытыйПараметр: string = test @hidden" ] ``` ### Объектная форма ```json { "name": "ДатаНач", "title": "Дата начала", "type": "date", "value": "0001-01-01T00:00:00", "expression": "&Период.ДатаНачала", "availableAsField": false, "useRestriction": true, "use": "Always" } ``` | Поле | Описание | |------|----------| | `name` | Имя параметра | | `title` | Заголовок (умолч. = name) | | `type` | Тип (см. таблицу типов) | | `value` | Значение по умолчанию (скаляр; для `valueListAllowed=true` — массив значений по умолчанию: `[ "ПланСчетов.Хозрасчетный.X", "...Y", "...Z" ]`) | | `expression` | Выражение для вычисления | | `availableAsField` | `false` — скрыть из полей | | `valueListAllowed` | `true` — разрешить список значений | | `hidden` | `true` — скрытый параметр (авто `availableAsField=false`, исключение из `dataParameters: auto`) | | `useRestriction` | `true` — скрыть от пользователя | | `use` | `"Always"`, `"Auto"` | | `denyIncompleteValues` | `true` — запретить произвольные значения (только из availableValues) | | `availableValues` | Массив `[{value, presentation}]` — допустимые значения с представлениями. Типы (bool/int/decimal) сохраняются нативно в JSON | | `inputParameters` | Параметры ввода (например `ФорматРедактирования`) — массив `[{parameter, value, valueType?, choiceParameters?, choiceParameterLinks?}]`. `valueType: {uri, name}` сохраняет кастомный xsi:type с локальным xmlns (например `d6p1:FoldersAndItemsUse`). В `choiceParameters[i].values` элементы — bool/int/double/string; compile эмитит соответствующий xsi:type (`xs:boolean` / `xs:decimal` / `dcscor:DesignTimeValue`) | | `nilValue` | `true` — эмитить `` для параметров с явным типом (decimal/string/dateTime), где XML-сериализатор обычно ставит типизированный default. Bit-perfect round-trip | ### availableValues Список допустимых значений параметра. Тип значения определяется автоматически (`Перечисление.*`, `Справочник.*` и др. → `dcscor:DesignTimeValue`): ```json { "name": "ПорядокОкругления", "type": "EnumRef.Округления", "value": "Перечисление.Округления.Окр1_00", "use": "Always", "denyIncompleteValues": true, "availableValues": [ {"value": "Перечисление.Округления.Окр1_00", "presentation": "руб. коп"}, {"value": "Перечисление.Округления.Окр1", "presentation": "руб."}, {"value": "Перечисление.Округления.Окр1000", "presentation": "тыс. руб"} ] } ``` ### Значения параметров по типу | Тип | value | XML | |-----|-------|-----| | `StandardPeriod` | `"LastMonth"`, `"ThisYear"` и др. | `LastMonth` | | `date` | `"0001-01-01T00:00:00"` | `xsi:type="xs:dateTime"` | | `string` | `"текст"` | `xsi:type="xs:string"` | | `boolean` | `true`/`false` | `xsi:type="xs:boolean"` | Стандартные варианты периодов: `Custom`, `Today`, `ThisWeek`, `ThisMonth`, `ThisQuarter`, `ThisYear`, `LastMonth`, `LastQuarter`, `LastYear`. --- ## 7. Вычисляемые поля (calculatedFields) ### Shorthand ``` " = " ``` ```json "calculatedFields": [ "УИД = Строка(Ссылка.УникальныйИдентификатор())", "Итого = Количество * Цена" ] ``` ### Объектная форма ```json { "dataPath": "Итого", "expression": "Количество * Цена", "title": "Итого", "type": "decimal(15,2)", "restrict": ["noGroup"], "appearance": { "Формат": "ЧДЦ=2" } } ``` Ключ `field` — алиас для `dataPath` (используется если `dataPath` не указан). --- ## 8. Связи наборов (dataSetLinks) Только объектная форма: ```json "dataSetLinks": [ { "source": "Периоды", "dest": "Данные", "sourceExpr": "Месяц", "destExpr": "Месяц", "parameter": "НачалоМесяца" } ] ``` | Поле | XML | |------|-----| | `source` / `sourceDataSet` | `` | | `dest` / `destinationDataSet` | `` | | `sourceExpr` / `sourceExpression` | `` | | `destExpr` / `destinationExpression` | `` | | `parameter` | `` (опц.) | | `parameterListAllowed` | `true` (опц., bool) | | `startExpression` | `` (опц.) | | `linkConditionExpression` | `` (опц.) | decompile эмитит длинные имена (`sourceDataSet` и т.д.); compile принимает обе формы. --- ## 9. Варианты настроек (settingsVariants) ```json "settingsVariants": [{ "name": "Основной", "presentation": "Основной вариант", "settings": { "userFields": [...], "selection": [...], "filter": [...], "order": [...], "conditionalAppearance": [...], "outputParameters": {...}, "dataParameters": [...], "structure": [...], "additionalProperties": { "ВариантНаименование": "...", "Адрес": "..." } } }] ``` `additionalProperties` — словарь служебных свойств варианта (`` в XML), значения сохраняются как `xs:string`. Платформа использует его для типа «имя варианта», URL временного хранилища и т.п. — для bit-perfect round-trip сохраняется как есть, обычно модели заполнять не нужно. ### selection ```json "selection": [ "Наименование", { "field": "Количество", "title": "Кол-во" }, { "field": "Контрагент", "viewMode": "Inaccessible" }, { "field": "Скрытое", "use": false }, { "auto": true, "use": false }, "Auto" ] ``` - Строка → `SelectedItemField` - `"Auto"` → `SelectedItemAuto` (только на уровне группировок; на верхнем уровне settings игнорируется) - Объект с `field` + опц. `title`/`viewMode`/`use` → `SelectedItemField`. `use: false` = поле выборки отключено (видно в UI, но не применяется) - Объект `{ auto: true, use: false }` → отключённый `SelectedItemAuto` - Объект с `folder`/`items` → `SelectedItemFolder` — группа полей с заголовком и `placement=Auto`: ```json "selection": [ "Auto", "Счет", {"folder": "Поступление", "items": ["ПолеА", "ПолеБ", "ПолеВ"]}, {"folder": "Выбытие", "items": ["ВыбытиеРеализовано", "ВыбытиеПрочее"]} ] ``` Опциональное поле `placement` (`Auto` / `Horizontally` / `Vertically` / `Special`) задаёт расположение элементов внутри группы (по умолчанию `Auto`): ```json {"folder": "Экономия ФОТ", "items": ["ЭкономияФОТ", "ЭкономияФОТПроцент"], "placement": "Horizontally"} ``` ### filter #### Shorthand-строка ```json "filter": [ "Организация = _ @off @user", "Дата >= 2024-01-01T00:00:00", "Статус filled", "Количество > 0" ] ``` Формат: `"<Поле> <оператор> [<значение>] [@off] [@user] [@quickAccess] [@normal] [@inaccessible]"`. - Значение `_` — пустое (placeholder, не выводится в XML) - `@off` → `use=false` - `@user` → `userSettingID=auto` (генерировать GUID) - `@quickAccess` → `viewMode=QuickAccess` - `@normal` → `viewMode=Normal` (явный — для bit-perfect, см. [viewMode](#viewmode-режим-доступности)) - `@inaccessible` → `viewMode=Inaccessible` - Типы значений автоопределяются: `true`/`false` → `xs:boolean`, дата `2024-01-01T00:00:00` → `xs:dateTime`, числа → `xs:decimal`, `Перечисление.X.Y`/`Справочник.X.Y`/`ПланСчетов.X.Y` и др. → `dcscor:DesignTimeValue`, остальное → `xs:string` - Типы значений автоопределяются: `true`/`false` → boolean, `2024-01-01T00:00:00` → dateTime, числа → decimal, `Перечисление.*`/`Справочник.*`/`ПланСчетов.*`/`Документ.*` → DesignTimeValue, прочее → string - OrGroup: `{"group": "Or", "items": ["условие1", "условие2"]}` — объединяет условия через ИЛИ #### Объектная форма ```json "filter": [ { "field": "Организация", "op": "=", "use": false, "userSettingID": "auto" }, { "field": "Дата", "op": ">=", "value": "0001-01-01T00:00:00", "valueType": "xs:dateTime" }, { "field": "СуммаДт", "op": "=", "value": "СуммаКт", "valueType": "dcscor:Field" }, { "field": "Статус", "op": "in", "value": [1, 3, 5] }, { "field": "Контрагенты", "op": "in", "value": [], "userSettingID": "auto" }, { "group": "Or", "items": [ { "field": "Статус", "op": "=", "value": true, "valueType": "xs:boolean" }, { "field": "Пометка", "op": "filled" } ], "userSettingID": "auto" } ] ``` | Поле | Описание | |------|----------| | `field` | Имя поля | | `op` | Оператор (см. таблицу) | | `value` | Правая часть (опц.). См. формы ниже | | `valueType` | xsi:type для значения (опц.). `"dcscor:Field"` = field-to-field comparison (значение — имя другого поля). Для массива `value: [...]` применяется ко всем элементам — нужен когда auto-detect ошибается (например `Перечисление.X.Y` должно остаться `xs:string`, а не `dcscor:DesignTimeValue`) | | `use` | Включён (`true` по умолчанию) | | `presentation` | Текст подсказки | | `viewMode` | `"Normal"`, `"QuickAccess"`, `"Inaccessible"` | | `userSettingID` | `"auto"` → генерировать GUID | | `userSettingPresentation` | Отображаемое имя настройки (LocalStringType) | **Формы `value`:** - Скаляр (`"X"`, `5`, `true`, `"2024-01-01T00:00:00"`) — single `` (стандартный случай). Тип определяется автоматически: bool / число / дата / строка. - Массив `[a, b, c]` — несколько `` подряд (для `in`/`notIn` с конкретными значениями). - Пустой массив `[]` — `` placeholder (типичный паттерн для `in` с пользовательскими настройками — значения заполнит пользователь через UI). Операторы: | DSL | XML comparisonType | |-----|--------------------| | `=` | `Equal` | | `<>` | `NotEqual` | | `>` | `Greater` | | `>=` | `GreaterOrEqual` | | `<` | `Less` | | `<=` | `LessOrEqual` | | `in` | `InList` | | `notIn` | `NotInList` | | `inHierarchy` | `InHierarchy` | | `contains` | `Contains` | | `notContains` | `NotContains` | | `beginsWith` | `BeginsWith` | | `filled` | `Filled` | | `notFilled` | `NotFilled` | Группа условий: `{ "group": "And"|"Or"|"Not", "items": [...] }` → `FilterItemGroup` с `groupType`. Группа также принимает item-level поля `presentation`, `viewMode`, `userSettingID`, `userSettingPresentation` — для регистрации группы как пункта пользовательских настроек. ### order ```json "order": [ "Количество desc", "Наименование", { "field": "Контрагент", "direction": "desc", "viewMode": "Inaccessible" }, "Auto" ] ``` - `"Field"` → `OrderItemField`, `orderType=Asc` - `"Field desc"` → `OrderItemField`, `orderType=Desc` - `"Field asc"` → `OrderItemField`, `orderType=Asc` - `"Auto"` → `OrderItemAuto` (только на уровне группировок; на верхнем уровне settings игнорируется) - Объект `{ field, direction?, viewMode?, use? }` — нужен, когда требуется задать `viewMode`, или отключить сортировку через `use: false` (см. [viewMode](#viewmode-режим-доступности)) ### conditionalAppearance Условное оформление — массив правил, каждое задаёт набор полей (selection), условия (filter), параметры оформления (appearance) и мета-атрибуты. ```json "conditionalAppearance": [ { "selection": ["Сумма"], "filter": ["Сумма > 1000"], "appearance": { "ЦветТекста": "style:ПросроченныеДанныеЦвет" }, "presentation": { "ru": "Выделять крупные суммы", "en": "Highlight large amounts" }, "viewMode": "Normal", "userSettingID": "auto" }, { "filter": ["Статус notFilled"], "appearance": { "Текст": "Не указано", "ЦветТекста": "web:Gray" }, "presentation": "Скрывать пустые статусы", "use": false, "useInDontUse": ["group", "fieldsHeader"] } ] ``` | Поле | Описание | |------|----------| | `selection` | Массив полей, к которым применяется. Пусто/опущено = все поля | | `filter` | Условия (shorthand-строки или объекты, как в settings filter) | | `appearance` | Объект `{ "Параметр": "Значение" }` | | `presentation` | Описание правила (строка или multilang dict `{ru, en}`) | | `use` | Включено (`true` по умолчанию). `false` = правило отключено | | `viewMode` | `"Normal"`, `"QuickAccess"`, `"Inaccessible"` | | `userSettingID` | `"auto"` → генерировать GUID | | `userSettingPresentation` | Имя в пользовательских настройках (string или multilang) | | `useInDontUse` | Массив контекстов где правило **НЕ** применяется. Возможные имена: `group`, `hierarchicalGroup`, `overall`, `fieldsHeader`, `header`, `parameters`, `filter`, `resourceFieldsHeader`, `overallHeader`, `overallResourceFieldsHeader` | **Типы значений appearance** определяются автоматически: - `style:XXX` → `v8ui:Color` (палитра темы платформы, namespace `http://v8.1c.ru/8.1/data/ui/style`) - `web:XXX` → `v8ui:Color` (web-имена цветов, namespace `http://v8.1c.ru/8.1/data/ui/colors/web`) - `win:XXX` → `v8ui:Color` (системные цвета Windows, namespace `http://v8.1c.ru/8.1/data/ui/colors/windows`) - Ключи `ЦветТекста`/`ЦветФона`/`ЦветГраницы` со значениями типа `auto` или `#XXXXXX` → `v8ui:Color` - Ключ `Размещение` → `dcscor:DataCompositionTextPlacementType` - Ключи `ГоризонтальноеПоложение`/`ВертикальноеПоложение` → `v8ui:HorizontalAlign`/`VerticalAlign` - Ключ `ТипМакета` → `dcsset:DataCompositionGroupTemplateType` - Ключи `Текст`/`Заголовок`/`Формат` → `v8:LocalStringType` (если значение строка) - Числовые строки (`"40"`, `"15"`) → `xs:decimal` - `true`/`false` → `xs:boolean` - Multilang dict `{ru, en}` для любого ключа → `v8:LocalStringType` - Прочее → `xs:string` Поддержка `use=false` на уровне параметра: ```json "appearance": { "ЦветФона": { "value": "web:LightGray", "use": false } } ``` ### outputParameters ```json "outputParameters": { "Заголовок": "Мой отчёт", "ВыводитьЗаголовок": "Output", "МакетОформления": "ОформлениеОтчетовЧерноБелый" } ``` Ключ → `dcscor:parameter`, значение → `dcscor:value`. Типы значений определяются автоматически: - `"Заголовок"` → `v8:LocalStringType` (примет строку или multilang dict) - `"ВыводитьЗаголовок"`, `"ВыводитьПараметрыДанных"`, `"ВыводитьОтбор"` → `dcsset:DataCompositionTextOutputType` - `"РасположениеПолейГруппировки"` → `dcsset:DataCompositionGroupFieldsPlacement` - `"РасположениеРеквизитов"` → `dcsset:DataCompositionAttributesPlacement` - `"ГоризонтальноеРасположениеОбщихИтогов"`, `"ВертикальноеРасположениеОбщихИтогов"`, `"РасположениеОбщихИтогов"`, `"РасположениеИтогов"` → `dcscor:DataCompositionTotalPlacement` - `"РасположениеГруппировки"` → `dcsset:DataCompositionFieldGroupPlacement` - `"РасположениеРесурсов"` → `dcsset:DataCompositionResourcesPlacement` - `"ТипМакета"` → `dcsset:DataCompositionGroupTemplateType` - Multilang dict `{ru, en}` для любого ключа → `v8:LocalStringType` - Прочие → `xs:string` Значение можно обернуть в `{ "value": ..., "use": false }` — отключённый параметр (платформа эмитит `false`). Такая же форма доступна в `appearance` items (см. раздел conditionalAppearance). #### Полная wrapper-форма (bit-perfect round-trip) Decompile сохраняет всю периферию каждого outputParameter в wrapper'е: ```json { "value": "Custom", "valueType": "v8:StandardPeriod", // полный xsi:type если не покрыт type-map'ом "use": false, // false "items": { // nested sub-параметры (ТипДиаграммы.ВидПодписей) "ТипДиаграммы.ВидПодписей": { "value": "Value", "valueType": "v8ui:ChartLabelType" } }, "viewMode": "Normal", // Normal "userSettingID": "auto", "userSettingPresentation": { "ru": "Тип" } } ``` Wrapper эмитится только при наличии extra-полей; простое `"key": "value"` остаётся как есть. #### Шрифт (v8ui:Font) в appearance Шрифт — объект с маркером `@type: "Font"`: ```json "Шрифт": { "@type": "Font", "ref": "sys:DefaultGUIFont", "height": 10, "bold": "true", "italic": "false", "underline": "false", "strikeout": "false", "kind": "WindowsFont" } ``` Все атрибуты исходного XML сохраняются — для bit-perfect. #### Граница (v8ui:Line) в appearance Граница — объект с маркером `@type: "Line"` (атрибуты `width`/`gap` и inner `` сериализуются inline): ```json "СтильГраницы": { "@type": "Line", "width": 0, "gap": false, "style": "None" } ``` Стороны (`СтильГраницы.Сверху/.Снизу/.Слева/.Справа`) — nested SettingsParameterValue, кладутся в `items` (как у outputParameters wrapper): ```json "СтильГраницы": { "@type": "Line", "width": 0, "gap": false, "style": "None", "items": { "СтильГраницы.Сверху": { "value": { "@type": "Line", "width": 1, "gap": false, "style": "Solid" }, "use": false }, "СтильГраницы.Снизу": { "value": { "@type": "Line", "width": 1, "gap": false, "style": "Double" } } } } ``` Top-level Line хранится **плоско** (`@type`/`width`/`gap`/`style` + `use?`/`items?` на одном уровне). Nested items используют универсальный wrapper `{ value, use? }` — у `value` тип любой (Line/Font/color/text). Значения `style`: `None`, `Solid`, `Double`, `LargeDashed`, `SmallDashed`, `Dotted` и т.п. (значения `v8ui:SpreadsheetDocumentCellLineType`). ### dataParameters #### Автогенерация ```json "dataParameters": "auto" ``` Генерирует записи `dataParameters` для всех не-hidden параметров с `userSettingID`. Скрытые параметры (`hidden: true` / `@hidden`) исключаются. #### Shorthand-строка ```json "dataParameters": [ "Период = LastMonth @user", "Организация @off @user" ] ``` Формат: `"<Имя> [= <значение>] [@off] [@user] [@quickAccess] [@normal] [@inaccessible]"`. - Значения-варианты периодов (`LastMonth`, `ThisYear` и др.) автоматически оборачиваются в `v8:StandardPeriod` - `@off` → `use=false`, `@user` → `userSettingID=auto` #### Объектная форма ```json "dataParameters": [ { "parameter": "Период", "value": { "variant": "LastMonth" }, "userSettingID": "auto" }, { "parameter": "Организация", "use": false, "viewMode": "Normal", "userSettingID": "auto", "userSettingPresentation": "Организация отчёта" } ] ``` | Поле | Описание | |------|----------| | `parameter` | Имя параметра | | `value` | Значение (объект `{ "variant": "LastMonth" }` для StandardPeriod, или скаляр) | | `valueType` | Полный xsi:type если кастомный (например `dcsset:DataCompositionGroupUseVariant`). Для пустого значения с `use: false` — `"xs:string"` эмитит `` (placeholder отключённого параметра типа DateTime, бит-перфектный аналог `xsi:nil`) | | `use` | Включён (`true` по умолчанию) | | `viewMode` | `"Normal"`, `"QuickAccess"`, `"Inaccessible"` | | `userSettingID` | `"auto"` → генерировать GUID | | `userSettingPresentation` | Отображаемое имя настройки (LocalStringType) | #### StandardPeriod / StandardBeginningDate — shape inference Compile различает варианты по форме `value`: | Форма | xsi:type | Когда | |---|---|---| | `{variant, startDate, endDate}` | `v8:StandardPeriod` | Custom с явными датами | | `{variant: "ThisMonth"}` (etc) | `v8:StandardPeriod` | без дат — non-Custom варианты SP | | `{variant, date}` | `v8:StandardBeginningDate` | Custom с явной датой | | `{variant: "BeginningOf*"}` | `v8:StandardBeginningDate` | без даты — variant'ы начинаются с `BeginningOf` | | `"2024-01-15T10:00:00"` (string) | `xs:dateTime` | raw datetime без обёртки | Platform-pattern: `startDate`/`endDate`/`date` эмитятся ТОЛЬКО для `variant=Custom`. Для `ThisMonth`/`LastYear`/`BeginningOfThisDay`/... — только ``. ### structure #### String shorthand (рекомендуется для типичных случаев) ```json "structure": "Организация > details" "structure": "Организация > Номенклатура > details" "structure": "Период > Организация > Номенклатура > details" ``` `>` разделяет уровни вложенности. Каждый сегмент — группировка по указанному полю. `details` (или `детали`) — детальные записи (пустой `groupBy`). Для каждого уровня `selection` и `order` автоматически `["Auto"]`. #### Массив объектов ```json "structure": [ { "type": "group", "groupBy": ["Организация"], "children": [ { "type": "group" } ] } ] ``` **Умолчания:** `selection` и `order` по умолчанию `["Auto"]` на каждом уровне (в группировках, строках/колонках таблиц, точках/сериях диаграмм). Указывать явно нужно только если требуется другой набор полей. #### Группировка (group) | Поле | Описание | |------|----------| | `type` | `"group"` | | `name` | Имя группировки (опц.) | | `groupBy` | Массив полей. Каждый элемент — строка (имя поля) или объект `{ field, groupType?, periodAdditionType?, periodAdditionBegin?, periodAdditionEnd? }`. Пусто/опущено = детальные записи. Object-форма нужна когда `groupType ≠ "Items"`, `periodAdditionType ≠ "None"` или задана `periodAdditionBegin/End` (см. ниже) | | `groupType` | `"Items"` (умолч.), `"Hierarchy"`, `"HierarchyOnly"` | | `selection` | Выборка (умолч. `["Auto"]`) | | `filter` | Отборы (как в settings) | | `order` | Сортировка (умолч. `["Auto"]`) | | `outputParameters` | Параметры вывода (как в settings) | | `conditionalAppearance` | Условное оформление группы (как в settings) | | `use` | `false` = ветка структуры отключена (на самой группе) | | `viewMode` | `"Normal"`, `"QuickAccess"`, `"Inaccessible"` — режим доступности группы в пользовательских настройках | | `itemsViewMode` | `"Normal"`, `"QuickAccess"`, `"Inaccessible"` — режим доступности подэлементов группы | | `userSettingID` | `"auto"` → генерировать GUID. Регистрирует группу как пункт пользовательских настроек | | `userSettingPresentation` | Имя в пользовательских настройках (string или multilang dict) | | `children` | Вложенные элементы структуры | Пустой `groupBy` (или `[]`) = детальные записи (без `groupItems` в XML). **`periodAdditionBegin` / `periodAdditionEnd`** на field-объекте — даты добавочного периода (``/``). Compile auto-определяет xsi:type значения: строка вида `2025-01-01T00:00:00` → `xs:dateTime`, иначе (путь к параметру, например `ПараметрыДанных.ДатаНачала`) → `dcscor:Field`. ```json { "field": "ПериодМесяц", "periodAdditionBegin": "ПараметрыДанных.ДатаНачала", "periodAdditionEnd": "ПараметрыДанных.ДатаОкончания" } ``` #### Таблица (table) ```json { "type": "table", "name": "Таблица", "rows": [ { "groupBy": ["Номенклатура"], "selection": ["Auto"], "order": ["Auto"] } ], "columns": [ { "name": "Период", "groupBy": ["Период"], "filter": ["Сумма > 0"], "selection": ["Auto"], "order": ["Auto"], "outputParameters": { "РасположениеИтогов": "None" }, "userSettingID": "auto", "userSettingPresentation": { "ru": "Колонка с периодом" } } ] } ``` Каждая `column`/`row` принимает те же поля что и `group`: `name`, `groupBy`/`groupFields`, `filter`, `order`, `selection`, `outputParameters`, `conditionalAppearance`, `children` (вложенные `StructureItemGroup`), плюс user-settings — `viewMode`, `userSettingID`, `userSettingPresentation`, `itemsViewMode` (регистрация column/row как пункта «Изменить вариант»). На самой `table` (отдельно от column/row) также допустимы `selection`, `conditionalAppearance`, `outputParameters`, плюс user-settings: `viewMode`, `userSettingID`, `userSettingPresentation`, `itemsViewMode`, `columnsViewMode`, `rowsViewMode`, `use` (`false` = таблица отключена). - `columnsViewMode` / `rowsViewMode` — режим доступности секции колонок / строк в пользовательских настройках (значения: `Normal` / `QuickAccess` / `Inaccessible`). > **Внутренний паттерн**: `` внутри ``/``/``/`` платформа всегда сериализует в **короткой форме** `` без `xsi:type`. Compile эмитит этот вариант автоматически для `children` table axis. #### Диаграмма (chart) ```json { "type": "chart", "points": { "groupBy": ["Организация"], "order": ["Auto"], "filter": [...] }, "series": { "groupBy": ["Месяц"], "order": ["Auto"] }, "selection": ["Сумма"] } ``` `points` и `series` принимают те же поля что table column/row (включая `name` и user-settings). На самой chart-item: `viewMode`, `userSettingID`, `userSettingPresentation`, `itemsViewMode`, `pointsViewMode`, `seriesViewMode`, `use: false` (диаграмма отключена). `pointsViewMode`/`seriesViewMode` — аналоги `columnsViewMode`/`rowsViewMode` у таблицы. **Multi-series / multi-points** — `points` и `series` могут быть массивом объектов, тогда генерируется несколько `` или `` подряд (каждый со своими `groupBy`, `filter`, user-settings). Используется например для разделения данных диаграммы на несколько серий по разным фильтрам: ```json { "type": "chart", "points": { "groupBy": ["Период"] }, "series": [ { "groupBy": ["Стадия"], "filter": ["Стадия = ЗНАЧЕНИЕ(Перечисление.X.A)"], "viewMode": "Normal", "userSettingID": "auto", "userSettingPresentation": { "ru": "Серия A" } }, { "groupBy": ["Стадия"], "filter": ["Стадия = ЗНАЧЕНИЕ(Перечисление.X.B)"], "viewMode": "Normal", "userSettingID": "auto", "userSettingPresentation": { "ru": "Серия B" } } ] } ``` ### userFields (пользовательские вычисляемые поля) Дополнительные поля, которые пользователь может задать в режиме «Изменить вариант» через UI. Хранятся в settings варианта. Два подтипа определяются по содержимому объекта: **Expression-форма** — поле вычисляется выражением (опционально с разделением для детальных строк и для итогов): ```json "userFields": [ { "dataPath": "ПользовательскиеПоля.Поле1", "title": { "ru": "Отработано дней", "en": "Days worked" }, "detail": { "expression": "Выбор Когда Группа = ... Тогда ОтработаноДней Иначе 0 Конец", "presentation": "Выбор Когда Группа = ... Тогда [Отработано дней] Иначе 0 Конец" }, "total": { "expression": "Сумма(Выбор Когда Группа = ... Тогда ОтработаноДней Иначе 0 Конец)", "presentation": "Сумма(Выбор Когда Группа = ... Тогда [Отработано дней] Иначе 0 Конец)" } } ] ``` | Поле | Описание | |------|----------| | `dataPath` | Путь поля в формате `ПользовательскиеПоля.ПолеN` | | `title` | Заголовок (строка или multilang dict) | | `detail.expression` | Выражение для детальных записей | | `detail.presentation` | Тот же expression с подстановкой `[Имя поля]` (для UI) | | `total.expression` | Выражение для итоговой строки | | `total.presentation` | Same для UI | > **Пустые значения**: XML всегда содержит все четыре элемента (`detailExpression`, `detailExpressionPresentation`, `totalExpression`, `totalExpressionPresentation`) — даже если без значения (``). decompile сохраняет ключ с пустой строкой, compile эмитит self-closing тег для пустых строк. Это нужно для bit-perfect round-trip. **Case-форма** — поле принимает разные значения в зависимости от условий: ```json "userFields": [ { "dataPath": "ПользовательскиеПоля.Поле1", "title": { "ru": "Вид продаж" }, "cases": [ { "filter": ["ХозОперация <> Перечисление.ХозяйственныеОперации.РеализацияВРозницу"], "value": 2, "presentation": { "ru": "Только оптовые продажи", "en": "Wholesale only" } }, { "filter": ["ХозОперация = Перечисление.ХозяйственныеОперации.РеализацияВРозницу"], "value": 3, "presentation": { "ru": "Только розничные продажи", "en": "Retail only" } } ] } ] ``` | Поле | Описание | |------|----------| | `cases[].filter` | Условие (как в settings filter) | | `cases[].value` | Значение поля если условие выполнено (типы автоопределяются: bool/decimal/string) | | `cases[].presentation` | Текст значения для UI (multilang) | Тип элемента определяется автоматически: наличие `cases` → `UserFieldCase`, иначе → `UserFieldExpression`. ### viewMode (режим доступности) `viewMode` управляет доступностью элемента в **пользовательских настройках** отчёта («Изменить вариант…» / «Настройки»). Возможные значения: | Значение | Семантика | |----------|-----------| | `"Normal"` | Пользователь видит и может править (default) | | `"Inaccessible"` | Скрыто от пользователя, не редактируется | | `"QuickAccess"` | Вынесено в быстрые настройки (на форму отчёта) | | `"Auto"` | Автоматический режим (наследование от контейнера) | Применяется в трёх контекстах: **1. Item-level** — на отдельном элементе блока (см. описание объектной формы соответствующего раздела): ```json "filter": [{ "field": "X", "op": "=", "value": "Y", "viewMode": "Inaccessible" }], "selection": [{ "field": "X", "viewMode": "Inaccessible" }], "order": [{ "field": "X", "viewMode": "Inaccessible" }], "conditionalAppearance": [{ "filter": [...], "appearance": {...}, "viewMode": "Inaccessible" }], "dataParameters": [{ "parameter": "X", "viewMode": "QuickAccess" }] ``` Shorthand-флаги `@inaccessible`, `@quickAccess` доступны для `filter` и `dataParameters` строковых форм. **2. Block-level** — на самом блоке (внутри `settings`). Управляет доступностью всей группы как пункта пользовательских настроек: ```json "settings": { "selectionViewMode": "Inaccessible", "filterViewMode": "Inaccessible", "orderViewMode": "Inaccessible", "conditionalAppearanceViewMode": "Inaccessible", "itemsViewMode": "Inaccessible", "selectionUserSettingID": "auto", "filterUserSettingID": "auto", "orderUserSettingID": "auto", "conditionalAppearanceUserSettingID": "auto", "selection": [...], "filter": [...] } ``` `itemsViewMode` на settings — общий режим для всех подэлементов варианта (`` в XML). `XxxUserSettingID` парят с `XxxViewMode` — platform пишет их в block-level пользовательских настроек. Пустые блоки (без items) тоже эмитятся, если есть block-level meta — например `Normal`. Также `orderViewMode`/`orderUserSettingID` поддержаны на StructureItemGroup для случаев когда block-level meta лежит на nested ``. **3. Structure item** — на элементе структуры (`group`): ```json { "type": "group", "groupBy": ["Организация"], "viewMode": "Inaccessible", "itemsViewMode": "Inaccessible" } ``` **4. Table axis / chart axis** — на самой `column`/`row`/`points`/`series`. Через те же поля `viewMode`, `userSettingID`, `userSettingPresentation` (см. раздел Таблица). #### Стратегия сохранения Платформа эмитит `viewMode` непоследовательно: в одних местах `Normal` присутствует явно (когда элемент — пункт пользовательских настроек), в других — нет. Для bit-perfect round-trip: - `skd-decompile` сохраняет `viewMode` в JSON **точно как было в XML**, включая явный `"Normal"` если он физически присутствовал. - `skd-compile` эмитит `` только если значение задано в JSON (без `implicit Normal`-подстановки). При компиляции JSON, написанного с нуля моделью, `viewMode` опускается → платформа применит default `Normal` при загрузке схемы. --- ## 10. Макеты и привязки (templates, groupTemplates) ### templates — компактный DSL (рекомендуемый) Табличное описание шаблона вывода. Содержимое задаётся через `rows`, оформление — через именованный пресет `style`. ```json "templates": [ { "name": "Макет1", "style": "header", "widths": [36, 33, 16, 17], "minHeight": 24.75, "rows": [ ["Виды кассы", "Валюта", "Остаток на начало\nпериода", "Остаток на\nконец\nпериода"], ["|", "|", "|", "|"], ["К1", "К2", "К3", "К4"] ] }, { "name": "Макет2", "style": "data", "widths": [36, 33, 16, 17], "rows": [["{ВидКассы}", "{Валюта}", "{ОстатокНачало}", "{ОстатокКонец}"]], "parameters": [ { "name": "ВидКассы", "expression": "Представление(СчетМеждународногоУчета)" }, { "name": "ОстатокНачало", "expression": "ОстатокНаНачалоПериода" } ] }, { "name": "Макет3", "style": "total", "widths": [36, 33, 16, 17], "rows": [["Итого", "Х", "{ОстатокНачало}", "{ОстатокКонец}"]], "parameters": [ { "name": "ОстатокНачало", "expression": "ОстатокНаНачалоПериода" } ] } ] ``` #### Свойства шаблона | Свойство | Описание | |----------|----------| | `name` | Имя макета (ссылаются groupTemplate) | | `rows` | Массив строк; каждая строка — массив ячеек | | `style` | Именованный пресет оформления (по умолчанию `"data"`) | | `widths` | Массив ширин колонок (применяется ко всем строкам) | | `minHeight` | Минимальная высота первой строки (для шапок) | | `parameters` | Параметры макета — выражения для подстановки (поддерживают `drilldown`) | #### Синтаксис ячеек | Значение | Описание | |----------|----------| | `"текст"` | Статический текст (`v8:LocalStringType`) | | `"{Имя}"` | Параметр шаблона (`dcscor:Parameter`), задаётся через `parameters` | | `"\|"` | Вертикальное объединение с ячейкой выше (`ОбъединятьПоВертикали`) | | `">"` | Горизонтальное объединение с ячейкой слева (`ОбъединятьПоГоризонтали`) | | `null` | Пустая ячейка (без содержимого) | #### Встроенные пресеты стилей | Пресет | Фон | Шрифт | Выравнивание | Перенос | Рамки | |--------|-----|-------|-------------|---------|-------| | `header` | ReportHeaderBackColor | Arial 10 | Center | да | Solid 1px | | `data` | ReportGroup1BackColor | Arial 10 | — | нет | Solid 1px | | `subheader` | — | Arial 10 | Center | да | Solid 1px | | `total` | — | Arial 10 | — | нет | Solid 1px | #### Пользовательские пресеты (skd-styles.json) Файл `skd-styles.json` в директории определения или в корне проекта. Переопределяет встроенные пресеты или добавляет новые: ```json { "header": { "bgColor": "style:ReportHeaderBackColor", "borderColor": "style:ReportLineColor", "bold": true }, "myStyle": { "font": "Arial", "fontSize": 12, "bgColor": "#FFE0E0" } } ``` Допустимые ключи: `font`, `fontSize`, `bold`, `italic`, `hAlign`, `vAlign`, `wrap`, `bgColor`, `textColor`, `borderColor`, `borders`. Недостающие ключи берутся из пресета `data`. Формат цветов: `"style:ИмяСтиля"` (ссылка на стиль платформы) или `"#RRGGBB"` (прямой цвет). ### templates — raw XML (fallback) Для нестандартных случаев — raw XML вставляется как есть: ```json "templates": [ { "name": "Макет1", "template": "", "parameters": [ { "name": "ТипЦены", "expression": "Представление(ТипЦен)" } ] } ] ``` Детект: если есть `rows` — используется компактный DSL, иначе — raw XML из `template`. #### Расшифровка (drilldown) в параметрах шаблона Ключ `drilldown` в параметре шаблона — три формы по типу значения: **Форма A (без drilldown)** — обычный `ExpressionAreaTemplateParameter`: ```json { "name": "Дата", "expression": "Документ.Дата" } ``` **Форма B (строка, shortcut)** — `ExpressionAreaTemplateParameter` + автоматический `DetailsAreaTemplateParameter` с именем `Расшифровка_`, `fieldExpression` по полю `ИмяРесурса` (`expression=""`), `mainAction=DrillDown`. Ячейки `{name}` получают appearance `Расшифровка → Расшифровка_` автоматически: ```json { "name": "Сырье", "expression": "ПоступлениеСырья", "drilldown": "ПоступлениеСырья" } ``` **Форма C (объект)** — самостоятельный `DetailsAreaTemplateParameter` с именем `name`, без `ExpressionAreaTemplateParameter`. Используется когда расшифровка ссылается на data-параметр (а не на ИмяРесурса) и/или нужен другой `mainAction` (например `OpenValue`): ```json { "name": "МаршрутныйЛист", "drilldown": { "field": "МаршрутныйЛист", "expression": "МаршрутныйЛист", "action": "OpenValue" } } ``` `action` по умолчанию `DrillDown`. **Override на уровне ячейки** — object-форма `{ value, drilldown }`. Используется когда несколько ячеек должны указывать на один и тот же параметр-расшифровку (объявленный формой C): ```json "rows": [ [ { "value": "{Номер}", "drilldown": "МаршрутныйЛист" }, { "value": "{Дата}", "drilldown": "МаршрутныйЛист" } ] ] ``` Значение `drilldown` в ячейке — это полное имя параметра-расшифровки (как объявлено в `parameters`). Для shortcut form B override не нужен — appearance подставляется автоматически. ### fieldTemplates Привязка именованного area-template к полю — `X`. Когда платформа выводит значение поля `X`, используется макет `Y`: ```json "fieldTemplates": [ { "field": "МаршрутныйЛист", "template": "Макет1" } ] ``` ### groupTemplates ```json "groupTemplates": [ { "groupName": "ДанныеОтчета", "templateType": "GroupHeader", "template": "Макет1" }, { "groupField": "Счет", "templateType": "Header", "template": "Макет2" }, { "groupField": "Счет", "templateType": "OverallHeader", "template": "Макет3" } ] ``` | Ключ | Описание | |------|----------| | `groupField` | Привязка к полю группировки → `` | | `groupName` | Привязка к именованной группировке в структуре варианта → `` | | `templateType` | `Header` / `OverallHeader` → ``, `GroupHeader` → `` | | `template` | Имя макета | --- ## 11. Полный пример — минимальный ```json { "dataSets": [ { "name": "НаборДанных1", "query": "ВЫБРАТЬ\n\tНоменклатура.Наименование КАК Наименование,\n\tКОЛИЧЕСТВО(1) КАК Количество\nИЗ\n\tСправочник.Номенклатура КАК Номенклатура\nСГРУППИРОВАТЬ ПО\n\tНоменклатура.Наименование", "fields": [ { "dataPath": "Наименование", "title": "Наименование" }, "Количество" ] } ], "totalFields": ["Количество: Сумма"], "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Наименование", "Количество"], "structure": [{ "type": "group" }] } }] } ``` ## 12. Полный пример — средний (с shorthand v2) ```json { "dataSets": [ { "name": "Продажи", "query": "ВЫБРАТЬ\n\tПродажи.Организация,\n\tПродажи.Номенклатура,\n\tПродажи.Количество,\n\tПродажи.Сумма\nИЗ\n\tРегистрНакопления.Продажи КАК Продажи\n{ГДЕ\n\tПродажи.Период >= &ДатаНачала\n\tИ Продажи.Период < &ДатаОкончания}", "fields": [ "Организация: СправочникСсылка.Организации @dimension", "Номенклатура: СправочникСсылка.Номенклатура @dimension", "Количество: число(15,3)", "Сумма: число(15,2)" ] } ], "totalFields": ["Количество: Сумма", "Сумма: Сумма"], "parameters": [ "Период: СтандартныйПериод = LastMonth @autoDates" ], "settingsVariants": [{ "name": "Основной", "presentation": "Продажи по организациям", "settings": { "selection": ["Номенклатура", "Количество", "Сумма", "Auto"], "filter": ["Организация = _ @off @user"], "order": ["Сумма desc", "Auto"], "outputParameters": { "Заголовок": "Анализ продаж", "ВыводитьЗаголовок": "Output" }, "dataParameters": ["Период = LastMonth @user"], "structure": "Организация > details" } }] } ``` **Сравнение с v1:** средний пример сократился с 58 до 33 строк (−43%). Основная экономия: `@autoDates` (−4 строки), structure shorthand (−9 строк), filter/dataParam shorthand (−4 строки).