diff --git a/.claude/skills/meta-compile/scripts/meta-compile.ps1 b/.claude/skills/meta-compile/scripts/meta-compile.ps1
index 1f3382c9..1f99abb2 100644
--- a/.claude/skills/meta-compile/scripts/meta-compile.ps1
+++ b/.claude/skills/meta-compile/scripts/meta-compile.ps1
@@ -1,4 +1,4 @@
-# meta-compile v1.45 — Compile 1C metadata object from JSON
+# meta-compile v1.46 — Compile 1C metadata object from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -1605,9 +1605,9 @@ function Emit-Attribute {
Emit-MinMaxValue "$indent`t`t" "MinValue" $parsed.minValue
Emit-MinMaxValue "$indent`t`t" "MaxValue" $parsed.maxValue
- # FillFromFillingValue — not for tabular/processor/chart/register-other
+ # FillFromFillingValue — not for tabular/processor/chart/register-other/register-accum
# (Chart*, AccumulationRegister/AccountingRegister/CalculationRegister don't support these)
- if ($context -notin @("tabular", "processor", "chart", "register-other")) {
+ if ($context -notin @("tabular", "processor", "chart", "register-other", "register-accum")) {
# Флаг-shorthand `master` у ведущего измерения регистра конвенционально ставит и FillFromFillingValue=true
# (эргономика авторинга; декомпилятор пишет key-форму master:true + явный fillFromFillingValue → роундтрип цел).
$ffv = if ($parsed.fillFromFillingValue -eq $true -or ($elemTag -eq "Dimension" -and $parsed.flags -contains "master")) { "true" } else { "false" }
@@ -1615,7 +1615,7 @@ function Emit-Attribute {
}
# FillValue — same restriction
- if ($context -notin @("tabular", "processor", "chart", "register-other")) {
+ if ($context -notin @("tabular", "processor", "chart", "register-other", "register-accum")) {
Emit-FillValue "$indent`t`t" $typeStr $parsed.fillValue $parsed.hasFillValue
}
@@ -1647,6 +1647,12 @@ function Emit-Attribute {
X "$indent`t`t$denyIncomplete"
}
+ # Измерение регистра накопления: DenyIncompleteValues (между ChoiceHistoryOnInput и Indexing).
+ if ($elemTag -eq "Dimension" -and $context -eq "register-accum") {
+ $denyIncomplete = if ($parsed.denyIncompleteValues -eq $true -or $parsed.flags -contains "denyincomplete") { "true" } else { "false" }
+ X "$indent`t`t$denyIncomplete"
+ }
+
# Use — only for catalog top-level attributes
if ($context -eq "catalog") {
$use = if ($parsed.use) { $parsed.use } else { "ForItem" }
@@ -1657,17 +1663,25 @@ function Emit-Attribute {
if ($context -notin @("processor", "processor-tabular")) {
# Признаки учёта ПС (account-flag) не имеют /, но имеют .
if ($context -ne "account-flag") {
- $indexing = "DontIndex"
- if ($parsed.flags -contains "index") { $indexing = "Index" }
- if ($parsed.flags -contains "indexadditional") { $indexing = "IndexWithAdditionalOrder" }
- if ($parsed.indexing) { $indexing = $parsed.indexing }
- X "$indent`t`t$indexing"
+ # Ресурс регистра накопления НЕ имеет (только ); измерение/реквизит — имеют.
+ if (-not ($context -eq "register-accum" -and $elemTag -eq "Resource")) {
+ $indexing = "DontIndex"
+ if ($parsed.flags -contains "index") { $indexing = "Index" }
+ if ($parsed.flags -contains "indexadditional") { $indexing = "IndexWithAdditionalOrder" }
+ if ($parsed.indexing) { $indexing = $parsed.indexing }
+ X "$indent`t`t$indexing"
+ }
$fts = if ($parsed.fullTextSearch) { $parsed.fullTextSearch } else { "Use" }
X "$indent`t`t$fts"
}
+ # Измерение регистра накопления: UseInTotals (после FullTextSearch, дефолт true).
+ if ($elemTag -eq "Dimension" -and $context -eq "register-accum") {
+ $useInTotals = if ($parsed.useInTotals -eq $false -or $parsed.flags -contains "nouseintotals") { "false" } else { "true" }
+ X "$indent`t`t$useInTotals"
+ }
# DataHistory — not for Chart* types and non-InformationRegister register family
- if ($context -notin @("chart", "register-other")) {
+ if ($context -notin @("chart", "register-other", "register-accum")) {
$dh = if ($parsed.dataHistory) { $parsed.dataHistory } else { "Use" }
X "$indent`t`t$dh"
}
@@ -2299,19 +2313,21 @@ function Emit-AccumulationRegisterProperties {
X "$i$(Esc-Xml $objName)"
Emit-MLText $i "Synonym" $synonym
- X "$i"
- X "$itrue"
- X "$i"
- X "$i"
+ if ($def.comment) { X "$i$(Esc-XmlText "$($def.comment)")" } else { X "$i" }
+ $useStdCmd = if (Get-BoolProp "useStandardCommands" $true) { "true" } else { "false" }
+ X "$i$useStdCmd"
+ Emit-FormRef $i "DefaultListForm" $def.defaultListForm
+ Emit-FormRef $i "AuxiliaryListForm" $def.auxiliaryListForm
$registerType = Get-EnumProp "RegisterType" "registerType" "Balance"
X "$i$registerType"
- X "$ifalse"
+ $inclHelp = if (Get-BoolProp "includeHelpInContents" $false) { "true" } else { "false" }
+ X "$i$inclHelp"
Emit-StandardAttributes $i "AccumulationRegister"
- $dataLockControlMode = Get-EnumProp "DataLockControlMode" "dataLockControlMode" "Automatic"
+ $dataLockControlMode = Get-EnumProp "DataLockControlMode" "dataLockControlMode" "Managed"
X "$i$dataLockControlMode"
$fullTextSearch = Get-EnumProp "FullTextSearch" "fullTextSearch" "Use"
@@ -2320,9 +2336,9 @@ function Emit-AccumulationRegisterProperties {
$enableTotalsSplitting = if ($def.enableTotalsSplitting -eq $false) { "false" } else { "true" }
X "$i$enableTotalsSplitting"
- X "$i"
- X "$i"
- X "$i"
+ Emit-MLText $i "ListPresentation" $def.listPresentation
+ Emit-MLText $i "ExtendedListPresentation" $def.extendedListPresentation
+ Emit-MLText $i "Explanation" $def.explanation
}
# --- 13a. Wave 1: DefinedType, CommonModule, ScheduledJob, EventSubscription ---
@@ -3685,14 +3701,15 @@ if ($objType -in @("InformationRegister","AccumulationRegister","AccountingRegis
# InformationRegister.Attribute supports FillFromFillingValue/FillValue/DataHistory;
# AccumulationRegister/AccountingRegister/CalculationRegister.Attribute do NOT.
$regCtx = if ($objType -eq "InformationRegister") { "register-info" } else { "register-other" }
- # InformationRegister: ресурсы/измерения — через богатый Emit-Attribute (общий слой object-свойств).
- # Прочие регистры — легаси Emit-Resource/Emit-Dimension (пока не портированы).
+ # InformationRegister/AccumulationRegister: ресурсы/измерения — через богатый Emit-Attribute (общий слой
+ # object-свойств). Прочие регистры (Accounting/Calculation) — легаси Emit-Resource/Emit-Dimension (пока не портированы).
+ $dimResCtx = switch ($objType) { "InformationRegister" { "register-info" } "AccumulationRegister" { "register-accum" } default { $null } }
foreach ($r in $resources) {
- if ($objType -eq "InformationRegister") { Emit-Attribute "`t`t`t" $r "register-info" "Resource" }
+ if ($dimResCtx) { Emit-Attribute "`t`t`t" $r $dimResCtx "Resource" }
else { Emit-Resource "`t`t`t" $r $objType }
}
foreach ($d in $dims) {
- if ($objType -eq "InformationRegister") { Emit-Attribute "`t`t`t" $d "register-info" "Dimension" }
+ if ($dimResCtx) { Emit-Attribute "`t`t`t" $d $dimResCtx "Dimension" }
else { Emit-Dimension "`t`t`t" $d $objType }
}
foreach ($a in $regAttrs) {
diff --git a/.claude/skills/meta-compile/scripts/meta-compile.py b/.claude/skills/meta-compile/scripts/meta-compile.py
index a7643989..49c98a40 100644
--- a/.claude/skills/meta-compile/scripts/meta-compile.py
+++ b/.claude/skills/meta-compile/scripts/meta-compile.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# meta-compile v1.45 — Compile 1C metadata object from JSON
+# meta-compile v1.46 — Compile 1C metadata object from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -1681,10 +1681,10 @@ def emit_attribute(indent, parsed, context, elem_tag='Attribute'):
emit_min_max_value(f'{indent}\t\t', 'MaxValue', parsed.get('maxValue'))
# FillFromFillingValue / FillValue — not for tabular/processor/chart/register-other
# (Chart*, AccumulationRegister/AccountingRegister/CalculationRegister don't support these)
- if context not in ('tabular', 'processor', 'chart', 'register-other'):
+ if context not in ('tabular', 'processor', 'chart', 'register-other', 'register-accum'):
ffv = 'true' if (parsed.get('fillFromFillingValue') is True or (elem_tag == 'Dimension' and 'master' in parsed.get('flags', []))) else 'false'
X(f'{indent}\t\t{ffv}')
- if context not in ('tabular', 'processor', 'chart', 'register-other'):
+ if context not in ('tabular', 'processor', 'chart', 'register-other', 'register-accum'):
emit_fill_value(f'{indent}\t\t', type_str, parsed.get('fillValue'), parsed.get('hasFillValue'))
fill_checking = 'DontCheck'
if 'req' in parsed.get('flags', []):
@@ -1709,22 +1709,32 @@ def emit_attribute(indent, parsed, context, elem_tag='Attribute'):
X(f'{indent}\t\t{master}')
X(f'{indent}\t\t{main_filter}')
X(f'{indent}\t\t{deny_incomplete}')
+ # Измерение регистра накопления: DenyIncompleteValues (между ChoiceHistoryOnInput и Indexing).
+ if elem_tag == 'Dimension' and context == 'register-accum':
+ deny_incomplete = 'true' if (parsed.get('denyIncompleteValues') is True or 'denyincomplete' in parsed.get('flags', [])) else 'false'
+ X(f'{indent}\t\t{deny_incomplete}')
if context == 'catalog':
X(f'{indent}\t\t')
if context not in ('processor', 'processor-tabular'):
# Признаки учёта ПС (account-flag) не имеют /, но имеют .
if context != 'account-flag':
- indexing = 'DontIndex'
- if 'index' in parsed.get('flags', []):
- indexing = 'Index'
- if 'indexadditional' in parsed.get('flags', []):
- indexing = 'IndexWithAdditionalOrder'
- if parsed.get('indexing'):
- indexing = parsed['indexing']
- X(f'{indent}\t\t{indexing}')
+ # Ресурс регистра накопления НЕ имеет (только ); измерение/реквизит — имеют.
+ if not (context == 'register-accum' and elem_tag == 'Resource'):
+ indexing = 'DontIndex'
+ if 'index' in parsed.get('flags', []):
+ indexing = 'Index'
+ if 'indexadditional' in parsed.get('flags', []):
+ indexing = 'IndexWithAdditionalOrder'
+ if parsed.get('indexing'):
+ indexing = parsed['indexing']
+ X(f'{indent}\t\t{indexing}')
X(f'{indent}\t\t{parsed.get("fullTextSearch") or "Use"}')
+ # Измерение регистра накопления: UseInTotals (после FullTextSearch, дефолт true).
+ if elem_tag == 'Dimension' and context == 'register-accum':
+ use_in_totals = 'false' if (parsed.get('useInTotals') is False or 'nouseintotals' in parsed.get('flags', [])) else 'true'
+ X(f'{indent}\t\t{use_in_totals}')
# DataHistory — not for Chart* types and non-InformationRegister register family
- if context not in ('chart', 'register-other'):
+ if context not in ('chart', 'register-other', 'register-accum'):
X(f'{indent}\t\t{parsed.get("dataHistory") or "Use"}')
X(f'{indent}\t')
X(f'{indent}{elem_tag}>')
@@ -2278,23 +2288,28 @@ def emit_accumulation_register_properties(indent):
i = indent
X(f'{i}{esc_xml(obj_name)}')
emit_mltext(i, 'Synonym', synonym)
- X(f'{i}')
- X(f'{i}true')
- X(f'{i}')
- X(f'{i}')
+ if defn.get('comment'):
+ X(f'{i}{esc_xml_text(str(defn["comment"]))}')
+ else:
+ X(f'{i}')
+ use_std_cmd = 'true' if get_bool_prop('useStandardCommands', True) else 'false'
+ X(f'{i}{use_std_cmd}')
+ emit_form_ref(i, 'DefaultListForm', defn.get('defaultListForm'))
+ emit_form_ref(i, 'AuxiliaryListForm', defn.get('auxiliaryListForm'))
register_type = get_enum_prop('RegisterType', 'registerType', 'Balance')
X(f'{i}{register_type}')
- X(f'{i}false')
+ incl_help = 'true' if get_bool_prop('includeHelpInContents', False) else 'false'
+ X(f'{i}{incl_help}')
emit_standard_attributes(i, 'AccumulationRegister')
- data_lock_control_mode = get_enum_prop('DataLockControlMode', 'dataLockControlMode', 'Automatic')
+ data_lock_control_mode = get_enum_prop('DataLockControlMode', 'dataLockControlMode', 'Managed')
X(f'{i}{data_lock_control_mode}')
full_text_search = get_enum_prop('FullTextSearch', 'fullTextSearch', 'Use')
X(f'{i}{full_text_search}')
enable_totals_splitting = 'false' if defn.get('enableTotalsSplitting') is False else 'true'
X(f'{i}{enable_totals_splitting}')
- X(f'{i}')
- X(f'{i}')
- X(f'{i}')
+ emit_mltext(i, 'ListPresentation', defn.get('listPresentation'))
+ emit_mltext(i, 'ExtendedListPresentation', defn.get('extendedListPresentation'))
+ emit_mltext(i, 'Explanation', defn.get('explanation'))
# --- 13a. DefinedType, CommonModule, ScheduledJob, EventSubscription ---
@@ -3491,16 +3506,17 @@ if obj_type in ('InformationRegister', 'AccumulationRegister', 'AccountingRegist
# InformationRegister.Attribute supports FillFromFillingValue/FillValue/DataHistory;
# AccumulationRegister/AccountingRegister/CalculationRegister.Attribute do NOT.
reg_ctx = 'register-info' if obj_type == 'InformationRegister' else 'register-other'
- # InformationRegister: ресурсы/измерения — через богатый emit_attribute (общий слой object-свойств).
- # Прочие регистры — легаси emit_resource/emit_dimension (пока не портированы).
+ # InformationRegister/AccumulationRegister: ресурсы/измерения — через богатый emit_attribute (общий слой
+ # object-свойств). Прочие регистры (Accounting/Calculation) — легаси emit_resource/emit_dimension (не портированы).
+ dim_res_ctx = {'InformationRegister': 'register-info', 'AccumulationRegister': 'register-accum'}.get(obj_type)
for r in resources:
- if obj_type == 'InformationRegister':
- emit_attribute('\t\t\t', r, 'register-info', 'Resource')
+ if dim_res_ctx:
+ emit_attribute('\t\t\t', r, dim_res_ctx, 'Resource')
else:
emit_resource('\t\t\t', r, obj_type)
for d in dims:
- if obj_type == 'InformationRegister':
- emit_attribute('\t\t\t', d, 'register-info', 'Dimension')
+ if dim_res_ctx:
+ emit_attribute('\t\t\t', d, dim_res_ctx, 'Dimension')
else:
emit_dimension('\t\t\t', d, obj_type)
for a in reg_attrs:
diff --git a/.claude/skills/meta-decompile/scripts/meta-decompile.ps1 b/.claude/skills/meta-decompile/scripts/meta-decompile.ps1
index b1a340fa..37522481 100644
--- a/.claude/skills/meta-decompile/scripts/meta-decompile.ps1
+++ b/.claude/skills/meta-decompile/scripts/meta-decompile.ps1
@@ -1,4 +1,4 @@
-# meta-decompile v0.37 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
+# meta-decompile v0.38 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
#
# Поддержаны: Catalog, ExchangePlan, ChartOfCharacteristicTypes, ChartOfAccounts, ChartOfCalculationTypes, Document. Инверс meta-compile (omit-on-default: ключ эмитим только
@@ -91,8 +91,8 @@ foreach ($c in $rootEl.ChildNodes) { if ($c.NodeType -eq 'Element') { $objNode =
if (-not $objNode) { [Console]::Error.WriteLine("meta-decompile: пустой MetaDataObject"); exit 3 }
$objType = $objNode.LocalName
-if ($objType -notin @('Catalog', 'ExchangePlan', 'ChartOfCharacteristicTypes', 'ChartOfAccounts', 'ChartOfCalculationTypes', 'Document', 'InformationRegister')) {
- [Console]::Error.WriteLine("meta-decompile: тип '$objType' пока не поддержан (Catalog, ExchangePlan, ChartOfCharacteristicTypes, ChartOfAccounts, ChartOfCalculationTypes, Document, InformationRegister)"); exit 3
+if ($objType -notin @('Catalog', 'ExchangePlan', 'ChartOfCharacteristicTypes', 'ChartOfAccounts', 'ChartOfCalculationTypes', 'Document', 'InformationRegister', 'AccumulationRegister')) {
+ [Console]::Error.WriteLine("meta-decompile: тип '$objType' пока не поддержан (Catalog, ExchangePlan, ChartOfCharacteristicTypes, ChartOfAccounts, ChartOfCalculationTypes, Document, InformationRegister, AccumulationRegister)"); exit 3
}
$props = $objNode.SelectSingleNode('md:Properties', $nsm)
@@ -297,6 +297,7 @@ function Attr-ToDsl {
$v = & $en 'Master'; if ($v -eq 'true') { $extra['master'] = $true }
$v = & $en 'MainFilter'; if ($v -eq 'true') { $extra['mainFilter'] = $true }
$v = & $en 'DenyIncompleteValues'; if ($v -eq 'true') { $extra['denyIncompleteValues'] = $true }
+ $v = & $en 'UseInTotals'; if ($v -eq 'false') { $extra['useInTotals'] = $false } # дефолт true → захват при false
# MinValue/MaxValue — граница диапазона (omit при nil). Тип сохраняем: xs:string→строка, xs:decimal→число.
foreach ($mm in @('MinValue','MaxValue')) {
$mn = $ap.SelectSingleNode("md:$mm", $nsm)
@@ -516,6 +517,11 @@ if ($objType -eq 'InformationRegister') {
Add-BoolProp 'updateDataHistoryImmediatelyAfterWrite' 'UpdateDataHistoryImmediatelyAfterWrite' $false
Add-BoolProp 'executeAfterWriteDataHistoryVersionProcessing' 'ExecuteAfterWriteDataHistoryVersionProcessing' $false
}
+# AccumulationRegister-специфичные свойства: тип регистра, разделение итогов.
+if ($objType -eq 'AccumulationRegister') {
+ Add-EnumProp 'registerType' 'RegisterType' 'Balance'
+ Add-BoolProp 'enableTotalsSplitting' 'EnableTotalsSplitting' $true
+}
# Короткая форма поля: ..StandardAttribute.X / .Attribute.X → StandardAttribute.X / Attribute.X
# (Expand-DataPath компилятора разворачивает частичную форму обратно — dogfood резолвера).
@@ -704,8 +710,8 @@ if ($saNode) {
}
# Условный тип (Catalog): пустой $saMap = триггер блока. Не-условный (ExchangePlan): блок и так эмитится → пустой не пишем.
if ($saMap.Count -gt 0 -or ($stdConditionalTypes -contains $objType)) { $dsl['standardAttributes'] = $saMap }
-} elseif ($objType -eq 'InformationRegister') {
- # Регистр опускает all-default блок стандартных реквизитов (~5%, правило не выводимо) — компилятор эмитит его
+} elseif ($objType -in @('InformationRegister', 'AccumulationRegister')) {
+ # Регистр опускает all-default блок стандартных реквизитов (~5-9%, правило не выводимо) — компилятор эмитит его
# по дефолту, поэтому отсутствие фиксируем opt-out `standardAttributes:""` (дом-конвенция суппресса).
$dsl['standardAttributes'] = ''
}
diff --git a/docs/meta-dsl-spec.md b/docs/meta-dsl-spec.md
index a50cb7b5..78bdd1b8 100644
--- a/docs/meta-dsl-spec.md
+++ b/docs/meta-dsl-spec.md
@@ -836,13 +836,23 @@ choiceParameters/indexing/fullTextSearch/dataHistory/…, см. §3–4). При
| Поле JSON | Умолчание | XML элемент |
|-----------|----------|-------------|
-| `registerType` | `Balance` | RegisterType |
+| `registerType` | `Balance` | RegisterType (Balance/Turnovers) |
| `enableTotalsSplitting` | `true` | EnableTotalsSplitting |
-| `dataLockControlMode` | `Automatic` | DataLockControlMode |
+| `dataLockControlMode` | `Managed` | DataLockControlMode |
| `fullTextSearch` | `Use` | FullTextSearch |
-| `dimensions` | `[]` | → Dimension в ChildObjects |
-| `resources` | `[]` | → Resource в ChildObjects |
+| `useStandardCommands` | `true` | UseStandardCommands |
+| `comment` | пусто | Comment |
+| `listPresentation` / `extendedListPresentation` / `explanation` | пусто | презентации (ML) |
+| `defaultListForm` / `auxiliaryListForm` | пусто | *ListForm (ссылка на форму) |
+| `standardAttributes` | (блок всегда) | `""` — opt-out: подавить all-default блок (~9% регистров опускают) |
+| `dimensions` | `[]` | → Dimension в ChildObjects (богатый object-слой + `denyIncomplete`/`useInTotals`) |
+| `resources` | `[]` | → Resource в ChildObjects (богатый object-слой; без Indexing/DataHistory) |
| `attributes` | `[]` | → Attribute в ChildObjects |
+| `commands` | `[]` | → Command в ChildObjects (см. §7.1.3) |
+
+Измерения/ресурсы РН поддерживают полный object-слой реквизита (synonym/tooltip/comment/type/choiceParameters/…, §3–4).
+Признаки измерения — флаги shorthand (`denyIncomplete`, `nouseintotals`) ЛИБО object-ключи (`denyIncompleteValues`,
+`useInTotals`: bool, дефолт true). Ресурс РН НЕ имеет `` (только ``).
### 7.7 DefinedType
diff --git a/tests/skills/cases/meta-compile/snapshots/accumulation-register/AccumulationRegisters/ОстаткиТоваров.xml b/tests/skills/cases/meta-compile/snapshots/accumulation-register/AccumulationRegisters/ОстаткиТоваров.xml
index ca8e7b23..f3ce2359 100644
--- a/tests/skills/cases/meta-compile/snapshots/accumulation-register/AccumulationRegisters/ОстаткиТоваров.xml
+++ b/tests/skills/cases/meta-compile/snapshots/accumulation-register/AccumulationRegisters/ОстаткиТоваров.xml
@@ -147,7 +147,7 @@
- Automatic
+ Managed
Use
true