mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-07-13 22:35:16 +03:00
feat(meta-compile,meta-decompile): поддержка типа ExchangePlan (План обмена) (v1.34/v0.23)
Первый тип после Catalog-пилота. Декомпилятор расширен Catalog-only → Catalog+
ExchangePlan (снят гейт, type из XML, тип-зависимые дефолты descriptionLength/
createOnInput/dataLockControlMode, EP-свойства distributedInfoBase/
includeConfigurationExtensions/dataHistory-триплет). Компилятор
Emit-ExchangePlanProperties переписан на общие хелперы (InputByString-derive,
Characteristics, BasedOn, DataLockFields, презентации, формы) в каноническом
порядке — был устаревший (хардкод, пропущенный Characteristics, кривой порядок).
StandardAttributes EP: профиль Description/Code=ShowError + EP условный (блок при
кастомизации; редкий all-default EP его опускает — условная модель это ловит).
Общие фиксы (не только EP):
• DSL-override стандартных реквизитов применялся лишь для условных типов —
снят гейт (if $sa), теперь и для не-условных.
• Доп./опциональные стандартные реквизиты вне фикс-списка (ExchangeDate у части
EP, легаси) — эмиссия по факту ключа; декомпилятор эмитит по присутствию.
• Пустой <Synonym/> реквизита ≠ авто-синоним из имени → декомпилятор пишет
synonym:"" (латентный баг: у Catalog 0/4018, всплыл на EP).
Роундтрип 42 EP: match 0→39, TOTAL 754→146 (−81%). Остаток (3) — принятые хвосты
(TS-LineNumber-опущение, FillValue-пробелы). Catalog не регрессировал (108/120).
Регресс 47/47 ps1+py, ps1↔py identical (8/8 EP). spec §7.2a, кейс exchange-plan.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# meta-compile v1.33 — Compile 1C metadata object from JSON
|
||||
# meta-compile v1.34 — Compile 1C metadata object from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -1037,6 +1037,11 @@ $script:stdAttrProfile = @{
|
||||
"Parent" = @{ FillFromFillingValue = "true" }
|
||||
"Description" = @{ FillChecking = "ShowError" }
|
||||
}
|
||||
# ExchangePlan: блок материализуется всегда (не условный), Наименование/Код → FillChecking=ShowError (корпус 40/38 из 41).
|
||||
"ExchangePlan" = @{
|
||||
"Description" = @{ FillChecking = "ShowError" }
|
||||
"Code" = @{ FillChecking = "ShowError" }
|
||||
}
|
||||
}
|
||||
|
||||
# $ov — hashtable переопределений (профиль + DSL) для полей: FillChecking, FillFromFillingValue,
|
||||
@@ -1097,7 +1102,7 @@ function Emit-StandardAttribute {
|
||||
# Прочие типы (не в множестве) → блок эмитится всегда (текущее поведение, пока их правило не выведено).
|
||||
# - stdAttrProfile[тип]: профиль материализованного блока (пусто = schema-дефолт), поверх — DSL-override.
|
||||
# Миграция типа = добавить его в stdAttrConditionalTypes + stdAttrProfile и переснять снэпшоты; КОД НЕ ТРОГАЕМ.
|
||||
$script:stdAttrConditionalTypes = @('Catalog')
|
||||
$script:stdAttrConditionalTypes = @('Catalog', 'ExchangePlan')
|
||||
function Emit-StandardAttributes {
|
||||
param([string]$indent, [string]$objectType)
|
||||
$attrs = $script:standardAttributesByType[$objectType]
|
||||
@@ -1106,11 +1111,15 @@ function Emit-StandardAttributes {
|
||||
$sa = $def.standardAttributes
|
||||
if ($conditional -and $null -eq $sa) { return } # условный тип без кастомизации → блока нет
|
||||
$profile = $script:stdAttrProfile[$objectType]; if (-not $profile) { $profile = @{} }
|
||||
# Доп. (опциональные) стандартные реквизиты вне фикс-списка типа — напр. ExchangeDate у части ПланОбмена
|
||||
# (легаси, присутствие не выводится из свойств). Эмитим по факту наличия ключа в DSL, ПЕРЕД фикс-списком (их позиция).
|
||||
$extra = @()
|
||||
if ($sa) { foreach ($k in $sa.PSObject.Properties.Name) { if ($attrs -notcontains $k) { $extra += $k } } }
|
||||
X "$indent<StandardAttributes>"
|
||||
foreach ($a in $attrs) {
|
||||
foreach ($a in ($extra + $attrs)) {
|
||||
$ov = @{}
|
||||
if ($profile.ContainsKey($a)) { foreach ($k in $profile[$a].Keys) { $ov[$k] = $profile[$a][$k] } }
|
||||
if ($conditional -and $sa) {
|
||||
if ($sa) { # DSL-override применяем всегда при наличии ключа (для не-условных типов тоже, напр. ExchangePlan)
|
||||
$d = $sa.$a
|
||||
if ($d) {
|
||||
if ($null -ne $d.synonym) { $ov['Synonym'] = $d.synonym } # строка ИЛИ {ru,en}
|
||||
@@ -2476,62 +2485,70 @@ function Emit-ExchangePlanProperties {
|
||||
|
||||
X "$i<Name>$(Esc-Xml $objName)</Name>"
|
||||
Emit-MLText $i "Synonym" $synonym
|
||||
X "$i<Comment/>"
|
||||
X "$i<UseStandardCommands>true</UseStandardCommands>"
|
||||
if ($def.comment) { X "$i<Comment>$(Esc-XmlText "$($def.comment)")</Comment>" } else { X "$i<Comment/>" }
|
||||
$useStdCmd = if (Get-BoolProp "useStandardCommands" $true) { "true" } else { "false" }
|
||||
X "$i<UseStandardCommands>$useStdCmd</UseStandardCommands>"
|
||||
|
||||
$codeLength = if ($null -ne $def.codeLength) { "$($def.codeLength)" } else { "9" }
|
||||
$descriptionLength = if ($null -ne $def.descriptionLength) { "$($def.descriptionLength)" } else { "100" }
|
||||
$descriptionLength = if ($null -ne $def.descriptionLength) { "$($def.descriptionLength)" } else { "150" }
|
||||
$codeAllowedLength = Get-EnumProp "CodeAllowedLength" "codeAllowedLength" "Variable"
|
||||
|
||||
X "$i<CodeLength>$codeLength</CodeLength>"
|
||||
X "$i<CodeAllowedLength>$codeAllowedLength</CodeAllowedLength>"
|
||||
X "$i<DescriptionLength>$descriptionLength</DescriptionLength>"
|
||||
X "$i<DefaultPresentation>AsDescription</DefaultPresentation>"
|
||||
X "$i<EditType>InDialog</EditType>"
|
||||
X "$i<DefaultPresentation>$(Get-EnumProp 'DefaultPresentation' 'defaultPresentation' 'AsDescription')</DefaultPresentation>"
|
||||
X "$i<EditType>$(Get-EnumProp 'EditType' 'editType' 'InDialog')</EditType>"
|
||||
$quickChoice = if ($def.quickChoice -eq $true) { "true" } else { "false" }
|
||||
X "$i<QuickChoice>$quickChoice</QuickChoice>"
|
||||
X "$i<ChoiceMode>$(Get-EnumProp 'ChoiceMode' 'choiceMode' 'BothWays')</ChoiceMode>"
|
||||
|
||||
# InputByString: override `inputByString` ЛИБО дефолт [Descr при D>0]+[Code при C>0] (prefix ExchangePlan).
|
||||
if (Test-DefKey 'inputByString') {
|
||||
$ibFields = @($def.inputByString | ForEach-Object { Expand-DataPath "$_" })
|
||||
} else {
|
||||
$ibFields = @()
|
||||
if ([int]$descriptionLength -gt 0) { $ibFields += "ExchangePlan.$objName.StandardAttribute.Description" }
|
||||
if ([int]$codeLength -gt 0) { $ibFields += "ExchangePlan.$objName.StandardAttribute.Code" }
|
||||
}
|
||||
Emit-FieldBlock $i "InputByString" $ibFields
|
||||
X "$i<SearchStringModeOnInputByString>$(Get-EnumProp 'SearchStringModeOnInputByString' 'searchStringModeOnInputByString' 'Begin')</SearchStringModeOnInputByString>"
|
||||
X "$i<FullTextSearchOnInputByString>DontUse</FullTextSearchOnInputByString>"
|
||||
X "$i<ChoiceDataGetModeOnInputByString>Directly</ChoiceDataGetModeOnInputByString>"
|
||||
Emit-FormRef $i "DefaultObjectForm" $def.defaultObjectForm
|
||||
Emit-FormRef $i "DefaultListForm" $def.defaultListForm
|
||||
Emit-FormRef $i "DefaultChoiceForm" $def.defaultChoiceForm
|
||||
Emit-FormRef $i "AuxiliaryObjectForm" $def.auxiliaryObjectForm
|
||||
Emit-FormRef $i "AuxiliaryListForm" $def.auxiliaryListForm
|
||||
Emit-FormRef $i "AuxiliaryChoiceForm" $def.auxiliaryChoiceForm
|
||||
|
||||
Emit-StandardAttributes $i "ExchangePlan"
|
||||
Emit-Characteristics $i $def.characteristics
|
||||
Emit-BasedOn $i $def.basedOn
|
||||
|
||||
$distributed = if ($def.distributedInfoBase -eq $true) { "true" } else { "false" }
|
||||
$includeExt = if ($def.includeConfigurationExtensions -eq $true) { "true" } else { "false" }
|
||||
X "$i<DistributedInfoBase>$distributed</DistributedInfoBase>"
|
||||
X "$i<IncludeConfigurationExtensions>$includeExt</IncludeConfigurationExtensions>"
|
||||
|
||||
X "$i<BasedOn/>"
|
||||
$quickChoice = if ($def.quickChoice -eq $true) { "true" } else { "false" }
|
||||
X "$i<QuickChoice>$quickChoice</QuickChoice>"
|
||||
X "$i<ChoiceMode>BothWays</ChoiceMode>"
|
||||
X "$i<InputByString>"
|
||||
X "$i`t<xr:Field>ExchangePlan.$objName.StandardAttribute.Description</xr:Field>"
|
||||
X "$i`t<xr:Field>ExchangePlan.$objName.StandardAttribute.Code</xr:Field>"
|
||||
X "$i</InputByString>"
|
||||
X "$i<SearchStringModeOnInputByString>Begin</SearchStringModeOnInputByString>"
|
||||
X "$i<FullTextSearchOnInputByString>DontUse</FullTextSearchOnInputByString>"
|
||||
X "$i<ChoiceDataGetModeOnInputByString>Directly</ChoiceDataGetModeOnInputByString>"
|
||||
X "$i<DefaultObjectForm/>"
|
||||
X "$i<DefaultListForm/>"
|
||||
X "$i<DefaultChoiceForm/>"
|
||||
X "$i<AuxiliaryObjectForm/>"
|
||||
X "$i<AuxiliaryListForm/>"
|
||||
X "$i<AuxiliaryChoiceForm/>"
|
||||
X "$i<IncludeHelpInContents>false</IncludeHelpInContents>"
|
||||
X "$i<DataLockFields/>"
|
||||
|
||||
$dataLockControlMode = Get-EnumProp "DataLockControlMode" "dataLockControlMode" "Automatic"
|
||||
X "$i<DataLockControlMode>$dataLockControlMode</DataLockControlMode>"
|
||||
|
||||
$fullTextSearch = Get-EnumProp "FullTextSearch" "fullTextSearch" "Use"
|
||||
X "$i<FullTextSearch>$fullTextSearch</FullTextSearch>"
|
||||
X "$i<CreateOnInput>$(Get-EnumProp 'CreateOnInput' 'createOnInput' 'DontUse')</CreateOnInput>"
|
||||
X "$i<ChoiceHistoryOnInput>$(Get-EnumProp 'ChoiceHistoryOnInput' 'choiceHistoryOnInput' 'Auto')</ChoiceHistoryOnInput>"
|
||||
$inclHelp = if (Get-BoolProp "includeHelpInContents" $false) { "true" } else { "false" }
|
||||
X "$i<IncludeHelpInContents>$inclHelp</IncludeHelpInContents>"
|
||||
$dlFields = if (Test-DefKey 'dataLockFields') { @($def.dataLockFields | ForEach-Object { Expand-DataPath "$_" }) } else { @() }
|
||||
Emit-FieldBlock $i "DataLockFields" $dlFields
|
||||
X "$i<DataLockControlMode>$(Get-EnumProp 'DataLockControlMode' 'dataLockControlMode' 'Managed')</DataLockControlMode>"
|
||||
X "$i<FullTextSearch>$(Get-EnumProp 'FullTextSearch' 'fullTextSearch' 'Use')</FullTextSearch>"
|
||||
|
||||
Emit-MLText $i "ObjectPresentation" $def.objectPresentation
|
||||
Emit-MLText $i "ExtendedObjectPresentation" $def.extendedObjectPresentation
|
||||
Emit-MLText $i "ListPresentation" $def.listPresentation
|
||||
Emit-MLText $i "ExtendedListPresentation" $def.extendedListPresentation
|
||||
Emit-MLText $i "Explanation" $def.explanation
|
||||
X "$i<CreateOnInput>DontUse</CreateOnInput>"
|
||||
X "$i<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>"
|
||||
X "$i<DataHistory>DontUse</DataHistory>"
|
||||
X "$i<UpdateDataHistoryImmediatelyAfterWrite>false</UpdateDataHistoryImmediatelyAfterWrite>"
|
||||
X "$i<ExecuteAfterWriteDataHistoryVersionProcessing>false</ExecuteAfterWriteDataHistoryVersionProcessing>"
|
||||
X "$i<DataHistory>$(Get-EnumProp 'DataHistory' 'dataHistory' 'DontUse')</DataHistory>"
|
||||
$updDH = if (Get-BoolProp "updateDataHistoryImmediatelyAfterWrite" $false) { "true" } else { "false" }
|
||||
X "$i<UpdateDataHistoryImmediatelyAfterWrite>$updDH</UpdateDataHistoryImmediatelyAfterWrite>"
|
||||
$execDH = if (Get-BoolProp "executeAfterWriteDataHistoryVersionProcessing" $false) { "true" } else { "false" }
|
||||
X "$i<ExecuteAfterWriteDataHistoryVersionProcessing>$execDH</ExecuteAfterWriteDataHistoryVersionProcessing>"
|
||||
}
|
||||
|
||||
function Emit-ChartOfCharacteristicTypesProperties {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# meta-compile v1.33 — Compile 1C metadata object from JSON
|
||||
# meta-compile v1.34 — Compile 1C metadata object from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -1050,7 +1050,12 @@ std_attr_profile = {
|
||||
'Owner': {'FillChecking': 'ShowError', 'FillFromFillingValue': 'true'},
|
||||
'Parent': {'FillFromFillingValue': 'true'},
|
||||
'Description': {'FillChecking': 'ShowError'},
|
||||
}
|
||||
},
|
||||
# ExchangePlan: блок при кастомизации; Наименование/Код → FillChecking=ShowError (корпус 40/38 из 41).
|
||||
'ExchangePlan': {
|
||||
'Description': {'FillChecking': 'ShowError'},
|
||||
'Code': {'FillChecking': 'ShowError'},
|
||||
},
|
||||
}
|
||||
|
||||
# ov — dict переопределений (профиль + DSL): FillChecking, FillFromFillingValue, Synonym,
|
||||
@@ -1116,7 +1121,7 @@ def emit_standard_attribute(indent, attr_name, ov=None):
|
||||
# Единый эмиттер блока StandardAttributes — поведение правят ДАННЫЕ, не форк кода (см. коммент в .ps1).
|
||||
# std_attr_conditional_types: типы, где блок только при кастомизации (DSL-ключ standardAttributes).
|
||||
# Прочие типы → блок всегда (текущее поведение). Миграция типа = +строчка в оба справочника + снэпшоты.
|
||||
std_attr_conditional_types = {'Catalog'}
|
||||
std_attr_conditional_types = {'Catalog', 'ExchangePlan'}
|
||||
def emit_standard_attributes(indent, object_type):
|
||||
attrs = standard_attributes_by_type.get(object_type)
|
||||
if not attrs:
|
||||
@@ -1126,10 +1131,13 @@ def emit_standard_attributes(indent, object_type):
|
||||
if conditional and sa is None:
|
||||
return
|
||||
profile = std_attr_profile.get(object_type, {})
|
||||
# Доп. (опциональные) стандартные реквизиты вне фикс-списка — напр. ExchangeDate у части ПланОбмена
|
||||
# (легаси, присутствие не выводится). Эмитим по факту ключа в DSL, ПЕРЕД фикс-списком (их позиция).
|
||||
extra = [k for k in sa if k not in attrs] if isinstance(sa, dict) else []
|
||||
X(f'{indent}<StandardAttributes>')
|
||||
for a in attrs:
|
||||
for a in extra + list(attrs):
|
||||
ov = dict(profile.get(a, {}))
|
||||
if conditional and isinstance(sa, dict):
|
||||
if isinstance(sa, dict):
|
||||
d = sa.get(a)
|
||||
if d:
|
||||
if d.get('synonym') is not None:
|
||||
@@ -2407,54 +2415,62 @@ def emit_exchange_plan_properties(indent):
|
||||
i = indent
|
||||
X(f'{i}<Name>{esc_xml(obj_name)}</Name>')
|
||||
emit_mltext(i, 'Synonym', synonym)
|
||||
X(f'{i}<Comment/>')
|
||||
X(f'{i}<UseStandardCommands>true</UseStandardCommands>')
|
||||
if defn.get('comment'):
|
||||
X(f'{i}<Comment>{esc_xml_text(str(defn["comment"]))}</Comment>')
|
||||
else:
|
||||
X(f'{i}<Comment/>')
|
||||
X(f'{i}<UseStandardCommands>{"true" if get_bool_prop("useStandardCommands", True) else "false"}</UseStandardCommands>')
|
||||
code_length = str(defn['codeLength']) if defn.get('codeLength') is not None else '9'
|
||||
description_length = str(defn['descriptionLength']) if defn.get('descriptionLength') is not None else '100'
|
||||
description_length = str(defn['descriptionLength']) if defn.get('descriptionLength') is not None else '150'
|
||||
code_allowed_length = get_enum_prop('CodeAllowedLength', 'codeAllowedLength', 'Variable')
|
||||
X(f'{i}<CodeLength>{code_length}</CodeLength>')
|
||||
X(f'{i}<CodeAllowedLength>{code_allowed_length}</CodeAllowedLength>')
|
||||
X(f'{i}<DescriptionLength>{description_length}</DescriptionLength>')
|
||||
X(f'{i}<DefaultPresentation>AsDescription</DefaultPresentation>')
|
||||
X(f'{i}<EditType>InDialog</EditType>')
|
||||
X(f'{i}<DefaultPresentation>{get_enum_prop("DefaultPresentation", "defaultPresentation", "AsDescription")}</DefaultPresentation>')
|
||||
X(f'{i}<EditType>{get_enum_prop("EditType", "editType", "InDialog")}</EditType>')
|
||||
X(f'{i}<QuickChoice>{"true" if defn.get("quickChoice") is True else "false"}</QuickChoice>')
|
||||
X(f'{i}<ChoiceMode>{get_enum_prop("ChoiceMode", "choiceMode", "BothWays")}</ChoiceMode>')
|
||||
# InputByString: override `inputByString` ЛИБО дефолт [Descr при D>0]+[Code при C>0] (prefix ExchangePlan).
|
||||
if 'inputByString' in defn:
|
||||
ib_fields = [expand_data_path(str(x)) for x in (defn.get('inputByString') or [])]
|
||||
else:
|
||||
ib_fields = []
|
||||
if int(description_length) > 0:
|
||||
ib_fields.append(f'ExchangePlan.{obj_name}.StandardAttribute.Description')
|
||||
if int(code_length) > 0:
|
||||
ib_fields.append(f'ExchangePlan.{obj_name}.StandardAttribute.Code')
|
||||
emit_field_block(i, 'InputByString', ib_fields)
|
||||
X(f'{i}<SearchStringModeOnInputByString>{get_enum_prop("SearchStringModeOnInputByString", "searchStringModeOnInputByString", "Begin")}</SearchStringModeOnInputByString>')
|
||||
X(f'{i}<FullTextSearchOnInputByString>DontUse</FullTextSearchOnInputByString>')
|
||||
X(f'{i}<ChoiceDataGetModeOnInputByString>Directly</ChoiceDataGetModeOnInputByString>')
|
||||
emit_form_ref(i, 'DefaultObjectForm', defn.get('defaultObjectForm'))
|
||||
emit_form_ref(i, 'DefaultListForm', defn.get('defaultListForm'))
|
||||
emit_form_ref(i, 'DefaultChoiceForm', defn.get('defaultChoiceForm'))
|
||||
emit_form_ref(i, 'AuxiliaryObjectForm', defn.get('auxiliaryObjectForm'))
|
||||
emit_form_ref(i, 'AuxiliaryListForm', defn.get('auxiliaryListForm'))
|
||||
emit_form_ref(i, 'AuxiliaryChoiceForm', defn.get('auxiliaryChoiceForm'))
|
||||
emit_standard_attributes(i, 'ExchangePlan')
|
||||
emit_characteristics(i, defn.get('characteristics'))
|
||||
emit_based_on(i, defn.get('basedOn'))
|
||||
distributed = 'true' if defn.get('distributedInfoBase') is True else 'false'
|
||||
include_ext = 'true' if defn.get('includeConfigurationExtensions') is True else 'false'
|
||||
X(f'{i}<DistributedInfoBase>{distributed}</DistributedInfoBase>')
|
||||
X(f'{i}<IncludeConfigurationExtensions>{include_ext}</IncludeConfigurationExtensions>')
|
||||
X(f'{i}<BasedOn/>')
|
||||
quick_choice = 'true' if defn.get('quickChoice') is True else 'false'
|
||||
X(f'{i}<QuickChoice>{quick_choice}</QuickChoice>')
|
||||
X(f'{i}<ChoiceMode>BothWays</ChoiceMode>')
|
||||
X(f'{i}<InputByString>')
|
||||
X(f'{i}\t<xr:Field>ExchangePlan.{obj_name}.StandardAttribute.Description</xr:Field>')
|
||||
X(f'{i}\t<xr:Field>ExchangePlan.{obj_name}.StandardAttribute.Code</xr:Field>')
|
||||
X(f'{i}</InputByString>')
|
||||
X(f'{i}<SearchStringModeOnInputByString>Begin</SearchStringModeOnInputByString>')
|
||||
X(f'{i}<FullTextSearchOnInputByString>DontUse</FullTextSearchOnInputByString>')
|
||||
X(f'{i}<ChoiceDataGetModeOnInputByString>Directly</ChoiceDataGetModeOnInputByString>')
|
||||
X(f'{i}<DefaultObjectForm/>')
|
||||
X(f'{i}<DefaultListForm/>')
|
||||
X(f'{i}<DefaultChoiceForm/>')
|
||||
X(f'{i}<AuxiliaryObjectForm/>')
|
||||
X(f'{i}<AuxiliaryListForm/>')
|
||||
X(f'{i}<AuxiliaryChoiceForm/>')
|
||||
X(f'{i}<IncludeHelpInContents>false</IncludeHelpInContents>')
|
||||
X(f'{i}<DataLockFields/>')
|
||||
data_lock_control_mode = get_enum_prop('DataLockControlMode', 'dataLockControlMode', 'Automatic')
|
||||
X(f'{i}<DataLockControlMode>{data_lock_control_mode}</DataLockControlMode>')
|
||||
full_text_search = get_enum_prop('FullTextSearch', 'fullTextSearch', 'Use')
|
||||
X(f'{i}<FullTextSearch>{full_text_search}</FullTextSearch>')
|
||||
X(f'{i}<CreateOnInput>{get_enum_prop("CreateOnInput", "createOnInput", "DontUse")}</CreateOnInput>')
|
||||
X(f'{i}<ChoiceHistoryOnInput>{get_enum_prop("ChoiceHistoryOnInput", "choiceHistoryOnInput", "Auto")}</ChoiceHistoryOnInput>')
|
||||
X(f'{i}<IncludeHelpInContents>{"true" if get_bool_prop("includeHelpInContents", False) else "false"}</IncludeHelpInContents>')
|
||||
dl_fields = [expand_data_path(str(x)) for x in defn.get('dataLockFields', [])] if 'dataLockFields' in defn else []
|
||||
emit_field_block(i, 'DataLockFields', dl_fields)
|
||||
X(f'{i}<DataLockControlMode>{get_enum_prop("DataLockControlMode", "dataLockControlMode", "Managed")}</DataLockControlMode>')
|
||||
X(f'{i}<FullTextSearch>{get_enum_prop("FullTextSearch", "fullTextSearch", "Use")}</FullTextSearch>')
|
||||
emit_mltext(i, 'ObjectPresentation', defn.get('objectPresentation'))
|
||||
emit_mltext(i, 'ExtendedObjectPresentation', defn.get('extendedObjectPresentation'))
|
||||
emit_mltext(i, 'ListPresentation', defn.get('listPresentation'))
|
||||
emit_mltext(i, 'ExtendedListPresentation', defn.get('extendedListPresentation'))
|
||||
emit_mltext(i, 'Explanation', defn.get('explanation'))
|
||||
X(f'{i}<CreateOnInput>DontUse</CreateOnInput>')
|
||||
X(f'{i}<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>')
|
||||
X(f'{i}<DataHistory>DontUse</DataHistory>')
|
||||
X(f'{i}<UpdateDataHistoryImmediatelyAfterWrite>false</UpdateDataHistoryImmediatelyAfterWrite>')
|
||||
X(f'{i}<ExecuteAfterWriteDataHistoryVersionProcessing>false</ExecuteAfterWriteDataHistoryVersionProcessing>')
|
||||
X(f'{i}<DataHistory>{get_enum_prop("DataHistory", "dataHistory", "DontUse")}</DataHistory>')
|
||||
X(f'{i}<UpdateDataHistoryImmediatelyAfterWrite>{"true" if get_bool_prop("updateDataHistoryImmediatelyAfterWrite", False) else "false"}</UpdateDataHistoryImmediatelyAfterWrite>')
|
||||
X(f'{i}<ExecuteAfterWriteDataHistoryVersionProcessing>{"true" if get_bool_prop("executeAfterWriteDataHistoryVersionProcessing", False) else "false"}</ExecuteAfterWriteDataHistoryVersionProcessing>')
|
||||
|
||||
def emit_chart_of_characteristic_types_properties(indent):
|
||||
i = indent
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# meta-decompile v0.22 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
|
||||
# meta-decompile v0.23 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
#
|
||||
# Пилот: только Catalog. Инверс meta-compile (omit-on-default: ключ эмитим только
|
||||
# Поддержаны: Catalog, ExchangePlan. Инверс meta-compile (omit-on-default: ключ эмитим только
|
||||
# когда значение в XML отличается от умолчания компилятора). Неподдерживаемый тип / не-MetaDataObject
|
||||
# root → exit 3 (ring3, как form-decompile).
|
||||
param(
|
||||
@@ -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 -ne 'Catalog') {
|
||||
[Console]::Error.WriteLine("meta-decompile: тип '$objType' пока не поддержан (пилот — только Catalog)"); exit 3
|
||||
if ($objType -notin @('Catalog', 'ExchangePlan')) {
|
||||
[Console]::Error.WriteLine("meta-decompile: тип '$objType' пока не поддержан (Catalog, ExchangePlan)"); exit 3
|
||||
}
|
||||
|
||||
$props = $objNode.SelectSingleNode('md:Properties', $nsm)
|
||||
@@ -261,8 +261,12 @@ function Attr-ToDsl {
|
||||
$ml = $ap.SelectSingleNode('md:MultiLine', $nsm); if ($ml -and $ml.InnerText -eq 'true') { $flags += 'multiline' }
|
||||
|
||||
# Синоним/подсказка (строка ru-only ИЛИ {ru,en}).
|
||||
$synVal = Get-MLValue ($ap.SelectSingleNode('md:Synonym', $nsm))
|
||||
$synNode = $ap.SelectSingleNode('md:Synonym', $nsm)
|
||||
$synVal = Get-MLValue $synNode
|
||||
$synCustom = $false
|
||||
# Пустой <Synonym/> (узел есть, значения нет) ≠ авто-синоним из имени → явный пустой (synonym:"").
|
||||
# У Catalog-реквизитов не встречается (0/4018), у части ExchangePlan — да.
|
||||
$synEmpty = ($synNode -and $null -eq $synVal)
|
||||
if ($synVal -is [string]) { if ($synVal -ne (Split-CamelWords $nm)) { $synCustom = $true } }
|
||||
elseif ($null -ne $synVal) { $synCustom = $true } # {ru,en} = всегда кастом
|
||||
$ttVal = Get-MLValue ($ap.SelectSingleNode('md:ToolTip', $nsm))
|
||||
@@ -343,10 +347,11 @@ function Attr-ToDsl {
|
||||
$cplArr = Parse-ChoiceParameterLinks $ap 'md:ChoiceParameterLinks'; if ($null -ne $cplArr) { $extra['choiceParameterLinks'] = $cplArr }
|
||||
$cpArr = Parse-ChoiceParameters $ap 'md:ChoiceParameters'; if ($null -ne $cpArr) { $extra['choiceParameters'] = $cpArr }
|
||||
|
||||
if ($synCustom -or ($null -ne $ttVal) -or $extra.Count -gt 0) {
|
||||
if ($synCustom -or $synEmpty -or ($null -ne $ttVal) -or $extra.Count -gt 0) {
|
||||
$o = [ordered]@{ name = $nm }
|
||||
if ($ts) { $o['type'] = $ts }
|
||||
if ($synCustom) { $o['synonym'] = $synVal }
|
||||
elseif ($synEmpty) { $o['synonym'] = '' }
|
||||
if ($null -ne $ttVal) { $o['tooltip'] = $ttVal }
|
||||
foreach ($k in $extra.Keys) { $o[$k] = $extra[$k] }
|
||||
if ($flags.Count -gt 0) { $o['flags'] = [System.Collections.ArrayList]@($flags) }
|
||||
@@ -358,7 +363,7 @@ function Attr-ToDsl {
|
||||
}
|
||||
|
||||
# === Сборка DSL ===
|
||||
$dsl = [ordered]@{ type = 'Catalog'; name = $objName }
|
||||
$dsl = [ordered]@{ type = $objType; name = $objName }
|
||||
|
||||
# Синоним объекта: строка ru-only ИЛИ {ru,en} (мультиязычно). Кастом → эмитим.
|
||||
$synVal = Get-MLValue ($props.SelectSingleNode('md:Synonym', $nsm))
|
||||
@@ -383,8 +388,12 @@ if ($ownersNode) {
|
||||
if ($items.Count -gt 0) { $dsl['owners'] = [System.Collections.ArrayList]@($items | ForEach-Object { if ($_ -match '^Catalog\.') { ($_ -split '\.', 2)[1] } else { $_ } }) }
|
||||
}
|
||||
Add-EnumProp 'subordinationUse' 'SubordinationUse' 'ToItems'
|
||||
# Тип-зависимые дефолты (компилятор задаёт их по типу — декомпилятор обязан зеркалить, иначе omit ≠ значению).
|
||||
$descrLenDef = if ($objType -eq 'ExchangePlan') { 150 } else { 25 }
|
||||
$createInpDef = if ($objType -eq 'ExchangePlan') { 'DontUse' } else { 'Use' }
|
||||
$dataLockDef = if ($objType -eq 'ExchangePlan') { 'Managed' } else { 'Automatic' }
|
||||
Add-IntProp 'codeLength' 'CodeLength' 9
|
||||
Add-IntProp 'descriptionLength' 'DescriptionLength' 25
|
||||
Add-IntProp 'descriptionLength' 'DescriptionLength' $descrLenDef
|
||||
Add-EnumProp 'codeType' 'CodeType' 'String'
|
||||
Add-EnumProp 'codeAllowedLength' 'CodeAllowedLength' 'Variable'
|
||||
Add-BoolProp 'autonumbering' 'Autonumbering' $true
|
||||
@@ -393,15 +402,23 @@ Add-EnumProp 'codeSeries' 'CodeSeries' 'WholeCatalog'
|
||||
Add-EnumProp 'defaultPresentation' 'DefaultPresentation' 'AsDescription'
|
||||
Add-BoolProp 'quickChoice' 'QuickChoice' $false
|
||||
Add-EnumProp 'choiceMode' 'ChoiceMode' 'BothWays'
|
||||
Add-EnumProp 'dataLockControlMode' 'DataLockControlMode' 'Automatic'
|
||||
Add-EnumProp 'dataLockControlMode' 'DataLockControlMode' $dataLockDef
|
||||
Add-EnumProp 'fullTextSearch' 'FullTextSearch' 'Use'
|
||||
Add-BoolProp 'useStandardCommands' 'UseStandardCommands' $true
|
||||
Add-EnumProp 'createOnInput' 'CreateOnInput' 'Use'
|
||||
Add-EnumProp 'createOnInput' 'CreateOnInput' $createInpDef
|
||||
Add-EnumProp 'editType' 'EditType' 'InDialog'
|
||||
Add-BoolProp 'includeHelpInContents' 'IncludeHelpInContents' $false
|
||||
Add-EnumProp 'choiceHistoryOnInput' 'ChoiceHistoryOnInput' 'Auto'
|
||||
Add-EnumProp 'predefinedDataUpdate' 'PredefinedDataUpdate' 'Auto'
|
||||
Add-EnumProp 'searchStringModeOnInputByString' 'SearchStringModeOnInputByString' 'Begin'
|
||||
# ExchangePlan-специфичные свойства (у Catalog этих тегов нет → блок не трогает его).
|
||||
if ($objType -eq 'ExchangePlan') {
|
||||
Add-BoolProp 'distributedInfoBase' 'DistributedInfoBase' $false
|
||||
Add-BoolProp 'includeConfigurationExtensions' 'IncludeConfigurationExtensions' $false
|
||||
Add-EnumProp 'dataHistory' 'DataHistory' 'DontUse'
|
||||
Add-BoolProp 'updateDataHistoryImmediatelyAfterWrite' 'UpdateDataHistoryImmediatelyAfterWrite' $false
|
||||
Add-BoolProp 'executeAfterWriteDataHistoryVersionProcessing' 'ExecuteAfterWriteDataHistoryVersionProcessing' $false
|
||||
}
|
||||
|
||||
# Короткая форма поля: <Type>.<Name>.StandardAttribute.X / .Attribute.X → StandardAttribute.X / Attribute.X
|
||||
# (Expand-DataPath компилятора разворачивает частичную форму обратно — dogfood резолвера).
|
||||
@@ -504,14 +521,32 @@ if ($charsNode) {
|
||||
}
|
||||
}
|
||||
|
||||
# --- StandardAttributes: блок есть ⟺ кастомизация ≥1 стандартного реквизита.
|
||||
# Захватываем ОТКЛОНЕНИЯ от профиля материализованного блока (профиль компилятор восстановит сам).
|
||||
# Профиль Catalog: Owner{FC=ShowError,FFV=true}, Parent{FFV=true}, Description{FC=ShowError}. ---
|
||||
$catStdProfile = @{
|
||||
'Owner' = @{ fillChecking = 'ShowError'; fillFromFillingValue = $true }
|
||||
'Parent' = @{ fillFromFillingValue = $true }
|
||||
'Description' = @{ fillChecking = 'ShowError' }
|
||||
# --- StandardAttributes: захватываем ОТКЛОНЕНИЯ от профиля материализованного блока (профиль компилятор
|
||||
# восстановит сам). Профиль зеркалит stdAttrProfile компилятора — по типу объекта.
|
||||
# Catalog: Owner{FC=ShowError,FFV=true}, Parent{FFV=true}, Description{FC=ShowError}.
|
||||
# ExchangePlan: Description{FC=ShowError}, Code{FC=ShowError} (блок всегда материализован). ---
|
||||
$stdProfileByType = @{
|
||||
'Catalog' = @{
|
||||
'Owner' = @{ fillChecking = 'ShowError'; fillFromFillingValue = $true }
|
||||
'Parent' = @{ fillFromFillingValue = $true }
|
||||
'Description' = @{ fillChecking = 'ShowError' }
|
||||
}
|
||||
'ExchangePlan' = @{
|
||||
'Description' = @{ fillChecking = 'ShowError' }
|
||||
'Code' = @{ fillChecking = 'ShowError' }
|
||||
}
|
||||
}
|
||||
$catStdProfile = if ($stdProfileByType.ContainsKey($objType)) { $stdProfileByType[$objType] } else { @{} }
|
||||
# Фикс-список стандартных реквизитов типа (зеркало standardAttributesByType компилятора) — чтобы отличать
|
||||
# доп./опциональные (напр. ExchangeDate у ПланОбмена), которые эмитим по факту присутствия даже all-default.
|
||||
$stdFixedByType = @{
|
||||
'Catalog' = @('PredefinedDataName','Predefined','Ref','DeletionMark','IsFolder','Owner','Parent','Description','Code')
|
||||
'ExchangePlan' = @('Ref','DeletionMark','Code','Description','ThisNode','SentNo','ReceivedNo')
|
||||
}
|
||||
$stdFixed = if ($stdFixedByType.ContainsKey($objType)) { $stdFixedByType[$objType] } else { @() }
|
||||
# Условные типы: блок эмитим-как-триггер даже пустым (материализуется при отклонении ≥1 реквизита от schema-default;
|
||||
# у ExchangePlan это почти всегда — Description/Code=ShowError; редкий all-default EP блок опускает).
|
||||
$stdConditionalTypes = @('Catalog', 'ExchangePlan')
|
||||
$saNode = $props.SelectSingleNode('md:StandardAttributes', $nsm)
|
||||
if ($saNode) {
|
||||
$saMap = [ordered]@{}
|
||||
@@ -543,9 +578,11 @@ if ($saNode) {
|
||||
$saCf = $sa.SelectSingleNode('xr:ChoiceForm', $nsm); if ($saCf -and $saCf.InnerText) { $ov['choiceForm'] = $saCf.InnerText }
|
||||
$saCpl = Parse-ChoiceParameterLinks $sa 'xr:ChoiceParameterLinks'; if ($null -ne $saCpl) { $ov['choiceParameterLinks'] = $saCpl }
|
||||
$saCp = Parse-ChoiceParameters $sa 'xr:ChoiceParameters'; if ($null -ne $saCp) { $ov['choiceParameters'] = $saCp }
|
||||
if ($ov.Count -gt 0) { $saMap[$an] = $ov }
|
||||
# Доп./опциональный реквизит (не в фикс-списке) — эмитим по присутствию даже без отклонений.
|
||||
if ($ov.Count -gt 0 -or ($stdFixed -notcontains $an)) { $saMap[$an] = $ov }
|
||||
}
|
||||
$dsl['standardAttributes'] = $saMap # даже пустой = блок есть (чистый профиль)
|
||||
# Условный тип (Catalog): пустой $saMap = триггер блока. Не-условный (ExchangePlan): блок и так эмитится → пустой не пишем.
|
||||
if ($saMap.Count -gt 0 -or ($stdConditionalTypes -contains $objType)) { $dsl['standardAttributes'] = $saMap }
|
||||
}
|
||||
|
||||
# --- ChildObjects: Attributes + TabularSections ---
|
||||
|
||||
@@ -594,6 +594,31 @@ omit-on-empty. Поля пишутся частичной формой (`Standar
|
||||
| `attributes` | `[]` | → Attribute в ChildObjects |
|
||||
| `tabularSections` | `{}` | → TabularSection в ChildObjects |
|
||||
|
||||
### 7.2a ExchangePlan (План обмена)
|
||||
|
||||
Близок к Catalog (без иерархии/владельцев/кодогенерации), плюс два своих флага. Общий с Catalog слой: `synonym`,
|
||||
`comment`, `useStandardCommands`, `codeLength`/`codeAllowedLength`/`descriptionLength`, `defaultPresentation`, `editType`,
|
||||
`quickChoice`, `choiceMode`, `inputByString` (§7.1.5, дефолт [Наименование]+[Код] по длинам), формы (`defaultObjectForm`/
|
||||
`defaultListForm`/`defaultChoiceForm`/`auxiliary*`), `standardAttributes` (§7.1.1), `characteristics` (§7.1.4), `basedOn`,
|
||||
`dataLockFields`, презентации, `choiceHistoryOnInput`, `includeHelpInContents`.
|
||||
|
||||
| Поле JSON | Умолчание | XML элемент |
|
||||
|-----------|----------|-------------|
|
||||
| `distributedInfoBase` | `false` | DistributedInfoBase (РИБ — распределённая ИБ) |
|
||||
| `includeConfigurationExtensions` | `false` | IncludeConfigurationExtensions |
|
||||
| `createOnInput` | `DontUse` | CreateOnInput *(отличие от Catalog: там `Use`)* |
|
||||
| `dataLockControlMode` | `Managed` | DataLockControlMode *(отличие от Catalog: там `Automatic`)* |
|
||||
| `dataHistory` | `DontUse` | DataHistory |
|
||||
| `updateDataHistoryImmediatelyAfterWrite` | `false` | UpdateDataHistoryImmediatelyAfterWrite |
|
||||
| `executeAfterWriteDataHistoryVersionProcessing` | `false` | ExecuteAfterWriteDataHistoryVersionProcessing |
|
||||
| `descriptionLength` | `150` | DescriptionLength *(отличие от Catalog: там `25`)* |
|
||||
| `attributes` / `tabularSections` | `[]` / `{}` | → ChildObjects |
|
||||
|
||||
Стандартные реквизиты EP: Ref, DeletionMark, Code, Description, ThisNode, SentNo, ReceivedNo (профиль материализованного
|
||||
блока: Наименование/Код → FillChecking=ShowError). Блок **условный** (как Catalog): материализуется при кастомизации —
|
||||
ключ `standardAttributes`. Опциональный легаси-реквизит `ExchangeDate` (часть планов) поддержан как «доп.» член
|
||||
`standardAttributes` (эмитится по факту наличия ключа, вне фикс-списка).
|
||||
|
||||
### 7.3 Enum
|
||||
|
||||
| Поле JSON | Умолчание | XML элемент |
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
"input": {
|
||||
"type": "ExchangePlan",
|
||||
"name": "ОбменСФилиалами",
|
||||
"comment": "обмен данными с филиалами",
|
||||
"codeLength": 9,
|
||||
"descriptionLength": 100,
|
||||
"distributedInfoBase": true,
|
||||
"standardAttributes": { "Description": { "synonym": "Имя узла" }, "Code": { "fillChecking": "ShowError" } },
|
||||
"attributes": ["ПутьКФайлу: String(500)"],
|
||||
"tabularSections": [
|
||||
{
|
||||
|
||||
+29
-23
@@ -32,13 +32,28 @@
|
||||
<v8:content>Обмен сфилиалами</v8:content>
|
||||
</v8:item>
|
||||
</Synonym>
|
||||
<Comment/>
|
||||
<Comment>обмен данными с филиалами</Comment>
|
||||
<UseStandardCommands>true</UseStandardCommands>
|
||||
<CodeLength>9</CodeLength>
|
||||
<CodeAllowedLength>Variable</CodeAllowedLength>
|
||||
<DescriptionLength>100</DescriptionLength>
|
||||
<DefaultPresentation>AsDescription</DefaultPresentation>
|
||||
<EditType>InDialog</EditType>
|
||||
<QuickChoice>false</QuickChoice>
|
||||
<ChoiceMode>BothWays</ChoiceMode>
|
||||
<InputByString>
|
||||
<xr:Field>ExchangePlan.ОбменСФилиалами.StandardAttribute.Description</xr:Field>
|
||||
<xr:Field>ExchangePlan.ОбменСФилиалами.StandardAttribute.Code</xr:Field>
|
||||
</InputByString>
|
||||
<SearchStringModeOnInputByString>Begin</SearchStringModeOnInputByString>
|
||||
<FullTextSearchOnInputByString>DontUse</FullTextSearchOnInputByString>
|
||||
<ChoiceDataGetModeOnInputByString>Directly</ChoiceDataGetModeOnInputByString>
|
||||
<DefaultObjectForm/>
|
||||
<DefaultListForm/>
|
||||
<DefaultChoiceForm/>
|
||||
<AuxiliaryObjectForm/>
|
||||
<AuxiliaryListForm/>
|
||||
<AuxiliaryChoiceForm/>
|
||||
<StandardAttributes>
|
||||
<xr:StandardAttribute name="Ref">
|
||||
<xr:LinkByType/>
|
||||
@@ -94,7 +109,7 @@
|
||||
</xr:StandardAttribute>
|
||||
<xr:StandardAttribute name="Code">
|
||||
<xr:LinkByType/>
|
||||
<xr:FillChecking>DontCheck</xr:FillChecking>
|
||||
<xr:FillChecking>ShowError</xr:FillChecking>
|
||||
<xr:MultiLine>false</xr:MultiLine>
|
||||
<xr:FillFromFillingValue>false</xr:FillFromFillingValue>
|
||||
<xr:CreateOnInput>Auto</xr:CreateOnInput>
|
||||
@@ -120,7 +135,7 @@
|
||||
</xr:StandardAttribute>
|
||||
<xr:StandardAttribute name="Description">
|
||||
<xr:LinkByType/>
|
||||
<xr:FillChecking>DontCheck</xr:FillChecking>
|
||||
<xr:FillChecking>ShowError</xr:FillChecking>
|
||||
<xr:MultiLine>false</xr:MultiLine>
|
||||
<xr:FillFromFillingValue>false</xr:FillFromFillingValue>
|
||||
<xr:CreateOnInput>Auto</xr:CreateOnInput>
|
||||
@@ -136,7 +151,12 @@
|
||||
<xr:DataHistory>Use</xr:DataHistory>
|
||||
<xr:MarkNegatives>false</xr:MarkNegatives>
|
||||
<xr:MinValue xsi:nil="true"/>
|
||||
<xr:Synonym/>
|
||||
<xr:Synonym>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Имя узла</v8:content>
|
||||
</v8:item>
|
||||
</xr:Synonym>
|
||||
<xr:Comment/>
|
||||
<xr:FullTextSearch>Use</xr:FullTextSearch>
|
||||
<xr:ChoiceParameterLinks/>
|
||||
@@ -223,35 +243,21 @@
|
||||
<xr:ChoiceParameters/>
|
||||
</xr:StandardAttribute>
|
||||
</StandardAttributes>
|
||||
<Characteristics/>
|
||||
<BasedOn/>
|
||||
<DistributedInfoBase>true</DistributedInfoBase>
|
||||
<IncludeConfigurationExtensions>false</IncludeConfigurationExtensions>
|
||||
<BasedOn/>
|
||||
<QuickChoice>false</QuickChoice>
|
||||
<ChoiceMode>BothWays</ChoiceMode>
|
||||
<InputByString>
|
||||
<xr:Field>ExchangePlan.ОбменСФилиалами.StandardAttribute.Description</xr:Field>
|
||||
<xr:Field>ExchangePlan.ОбменСФилиалами.StandardAttribute.Code</xr:Field>
|
||||
</InputByString>
|
||||
<SearchStringModeOnInputByString>Begin</SearchStringModeOnInputByString>
|
||||
<FullTextSearchOnInputByString>DontUse</FullTextSearchOnInputByString>
|
||||
<ChoiceDataGetModeOnInputByString>Directly</ChoiceDataGetModeOnInputByString>
|
||||
<DefaultObjectForm/>
|
||||
<DefaultListForm/>
|
||||
<DefaultChoiceForm/>
|
||||
<AuxiliaryObjectForm/>
|
||||
<AuxiliaryListForm/>
|
||||
<AuxiliaryChoiceForm/>
|
||||
<CreateOnInput>DontUse</CreateOnInput>
|
||||
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
|
||||
<IncludeHelpInContents>false</IncludeHelpInContents>
|
||||
<DataLockFields/>
|
||||
<DataLockControlMode>Automatic</DataLockControlMode>
|
||||
<DataLockControlMode>Managed</DataLockControlMode>
|
||||
<FullTextSearch>Use</FullTextSearch>
|
||||
<ObjectPresentation/>
|
||||
<ExtendedObjectPresentation/>
|
||||
<ListPresentation/>
|
||||
<ExtendedListPresentation/>
|
||||
<Explanation/>
|
||||
<CreateOnInput>DontUse</CreateOnInput>
|
||||
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
|
||||
<DataHistory>DontUse</DataHistory>
|
||||
<UpdateDataHistoryImmediatelyAfterWrite>false</UpdateDataHistoryImmediatelyAfterWrite>
|
||||
<ExecuteAfterWriteDataHistoryVersionProcessing>false</ExecuteAfterWriteDataHistoryVersionProcessing>
|
||||
|
||||
Reference in New Issue
Block a user