mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-08-18 01:00:24 +03:00
feat(mxl-compile,mxl-decompile): значение ячейки-поля ввода и настройки элемента управления
Ключ ячейки value несёт значение, набранное в поле ввода, ключ control — сериализованные настройки самого элемента управления. Оба живут у ячейки, а не в палитре формата: у двух ячеек с одинаковым оформлением значения разные. Тип значения выражается литералом JSON и приведения к объявленному типу НЕ делается. Так пишет платформа: ссылочный и составной тип она хранит строкой, а при смене типа ячейки прежнее значение не переписывает — на корпусе 560 ячеек объявлены числом, но несут строку. Приведение здесь означало бы переписывать данные при пересборке. Дата литералом JSON не выражается, поэтому едет строкой и читается как дата только у ячейки, объявленной датой. Настройки элемента управления возим дословно: 26 370 вхождений корпуса дают всего 163 различных блоба, разбирать структуру незачем. Переводы строк внутри блоба приводим к LF на чтении — XML-парсеры двух портов нормализуют их по-разному, и без этого порты давали разный JSON на одном файле. Стенд СЗначениями снова собирается байт в байт обоими портами: фикстура обновлена до версии со значениями, флажком и блобом настроек. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
66bb285636
commit
43d2f660da
@@ -59,7 +59,7 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/mxl-compile.ps1" -J
|
||||
styles: { name: { font, horizontalAlignment, verticalAlignment, textPlacement,
|
||||
backColor, textColor, border, borderColor, format, hidden } },
|
||||
areas: [{ name, columnSet, rows: [{ height, hidden, rowStyle, cells: [
|
||||
{ col, span, rowspan, style, param, detail, text, template, valueType, controlType }
|
||||
{ col, span, rowspan, style, param, detail, text, template, valueType, controlType, value }
|
||||
]}]}],
|
||||
namedAreas: [{ name, rows, cols }],
|
||||
columnSets: { name: { columns, columnWidths, columnStyles } }
|
||||
@@ -80,7 +80,7 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/mxl-compile.ps1" -J
|
||||
- `col` — 1-based позиция колонки
|
||||
- `rowspan` — объединение строк вниз (rowStyle учитывает занятые ячейки)
|
||||
- Содержимое ячейки задаётся одним из ключей: `param` — параметр заполнения, `text` — статический текст, `template` — текст со вставками `[Параметр]`
|
||||
- `valueType` делает ячейку полем ввода (`"Number(15,3,nonneg)"`, `"String(10)"`, `"CatalogRef.Валюты"`, составной через ` + `); текста в такой ячейке быть не может, а `controlType: "checkbox"` меняет поле ввода на флажок
|
||||
- `valueType` делает ячейку полем ввода (`"Number(15,3,nonneg)"`, `"String(10)"`, `"CatalogRef.Валюты"`, составной через ` + `); текста в такой ячейке быть не может, а `controlType: "checkbox"` меняет поле ввода на флажок; `value` — значение в поле
|
||||
|
||||
Двухуровневая шапка массивами:
|
||||
```json
|
||||
|
||||
@@ -152,7 +152,8 @@
|
||||
| `{ ... }` | Обычная ячейка **без** `col`; нужна для `style`, `detail`, `template` |
|
||||
|
||||
Объект-элемент трактуется по его ключам: если среди них есть ключ ячейки (`span`, `rowspan`,
|
||||
`style`, `param`, `detail`, `text`, `template`, `valueType`, `controlType`) — объект описывает
|
||||
`style`, `param`, `detail`, `text`, `template`, `valueType`, `controlType`, `value`) — объект
|
||||
описывает
|
||||
свойства ячейки. Иначе он целиком считается её текстом, а его ключи — идентификаторами языков.
|
||||
|
||||
```json
|
||||
@@ -184,6 +185,7 @@
|
||||
| `template` | нет | — | Шаблонный текст с `[Параметр]`. Строка или объект, как `text` |
|
||||
| `valueType` | нет | — | Тип значения: ячейка становится полем ввода (см. ниже) |
|
||||
| `controlType` | нет | `input` | Элемент управления поля ввода: `input` или `checkbox`. Только вместе с `valueType` |
|
||||
| `value` | нет | — | Значение в поле ввода. Только вместе с `valueType` |
|
||||
|
||||
### Содержимое ячейки
|
||||
|
||||
@@ -248,6 +250,20 @@
|
||||
|
||||
Пустой тип `"valueType": ""` — «ячейка содержит значение», но тип не ограничен.
|
||||
|
||||
Значение поля ввода задаётся ключом `value`, и его тип выражается литералом JSON: строка —
|
||||
строкой, число — числом, булево — `true`/`false`. Приведения к объявленному типу **не
|
||||
происходит**: платформа хранит значение с его собственным типом и совпадать с объявленным он
|
||||
не обязан (у ссылочного и составного типа значение всегда строковое). Пустая строка означает
|
||||
пустое значение объявленного типа. Дата записывается строкой в формате `ГГГГ-ММ-ДДTчч:мм:сс`
|
||||
и читается как дата только у ячейки, объявленной датой.
|
||||
|
||||
```json
|
||||
{ "col": 1, "valueType": "Number(15,3)", "value": 12.5 }
|
||||
{ "col": 2, "valueType": "String(10)", "value": "5" }
|
||||
{ "col": 3, "valueType": "Boolean", "value": true }
|
||||
{ "col": 4, "valueType": "DateTime", "value": "" }
|
||||
```
|
||||
|
||||
`controlType` нужен редко: умолчание платформы — поле ввода, и оно применяется ко всем типам,
|
||||
включая `Boolean`. Флажок задаётся явно. Значение `"none"` (тега элемента управления нет вовсе) —
|
||||
форма раундтрипа, для ручного авторинга не нужна.
|
||||
@@ -266,8 +282,6 @@ DSL описывает не все конструкции табличного
|
||||
round-trip** (`/mxl-decompile` → `/mxl-compile`): в JSON оно не попадает, в сгенерированный
|
||||
XML не возвращается.
|
||||
|
||||
- начальное значение ячейки-поля ввода и сериализованные настройки её элемента управления
|
||||
(тип значения при этом переживает цикл);
|
||||
- объединения, не привязанные к ячейке (по всей высоте или ширине документа);
|
||||
- рисунки и картинки, в том числе штрихкоды, и примечания к ячейкам;
|
||||
- группировки строк и колонок;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# mxl-compile v1.41 — Compile 1C spreadsheet from JSON
|
||||
# mxl-compile v1.42 — Compile 1C spreadsheet from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -854,6 +854,14 @@ function Get-CellValueProps {
|
||||
[Console]::Error.WriteLine("Cell 'controlType' requires 'valueType' ($where)")
|
||||
exit 1
|
||||
}
|
||||
if ($null -ne $cell.PSObject.Properties['value'] -and $null -ne $cell.value) {
|
||||
[Console]::Error.WriteLine("Cell 'value' requires 'valueType' ($where)")
|
||||
exit 1
|
||||
}
|
||||
if ($null -ne $cell.control -and "$($cell.control)" -ne '') {
|
||||
[Console]::Error.WriteLine("Cell 'control' requires 'valueType' ($where)")
|
||||
exit 1
|
||||
}
|
||||
return $props
|
||||
}
|
||||
# Ячейка, содержащая значение, текста не несёт: платформа этого не допускает, и в корпусе
|
||||
@@ -885,6 +893,46 @@ function Get-CellValueProps {
|
||||
return $props
|
||||
}
|
||||
|
||||
# Значение ячейки-поля ввода — тег САМОЙ ячейки (<v>), а не запись палитры: у двух ячеек
|
||||
# с одинаковым оформлением значения разные, и в дедупликацию формата оно не входит.
|
||||
# Тип значения берём из литерала JSON и приведения НЕ делаем: платформа хранит значение с его
|
||||
# собственным типом, и совпадать с объявленным он не обязан (ссылочный и составной тип она
|
||||
# держит строкой, а при смене типа ячейки прежнее значение не переписывает).
|
||||
function Get-CellValue {
|
||||
param($cell, [string]$canonType, [string]$where)
|
||||
$prop = $cell.PSObject.Properties['value']
|
||||
if ($null -eq $prop -or $null -eq $prop.Value) { return $null }
|
||||
$v = $prop.Value
|
||||
|
||||
if ($v -is [bool]) {
|
||||
return @{ Type = 'xs:boolean'; Text = $(if ($v) { 'true' } else { 'false' }) }
|
||||
}
|
||||
if ($v -is [int] -or $v -is [long] -or $v -is [double] -or $v -is [decimal]) {
|
||||
return @{ Type = 'xs:decimal'; Text = (Format-Num $v) }
|
||||
}
|
||||
|
||||
$s = "$v"
|
||||
if ($s -ne '') {
|
||||
# Дата литералом JSON не выражается, поэтому едет строкой. Читаем её как дату только
|
||||
# у ячейки, объявленной датой: там платформа других значений не держит.
|
||||
if (($canonType -ceq 'Date' -or $canonType -ceq 'DateTime' -or $canonType -ceq 'Time') -and
|
||||
$s -match '^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$') {
|
||||
return @{ Type = 'xs:dateTime'; Text = $s }
|
||||
}
|
||||
return @{ Type = 'xs:string'; Text = $s }
|
||||
}
|
||||
|
||||
# Пустая строка — пустое значение ОБЪЯВЛЕННОГО типа: платформа так и пишет, когда текст
|
||||
# ячейки к типу не привёлся. Ссылочный и составной тип пустого значения своего вида не
|
||||
# имеют — там остаётся пустая строка.
|
||||
if ($canonType -ceq 'Boolean') { return @{ Type = 'xs:boolean'; Text = 'false' } }
|
||||
if ($canonType -like 'Number(*') { return @{ Type = 'xs:decimal'; Text = '0' } }
|
||||
if ($canonType -ceq 'Date' -or $canonType -ceq 'DateTime' -or $canonType -ceq 'Time') {
|
||||
return @{ Type = 'xs:dateTime'; Text = '0001-01-01T00:00:00' }
|
||||
}
|
||||
return @{ Type = 'xs:string'; Text = '' }
|
||||
}
|
||||
|
||||
# --- 6. Format palette builder ---
|
||||
|
||||
$formatRegistry = [ordered]@{} # key -> hashtable with properties
|
||||
@@ -1140,7 +1188,7 @@ function Set-CellProp {
|
||||
function Test-CellObject {
|
||||
param($el)
|
||||
$cellKeys = @('col', 'span', 'rowspan', 'style', 'param', 'detail', 'text', 'template',
|
||||
'valueType', 'controlType')
|
||||
'valueType', 'controlType', 'value', 'control')
|
||||
foreach ($p in $el.PSObject.Properties) {
|
||||
if ($cellKeys -contains $p.Name) { return $true }
|
||||
}
|
||||
@@ -1613,6 +1661,8 @@ foreach ($area in $def.areas) {
|
||||
Detail = $cell.detail
|
||||
Text = $cell.text
|
||||
Template = $cell.template
|
||||
Value = $(if ($vp.Count -gt 0) { Get-CellValue $cell "$($vp['valueType'])" "area `"$areaName`", row $($localRow + 1)" } else { $null })
|
||||
Control = $(if ($vp.Count -gt 0) { $cell.control } else { $null })
|
||||
}
|
||||
$rowCells += $cellInfo
|
||||
|
||||
@@ -1719,6 +1769,22 @@ foreach ($area in $def.areas) {
|
||||
|
||||
if ($null -ne $cellInfo.Template) { Emit-CellText $cellInfo.Template }
|
||||
|
||||
if ($null -ne $cellInfo.Value) {
|
||||
X "`t`t`t`t`t<v xsi:type=`"$($cellInfo.Value.Type)`">$(Esc-XmlText $cellInfo.Value.Text)</v>"
|
||||
}
|
||||
|
||||
# Настройки элемента управления платформа сериализует в base64 и держит у самой
|
||||
# ячейки. Структуру не разбираем — возим дословно, иначе она теряется.
|
||||
if ($null -ne $cellInfo.Control -and "$($cellInfo.Control)" -ne '') {
|
||||
# Блоб платформа переносит по строкам, а X дописывает перевод строки сам —
|
||||
# поэтому каждую строку блоба пишем отдельным вызовом, иначе перевод строки
|
||||
# внутри значения разошёлся бы с остальным файлом.
|
||||
$parts = @("$($cellInfo.Control)" -split "`r?`n")
|
||||
$parts[0] = "`t`t`t`t`t<control xsi:type=`"xs:base64Binary`">$($parts[0])"
|
||||
$parts[-1] = "$($parts[-1])</control>"
|
||||
foreach ($p in $parts) { X $p }
|
||||
}
|
||||
|
||||
# Расшифровка от параметра заполнения не зависит: на корпусе 20 404 ячейки несут
|
||||
# её БЕЗ параметра (у текста, у пустой ячейки, у поля ввода) против 8 582 с ним.
|
||||
# Пока она стояла внутри ветки параметра, две трети расшифровок терялись молча.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# mxl-compile v1.41 — Compile 1C spreadsheet from JSON
|
||||
# mxl-compile v1.42 — Compile 1C spreadsheet from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import hashlib
|
||||
@@ -644,6 +644,45 @@ def emit_value_type_content(lines, indent, canon_type):
|
||||
lines.extend(quals[q])
|
||||
|
||||
|
||||
def cell_value(cell, canon_type, where):
|
||||
"""Значение ячейки-поля ввода — тег САМОЙ ячейки (<v>), а не запись палитры: у двух ячеек
|
||||
с одинаковым оформлением значения разные, и в дедупликацию формата оно не входит.
|
||||
Тип значения берём из литерала JSON и приведения НЕ делаем: платформа хранит значение с его
|
||||
собственным типом, и совпадать с объявленным он не обязан (ссылочный и составной тип она
|
||||
держит строкой, а при смене типа ячейки прежнее значение не переписывает)."""
|
||||
if 'value' not in cell:
|
||||
return None
|
||||
v = cell.get('value')
|
||||
if v is None:
|
||||
return None
|
||||
if isinstance(v, bool):
|
||||
return {'Type': 'xs:boolean', 'Text': 'true' if v else 'false'}
|
||||
if isinstance(v, (int, float)):
|
||||
# 8.0 обязано дать "8", как в PS-порту: там Convert.ToString инвариантной культурой
|
||||
# хвостовой .0 не пишет, а str() в py — пишет.
|
||||
text = str(int(v)) if (isinstance(v, float) and v.is_integer()) else str(v)
|
||||
return {'Type': 'xs:decimal', 'Text': text}
|
||||
|
||||
s = str(v)
|
||||
if s != '':
|
||||
# Дата литералом JSON не выражается, поэтому едет строкой. Читаем её как дату только
|
||||
# у ячейки, объявленной датой: там платформа других значений не держит.
|
||||
if canon_type in ('Date', 'DateTime', 'Time') and re.match(r'^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$', s):
|
||||
return {'Type': 'xs:dateTime', 'Text': s}
|
||||
return {'Type': 'xs:string', 'Text': s}
|
||||
|
||||
# Пустая строка — пустое значение ОБЪЯВЛЕННОГО типа: платформа так и пишет, когда текст
|
||||
# ячейки к типу не привёлся. Ссылочный и составной тип пустого значения своего вида не
|
||||
# имеют — там остаётся пустая строка.
|
||||
if canon_type == 'Boolean':
|
||||
return {'Type': 'xs:boolean', 'Text': 'false'}
|
||||
if canon_type.startswith('Number('):
|
||||
return {'Type': 'xs:decimal', 'Text': '0'}
|
||||
if canon_type in ('Date', 'DateTime', 'Time'):
|
||||
return {'Type': 'xs:dateTime', 'Text': '0001-01-01T00:00:00'}
|
||||
return {'Type': 'xs:string', 'Text': ''}
|
||||
|
||||
|
||||
def cell_value_props(cell, where):
|
||||
"""Свойства значения ячейки — пустой набор, если ячейка обычная. Считаются ОДНОЙ функцией:
|
||||
пре-проход регистрации палитры и генерация обязаны получить один и тот же набор, иначе
|
||||
@@ -655,6 +694,12 @@ def cell_value_props(cell, where):
|
||||
if ctl is not None and str(ctl) != '':
|
||||
print(f"Cell 'controlType' requires 'valueType' ({where})", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
if cell.get('value') is not None:
|
||||
print(f"Cell 'value' requires 'valueType' ({where})", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
if cell.get('control'):
|
||||
print(f"Cell 'control' requires 'valueType' ({where})", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
return props
|
||||
# Ячейка, содержащая значение, текста не несёт: платформа этого не допускает, и в корпусе
|
||||
# нет ни одной такой ячейки из 370 197.
|
||||
@@ -1154,7 +1199,7 @@ def main():
|
||||
ключей есть ключ схемы ячейки, во втором ключи — идентификаторы языков. Пересечений
|
||||
нет: в корпусе это ru, en, ru1, Русский."""
|
||||
cell_keys = ('col', 'span', 'rowspan', 'style', 'param', 'detail', 'text', 'template',
|
||||
'valueType', 'controlType')
|
||||
'valueType', 'controlType', 'value', 'control')
|
||||
return any(k in el for k in cell_keys)
|
||||
|
||||
def expand_shorthand_row(row, area_name, row_idx, open_by_col, max_cols):
|
||||
@@ -1570,6 +1615,9 @@ def main():
|
||||
'Detail': cell.get('detail'),
|
||||
'Text': cell.get('text'),
|
||||
'Template': cell.get('template'),
|
||||
'Value': (cell_value(cell, vp.get('valueType', ''),
|
||||
f'area "{area_name}", row {local_row + 1}') if vp else None),
|
||||
'Control': (cell.get('control') if vp else None),
|
||||
}
|
||||
row_cells.append(cell_info)
|
||||
|
||||
@@ -1667,6 +1715,21 @@ def main():
|
||||
if cell_info['Template'] is not None:
|
||||
emit_cell_text(lines, cell_info['Template'])
|
||||
|
||||
if cell_info.get('Value') is not None:
|
||||
val = cell_info['Value']
|
||||
lines.append(f'\t\t\t\t\t<v xsi:type="{val["Type"]}">{esc_xml_text(val["Text"])}</v>')
|
||||
|
||||
# Настройки элемента управления платформа сериализует в base64 и держит у самой
|
||||
# ячейки. Структуру не разбираем — возим дословно, иначе она теряется.
|
||||
if cell_info.get('Control'):
|
||||
# Блоб платформа переносит по строкам, а строки документа склеиваются
|
||||
# позже — поэтому каждую строку блоба кладём отдельным элементом списка,
|
||||
# иначе перевод строки внутри значения разошёлся бы с остальным файлом.
|
||||
parts = str(cell_info['Control']).replace('\r\n', '\n').split('\n')
|
||||
parts[0] = f'\t\t\t\t\t<control xsi:type="xs:base64Binary">{parts[0]}'
|
||||
parts[-1] = f'{parts[-1]}</control>'
|
||||
lines.extend(parts)
|
||||
|
||||
# Расшифровка от параметра заполнения не зависит: на корпусе 20 404 ячейки несут
|
||||
# её БЕЗ параметра (у текста, у пустой ячейки, у поля ввода) против 8 582 с ним.
|
||||
# Пока она стояла внутри ветки параметра, две трети расшифровок терялись молча.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# mxl-decompile v1.21 — Decompile 1C spreadsheet to JSON
|
||||
# mxl-decompile v1.22 — Decompile 1C spreadsheet to JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -92,6 +92,25 @@ $valueControlNames = @{
|
||||
# значение» без указания типа — самостоятельное состояние.
|
||||
# Префикс ссылочного типа разрешаем по URI, а не по имени: локальное объявление платформа
|
||||
# называет сгенерированным dNpM. Чужое пространство имён оставляем как есть.
|
||||
# Значение ячейки-поля ввода → литерал DSL. Тип значения выражается самим литералом:
|
||||
# число → числом, булево → true/false, строка и дата → строкой. Пустое значение пишем
|
||||
# как есть (0, false, пустая дата), а не схлопываем: так оно собирается обратно тем же
|
||||
# типом независимо от того, какой тип объявлен у ячейки.
|
||||
function ConvertTo-DslValue {
|
||||
param([string]$xsiType, [string]$text)
|
||||
if ($null -eq $text) { $text = '' }
|
||||
if ($xsiType -ceq 'xs:boolean') { return ($text.Trim() -ceq 'true') }
|
||||
if ($xsiType -ceq 'xs:decimal') {
|
||||
$s = $text.Trim()
|
||||
$i = 0; $d = 0.0
|
||||
if ($s -notlike '*.*' -and [int]::TryParse($s, [ref]$i)) { return $i }
|
||||
if ([double]::TryParse($s, [System.Globalization.NumberStyles]::Float,
|
||||
[System.Globalization.CultureInfo]::InvariantCulture, [ref]$d)) { return $d }
|
||||
return $s
|
||||
}
|
||||
return $text
|
||||
}
|
||||
|
||||
function Get-ValueQualifier {
|
||||
param($quals, [string]$kind, [string]$name, [string]$default = '')
|
||||
if (-not $quals.ContainsKey($kind)) { return $default }
|
||||
@@ -390,6 +409,22 @@ foreach ($riNode in $root.SelectNodes("d:rowsItem", $ns)) {
|
||||
$dNode = $cContent.SelectSingleNode("d:detailParameter", $ns)
|
||||
if ($dNode) { $detail = $dNode.InnerText }
|
||||
|
||||
# Значение ячейки-поля ввода. Тип значения свой, из объявленного не выводится,
|
||||
# поэтому читаем и его.
|
||||
$value = $null
|
||||
$vNode = $cContent.SelectSingleNode("d:v", $ns)
|
||||
if ($vNode) {
|
||||
$value = @{ Type = $vNode.GetAttribute("type", "http://www.w3.org/2001/XMLSchema-instance"); Text = $vNode.InnerText }
|
||||
}
|
||||
|
||||
# Настройки элемента управления — сериализованный base64 у самой ячейки.
|
||||
# Структуру не разбираем, возим дословно.
|
||||
$control = $null
|
||||
$ctlNode = $cContent.SelectSingleNode("d:control", $ns)
|
||||
# Переводы строк внутри блоба приводим к LF: XML-парсеры нормализуют их
|
||||
# по-разному, и без этого порты давали разный JSON на одном файле.
|
||||
if ($ctlNode -and $ctlNode.InnerText) { $control = $ctlNode.InnerText -replace "`r`n", "`n" }
|
||||
|
||||
# Текст ячейки платформа хранит по элементу на язык. Раньше брался ПЕРВЫЙ, и всё
|
||||
# остальное терялось — в корпусе ERP 98% макетов держат текст и под ru, и под en.
|
||||
# Здесь собираем «язык → текст» как есть; свернётся в строку позже, когда станет
|
||||
@@ -423,6 +458,8 @@ foreach ($riNode in $root.SelectNodes("d:rowsItem", $ns)) {
|
||||
FormatIdx = $cellFmtIdx
|
||||
Param = $param
|
||||
Detail = $detail
|
||||
Value = $value
|
||||
Control = $control
|
||||
Text = $text
|
||||
HasText = $hasText
|
||||
}
|
||||
@@ -1135,6 +1172,10 @@ foreach ($area in $blocks) {
|
||||
# форматах корпуса.
|
||||
if ($name -cne 'input') { $dslCell["controlType"] = $name }
|
||||
}
|
||||
if ($null -ne $cell.Value) {
|
||||
$dslCell["value"] = ConvertTo-DslValue $cell.Value.Type $cell.Value.Text
|
||||
}
|
||||
if ($cell.Control) { $dslCell["control"] = $cell.Control }
|
||||
}
|
||||
|
||||
# Content
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# mxl-decompile v1.21 — Decompile 1C spreadsheet to JSON
|
||||
# mxl-decompile v1.22 — Decompile 1C spreadsheet to JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -187,6 +187,23 @@ def value_type_to_dsl(node):
|
||||
return ' + '.join(parts)
|
||||
|
||||
|
||||
def value_to_dsl(xsi_type, text):
|
||||
"""Значение ячейки-поля ввода → литерал DSL. Тип значения выражается самим литералом:
|
||||
число → числом, булево → true/false, строка и дата → строкой. Пустое значение пишем
|
||||
как есть (0, false, пустая дата), а не схлопываем: так оно собирается обратно тем же
|
||||
типом независимо от того, какой тип объявлен у ячейки."""
|
||||
text = text or ''
|
||||
if xsi_type == 'xs:boolean':
|
||||
return text.strip() == 'true'
|
||||
if xsi_type == 'xs:decimal':
|
||||
s = text.strip()
|
||||
try:
|
||||
return int(s) if '.' not in s else float(s)
|
||||
except ValueError:
|
||||
return s
|
||||
return text
|
||||
|
||||
|
||||
def int_of(node, default=0):
|
||||
if node is not None and node.text:
|
||||
return int(node.text)
|
||||
@@ -556,6 +573,22 @@ def main():
|
||||
if d_node is not None and d_node.text:
|
||||
detail = d_node.text
|
||||
|
||||
# Значение ячейки-поля ввода. Тип значения свой, из объявленного не выводится,
|
||||
# поэтому читаем и его: пустое значение сворачивается в "", остальные едут как есть.
|
||||
value = None
|
||||
v_node = find(c_content, "d:v")
|
||||
if v_node is not None:
|
||||
value = (v_node.get(f'{{{XSI_NS}}}type') or '', (v_node.text or ''))
|
||||
|
||||
# Настройки элемента управления — сериализованный base64 у самой ячейки.
|
||||
# Структуру не разбираем, возим дословно.
|
||||
control = None
|
||||
ctl_node = find(c_content, "d:control")
|
||||
if ctl_node is not None and ctl_node.text:
|
||||
# Переводы строк внутри блоба приводим к LF: XML-парсеры нормализуют их
|
||||
# по-разному, и без этого порты давали разный JSON на одном файле.
|
||||
control = ctl_node.text.replace('\r\n', '\n')
|
||||
|
||||
# Текст ячейки платформа хранит по элементу на язык. Раньше брался ПЕРВЫЙ, и всё
|
||||
# остальное терялось — в корпусе ERP 98% макетов держат текст и под ru, и под en.
|
||||
# Здесь собираем «язык → текст» как есть; свернётся в строку позже, когда станет
|
||||
@@ -587,6 +620,8 @@ def main():
|
||||
"FormatIdx": cell_fmt_idx,
|
||||
"Param": param,
|
||||
"Detail": detail,
|
||||
"Value": value,
|
||||
"Control": control,
|
||||
"Text": text,
|
||||
"HasText": has_text,
|
||||
})
|
||||
@@ -1128,6 +1163,10 @@ def main():
|
||||
# форматах корпуса.
|
||||
if name != "input":
|
||||
dsl_cell["controlType"] = name
|
||||
if cell["Value"] is not None:
|
||||
dsl_cell["value"] = value_to_dsl(*cell["Value"])
|
||||
if cell["Control"]:
|
||||
dsl_cell["control"] = cell["Control"]
|
||||
|
||||
# Content
|
||||
fill_type = cell_fmt["FillType"] if cell_fmt else ""
|
||||
|
||||
+17
-3
@@ -152,7 +152,8 @@
|
||||
| `{ ... }` | Обычная ячейка **без** `col`; нужна для `style`, `detail`, `template` |
|
||||
|
||||
Объект-элемент трактуется по его ключам: если среди них есть ключ ячейки (`span`, `rowspan`,
|
||||
`style`, `param`, `detail`, `text`, `template`, `valueType`, `controlType`) — объект описывает
|
||||
`style`, `param`, `detail`, `text`, `template`, `valueType`, `controlType`, `value`) — объект
|
||||
описывает
|
||||
свойства ячейки. Иначе он целиком считается её текстом, а его ключи — идентификаторами языков.
|
||||
|
||||
```json
|
||||
@@ -184,6 +185,7 @@
|
||||
| `template` | нет | — | Шаблонный текст с `[Параметр]`. Строка или объект, как `text` |
|
||||
| `valueType` | нет | — | Тип значения: ячейка становится полем ввода (см. ниже) |
|
||||
| `controlType` | нет | `input` | Элемент управления поля ввода: `input` или `checkbox`. Только вместе с `valueType` |
|
||||
| `value` | нет | — | Значение в поле ввода. Только вместе с `valueType` |
|
||||
|
||||
### Содержимое ячейки
|
||||
|
||||
@@ -248,6 +250,20 @@
|
||||
|
||||
Пустой тип `"valueType": ""` — «ячейка содержит значение», но тип не ограничен.
|
||||
|
||||
Значение поля ввода задаётся ключом `value`, и его тип выражается литералом JSON: строка —
|
||||
строкой, число — числом, булево — `true`/`false`. Приведения к объявленному типу **не
|
||||
происходит**: платформа хранит значение с его собственным типом и совпадать с объявленным он
|
||||
не обязан (у ссылочного и составного типа значение всегда строковое). Пустая строка означает
|
||||
пустое значение объявленного типа. Дата записывается строкой в формате `ГГГГ-ММ-ДДTчч:мм:сс`
|
||||
и читается как дата только у ячейки, объявленной датой.
|
||||
|
||||
```json
|
||||
{ "col": 1, "valueType": "Number(15,3)", "value": 12.5 }
|
||||
{ "col": 2, "valueType": "String(10)", "value": "5" }
|
||||
{ "col": 3, "valueType": "Boolean", "value": true }
|
||||
{ "col": 4, "valueType": "DateTime", "value": "" }
|
||||
```
|
||||
|
||||
`controlType` нужен редко: умолчание платформы — поле ввода, и оно применяется ко всем типам,
|
||||
включая `Boolean`. Флажок задаётся явно. Значение `"none"` (тега элемента управления нет вовсе) —
|
||||
форма раундтрипа, для ручного авторинга не нужна.
|
||||
@@ -266,8 +282,6 @@ DSL описывает не все конструкции табличного
|
||||
round-trip** (`/mxl-decompile` → `/mxl-compile`): в JSON оно не попадает, в сгенерированный
|
||||
XML не возвращается.
|
||||
|
||||
- начальное значение ячейки-поля ввода и сериализованные настройки её элемента управления
|
||||
(тип значения при этом переживает цикл);
|
||||
- объединения, не привязанные к ячейке (по всей высоте или ширине документа);
|
||||
- рисунки и картинки, в том числе штрихкоды, и примечания к ячейкам;
|
||||
- группировки строк и колонок;
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "Ошибка: value без valueType",
|
||||
"input": {
|
||||
"columns": 1,
|
||||
"areas": [
|
||||
{
|
||||
"name": "Ввод",
|
||||
"rows": [{ "cells": [{ "col": 1, "value": "5" }] }]
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": { "outputPath": "Template.xml" },
|
||||
"expectError": "Cell 'value' requires 'valueType' (area \"Ввод\")"
|
||||
}
|
||||
@@ -112,10 +112,129 @@
|
||||
</c>
|
||||
</row>
|
||||
</rowsItem>
|
||||
<rowsItem>
|
||||
<index>7</index>
|
||||
<row>
|
||||
<c>
|
||||
<c>
|
||||
<f>3</f>
|
||||
<v xsi:type="xs:string">5</v>
|
||||
</c>
|
||||
</c>
|
||||
<c>
|
||||
<c>
|
||||
<f>2</f>
|
||||
<v xsi:type="xs:decimal">8</v>
|
||||
</c>
|
||||
</c>
|
||||
</row>
|
||||
</rowsItem>
|
||||
<rowsItem>
|
||||
<index>8</index>
|
||||
<row>
|
||||
<c>
|
||||
<c>
|
||||
<f>3</f>
|
||||
<v xsi:type="xs:string">4 5</v>
|
||||
</c>
|
||||
</c>
|
||||
<c>
|
||||
<c>
|
||||
<f>2</f>
|
||||
<v xsi:type="xs:decimal">0</v>
|
||||
</c>
|
||||
</c>
|
||||
<c>
|
||||
<c>
|
||||
<f>12</f>
|
||||
<v xsi:type="xs:dateTime">0001-01-01T00:00:00</v>
|
||||
</c>
|
||||
</c>
|
||||
</row>
|
||||
</rowsItem>
|
||||
<rowsItem>
|
||||
<index>9</index>
|
||||
<row>
|
||||
<c>
|
||||
<c>
|
||||
<f>13</f>
|
||||
<v xsi:type="xs:string">4 5</v>
|
||||
</c>
|
||||
</c>
|
||||
<c>
|
||||
<c>
|
||||
<f>12</f>
|
||||
<v xsi:type="xs:dateTime">0001-01-01T00:00:00</v>
|
||||
</c>
|
||||
</c>
|
||||
<c>
|
||||
<c>
|
||||
<f>4</f>
|
||||
<v xsi:type="xs:boolean">true</v>
|
||||
</c>
|
||||
</c>
|
||||
</row>
|
||||
</rowsItem>
|
||||
<rowsItem>
|
||||
<index>10</index>
|
||||
<row>
|
||||
<c>
|
||||
<c>
|
||||
<f>14</f>
|
||||
<v xsi:type="xs:string">Составной</v>
|
||||
</c>
|
||||
</c>
|
||||
<c>
|
||||
<c>
|
||||
<f>2</f>
|
||||
<v xsi:type="xs:decimal">12.5</v>
|
||||
</c>
|
||||
</c>
|
||||
<c>
|
||||
<c>
|
||||
<f>2</f>
|
||||
<v xsi:type="xs:decimal">-3</v>
|
||||
</c>
|
||||
</c>
|
||||
</row>
|
||||
</rowsItem>
|
||||
<rowsItem>
|
||||
<index>11</index>
|
||||
<row>
|
||||
<c>
|
||||
<c>
|
||||
<f>15</f>
|
||||
</c>
|
||||
</c>
|
||||
<c>
|
||||
<c>
|
||||
<f>12</f>
|
||||
<v xsi:type="xs:dateTime">0001-01-01T00:00:00</v>
|
||||
</c>
|
||||
</c>
|
||||
<c>
|
||||
<c>
|
||||
<f>3</f>
|
||||
<control xsi:type="xs:base64Binary">77u/MiwxLDM4MWVkNjI0LTkyMTctNGU2My04NWRiLWM0YzNjYjg3ZGFhZSwNCnsN
|
||||
Cns5LA0KeyJQYXR0ZXJuIiwNCnsiUyJ9DQp9LA0Kew0Kew0KezE2LDEsDQp7Myw0
|
||||
LA0KezB9DQp9LA0KezMsNCwNCnswfQ0KfSwNCns3LDMsMCwxLDEwMH0sMCwNCnsz
|
||||
LDQsDQp7MH0NCn0sDQp7Myw0LA0KezB9DQp9LA0KezMsNCwNCnswfQ0KfSwNCnsz
|
||||
LDMsDQp7LTd9DQp9LA0KezMsMywNCnstMjF9DQp9LA0KezMsMSwNCnstMTh9LDAs
|
||||
MCwwfSwNCnsxLDB9LDAsMCwxMDAsMCwwfSwzMCwwLDAsMSwwLDAsMSwxLDEsMCwx
|
||||
LDAsMCwwLDAsMCw0LDAsDQp7IlUifSwNCnsiVSJ9LCIiLDAsMSwwLDAsMCwwLA0K
|
||||
ezQsMCwNCnswfSwiIiwtMSwtMSwxLDAsIiJ9LA0KezQsMCwNCnswfSwiIiwtMSwt
|
||||
MSwxLDAsIiJ9LDAsMCwwLA0KezAsMCwwfSwNCnsxLDB9LDAsMCwwLDAsMCwwLDAs
|
||||
MTY3NzcyMTUsMn0NCn0sDQp7MSwNCns5YTc2NDNkMi0xOWU5LTQ1ZTItODg5My0y
|
||||
ODBiYzkxOTVhOTcsDQp7NCwNCnsiVSJ9LA0KeyJVIn0sMCwiIiwwLDB9DQp9DQp9
|
||||
LA0KezB9LDAsMSwwLA0KezEsMH0sMH0NCn0sMA==</control>
|
||||
</c>
|
||||
</c>
|
||||
</row>
|
||||
</rowsItem>
|
||||
<templateMode>true</templateMode>
|
||||
<defaultFormatIndex>12</defaultFormatIndex>
|
||||
<height>7</height>
|
||||
<vgRows>7</vgRows>
|
||||
<defaultFormatIndex>16</defaultFormatIndex>
|
||||
<height>12</height>
|
||||
<vgRows>12</vgRows>
|
||||
<format>
|
||||
<containsValue>true</containsValue>
|
||||
<valueType>
|
||||
@@ -232,6 +351,57 @@
|
||||
</valueType>
|
||||
<controlType>381ed624-9217-4e63-85db-c4c3cb87daae</controlType>
|
||||
</format>
|
||||
<format>
|
||||
<containsValue>true</containsValue>
|
||||
<valueType>
|
||||
<v8:Type>xs:dateTime</v8:Type>
|
||||
<v8:DateQualifiers>
|
||||
<v8:DateFractions>DateTime</v8:DateFractions>
|
||||
</v8:DateQualifiers>
|
||||
</valueType>
|
||||
<controlType>381ed624-9217-4e63-85db-c4c3cb87daae</controlType>
|
||||
</format>
|
||||
<format>
|
||||
<containsValue>true</containsValue>
|
||||
<valueType>
|
||||
<v8:Type xmlns:d4p1="http://v8.1c.ru/8.1/data/enterprise/current-config">d4p1:CatalogRef.Бригады</v8:Type>
|
||||
</valueType>
|
||||
<controlType>381ed624-9217-4e63-85db-c4c3cb87daae</controlType>
|
||||
</format>
|
||||
<format>
|
||||
<containsValue>true</containsValue>
|
||||
<valueType>
|
||||
<v8:Type>xs:boolean</v8:Type>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:Type>xs:dateTime</v8:Type>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>0</v8:Digits>
|
||||
<v8:FractionDigits>0</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
<v8:StringQualifiers>
|
||||
<v8:Length>0</v8:Length>
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
<v8:DateQualifiers>
|
||||
<v8:DateFractions>DateTime</v8:DateFractions>
|
||||
</v8:DateQualifiers>
|
||||
</valueType>
|
||||
<controlType>381ed624-9217-4e63-85db-c4c3cb87daae</controlType>
|
||||
</format>
|
||||
<format>
|
||||
<containsValue>true</containsValue>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>0</v8:Digits>
|
||||
<v8:FractionDigits>0</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
<controlType>35af3d93-d7c7-4a2e-a8eb-bac87a1a3f26</controlType>
|
||||
</format>
|
||||
<format>
|
||||
<width>72</width>
|
||||
</format>
|
||||
|
||||
@@ -0,0 +1,225 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document xmlns="http://v8.1c.ru/8.2/data/spreadsheet" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" 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">
|
||||
<languageSettings>
|
||||
<currentLanguage>ru</currentLanguage>
|
||||
<defaultLanguage>ru</defaultLanguage>
|
||||
<languageInfo>
|
||||
<id>ru</id>
|
||||
<code>Русский</code>
|
||||
<description>Русский</description>
|
||||
</languageInfo>
|
||||
</languageSettings>
|
||||
<columns>
|
||||
<size>3</size>
|
||||
</columns>
|
||||
<rowsItem>
|
||||
<index>0</index>
|
||||
<row>
|
||||
<c>
|
||||
<c>
|
||||
<f>1</f>
|
||||
<v xsi:type="xs:string">5</v>
|
||||
</c>
|
||||
</c>
|
||||
<c>
|
||||
<c>
|
||||
<f>2</f>
|
||||
<v xsi:type="xs:decimal">12.5</v>
|
||||
</c>
|
||||
</c>
|
||||
<c>
|
||||
<c>
|
||||
<f>3</f>
|
||||
<v xsi:type="xs:decimal">-3</v>
|
||||
</c>
|
||||
</c>
|
||||
</row>
|
||||
</rowsItem>
|
||||
<rowsItem>
|
||||
<index>1</index>
|
||||
<row>
|
||||
<c>
|
||||
<c>
|
||||
<f>4</f>
|
||||
<v xsi:type="xs:boolean">true</v>
|
||||
</c>
|
||||
</c>
|
||||
<c>
|
||||
<c>
|
||||
<f>4</f>
|
||||
<v xsi:type="xs:boolean">false</v>
|
||||
</c>
|
||||
</c>
|
||||
<c>
|
||||
<c>
|
||||
<f>5</f>
|
||||
<v xsi:type="xs:dateTime">2026-08-09T13:45:00</v>
|
||||
</c>
|
||||
</c>
|
||||
</row>
|
||||
</rowsItem>
|
||||
<rowsItem>
|
||||
<index>2</index>
|
||||
<row>
|
||||
<c>
|
||||
<c>
|
||||
<f>6</f>
|
||||
<v xsi:type="xs:string"></v>
|
||||
</c>
|
||||
</c>
|
||||
<c>
|
||||
<c>
|
||||
<f>7</f>
|
||||
<v xsi:type="xs:decimal">0</v>
|
||||
</c>
|
||||
</c>
|
||||
<c>
|
||||
<c>
|
||||
<f>5</f>
|
||||
<v xsi:type="xs:dateTime">0001-01-01T00:00:00</v>
|
||||
</c>
|
||||
</c>
|
||||
</row>
|
||||
</rowsItem>
|
||||
<rowsItem>
|
||||
<index>3</index>
|
||||
<row>
|
||||
<c>
|
||||
<c>
|
||||
<f>8</f>
|
||||
<v xsi:type="xs:string">4 5</v>
|
||||
</c>
|
||||
</c>
|
||||
<c>
|
||||
<c>
|
||||
<f>9</f>
|
||||
<v xsi:type="xs:string">Составной</v>
|
||||
</c>
|
||||
</c>
|
||||
<c>
|
||||
<c>
|
||||
<f>3</f>
|
||||
<v xsi:type="xs:decimal">8</v>
|
||||
<detailParameter>Расшифровка</detailParameter>
|
||||
</c>
|
||||
</c>
|
||||
</row>
|
||||
</rowsItem>
|
||||
<templateMode>true</templateMode>
|
||||
<defaultFormatIndex>10</defaultFormatIndex>
|
||||
<height>4</height>
|
||||
<vgRows>4</vgRows>
|
||||
<namedItem xsi:type="NamedItemCells">
|
||||
<name>Значения</name>
|
||||
<area>
|
||||
<type>Rows</type>
|
||||
<beginRow>0</beginRow>
|
||||
<endRow>3</endRow>
|
||||
<beginColumn>-1</beginColumn>
|
||||
<endColumn>-1</endColumn>
|
||||
</area>
|
||||
</namedItem>
|
||||
<format>
|
||||
<containsValue>true</containsValue>
|
||||
<valueType>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:StringQualifiers>
|
||||
<v8:Length>10</v8:Length>
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</valueType>
|
||||
<controlType>381ed624-9217-4e63-85db-c4c3cb87daae</controlType>
|
||||
</format>
|
||||
<format>
|
||||
<containsValue>true</containsValue>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>15</v8:Digits>
|
||||
<v8:FractionDigits>3</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
<controlType>381ed624-9217-4e63-85db-c4c3cb87daae</controlType>
|
||||
</format>
|
||||
<format>
|
||||
<containsValue>true</containsValue>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
<controlType>381ed624-9217-4e63-85db-c4c3cb87daae</controlType>
|
||||
</format>
|
||||
<format>
|
||||
<containsValue>true</containsValue>
|
||||
<valueType>
|
||||
<v8:Type>xs:boolean</v8:Type>
|
||||
</valueType>
|
||||
<controlType>381ed624-9217-4e63-85db-c4c3cb87daae</controlType>
|
||||
</format>
|
||||
<format>
|
||||
<containsValue>true</containsValue>
|
||||
<valueType>
|
||||
<v8:Type>xs:dateTime</v8:Type>
|
||||
<v8:DateQualifiers>
|
||||
<v8:DateFractions>DateTime</v8:DateFractions>
|
||||
</v8:DateQualifiers>
|
||||
</valueType>
|
||||
<controlType>381ed624-9217-4e63-85db-c4c3cb87daae</controlType>
|
||||
</format>
|
||||
<format>
|
||||
<containsValue>true</containsValue>
|
||||
<valueType>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:StringQualifiers>
|
||||
<v8:Length>0</v8:Length>
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</valueType>
|
||||
<controlType>381ed624-9217-4e63-85db-c4c3cb87daae</controlType>
|
||||
</format>
|
||||
<format>
|
||||
<containsValue>true</containsValue>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>0</v8:Digits>
|
||||
<v8:FractionDigits>0</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
<controlType>381ed624-9217-4e63-85db-c4c3cb87daae</controlType>
|
||||
</format>
|
||||
<format>
|
||||
<containsValue>true</containsValue>
|
||||
<valueType>
|
||||
<v8:Type xmlns:d4p1="http://v8.1c.ru/8.1/data/enterprise/current-config">d4p1:CatalogRef.Валюты</v8:Type>
|
||||
</valueType>
|
||||
<controlType>381ed624-9217-4e63-85db-c4c3cb87daae</controlType>
|
||||
</format>
|
||||
<format>
|
||||
<containsValue>true</containsValue>
|
||||
<valueType>
|
||||
<v8:Type>xs:boolean</v8:Type>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>0</v8:Digits>
|
||||
<v8:FractionDigits>0</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
<v8:StringQualifiers>
|
||||
<v8:Length>0</v8:Length>
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</valueType>
|
||||
<controlType>381ed624-9217-4e63-85db-c4c3cb87daae</controlType>
|
||||
</format>
|
||||
<format>
|
||||
<width>10</width>
|
||||
</format>
|
||||
</document>
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "Ячейки-поля ввода: сохранённое значение",
|
||||
"input": {
|
||||
"columns": 3,
|
||||
"areas": [
|
||||
{
|
||||
"name": "Значения",
|
||||
"rows": [
|
||||
{ "cells": [
|
||||
{ "col": 1, "valueType": "String(10)", "value": "5" },
|
||||
{ "col": 2, "valueType": "Number(15,3)", "value": 12.5 },
|
||||
{ "col": 3, "valueType": "Number(10,2)", "value": -3 }
|
||||
]},
|
||||
{ "cells": [
|
||||
{ "col": 1, "valueType": "Boolean", "value": true },
|
||||
{ "col": 2, "valueType": "Boolean", "value": false },
|
||||
{ "col": 3, "valueType": "DateTime", "value": "2026-08-09T13:45:00" }
|
||||
]},
|
||||
{ "cells": [
|
||||
{ "col": 1, "valueType": "String", "value": "" },
|
||||
{ "col": 2, "valueType": "Number", "value": "" },
|
||||
{ "col": 3, "valueType": "DateTime", "value": "" }
|
||||
]},
|
||||
{ "cells": [
|
||||
{ "col": 1, "valueType": "CatalogRef.Валюты", "value": "4 5" },
|
||||
{ "col": 2, "valueType": "Boolean + String + Number", "value": "Составной" },
|
||||
{ "col": 3, "valueType": "Number(10,2)", "value": 8, "detail": "Расшифровка" }
|
||||
]}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"outputPath": "Template.xml"
|
||||
},
|
||||
"skipPlatformVerify": "ссылочный тип разрешается только в базе с матч-конфигурацией: временная база-заглушка таких объектов не содержит"
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "Roundtrip — сохранённые значения ячеек-полей ввода",
|
||||
"preRun": [
|
||||
{
|
||||
"script": "mxl-compile/scripts/mxl-compile",
|
||||
"input": {
|
||||
"columns": 3,
|
||||
"areas": [
|
||||
{
|
||||
"name": "Значения",
|
||||
"rows": [
|
||||
{ "cells": [
|
||||
{ "col": 1, "valueType": "String(10)", "value": "5" },
|
||||
{ "col": 2, "valueType": "Number(15,3)", "value": 12.5 },
|
||||
{ "col": 3, "valueType": "Number(10,2)", "value": -3 }
|
||||
]},
|
||||
{ "cells": [
|
||||
{ "col": 1, "valueType": "Boolean", "value": true },
|
||||
{ "col": 2, "valueType": "DateTime", "value": "2026-08-09T13:45:00" },
|
||||
{ "col": 3, "valueType": "DateTime", "value": "" }
|
||||
]},
|
||||
{ "cells": [
|
||||
{ "col": 1, "valueType": "String", "value": "" },
|
||||
{ "col": 2, "valueType": "Number", "value": "" },
|
||||
{ "col": 3, "valueType": "Boolean + String + Number", "value": "Составной" }
|
||||
]}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"args": { "-JsonPath": "{inputFile}", "-OutputPath": "Template.xml" },
|
||||
"cwd": "{workDir}"
|
||||
}
|
||||
],
|
||||
"params": { "templatePath": "Template.xml" },
|
||||
"args_extra": ["-OutputPath", "{workDir}/back.json"],
|
||||
"expect": {
|
||||
"files": ["back.json"],
|
||||
"stdoutContains": "[OK] Decompiled:"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document xmlns="http://v8.1c.ru/8.2/data/spreadsheet" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" 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">
|
||||
<languageSettings>
|
||||
<currentLanguage>ru</currentLanguage>
|
||||
<defaultLanguage>ru</defaultLanguage>
|
||||
<languageInfo>
|
||||
<id>ru</id>
|
||||
<code>Русский</code>
|
||||
<description>Русский</description>
|
||||
</languageInfo>
|
||||
</languageSettings>
|
||||
<columns>
|
||||
<size>3</size>
|
||||
</columns>
|
||||
<rowsItem>
|
||||
<index>0</index>
|
||||
<row>
|
||||
<c>
|
||||
<c>
|
||||
<f>1</f>
|
||||
<v xsi:type="xs:string">5</v>
|
||||
</c>
|
||||
</c>
|
||||
<c>
|
||||
<c>
|
||||
<f>2</f>
|
||||
<v xsi:type="xs:decimal">12.5</v>
|
||||
</c>
|
||||
</c>
|
||||
<c>
|
||||
<c>
|
||||
<f>3</f>
|
||||
<v xsi:type="xs:decimal">-3</v>
|
||||
</c>
|
||||
</c>
|
||||
</row>
|
||||
</rowsItem>
|
||||
<rowsItem>
|
||||
<index>1</index>
|
||||
<row>
|
||||
<c>
|
||||
<c>
|
||||
<f>4</f>
|
||||
<v xsi:type="xs:boolean">true</v>
|
||||
</c>
|
||||
</c>
|
||||
<c>
|
||||
<c>
|
||||
<f>5</f>
|
||||
<v xsi:type="xs:dateTime">2026-08-09T13:45:00</v>
|
||||
</c>
|
||||
</c>
|
||||
<c>
|
||||
<c>
|
||||
<f>5</f>
|
||||
<v xsi:type="xs:dateTime">0001-01-01T00:00:00</v>
|
||||
</c>
|
||||
</c>
|
||||
</row>
|
||||
</rowsItem>
|
||||
<rowsItem>
|
||||
<index>2</index>
|
||||
<row>
|
||||
<c>
|
||||
<c>
|
||||
<f>6</f>
|
||||
<v xsi:type="xs:string"></v>
|
||||
</c>
|
||||
</c>
|
||||
<c>
|
||||
<c>
|
||||
<f>7</f>
|
||||
<v xsi:type="xs:decimal">0</v>
|
||||
</c>
|
||||
</c>
|
||||
<c>
|
||||
<c>
|
||||
<f>8</f>
|
||||
<v xsi:type="xs:string">Составной</v>
|
||||
</c>
|
||||
</c>
|
||||
</row>
|
||||
</rowsItem>
|
||||
<templateMode>true</templateMode>
|
||||
<defaultFormatIndex>9</defaultFormatIndex>
|
||||
<height>3</height>
|
||||
<vgRows>3</vgRows>
|
||||
<namedItem xsi:type="NamedItemCells">
|
||||
<name>Значения</name>
|
||||
<area>
|
||||
<type>Rows</type>
|
||||
<beginRow>0</beginRow>
|
||||
<endRow>2</endRow>
|
||||
<beginColumn>-1</beginColumn>
|
||||
<endColumn>-1</endColumn>
|
||||
</area>
|
||||
</namedItem>
|
||||
<format>
|
||||
<containsValue>true</containsValue>
|
||||
<valueType>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:StringQualifiers>
|
||||
<v8:Length>10</v8:Length>
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</valueType>
|
||||
<controlType>381ed624-9217-4e63-85db-c4c3cb87daae</controlType>
|
||||
</format>
|
||||
<format>
|
||||
<containsValue>true</containsValue>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>15</v8:Digits>
|
||||
<v8:FractionDigits>3</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
<controlType>381ed624-9217-4e63-85db-c4c3cb87daae</controlType>
|
||||
</format>
|
||||
<format>
|
||||
<containsValue>true</containsValue>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>10</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
<controlType>381ed624-9217-4e63-85db-c4c3cb87daae</controlType>
|
||||
</format>
|
||||
<format>
|
||||
<containsValue>true</containsValue>
|
||||
<valueType>
|
||||
<v8:Type>xs:boolean</v8:Type>
|
||||
</valueType>
|
||||
<controlType>381ed624-9217-4e63-85db-c4c3cb87daae</controlType>
|
||||
</format>
|
||||
<format>
|
||||
<containsValue>true</containsValue>
|
||||
<valueType>
|
||||
<v8:Type>xs:dateTime</v8:Type>
|
||||
<v8:DateQualifiers>
|
||||
<v8:DateFractions>DateTime</v8:DateFractions>
|
||||
</v8:DateQualifiers>
|
||||
</valueType>
|
||||
<controlType>381ed624-9217-4e63-85db-c4c3cb87daae</controlType>
|
||||
</format>
|
||||
<format>
|
||||
<containsValue>true</containsValue>
|
||||
<valueType>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:StringQualifiers>
|
||||
<v8:Length>0</v8:Length>
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</valueType>
|
||||
<controlType>381ed624-9217-4e63-85db-c4c3cb87daae</controlType>
|
||||
</format>
|
||||
<format>
|
||||
<containsValue>true</containsValue>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>0</v8:Digits>
|
||||
<v8:FractionDigits>0</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
<controlType>381ed624-9217-4e63-85db-c4c3cb87daae</controlType>
|
||||
</format>
|
||||
<format>
|
||||
<containsValue>true</containsValue>
|
||||
<valueType>
|
||||
<v8:Type>xs:boolean</v8:Type>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>0</v8:Digits>
|
||||
<v8:FractionDigits>0</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
<v8:StringQualifiers>
|
||||
<v8:Length>0</v8:Length>
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</valueType>
|
||||
<controlType>381ed624-9217-4e63-85db-c4c3cb87daae</controlType>
|
||||
</format>
|
||||
<format>
|
||||
<width>10</width>
|
||||
</format>
|
||||
</document>
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"columns": 3,
|
||||
"defaultWidth": 10,
|
||||
"fonts": {},
|
||||
"styles": {},
|
||||
"areas": [
|
||||
{
|
||||
"name": "Значения",
|
||||
"rows": [
|
||||
[{ "valueType": "String(10)", "value": "5" }, { "valueType": "Number(15,3)", "value": 12.5 }, { "valueType": "Number(10,2)", "value": -3 }],
|
||||
[{ "valueType": "Boolean", "value": true }, { "valueType": "DateTime", "value": "2026-08-09T13:45:00" }, { "valueType": "DateTime", "value": "0001-01-01T00:00:00" }],
|
||||
[{ "valueType": "String", "value": "" }, { "valueType": "Number", "value": 0 }, { "valueType": "Boolean + String + Number", "value": "Составной" }]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user