fix(mxl-compile): неоформленная ячейка ссылается на формат по умолчанию

Платформа держит для неоформленного макета ОДИН формат — ширину колонки, он же
defaultFormatIndex, и все ячейки указывают на него. Компилятор заводил каждой ячейке
собственный формат с <font>0</font>, где ноль означает «шрифт не задан», то есть
формат был пуст по смыслу и отличался от умолчания только своим существованием.

Теперь ячейка, у которой не задано ничего (шрифт умолчательный, нет рамок,
выравнивания, переноса, типа заполнения и формата числа), ссылается на
defaultFormatIndex. На минимальном макете палитра сократилась с двух форматов до
одного и совпала по форме с платформенной.

На корпусе правка закрывает случай неоформленной ячейки начисто: на макете
АтрибВыгрузкиXML2015Кв1 расхождения по формату исчезли полностью, блок диффа
сократился с 75 строк до 40, и всё оставшееся — многоязычный текст. В агрегате по
пилоту это 497 строк из 64 865: остальное держат макеты, где ячейки реально
оформлены, и там расходится состав самих форматов — отдельная категория.

Дрейф 18 снэпшотов разобран построчно, посторонних строк нет: 170 сменившихся
индексов <f>, 36 границ <format> (палитра стала короче), 18 удалённых <font>.

