Split totals into calculated and resources modes

Each concept now has its own mode with clear naming that matches
the overview labels. Overview now shows "Resources:" instead of
"Totals:" for consistency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-02-10 18:40:50 +03:00
parent 21dded4d1c
commit f211ffa2f0
2 changed files with 103 additions and 90 deletions
+30 -18
View File
@@ -1,7 +1,7 @@
---
name: skd-info
description: Анализ структуры схемы компоновки данных 1С (СКД) — наборы, поля, параметры, варианты
argument-hint: <TemplatePath> [-Mode overview|query|fields|links|totals|params|variant|trace] [-Name <dataset|variant|field>]
argument-hint: <TemplatePath> [-Mode overview|query|fields|links|calculated|resources|params|variant|trace] [-Name <dataset|variant|field>]
allowed-tools:
- Bash
- Read
@@ -44,8 +44,10 @@ powershell.exe -NoProfile -File .claude\skills\skd-info\scripts\skd-info.ps1 -Te
... -Mode fields
... -Mode fields -Name НаборДанных1
... -Mode links
... -Mode totals
... -Mode totals -Name СуммаНалога
... -Mode calculated
... -Mode calculated -Name КоэффициентКи
... -Mode resources
... -Mode resources -Name СуммаНалога
... -Mode params
... -Mode trace -Name КоэффициентКи
... -Mode trace -Name "Коэффициент Ки"
@@ -73,7 +75,7 @@ Sources: ИсточникДанных1 (Local)
Datasets:
[Query] НоменклатураСЦенами 7 fields, query 40 lines
Calculated: 1
Totals: 1
Resources: 1
Templates: 1 templates, 1 group bindings
Params: (none)
@@ -84,7 +86,8 @@ Variants:
Next:
-Mode query query text
-Mode fields field tables by dataset
-Mode totals calculated fields + resources
-Mode calculated calculated field expressions
-Mode resources resource aggregation
-Mode variant -Name <N> variant structure (1..2)
```
@@ -152,15 +155,30 @@ Params: 18 (7 visible, 11 hidden): Период, Ответственный, ...
Группирует по парам наборов. Показывает поля связи и параметры.
### totals — вычисляемые поля и ресурсы
### calculated — вычисляемые поля
Без `-Name` — карта: имена вычисляемых полей и ресурсов:
Без `-Name` — карта: имена и заголовки:
```
=== Calculated fields (23) ===
ДоляСтоимости "Доля стоимости"
КоэффициентКи "Коэффициент Ки"
...
```
С `-Name <поле>` — полное выражение:
```
=== Calculated: ДоляСтоимости ===
Expression:
ВЫБОР КОГДА ... ТОГДА "1" ИНАЧЕ ... КОНЕЦ
Title: Доля стоимости
Restrict: condition
```
### resources — ресурсы (итоги по группировкам)
Без `-Name` — карта: имена полей, `*` = есть формулы по группировкам:
```
=== Resources (51) ===
НалоговаяБаза
КоэффициентКи *
@@ -168,18 +186,11 @@ Params: 18 (7 visible, 11 hidden): Период, Ответственный, ...
* = has group-level formulas
```
С `-Name <поле>`полная формула (если поле есть и в calculated, и в resources — покажет обе части):
С `-Name <поле>`формулы агрегации:
```
=== Calculated: КоэффициентКи ===
=== Resource: ДатаСостояния ===
Expression:
ВЫБОР КОГДА ... ТОГДА 0 ИНАЧЕ ... КОНЕЦ
Title: Коэффициент Ки
Restrict: condition
=== Resource: КоэффициентКи ===
[ОсновноеСредство] Сумма(КоэффициентКи)
[ОсновноеСредство] ЕстьNull(ДатаСостояния, "")
```
### params — параметры схемы
@@ -253,7 +264,8 @@ Resource:
- **Отладка данных**: query для просмотра текста запроса
- **Модификация полей**: fields для списка с ролями по наборам
- **Связи между наборами**: links для полей связи и параметров
- **Формулы и ресурсы**: totals для вычисляемых полей и ресурсов
- **Вычисляемые поля**: calculated для выражений вычисляемых полей
- **Ресурсы**: resources для формул агрегации по группировкам
- **Программный вызов**: params для списка параметров
- **Изменение вывода**: variant для структуры группировок и фильтров
- **Как считается колонка?**: trace для полной цепочки от заголовка до запроса
+73 -72
View File
@@ -1,7 +1,7 @@
param(
[Parameter(Mandatory=$true)]
[string]$TemplatePath,
[ValidateSet("overview", "query", "fields", "links", "totals", "params", "variant", "trace")]
[ValidateSet("overview", "query", "fields", "links", "calculated", "resources", "params", "variant", "trace")]
[string]$Mode = "overview",
[string]$Name,
[int]$Batch = 0,
@@ -385,9 +385,9 @@ if ($Mode -eq "overview") {
}
$groupNote = if ($hasGrouped) { ", with group formulas" } else { "" }
if ($uniquePaths.Count -eq $totalFields.Count) {
$lines.Add("Totals: $($totalFields.Count)$groupNote")
$lines.Add("Resources: $($totalFields.Count)$groupNote")
} else {
$lines.Add("Totals: $($totalFields.Count) ($($uniquePaths.Count) fields$groupNote)")
$lines.Add("Resources: $($totalFields.Count) ($($uniquePaths.Count) fields$groupNote)")
}
}
@@ -505,8 +505,11 @@ if ($Mode -eq "overview") {
}
$calcCount = $root.SelectNodes("s:calculatedField", $ns).Count
$totalCount = $root.SelectNodes("s:totalField", $ns).Count
if ($calcCount -gt 0 -or $totalCount -gt 0) {
$hints += "-Mode totals calculated fields + resources"
if ($calcCount -gt 0) {
$hints += "-Mode calculated calculated field expressions ($calcCount)"
}
if ($totalCount -gt 0) {
$hints += "-Mode resources resource aggregation ($totalCount)"
}
if ($params.Count -gt 0) {
$hints += "-Mode params parameter details"
@@ -827,18 +830,15 @@ elseif ($Mode -eq "links") {
}
# ============================================================
# MODE: totals
# MODE: calculated
# ============================================================
elseif ($Mode -eq "totals") {
elseif ($Mode -eq "calculated") {
$calcFields = $root.SelectNodes("s:calculatedField", $ns)
$totalFields = $root.SelectNodes("s:totalField", $ns)
if ($Name) {
# Detail for specific field
if ($calcFields.Count -eq 0) {
$lines.Add("(no calculated fields)")
} elseif ($Name) {
$found = $false
# Search in calculated fields
foreach ($cf in $calcFields) {
$cfPath = $cf.SelectSingleNode("s:dataPath", $ns).InnerText
if ($cfPath -eq $Name) {
@@ -870,74 +870,75 @@ elseif ($Mode -eq "totals") {
break
}
}
# Search in resources (also show if already found in calculated — field can be both)
$matchedResources = @()
foreach ($tf in $totalFields) {
$tfPath = $tf.SelectSingleNode("s:dataPath", $ns).InnerText
if ($tfPath -eq $Name) { $matchedResources += $tf }
}
if ($matchedResources.Count -gt 0) {
if ($found) { $lines.Add("") }
$lines.Add("=== Resource: $Name ===")
$lines.Add("")
foreach ($tf in $matchedResources) {
$tfExpr = $tf.SelectSingleNode("s:expression", $ns).InnerText
$tfGroup = $tf.SelectSingleNode("s:group", $ns)
$groupStr = "(overall)"
if ($tfGroup) { $groupStr = $tfGroup.InnerText }
$lines.Add(" [$groupStr] $tfExpr")
}
$found = $true
}
if (-not $found) {
Write-Error "Field '$Name' not found in calculated fields or resources"
Write-Error "Calculated field '$Name' not found"
exit 1
}
} else {
# Compact map
if ($calcFields.Count -gt 0) {
$lines.Add("=== Calculated fields ($($calcFields.Count)) ===")
foreach ($cf in $calcFields) {
$cfPath = $cf.SelectSingleNode("s:dataPath", $ns).InnerText
$cfTitle = $cf.SelectSingleNode("s:title", $ns)
$titleStr = ""
if ($cfTitle) {
$t = Get-MLText $cfTitle
if ($t -and $t -ne $cfPath) { $titleStr = " `"$t`"" }
}
$lines.Add(" $cfPath$titleStr")
# Map
$lines.Add("=== Calculated fields ($($calcFields.Count)) ===")
foreach ($cf in $calcFields) {
$cfPath = $cf.SelectSingleNode("s:dataPath", $ns).InnerText
$cfTitle = $cf.SelectSingleNode("s:title", $ns)
$titleStr = ""
if ($cfTitle) {
$t = Get-MLText $cfTitle
if ($t -and $t -ne $cfPath) { $titleStr = " `"$t`"" }
}
$lines.Add("")
$lines.Add(" $cfPath$titleStr")
}
$lines.Add("")
$lines.Add("Use -Name <field> for full expression.")
}
}
if ($totalFields.Count -gt 0) {
$lines.Add("=== Resources ($($totalFields.Count)) ===")
# Collect unique field names with group info
$resMap = [ordered]@{}
foreach ($tf in $totalFields) {
$tfPath = $tf.SelectSingleNode("s:dataPath", $ns).InnerText
$tfGroup = $tf.SelectSingleNode("s:group", $ns)
if (-not $resMap.Contains($tfPath)) {
$resMap[$tfPath] = @{ hasGroup = $false }
}
if ($tfGroup) { $resMap[$tfPath].hasGroup = $true }
}
foreach ($key in $resMap.Keys) {
$groupMark = if ($resMap[$key].hasGroup) { " *" } else { "" }
$lines.Add(" $key$groupMark")
}
$lines.Add("")
$lines.Add(" * = has group-level formulas")
}
# ============================================================
# MODE: resources
# ============================================================
elseif ($Mode -eq "resources") {
if ($calcFields.Count -eq 0 -and $totalFields.Count -eq 0) {
$lines.Add("(no calculated fields or resources)")
} else {
$lines.Add("")
$lines.Add("Use -Name <field> for full expression.")
$totalFields = $root.SelectNodes("s:totalField", $ns)
if ($totalFields.Count -eq 0) {
$lines.Add("(no resources)")
} elseif ($Name) {
$matched = @()
foreach ($tf in $totalFields) {
$tfPath = $tf.SelectSingleNode("s:dataPath", $ns).InnerText
if ($tfPath -eq $Name) { $matched += $tf }
}
if ($matched.Count -eq 0) {
Write-Error "Resource '$Name' not found"
exit 1
}
$lines.Add("=== Resource: $Name ===")
$lines.Add("")
foreach ($tf in $matched) {
$tfExpr = $tf.SelectSingleNode("s:expression", $ns).InnerText
$tfGroup = $tf.SelectSingleNode("s:group", $ns)
$groupStr = "(overall)"
if ($tfGroup) { $groupStr = $tfGroup.InnerText }
$lines.Add(" [$groupStr] $tfExpr")
}
} else {
# Map
$lines.Add("=== Resources ($($totalFields.Count)) ===")
$resMap = [ordered]@{}
foreach ($tf in $totalFields) {
$tfPath = $tf.SelectSingleNode("s:dataPath", $ns).InnerText
$tfGroup = $tf.SelectSingleNode("s:group", $ns)
if (-not $resMap.Contains($tfPath)) {
$resMap[$tfPath] = @{ hasGroup = $false }
}
if ($tfGroup) { $resMap[$tfPath].hasGroup = $true }
}
foreach ($key in $resMap.Keys) {
$groupMark = if ($resMap[$key].hasGroup) { " *" } else { "" }
$lines.Add(" $key$groupMark")
}
$lines.Add("")
$lines.Add(" * = has group-level formulas")
$lines.Add("")
$lines.Add("Use -Name <field> for full formula.")
}
}