feat(skd-edit): empty parameter values, decimal/time/fix/composite

Brings skd-edit to parity with the skd-compile fixes from 449f814 / 0537410
/ ff2d851. Same helpers (Test-EmptyValue / Build-EmptyValueXml in ps1,
is_empty_value / build_empty_value_xml in py) shared by add-parameter,
modify-parameter (value=...), availableValues, add-dataParameter and
modify-dataParameter.

Behavior:
- Sentinel empty (null / "" / "_" / "null") serializes per declared type,
  matching what 1C Designer writes — ref/no-type → xsi:nil, string →
  xsi:type="xs:string" empty, date/time/decimal/boolean → typed zero,
  StandardPeriod → Custom + zero dates, dataParameters → dcscor:value
  xsi:nil="true". @valueList omits <value> entirely.
- Build-ValueTypeXml accepts bare decimal (10,2), decimal(N) (N,0),
  string(N,fix) (AllowedLength=Fixed), time (DateFractions=Time), and
  composite array of types.
- Parse-ParamShorthand / Parse-DataParamShorthand regex .+ → .* so a
  trailing `=` is treated as the empty-value sentinel. New @valueList flag.

New test cases: empty-param-values-add / -modify / empty-dataparam-values.
Three outdated skd-edit snapshots regenerated to reflect upstream skd-compile
empty-value emission (rename-parameter, reorder-parameters,
conditional-appearance-v2).

