feat(skd-edit): modify-structure + фиксы set-structure/parameter/patch-query

- modify-structure: новая операция, меняет groupItems группы по @name=,
  сохраняя Selection/order/filter/conditionalAppearance (Bug 1)
- set-structure: shorthand поддерживает запятую для нескольких полей
  в одном уровне группировки (Bug 2)
- set-structure: @name= с обрамляющими кавычками (двойными/одинарными)
  снимает их при записи в <dcsset:name> (Bug 3)
- add-parameter: ссылочные типы (CatalogRef, ChartOfAccountsRef, …)
  пишут <value xsi:type="dcscor:DesignTimeValue">, не xs:string (Bug 4a)
- modify-parameter: namespace-aware lookup существующих свойств
  — обновляет inplace, не плодит дубли (Bug 4b)
- modify-parameter value=…: пересборка <value> с корректным xsi:type
  из <valueType> (попутно лечит ранее битый XML)
- patch-query: батч ;;-сегментов триммится по краям (Bug 5)
- skd-compile: симметричный фикс ссылочных типов в emit_value

Регресс: 23/23 PS, 23/23 PY (skd-edit), 21/21 PS+PY (skd-compile),
23/23 платформенный verify-snapshots.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-05-15 13:40:49 +03:00
parent 8b0f55f1cc
commit 529a5cacae
15 changed files with 854 additions and 64 deletions
@@ -1,4 +1,4 @@
# skd-compile v1.21 — Compile 1C DCS from JSON
# skd-compile v1.22 — Compile 1C DCS from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[string]$DefinitionFile,
@@ -1130,6 +1130,8 @@ function Emit-ParamValue {
X "$indent<value xsi:type=`"xs:decimal`">$(Esc-Xml $valStr)</value>"
} elseif ($type -match '^string') {
X "$indent<value xsi:type=`"xs:string`">$(Esc-Xml $valStr)</value>"
} elseif ($type -match '^(CatalogRef|DocumentRef|EnumRef|ChartOfAccountsRef|ChartOfCharacteristicTypesRef|ChartOfCalculationTypesRef|BusinessProcessRef|TaskRef|ExchangePlanRef)\.') {
X "$indent<value xsi:type=`"dcscor:DesignTimeValue`">$(Esc-Xml $valStr)</value>"
} else {
# Guess from value
if ($valStr -match '^\d{4}-\d{2}-\d{2}T') {
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# skd-compile v1.21 — Compile 1C DCS from JSON
# skd-compile v1.22 — Compile 1C DCS from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import json
@@ -811,6 +811,8 @@ def emit_param_value(lines, type_str, val, indent):
lines.append(f'{indent}<value xsi:type="xs:decimal">{esc_xml(val_str)}</value>')
elif type_str and re.match(r'^string', type_str):
lines.append(f'{indent}<value xsi:type="xs:string">{esc_xml(val_str)}</value>')
elif type_str and re.match(r'^(CatalogRef|DocumentRef|EnumRef|ChartOfAccountsRef|ChartOfCharacteristicTypesRef|ChartOfCalculationTypesRef|BusinessProcessRef|TaskRef|ExchangePlanRef)\.', type_str):
lines.append(f'{indent}<value xsi:type="dcscor:DesignTimeValue">{esc_xml(val_str)}</value>')
else:
# Guess from value
if re.match(r'^\d{4}-\d{2}-\d{2}T', val_str):
+12 -1
View File
@@ -249,16 +249,27 @@ Shorthand: `"старое => новое"`. Заменяет все вхожде
### set-structure — установить структуру варианта
Shorthand: `"Поле1 > Поле2 > details"`. `details`/`детали` — детальные записи. Заменяет всю структуру. Не поддерживает пакетный режим.
Shorthand: `"Поле1 > Поле2 > details"`. `>` — вложенный уровень группировки, `,` — несколько полей в одном уровне, `details` — детальные записи. **Заменяет всю структуру полностью** (включая Selection/order/filter/conditionalAppearance каждой группы). Для точечной модификации полей группировки с сохранением настроек — используй `modify-structure`. Не поддерживает пакетный режим.
```
"Организация > Номенклатура > details"
"Валюта, НаименованиеБанка, ИНН"
"details"
"СчетМеждународногоУчета @name=ДанныеОтчета"
```
`@name=Имя` — присваивает имя группировке (`<dcsset:name>`). Используется для привязки шаблонов через `groupName`.
### modify-structure — изменить поля группировки существующей группы
Тот же shorthand что и `set-structure`. Находит группу по `@name=`, заменяет только `<groupItems>` (поля группировки). Selection/order/filter/conditionalAppearance/outputParameters группы сохраняются. Без `@name=` — ошибка.
```
"Валюта @name=ДанныеОтчета"
"Валюта, НаименованиеБанка @name=ДанныеОтчета"
"details @name=ДанныеОтчета"
```
### modify-field — изменить существующее поле
Тот же shorthand что и `add-field`. Находит по dataPath, объединяет свойства (непустые переопределяют), сохраняет позицию.
+216 -32
View File
@@ -1,4 +1,4 @@
# skd-edit v1.11 — Atomic 1C DCS editor
# skd-edit v1.12 — Atomic 1C DCS editor
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -11,7 +11,7 @@ param(
"add-dataParameter","add-order","add-selection","add-dataSetLink",
"add-dataSet","add-variant","add-conditionalAppearance","add-drilldown",
"set-query","patch-query","set-outputParameter","set-structure",
"modify-field","modify-filter","modify-dataParameter","modify-parameter",
"modify-field","modify-filter","modify-dataParameter","modify-parameter","modify-structure",
"rename-parameter","reorder-parameters",
"clear-selection","clear-order","clear-filter",
"remove-field","remove-total","remove-calculated-field","remove-parameter","remove-filter")]
@@ -581,15 +581,17 @@ function Parse-StructureShorthand {
$seg = $segments[$i].Trim()
$group = @{ type = "group" }
if ($seg -match '@name=(.+)') {
$group["name"] = $Matches[1].Trim()
$seg = ($seg -replace '\s*@name=.+', '').Trim()
if ($seg -match '@name=(?:"([^"]+)"|''([^'']+)''|(\S+))') {
$rawName = if ($Matches[1]) { $Matches[1] } elseif ($Matches[2]) { $Matches[2] } else { $Matches[3] }
$group["name"] = $rawName.Trim()
$seg = ($seg -replace '\s*@name=(?:"[^"]+"|''[^'']+''|\S+)', '').Trim()
}
if ($seg -match '^(?i)(details|детали)$') {
$group["groupBy"] = @()
} else {
$group["groupBy"] = @($seg)
$fields = @($seg -split '\s*,\s*' | ForEach-Object { $_.Trim() } | Where-Object { $_ })
$group["groupBy"] = $fields
}
if ($null -ne $innermost) {
@@ -804,6 +806,48 @@ function Build-CalcFieldFragment {
return $lines -join "`r`n"
}
function Build-ParamValueXml {
# Returns array of XML lines for a <value xsi:type=...>...</value> element (or StandardPeriod block).
# Selects xsi:type by declared type, then falls back to value pattern.
param([string]$type, [string]$value, [string]$indent, [string]$tagName = "value", [string]$tagNs = "")
$i = $indent
$valStr = "$value"
$open = if ($tagNs) { "$tagNs`:$tagName" } else { $tagName }
$lines = @()
if ($type -eq "StandardPeriod") {
$lines += "$i<$open xsi:type=`"v8:StandardPeriod`">"
$lines += "$i`t<v8:variant xsi:type=`"v8:StandardPeriodVariant`">$(Esc-Xml $valStr)</v8:variant>"
$lines += "$i`t<v8:startDate>0001-01-01T00:00:00</v8:startDate>"
$lines += "$i`t<v8:endDate>0001-01-01T00:00:00</v8:endDate>"
$lines += "$i</$open>"
return $lines
}
$xsi = $null
if ($type -match '^date') { $xsi = "xs:dateTime" }
elseif ($type -eq "boolean") { $xsi = "xs:boolean" }
elseif ($type -match '^decimal') { $xsi = "xs:decimal" }
elseif ($type -match '^string') { $xsi = "xs:string" }
elseif ($type -match '^(CatalogRef|DocumentRef|EnumRef|ChartOfAccountsRef|ChartOfCharacteristicTypesRef|ChartOfCalculationTypesRef|BusinessProcessRef|TaskRef|ExchangePlanRef)\.') {
$xsi = "dcscor:DesignTimeValue"
}
else {
# Type unknown or empty — guess from value
if ($valStr -match '^\d{4}-\d{2}-\d{2}T') { $xsi = "xs:dateTime" }
elseif ($valStr -eq "true" -or $valStr -eq "false") { $xsi = "xs:boolean" }
elseif ($valStr -match '^(Перечисление|Справочник|ПланСчетов|Документ|ПланВидовХарактеристик|ПланВидовРасчета|БизнесПроцесс|Задача|РегистрСведений|ПланОбмена)\.' -or
$valStr -match '^(Catalog|Document|Enum|ChartOfAccounts|ChartOfCharacteristicTypes|ChartOfCalculationTypes|BusinessProcess|Task|InformationRegister|ExchangePlan)\.') {
$xsi = "dcscor:DesignTimeValue"
}
else { $xsi = "xs:string" }
}
$lines += "$i<$open xsi:type=`"$xsi`">$(Esc-Xml $valStr)</$open>"
return $lines
}
function Build-ParamFragment {
param($parsed, [string]$indent)
@@ -825,22 +869,8 @@ function Build-ParamFragment {
}
if ($null -ne $parsed.value) {
$valStr = "$($parsed.value)"
if ($parsed.type -eq "StandardPeriod") {
$lines += "$i`t<value xsi:type=`"v8:StandardPeriod`">"
$lines += "$i`t`t<v8:variant xsi:type=`"v8:StandardPeriodVariant`">$(Esc-Xml $valStr)</v8:variant>"
$lines += "$i`t`t<v8:startDate>0001-01-01T00:00:00</v8:startDate>"
$lines += "$i`t`t<v8:endDate>0001-01-01T00:00:00</v8:endDate>"
$lines += "$i`t</value>"
} elseif ($parsed.type -match '^date') {
$lines += "$i`t<value xsi:type=`"xs:dateTime`">$(Esc-Xml $valStr)</value>"
} elseif ($parsed.type -eq "boolean") {
$lines += "$i`t<value xsi:type=`"xs:boolean`">$(Esc-Xml $valStr)</value>"
} elseif ($parsed.type -match '^decimal') {
$lines += "$i`t<value xsi:type=`"xs:decimal`">$(Esc-Xml $valStr)</value>"
} else {
$lines += "$i`t<value xsi:type=`"xs:string`">$(Esc-Xml $valStr)</value>"
}
$valueLines = Build-ParamValueXml -type $parsed.type -value $parsed.value -indent "$i`t"
foreach ($vl in $valueLines) { $lines += $vl }
}
$lines += "$i</parameter>"
@@ -1565,10 +1595,10 @@ $corNs = "http://v8.1c.ru/8.1/data-composition-system/core"
# --- 7. Batch value splitting ---
if ($Operation -eq "set-query" -or $Operation -eq "set-structure" -or $Operation -eq "add-dataSet") {
if ($Operation -eq "set-query" -or $Operation -eq "set-structure" -or $Operation -eq "modify-structure" -or $Operation -eq "add-dataSet") {
$values = @($Value)
} elseif ($Operation -eq "patch-query") {
$values = @($Value -split ';;' | Where-Object { $_.Trim() })
$values = @($Value -split ';;' | ForEach-Object { $_.Trim() } | Where-Object { $_ })
} elseif ($Operation -eq "add-drilldown") {
if ($Value.Contains(';;')) {
$values = @($Value -split ';;' | ForEach-Object { $_.Trim() } | Where-Object { $_ })
@@ -1810,15 +1840,63 @@ switch ($Operation) {
$avPart = $rest.Substring($avIdx)
}
# Process simple key=value pairs (use, denyIncompleteValues, etc.)
# Process simple key=value pairs (use, denyIncompleteValues, value, etc.)
if ($simpleRest) {
$kvPairs = [regex]::Matches($simpleRest, '(\w+)=(\S+)')
foreach ($kv in $kvPairs) {
$key = $kv.Groups[1].Value
$value = $kv.Groups[2].Value
$existing = $paramEl.SelectSingleNode($key)
if ($existing) {
# Namespace-aware lookup (children live in $schNs)
$existing = $null
foreach ($ch in $paramEl.ChildNodes) {
if ($ch.NodeType -eq 'Element' -and $ch.LocalName -eq $key -and $ch.NamespaceURI -eq $schNs) {
$existing = $ch; break
}
}
if ($key -eq "value") {
# Special-case: rebuild <value> with correct xsi: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
}
}
}
$valueLines = Build-ParamValueXml -type $declaredType -value $value -indent $childIndent
$fragXml = $valueLines -join "`r`n"
$wasExisting = ($null -ne $existing)
if ($existing) {
# Capture position by next-element sibling, then remove existing
$refNode = $existing.NextSibling
while ($refNode -and ($refNode.NodeType -eq 'Whitespace' -or $refNode.NodeType -eq 'SignificantWhitespace')) {
$refNode = $refNode.NextSibling
}
Remove-NodeWithWhitespace $existing
} else {
# Insert before useRestriction/availableValue/denyIncompleteValues/use
$refNode = $null
foreach ($child in $paramEl.ChildNodes) {
if ($child.NodeType -eq 'Element' -and $child.LocalName -in @('useRestriction','availableValue','denyIncompleteValues','use')) {
$refNode = $child; break
}
}
}
$nodes = Import-Fragment $xmlDoc $fragXml
foreach ($node in $nodes) {
Insert-BeforeElement $paramEl $node $refNode $childIndent
}
$verb = if ($wasExisting) { "updated" } else { "added" }
Write-Host "[OK] Parameter `"$paramName`": value $verb to $value"
} elseif ($existing) {
$existing.InnerText = $value
Write-Host "[OK] Parameter `"$paramName`": $key updated to $value"
} else {
@@ -1849,15 +1927,25 @@ switch ($Operation) {
$avValue = $avParts[0].Trim()
$avPresentation = if ($avParts.Count -gt 1) { $avParts[1].Trim() } else { "" }
# Detect value type
$avType = "xs:string"
if ($avValue -match '^(Перечисление|Справочник|ПланСчетов|Документ|ПланВидовХарактеристик|ПланВидовРасчета)\.') {
$avType = "dcscor:DesignTimeValue"
# Detect value type: prefer declared <valueType> of the parameter, else guess from value
$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
}
}
}
$avLines = @()
$avLines += "$childIndent<availableValue>"
$avLines += "$childIndent`t<value xsi:type=`"$avType`">$(Esc-Xml $avValue)</value>"
$valueLines = Build-ParamValueXml -type $declaredType -value $avValue -indent "$childIndent`t"
foreach ($vl in $valueLines) { $avLines += $vl }
if ($avPresentation) {
$avLines += "$childIndent`t<presentation xsi:type=`"v8:LocalStringType`">"
$avLines += "$childIndent`t`t<v8:item>"
@@ -2289,6 +2377,102 @@ switch ($Operation) {
Write-Host "[OK] Structure set in variant `"$varName`": $Value"
}
"modify-structure" {
$settings = Resolve-VariantSettings
$varName = Get-VariantName
$structItems = Parse-StructureShorthand $Value
# Flatten parsed tree into (name, groupBy) targets
$targets = @()
$stack = New-Object System.Collections.Stack
foreach ($it in $structItems) { $stack.Push($it) }
while ($stack.Count -gt 0) {
$it = $stack.Pop()
if ($it["name"]) {
$targets += @{ name = $it["name"]; groupBy = $it["groupBy"] }
}
if ($it["children"]) {
foreach ($ch in $it["children"]) { $stack.Push($ch) }
}
}
if ($targets.Count -eq 0) {
Write-Error "modify-structure requires @name= for at least one group: $Value"
exit 1
}
$nsMgr = New-Object System.Xml.XmlNamespaceManager($xmlDoc.NameTable)
$nsMgr.AddNamespace("dcsset", $setNs)
$nsMgr.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance")
foreach ($t in $targets) {
$groupEl = $settings.SelectSingleNode(".//dcsset:item[@xsi:type='dcsset:StructureItemGroup'][dcsset:name='$($t.name)']", $nsMgr)
if (-not $groupEl) {
Write-Host "[WARN] Group with @name=`"$($t.name)`" not found — skipped"
continue
}
$giEl = $null
foreach ($ch in $groupEl.ChildNodes) {
if ($ch.NodeType -eq 'Element' -and $ch.LocalName -eq 'groupItems' -and $ch.NamespaceURI -eq $setNs) {
$giEl = $ch; break
}
}
$groupIndent = Get-ChildIndent $groupEl
if (-not $giEl) {
# Create <groupItems> after <name>, before <order>/<selection>/...
$nameEl = $null
$refAfterName = $null
foreach ($ch in $groupEl.ChildNodes) {
if ($ch.NodeType -eq 'Element' -and $ch.LocalName -eq 'name' -and $ch.NamespaceURI -eq $setNs) {
$nameEl = $ch
} elseif ($ch.NodeType -eq 'Element' -and $nameEl -and -not $refAfterName) {
$refAfterName = $ch; break
}
}
$giFrag = "$groupIndent<dcsset:groupItems></dcsset:groupItems>"
$nodes = Import-Fragment $xmlDoc $giFrag
foreach ($node in $nodes) {
Insert-BeforeElement $groupEl $node $refAfterName $groupIndent
}
# Re-find
foreach ($ch in $groupEl.ChildNodes) {
if ($ch.NodeType -eq 'Element' -and $ch.LocalName -eq 'groupItems' -and $ch.NamespaceURI -eq $setNs) {
$giEl = $ch; break
}
}
}
$toRemove = @()
foreach ($ch in $giEl.ChildNodes) {
if ($ch.NodeType -eq 'Element') { $toRemove += $ch }
}
foreach ($el in $toRemove) { Remove-NodeWithWhitespace $el }
$itemIndent = "$groupIndent`t"
foreach ($field in $t.groupBy) {
$lines = @()
$lines += "$itemIndent<dcsset:item xsi:type=`"dcsset:GroupItemField`">"
$lines += "$itemIndent`t<dcsset:field>$(Esc-Xml $field)</dcsset:field>"
$lines += "$itemIndent`t<dcsset:groupType>Items</dcsset:groupType>"
$lines += "$itemIndent`t<dcsset:periodAdditionType>None</dcsset:periodAdditionType>"
$lines += "$itemIndent`t<dcsset:periodAdditionBegin xsi:type=`"xs:dateTime`">0001-01-01T00:00:00</dcsset:periodAdditionBegin>"
$lines += "$itemIndent`t<dcsset:periodAdditionEnd xsi:type=`"xs:dateTime`">0001-01-01T00:00:00</dcsset:periodAdditionEnd>"
$lines += "$itemIndent</dcsset:item>"
$fragXml = $lines -join "`r`n"
$nodes = Import-Fragment $xmlDoc $fragXml
foreach ($node in $nodes) {
Insert-BeforeElement $giEl $node $null $itemIndent
}
}
$desc = if ($t.groupBy.Count -eq 0) { "details" } else { $t.groupBy -join ', ' }
Write-Host "[OK] Group `"$($t.name)`" groupItems updated: $desc"
}
}
"add-dataSetLink" {
foreach ($val in $values) {
$parsed = Parse-DataSetLinkShorthand $val
+173 -29
View File
@@ -1,4 +1,4 @@
# skd-edit v1.11 — Atomic 1C DCS editor (Python port)
# skd-edit v1.12 — Atomic 1C DCS editor (Python port)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import os
@@ -18,7 +18,7 @@ VALID_OPS = [
"add-dataParameter", "add-order", "add-selection", "add-dataSetLink",
"add-dataSet", "add-variant", "add-conditionalAppearance", "add-drilldown",
"set-query", "patch-query", "set-outputParameter", "set-structure",
"modify-field", "modify-filter", "modify-dataParameter", "modify-parameter",
"modify-field", "modify-filter", "modify-dataParameter", "modify-parameter", "modify-structure",
"rename-parameter", "reorder-parameters",
"clear-selection", "clear-order", "clear-filter",
"remove-field", "remove-total", "remove-calculated-field", "remove-parameter", "remove-filter",
@@ -545,15 +545,17 @@ def parse_structure_shorthand(s):
seg = segments[i].strip()
group = {"type": "group"}
name_m = re.search(r'\s*@name=(.+)', seg)
name_m = re.search(r'@name=(?:"([^"]+)"|\'([^\']+)\'|(\S+))', seg)
if name_m:
group["name"] = name_m.group(1).strip()
seg = re.sub(r'\s*@name=.+', '', seg).strip()
raw_name = name_m.group(1) or name_m.group(2) or name_m.group(3)
group["name"] = raw_name.strip()
seg = re.sub(r'\s*@name=(?:"[^"]+"|\'[^\']+\'|\S+)', '', seg).strip()
if re.match(r'^(details|\u0434\u0435\u0442\u0430\u043b\u0438)$', seg, re.IGNORECASE):
group["groupBy"] = []
else:
group["groupBy"] = [seg]
fields = [f.strip() for f in re.split(r'\s*,\s*', seg) if f.strip()]
group["groupBy"] = fields
if innermost is not None:
group["children"] = [innermost]
@@ -724,6 +726,47 @@ def build_calc_field_fragment(parsed, indent):
return "\r\n".join(lines)
def build_param_value_xml(type_str, value, indent, tag_name="value", tag_ns=""):
"""Return list of XML lines for <value xsi:type=...>...</value>."""
val_str = "" if value is None else str(value)
open_tag = f"{tag_ns}:{tag_name}" if tag_ns else tag_name
lines = []
if type_str == "StandardPeriod":
lines.append(f'{indent}<{open_tag} xsi:type="v8:StandardPeriod">')
lines.append(f'{indent}\t<v8:variant xsi:type="v8:StandardPeriodVariant">{esc_xml(val_str)}</v8:variant>')
lines.append(f"{indent}\t<v8:startDate>0001-01-01T00:00:00</v8:startDate>")
lines.append(f"{indent}\t<v8:endDate>0001-01-01T00:00:00</v8:endDate>")
lines.append(f"{indent}</{open_tag}>")
return lines
t = type_str or ""
xsi = None
if t.startswith("date"):
xsi = "xs:dateTime"
elif t == "boolean":
xsi = "xs:boolean"
elif t.startswith("decimal"):
xsi = "xs:decimal"
elif t.startswith("string"):
xsi = "xs:string"
elif re.match(r'^(CatalogRef|DocumentRef|EnumRef|ChartOfAccountsRef|ChartOfCharacteristicTypesRef|ChartOfCalculationTypesRef|BusinessProcessRef|TaskRef|ExchangePlanRef)\.', t):
xsi = "dcscor:DesignTimeValue"
else:
if re.match(r'^\d{4}-\d{2}-\d{2}T', val_str):
xsi = "xs:dateTime"
elif val_str in ("true", "false"):
xsi = "xs:boolean"
elif re.match(r'^(Перечисление|Справочник|ПланСчетов|Документ|ПланВидовХарактеристик|ПланВидовРасчета|БизнесПроцесс|Задача|РегистрСведений|ПланОбмена)\.', val_str) or \
re.match(r'^(Catalog|Document|Enum|ChartOfAccounts|ChartOfCharacteristicTypes|ChartOfCalculationTypes|BusinessProcess|Task|InformationRegister|ExchangePlan)\.', val_str):
xsi = "dcscor:DesignTimeValue"
else:
xsi = "xs:string"
lines.append(f'{indent}<{open_tag} xsi:type="{xsi}">{esc_xml(val_str)}</{open_tag}>')
return lines
def build_param_fragment(parsed, indent):
i = indent
fragments = []
@@ -739,21 +782,8 @@ def build_param_fragment(parsed, indent):
lines.append(f"{i}\t</valueType>")
if parsed["value"] is not None:
val_str = str(parsed["value"])
if parsed.get("type") == "StandardPeriod":
lines.append(f'{i}\t<value xsi:type="v8:StandardPeriod">')
lines.append(f'{i}\t\t<v8:variant xsi:type="v8:StandardPeriodVariant">{esc_xml(val_str)}</v8:variant>')
lines.append(f"{i}\t\t<v8:startDate>0001-01-01T00:00:00</v8:startDate>")
lines.append(f"{i}\t\t<v8:endDate>0001-01-01T00:00:00</v8:endDate>")
lines.append(f"{i}\t</value>")
elif parsed.get("type", "").startswith("date"):
lines.append(f'{i}\t<value xsi:type="xs:dateTime">{esc_xml(val_str)}</value>')
elif parsed.get("type") == "boolean":
lines.append(f'{i}\t<value xsi:type="xs:boolean">{esc_xml(val_str)}</value>')
elif parsed.get("type", "").startswith("decimal"):
lines.append(f'{i}\t<value xsi:type="xs:decimal">{esc_xml(val_str)}</value>')
else:
lines.append(f'{i}\t<value xsi:type="xs:string">{esc_xml(val_str)}</value>')
for vl in build_param_value_xml(parsed.get("type", ""), parsed["value"], f"{i}\t"):
lines.append(vl)
lines.append(f"{i}</parameter>")
fragments.append("\r\n".join(lines))
@@ -1361,10 +1391,10 @@ xml_doc = tree.getroot()
# ── 7. Batch value splitting ────────────────────────────────
if operation in ("set-query", "set-structure", "add-dataSet"):
if operation in ("set-query", "set-structure", "modify-structure", "add-dataSet"):
values = [value_arg]
elif operation == "patch-query":
values = [v for v in value_arg.split(";;") if v.strip()]
values = [v.strip() for v in value_arg.split(";;") if v.strip()]
elif operation == "add-drilldown":
if ";;" in value_arg:
values = [v.strip() for v in value_arg.split(";;") if v.strip()]
@@ -1568,8 +1598,33 @@ elif operation == "modify-parameter":
if simple_rest:
for m in re.finditer(r'(\w+)=(\S+)', simple_rest):
key, value = m.group(1), m.group(2)
existing = next((ch for ch in param_el if isinstance(ch.tag, str) and local_name(ch) == key), None)
if existing is not None:
existing = next((ch for ch in param_el if isinstance(ch.tag, str) and local_name(ch) == key and etree.QName(ch.tag).namespace == SCH_NS), None)
if key == "value":
# Rebuild <value> with correct xsi:type from <valueType>
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
value_lines = build_param_value_xml(declared_type, value, child_indent)
frag_xml = "\r\n".join(value_lines)
was_existing = existing is not None
if existing is not None:
# Find next-element sibling as ref before removing
idx = list(param_el).index(existing)
ref_node = param_el[idx + 1] if idx + 1 < len(param_el) else None
remove_node_with_whitespace(existing)
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)
nodes = import_fragment(xml_doc, frag_xml)
for node in nodes:
insert_before_element(param_el, node, ref_node, child_indent)
verb = "updated" if was_existing else "added"
print(f'[OK] Parameter "{param_name}": value {verb} to {value}')
elif existing is not None:
existing.text = value
print(f'[OK] Parameter "{param_name}": {key} updated to {value}')
else:
@@ -1591,12 +1646,22 @@ elif operation == "modify-parameter":
av_value = av_parts[0].strip()
av_presentation = av_parts[1].strip() if len(av_parts) > 1 else ""
av_type = "xs:string"
if re.match(r'^(Перечисление|Справочник|ПланСчетов|Документ|ПланВидовХарактеристик|ПланВидовРасчета)\.', av_value):
av_type = "dcscor:DesignTimeValue"
# Prefer declared <valueType> of the parameter; fall back to value pattern
declared_type = ""
vt_el = None
for ch in param_el:
if isinstance(ch.tag, str) and local_name(ch) == "valueType" and etree.QName(ch.tag).namespace == SCH_NS:
vt_el = ch
break
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
av_lines = [f"{child_indent}<availableValue>"]
av_lines.append(f'{child_indent}\t<value xsi:type="{av_type}">{esc_xml(av_value)}</value>')
for vl in build_param_value_xml(declared_type, av_value, f"{child_indent}\t"):
av_lines.append(vl)
if av_presentation:
av_lines.append(f'{child_indent}\t<presentation xsi:type="v8:LocalStringType">')
av_lines.append(f"{child_indent}\t\t<v8:item>")
@@ -1922,6 +1987,85 @@ elif operation == "set-structure":
print(f'[OK] Structure set in variant "{var_name}": {value_arg}')
elif operation == "modify-structure":
settings = resolve_variant_settings()
var_name = get_variant_name()
struct_items = parse_structure_shorthand(value_arg)
# Flatten parsed tree into (name, groupBy) targets
targets = []
stack = list(struct_items)
while stack:
it = stack.pop()
if it.get("name"):
targets.append({"name": it["name"], "groupBy": it.get("groupBy", [])})
for ch in it.get("children", []) or []:
stack.append(ch)
if not targets:
print(f"modify-structure requires @name= for at least one group: {value_arg}", file=sys.stderr)
sys.exit(1)
ns = {"dcsset": SET_NS, "xsi": XSI_NS}
for t in targets:
xpath = f".//dcsset:item[@xsi:type='dcsset:StructureItemGroup'][dcsset:name='{t['name']}']"
group_el = settings.find(xpath, ns)
if group_el is None:
print(f'[WARN] Group with @name="{t["name"]}" not found — skipped')
continue
gi_el = None
for ch in group_el:
if isinstance(ch.tag, str) and local_name(ch) == "groupItems" and etree.QName(ch.tag).namespace == SET_NS:
gi_el = ch
break
group_indent = get_child_indent(group_el)
if gi_el is None:
# Insert <groupItems> after <name>, before first non-name sibling
ref_after_name = None
saw_name = False
for ch in group_el:
if not isinstance(ch.tag, str):
continue
if local_name(ch) == "name" and etree.QName(ch.tag).namespace == SET_NS:
saw_name = True
elif saw_name:
ref_after_name = ch
break
gi_frag = f"{group_indent}<dcsset:groupItems></dcsset:groupItems>"
for node in import_fragment(xml_doc, gi_frag):
insert_before_element(group_el, node, ref_after_name, group_indent)
for ch in group_el:
if isinstance(ch.tag, str) and local_name(ch) == "groupItems" and etree.QName(ch.tag).namespace == SET_NS:
gi_el = ch
break
to_remove = [ch for ch in gi_el if isinstance(ch.tag, str)]
for el in to_remove:
remove_node_with_whitespace(el)
item_indent = group_indent + "\t"
for field in t["groupBy"]:
lines = [
f'{item_indent}<dcsset:item xsi:type="dcsset:GroupItemField">',
f'{item_indent}\t<dcsset:field>{esc_xml(field)}</dcsset:field>',
f'{item_indent}\t<dcsset:groupType>Items</dcsset:groupType>',
f'{item_indent}\t<dcsset:periodAdditionType>None</dcsset:periodAdditionType>',
f'{item_indent}\t<dcsset:periodAdditionBegin xsi:type="xs:dateTime">0001-01-01T00:00:00</dcsset:periodAdditionBegin>',
f'{item_indent}\t<dcsset:periodAdditionEnd xsi:type="xs:dateTime">0001-01-01T00:00:00</dcsset:periodAdditionEnd>',
f'{item_indent}</dcsset:item>',
]
frag_xml = "\r\n".join(lines)
for node in import_fragment(xml_doc, frag_xml):
insert_before_element(gi_el, node, None, item_indent)
desc = "details" if not t["groupBy"] else ", ".join(t["groupBy"])
print(f'[OK] Group "{t["name"]}" groupItems updated: {desc}')
elif operation == "add-dataSetLink":
for val in values:
parsed = parse_data_set_link_shorthand(val)
@@ -0,0 +1,21 @@
{
"name": "add-parameter: ссылочный тип → xsi:type=dcscor:DesignTimeValue",
"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": "Контрагент: CatalogRef.Контрагенты = Справочник.Контрагенты.ПустаяСсылка"
}
}
@@ -0,0 +1,25 @@
{
"name": "modify-parameter value=... обновляет существующий <value> (не дублирует)",
"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.Контрагенты = Справочник.Контрагенты.ПустаяСсылка" }
}
],
"params": {
"templatePath": "Template.xml",
"operation": "modify-parameter",
"value": "Контрагент value=Справочник.Контрагенты.НашаОрганизация"
}
}
@@ -0,0 +1,29 @@
{
"name": "modify-structure меняет groupItems, сохраняет Selection",
"preRun": [
{
"script": "skd-compile/scripts/skd-compile",
"input": {
"dataSets": [{
"name": "Основной",
"query": "ВЫБРАТЬ Т.Счет, Т.Сумма, Т.Валюта ИЗ Регистр КАК Т",
"fields": ["Счет: string", "Сумма: decimal(15,2)", "Валюта: string"]
}]
},
"args": { "-DefinitionFile": "{inputFile}", "-OutputPath": "{workDir}/Template.xml" }
},
{
"script": "skd-edit/scripts/skd-edit",
"args": { "-TemplatePath": "{workDir}/Template.xml", "-Operation": "set-structure", "-Value": "Счет @name=ДанныеОтчета" }
},
{
"script": "skd-edit/scripts/skd-edit",
"args": { "-TemplatePath": "{workDir}/Template.xml", "-Operation": "add-selection", "-Value": "Счет @group=ДанныеОтчета ;; Сумма @group=ДанныеОтчета" }
}
],
"params": {
"templatePath": "Template.xml",
"operation": "modify-structure",
"value": "Валюта @name=ДанныеОтчета"
}
}
@@ -0,0 +1,21 @@
{
"name": "patch-query ;;-batch: сегменты триммятся по краям",
"preRun": [
{
"script": "skd-compile/scripts/skd-compile",
"input": {
"dataSets": [{
"name": "Основной",
"query": "ВЫБРАТЬ Т.СтароеИмя1, Т.СтароеИмя2 ИЗ Регистр КАК Т",
"fields": ["СтароеИмя1: string", "СтароеИмя2: string"]
}]
},
"args": { "-DefinitionFile": "{inputFile}", "-OutputPath": "{workDir}/Template.xml" }
}
],
"params": {
"templatePath": "Template.xml",
"operation": "patch-query",
"value": "СтароеИмя1 => НовоеИмя1 ;; СтароеИмя2 => НовоеИмя2"
}
}
@@ -0,0 +1,21 @@
{
"name": "set-structure: запятая в shorthand → несколько GroupItemField",
"preRun": [
{
"script": "skd-compile/scripts/skd-compile",
"input": {
"dataSets": [{
"name": "Основной",
"query": "ВЫБРАТЬ Т.Валюта, Т.Банк, Т.ИНН ИЗ Регистр КАК Т",
"fields": ["Валюта: string", "Банк: string", "ИНН: string"]
}]
},
"args": { "-DefinitionFile": "{inputFile}", "-OutputPath": "{workDir}/Template.xml" }
}
],
"params": {
"templatePath": "Template.xml",
"operation": "set-structure",
"value": "Валюта, Банк, ИНН @name=ДанныеОтчета"
}
}
@@ -0,0 +1,51 @@
<?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">Справочник.Контрагенты.ПустаяСсылка</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: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,51 @@
<?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">Справочник.Контрагенты.НашаОрганизация</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: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,83 @@
<?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>
<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: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>
<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:item xsi:type="dcsset:StructureItemGroup">
<dcsset:name>ДанныеОтчета</dcsset:name>
<dcsset:groupItems>
<dcsset:item xsi:type="dcsset:GroupItemField">
<dcsset:field>Валюта</dcsset:field>
<dcsset:groupType>Items</dcsset:groupType>
<dcsset:periodAdditionType>None</dcsset:periodAdditionType>
<dcsset:periodAdditionBegin xsi:type="xs:dateTime">0001-01-01T00:00:00</dcsset:periodAdditionBegin>
<dcsset:periodAdditionEnd xsi:type="xs:dateTime">0001-01-01T00:00:00</dcsset:periodAdditionEnd>
</dcsset:item>
</dcsset:groupItems>
<dcsset:order>
<dcsset:item xsi:type="dcsset:OrderItemAuto" />
</dcsset:order>
<dcsset:selection>
<dcsset:item xsi:type="dcsset:SelectedItemAuto" />
<dcsset:item xsi:type="dcsset:SelectedItemField">
<dcsset:field>Счет</dcsset:field>
</dcsset:item>
<dcsset:item xsi:type="dcsset:SelectedItemField">
<dcsset:field>Сумма</dcsset:field>
</dcsset:item>
</dcsset:selection>
</dcsset:item>
<dcsset:selection>
</dcsset:selection>
</dcsset:settings>
</settingsVariant>
</DataCompositionSchema>
@@ -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>СтароеИмя1</dataPath>
<field>СтароеИмя1</field>
<valueType>
<v8:Type>xs:string</v8:Type>
<v8:StringQualifiers>
<v8:Length>0</v8:Length>
<v8:AllowedLength>Variable</v8:AllowedLength>
</v8:StringQualifiers>
</valueType>
</field>
<field xsi:type="DataSetFieldField">
<dataPath>СтароеИмя2</dataPath>
<field>СтароеИмя2</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>ВЫБРАТЬ Т.НовоеИмя1, Т.НовоеИмя2 ИЗ Регистр КАК Т</query>
</dataSet>
<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,90 @@
<?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>
<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>
<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>
<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:item xsi:type="dcsset:StructureItemGroup">
<dcsset:name>ДанныеОтчета</dcsset:name>
<dcsset:groupItems>
<dcsset:item xsi:type="dcsset:GroupItemField">
<dcsset:field>Валюта</dcsset:field>
<dcsset:groupType>Items</dcsset:groupType>
<dcsset:periodAdditionType>None</dcsset:periodAdditionType>
<dcsset:periodAdditionBegin xsi:type="xs:dateTime">0001-01-01T00:00:00</dcsset:periodAdditionBegin>
<dcsset:periodAdditionEnd xsi:type="xs:dateTime">0001-01-01T00:00:00</dcsset:periodAdditionEnd>
</dcsset:item>
<dcsset:item xsi:type="dcsset:GroupItemField">
<dcsset:field>Банк</dcsset:field>
<dcsset:groupType>Items</dcsset:groupType>
<dcsset:periodAdditionType>None</dcsset:periodAdditionType>
<dcsset:periodAdditionBegin xsi:type="xs:dateTime">0001-01-01T00:00:00</dcsset:periodAdditionBegin>
<dcsset:periodAdditionEnd xsi:type="xs:dateTime">0001-01-01T00:00:00</dcsset:periodAdditionEnd>
</dcsset:item>
<dcsset:item xsi:type="dcsset:GroupItemField">
<dcsset:field>ИНН</dcsset:field>
<dcsset:groupType>Items</dcsset:groupType>
<dcsset:periodAdditionType>None</dcsset:periodAdditionType>
<dcsset:periodAdditionBegin xsi:type="xs:dateTime">0001-01-01T00:00:00</dcsset:periodAdditionBegin>
<dcsset:periodAdditionEnd xsi:type="xs:dateTime">0001-01-01T00:00:00</dcsset:periodAdditionEnd>
</dcsset:item>
</dcsset:groupItems>
<dcsset:order>
<dcsset:item xsi:type="dcsset:OrderItemAuto" />
</dcsset:order>
<dcsset:selection>
<dcsset:item xsi:type="dcsset:SelectedItemAuto" />
</dcsset:selection>
</dcsset:item>
<dcsset:selection>
</dcsset:selection>
</dcsset:settings>
</settingsVariant>
</DataCompositionSchema>