Repository navigation
Conversation
Excel 2010+ keeps conditional format rules whose formulas refer to
other sheets only in the worksheet's x14:conditionalFormattings
extension, with xm:f formulas and an inline x14:dxf in place of a
dxfId. GridCraft skipped the whole extension with a warning.
Read: x14 cellIs (every operator, one or two formulas), expression,
blanks, errors, duplicate/unique, top 10, above average and time
period rules become ordinary rules, with the inline differential
format (font, fill, border, number format) and priorities that
interleave with the main section's. A data bar's linked extension
(the x14:id of a main-section rule) adds no second rule. Other x14
kinds (data bar settings, x14 icon sets) are skipped with a warning
naming the kind.
Evaluate: cross-sheet references in rule formulas already resolve;
an engine test pins cellIs and expression rules against cells on
another sheet.
Write: a cell-value or formula rule referring to another sheet is
written in the x14 extension ({78C0D931-6437-407d-A8EE-F0AAD7539E65})
with an inline x14:dxf and a unique id; other rules stay in the main
section. The extension shares one extLst with the sparklines (CF
first). Inline number formats get ids styles.xml declares.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Colour scale, data bar and icon set rules are always written in the main section, even when their cfvo formulas refer to other sheets; the parity docs now say so. (This commit first dropped the reader's own x14:id linking; after the rebase onto main, main's data bar linking from storytold#550 is the one path, so only the docs part remains.)
…kinds The file that motivated the x14 conditional format work (watchdog-report.xlsx) was saved by LibreOffice 25.2, not Excel, so nothing observed in Excel backs the earlier commit's statement that Excel 2010+ keeps cross-sheet rules only in the extension. MS-XLSX 2.6.27 (CT_CfRule) allows single-sheet references in xm:f but says nothing about where Excel places such rules; the comments and docs now say the placement follows the LibreOffice-saved file and Excel's own is unverified. MS-XLSX 2.6.27 forbids sheet-range-reference (3-D spans) in xm:f, so a rule with a 3-D span now stays in the main section. The parity docs and gaps list name the x14 kinds read (cellIs, expression, blanks, errors, duplicate/unique, top10, aboveAverage, timePeriod) and those skipped with a warning and lost on save (data bars, icon sets, colour scales, containsText, notContainsText, beginsWith, endsWith). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dxf_xml, which writes both styles.xml dxfs and inline x14:dxf elements, wrote font, number format, fill, alignment and border but never protection, although read_dxf reads it. A rule whose format unlocked or hid cells lost that on save. It now writes protection after border, the order CT_Dxf requires.
…ounds and their lengths (fixes storytold#1158, storytold#1159) Excel writes Automatic and Lowest/Highest Value both as min/max in the main section; only the x14 rule tells them apart (autoMin/autoMax), and it holds the bar lengths. GridCraft read both as Min/Max, evaluated Min as Automatic, wrote its bars without x14 bounds (Excel reads them as Lowest/Highest Value, 10-90 %), and drew every bar as frac * 0.9 + 0.1 from 0. - Model: CfValueKind::AutoMin/AutoMax; DataBar min_length/max_length (10/90 by default). - Evaluation: only Automatic pulls a positive minimum to 0; the bar is minLength + frac * (maxLength - minLength), as Excel draws it without an axis. - XLSX: autoMin/autoMax and the lengths are read from the linked x14 rule (and the main section's lengths); written as min/max plus an x14 rule with autoMin/autoMax whenever a bar needs one (solid, Automatic, or lengths other than 10-90). - home.conditionalFormat: data bars default to Automatic, 0-100 %, as Excel's gallery. Measured in Excel for Microsoft 365: a file this branch writes opens with Automatic, Lowest/Highest and Number bounds and the lengths as written, and the bar lengths match. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SAgnkqJiy3v24Hp25dQLRj
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1158 and #1159. Data bars told Excel's Automatic bounds and Lowest/Highest Value apart nowhere, and drew every bar from 0 with a fixed 10 % head start.
Builds on #717 (Excel 2010 conditional formats, @neilcawse). That PR moves the x14 data bar reader and writer this one extends, so this branch starts from its head (6f0f747) and contains its four commits until it merges. Please merge #717 first; I'll rebase this one onto
mainthen.Problem
<cfvo type="min"/>/maxin the main section; only the x14 rule tells them apart (autoMin/autoMax). GridCraft read both asMin/Maxand evaluatedMinas Automatic. It wrote its own bars without x14 bounds, which Excel reads as Lowest/Highest Value. So a bar made in GridCraft looked different in Excel, and an Excel bar with Lowest Value looked different in GridCraft.CfCache::lookpulled every positive minimum to 0 and drewfrac × 0.9 + 0.1. A bar with a fixed minimum (Number, Percent, Percentile, Formula, Lowest Value) was too long, and a value at the minimum got half a bar instead of none. The bar lengths in the file (minLength/maxLength) were ignored.Fix
features.rs):CfValueKind::AutoMinandAutoMax, documented as data-bar only.CfRule::DataBargetsmin_lengthandmax_length(percent of the cell). The serde defaults are 10 and 90, a file's defaults.cf.rs):minLength + frac × (maxLength − minLength)of the cell, withfrac = (value − min) / (max − min)clamped to 0…1.sheet_read.rs):autoMin/autoMaxbecomeAutoMin/AutoMax.minLength/maxLengthare read too.sheet_write.rs):min/maxin the main section andautoMin/autoMaxin the x14 rule, as Excel does.solid_bar_*helpers becomebar_x14_*.home.conditionalFormatdata bars default to Automatic and 0–100 %, as Excel's Data Bars gallery makes them.min/maxalso takeautoMin/autoMax. The ribbon gallery and the sample workbooks get Automatic bars.Measured in Excel for Microsoft 365
A file written by this branch, opened in its own Excel instance. Bounds, fill and lengths come from COM (
Databar.MinPoint.Type,BarFillType,PercentMin/PercentMax). Bar length is a fraction of the full bar, from a capture of Excel's window (solid bars).{"type": "dataBar"}over 10…20min/maxover 10…20min/max, 10–90 (no x14 rule)These are the values
data_bar_lengths_as_in_excelexpects, with #1158's table for Percent, Percentile and Formula.Bar lengths and the axis. The lengths behave as above only without an axis. Measured over 0…10, Lowest to Highest, solid:
minLength–maxLengthaxisPosition="none")With Excel's automatic axis, a nonzero shortest bar is halved:
minLength/2 + frac × (maxLength − minLength). A bar without an x14 rule (Excel 2007, other writers; 10–90) is drawn like the no-axis column.GridCraft draws no axis, which is #781's work, so it draws every bar like the no-axis column. That matches Excel for:
Only a bar with a nonzero
minLengthfrom VBA or another writer, on Excel's automatic axis, still differs. For that reasonhome.conditionalFormattakes no length parameters.Testing
data_bar_lengths_as_in_excel(engine): the command's default bar and Number, Percent, Percentile, Formula and Lowest/Highest bounds, against the measured values (tolerance 0.02).data_bar_lengths_from_a_file(engine): lengths 10–90, 50–100, 20–100 and 40–60, against the no-axis measurements.data_bar_bounds_and_lengths(xlsx), from Excel-shaped XML:AutoMin/AutoMax, 0–100, one "partly skipped" warning);Writing it back gives three x14 rules with the expected bounds and lengths, no
autoMinin the main section, and the same rules on reading, without warnings.XLSX: read, evaluate and write Excel 2010 conditional formats #717's
x14_conditional_formats_are_read: its x14 bar (Automatic, 0–100, solid) now reads with those bounds and lengths. It no longer warns, since the model holds all of its settings.full_roundtrip: its data bar carries lengths 5–95.cargo xtask ci: fmt, clippy, test, assets, layers and wasm pass.parityandkeytipsreport their generated files out of date on this Windows checkout (core.autocrlf).git diffis empty, as onmain.gridcraft-xlsx(176 tests) and the engine'scf::tests pass again.Conflicts:
home.conditionalFormatparameter line and the icon-set arm next to the data bar arm ininsert.rs.The merges are mechanical.
🤖 Generated with Claude Code
https://claude.ai/code/session_01SAgnkqJiy3v24Hp25dQLRj