Regression: 41/41 ps1 + 41/41 py runner; 41/41 verify-snapshots ps1 + py
(live load into 1С 8.3.24). skd-compile 23/23 and skd-validate 15/15
unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-05-20 13:38:52 +03:00
parent ff2d8513c4
commit 6e14f2502e
11 changed files with 734 additions and 53 deletions
@@ -0,0 +1,37 @@
{
"name": "modify-dataParameter: пустые значения (sentinel-формы) → dcscor:value xsi:nil",
"preRun": [
{
"script": "skd-compile/scripts/skd-compile",
"input": {
"dataSets": [{
"name": "Основной",
"query": "ВЫБРАТЬ 1 КАК Поле1",
"fields": ["Поле1: decimal(1,0)"]
}],
"parameters": [
"Период: StandardPeriod = LastMonth",
"Организация: string = Альфа"
],
"settingsVariants": [{
"name": "Основной",
"settings": {
"selection": ["Auto"],
"dataParameters": ["Период = LastMonth", "Организация = Альфа"],
"structure": "details"
}
}]
},
"args": { "-DefinitionFile": "{inputFile}", "-OutputPath": "{workDir}/Template.xml" }
},
{
"script": "skd-edit/scripts/skd-edit",
"args": { "-TemplatePath": "{workDir}/Template.xml", "-Operation": "modify-dataParameter", "-Value": "Период = _" }
}
],
"params": {
"templatePath": "Template.xml",
"operation": "modify-dataParameter",
"value": "Организация = null"
}
}
@@ -0,0 +1,21 @@
{
"name": "add-parameter: пустые значения и расширенные типы (decimal bare, time, string fix, sentinels)",
"preRun": [
{
"script": "skd-compile/scripts/skd-compile",
"input": {
"dataSets": [{
"name": "Основной",
"query": "ВЫБРАТЬ 1 КАК Поле1",
"fields": ["Поле1: decimal(1,0)"]
}]
},
"args": { "-DefinitionFile": "{inputFile}", "-OutputPath": "{workDir}/Template.xml" }
}
],
"params": {
"templatePath": "Template.xml",
"operation": "add-parameter",
"value": "ПарСтрока: string =;;ПарСтрокаНулл: string = null;;ПарСтрокаПодч: string = _;;ПарДата: date =;;ПарВремя: time =;;ПарВремяНепусто: time = 0001-01-01T12:30:00;;ПарДатаВремя: dateTime = _;;ПарЧислоБар: decimal =;;ПарЧислоН: decimal(8) =;;ПарБул: boolean =;;ПарПериод: StandardPeriod = _;;ПарСсылка: CatalogRef.Номенклатура = null;;ПарСтрокаФикс: string(10,fix) =;;ПарСписок: string @valueList = _"
}
}
@@ -0,0 +1,39 @@
{
"name": "modify-parameter: установка пустого значения через sentinel-формы (value=_, value=null)",
"preRun": [
{
"script": "skd-compile/scripts/skd-compile",
"input": {
"dataSets": [{
"name": "Основной",
"query": "ВЫБРАТЬ 1 КАК Поле1",
"fields": ["Поле1: decimal(1,0)"]
}],
"parameters": [
"ПарСтрока: string = ABC",
"ПарДата: date = 2025-01-15T00:00:00",
"ПарЧисло: decimal = 42",
"ПарСсылка: CatalogRef.Номенклатура = Справочник.Номенклатура.НашаОрганизация"
]
},
"args": { "-DefinitionFile": "{inputFile}", "-OutputPath": "{workDir}/Template.xml" }
},
{
"script": "skd-edit/scripts/skd-edit",
"args": { "-TemplatePath": "{workDir}/Template.xml", "-Operation": "modify-parameter", "-Value": "ПарСтрока value=_" }
},
{
"script": "skd-edit/scripts/skd-edit",
"args": { "-TemplatePath": "{workDir}/Template.xml", "-Operation": "modify-parameter", "-Value": "ПарДата value=null" }
},
{
"script": "skd-edit/scripts/skd-edit",
"args": { "-TemplatePath": "{workDir}/Template.xml", "-Operation": "modify-parameter", "-Value": "ПарЧисло value=_" }
}
],
"params": {
"templatePath": "Template.xml",
"operation": "modify-parameter",
"value": "ПарСсылка value=null"
}
}
@@ -37,6 +37,7 @@
<v8:AllowedLength>Variable</v8:AllowedLength>
</v8:StringQualifiers>
</valueType>
<value xsi:type="xs:string"/>
</parameter>
<settingsVariant>
<dcsset:name>Основной</dcsset:name>
@@ -0,0 +1,84 @@
<?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>Поле1</dataPath>
<field>Поле1</field>
<valueType>
<v8:Type>xs:decimal</v8:Type>
<v8:NumberQualifiers>
<v8:Digits>1</v8:Digits>
<v8:FractionDigits>0</v8:FractionDigits>
<v8:AllowedSign>Any</v8:AllowedSign>
</v8:NumberQualifiers>
</valueType>
</field>
<dataSource>ИсточникДанных1</dataSource>
<query>ВЫБРАТЬ 1 КАК Поле1</query>
</dataSet>
<parameter>
<name>Период</name>
<valueType>
<v8:Type>v8:StandardPeriod</v8:Type>
</valueType>
<value xsi:type="v8:StandardPeriod">
<v8:variant xsi:type="v8:StandardPeriodVariant">LastMonth</v8:variant>
<v8:startDate>0001-01-01T00:00:00</v8:startDate>
<v8:endDate>0001-01-01T00:00:00</v8:endDate>
</value>
</parameter>
<parameter>
<name>Организация</name>
<valueType>
<v8:Type>xs:string</v8:Type>
<v8:StringQualifiers>
<v8:Length>0</v8:Length>
<v8:AllowedLength>Variable</v8:AllowedLength>
</v8:StringQualifiers>
</valueType>
<value xsi:type="xs:string">Альфа</value>
</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:selection>
<dcsset:dataParameters>
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
<dcscor:parameter>Период</dcscor:parameter>
<dcscor:value xsi:nil="true"/>
</dcscor:item>
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
<dcscor:parameter>Организация</dcscor:parameter>
<dcscor:value xsi:nil="true"/>
</dcscor:item>
</dcsset:dataParameters>
<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,196 @@
<?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>Поле1</dataPath>
<field>Поле1</field>
<valueType>
<v8:Type>xs:decimal</v8:Type>
<v8:NumberQualifiers>
<v8:Digits>1</v8:Digits>
<v8:FractionDigits>0</v8:FractionDigits>
<v8:AllowedSign>Any</v8:AllowedSign>
</v8:NumberQualifiers>
</valueType>
</field>
<dataSource>ИсточникДанных1</dataSource>
<query>ВЫБРАТЬ 1 КАК Поле1</query>
</dataSet>
<parameter>
<name>ПарСтрока</name>
<valueType>
<v8:Type>xs:string</v8:Type>
<v8:StringQualifiers>
<v8:Length>0</v8:Length>
<v8:AllowedLength>Variable</v8:AllowedLength>
</v8:StringQualifiers>
</valueType>
<value xsi:type="xs:string"/>
</parameter>
<parameter>
<name>ПарСтрокаНулл</name>
<valueType>
<v8:Type>xs:string</v8:Type>
<v8:StringQualifiers>
<v8:Length>0</v8:Length>
<v8:AllowedLength>Variable</v8:AllowedLength>
</v8:StringQualifiers>
</valueType>
<value xsi:type="xs:string"/>
</parameter>
<parameter>
<name>ПарСтрокаПодч</name>
<valueType>
<v8:Type>xs:string</v8:Type>
<v8:StringQualifiers>
<v8:Length>0</v8:Length>
<v8:AllowedLength>Variable</v8:AllowedLength>
</v8:StringQualifiers>
</valueType>
<value xsi:type="xs:string"/>
</parameter>
<parameter>
<name>ПарДата</name>
<valueType>
<v8:Type>xs:dateTime</v8:Type>
<v8:DateQualifiers>
<v8:DateFractions>Date</v8:DateFractions>
</v8:DateQualifiers>
</valueType>
<value xsi:type="xs:dateTime">0001-01-01T00:00:00</value>
</parameter>
<parameter>
<name>ПарВремя</name>
<valueType>
<v8:Type>xs:dateTime</v8:Type>
<v8:DateQualifiers>
<v8:DateFractions>Time</v8:DateFractions>
</v8:DateQualifiers>
</valueType>
<value xsi:type="xs:dateTime">0001-01-01T00:00:00</value>
</parameter>
<parameter>
<name>ПарВремяНепусто</name>
<valueType>
<v8:Type>xs:dateTime</v8:Type>
<v8:DateQualifiers>
<v8:DateFractions>Time</v8:DateFractions>
</v8:DateQualifiers>
</valueType>
<value xsi:type="xs:dateTime">0001-01-01T12:30:00</value>
</parameter>
<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">0001-01-01T00:00:00</value>
</parameter>
<parameter>
<name>ПарЧислоБар</name>
<valueType>
<v8:Type>xs:decimal</v8:Type>
<v8:NumberQualifiers>
<v8:Digits>10</v8:Digits>
<v8:FractionDigits>2</v8:FractionDigits>
<v8:AllowedSign>Any</v8:AllowedSign>
</v8:NumberQualifiers>
</valueType>
<value xsi:type="xs:decimal">0</value>
</parameter>
<parameter>
<name>ПарЧислоН</name>
<valueType>
<v8:Type>xs:decimal</v8:Type>
<v8:NumberQualifiers>
<v8:Digits>8</v8:Digits>
<v8:FractionDigits>0</v8:FractionDigits>
<v8:AllowedSign>Any</v8:AllowedSign>
</v8:NumberQualifiers>
</valueType>
<value xsi:type="xs:decimal">0</value>
</parameter>
<parameter>
<name>ПарБул</name>
<valueType>
<v8:Type>xs:boolean</v8:Type>
</valueType>
<value xsi:type="xs:boolean">false</value>
</parameter>
<parameter>
<name>ПарПериод</name>
<valueType>
<v8:Type>v8:StandardPeriod</v8:Type>
</valueType>
<value xsi:type="v8:StandardPeriod">
<v8:variant xsi:type="v8:StandardPeriodVariant">Custom</v8:variant>
<v8:startDate>0001-01-01T00:00:00</v8:startDate>
<v8:endDate>0001-01-01T00:00:00</v8:endDate>
</value>
</parameter>
<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:nil="true"/>
</parameter>
<parameter>
<name>ПарСтрокаФикс</name>
<valueType>
<v8:Type>xs:string</v8:Type>
<v8:StringQualifiers>
<v8:Length>10</v8:Length>
<v8:AllowedLength>Fixed</v8:AllowedLength>
</v8:StringQualifiers>
</valueType>
<value xsi:type="xs:string"/>
</parameter>
<parameter>
<name>ПарСписок</name>
<valueType>
<v8:Type>xs:string</v8:Type>
<v8:StringQualifiers>
<v8:Length>0</v8:Length>
<v8:AllowedLength>Variable</v8:AllowedLength>
</v8:StringQualifiers>
</valueType>
<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: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,92 @@
<?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>Поле1</dataPath>
<field>Поле1</field>
<valueType>
<v8:Type>xs:decimal</v8:Type>
<v8:NumberQualifiers>
<v8:Digits>1</v8:Digits>
<v8:FractionDigits>0</v8:FractionDigits>
<v8:AllowedSign>Any</v8:AllowedSign>
</v8:NumberQualifiers>
</valueType>
</field>
<dataSource>ИсточникДанных1</dataSource>
<query>ВЫБРАТЬ 1 КАК Поле1</query>
</dataSet>
<parameter>
<name>ПарСтрока</name>
<valueType>
<v8:Type>xs:string</v8:Type>
<v8:StringQualifiers>
<v8:Length>0</v8:Length>
<v8:AllowedLength>Variable</v8:AllowedLength>
</v8:StringQualifiers>
</valueType>
<value xsi:type="xs:string"/>
</parameter>
<parameter>
<name>ПарДата</name>
<valueType>
<v8:Type>xs:dateTime</v8:Type>
<v8:DateQualifiers>
<v8:DateFractions>Date</v8:DateFractions>
</v8:DateQualifiers>
</valueType>
<value xsi:type="xs:dateTime">0001-01-01T00:00:00</value>
</parameter>
<parameter>
<name>ПарЧисло</name>
<valueType>
<v8:Type>xs:decimal</v8:Type>
<v8:NumberQualifiers>
<v8:Digits>10</v8:Digits>
<v8:FractionDigits>2</v8:FractionDigits>
<v8:AllowedSign>Any</v8:AllowedSign>
</v8:NumberQualifiers>
</valueType>
<value xsi:type="xs:decimal">0</value>
</parameter>
<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:nil="true"/>
</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: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>
@@ -86,6 +86,7 @@
<v8:AllowedLength>Variable</v8:AllowedLength>
</v8:StringQualifiers>
</valueType>
<value xsi:type="xs:string"/>
</parameter>
<settingsVariant>
<dcsset:name>Основной</dcsset:name>
@@ -111,6 +112,7 @@
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
<dcscor:use>false</dcscor:use>
<dcscor:parameter>Организация</dcscor:parameter>
<dcscor:value xsi:nil="true"/>
</dcscor:item>
</dcsset:dataParameters>
<dcsset:item xsi:type="dcsset:StructureItemGroup">
@@ -47,6 +47,7 @@
<v8:AllowedLength>Variable</v8:AllowedLength>
</v8:StringQualifiers>
</valueType>
<value xsi:type="xs:string"/>
</parameter>
<parameter>
<name>ПорядокОкругленияСумм</name>
@@ -57,6 +58,7 @@
<v8:AllowedLength>Variable</v8:AllowedLength>
</v8:StringQualifiers>
</valueType>
<value xsi:type="xs:string"/>
</parameter>
<parameter>
<name>Организация</name>
@@ -67,12 +69,14 @@
<v8:AllowedLength>Variable</v8:AllowedLength>
</v8:StringQualifiers>
</valueType>
<value xsi:type="xs:string"/>
</parameter>
<parameter>
<name>ПрекращаемаяДеятельность</name>
<valueType>
<v8:Type>xs:boolean</v8:Type>
</valueType>
<value xsi:type="xs:boolean">false</value>
</parameter>
<settingsVariant>