-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conditional Range Unions and Intersections #4042
Conversation
Fix PHPOffice#4039. Excel sometimes stores the location for a Conditional as, say, `B1:B10 C1:C10` rather than `B1:C10`. PhpSpreadsheet does not have a problem with this, but internally stores it as separate Conditionals, one for each range. (There may be more than 2.) User would like it stored as a single Conditional. Since the range is used as the index of an array which holds the conditionals, there is no technical reason why this can't be done. And it does seem like being able to change multiple ranges all at once has some advantages, whether you're doing it in PhpSpreadsheet or in Excel itself. Making such a change in Xlsx Reader showed no problem in Xlsx Reader and Writer tests. A number of problems did show up in CellMatcherTest, and one in WizardFactoryTest. This was good news, because it meant some of our test spreadsheets used the same type of construction as the test spreadsheet supplied with the issue. So, if additional fixes make the test problems go away, I think no new tests are required. And a smattering of source changes did indeed result in a clean test suite once more. This is a change, but I don't really think it should break anyone. So I don't think it's necessary to add an option to opt in to the old or new behavior. I could be wrong. I'll leave this ticket open for at least a couple of weeks to see if anyone thinks otherwise.
There is additional discussion of this topic in issue #3206. |
And, following on that discussion, there is more Excel weirdness. Nominally, the intersection operation for cell ranges is a space, and the union operator is a comma. Now, let's take a look at a worksheet.
The separator is comma, and this is treated as a union, as intended. But ... what do we see in the Xml? <conditionalFormatting sqref="A1:A3 C1:E3"> Here the separator is space, not comma. Excel is treating it as a union despite the apparent use of the intersection operator! And, not surprisingly, further testing seems to indicate that the use of comma as separator in the xml is treated by Excel as intersection, not union. I need to take some time to figure out how to differentiate ranges loaded from a spreadsheet vs. ranges entered via So, expect some delay in merging this PR. |
Xls Reader expects only simple ranges, not union or intersection. Therefore, Xls Writer needs to split union ranges into separate ranges before writing. |
I don't know why MS did this. We're stuck with it.
Updated branch to pull in some recent Conditional changes, not because PR is close to ready. |
Provide a means to convert a range, possibly with unions and possibly with intersections, into something that both Excel and PhpSpreadsheet can handle. Intersections are changed into unions of the individual cells which they comprise. With this change, Xls Writer now handles intersections (previously it would have thrown an Exception or created a corrupt worksheet if this was attempted), and Xlsx Writer works correctly (it seemed to before, but Excel didn't understand what it wrote). Worksheet::getConditionalRange and ::getConditionalStyles would previously have thrown an Exception when presented with an intersection, and will no longer do so. **NOTE:** Intersection support is limited to Conditional ranges. Use of intersections in other contexts will usually not achieve the desired result.
Taking out of draft status. I think the code has gone as far as it needs. I need to think about whether additional tests are needed. AFAICT, intersection and union are now completely supported for Xlsx/Xls Conditional; but intersection may not be fully supported in other contexts. |
Fix #4039. Excel sometimes stores the location for a Conditional as, say,
B1:B10 C1:C10
rather thanB1:C10
. PhpSpreadsheet does not have a problem with this, but internally stores it as separate Conditionals, one for each range. (There may be more than 2.) User would like it stored as a single Conditional. Since the range is used as the index of an array which holds the conditionals, there is no technical reason why this can't be done. And it does seem like being able to change multiple ranges all at once has some advantages, whether you're doing it in PhpSpreadsheet or in Excel itself.Making such a change in Xlsx Reader showed no problem in Xlsx Reader and Writer tests. A number of problems did show up in CellMatcherTest, and one in WizardFactoryTest. This was good news, because it meant some of our test spreadsheets used the same type of construction as the test spreadsheet supplied with the issue. So, if additional fixes make the test problems go away, I think no new tests are required. And a smattering of source changes did indeed result in a clean test suite once more.
This is a change, but I don't really think it should break anyone. So I don't think it's necessary to add an option to opt in to the old or new behavior. I could be wrong. I'll leave this ticket open for at least a couple of weeks to see if anyone thinks otherwise.
This is:
Checklist:
Why this change is needed?
Provide an explanation of why this change is needed, with links to any Issues (if appropriate).
If this is a bugfix or a new feature, and there are no existing Issues, then please also create an issue that will make it easier to track progress with this PR.