diff --git a/.claude/skills/mxl-compile/SKILL.md b/.claude/skills/mxl-compile/SKILL.md index 70972934..e2599df2 100644 --- a/.claude/skills/mxl-compile/SKILL.md +++ b/.claude/skills/mxl-compile/SKILL.md @@ -142,6 +142,7 @@ powershell.exe -NoProfile -File .claude/skills/mxl-compile/scripts/mxl-compile.p | `border` | — | Стороны рамки: `all`, `top`, `bottom`, `left`, `right`, `none`. Через запятую: `"top,bottom"` | | `borderWidth` | `"thin"` | Толщина рамки: `thin` (1px) или `thick` (2px) | | `wrap` | `false` | Перенос текста | +| `numberFormat` | — | Формат числа 1С, например `"ЧЦ=15; ЧДЦ=2"` | ### Области (`areas[]`) @@ -165,7 +166,8 @@ powershell.exe -NoProfile -File .claude/skills/mxl-compile/scripts/mxl-compile.p | Поле | Обяз. | По умолч. | Описание | |------|:-----:|-----------|----------| | `col` | да | — | Позиция колонки (1-based) | -| `span` | нет | `1` | Количество объединённых колонок | +| `span` | нет | `1` | Объединение по горизонтали (количество колонок) | +| `rowspan` | нет | `1` | Объединение по вертикали (количество строк) | | `style` | нет | rowStyle | Стиль ячейки (переопределяет rowStyle) | | `param` | нет | — | Параметр заполнения | | `detail` | нет | — | Параметр расшифровки (только с `param`) | @@ -187,8 +189,6 @@ powershell.exe -NoProfile -File .claude/skills/mxl-compile/scripts/mxl-compile.p - Множественные наборы колонок - Области типа Columns / Rectangle - Рисунки (штрихкоды, картинки) -- Объединение по строкам (rowspan) -- Числовые форматы - Фон ячеек Эти возможности будут добавлены в будущих версиях без переделки основной архитектуры. diff --git a/.claude/skills/mxl-compile/scripts/mxl-compile.ps1 b/.claude/skills/mxl-compile/scripts/mxl-compile.ps1 index b05377b5..28082fd3 100644 --- a/.claude/skills/mxl-compile/scripts/mxl-compile.ps1 +++ b/.claude/skills/mxl-compile/scripts/mxl-compile.ps1 @@ -138,7 +138,7 @@ function Resolve-Style { $fontIdx = $fontMap["default"] $lb = -1; $tb = -1; $rb = -1; $bb = -1 - $ha = ""; $va = "" + $ha = ""; $va = ""; $nf = "" $wrap = $false if ($styleName -and $def.styles) { @@ -180,15 +180,19 @@ function Resolve-Style { # Wrap if ($style.wrap -eq $true) { $wrap = $true } + + # Number format + if ($style.numberFormat) { $nf = $style.numberFormat } } } return @{ - FontIdx = $fontIdx - LB = $lb; TB = $tb; RB = $rb; BB = $bb - HA = $ha; VA = $va - Wrap = $wrap - FillType = $fillType + FontIdx = $fontIdx + LB = $lb; TB = $tb; RB = $rb; BB = $bb + HA = $ha; VA = $va + Wrap = $wrap + FillType = $fillType + NumberFormat = $nf } } @@ -204,10 +208,11 @@ function Get-FormatKey { [string]$ha = "", [string]$va = "", [bool]$wrap = $false, [string]$fillType = "", + [string]$numberFormat = "", [int]$width = -1, [int]$height = -1 ) - return "f=$fontIdx|lb=$lb|tb=$tb|rb=$rb|bb=$bb|ha=$ha|va=$va|wr=$wrap|ft=$fillType|w=$width|h=$height" + return "f=$fontIdx|lb=$lb|tb=$tb|rb=$rb|bb=$bb|ha=$ha|va=$va|wr=$wrap|ft=$fillType|nf=$numberFormat|w=$width|h=$height" } function Register-Format { @@ -263,14 +268,16 @@ function Register-CellFormat { $key = Get-FormatKey -fontIdx $resolved.FontIdx ` -lb $resolved.LB -tb $resolved.TB -rb $resolved.RB -bb $resolved.BB ` -ha $resolved.HA -va $resolved.VA ` - -wrap $resolved.Wrap -fillType $resolved.FillType + -wrap $resolved.Wrap -fillType $resolved.FillType ` + -numberFormat $resolved.NumberFormat $props = @{ - FontIdx = $resolved.FontIdx - LB = $resolved.LB; TB = $resolved.TB - RB = $resolved.RB; BB = $resolved.BB - HA = $resolved.HA; VA = $resolved.VA - Wrap = $resolved.Wrap - FillType = $resolved.FillType + FontIdx = $resolved.FontIdx + LB = $resolved.LB; TB = $resolved.TB + RB = $resolved.RB; BB = $resolved.BB + HA = $resolved.HA; VA = $resolved.VA + Wrap = $resolved.Wrap + FillType = $resolved.FillType + NumberFormat = $resolved.NumberFormat } return Register-Format -key $key -props $props } @@ -351,8 +358,20 @@ $totalRowCount = 0 foreach ($area in $def.areas) { $areaStartRow = $globalRow $areaName = $area.name + $activeRowspans = @() # @{ColStart=1-based; ColEnd=1-based; EndLocalRow=int} + $localRow = 0 foreach ($row in $area.rows) { + # Build set of columns occupied by rowspans from previous rows + $rowspanOccupied = @{} # 1-based col -> $true + foreach ($rs in $activeRowspans) { + if ($localRow -gt $rs.StartLocalRow -and $localRow -le $rs.EndLocalRow) { + for ($c = $rs.ColStart; $c -le $rs.ColEnd; $c++) { + $rowspanOccupied[$c] = $true + } + } + } + $rowHasContent = $false $rowCells = @() # array of { Col(0-based), FormatIdx, Content } @@ -371,8 +390,9 @@ foreach ($area in $def.areas) { if ($row.cells -and $row.cells.Count -gt 0) { $rowHasContent = $true - # Build set of occupied columns (1-based) + # Build set of occupied columns (1-based): explicit cells + rowspan from above $occupiedCols = @{} + foreach ($rsk in $rowspanOccupied.Keys) { $occupiedCols[$rsk] = $true } foreach ($cell in $row.cells) { $colStart = [int]$cell.col $colSpan = if ($cell.span) { [int]$cell.span } else { 1 } @@ -385,6 +405,7 @@ foreach ($area in $def.areas) { foreach ($cell in $row.cells) { $colStart = [int]$cell.col $colSpan = if ($cell.span) { [int]$cell.span } else { 1 } + $rowspan = if ($cell.rowspan) { [int]$cell.rowspan } else { 1 } $cellStyle = if ($cell.style) { $cell.style } elseif ($row.rowStyle) { $row.rowStyle } else { "default" } $ft = Get-FillType $cell $fmtIdx = Register-CellFormat -styleName $cellStyle -fillType $ft @@ -399,14 +420,22 @@ foreach ($area in $def.areas) { } $rowCells += $cellInfo - # Collect merge - if ($colSpan -gt 1) { - $merges += @{ - R = $globalRow - C = $colStart - 1 - W = $colSpan - 1 + # Track rowspan for subsequent rows + if ($rowspan -gt 1) { + $activeRowspans += @{ + ColStart = $colStart + ColEnd = $colStart + $colSpan - 1 + StartLocalRow = $localRow + EndLocalRow = $localRow + $rowspan - 1 } } + + # Collect merge (horizontal, vertical, or both) + if ($colSpan -gt 1 -or $rowspan -gt 1) { + $merge = @{ R = $globalRow; C = $colStart - 1; W = $colSpan - 1 } + if ($rowspan -gt 1) { $merge.H = $rowspan - 1 } + $merges += $merge + } } # Generate gap-fill cells for rowStyle @@ -430,12 +459,13 @@ foreach ($area in $def.areas) { $rowCells = $rowCells | Sort-Object { $_.Col } } elseif ($row.rowStyle) { - # Row with only rowStyle, no explicit cells — fill all columns + # Row with only rowStyle, no explicit cells — fill non-rowspan columns $rowHasContent = $true $gapFmtIdx = Register-CellFormat -styleName $row.rowStyle -fillType "" - for ($c = 0; $c -lt $totalColumns; $c++) { + for ($c = 1; $c -le $totalColumns; $c++) { + if ($rowspanOccupied.ContainsKey($c)) { continue } $rowCells += @{ - Col = $c + Col = $c - 1 FormatIdx = $gapFmtIdx Param = $null Detail = $null @@ -496,6 +526,7 @@ foreach ($area in $def.areas) { X "`t`t" X "`t" + $localRow++ $globalRow++ } @@ -520,6 +551,7 @@ foreach ($m in $merges) { X "`t" X "`t`t$($m.R)" X "`t`t$($m.C)" + if ($m.H) { X "`t`t$($m.H)" } X "`t`t$($m.W)" X "`t" } @@ -593,6 +625,14 @@ foreach ($key in $formatRegistry.Keys) { if ($fmt.FillType) { X "`t`t$($fmt.FillType)" } + if ($fmt.NumberFormat) { + X "`t`t" + X "`t`t`t" + X "`t`t`t`tru" + X "`t`t`t`t$(Esc-Xml $fmt.NumberFormat)" + X "`t`t`t" + X "`t`t" + } X "`t" }