mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-06-10 08:04:56 +03:00
feat(skd-info): флаг -Raw для lossless round-trip извлечения запроса
skd-info -Mode query был просмотрщиком (заголовки, оглавление батчей, разделители --- Batch ---) и терял разделители пакетов при split, поэтому не годился как источник для skd-edit set-query @file. Флаг -Raw отдаёт текст запроса целиком, verbatim, без декораций и без дробления на пакеты — все ; и //// на месте. С -OutFile пишет чистый .sql, который без потерь возвращается через set-query @file. Stdout не усекается по -Limit. Версия v1.6 в обоих скриптах (ps1 + py). Документация: таблица параметров/режимов и round-trip workflow в skd-info, указатель + разводка patch-query vs set-query+-Raw в skd-edit. Тесты: query-raw (raw без декораций, разделитель //// сохранён) и query-view (просмотр не задет). Зелёные на ps1 и py. Чистка: удалён modes-reference.md — галерея примеров вывода избыточна для модели (инструмент самодемонстрирующийся), а человек покрыт docs/skd-guide.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -256,6 +256,8 @@ Value — имена ресурсов (как в полях/вычисляемы
|
||||
|
||||
Не поддерживает пакетный режим. Value — полный текст запроса или `@path/to/file.sql` (ссылка на внешний файл). Путь разрешается относительно Template.xml, затем CWD.
|
||||
|
||||
Когда что: **существенная переработка** (добавить поля, соединения, переписать пакет) → выгрузи запрос через `/skd-info <tpl> -Mode query -Name <набор> -Raw -OutFile file.sql`, отредактируй файл, верни `set-query @file`. `-Raw` отдаёт запрос целиком без декораций, поэтому выгрузка ↔ возврат точны (включая многопакетные запросы). **Точечная замена** (переименовать идентификатор, заменить подстроку) → выгрузка не нужна, используй `patch-query` ниже.
|
||||
|
||||
### patch-query — точечная замена в тексте запроса
|
||||
|
||||
Shorthand: `"старое => новое [@once]"`. По умолчанию заменяет все вхождения подстроки. Поддерживает пакетный режим и `-DataSet`.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: skd-info
|
||||
description: Анализ структуры схемы компоновки данных 1С (СКД) — наборы, поля, параметры, варианты. Используй для понимания отчёта — источник данных (запрос), доступные поля, параметры
|
||||
argument-hint: <TemplatePath> [-Mode overview|query|fields|links|calculated|resources|params|variant|templates|trace|full] [-Name <dataset|variant|field|group>]
|
||||
argument-hint: <TemplatePath> [-Mode overview|query|fields|links|calculated|resources|params|variant|templates|trace|full] [-Name <dataset|variant|field|group>] [-Raw]
|
||||
allowed-tools:
|
||||
- Bash
|
||||
- Read
|
||||
@@ -20,7 +20,8 @@ allowed-tools:
|
||||
| `Mode` | Режим анализа (по умолчанию `overview`) |
|
||||
| `Name` | Имя набора (query), поля (fields/calculated/resources/trace), варианта (variant) или группировки/поля (templates) |
|
||||
| `Batch` | Номер пакета запроса, 0 = все (только query) |
|
||||
| `Limit` / `Offset` | Пагинация (по умолчанию 150 строк) |
|
||||
| `Raw` | (только query) сырой текст запроса целиком, без заголовков/оглавления/разделителей пакетов. Для выгрузки в `.sql` и возврата через `skd-edit set-query @file` |
|
||||
| `Limit` / `Offset` | Пагинация (по умолчанию 150 строк; `-Raw` не усекается) |
|
||||
| `OutFile` | Записать результат в файл (UTF-8 BOM) |
|
||||
|
||||
```powershell
|
||||
@@ -31,6 +32,7 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/skd-info.ps1" -Temp
|
||||
```powershell
|
||||
... -Mode query -Name НоменклатураСЦенами
|
||||
... -Mode query -Name ДанныеТ13 -Batch 3
|
||||
... -Mode query -Name ДанныеТ13 -Raw -OutFile query.sql
|
||||
... -Mode fields -Name КадастроваяСтоимость
|
||||
... -Mode calculated -Name КоэффициентКи
|
||||
... -Mode resources -Name СуммаНалога
|
||||
@@ -45,7 +47,7 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/skd-info.ps1" -Temp
|
||||
| Режим | Без `-Name` | С `-Name` |
|
||||
|-------|-------------|-----------|
|
||||
| `overview` | Навигационная карта схемы + подсказки Next | — |
|
||||
| `query` | — | Текст запроса набора (с оглавлением батчей) |
|
||||
| `query` | — | Текст запроса набора (с оглавлением батчей); `-Raw` — чистая выгрузка для правки |
|
||||
| `fields` | Карта: имена полей по наборам | Деталь поля: набор, тип, роль, формат |
|
||||
| `links` | Все связи наборов | — |
|
||||
| `calculated` | Карта: имена вычисляемых полей | Выражение + заголовок + ограничения |
|
||||
@@ -65,7 +67,10 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/skd-info.ps1" -Temp
|
||||
3. `query -Name <набор>` — посмотреть текст SQL-запроса
|
||||
4. `variant -Name <N>` — посмотреть группировки и фильтры варианта
|
||||
|
||||
Подробные примеры вывода каждого режима — в `modes-reference.md`.
|
||||
Переработка запроса (round-trip): `query -Name <набор> -Raw -OutFile q.sql` →
|
||||
правка `q.sql` → `/skd-edit <tpl> -Operation set-query -Value "@q.sql"`. Флаг
|
||||
`-Raw` отдаёт запрос целиком без декораций, поэтому выгрузка ↔ возврат
|
||||
точны (включая многопакетные запросы с временными таблицами).
|
||||
|
||||
## Верификация
|
||||
|
||||
|
||||
@@ -1,246 +0,0 @@
|
||||
# /skd-info — полная справка по режимам
|
||||
|
||||
Компактное описание — в [SKILL.md](SKILL.md).
|
||||
|
||||
## overview (по умолчанию) — карта схемы
|
||||
|
||||
Компактная навигационная карта (10-25 строк). Показывает структуру и подсказывает следующие шаги:
|
||||
|
||||
```
|
||||
=== DCS: ОсновнаяСхемаКомпоновкиДанных (362 lines) ===
|
||||
|
||||
Sources: ИсточникДанных1 (Local)
|
||||
|
||||
Datasets:
|
||||
[Query] НоменклатураСЦенами 7 fields, query 40 lines
|
||||
Calculated: 1
|
||||
Resources: 1
|
||||
Templates: 1 templates, 1 group bindings
|
||||
Params: (none)
|
||||
|
||||
Variants:
|
||||
[1] НоменклатураИЦены "Номенклатура и цены" Table(detail) 3 filters
|
||||
[2] НоменклатураБезЦен "Номенклатура без цен" Group(detail) 2 filters
|
||||
|
||||
Next:
|
||||
-Mode query query text
|
||||
-Mode fields field tables by dataset
|
||||
-Mode calculated calculated field expressions
|
||||
-Mode resources resource aggregation
|
||||
-Mode variant -Name <N> variant structure (1..2)
|
||||
```
|
||||
|
||||
Для DataSetUnion — дерево наборов + связи:
|
||||
```
|
||||
Datasets:
|
||||
[Union] РасчетНалогаНаИмущество 52 fields
|
||||
├─ [Query] РасчетНалогаНаИмущество 51 fields, query 181 lines
|
||||
├─ [Query] ДанныеПоКадастровой 29 fields, query 40 lines
|
||||
├─ [Query] ДанныеПоСреднегодовой 34 fields, query 41 lines
|
||||
Links: РасчетНалогаНаИмущество -> СостояниеОС (2 fields)
|
||||
```
|
||||
|
||||
Параметры разделяются на видимые/скрытые:
|
||||
```
|
||||
Params: 18 (7 visible, 11 hidden): Период, Ответственный, ...
|
||||
```
|
||||
|
||||
## query — текст запроса
|
||||
|
||||
`-Name <набор>` — имя DataSet (обязателен если наборов > 1).
|
||||
|
||||
Извлекает raw-текст запроса с деэкранированием XML (`&`→`&`, `>`→`>`). Для пакетных запросов — оглавление батчей:
|
||||
|
||||
```
|
||||
=== Query: ДанныеТ13 (334 lines, 13 batches) ===
|
||||
Batch 1: lines 1-8 → ПОМЕСТИТЬ Представления_Периоды
|
||||
Batch 2: lines 9-26 → ПОМЕСТИТЬ Представления_СотрудникиОрганизации
|
||||
...
|
||||
--- Batch 1 ---
|
||||
ВЫБРАТЬ
|
||||
ДАТАВРЕМЯ(1, 1, 1) КАК Период
|
||||
ПОМЕСТИТЬ Представления_Периоды
|
||||
...
|
||||
```
|
||||
|
||||
Фильтр по номеру батча: `-Batch 3` покажет только 3-й пакет.
|
||||
|
||||
## fields — поля наборов данных
|
||||
|
||||
Без `-Name` — карта: имена полей по наборам:
|
||||
```
|
||||
=== Fields map ===
|
||||
СостояниеОС [Query] (3): Организация, ОсновноеСредство, ДатаСостояния
|
||||
РасчетНалогаНаИмущество [Union] (52): ДоляСтоимостиЧислитель, ...
|
||||
РасчетНалогаНаИмущество [Query] (51): КадастроваяСтоимость, ...
|
||||
```
|
||||
|
||||
С `-Name <поле>` — детали конкретного поля:
|
||||
```
|
||||
=== Field: ДатаСостояния "Дата ввода в эксплуатацию" ===
|
||||
|
||||
Dataset: СостояниеОС [Query]
|
||||
Format: ДФ=dd.MM.yyyy
|
||||
```
|
||||
|
||||
Показывает: dataset, title, type, role, useRestriction, format, presentationExpression.
|
||||
|
||||
## links — связи наборов данных
|
||||
|
||||
```
|
||||
=== Links (4) ===
|
||||
|
||||
РасчетНалогаНаИмущество -> СостояниеОС :
|
||||
Организация -> Организация
|
||||
ОсновноеСредство -> ОсновноеСредство
|
||||
```
|
||||
|
||||
Группирует по парам наборов. Показывает поля связи и параметры.
|
||||
|
||||
## calculated — вычисляемые поля
|
||||
|
||||
Без `-Name` — карта: имена и заголовки:
|
||||
```
|
||||
=== Calculated fields (23) ===
|
||||
ДоляСтоимости "Доля стоимости"
|
||||
КоэффициентКи "Коэффициент Ки"
|
||||
...
|
||||
```
|
||||
|
||||
С `-Name <поле>` — полное выражение:
|
||||
```
|
||||
=== Calculated: ДоляСтоимости ===
|
||||
|
||||
Expression:
|
||||
ВЫБОР КОГДА ... ТОГДА "1" ИНАЧЕ ... КОНЕЦ
|
||||
Title: Доля стоимости
|
||||
Restrict: condition
|
||||
```
|
||||
|
||||
## resources — ресурсы (итоги по группировкам)
|
||||
|
||||
Без `-Name` — карта: имена полей, `*` = есть формулы по группировкам:
|
||||
```
|
||||
=== Resources (51) ===
|
||||
НалоговаяБаза
|
||||
КоэффициентКи *
|
||||
...
|
||||
* = has group-level formulas
|
||||
```
|
||||
|
||||
С `-Name <поле>` — формулы агрегации:
|
||||
```
|
||||
=== Resource: ДатаСостояния ===
|
||||
|
||||
[ОсновноеСредство] ЕстьNull(ДатаСостояния, "")
|
||||
```
|
||||
|
||||
## params — параметры схемы
|
||||
|
||||
```
|
||||
=== Parameters (16) ===
|
||||
Name Type Default Visible Expression
|
||||
Период StandardPeriod LastMonth yes -
|
||||
НачалоПериода DateTime - hidden &Период.ДатаНачала
|
||||
Организация CatalogRef.Организации null yes -
|
||||
```
|
||||
|
||||
## variant — варианты отчёта
|
||||
|
||||
Без `-Name` — список вариантов:
|
||||
```
|
||||
=== Variants (2) ===
|
||||
[1] НоменклатураИЦены "Номенклатура и цены" Table(detail) 3 filters
|
||||
[2] НоменклатураБезЦен "Номенклатура без цен" Group(detail) 2 filters
|
||||
```
|
||||
|
||||
С `-Name <N|имя>` — структура конкретного варианта:
|
||||
```
|
||||
=== Variant [1]: НоменклатураИЦены "Номенклатура и цены" ===
|
||||
|
||||
Structure:
|
||||
Table "Таблица"
|
||||
├── Columns: [ТипЦен Items]
|
||||
│ Selection: Auto, Цена
|
||||
└── Rows: [Номенклатура Items]
|
||||
Selection: Номенклатура, УИД, Auto
|
||||
|
||||
Filter:
|
||||
[ ] Номенклатура InHierarchy [user]
|
||||
[ ] ТипЦен Equal
|
||||
[x] ВАрхиве = false "Исключая скрытые товары"
|
||||
|
||||
DataParams: КлючВарианта="НоменклатураИЦены"
|
||||
Output: style=ЧерноБелый groups=Separately totalsH=None totalsV=None
|
||||
```
|
||||
|
||||
## templates — привязки шаблонов вывода
|
||||
|
||||
Три типа привязок: `fieldTemplate` (к полю), `groupTemplate` (к группировке, Header/Footer), `groupHeaderTemplate` (заголовок группы).
|
||||
|
||||
Без `-Name` — карта привязок:
|
||||
```
|
||||
=== Templates (70 defined: 49 field, 37 group) ===
|
||||
|
||||
Field bindings (49): (all trivial)
|
||||
ОстаточнаяСтоимостьНа0101, ОстаточнаяСтоимостьНа0102, ...
|
||||
|
||||
Group bindings (37):
|
||||
ВидНалоговойБазы
|
||||
Header -> Макет3 (1 rows, 1 params)
|
||||
СреднегодоваяСтоимость2019
|
||||
Footer -> Макет50 (1 rows) spacer
|
||||
GroupHeader -> Макет40 (3 rows)
|
||||
```
|
||||
|
||||
С `-Name <группировка|поле>` — содержимое шаблонов:
|
||||
```
|
||||
=== Templates: СреднегодоваяСтоимость2019 ===
|
||||
|
||||
Footer -> Макет50 [1 rows, 1 cells]:
|
||||
Row 1: (empty)
|
||||
|
||||
GroupHeader -> Макет40 [3 rows, 78 cells]:
|
||||
Row 1: "№ п/п" | "###Группировки1###" | "Инв. номер" | ...
|
||||
Row 2: "01.01" | "01.02" | ... | "31.12"
|
||||
Row 3: "1" | "2" | ... | "26"
|
||||
```
|
||||
|
||||
Для field-привязок:
|
||||
```
|
||||
=== Field template: ОстаточнаяСтоимостьНа0101 -> Макет4 ===
|
||||
[1 rows, 1 cells]
|
||||
Row 1: {ОстаточнаяСтоимостьНа0101}
|
||||
(all params trivial)
|
||||
```
|
||||
|
||||
**Тривиальность выражений**: `Поле = Поле` и `Поле = Представление(Поле)` считаются тривиальными и НЕ выводятся. Показываются только нетривиальные — когда выражение содержит другое поле, вызов метода, пустую строку и т.д.
|
||||
|
||||
## trace — трассировка поля от заголовка до запроса
|
||||
|
||||
Ищет поле по dataPath ИЛИ заголовку (включая подстроку) и показывает полную цепочку происхождения за один вызов:
|
||||
|
||||
```
|
||||
=== Trace: КоэффициентКи "Коэффициент Ки" ===
|
||||
|
||||
Dataset: (schema-level only, not in dataset fields)
|
||||
|
||||
Calculated:
|
||||
ВЫБОР КОГДА ... ТОГДА 0 ИНАЧЕ ... КОНЕЦ
|
||||
Operands:
|
||||
КоличествоМесяцевИспользования -> РасчетНалогаНаИмущество [Query]
|
||||
КоличествоМесяцевВладения -> РасчетНалогаНаИмущество [Query]
|
||||
|
||||
Resource:
|
||||
[ОсновноеСредство] Сумма(КоэффициентКи)
|
||||
```
|
||||
|
||||
Типичный сценарий: пользователь видит колонку "Коэффициент Ки" в отчёте и спрашивает как она считается. Один вызов `trace` показывает: формулу вычисления, откуда берутся операнды, как агрегируется в ресурс.
|
||||
|
||||
## Что не выводится
|
||||
|
||||
- XML namespace-декларации
|
||||
- Обёртки v8:item/v8:lang/v8:content (извлекаем чистый текст)
|
||||
- userSettingID (GUID-ы пользовательских настроек)
|
||||
- Дефолтные periodAdditionBegin/End = 0001-01-01
|
||||
- viewMode
|
||||
@@ -1,4 +1,4 @@
|
||||
# skd-info v1.5 — Analyze 1C DCS structure
|
||||
# skd-info v1.6 — Analyze 1C DCS structure
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
@@ -10,7 +10,8 @@ param(
|
||||
[int]$Batch = 0,
|
||||
[int]$Limit = 150,
|
||||
[int]$Offset = 0,
|
||||
[string]$OutFile
|
||||
[string]$OutFile,
|
||||
[switch]$Raw
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
@@ -655,6 +656,13 @@ function Show-Query {
|
||||
}
|
||||
|
||||
$rawQuery = Unescape-Xml $queryNode.InnerText
|
||||
|
||||
# Raw mode: emit verbatim query text only (no headers/TOC/batch split) for round-trip
|
||||
if ($Raw) {
|
||||
foreach ($ql in ($rawQuery.Trim() -split "`n")) { $lines.Add($ql.TrimEnd()) }
|
||||
return
|
||||
}
|
||||
|
||||
$dsNameStr = $targetDs.SelectSingleNode("s:name", $ns).InnerText
|
||||
|
||||
# Split into batches
|
||||
@@ -1894,7 +1902,7 @@ if ($Offset -gt 0) {
|
||||
$result = $result[$Offset..($totalLines - 1)]
|
||||
}
|
||||
|
||||
if ($result.Count -gt $Limit) {
|
||||
if (-not $Raw -and $result.Count -gt $Limit) {
|
||||
$shown = $result[0..($Limit - 1)]
|
||||
foreach ($l in $shown) { Write-Host $l }
|
||||
Write-Host ""
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# skd-info v1.5 — Analyze 1C DCS structure
|
||||
# skd-info v1.6 — Analyze 1C DCS structure
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -278,6 +278,7 @@ def main():
|
||||
parser.add_argument("-Limit", type=int, default=150)
|
||||
parser.add_argument("-Offset", type=int, default=0)
|
||||
parser.add_argument("-OutFile", default=None)
|
||||
parser.add_argument("-Raw", action="store_true")
|
||||
args = parser.parse_args()
|
||||
|
||||
# --- Resolve path ---
|
||||
@@ -634,6 +635,13 @@ def main():
|
||||
sys.exit(1)
|
||||
|
||||
raw_query = unescape_xml("".join(query_node.itertext()))
|
||||
|
||||
# Raw mode: emit verbatim query text only (no headers/TOC/batch split) for round-trip
|
||||
if args.Raw:
|
||||
for ql in raw_query.strip().split("\n"):
|
||||
lines.append(ql.rstrip())
|
||||
return
|
||||
|
||||
ds_name_str = (target_ds.find("s:name", NSMAP).text or "")
|
||||
|
||||
# Split into batches
|
||||
@@ -1719,7 +1727,7 @@ def main():
|
||||
sys.exit(0)
|
||||
result = result[args.Offset:]
|
||||
|
||||
if len(result) > args.Limit:
|
||||
if not args.Raw and len(result) > args.Limit:
|
||||
shown = result[:args.Limit]
|
||||
for line in shown:
|
||||
print(line)
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "Raw-выгрузка многопакетного запроса без декораций",
|
||||
"preRun": [
|
||||
{
|
||||
"script": "skd-compile/scripts/skd-compile",
|
||||
"input": {
|
||||
"dataSets": [{
|
||||
"name": "Основной",
|
||||
"query": "ВЫБРАТЬ 1 КАК Поле\nПОМЕСТИТЬ ВТ_Первая\n;\n////////////////////////////////////////////////////////////////////////////////\nВЫБРАТЬ Поле ИЗ ВТ_Первая КАК Т",
|
||||
"fields": ["Поле"]
|
||||
}]
|
||||
},
|
||||
"args": { "-DefinitionFile": "{inputFile}", "-OutputPath": "{workDir}/Template.xml" }
|
||||
}
|
||||
],
|
||||
"params": { "templatePath": "Template.xml" },
|
||||
"args_extra": ["-Mode", "query", "-Name", "Основной", "-Raw"],
|
||||
"expect": {
|
||||
"stdoutContains": ["ПОМЕСТИТЬ ВТ_Первая", "////", "ВЫБРАТЬ Поле ИЗ ВТ_Первая"],
|
||||
"stdoutNotContains": ["=== Query", "--- Batch", "Batch 1: lines"]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "Просмотр запроса (без -Raw) сохраняет декорации",
|
||||
"preRun": [
|
||||
{
|
||||
"script": "skd-compile/scripts/skd-compile",
|
||||
"input": {
|
||||
"dataSets": [{
|
||||
"name": "Основной",
|
||||
"query": "ВЫБРАТЬ 1 КАК Поле\nПОМЕСТИТЬ ВТ_Первая\n;\n////////////////////////////////////////////////////////////////////////////////\nВЫБРАТЬ Поле ИЗ ВТ_Первая КАК Т",
|
||||
"fields": ["Поле"]
|
||||
}]
|
||||
},
|
||||
"args": { "-DefinitionFile": "{inputFile}", "-OutputPath": "{workDir}/Template.xml" }
|
||||
}
|
||||
],
|
||||
"params": { "templatePath": "Template.xml" },
|
||||
"args_extra": ["-Mode", "query", "-Name", "Основной"],
|
||||
"expect": {
|
||||
"stdoutContains": ["=== Query", "--- Batch", "Batch 1: lines"]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user