fix(skd-edit): parse #restriction flags in add-calculated-field shorthand

Previously #noFilter/#noOrder/#noGroup flags were included verbatim in
<expression> instead of generating <useRestriction>. Now parsed and
handled identically to add-field.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-04-08 19:34:55 +03:00
parent afacaa5ade
commit fdfe4ac2f4
5 changed files with 126 additions and 9 deletions
+4 -1
View File
@@ -61,13 +61,16 @@ Shorthand: `"Имя [Заголовок]: тип @роль #ограничени
### add-calculated-field — добавить вычисляемое поле
Shorthand: `"Имя [Заголовок]: тип = Выражение"`.
Shorthand: `"Имя [Заголовок]: тип = Выражение #noFilter #noOrder #noGroup"`.
```
"Маржа = Продажа - Закупка"
"Наценка [Наценка, %]: decimal(10,2) = Маржа / Закупка * 100"
"Служебное: string = \"\" #noFilter #noOrder #noGroup"
```
`#noFilter`, `#noOrder`, `#noGroup`, `#noField``<useRestriction>` (аналогично add-field).
Также добавляется в selection варианта.
### add-parameter — добавить параметр
+16 -4
View File
@@ -1,4 +1,4 @@
# skd-edit v1.6 — Atomic 1C DCS editor
# skd-edit v1.7 — Atomic 1C DCS editor
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -257,6 +257,14 @@ function Parse-CalcShorthand {
$s = $s -replace '\s*\[[^\]]+\]', ''
}
# Extract #restrictions
$restrict = @()
$restrictMatches = [regex]::Matches($s, '#(\w+)')
foreach ($m in $restrictMatches) {
$restrict += $m.Groups[1].Value
}
$s = [regex]::Replace($s, '\s*#\w+', '')
# Support "Name: Type = Expression" and "Name = Expression"
$eqIdx = $s.IndexOf('=')
if ($eqIdx -gt 0) {
@@ -267,11 +275,11 @@ function Parse-CalcShorthand {
$colonIdx = $left.IndexOf(':')
$dataPath = $left.Substring(0, $colonIdx).Trim()
$type = Resolve-TypeStr ($left.Substring($colonIdx + 1).Trim())
return @{ dataPath = $dataPath; expression = $expression; type = $type; title = $title }
return @{ dataPath = $dataPath; expression = $expression; type = $type; title = $title; restrict = $restrict }
}
return @{ dataPath = $left; expression = $expression; type = ""; title = $title }
return @{ dataPath = $left; expression = $expression; type = ""; title = $title; restrict = $restrict }
}
return @{ dataPath = $s.Trim(); expression = ""; type = ""; title = $title }
return @{ dataPath = $s.Trim(); expression = ""; type = ""; title = $title; restrict = $restrict }
}
function Parse-ParamShorthand {
@@ -752,6 +760,10 @@ function Build-CalcFieldFragment {
$lines += (Build-MLTextXml -tag "title" -text $parsed.title -indent "$i`t")
}
if ($parsed.restrict -and $parsed.restrict.Count -gt 0) {
$lines += (Build-RestrictionXml -restrict $parsed.restrict -indent "$i`t")
}
if ($parsed.type) {
$lines += "$i`t<valueType>"
$lines += (Build-ValueTypeXml -typeStr $parsed.type -indent "$i`t`t")
+9 -4
View File
@@ -1,4 +1,4 @@
# skd-edit v1.6 — Atomic 1C DCS editor (Python port)
# skd-edit v1.7 — Atomic 1C DCS editor (Python port)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import os
@@ -265,6 +265,9 @@ def parse_calc_shorthand(s):
title = m.group(1)
s = re.sub(r'\s*\[[^\]]+\]', '', s)
restrict_matches = re.findall(r'#(\w+)', s)
s = re.sub(r'\s*#\w+', '', s)
eq_idx = s.find("=")
if eq_idx > 0:
left = s[:eq_idx].strip()
@@ -273,9 +276,9 @@ def parse_calc_shorthand(s):
colon_idx = left.index(":")
data_path = left[:colon_idx].strip()
type_str = resolve_type_str(left[colon_idx + 1:].strip())
return {"dataPath": data_path, "expression": expression, "type": type_str, "title": title}
return {"dataPath": left, "expression": expression, "type": "", "title": title}
return {"dataPath": s.strip(), "expression": "", "type": "", "title": title}
return {"dataPath": data_path, "expression": expression, "type": type_str, "title": title, "restrict": restrict_matches}
return {"dataPath": left, "expression": expression, "type": "", "title": title, "restrict": restrict_matches}
return {"dataPath": s.strip(), "expression": "", "type": "", "title": title, "restrict": restrict_matches}
def parse_param_shorthand(s):
@@ -678,6 +681,8 @@ def build_calc_field_fragment(parsed, indent):
]
if parsed.get("title"):
lines.append(build_mltext_xml("title", parsed["title"], f"{i}\t"))
if parsed.get("restrict"):
lines.append(build_restriction_xml(parsed["restrict"], f"{i}\t"))
if parsed.get("type"):
lines.append(f"{i}\t<valueType>")
lines.append(build_value_type_xml(parsed["type"], f"{i}\t\t"))
@@ -0,0 +1,21 @@
{
"name": "Вычисляемое поле с useRestriction",
"preRun": [
{
"script": "skd-compile/scripts/skd-compile",
"input": {
"dataSets": [{
"name": "Основной",
"query": "ВЫБРАТЬ Т.Цена, Т.Закупка ИЗ Регистр КАК Т",
"fields": ["Цена: decimal(15,2)", "Закупка: decimal(15,2)"]
}]
},
"args": { "-DefinitionFile": "{inputFile}", "-OutputPath": "{workDir}/Template.xml" }
}
],
"params": {
"templatePath": "Template.xml",
"operation": "add-calculated-field",
"value": "Служебное: string = \"\" #noFilter #noOrder #noGroup"
}
}
@@ -0,0 +1,76 @@
<?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:decimal</v8:Type>
<v8:NumberQualifiers>
<v8:Digits>15</v8:Digits>
<v8:FractionDigits>2</v8:FractionDigits>
<v8:AllowedSign>Any</v8:AllowedSign>
</v8:NumberQualifiers>
</valueType>
</field>
<field xsi:type="DataSetFieldField">
<dataPath>Закупка</dataPath>
<field>Закупка</field>
<valueType>
<v8:Type>xs:decimal</v8:Type>
<v8:NumberQualifiers>
<v8:Digits>15</v8:Digits>
<v8:FractionDigits>2</v8:FractionDigits>
<v8:AllowedSign>Any</v8:AllowedSign>
</v8:NumberQualifiers>
</valueType>
</field>
<dataSource>ИсточникДанных1</dataSource>
<query>ВЫБРАТЬ Т.Цена, Т.Закупка ИЗ Регистр КАК Т</query>
</dataSet>
<calculatedField>
<dataPath>Служебное</dataPath>
<expression>""</expression>
<useRestriction>
<condition>true</condition>
<order>true</order>
<group>true</group>
</useRestriction>
<valueType>
<v8:Type>xs:string</v8:Type>
<v8:StringQualifiers>
<v8:Length>0</v8:Length>
<v8:AllowedLength>Variable</v8:AllowedLength>
</v8:StringQualifiers>
</valueType>
</calculatedField>
<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:SelectedItemField">
<dcsset:field>Служебное</dcsset:field>
</dcsset:item>
</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>