Проверено: тесты 53/53 на обоих рантаймах, verify-snapshots 23/23.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-08-10 20:20:35 +03:00
co-authored by Claude Opus 5
parent 66c7364c37
commit 572b75984a
20 changed files with 107 additions and 141 deletions
@@ -1,4 +1,4 @@
# mxl-compile v1.22 — Compile 1C spreadsheet from JSON (+write_xml_file/write_utf8_bom: общий эталон записи)
# mxl-compile v1.23 — Compile 1C spreadsheet from JSON (+write_xml_file/write_utf8_bom: общий эталон записи)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -573,6 +573,16 @@ function Get-FillType {
function Register-CellFormat {
param($styleName, [string]$fillType)
$resolved = Resolve-Style -styleName $styleName -fillType $fillType
# Ячейка без собственного оформления ссылается на формат ПО УМОЛЧАНИЮ — так делает
# платформа: в её палитре у неоформленного макета один формат (ширина колонки), и все
# ячейки указывают на него. Мы же заводили каждой свой формат с <font>0</font>, где ноль
# означает «шрифт не задан», то есть формат был пуст по смыслу.
if ($resolved.FontIdx -eq $fontMap["default"] -and
$resolved.LB -lt 0 -and $resolved.TB -lt 0 -and $resolved.RB -lt 0 -and $resolved.BB -lt 0 -and
-not $resolved.HA -and -not $resolved.VA -and -not $resolved.Wrap -and
-not $resolved.FillType -and -not $resolved.NumberFormat) {
return $script:defaultFormatIndex
}
$key = Get-FormatKey -fontIdx $resolved.FontIdx `
-lb $resolved.LB -tb $resolved.TB -rb $resolved.RB -bb $resolved.BB `
-ha $resolved.HA -va $resolved.VA `
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# mxl-compile v1.22 — Compile 1C spreadsheet from JSON (+write_xml_file/write_utf8_bom: общий эталон записи)
# mxl-compile v1.23 — Compile 1C spreadsheet from JSON (+write_xml_file/write_utf8_bom: общий эталон записи)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import hashlib
@@ -619,6 +619,16 @@ def main():
# Helper: register a cell format and return its index
def register_cell_format(style_name, fill_type):
resolved = resolve_style(style_name, fill_type)
# Ячейка без собственного оформления ссылается на формат ПО УМОЛЧАНИЮ — так делает
# платформа: в её палитре у неоформленного макета один формат (ширина колонки), и все
# ячейки указывают на него. Мы же заводили каждой свой формат с <font>0</font>, где ноль
# означает «шрифт не задан», то есть формат был пуст по смыслу.
if (resolved['FontIdx'] == font_map.get('default', 0)
and resolved['LB'] < 0 and resolved['TB'] < 0
and resolved['RB'] < 0 and resolved['BB'] < 0
and not resolved['HA'] and not resolved['VA'] and not resolved['Wrap']
and not resolved['FillType'] and not resolved['NumberFormat']):
return default_format_index
key = get_format_key(
font_idx=resolved['FontIdx'],
lb=resolved['LB'], tb=resolved['TB'], rb=resolved['RB'], bb=resolved['BB'],
@@ -58,7 +58,7 @@
<c>
<i>0</i>
<c>
<f>4</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -70,7 +70,7 @@
<c>
<i>1</i>
<c>
<f>4</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -82,7 +82,7 @@
<c>
<i>2</i>
<c>
<f>4</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -100,21 +100,21 @@
<c>
<i>0</i>
<c>
<f>5</f>
<f>4</f>
<parameter>Товар</parameter>
</c>
</c>
<c>
<i>1</i>
<c>
<f>5</f>
<f>4</f>
<parameter>Кол</parameter>
</c>
</c>
<c>
<i>2</i>
<c>
<f>5</f>
<f>4</f>
<parameter>Сумма</parameter>
</c>
</c>
@@ -154,9 +154,6 @@
<format>
<width>8</width>
</format>
<format>
<font>0</font>
</format>
<format>
<font>0</font>
<fillType>Parameter</fillType>
@@ -18,7 +18,7 @@
<c>
<i>0</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -47,7 +47,4 @@
<format>
<width>10</width>
</format>
<format>
<font>0</font>
</format>
</document>
@@ -18,7 +18,7 @@
<c>
<i>0</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -30,7 +30,7 @@
<c>
<i>1</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -42,7 +42,7 @@
<c>
<i>2</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -59,7 +59,7 @@
<c>
<i>0</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -71,7 +71,7 @@
<c>
<i>1</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -83,7 +83,7 @@
<c>
<i>2</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -100,7 +100,7 @@
<c>
<i>1</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -112,7 +112,7 @@
<c>
<i>2</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -129,7 +129,7 @@
<c>
<i>0</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -141,7 +141,7 @@
<c>
<i>2</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -181,7 +181,4 @@
<format>
<width>10</width>
</format>
<format>
<font>0</font>
</format>
</document>
@@ -18,7 +18,7 @@
<c>
<i>0</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -30,7 +30,7 @@
<c>
<i>1</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -42,7 +42,7 @@
<c>
<i>2</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -71,7 +71,4 @@
<format>
<width>10</width>
</format>
<format>
<font>0</font>
</format>
</document>
@@ -18,7 +18,7 @@
<c>
<i>0</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -47,7 +47,4 @@
<format>
<width>10</width>
</format>
<format>
<font>0</font>
</format>
</document>
@@ -18,7 +18,7 @@
<c>
<i>0</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -30,7 +30,7 @@
<c>
<i>1</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -42,7 +42,7 @@
<c>
<i>2</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -54,7 +54,7 @@
<c>
<i>3</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -71,28 +71,28 @@
<c>
<i>0</i>
<c>
<f>3</f>
<f>2</f>
<parameter>П1</parameter>
</c>
</c>
<c>
<i>1</i>
<c>
<f>3</f>
<f>2</f>
<parameter>П2</parameter>
</c>
</c>
<c>
<i>2</i>
<c>
<f>3</f>
<f>2</f>
<parameter>П3</parameter>
</c>
</c>
<c>
<i>3</i>
<c>
<f>3</f>
<f>2</f>
<parameter>П4</parameter>
</c>
</c>
@@ -146,9 +146,6 @@
<format>
<width>10</width>
</format>
<format>
<font>0</font>
</format>
<format>
<font>0</font>
<fillType>Parameter</fillType>
@@ -18,7 +18,7 @@
<c>
<i>0</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -47,7 +47,4 @@
<format>
<width>10</width>
</format>
<format>
<font>0</font>
</format>
</document>
@@ -18,7 +18,7 @@
<c>
<i>0</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -30,7 +30,7 @@
<c>
<i>1</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -42,7 +42,7 @@
<c>
<i>3</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -59,7 +59,7 @@
<c>
<i>1</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -71,7 +71,7 @@
<c>
<i>2</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -88,28 +88,28 @@
<c>
<i>0</i>
<c>
<f>3</f>
<f>2</f>
<parameter>Вид</parameter>
</c>
</c>
<c>
<i>1</i>
<c>
<f>3</f>
<f>2</f>
<parameter>Нач</parameter>
</c>
</c>
<c>
<i>2</i>
<c>
<f>3</f>
<f>2</f>
<parameter>Кон</parameter>
</c>
</c>
<c>
<i>3</i>
<c>
<f>3</f>
<f>2</f>
<parameter>Итог</parameter>
</c>
</c>
@@ -150,9 +150,6 @@
<format>
<width>10</width>
</format>
<format>
<font>0</font>
</format>
<format>
<font>0</font>
<fillType>Parameter</fillType>
@@ -18,7 +18,7 @@
<c>
<i>0</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -30,7 +30,7 @@
<c>
<i>1</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -42,7 +42,7 @@
<c>
<i>2</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -54,7 +54,7 @@
<c>
<i>3</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -71,21 +71,21 @@
<c>
<i>0</i>
<c>
<f>3</f>
<f>2</f>
<parameter>Товар</parameter>
</c>
</c>
<c>
<i>1</i>
<c>
<f>3</f>
<f>2</f>
<parameter>Кол</parameter>
</c>
</c>
<c>
<i>3</i>
<c>
<f>4</f>
<f>3</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -117,9 +117,6 @@
<format>
<width>10</width>
</format>
<format>
<font>0</font>
</format>
<format>
<font>0</font>
<fillType>Parameter</fillType>
@@ -18,7 +18,7 @@
<c>
<i>0</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -30,7 +30,7 @@
<c>
<i>1</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -42,7 +42,7 @@
<c>
<i>2</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -71,7 +71,4 @@
<format>
<width>10</width>
</format>
<format>
<font>0</font>
</format>
</document>
@@ -18,7 +18,7 @@
<c>
<i>0</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -30,7 +30,7 @@
<c>
<i>1</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -42,7 +42,7 @@
<c>
<i>2</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -59,7 +59,7 @@
<c>
<i>0</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -76,21 +76,21 @@
<c>
<i>0</i>
<c>
<f>3</f>
<f>2</f>
<parameter>П1</parameter>
</c>
</c>
<c>
<i>1</i>
<c>
<f>3</f>
<f>2</f>
<parameter>П2</parameter>
</c>
</c>
<c>
<i>2</i>
<c>
<f>3</f>
<f>2</f>
<parameter>П3</parameter>
</c>
</c>
@@ -129,9 +129,6 @@
<format>
<width>10</width>
</format>
<format>
<font>0</font>
</format>
<format>
<font>0</font>
<fillType>Parameter</fillType>
@@ -18,7 +18,7 @@
<c>
<i>0</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -30,7 +30,7 @@
<c>
<i>1</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -59,7 +59,4 @@
<format>
<width>10</width>
</format>
<format>
<font>0</font>
</format>
</document>
@@ -18,7 +18,7 @@
<c>
<i>0</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -30,7 +30,7 @@
<c>
<i>1</i>
<c>
<f>3</f>
<f>2</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -59,9 +59,6 @@
<format>
<width>10</width>
</format>
<format>
<font>0</font>
</format>
<format>
<font>0</font>
<fillType>Template</fillType>
@@ -18,7 +18,7 @@
<c>
<i>0</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -30,7 +30,7 @@
<c>
<i>1</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -42,7 +42,7 @@
<c>
<i>2</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -71,7 +71,4 @@
<format>
<width>10</width>
</format>
<format>
<font>0</font>
</format>
</document>
@@ -30,7 +30,7 @@
<c>
<i>0</i>
<c>
<f>3</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -55,14 +55,14 @@
<c>
<i>0</i>
<c>
<f>5</f>
<f>4</f>
<parameter>НомерСтроки</parameter>
</c>
</c>
<c>
<i>1</i>
<c>
<f>5</f>
<f>4</f>
<parameter>Товар</parameter>
<detailParameter>Номенклатура</detailParameter>
</c>
@@ -70,21 +70,21 @@
<c>
<i>2</i>
<c>
<f>6</f>
<f>5</f>
<parameter>Количество</parameter>
</c>
</c>
<c>
<i>3</i>
<c>
<f>6</f>
<f>5</f>
<parameter>Цена</parameter>
</c>
</c>
<c>
<i>4</i>
<c>
<f>6</f>
<f>5</f>
<parameter>Сумма</parameter>
</c>
</c>
@@ -96,7 +96,7 @@
<c>
<i>3</i>
<c>
<f>7</f>
<f>6</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -108,7 +108,7 @@
<c>
<i>4</i>
<c>
<f>8</f>
<f>7</f>
<parameter>Всего</parameter>
</c>
</c>
@@ -185,9 +185,6 @@
<font>0</font>
<fillType>Parameter</fillType>
</format>
<format>
<font>0</font>
</format>
<format>
<font>0</font>
<leftBorder>0</leftBorder>
@@ -18,7 +18,7 @@
<c>
<i>0</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -30,7 +30,7 @@
<c>
<i>1</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -42,7 +42,7 @@
<c>
<i>2</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -71,7 +71,4 @@
<format>
<width>10</width>
</format>
<format>
<font>0</font>
</format>
</document>
@@ -18,7 +18,7 @@
<c>
<i>0</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -30,7 +30,7 @@
<c>
<i>1</i>
<c>
<f>3</f>
<f>2</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -47,7 +47,7 @@
<c>
<i>0</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -59,7 +59,7 @@
<c>
<i>1</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -71,7 +71,7 @@
<c>
<i>2</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -88,21 +88,21 @@
<c>
<i>0</i>
<c>
<f>4</f>
<f>3</f>
<parameter>Код</parameter>
</c>
</c>
<c>
<i>1</i>
<c>
<f>4</f>
<f>3</f>
<parameter>Наименование</parameter>
</c>
</c>
<c>
<i>2</i>
<c>
<f>4</f>
<f>3</f>
<parameter>Сумма</parameter>
</c>
</c>
@@ -151,9 +151,6 @@
<format>
<width>10</width>
</format>
<format>
<font>0</font>
</format>
<format>
<font>0</font>
<fillType>Template</fillType>
@@ -18,7 +18,7 @@
<c>
<i>0</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -30,7 +30,7 @@
<c>
<i>1</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -42,7 +42,7 @@
<c>
<i>2</i>
<c>
<f>2</f>
<f>1</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
@@ -71,7 +71,4 @@
<format>
<width>10</width>
</format>
<format>
<font>0</font>
</format>
</document>