mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-06-10 08:04:56 +03:00
Compare commits
2 Commits
46ee078343
...
6d119eb473
| Author | SHA1 | Date | |
|---|---|---|---|
| 6d119eb473 | |||
| 9877fe403a |
@@ -152,11 +152,19 @@ Shorthand: `"Имя [Заголовок]: тип = значение @флаги"
|
|||||||
|
|
||||||
Флаги shorthand:
|
Флаги shorthand:
|
||||||
- `@autoDates` — добавляет к параметру StandardPeriod пару дат `НачалоПериода`/`КонецПериода`, вычисляемых из него. Используй их в тексте запроса как `&НачалоПериода`/`&КонецПериода`; пользователь выбирает только сам период. По умолчанию сам параметр получает `use=Always` и `denyIncompleteValues=true` (чтобы производные даты всегда были заполнены); в объектной форме можно явно переопределить.
|
- `@autoDates` — добавляет к параметру StandardPeriod пару дат `НачалоПериода`/`КонецПериода`, вычисляемых из него. Используй их в тексте запроса как `&НачалоПериода`/`&КонецПериода`; пользователь выбирает только сам период. По умолчанию сам параметр получает `use=Always` и `denyIncompleteValues=true` (чтобы производные даты всегда были заполнены); в объектной форме можно явно переопределить.
|
||||||
- `@valueList` — `<valueListAllowed>true</valueListAllowed>` — разрешает передавать список значений
|
- `@valueList` — `<valueListAllowed>true</valueListAllowed>` — разрешает передавать список значений (при значении-списке ниже подразумевается автоматически)
|
||||||
- `@hidden` — скрытый параметр: `availableAsField=false` + исключается из `"dataParameters": "auto"`
|
- `@hidden` — скрытый параметр: `availableAsField=false` + исключается из `"dataParameters": "auto"`
|
||||||
|
|
||||||
Объектная форма: `title`, `hidden: true`, `valueListAllowed: true`, `availableAsField: false`, `denyIncompleteValues: true`, `use: "Always"`.
|
Объектная форма: `title`, `hidden: true`, `valueListAllowed: true`, `availableAsField: false`, `denyIncompleteValues: true`, `use: "Always"`.
|
||||||
|
|
||||||
|
Значение-список: несколько значений по умолчанию через запятую в `значение` (для запятой внутри значения — кавычки `'...'`). В объектной форме — массив в `value`.
|
||||||
|
|
||||||
|
```json
|
||||||
|
"parameters": [
|
||||||
|
"Виды: ChartOfCharacteristicTypesRef.ВидыСубконтоХозрасчетные = ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты, ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
Если значения по умолчанию нет — пропусти `=` в shorthand или укажи `"value": null` в объектной форме.
|
Если значения по умолчанию нет — пропусти `=` в shorthand или укажи `"value": null` в объектной форме.
|
||||||
|
|
||||||
Список допустимых значений (availableValues):
|
Список допустимых значений (availableValues):
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# skd-compile v1.104 — Compile 1C DCS from JSON
|
# skd-compile v1.105 — Compile 1C DCS from JSON
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
param(
|
param(
|
||||||
[string]$DefinitionFile,
|
[string]$DefinitionFile,
|
||||||
@@ -475,6 +475,31 @@ function Parse-TotalShorthand {
|
|||||||
|
|
||||||
# --- 7. Parameter shorthand parser ---
|
# --- 7. Parameter shorthand parser ---
|
||||||
|
|
||||||
|
function Split-ValueListCsv {
|
||||||
|
# Split on top-level commas (respecting 'single'/"double" quotes), strip quotes,
|
||||||
|
# drop empties. No ':' handling — values may contain colons (dateTime).
|
||||||
|
param([string]$s)
|
||||||
|
$result = @()
|
||||||
|
if ($null -eq $s) { return ,$result }
|
||||||
|
$items = @()
|
||||||
|
$buf = New-Object System.Text.StringBuilder
|
||||||
|
$inQuote = $null
|
||||||
|
for ($i = 0; $i -lt $s.Length; $i++) {
|
||||||
|
$ch = $s[$i]
|
||||||
|
if ($inQuote) { [void]$buf.Append($ch); if ($ch -eq $inQuote) { $inQuote = $null } }
|
||||||
|
elseif ($ch -eq "'" -or $ch -eq '"') { $inQuote = $ch; [void]$buf.Append($ch) }
|
||||||
|
elseif ($ch -eq ',') { $items += $buf.ToString(); [void]$buf.Clear() }
|
||||||
|
else { [void]$buf.Append($ch) }
|
||||||
|
}
|
||||||
|
if ($buf.Length -gt 0) { $items += $buf.ToString() }
|
||||||
|
foreach ($raw in $items) {
|
||||||
|
$t = $raw.Trim()
|
||||||
|
if ($t.Length -ge 2 -and (($t[0] -eq "'" -and $t[-1] -eq "'") -or ($t[0] -eq '"' -and $t[-1] -eq '"'))) { $t = $t.Substring(1, $t.Length - 2) }
|
||||||
|
if ($t -ne "") { $result += $t }
|
||||||
|
}
|
||||||
|
return ,$result
|
||||||
|
}
|
||||||
|
|
||||||
function Parse-ParamShorthand {
|
function Parse-ParamShorthand {
|
||||||
param([string]$s)
|
param([string]$s)
|
||||||
|
|
||||||
@@ -509,7 +534,17 @@ function Parse-ParamShorthand {
|
|||||||
$result.name = $Matches[1].Trim()
|
$result.name = $Matches[1].Trim()
|
||||||
$result.type = Resolve-TypeStr ($Matches[2].Trim())
|
$result.type = Resolve-TypeStr ($Matches[2].Trim())
|
||||||
if ($Matches[4]) {
|
if ($Matches[4]) {
|
||||||
$result.value = $Matches[4].Trim()
|
$rhs = $Matches[4].Trim()
|
||||||
|
$items = Split-ValueListCsv $rhs
|
||||||
|
if ($items.Count -ge 2) {
|
||||||
|
# Multi-value default → list; valueListAllowed implied
|
||||||
|
$result.value = $items
|
||||||
|
$result.valueListAllowed = $true
|
||||||
|
} elseif ($items.Count -eq 1) {
|
||||||
|
$result.value = $items[0]
|
||||||
|
} else {
|
||||||
|
$result.value = $rhs
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$result.name = $s.Trim()
|
$result.name = $s.Trim()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# skd-compile v1.104 — Compile 1C DCS from JSON
|
# skd-compile v1.105 — Compile 1C DCS from JSON
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
@@ -325,6 +325,39 @@ def parse_total_shorthand(s):
|
|||||||
|
|
||||||
# --- Parameter shorthand parser ---
|
# --- Parameter shorthand parser ---
|
||||||
|
|
||||||
|
def split_value_list_csv(s):
|
||||||
|
"""Split on top-level commas (respecting single/double quotes), strip quotes,
|
||||||
|
drop empties. No ':' handling — values may contain colons (dateTime)."""
|
||||||
|
result = []
|
||||||
|
if s is None:
|
||||||
|
return result
|
||||||
|
items = []
|
||||||
|
buf = []
|
||||||
|
in_quote = None
|
||||||
|
for ch in s:
|
||||||
|
if in_quote:
|
||||||
|
buf.append(ch)
|
||||||
|
if ch == in_quote:
|
||||||
|
in_quote = None
|
||||||
|
elif ch in ("'", '"'):
|
||||||
|
in_quote = ch
|
||||||
|
buf.append(ch)
|
||||||
|
elif ch == ',':
|
||||||
|
items.append("".join(buf))
|
||||||
|
buf = []
|
||||||
|
else:
|
||||||
|
buf.append(ch)
|
||||||
|
if buf:
|
||||||
|
items.append("".join(buf))
|
||||||
|
for raw in items:
|
||||||
|
t = raw.strip()
|
||||||
|
if len(t) >= 2 and ((t[0] == "'" and t[-1] == "'") or (t[0] == '"' and t[-1] == '"')):
|
||||||
|
t = t[1:-1]
|
||||||
|
if t != "":
|
||||||
|
result.append(t)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def parse_param_shorthand(s):
|
def parse_param_shorthand(s):
|
||||||
result = {'name': '', 'type': '', 'value': None, 'autoDates': False, 'title': None}
|
result = {'name': '', 'type': '', 'value': None, 'autoDates': False, 'title': None}
|
||||||
|
|
||||||
@@ -355,7 +388,16 @@ def parse_param_shorthand(s):
|
|||||||
result['name'] = m.group(1).strip()
|
result['name'] = m.group(1).strip()
|
||||||
result['type'] = resolve_type_str(m.group(2).strip())
|
result['type'] = resolve_type_str(m.group(2).strip())
|
||||||
if m.group(4):
|
if m.group(4):
|
||||||
result['value'] = m.group(4).strip()
|
rhs = m.group(4).strip()
|
||||||
|
items = split_value_list_csv(rhs)
|
||||||
|
if len(items) >= 2:
|
||||||
|
# Multi-value default → list; valueListAllowed implied
|
||||||
|
result['value'] = items
|
||||||
|
result['valueListAllowed'] = True
|
||||||
|
elif len(items) == 1:
|
||||||
|
result['value'] = items[0]
|
||||||
|
else:
|
||||||
|
result['value'] = rhs
|
||||||
else:
|
else:
|
||||||
result['name'] = s.strip()
|
result['name'] = s.strip()
|
||||||
|
|
||||||
|
|||||||
@@ -91,6 +91,13 @@ Shorthand: `"Имя [Заголовок]: тип = значение [availableVa
|
|||||||
- `@autoDates` — генерирует пару скрытых параметров `ДатаНачала`/`ДатаОкончания` для StandardPeriod-параметра.
|
- `@autoDates` — генерирует пару скрытых параметров `ДатаНачала`/`ДатаОкончания` для StandardPeriod-параметра.
|
||||||
- `@hidden` — скрывает параметр от пользовательских настроек (для параметров-констант, используемых в запросе).
|
- `@hidden` — скрывает параметр от пользовательских настроек (для параметров-констант, используемых в запросе).
|
||||||
- `@always` — параметр всегда подставляется в запрос. Часто вместе с `@hidden`, но используется и отдельно (для видимых обязательных параметров типа отчётного периода).
|
- `@always` — параметр всегда подставляется в запрос. Часто вместе с `@hidden`, но используется и отдельно (для видимых обязательных параметров типа отчётного периода).
|
||||||
|
- `@valueList` — разрешает передавать в параметр список значений (при значении-списке ниже подразумевается автоматически, отдельно указывать не обязательно).
|
||||||
|
|
||||||
|
Значение-список: несколько значений по умолчанию задаются через запятую в `значение`. Для запятой внутри одного значения — кавычки `'...'`.
|
||||||
|
|
||||||
|
```
|
||||||
|
"Виды [Виды субконто]: ChartOfCharacteristicTypesRef.ВидыСубконтоХозрасчетные = ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты, ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры"
|
||||||
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
"ПС: CatalogRef.Контрагенты = Справочник.Контрагенты.ПустаяСсылка @hidden"
|
"ПС: CatalogRef.Контрагенты = Справочник.Контрагенты.ПустаяСсылка @hidden"
|
||||||
@@ -115,6 +122,7 @@ Shorthand: `"ИмяПараметра [Заголовок] [ключ=значе
|
|||||||
"ПериодОтчета [Отчетный период]" # только title
|
"ПериодОтчета [Отчетный период]" # только title
|
||||||
"ПорядокОкругления availableValue=Перечисление.Округления.Окр1: руб., Перечисление.Округления.Окр1000: тыс."
|
"ПорядокОкругления availableValue=Перечисление.Округления.Окр1: руб., Перечисление.Округления.Окр1000: тыс."
|
||||||
"СчетПС value=ПланСчетов.Хозрасчетный.КассаПредприятия"
|
"СчетПС value=ПланСчетов.Хозрасчетный.КассаПредприятия"
|
||||||
|
"Виды value=ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты, ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры"
|
||||||
"Контрагент @hidden @always"
|
"Контрагент @hidden @always"
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -122,7 +130,7 @@ Shorthand: `"ИмяПараметра [Заголовок] [ключ=значе
|
|||||||
|
|
||||||
`availableValue=` **заменяет весь список** допустимых значений (старые удаляются). Формат и кавычки — те же, что в `add-parameter`.
|
`availableValue=` **заменяет весь список** допустимых значений (старые удаляются). Формат и кавычки — те же, что в `add-parameter`.
|
||||||
|
|
||||||
`value=` заменяет значение параметра (тип значения подбирается автоматически по объявленному типу параметра).
|
`value=` заменяет значение параметра. Несколько значений через запятую → **список значений** (заменяет все прежние); для запятой внутри значения — кавычки `'...'`.
|
||||||
|
|
||||||
Флаги `@hidden` / `@always` — те же, что и в `add-parameter`. Идемпотентны.
|
Флаги `@hidden` / `@always` — те же, что и в `add-parameter`. Идемпотентны.
|
||||||
|
|
||||||
@@ -256,6 +264,8 @@ Value — имена ресурсов (как в полях/вычисляемы
|
|||||||
|
|
||||||
Не поддерживает пакетный режим. Value — полный текст запроса или `@path/to/file.sql` (ссылка на внешний файл). Путь разрешается относительно Template.xml, затем CWD.
|
Не поддерживает пакетный режим. 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 — точечная замена в тексте запроса
|
### patch-query — точечная замена в тексте запроса
|
||||||
|
|
||||||
Shorthand: `"старое => новое [@once]"`. По умолчанию заменяет все вхождения подстроки. Поддерживает пакетный режим и `-DataSet`.
|
Shorthand: `"старое => новое [@once]"`. По умолчанию заменяет все вхождения подстроки. Поддерживает пакетный режим и `-DataSet`.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# skd-edit v1.24 — Atomic 1C DCS editor
|
# skd-edit v1.25 — Atomic 1C DCS editor
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory)]
|
[Parameter(Mandatory)]
|
||||||
@@ -378,7 +378,19 @@ function Parse-ParamShorthand {
|
|||||||
$hasEq = $null -ne $Matches[3]
|
$hasEq = $null -ne $Matches[3]
|
||||||
$rhs = $Matches[4]
|
$rhs = $Matches[4]
|
||||||
if ($hasEq) {
|
if ($hasEq) {
|
||||||
$result.value = if ($rhs) { $rhs.Trim() } else { "" }
|
if ($rhs -and $rhs.Trim()) {
|
||||||
|
$items = Parse-ValueList $rhs.Trim()
|
||||||
|
if ($items.Count -ge 2) {
|
||||||
|
# Multi-value default → list; valueListAllowed implied
|
||||||
|
$result.value = $items
|
||||||
|
$result.valueListAllowed = $true
|
||||||
|
} else {
|
||||||
|
# Scalar (single item, quotes stripped) or empty sentinel
|
||||||
|
$result.value = if ($items.Count -eq 1) { $items[0] } else { "" }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$result.value = ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$result.name = $s.Trim()
|
$result.name = $s.Trim()
|
||||||
@@ -679,16 +691,13 @@ function Parse-OutputParamShorthand {
|
|||||||
return @{ key = $s.Trim(); value = "" }
|
return @{ key = $s.Trim(); value = "" }
|
||||||
}
|
}
|
||||||
|
|
||||||
function Parse-AvailableValueList {
|
function Split-QuotedCsv {
|
||||||
# Returns array of @{ value=...; presentation=... } from comma-separated list.
|
# Splits on top-level commas, respecting 'single' and "double" quoted spans.
|
||||||
# Items can use 'single' or "double" quotes (stripped). Quoted spans preserve commas/colons.
|
# Returns raw (un-stripped, un-trimmed) item spans. Used by both availableValue
|
||||||
|
# (value:presentation) and value-list (values only) parsing.
|
||||||
param([string]$s)
|
param([string]$s)
|
||||||
|
|
||||||
$result = @()
|
|
||||||
if (-not $s) { return ,$result }
|
|
||||||
|
|
||||||
# Tokenize by ',' respecting quoted spans
|
|
||||||
$items = @()
|
$items = @()
|
||||||
|
if ($null -eq $s) { return ,$items }
|
||||||
$buf = New-Object System.Text.StringBuilder
|
$buf = New-Object System.Text.StringBuilder
|
||||||
$inQuote = $null
|
$inQuote = $null
|
||||||
for ($i = 0; $i -lt $s.Length; $i++) {
|
for ($i = 0; $i -lt $s.Length; $i++) {
|
||||||
@@ -707,16 +716,42 @@ function Parse-AvailableValueList {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($buf.Length -gt 0) { $items += $buf.ToString() }
|
if ($buf.Length -gt 0) { $items += $buf.ToString() }
|
||||||
|
return ,$items
|
||||||
|
}
|
||||||
|
|
||||||
# For each item: split into value[:presentation], strip quotes
|
function Strip-Quotes {
|
||||||
$stripQuotes = {
|
# Strips a single surrounding pair of matching quotes; trims first.
|
||||||
param($t)
|
param([string]$t)
|
||||||
$t = $t.Trim()
|
$t = $t.Trim()
|
||||||
if ($t.Length -ge 2 -and (($t[0] -eq "'" -and $t[-1] -eq "'") -or ($t[0] -eq '"' -and $t[-1] -eq '"'))) {
|
if ($t.Length -ge 2 -and (($t[0] -eq "'" -and $t[-1] -eq "'") -or ($t[0] -eq '"' -and $t[-1] -eq '"'))) {
|
||||||
return $t.Substring(1, $t.Length - 2)
|
return $t.Substring(1, $t.Length - 2)
|
||||||
}
|
|
||||||
return $t
|
|
||||||
}
|
}
|
||||||
|
return $t
|
||||||
|
}
|
||||||
|
|
||||||
|
function Parse-ValueList {
|
||||||
|
# Returns array of value strings (quotes stripped) split by top-level commas.
|
||||||
|
# No ':' handling — values may contain colons (e.g. dateTime 2024-01-01T12:30:00).
|
||||||
|
param([string]$s)
|
||||||
|
$result = @()
|
||||||
|
if ($null -eq $s) { return ,$result }
|
||||||
|
foreach ($raw in (Split-QuotedCsv $s)) {
|
||||||
|
$v = Strip-Quotes $raw
|
||||||
|
if ($v -ne "") { $result += $v }
|
||||||
|
}
|
||||||
|
return ,$result
|
||||||
|
}
|
||||||
|
|
||||||
|
function Parse-AvailableValueList {
|
||||||
|
# Returns array of @{ value=...; presentation=... } from comma-separated list.
|
||||||
|
# Items can use 'single' or "double" quotes (stripped). Quoted spans preserve commas/colons.
|
||||||
|
param([string]$s)
|
||||||
|
|
||||||
|
$result = @()
|
||||||
|
if (-not $s) { return ,$result }
|
||||||
|
|
||||||
|
$items = Split-QuotedCsv $s
|
||||||
|
$stripQuotes = { param($t) Strip-Quotes $t }
|
||||||
|
|
||||||
foreach ($raw in $items) {
|
foreach ($raw in $items) {
|
||||||
$item = $raw.Trim()
|
$item = $raw.Trim()
|
||||||
@@ -1135,7 +1170,14 @@ function Build-ParamFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$vla = [bool]$parsed.valueListAllowed
|
$vla = [bool]$parsed.valueListAllowed
|
||||||
if ($null -ne $parsed.value) {
|
$valIsArray = ($parsed.value -is [array]) -or ($parsed.value -is [System.Collections.IList] -and $parsed.value -isnot [string])
|
||||||
|
if ($valIsArray) {
|
||||||
|
# Multi-value default (value-list): one <value> per item
|
||||||
|
foreach ($v in $parsed.value) {
|
||||||
|
$valueLines = Build-ParamValueXml -type $parsed.type -value $v -indent "$i`t"
|
||||||
|
foreach ($vl in $valueLines) { $lines += $vl }
|
||||||
|
}
|
||||||
|
} elseif ($null -ne $parsed.value) {
|
||||||
if (Test-EmptyValue $parsed.value) {
|
if (Test-EmptyValue $parsed.value) {
|
||||||
$emptyXml = Build-EmptyValueXml -type $parsed.type -indent "$i`t" -tagPrefix "" -tagName "value" -valueListAllowed $vla
|
$emptyXml = Build-EmptyValueXml -type $parsed.type -indent "$i`t" -tagPrefix "" -tagName "value" -valueListAllowed $vla
|
||||||
if ($emptyXml) { $lines += $emptyXml }
|
if ($emptyXml) { $lines += $emptyXml }
|
||||||
@@ -2292,6 +2334,20 @@ switch ($Operation) {
|
|||||||
$avPart = $rest.Substring($avIdx)
|
$avPart = $rest.Substring($avIdx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Separate a multi-value value=... (list) — kv-regex below grabs only a single
|
||||||
|
# \S+ token, so a comma-separated list (with spaces) wouldn't be captured.
|
||||||
|
# availableValue already peeled, so 'value=' here is the real value key.
|
||||||
|
$valueListItems = $null
|
||||||
|
$vlIdx = $simpleRest.IndexOf('value=')
|
||||||
|
if ($vlIdx -ge 0) {
|
||||||
|
$vlRhs = $simpleRest.Substring($vlIdx + 'value='.Length)
|
||||||
|
$cand = Parse-ValueList $vlRhs
|
||||||
|
if ($cand.Count -ge 2) {
|
||||||
|
$valueListItems = $cand
|
||||||
|
$simpleRest = $simpleRest.Substring(0, $vlIdx).Trim()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Process simple key=value pairs (use, denyIncompleteValues, value, etc.)
|
# Process simple key=value pairs (use, denyIncompleteValues, value, etc.)
|
||||||
if ($simpleRest) {
|
if ($simpleRest) {
|
||||||
$kvPairs = [regex]::Matches($simpleRest, '(\w+)=(\S+)')
|
$kvPairs = [regex]::Matches($simpleRest, '(\w+)=(\S+)')
|
||||||
@@ -2337,14 +2393,20 @@ switch ($Operation) {
|
|||||||
$fragXml = $valueLines -join "`n"
|
$fragXml = $valueLines -join "`n"
|
||||||
}
|
}
|
||||||
|
|
||||||
$wasExisting = ($null -ne $existing)
|
# Collect ALL existing <value> (a param may carry a value-list) — scalar
|
||||||
if ($existing) {
|
# value= collapses them to one, so remove every <value>, not just the first.
|
||||||
# Capture position by next-element sibling, then remove existing
|
$allValueEls = @()
|
||||||
$refNode = $existing.NextSibling
|
foreach ($ch in $paramEl.ChildNodes) {
|
||||||
|
if ($ch.NodeType -eq 'Element' -and $ch.LocalName -eq 'value' -and $ch.NamespaceURI -eq $schNs) { $allValueEls += $ch }
|
||||||
|
}
|
||||||
|
$wasExisting = ($allValueEls.Count -gt 0)
|
||||||
|
if ($wasExisting) {
|
||||||
|
# Capture position after the last existing value, then remove all
|
||||||
|
$refNode = $allValueEls[$allValueEls.Count - 1].NextSibling
|
||||||
while ($refNode -and ($refNode.NodeType -eq 'Whitespace' -or $refNode.NodeType -eq 'SignificantWhitespace')) {
|
while ($refNode -and ($refNode.NodeType -eq 'Whitespace' -or $refNode.NodeType -eq 'SignificantWhitespace')) {
|
||||||
$refNode = $refNode.NextSibling
|
$refNode = $refNode.NextSibling
|
||||||
}
|
}
|
||||||
Remove-NodeWithWhitespace $existing
|
foreach ($ve in $allValueEls) { Remove-NodeWithWhitespace $ve }
|
||||||
} else {
|
} else {
|
||||||
# Insert before useRestriction/availableValue/denyIncompleteValues/use
|
# Insert before useRestriction/availableValue/denyIncompleteValues/use
|
||||||
$refNode = $null
|
$refNode = $null
|
||||||
@@ -2385,6 +2447,60 @@ switch ($Operation) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Process multi-value list (value=v1, v2, ...) — replace ALL <value>, ensure valueListAllowed=true
|
||||||
|
if ($valueListItems) {
|
||||||
|
# Declared type from <valueType>
|
||||||
|
$declaredType = ""
|
||||||
|
$vtEl = $null
|
||||||
|
foreach ($ch in $paramEl.ChildNodes) {
|
||||||
|
if ($ch.NodeType -eq 'Element' -and $ch.LocalName -eq 'valueType' -and $ch.NamespaceURI -eq $schNs) { $vtEl = $ch; break }
|
||||||
|
}
|
||||||
|
if ($vtEl) {
|
||||||
|
foreach ($tnode in $vtEl.ChildNodes) {
|
||||||
|
if ($tnode.NodeType -eq 'Element' -and $tnode.LocalName -eq 'Type') {
|
||||||
|
$declaredType = $tnode.InnerText.Trim() -replace '^d\d+p\d+:', ''
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# Remove ALL existing <value>; capture insertion ref after the last one
|
||||||
|
$valueEls = @()
|
||||||
|
foreach ($child in $paramEl.ChildNodes) {
|
||||||
|
if ($child.NodeType -eq 'Element' -and $child.LocalName -eq 'value' -and $child.NamespaceURI -eq $schNs) { $valueEls += $child }
|
||||||
|
}
|
||||||
|
$refNode = $null
|
||||||
|
if ($valueEls.Count -gt 0) {
|
||||||
|
$refNode = $valueEls[$valueEls.Count - 1].NextSibling
|
||||||
|
while ($refNode -and ($refNode.NodeType -eq 'Whitespace' -or $refNode.NodeType -eq 'SignificantWhitespace')) { $refNode = $refNode.NextSibling }
|
||||||
|
foreach ($ve in $valueEls) { Remove-NodeWithWhitespace $ve }
|
||||||
|
} else {
|
||||||
|
foreach ($child in $paramEl.ChildNodes) {
|
||||||
|
if ($child.NodeType -eq 'Element' -and $child.LocalName -in @('useRestriction','availableValue','denyIncompleteValues','use')) { $refNode = $child; break }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($v in $valueListItems) {
|
||||||
|
$fragXml = (Build-ParamValueXml -type $declaredType -value $v -indent $childIndent) -join "`n"
|
||||||
|
$nodes = Import-Fragment $xmlDoc $fragXml
|
||||||
|
foreach ($node in $nodes) { Insert-BeforeElement $paramEl $node $refNode $childIndent }
|
||||||
|
}
|
||||||
|
# Ensure <valueListAllowed>true</valueListAllowed> (schema order: after useRestriction, before availableValue/use)
|
||||||
|
$vlaEl = $null
|
||||||
|
foreach ($ch in $paramEl.ChildNodes) {
|
||||||
|
if ($ch.NodeType -eq 'Element' -and $ch.LocalName -eq 'valueListAllowed' -and $ch.NamespaceURI -eq $schNs) { $vlaEl = $ch; break }
|
||||||
|
}
|
||||||
|
if ($vlaEl) {
|
||||||
|
if ($vlaEl.InnerText.Trim() -ne 'true') { $vlaEl.InnerText = 'true' }
|
||||||
|
} else {
|
||||||
|
$refVla = $null
|
||||||
|
foreach ($child in $paramEl.ChildNodes) {
|
||||||
|
if ($child.NodeType -eq 'Element' -and $child.LocalName -in @('availableValue','denyIncompleteValues','use')) { $refVla = $child; break }
|
||||||
|
}
|
||||||
|
$nodes = Import-Fragment $xmlDoc "$childIndent<valueListAllowed>true</valueListAllowed>"
|
||||||
|
foreach ($node in $nodes) { Insert-BeforeElement $paramEl $node $refVla $childIndent }
|
||||||
|
}
|
||||||
|
$script:Dirty = $true; Write-Host "[OK] Parameter `"$paramName`": value set to list of $($valueListItems.Count) item(s)"
|
||||||
|
}
|
||||||
|
|
||||||
# Process availableValue — replace whole list with new items
|
# Process availableValue — replace whole list with new items
|
||||||
if ($avPart) {
|
if ($avPart) {
|
||||||
$avRest = ($avPart -replace '^availableValue=', '').Trim()
|
$avRest = ($avPart -replace '^availableValue=', '').Trim()
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# skd-edit v1.24 — Atomic 1C DCS editor (Python port)
|
# skd-edit v1.25 — Atomic 1C DCS editor (Python port)
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
@@ -371,7 +371,18 @@ def parse_param_shorthand(s):
|
|||||||
result["name"] = m.group(1).strip()
|
result["name"] = m.group(1).strip()
|
||||||
result["type"] = resolve_type_str(m.group(2).strip())
|
result["type"] = resolve_type_str(m.group(2).strip())
|
||||||
if m.group(3) is not None:
|
if m.group(3) is not None:
|
||||||
result["value"] = m.group(4).strip() if m.group(4) else ""
|
rhs = m.group(4)
|
||||||
|
if rhs and rhs.strip():
|
||||||
|
items = parse_value_list(rhs.strip())
|
||||||
|
if len(items) >= 2:
|
||||||
|
# Multi-value default → list; valueListAllowed implied
|
||||||
|
result["value"] = items
|
||||||
|
result["valueListAllowed"] = True
|
||||||
|
else:
|
||||||
|
# Scalar (single item, quotes stripped) or empty sentinel
|
||||||
|
result["value"] = items[0] if len(items) == 1 else ""
|
||||||
|
else:
|
||||||
|
result["value"] = ""
|
||||||
else:
|
else:
|
||||||
result["name"] = s.strip()
|
result["name"] = s.strip()
|
||||||
|
|
||||||
@@ -631,14 +642,12 @@ def parse_output_param_shorthand(s):
|
|||||||
return {"key": s.strip(), "value": ""}
|
return {"key": s.strip(), "value": ""}
|
||||||
|
|
||||||
|
|
||||||
def parse_available_value_list(s):
|
def split_quoted_csv(s):
|
||||||
"""Returns list of {value, presentation} from comma-separated list.
|
"""Split on top-level commas, respecting single/double quoted spans.
|
||||||
Items can use single/double quotes (stripped). Quoted spans preserve commas/colons."""
|
Returns raw (un-stripped) item spans. Shared by availableValue and value-list parsing."""
|
||||||
if not s:
|
|
||||||
return []
|
|
||||||
|
|
||||||
# Tokenize by ',' respecting quoted spans
|
|
||||||
items = []
|
items = []
|
||||||
|
if s is None:
|
||||||
|
return items
|
||||||
buf = []
|
buf = []
|
||||||
in_quote = None
|
in_quote = None
|
||||||
for ch in s:
|
for ch in s:
|
||||||
@@ -656,12 +665,37 @@ def parse_available_value_list(s):
|
|||||||
buf.append(ch)
|
buf.append(ch)
|
||||||
if buf:
|
if buf:
|
||||||
items.append("".join(buf))
|
items.append("".join(buf))
|
||||||
|
return items
|
||||||
|
|
||||||
def strip_quotes(t):
|
|
||||||
t = t.strip()
|
def strip_quotes(t):
|
||||||
if len(t) >= 2 and ((t[0] == "'" and t[-1] == "'") or (t[0] == '"' and t[-1] == '"')):
|
"""Strip a single surrounding pair of matching quotes; trims first."""
|
||||||
return t[1:-1]
|
t = t.strip()
|
||||||
return t
|
if len(t) >= 2 and ((t[0] == "'" and t[-1] == "'") or (t[0] == '"' and t[-1] == '"')):
|
||||||
|
return t[1:-1]
|
||||||
|
return t
|
||||||
|
|
||||||
|
|
||||||
|
def parse_value_list(s):
|
||||||
|
"""Return list of value strings (quotes stripped) split by top-level commas.
|
||||||
|
No ':' handling — values may contain colons (e.g. dateTime 2024-01-01T12:30:00)."""
|
||||||
|
if s is None:
|
||||||
|
return []
|
||||||
|
result = []
|
||||||
|
for raw in split_quoted_csv(s):
|
||||||
|
v = strip_quotes(raw)
|
||||||
|
if v != "":
|
||||||
|
result.append(v)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def parse_available_value_list(s):
|
||||||
|
"""Returns list of {value, presentation} from comma-separated list.
|
||||||
|
Items can use single/double quotes (stripped). Quoted spans preserve commas/colons."""
|
||||||
|
if not s:
|
||||||
|
return []
|
||||||
|
|
||||||
|
items = split_quoted_csv(s)
|
||||||
|
|
||||||
result = []
|
result = []
|
||||||
for raw in items:
|
for raw in items:
|
||||||
@@ -1012,7 +1046,12 @@ def build_param_fragment(parsed, indent):
|
|||||||
lines.append(f"{i}\t</valueType>")
|
lines.append(f"{i}\t</valueType>")
|
||||||
|
|
||||||
vla = bool(parsed.get("valueListAllowed"))
|
vla = bool(parsed.get("valueListAllowed"))
|
||||||
if parsed["value"] is not None:
|
if isinstance(parsed["value"], list):
|
||||||
|
# Multi-value default (value-list): one <value> per item
|
||||||
|
for v in parsed["value"]:
|
||||||
|
for vl in build_param_value_xml(parsed.get("type", ""), v, f"{i}\t"):
|
||||||
|
lines.append(vl)
|
||||||
|
elif parsed["value"] is not None:
|
||||||
if is_empty_value(parsed["value"]):
|
if is_empty_value(parsed["value"]):
|
||||||
empty_xml = build_empty_value_xml(parsed.get("type", ""), f"{i}\t", "", "value", vla)
|
empty_xml = build_empty_value_xml(parsed.get("type", ""), f"{i}\t", "", "value", vla)
|
||||||
if empty_xml:
|
if empty_xml:
|
||||||
@@ -1987,6 +2026,17 @@ elif operation == "modify-parameter":
|
|||||||
simple_rest = rest[:av_idx].strip()
|
simple_rest = rest[:av_idx].strip()
|
||||||
av_part = rest[av_idx:]
|
av_part = rest[av_idx:]
|
||||||
|
|
||||||
|
# Separate a multi-value value=... (list) — kv-regex below grabs only a single
|
||||||
|
# \S+ token, so a comma-separated list (with spaces) wouldn't be captured.
|
||||||
|
value_list_items = None
|
||||||
|
vl_idx = simple_rest.find("value=")
|
||||||
|
if vl_idx >= 0:
|
||||||
|
vl_rhs = simple_rest[vl_idx + len("value="):]
|
||||||
|
cand = parse_value_list(vl_rhs)
|
||||||
|
if len(cand) >= 2:
|
||||||
|
value_list_items = cand
|
||||||
|
simple_rest = simple_rest[:vl_idx].strip()
|
||||||
|
|
||||||
# Process simple key=value pairs (use, denyIncompleteValues, etc.)
|
# Process simple key=value pairs (use, denyIncompleteValues, etc.)
|
||||||
if simple_rest:
|
if simple_rest:
|
||||||
for m in re.finditer(r'(\w+)=(\S+)', simple_rest):
|
for m in re.finditer(r'(\w+)=(\S+)', simple_rest):
|
||||||
@@ -2012,12 +2062,15 @@ elif operation == "modify-parameter":
|
|||||||
else:
|
else:
|
||||||
value_lines = build_param_value_xml(declared_type, value, child_indent)
|
value_lines = build_param_value_xml(declared_type, value, child_indent)
|
||||||
frag_xml = "\n".join(value_lines)
|
frag_xml = "\n".join(value_lines)
|
||||||
was_existing = existing is not None
|
# Collect ALL existing <value> (a param may carry a value-list) — scalar
|
||||||
if existing is not None:
|
# value= collapses them to one, so remove every <value>, not just the first.
|
||||||
# Find next-element sibling as ref before removing
|
all_value_els = [ch for ch in param_el if isinstance(ch.tag, str) and local_name(ch) == "value" and etree.QName(ch.tag).namespace == SCH_NS]
|
||||||
idx = list(param_el).index(existing)
|
was_existing = len(all_value_els) > 0
|
||||||
ref_node = param_el[idx + 1] if idx + 1 < len(param_el) else None
|
if was_existing:
|
||||||
remove_node_with_whitespace(existing)
|
last_idx = list(param_el).index(all_value_els[-1])
|
||||||
|
ref_node = param_el[last_idx + 1] if last_idx + 1 < len(param_el) else None
|
||||||
|
for ve in all_value_els:
|
||||||
|
remove_node_with_whitespace(ve)
|
||||||
else:
|
else:
|
||||||
ref_node = next((ch for ch in param_el if isinstance(ch.tag, str) and local_name(ch) in ("useRestriction", "availableValue", "denyIncompleteValues", "use")), None)
|
ref_node = next((ch for ch in param_el if isinstance(ch.tag, str) and local_name(ch) in ("useRestriction", "availableValue", "denyIncompleteValues", "use")), None)
|
||||||
if frag_xml:
|
if frag_xml:
|
||||||
@@ -2040,6 +2093,39 @@ elif operation == "modify-parameter":
|
|||||||
insert_before_element(param_el, node, ref_node, child_indent)
|
insert_before_element(param_el, node, ref_node, child_indent)
|
||||||
dirty = True; print(f'[OK] Parameter "{param_name}": {key}={value} added')
|
dirty = True; print(f'[OK] Parameter "{param_name}": {key}={value} added')
|
||||||
|
|
||||||
|
# Process multi-value list (value=v1, v2, ...) — replace ALL <value>, ensure valueListAllowed=true
|
||||||
|
if value_list_items:
|
||||||
|
declared_type = ""
|
||||||
|
vt_el = next((ch for ch in param_el if isinstance(ch.tag, str) and local_name(ch) == "valueType" and etree.QName(ch.tag).namespace == SCH_NS), None)
|
||||||
|
if vt_el is not None:
|
||||||
|
for tnode in vt_el:
|
||||||
|
if isinstance(tnode.tag, str) and local_name(tnode) == "Type":
|
||||||
|
declared_type = re.sub(r'^d\d+p\d+:', '', (tnode.text or "").strip())
|
||||||
|
break
|
||||||
|
# Remove ALL existing <value>; capture insertion ref after the last one
|
||||||
|
value_els = [ch for ch in param_el if isinstance(ch.tag, str) and local_name(ch) == "value" and etree.QName(ch.tag).namespace == SCH_NS]
|
||||||
|
if value_els:
|
||||||
|
last_idx = list(param_el).index(value_els[-1])
|
||||||
|
ref_node = param_el[last_idx + 1] if last_idx + 1 < len(param_el) else None
|
||||||
|
for ve in value_els:
|
||||||
|
remove_node_with_whitespace(ve)
|
||||||
|
else:
|
||||||
|
ref_node = next((ch for ch in param_el if isinstance(ch.tag, str) and local_name(ch) in ("useRestriction", "availableValue", "denyIncompleteValues", "use")), None)
|
||||||
|
for v in value_list_items:
|
||||||
|
frag_xml = "\n".join(build_param_value_xml(declared_type, v, child_indent))
|
||||||
|
for node in import_fragment(xml_doc, frag_xml):
|
||||||
|
insert_before_element(param_el, node, ref_node, child_indent)
|
||||||
|
# Ensure <valueListAllowed>true</valueListAllowed> (schema order: after useRestriction, before availableValue/use)
|
||||||
|
vla_el = next((ch for ch in param_el if isinstance(ch.tag, str) and local_name(ch) == "valueListAllowed" and etree.QName(ch.tag).namespace == SCH_NS), None)
|
||||||
|
if vla_el is not None:
|
||||||
|
if (vla_el.text or "").strip() != "true":
|
||||||
|
vla_el.text = "true"
|
||||||
|
else:
|
||||||
|
ref_vla = next((ch for ch in param_el if isinstance(ch.tag, str) and local_name(ch) in ("availableValue", "denyIncompleteValues", "use")), None)
|
||||||
|
for node in import_fragment(xml_doc, f"{child_indent}<valueListAllowed>true</valueListAllowed>"):
|
||||||
|
insert_before_element(param_el, node, ref_vla, child_indent)
|
||||||
|
dirty = True; print(f'[OK] Parameter "{param_name}": value set to list of {len(value_list_items)} item(s)')
|
||||||
|
|
||||||
# Process availableValue
|
# Process availableValue
|
||||||
if av_part:
|
if av_part:
|
||||||
av_rest = av_part[len("availableValue="):].strip()
|
av_rest = av_part[len("availableValue="):].strip()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
name: skd-info
|
name: skd-info
|
||||||
description: Анализ структуры схемы компоновки данных 1С (СКД) — наборы, поля, параметры, варианты. Используй для понимания отчёта — источник данных (запрос), доступные поля, параметры
|
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:
|
allowed-tools:
|
||||||
- Bash
|
- Bash
|
||||||
- Read
|
- Read
|
||||||
@@ -20,7 +20,8 @@ allowed-tools:
|
|||||||
| `Mode` | Режим анализа (по умолчанию `overview`) |
|
| `Mode` | Режим анализа (по умолчанию `overview`) |
|
||||||
| `Name` | Имя набора (query), поля (fields/calculated/resources/trace), варианта (variant) или группировки/поля (templates) |
|
| `Name` | Имя набора (query), поля (fields/calculated/resources/trace), варианта (variant) или группировки/поля (templates) |
|
||||||
| `Batch` | Номер пакета запроса, 0 = все (только query) |
|
| `Batch` | Номер пакета запроса, 0 = все (только query) |
|
||||||
| `Limit` / `Offset` | Пагинация (по умолчанию 150 строк) |
|
| `Raw` | (только query) сырой текст запроса целиком, без заголовков/оглавления/разделителей пакетов. Для выгрузки в `.sql` и возврата через `skd-edit set-query @file` |
|
||||||
|
| `Limit` / `Offset` | Пагинация (по умолчанию 150 строк; `-Raw` не усекается) |
|
||||||
| `OutFile` | Записать результат в файл (UTF-8 BOM) |
|
| `OutFile` | Записать результат в файл (UTF-8 BOM) |
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
@@ -31,6 +32,7 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/skd-info.ps1" -Temp
|
|||||||
```powershell
|
```powershell
|
||||||
... -Mode query -Name НоменклатураСЦенами
|
... -Mode query -Name НоменклатураСЦенами
|
||||||
... -Mode query -Name ДанныеТ13 -Batch 3
|
... -Mode query -Name ДанныеТ13 -Batch 3
|
||||||
|
... -Mode query -Name ДанныеТ13 -Raw -OutFile query.sql
|
||||||
... -Mode fields -Name КадастроваяСтоимость
|
... -Mode fields -Name КадастроваяСтоимость
|
||||||
... -Mode calculated -Name КоэффициентКи
|
... -Mode calculated -Name КоэффициентКи
|
||||||
... -Mode resources -Name СуммаНалога
|
... -Mode resources -Name СуммаНалога
|
||||||
@@ -45,7 +47,7 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/skd-info.ps1" -Temp
|
|||||||
| Режим | Без `-Name` | С `-Name` |
|
| Режим | Без `-Name` | С `-Name` |
|
||||||
|-------|-------------|-----------|
|
|-------|-------------|-----------|
|
||||||
| `overview` | Навигационная карта схемы + подсказки Next | — |
|
| `overview` | Навигационная карта схемы + подсказки Next | — |
|
||||||
| `query` | — | Текст запроса набора (с оглавлением батчей) |
|
| `query` | — | Текст запроса набора (с оглавлением батчей); `-Raw` — чистая выгрузка для правки |
|
||||||
| `fields` | Карта: имена полей по наборам | Деталь поля: набор, тип, роль, формат |
|
| `fields` | Карта: имена полей по наборам | Деталь поля: набор, тип, роль, формат |
|
||||||
| `links` | Все связи наборов | — |
|
| `links` | Все связи наборов | — |
|
||||||
| `calculated` | Карта: имена вычисляемых полей | Выражение + заголовок + ограничения |
|
| `calculated` | Карта: имена вычисляемых полей | Выражение + заголовок + ограничения |
|
||||||
@@ -65,7 +67,10 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/skd-info.ps1" -Temp
|
|||||||
3. `query -Name <набор>` — посмотреть текст SQL-запроса
|
3. `query -Name <набор>` — посмотреть текст SQL-запроса
|
||||||
4. `variant -Name <N>` — посмотреть группировки и фильтры варианта
|
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
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory=$true)]
|
||||||
@@ -10,7 +10,8 @@ param(
|
|||||||
[int]$Batch = 0,
|
[int]$Batch = 0,
|
||||||
[int]$Limit = 150,
|
[int]$Limit = 150,
|
||||||
[int]$Offset = 0,
|
[int]$Offset = 0,
|
||||||
[string]$OutFile
|
[string]$OutFile,
|
||||||
|
[switch]$Raw
|
||||||
)
|
)
|
||||||
|
|
||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
@@ -655,6 +656,13 @@ function Show-Query {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$rawQuery = Unescape-Xml $queryNode.InnerText
|
$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
|
$dsNameStr = $targetDs.SelectSingleNode("s:name", $ns).InnerText
|
||||||
|
|
||||||
# Split into batches
|
# Split into batches
|
||||||
@@ -1894,7 +1902,7 @@ if ($Offset -gt 0) {
|
|||||||
$result = $result[$Offset..($totalLines - 1)]
|
$result = $result[$Offset..($totalLines - 1)]
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($result.Count -gt $Limit) {
|
if (-not $Raw -and $result.Count -gt $Limit) {
|
||||||
$shown = $result[0..($Limit - 1)]
|
$shown = $result[0..($Limit - 1)]
|
||||||
foreach ($l in $shown) { Write-Host $l }
|
foreach ($l in $shown) { Write-Host $l }
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/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
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
@@ -278,6 +278,7 @@ def main():
|
|||||||
parser.add_argument("-Limit", type=int, default=150)
|
parser.add_argument("-Limit", type=int, default=150)
|
||||||
parser.add_argument("-Offset", type=int, default=0)
|
parser.add_argument("-Offset", type=int, default=0)
|
||||||
parser.add_argument("-OutFile", default=None)
|
parser.add_argument("-OutFile", default=None)
|
||||||
|
parser.add_argument("-Raw", action="store_true")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
# --- Resolve path ---
|
# --- Resolve path ---
|
||||||
@@ -634,6 +635,13 @@ def main():
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
raw_query = unescape_xml("".join(query_node.itertext()))
|
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 "")
|
ds_name_str = (target_ds.find("s:name", NSMAP).text or "")
|
||||||
|
|
||||||
# Split into batches
|
# Split into batches
|
||||||
@@ -1719,7 +1727,7 @@ def main():
|
|||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
result = result[args.Offset:]
|
result = result[args.Offset:]
|
||||||
|
|
||||||
if len(result) > args.Limit:
|
if not args.Raw and len(result) > args.Limit:
|
||||||
shown = result[:args.Limit]
|
shown = result[:args.Limit]
|
||||||
for line in shown:
|
for line in shown:
|
||||||
print(line)
|
print(line)
|
||||||
|
|||||||
@@ -530,6 +530,26 @@ DataCompositionSchema
|
|||||||
|
|
||||||
Стандартные варианты периодов (`v8:StandardPeriodVariant`): `Custom`, `Today`, `ThisWeek`, `ThisMonth`, `ThisQuarter`, `ThisYear`, `LastMonth`, `LastQuarter`, `LastYear` и др.
|
Стандартные варианты периодов (`v8:StandardPeriodVariant`): `Custom`, `Today`, `ThisWeek`, `ThisMonth`, `ThisQuarter`, `ThisYear`, `LastMonth`, `LastQuarter`, `LastYear` и др.
|
||||||
|
|
||||||
|
#### Значение-список (несколько значений по умолчанию)
|
||||||
|
|
||||||
|
Значением параметра может быть список — несколько элементов `<value>` подряд внутри
|
||||||
|
`<parameter>`, при `<valueListAllowed>true</valueListAllowed>`:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<parameter>
|
||||||
|
<name>ВидыСубконто</name>
|
||||||
|
<valueType>
|
||||||
|
<v8:Type xmlns:d5p1="http://v8.1c.ru/8.1/data/enterprise/current-config">d5p1:ChartOfCharacteristicTypesRef.ВидыСубконтоХозрасчетные</v8:Type>
|
||||||
|
</valueType>
|
||||||
|
<value xsi:type="dcscor:DesignTimeValue">ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты</value>
|
||||||
|
<value xsi:type="dcscor:DesignTimeValue">ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры</value>
|
||||||
|
<useRestriction>true</useRestriction>
|
||||||
|
<valueListAllowed>true</valueListAllowed>
|
||||||
|
</parameter>
|
||||||
|
```
|
||||||
|
|
||||||
|
Порядок элементов: `name, title, valueType, value*, useRestriction, …, valueListAllowed`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 9. Макеты областей (template)
|
## 9. Макеты областей (template)
|
||||||
|
|||||||
@@ -339,6 +339,12 @@ XML-маппинг — по `<group>` на каждый элемент:
|
|||||||
|
|
||||||
**Парсинг:** `"A: T = V"` → `name=A`, `type=T`, `value=V`. Значение `LastMonth` и другие варианты периодов → `v8:StandardPeriod` с `v8:variant`.
|
**Парсинг:** `"A: T = V"` → `name=A`, `type=T`, `value=V`. Значение `LastMonth` и другие варианты периодов → `v8:StandardPeriod` с `v8:variant`.
|
||||||
|
|
||||||
|
`<default>` может быть **списком** — несколько значений через запятую (с `'...'` для запятой внутри значения). В этом случае эмитятся несколько `<value>`, а `valueListAllowed=true` выводится автоматически (явный `@valueList` не нужен). Эквивалент объектной формы `"value": [ ... ]`.
|
||||||
|
|
||||||
|
```json
|
||||||
|
"parameters": ["Виды: ChartOfCharacteristicTypesRef.ВидыСубконтоХозрасчетные = ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты, ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры"]
|
||||||
|
```
|
||||||
|
|
||||||
### @autoDates
|
### @autoDates
|
||||||
|
|
||||||
Флаг `@autoDates` в shorthand параметра автоматически генерирует два дополнительных параметра:
|
Флаг `@autoDates` в shorthand параметра автоматически генерирует два дополнительных параметра:
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "СКД: параметр со списком значений в шортхенде",
|
||||||
|
"params": { "outputPath": "Template.xml" },
|
||||||
|
"input": {
|
||||||
|
"dataSets": [{
|
||||||
|
"name": "Основной",
|
||||||
|
"query": "ВЫБРАТЬ Т.Поле ИЗ Регистр КАК Т",
|
||||||
|
"fields": ["Поле: string"]
|
||||||
|
}],
|
||||||
|
"parameters": [
|
||||||
|
"Виды: ChartOfCharacteristicTypesRef.ВидыСубконтоХозрасчетные = ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты, ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"validatePath": "Template.xml",
|
||||||
|
"expect": {
|
||||||
|
"files": ["Template.xml"]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<DataCompositionSchema xmlns="http://v8.1c.ru/8.1/data-composition-system/schema" xmlns:dcscom="http://v8.1c.ru/8.1/data-composition-system/common" xmlns:dcscor="http://v8.1c.ru/8.1/data-composition-system/core" xmlns:dcsset="http://v8.1c.ru/8.1/data-composition-system/settings" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<dataSource>
|
||||||
|
<name>ИсточникДанных1</name>
|
||||||
|
<dataSourceType>Local</dataSourceType>
|
||||||
|
</dataSource>
|
||||||
|
<dataSet xsi:type="DataSetQuery">
|
||||||
|
<name>Основной</name>
|
||||||
|
<field xsi:type="DataSetFieldField">
|
||||||
|
<dataPath>Поле</dataPath>
|
||||||
|
<field>Поле</field>
|
||||||
|
<valueType>
|
||||||
|
<v8:Type>xs:string</v8:Type>
|
||||||
|
<v8:StringQualifiers>
|
||||||
|
<v8:Length>0</v8:Length>
|
||||||
|
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||||
|
</v8:StringQualifiers>
|
||||||
|
</valueType>
|
||||||
|
</field>
|
||||||
|
<dataSource>ИсточникДанных1</dataSource>
|
||||||
|
<query>ВЫБРАТЬ Т.Поле ИЗ Регистр КАК Т</query>
|
||||||
|
</dataSet>
|
||||||
|
<parameter>
|
||||||
|
<name>Виды</name>
|
||||||
|
<valueType>
|
||||||
|
<v8:Type xmlns:d5p1="http://v8.1c.ru/8.1/data/enterprise/current-config">d5p1:ChartOfCharacteristicTypesRef.ВидыСубконтоХозрасчетные</v8:Type>
|
||||||
|
</valueType>
|
||||||
|
<value xsi:type="dcscor:DesignTimeValue">ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты</value>
|
||||||
|
<value xsi:type="dcscor:DesignTimeValue">ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры</value>
|
||||||
|
<useRestriction>false</useRestriction>
|
||||||
|
<valueListAllowed>true</valueListAllowed>
|
||||||
|
</parameter>
|
||||||
|
<settingsVariant>
|
||||||
|
<dcsset:name>Основной</dcsset:name>
|
||||||
|
<dcsset:presentation xsi:type="v8:LocalStringType">
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>Основной</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</dcsset:presentation>
|
||||||
|
<dcsset:settings xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows">
|
||||||
|
<dcsset:selection>
|
||||||
|
<dcsset:item xsi:type="dcsset:SelectedItemAuto"/>
|
||||||
|
</dcsset:selection>
|
||||||
|
<dcsset:item xsi:type="dcsset:StructureItemGroup">
|
||||||
|
<dcsset:order>
|
||||||
|
<dcsset:item xsi:type="dcsset:OrderItemAuto"/>
|
||||||
|
</dcsset:order>
|
||||||
|
<dcsset:selection>
|
||||||
|
<dcsset:item xsi:type="dcsset:SelectedItemAuto"/>
|
||||||
|
</dcsset:selection>
|
||||||
|
</dcsset:item>
|
||||||
|
</dcsset:settings>
|
||||||
|
</settingsVariant>
|
||||||
|
</DataCompositionSchema>
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"name": "add-parameter список значений-дат — двоеточия в значениях не режутся",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"script": "skd-compile/scripts/skd-compile",
|
||||||
|
"input": {
|
||||||
|
"dataSets": [{
|
||||||
|
"name": "Основной",
|
||||||
|
"query": "ВЫБРАТЬ Т.Поле ИЗ Регистр КАК Т",
|
||||||
|
"fields": ["Поле: string"]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"args": { "-DefinitionFile": "{inputFile}", "-OutputPath": "{workDir}/Template.xml" }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": {
|
||||||
|
"templatePath": "Template.xml",
|
||||||
|
"operation": "add-parameter",
|
||||||
|
"value": "Даты: dateTime = 2024-01-01T00:00:00, 2024-06-15T12:30:45"
|
||||||
|
},
|
||||||
|
"expect": {
|
||||||
|
"files": ["Template.xml"]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"name": "add-parameter со списком значений (несколько <value> + valueListAllowed)",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"script": "skd-compile/scripts/skd-compile",
|
||||||
|
"input": {
|
||||||
|
"dataSets": [{
|
||||||
|
"name": "Основной",
|
||||||
|
"query": "ВЫБРАТЬ Т.Поле ИЗ Регистр КАК Т",
|
||||||
|
"fields": ["Поле: string"]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"args": { "-DefinitionFile": "{inputFile}", "-OutputPath": "{workDir}/Template.xml" }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": {
|
||||||
|
"templatePath": "Template.xml",
|
||||||
|
"operation": "add-parameter",
|
||||||
|
"value": "Виды: ChartOfCharacteristicTypesRef.ВидыСубконтоХозрасчетные = ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты, ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"name": "modify-parameter value=список — скаляр заменяется списком + valueListAllowed добавлен",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"script": "skd-compile/scripts/skd-compile",
|
||||||
|
"input": {
|
||||||
|
"dataSets": [{
|
||||||
|
"name": "Основной",
|
||||||
|
"query": "ВЫБРАТЬ Т.Поле ИЗ Регистр КАК Т",
|
||||||
|
"fields": ["Поле: string"]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"args": { "-DefinitionFile": "{inputFile}", "-OutputPath": "{workDir}/Template.xml" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": "skd-edit/scripts/skd-edit",
|
||||||
|
"args": { "-TemplatePath": "{workDir}/Template.xml", "-Operation": "add-parameter", "-Value": "Орг: CatalogRef.Организации = Справочник.Организации.X" }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": {
|
||||||
|
"templatePath": "Template.xml",
|
||||||
|
"operation": "modify-parameter",
|
||||||
|
"value": "Орг value=Справочник.Организации.X, Справочник.Организации.Y"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<DataCompositionSchema xmlns="http://v8.1c.ru/8.1/data-composition-system/schema" xmlns:dcscom="http://v8.1c.ru/8.1/data-composition-system/common" xmlns:dcscor="http://v8.1c.ru/8.1/data-composition-system/core" xmlns:dcsset="http://v8.1c.ru/8.1/data-composition-system/settings" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<dataSource>
|
||||||
|
<name>ИсточникДанных1</name>
|
||||||
|
<dataSourceType>Local</dataSourceType>
|
||||||
|
</dataSource>
|
||||||
|
<dataSet xsi:type="DataSetQuery">
|
||||||
|
<name>Основной</name>
|
||||||
|
<field xsi:type="DataSetFieldField">
|
||||||
|
<dataPath>Поле</dataPath>
|
||||||
|
<field>Поле</field>
|
||||||
|
<valueType>
|
||||||
|
<v8:Type>xs:string</v8:Type>
|
||||||
|
<v8:StringQualifiers>
|
||||||
|
<v8:Length>0</v8:Length>
|
||||||
|
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||||
|
</v8:StringQualifiers>
|
||||||
|
</valueType>
|
||||||
|
</field>
|
||||||
|
<dataSource>ИсточникДанных1</dataSource>
|
||||||
|
<query>ВЫБРАТЬ Т.Поле ИЗ Регистр КАК Т</query>
|
||||||
|
</dataSet>
|
||||||
|
<parameter>
|
||||||
|
<name>Даты</name>
|
||||||
|
<valueType>
|
||||||
|
<v8:Type>xs:dateTime</v8:Type>
|
||||||
|
<v8:DateQualifiers>
|
||||||
|
<v8:DateFractions>DateTime</v8:DateFractions>
|
||||||
|
</v8:DateQualifiers>
|
||||||
|
</valueType>
|
||||||
|
<value xsi:type="xs:dateTime">2024-01-01T00:00:00</value>
|
||||||
|
<value xsi:type="xs:dateTime">2024-06-15T12:30:45</value>
|
||||||
|
<valueListAllowed>true</valueListAllowed>
|
||||||
|
</parameter>
|
||||||
|
<settingsVariant>
|
||||||
|
<dcsset:name>Основной</dcsset:name>
|
||||||
|
<dcsset:presentation xsi:type="v8:LocalStringType">
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>Основной</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</dcsset:presentation>
|
||||||
|
<dcsset:settings xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows">
|
||||||
|
<dcsset:selection>
|
||||||
|
<dcsset:item xsi:type="dcsset:SelectedItemAuto"/>
|
||||||
|
</dcsset:selection>
|
||||||
|
<dcsset:item xsi:type="dcsset:StructureItemGroup">
|
||||||
|
<dcsset:order>
|
||||||
|
<dcsset:item xsi:type="dcsset:OrderItemAuto"/>
|
||||||
|
</dcsset:order>
|
||||||
|
<dcsset:selection>
|
||||||
|
<dcsset:item xsi:type="dcsset:SelectedItemAuto"/>
|
||||||
|
</dcsset:selection>
|
||||||
|
</dcsset:item>
|
||||||
|
</dcsset:settings>
|
||||||
|
</settingsVariant>
|
||||||
|
</DataCompositionSchema>
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<DataCompositionSchema xmlns="http://v8.1c.ru/8.1/data-composition-system/schema" xmlns:dcscom="http://v8.1c.ru/8.1/data-composition-system/common" xmlns:dcscor="http://v8.1c.ru/8.1/data-composition-system/core" xmlns:dcsset="http://v8.1c.ru/8.1/data-composition-system/settings" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<dataSource>
|
||||||
|
<name>ИсточникДанных1</name>
|
||||||
|
<dataSourceType>Local</dataSourceType>
|
||||||
|
</dataSource>
|
||||||
|
<dataSet xsi:type="DataSetQuery">
|
||||||
|
<name>Основной</name>
|
||||||
|
<field xsi:type="DataSetFieldField">
|
||||||
|
<dataPath>Поле</dataPath>
|
||||||
|
<field>Поле</field>
|
||||||
|
<valueType>
|
||||||
|
<v8:Type>xs:string</v8:Type>
|
||||||
|
<v8:StringQualifiers>
|
||||||
|
<v8:Length>0</v8:Length>
|
||||||
|
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||||
|
</v8:StringQualifiers>
|
||||||
|
</valueType>
|
||||||
|
</field>
|
||||||
|
<dataSource>ИсточникДанных1</dataSource>
|
||||||
|
<query>ВЫБРАТЬ Т.Поле ИЗ Регистр КАК Т</query>
|
||||||
|
</dataSet>
|
||||||
|
<parameter>
|
||||||
|
<name>Виды</name>
|
||||||
|
<valueType>
|
||||||
|
<v8:Type xmlns:d5p1="http://v8.1c.ru/8.1/data/enterprise/current-config">d5p1:ChartOfCharacteristicTypesRef.ВидыСубконтоХозрасчетные</v8:Type>
|
||||||
|
</valueType>
|
||||||
|
<value xsi:type="dcscor:DesignTimeValue">ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты</value>
|
||||||
|
<value xsi:type="dcscor:DesignTimeValue">ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры</value>
|
||||||
|
<valueListAllowed>true</valueListAllowed>
|
||||||
|
</parameter>
|
||||||
|
<settingsVariant>
|
||||||
|
<dcsset:name>Основной</dcsset:name>
|
||||||
|
<dcsset:presentation xsi:type="v8:LocalStringType">
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>Основной</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</dcsset:presentation>
|
||||||
|
<dcsset:settings xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows">
|
||||||
|
<dcsset:selection>
|
||||||
|
<dcsset:item xsi:type="dcsset:SelectedItemAuto"/>
|
||||||
|
</dcsset:selection>
|
||||||
|
<dcsset:item xsi:type="dcsset:StructureItemGroup">
|
||||||
|
<dcsset:order>
|
||||||
|
<dcsset:item xsi:type="dcsset:OrderItemAuto"/>
|
||||||
|
</dcsset:order>
|
||||||
|
<dcsset:selection>
|
||||||
|
<dcsset:item xsi:type="dcsset:SelectedItemAuto"/>
|
||||||
|
</dcsset:selection>
|
||||||
|
</dcsset:item>
|
||||||
|
</dcsset:settings>
|
||||||
|
</settingsVariant>
|
||||||
|
</DataCompositionSchema>
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<DataCompositionSchema xmlns="http://v8.1c.ru/8.1/data-composition-system/schema" xmlns:dcscom="http://v8.1c.ru/8.1/data-composition-system/common" xmlns:dcscor="http://v8.1c.ru/8.1/data-composition-system/core" xmlns:dcsset="http://v8.1c.ru/8.1/data-composition-system/settings" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<dataSource>
|
||||||
|
<name>ИсточникДанных1</name>
|
||||||
|
<dataSourceType>Local</dataSourceType>
|
||||||
|
</dataSource>
|
||||||
|
<dataSet xsi:type="DataSetQuery">
|
||||||
|
<name>Основной</name>
|
||||||
|
<field xsi:type="DataSetFieldField">
|
||||||
|
<dataPath>Поле</dataPath>
|
||||||
|
<field>Поле</field>
|
||||||
|
<valueType>
|
||||||
|
<v8:Type>xs:string</v8:Type>
|
||||||
|
<v8:StringQualifiers>
|
||||||
|
<v8:Length>0</v8:Length>
|
||||||
|
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||||
|
</v8:StringQualifiers>
|
||||||
|
</valueType>
|
||||||
|
</field>
|
||||||
|
<dataSource>ИсточникДанных1</dataSource>
|
||||||
|
<query>ВЫБРАТЬ Т.Поле ИЗ Регистр КАК Т</query>
|
||||||
|
</dataSet>
|
||||||
|
<parameter>
|
||||||
|
<name>Орг</name>
|
||||||
|
<valueType>
|
||||||
|
<v8:Type xmlns:d5p1="http://v8.1c.ru/8.1/data/enterprise/current-config">d5p1:CatalogRef.Организации</v8:Type>
|
||||||
|
</valueType>
|
||||||
|
<value xsi:type="dcscor:DesignTimeValue">Справочник.Организации.X</value>
|
||||||
|
<value xsi:type="dcscor:DesignTimeValue">Справочник.Организации.Y</value>
|
||||||
|
<valueListAllowed>true</valueListAllowed>
|
||||||
|
</parameter>
|
||||||
|
<settingsVariant>
|
||||||
|
<dcsset:name>Основной</dcsset:name>
|
||||||
|
<dcsset:presentation xsi:type="v8:LocalStringType">
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>Основной</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</dcsset:presentation>
|
||||||
|
<dcsset:settings xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows">
|
||||||
|
<dcsset:selection>
|
||||||
|
<dcsset:item xsi:type="dcsset:SelectedItemAuto"/>
|
||||||
|
</dcsset:selection>
|
||||||
|
<dcsset:item xsi:type="dcsset:StructureItemGroup">
|
||||||
|
<dcsset:order>
|
||||||
|
<dcsset:item xsi:type="dcsset:OrderItemAuto"/>
|
||||||
|
</dcsset:order>
|
||||||
|
<dcsset:selection>
|
||||||
|
<dcsset:item xsi:type="dcsset:SelectedItemAuto"/>
|
||||||
|
</dcsset:selection>
|
||||||
|
</dcsset:item>
|
||||||
|
</dcsset:settings>
|
||||||
|
</settingsVariant>
|
||||||
|
</DataCompositionSchema>
|
||||||
@@ -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