feat(skd): block-level userSettingID на selection/filter/order/CA + meta на StructureItemTable

Раньше теряли userSettingID, который platform пишет:
1. Прямо в блоки selection/filter/order/conditionalAppearance под
   <dcsset:settings> (рядом с block-level viewMode). Расширена цепочка
   Get-BlockUSID + новый -blockUserSettingID параметр в Emit-*.
2. На самой <dcsset:item xsi:type="dcsset:StructureItemTable"> (рядом
   с viewMode/userSettingPresentation/itemsViewMode). Build-Structure
   читает их, Emit-StructureItem (type=table) эмитит.

sample30: −46 строк (1602 → 1556).
This commit is contained in:
Nick Shirokov
2026-05-23 20:12:14 +03:00
parent 1b36aa97c8
commit 9ef554a576
3 changed files with 103 additions and 20 deletions
@@ -1,4 +1,4 @@
# skd-compile v1.77 — Compile 1C DCS from JSON
# skd-compile v1.79 — Compile 1C DCS from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[string]$DefinitionFile,
@@ -1982,7 +1982,7 @@ function Emit-SelectionItem {
}
function Emit-Selection {
param($items, [string]$indent, [switch]$skipAuto, $blockViewMode = $null)
param($items, [string]$indent, [switch]$skipAuto, $blockViewMode = $null, $blockUserSettingID = $null)
if (-not $items -or $items.Count -eq 0) { return }
@@ -1994,6 +1994,10 @@ function Emit-Selection {
if ($null -ne $blockViewMode) {
X "$indent`t<dcsset:viewMode>$(Esc-Xml "$blockViewMode")</dcsset:viewMode>"
}
if ($null -ne $blockUserSettingID) {
$uid = if ("$blockUserSettingID" -eq 'auto') { New-Guid-String } else { "$blockUserSettingID" }
X "$indent`t<dcsset:userSettingID>$(Esc-Xml $uid)</dcsset:userSettingID>"
}
X "$indent</dcsset:selection>"
}
@@ -2124,7 +2128,7 @@ function Emit-FilterItem {
}
function Emit-Filter {
param($items, [string]$indent, $blockViewMode = $null)
param($items, [string]$indent, $blockViewMode = $null, $blockUserSettingID = $null)
if (-not $items -or $items.Count -eq 0) { return }
@@ -2159,6 +2163,10 @@ function Emit-Filter {
if ($null -ne $blockViewMode) {
X "$indent`t<dcsset:viewMode>$(Esc-Xml "$blockViewMode")</dcsset:viewMode>"
}
if ($null -ne $blockUserSettingID) {
$uid = if ("$blockUserSettingID" -eq 'auto') { New-Guid-String } else { "$blockUserSettingID" }
X "$indent`t<dcsset:userSettingID>$(Esc-Xml $uid)</dcsset:userSettingID>"
}
X "$indent</dcsset:filter>"
}
@@ -2293,7 +2301,7 @@ function Emit-AppearanceValue {
}
function Emit-ConditionalAppearance {
param($items, [string]$indent, $blockViewMode = $null)
param($items, [string]$indent, $blockViewMode = $null, $blockUserSettingID = $null)
if (-not $items -or $items.Count -eq 0) { return }
@@ -2381,6 +2389,10 @@ function Emit-ConditionalAppearance {
if ($null -ne $blockViewMode) {
X "$indent`t<dcsset:viewMode>$(Esc-Xml "$blockViewMode")</dcsset:viewMode>"
}
if ($null -ne $blockUserSettingID) {
$uid = if ("$blockUserSettingID" -eq 'auto') { New-Guid-String } else { "$blockUserSettingID" }
X "$indent`t<dcsset:userSettingID>$(Esc-Xml $uid)</dcsset:userSettingID>"
}
X "$indent</dcsset:conditionalAppearance>"
}
@@ -2894,6 +2906,20 @@ function Emit-StructureItem {
if ($item.outputParameters) {
Emit-OutputParameters -params $item.outputParameters -indent "$indent`t"
}
# viewMode / userSettingID / userSettingPresentation / itemsViewMode на самой таблице
if ($item.viewMode) {
X "$indent`t<dcsset:viewMode>$(Esc-Xml "$($item.viewMode)")</dcsset:viewMode>"
}
if ($item.userSettingID) {
$gid = if ("$($item.userSettingID)" -eq "auto") { New-Guid-String } else { "$($item.userSettingID)" }
X "$indent`t<dcsset:userSettingID>$(Esc-Xml $gid)</dcsset:userSettingID>"
}
if ($item.userSettingPresentation) {
Emit-MLText -tag "dcsset:userSettingPresentation" -text $item.userSettingPresentation -indent "$indent`t"
}
if ($item.itemsViewMode) {
X "$indent`t<dcsset:itemsViewMode>$(Esc-Xml "$($item.itemsViewMode)")</dcsset:itemsViewMode>"
}
X "$indent</dcsset:item>"
}
@@ -2989,12 +3015,17 @@ function Emit-SettingsVariants {
$s = $v.settings
# Helper: resolve XViewMode from settings — emit only if explicitly set
# Helper: resolve XViewMode/XUserSettingID from settings — emit only if explicitly set
function Get-BlockVM([string]$key) {
$prop = "${key}ViewMode"
if ($s.PSObject.Properties[$prop]) { return "$($s.$prop)" }
return $null
}
function Get-BlockUSID([string]$key) {
$prop = "${key}UserSettingID"
if ($s.PSObject.Properties[$prop]) { return "$($s.$prop)" }
return $null
}
# userFields — пользовательские вычисляемые поля (Expression / Case)
if ($s.userFields -and $s.userFields.Count -gt 0) {
@@ -3003,22 +3034,22 @@ function Emit-SettingsVariants {
# Selection (Auto items only belong at group level, not top-level settings)
if ($s.selection) {
Emit-Selection -items $s.selection -indent "`t`t`t" -skipAuto -blockViewMode (Get-BlockVM 'selection')
Emit-Selection -items $s.selection -indent "`t`t`t" -skipAuto -blockViewMode (Get-BlockVM 'selection') -blockUserSettingID (Get-BlockUSID 'selection')
}
# Filter
if ($s.filter) {
Emit-Filter -items $s.filter -indent "`t`t`t" -blockViewMode (Get-BlockVM 'filter')
Emit-Filter -items $s.filter -indent "`t`t`t" -blockViewMode (Get-BlockVM 'filter') -blockUserSettingID (Get-BlockUSID 'filter')
}
# Order (Auto items only belong at group level, not top-level settings)
if ($s.order) {
Emit-Order -items $s.order -indent "`t`t`t" -skipAuto -blockViewMode (Get-BlockVM 'order')
Emit-Order -items $s.order -indent "`t`t`t" -skipAuto -blockViewMode (Get-BlockVM 'order') -blockUserSettingID (Get-BlockUSID 'order')
}
# ConditionalAppearance
if ($s.conditionalAppearance) {
Emit-ConditionalAppearance -items $s.conditionalAppearance -indent "`t`t`t" -blockViewMode (Get-BlockVM 'conditionalAppearance')
Emit-ConditionalAppearance -items $s.conditionalAppearance -indent "`t`t`t" -blockViewMode (Get-BlockVM 'conditionalAppearance') -blockUserSettingID (Get-BlockUSID 'conditionalAppearance')
}
# OutputParameters (platform does NOT emit <viewMode> on this block)
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# skd-compile v1.77 — Compile 1C DCS from JSON
# skd-compile v1.79 — Compile 1C DCS from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import json
@@ -1641,7 +1641,7 @@ def emit_selection_item(lines, item, indent):
lines.append(f'{indent}</dcsset:item>')
def emit_selection(lines, items, indent, skip_auto=False, block_view_mode=None):
def emit_selection(lines, items, indent, skip_auto=False, block_view_mode=None, block_user_setting_id=None):
if not items or len(items) == 0:
return
lines.append(f'{indent}<dcsset:selection>')
@@ -1651,6 +1651,9 @@ def emit_selection(lines, items, indent, skip_auto=False, block_view_mode=None):
emit_selection_item(lines, item, f'{indent}\t')
if block_view_mode is not None:
lines.append(f'{indent}\t<dcsset:viewMode>{esc_xml(str(block_view_mode))}</dcsset:viewMode>')
if block_user_setting_id is not None:
uid = new_uuid() if str(block_user_setting_id) == 'auto' else str(block_user_setting_id)
lines.append(f'{indent}\t<dcsset:userSettingID>{esc_xml(uid)}</dcsset:userSettingID>')
lines.append(f'{indent}</dcsset:selection>')
@@ -1764,7 +1767,7 @@ def emit_filter_item(lines, item, indent):
lines.append(f'{indent}</dcsset:item>')
def emit_filter(lines, items, indent, block_view_mode=None):
def emit_filter(lines, items, indent, block_view_mode=None, block_user_setting_id=None):
if not items or len(items) == 0:
return
@@ -1791,6 +1794,9 @@ def emit_filter(lines, items, indent, block_view_mode=None):
emit_filter_item(lines, item, f'{indent}\t')
if block_view_mode is not None:
lines.append(f'{indent}\t<dcsset:viewMode>{esc_xml(str(block_view_mode))}</dcsset:viewMode>')
if block_user_setting_id is not None:
uid = new_uuid() if str(block_user_setting_id) == 'auto' else str(block_user_setting_id)
lines.append(f'{indent}\t<dcsset:userSettingID>{esc_xml(uid)}</dcsset:userSettingID>')
lines.append(f'{indent}</dcsset:filter>')
@@ -1895,7 +1901,7 @@ def emit_appearance_value(lines, key, val, indent):
lines.append(f'{indent}</dcscor:item>')
def emit_conditional_appearance(lines, items, indent, block_view_mode=None):
def emit_conditional_appearance(lines, items, indent, block_view_mode=None, block_user_setting_id=None):
if not items or len(items) == 0:
return
@@ -1964,6 +1970,9 @@ def emit_conditional_appearance(lines, items, indent, block_view_mode=None):
lines.append(f'{indent}\t</dcsset:item>')
if block_view_mode is not None:
lines.append(f'{indent}\t<dcsset:viewMode>{esc_xml(str(block_view_mode))}</dcsset:viewMode>')
if block_user_setting_id is not None:
uid = new_uuid() if str(block_user_setting_id) == 'auto' else str(block_user_setting_id)
lines.append(f'{indent}\t<dcsset:userSettingID>{esc_xml(uid)}</dcsset:userSettingID>')
lines.append(f'{indent}</dcsset:conditionalAppearance>')
@@ -2334,6 +2343,16 @@ def emit_structure_item(lines, item, indent):
emit_conditional_appearance(lines, item['conditionalAppearance'], f'{indent}\t')
if item.get('outputParameters'):
emit_output_parameters(lines, item['outputParameters'], f'{indent}\t')
# viewMode / userSettingID / userSettingPresentation / itemsViewMode на самой таблице
if item.get('viewMode'):
lines.append(f'{indent}\t<dcsset:viewMode>{esc_xml(str(item["viewMode"]))}</dcsset:viewMode>')
if item.get('userSettingID'):
gid = new_uuid() if str(item['userSettingID']) == 'auto' else str(item['userSettingID'])
lines.append(f'{indent}\t<dcsset:userSettingID>{esc_xml(gid)}</dcsset:userSettingID>')
if item.get('userSettingPresentation'):
emit_mltext(lines, f'{indent}\t', 'dcsset:userSettingPresentation', item['userSettingPresentation'])
if item.get('itemsViewMode'):
lines.append(f'{indent}\t<dcsset:itemsViewMode>{esc_xml(str(item["itemsViewMode"]))}</dcsset:itemsViewMode>')
lines.append(f'{indent}</dcsset:item>')
@@ -2407,7 +2426,10 @@ def emit_settings_variants(lines, defn):
s = v.get('settings', {})
# Helper: resolve XViewMode from settings — emit only if explicitly set
# Helper: resolve XViewMode/XUserSettingID from settings — emit only if explicitly set
def _block_usid(key):
prop = f'{key}UserSettingID'
return str(s[prop]) if prop in s else None
def _block_vm(key):
prop = f'{key}ViewMode'
if prop in s:
@@ -2420,19 +2442,19 @@ def emit_settings_variants(lines, defn):
# Selection
if s.get('selection'):
emit_selection(lines, s['selection'], '\t\t\t', skip_auto=True, block_view_mode=_block_vm('selection'))
emit_selection(lines, s['selection'], '\t\t\t', skip_auto=True, block_view_mode=_block_vm('selection'), block_user_setting_id=_block_usid('selection'))
# Filter
if s.get('filter'):
emit_filter(lines, s['filter'], '\t\t\t', block_view_mode=_block_vm('filter'))
emit_filter(lines, s['filter'], '\t\t\t', block_view_mode=_block_vm('filter'), block_user_setting_id=_block_usid('filter'))
# Order
if s.get('order'):
emit_order(lines, s['order'], '\t\t\t', skip_auto=True, block_view_mode=_block_vm('order'))
emit_order(lines, s['order'], '\t\t\t', skip_auto=True, block_view_mode=_block_vm('order'), block_user_setting_id=_block_usid('order'))
# ConditionalAppearance
if s.get('conditionalAppearance'):
emit_conditional_appearance(lines, s['conditionalAppearance'], '\t\t\t', block_view_mode=_block_vm('conditionalAppearance'))
emit_conditional_appearance(lines, s['conditionalAppearance'], '\t\t\t', block_view_mode=_block_vm('conditionalAppearance'), block_user_setting_id=_block_usid('conditionalAppearance'))
# OutputParameters (platform does NOT emit <viewMode> on this block)
if s.get('outputParameters'):
@@ -1,4 +1,4 @@
# skd-decompile v0.63 — Decompile 1C DCS Template.xml to JSON DSL (draft)
# skd-decompile v0.65 — Decompile 1C DCS Template.xml to JSON DSL (draft)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -1985,6 +1985,17 @@ function Build-Structure {
$tCa = Build-ConditionalAppearance -caNode $tCaN -loc "$loc/$idx/ca"
if ($tCa.Count -gt 0) { $entry['conditionalAppearance'] = $tCa }
}
# viewMode / userSettingID / userSettingPresentation на самой таблице (direct child)
foreach ($ch in $it.ChildNodes) {
if ($ch.NodeType -ne 'Element' -or $ch.NamespaceURI -ne 'http://v8.1c.ru/8.1/data-composition-system/settings') { continue }
if ($ch.LocalName -eq 'viewMode' -and -not $entry.Contains('viewMode')) { $entry['viewMode'] = $ch.InnerText }
elseif ($ch.LocalName -eq 'userSettingID' -and -not $entry.Contains('userSettingID')) { $entry['userSettingID'] = 'auto' }
elseif ($ch.LocalName -eq 'userSettingPresentation' -and -not $entry.Contains('userSettingPresentation')) {
$uspV = Get-MLText $ch
if ($uspV) { $entry['userSettingPresentation'] = $uspV }
}
elseif ($ch.LocalName -eq 'itemsViewMode' -and -not $entry.Contains('itemsViewMode')) { $entry['itemsViewMode'] = $ch.InnerText }
}
$items += $entry
$idx++
continue
@@ -2427,6 +2438,17 @@ foreach ($sv in $svNodes) {
return $null
}
# Block-level userSettingID (direct child of selection/filter/order/conditionalAppearance).
function Get-BlockUSID($node) {
if (-not $node) { return $null }
foreach ($child in $node.ChildNodes) {
if ($child.NodeType -eq 'Element' -and $child.LocalName -eq 'userSettingID' -and $child.NamespaceURI -eq 'http://v8.1c.ru/8.1/data-composition-system/settings') {
return $child.InnerText
}
}
return $null
}
# userFields — пользовательские вычисляемые поля (Expression / Case)
$ufNode = $settingsNode.SelectSingleNode("dcsset:userFields", $ns)
if ($ufNode) {
@@ -2500,9 +2522,11 @@ foreach ($sv in $svNodes) {
$selTop = $settingsNode.SelectSingleNode("dcsset:selection", $ns)
$selItems = Build-Selection -selNode $selTop -loc "variant[$vi]/selection"
if ($selItems.Count -gt 0) { $settings['selection'] = $selItems }
# Block-level viewMode: preserve exact presence (even Normal) for bit-perfect round-trip
# Block-level viewMode/userSettingID: preserve exact presence (even Normal) for bit-perfect
$svm = Get-BlockVM $selTop
if ($null -ne $svm) { $settings['selectionViewMode'] = $svm }
$susid = Get-BlockUSID $selTop
if ($susid) { $settings['selectionUserSettingID'] = 'auto' }
# filter
$fTop = $settingsNode.SelectSingleNode("dcsset:filter", $ns)
@@ -2513,6 +2537,8 @@ foreach ($sv in $svNodes) {
}
$fvm = Get-BlockVM $fTop
if ($null -ne $fvm) { $settings['filterViewMode'] = $fvm }
$fusid = Get-BlockUSID $fTop
if ($fusid) { $settings['filterUserSettingID'] = 'auto' }
# order
$ordTop = $settingsNode.SelectSingleNode("dcsset:order", $ns)
@@ -2520,6 +2546,8 @@ foreach ($sv in $svNodes) {
if ($ordItems.Count -gt 0) { $settings['order'] = $ordItems }
$ovm = Get-BlockVM $ordTop
if ($null -ne $ovm) { $settings['orderViewMode'] = $ovm }
$ousid = Get-BlockUSID $ordTop
if ($ousid) { $settings['orderUserSettingID'] = 'auto' }
# conditionalAppearance
$caTop = $settingsNode.SelectSingleNode("dcsset:conditionalAppearance", $ns)
@@ -2529,6 +2557,8 @@ foreach ($sv in $svNodes) {
}
$cavm = Get-BlockVM $caTop
if ($null -ne $cavm) { $settings['conditionalAppearanceViewMode'] = $cavm }
$causid = Get-BlockUSID $caTop
if ($causid) { $settings['conditionalAppearanceUserSettingID'] = 'auto' }
# outputParameters
$opTop = $settingsNode.SelectSingleNode("dcsset:outputParameters", $ns)