feat(form-decompile,form-compile): системные перечисления в choiceList + footerDataPath/footerText/editMode на labelField/radio + AdditionalColumns empty self-closing

Четыре находки из rt-iter2 (формы Хозрасчётный/ФормаСчёта, СпецификацииНоменклатуры):

1. **Системные перечисления в choiceList** (ent: namespace, напр. ent:AccountType=ВидСчёта):
   значение несёт xsi:type="ent:AccountType", компилятор эмитил xs:string (терял тип).
   Per-item ключ `valueType` (как у фильтра): декомпилятор сохраняет не-примитивный
   не-DesignTimeRef xsi:type, компилятор эмитит его вместо авто-детекта.
2. **footerDataPath/footerText на LabelField** — были только у InputField, на поле-надписи
   (колонка таблицы) терялись. Добавлены (decompile + compile, позиция по корпусу).
3. **editMode у RadioButtonField** — не ловился/не эмитился (форма ВидСчёта). Добавлен.
4. **Пустая AdditionalColumns** (table-ref без колонок) — компилятор эмитил пустую пару
   <AdditionalColumns table="X"></...>, платформа — self-closing. Фикс: self-closing при
   пустых columns.

Зеркало py. Обе формы → match. Кейсы radio-tumbler-strings (+ent:AccountType +editMode),
picture-field (labelField-колонка +footerDataPath/footerText), additional-columns
(+пустая группа) сертифицированы в 1С. Регресс 43/43 (ps1+py).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-06-11 21:32:04 +03:00
parent bdd38691aa
commit 330447c95f
11 changed files with 236 additions and 16 deletions
@@ -7,7 +7,8 @@
"type": "DataProcessor",
"name": "ДопКолонки",
"tabularSections": [
{ "name": "Прочее", "attributes": [ { "name": "Значение", "type": "String", "length": 50 } ] }
{ "name": "Прочее", "attributes": [ { "name": "Значение", "type": "String", "length": 50 } ] },
{ "name": "ЕщёТаблица", "attributes": [ { "name": "Поле", "type": "String", "length": 10 } ] }
]
},
"args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" }
@@ -30,7 +31,8 @@
{ "table": "Объект.Прочее", "columns": [
{ "name": "Доступность", "type": "boolean" },
{ "name": "Служебная", "type": "string" }
]}
]},
{ "table": "Объект.ЕщёТаблица", "columns": [] }
]
}
]
@@ -21,7 +21,8 @@
"columns": [
{ "input": "ТаблицаДанныхНоменклатура", "path": "ТаблицаДанных.Номенклатура" },
{ "picField": "ТаблицаДанныхКартинка", "path": "ТаблицаДанных.Картинка", "titleLocation": "none", "editMode": "EnterOnInput", "hyperlink": true, "shortcut": "Ctrl+S", "headerPicture": "StdPicture.ExecuteTask", "valuesPicture": { "src": "StdPicture.FilterCriterion", "loadTransparent": true, "transparentPixel": { "x": 7, "y": 3 } } },
{ "check": "ТаблицаДанныхКартинкаФлаг", "path": "ТаблицаДанных.Картинка", "title": "Флаг", "headerPicture": { "src": "StdPicture.ClearFilter", "loadTransparent": true } }
{ "check": "ТаблицаДанныхКартинкаФлаг", "path": "ТаблицаДанных.Картинка", "title": "Флаг", "headerPicture": { "src": "StdPicture.ClearFilter", "loadTransparent": true } },
{ "labelField": "ТаблицаДанныхИтог", "path": "ТаблицаДанных.Номенклатура", "editMode": "EnterOnInput", "footerDataPath": "ТаблицаДанных.Номенклатура", "footerText": "Итого" }
]}
],
"attributes": [
@@ -26,11 +26,20 @@
"radio": "ОтборСтрок",
"path": "ОтборСтрок",
"radioButtonType": "Tumbler",
"editMode": "EnterOnInput",
"warningOnEdit": "Смена отбора перезагрузит список",
"choiceList": [
{ "value": "Рекомендуемые" },
{ "value": "Все" }
]
},
{
"radio": "ВидСчета",
"choiceList": [
{ "value": "Active", "valueType": "ent:AccountType", "presentation": "Активный" },
{ "value": "Passive", "valueType": "ent:AccountType", "presentation": "Пассивный" },
{ "value": "ActivePassive", "valueType": "ent:AccountType", "presentation": "Активный/Пассивный" }
]
}
]
}
@@ -123,6 +123,100 @@
</Attribute>
</ChildObjects>
</TabularSection>
<TabularSection uuid="UUID-012">
<InternalInfo>
<xr:GeneratedType name="DataProcessorTabularSection.ДопКолонки.ЕщёТаблица" category="TabularSection">
<xr:TypeId>UUID-013</xr:TypeId>
<xr:ValueId>UUID-014</xr:ValueId>
</xr:GeneratedType>
<xr:GeneratedType name="DataProcessorTabularSectionRow.ДопКолонки.ЕщёТаблица" category="TabularSectionRow">
<xr:TypeId>UUID-015</xr:TypeId>
<xr:ValueId>UUID-016</xr:ValueId>
</xr:GeneratedType>
</InternalInfo>
<Properties>
<Name>ЕщёТаблица</Name>
<Synonym>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Ещё таблица</v8:content>
</v8:item>
</Synonym>
<Comment />
<ToolTip />
<FillChecking>DontCheck</FillChecking>
<StandardAttributes>
<xr:StandardAttribute name="LineNumber">
<xr:LinkByType />
<xr:FillChecking>DontCheck</xr:FillChecking>
<xr:MultiLine>false</xr:MultiLine>
<xr:FillFromFillingValue>false</xr:FillFromFillingValue>
<xr:CreateOnInput>Auto</xr:CreateOnInput>
<xr:MaxValue xsi:nil="true" />
<xr:ToolTip />
<xr:ExtendedEdit>false</xr:ExtendedEdit>
<xr:Format />
<xr:ChoiceForm />
<xr:QuickChoice>Auto</xr:QuickChoice>
<xr:ChoiceHistoryOnInput>Auto</xr:ChoiceHistoryOnInput>
<xr:EditFormat />
<xr:PasswordMode>false</xr:PasswordMode>
<xr:DataHistory>Use</xr:DataHistory>
<xr:MarkNegatives>false</xr:MarkNegatives>
<xr:MinValue xsi:nil="true" />
<xr:Synonym />
<xr:Comment />
<xr:FullTextSearch>Use</xr:FullTextSearch>
<xr:ChoiceParameterLinks />
<xr:FillValue xsi:nil="true" />
<xr:Mask />
<xr:ChoiceParameters />
</xr:StandardAttribute>
</StandardAttributes>
</Properties>
<ChildObjects>
<Attribute uuid="UUID-017">
<Properties>
<Name>Поле</Name>
<Synonym>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Поле</v8:content>
</v8:item>
</Synonym>
<Comment />
<Type>
<v8:Type>xs:string</v8:Type>
<v8:StringQualifiers>
<v8:Length>10</v8:Length>
<v8:AllowedLength>Variable</v8:AllowedLength>
</v8:StringQualifiers>
</Type>
<PasswordMode>false</PasswordMode>
<Format />
<EditFormat />
<ToolTip />
<MarkNegatives>false</MarkNegatives>
<Mask />
<MultiLine>false</MultiLine>
<ExtendedEdit>false</ExtendedEdit>
<MinValue xsi:nil="true" />
<MaxValue xsi:nil="true" />
<FillFromFillingValue>false</FillFromFillingValue>
<FillValue xsi:type="xs:string" />
<FillChecking>DontCheck</FillChecking>
<ChoiceFoldersAndItems>Items</ChoiceFoldersAndItems>
<ChoiceParameterLinks />
<ChoiceParameters />
<QuickChoice>Auto</QuickChoice>
<CreateOnInput>Auto</CreateOnInput>
<ChoiceForm />
<LinkByType />
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
</Properties>
</Attribute>
</ChildObjects>
</TabularSection>
</ChildObjects>
</DataProcessor>
</MetaDataObject>
@@ -43,6 +43,7 @@
</Type>
</Column>
</AdditionalColumns>
<AdditionalColumns table="Объект.ЕщёТаблица"/>
</Columns>
</Attribute>
</Attributes>
@@ -79,6 +79,19 @@
<ContextMenu name="ТаблицаДанныхКартинкаФлагКонтекстноеМеню" id="21"/>
<ExtendedTooltip name="ТаблицаДанныхКартинкаФлагРасширеннаяПодсказка" id="22"/>
</CheckBoxField>
<LabelField name="ТаблицаДанныхИтог" id="23">
<DataPath>ТаблицаДанных.Номенклатура</DataPath>
<EditMode>EnterOnInput</EditMode>
<FooterDataPath>ТаблицаДанных.Номенклатура</FooterDataPath>
<FooterText>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Итого</v8:content>
</v8:item>
</FooterText>
<ContextMenu name="ТаблицаДанныхИтогКонтекстноеМеню" id="24"/>
<ExtendedTooltip name="ТаблицаДанныхИтогРасширеннаяПодсказка" id="25"/>
</LabelField>
</ChildItems>
<Events>
<Event name="Selection">ТаблицаДанныхВыбор</Event>
@@ -86,13 +99,13 @@
</Table>
</ChildItems>
<Attributes>
<Attribute name="Объект" id="23">
<Attribute name="Объект" id="26">
<Type>
<v8:Type>cfg:DataProcessorObject.КартинкаВСтроке</v8:Type>
</Type>
<MainAttribute>true</MainAttribute>
</Attribute>
<Attribute name="ТаблицаДанных" id="24">
<Attribute name="ТаблицаДанных" id="27">
<Title>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -103,7 +116,7 @@
<v8:Type>v8:ValueTable</v8:Type>
</Type>
<Columns>
<Column name="Номенклатура" id="25">
<Column name="Номенклатура" id="28">
<Type>
<v8:Type>xs:string</v8:Type>
<v8:StringQualifiers>
@@ -112,7 +125,7 @@
</v8:StringQualifiers>
</Type>
</Column>
<Column name="Картинка" id="26">
<Column name="Картинка" id="29">
<Type>
<v8:Type>xs:boolean</v8:Type>
</Type>
@@ -11,6 +11,7 @@
<ChildItems>
<RadioButtonField name="ОтборСтрок" id="1">
<DataPath>ОтборСтрок</DataPath>
<EditMode>EnterOnInput</EditMode>
<TitleLocation>None</TitleLocation>
<RadioButtonType>Tumbler</RadioButtonType>
<ChoiceList>
@@ -50,15 +51,68 @@
<ContextMenu name="ОтборСтрокКонтекстноеМеню" id="2"/>
<ExtendedTooltip name="ОтборСтрокРасширеннаяПодсказка" id="3"/>
</RadioButtonField>
<RadioButtonField name="ВидСчета" id="4">
<Title>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Вид счета</v8:content>
</v8:item>
</Title>
<TitleLocation>None</TitleLocation>
<RadioButtonType>Auto</RadioButtonType>
<ChoiceList>
<xr:Item>
<xr:Presentation/>
<xr:CheckState>0</xr:CheckState>
<xr:Value xsi:type="FormChoiceListDesTimeValue">
<Presentation>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Активный</v8:content>
</v8:item>
</Presentation>
<Value xsi:type="ent:AccountType">Active</Value>
</xr:Value>
</xr:Item>
<xr:Item>
<xr:Presentation/>
<xr:CheckState>0</xr:CheckState>
<xr:Value xsi:type="FormChoiceListDesTimeValue">
<Presentation>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Пассивный</v8:content>
</v8:item>
</Presentation>
<Value xsi:type="ent:AccountType">Passive</Value>
</xr:Value>
</xr:Item>
<xr:Item>
<xr:Presentation/>
<xr:CheckState>0</xr:CheckState>
<xr:Value xsi:type="FormChoiceListDesTimeValue">
<Presentation>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Активный/Пассивный</v8:content>
</v8:item>
</Presentation>
<Value xsi:type="ent:AccountType">ActivePassive</Value>
</xr:Value>
</xr:Item>
</ChoiceList>
<ContextMenu name="ВидСчетаКонтекстноеМеню" id="5"/>
<ExtendedTooltip name="ВидСчетаРасширеннаяПодсказка" id="6"/>
</RadioButtonField>
</ChildItems>
<Attributes>
<Attribute name="Объект" id="4">
<Attribute name="Объект" id="7">
<Type>
<v8:Type>cfg:DataProcessorObject.ТестТумблер</v8:Type>
</Type>
<MainAttribute>true</MainAttribute>
</Attribute>
<Attribute name="ОтборСтрок" id="5">
<Attribute name="ОтборСтрок" id="8">
<Title>
<v8:item>
<v8:lang>ru</v8:lang>