Skip to content
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

WIP Excel Adding At-Signs to Functions #3962

Draft
wants to merge 15 commits into
base: master
Choose a base branch
from

Commits on Mar 27, 2024

  1. WIP Excel Adding At-Signs to Functions

    This has come up a number of times, most recently with issue PHPOffice#3901, and also issue PHPOffice#3659. It will certainly come up more often in days to come. Excel is changing formulas which PhpSpreadsheet has output as `=UNIQUE(A1:A19)`; Excel is processing the formula as it were `=@unique(A1:A19)`. This behavior is explained, in part, by PHPOffice#3659 (comment). It is doing so in order to ensure that the function returns only a single value rather than an array of values, in case the spreadsheet is being processed (or possibly was created) by a less current version of Excel which cannot handle the array result.
    
    PhpSpreadsheet follows Excel to a certain extent; it defaults to returning a single calculated value when an array would be returned. Further, its support for outputting an array even when that default is overridden is incomplete. I am not prepared to do everything that Excel does for the array functions (details below), but this PR is a start in that direction. If the default is changed via:
    ```php
    use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
    Calculation::setArrayReturnType(Calculation::RETURN_ARRAY_AS_ARRAY);
    ```
    When that is done, `getCalculatedValue` will return an array (no code change necessary). However, Writer/Xlsx will now be updated to look at that value, and if an array is returned in that circumstance, will indicate in the Xml that the result is an array *and* will include a reference to the bounds of the array. This gets us close, although not completely there, to what Excel does, and may be good enough for now. Excel will still mess with the formula, but now it will treat it as `{=UNIQUE(A1:A19)}`. This means that the spreadsheet will now look correct; there will be superficial differences, but all cells will have the expected value.
    
    Technically, the major difference between what PhpSpreadsheet will output now, and what Excel does on its own, is that Excel supplies values in the xml for all the cells in the range. That would be difficult for PhpSpreadsheet to do; that could be a project for another day. Excel will treat the output from PhpSpreadsheet as "Array Formulas" (a.k.a. CSE (control shift enter) formulas because you need to use that combination of keys to manually enter them in older versions of Excel). Current versions of Excel will instead use "Dynamic Array Formulas". Dynamic Array Formulas can be changed by the user; Array Formulas need to be deleted and re-entered if you want to change them. I don't know what else might have to change to get Excel to use the latter for PhpSpreadsheet formulas, and I will probably not even try to look now, saving it for a future date.
    
    Unit testing of this change uncovered a bug in Calculation::calculateCellValue. That routine saves off ArrayReturnType, and may change it, and is supposed to restore it. But it does not do the restore if the calculation throws an exception. It is changed to do so.
    oleibman committed Mar 27, 2024
    Configuration menu
    Copy the full SHA
    be25c44 View commit details
    Browse the repository at this point in the history

Commits on Apr 17, 2024

  1. Xlsx Reader Use Dimensions from Functions With Array Results

    Thinking about PHPOffice#3958 - user wondered if unsupported formulas with array results could be handled better. I said that the answer was "no", but I think Xlsx Reader can make use of the dimensions of the result after all, so the answer is actually "sometimes". This is an initial attempt to do that. Implementing it revealed a bug in how Xlsx Reader handles array formula attributes, and that is now corrected. Likewise, Xlsx Writer did not indicate a value for the first cell in the array, and does now.
    oleibman committed Apr 17, 2024
    Configuration menu
    Copy the full SHA
    b53a4b7 View commit details
    Browse the repository at this point in the history

Commits on Apr 19, 2024

  1. Sample Submitted by @jr212

    Address sample code submitted by @jr212 which was not working correctly.
    oleibman committed Apr 19, 2024
    Configuration menu
    Copy the full SHA
    61f24ca View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    74f312b View commit details
    Browse the repository at this point in the history

Commits on May 31, 2024

  1. Configuration menu
    Copy the full SHA
    c78888c View commit details
    Browse the repository at this point in the history

Commits on Jun 3, 2024

  1. Configuration menu
    Copy the full SHA
    5e7ebf3 View commit details
    Browse the repository at this point in the history

Commits on Jun 5, 2024

  1. Configuration menu
    Copy the full SHA
    b79cd20 View commit details
    Browse the repository at this point in the history

Commits on Jun 6, 2024

  1. Populate Rest of Array Cells, UNIQUE Changes

    See issue PHPOffice#4062. When calculating an array formula, populate all the cells associated with the result. This is almost the same as Excel's behavior. As yet, there is no attempt to create a #SPILL error, so cells may be inappropriately overwritten. Also, if the array size shrinks (e.g. there are fewer unique values than before),  no attempt is made to unpopulate the cells which were in range but are now outside the new dimensions. Spill and unpopulation are somewhat related, and will probably be handled at the same time, but their time has not yet come.
    
    UNIQUE, at least for rows, was treating all cell (calculated) values as strings. This is not the same behavior as Excel, which will preserve datatypes, and treat int 3 and string 3 as unique values. Excel will, however, treat int 3 and float 3.0 as non-unique. Within UNIQUE, private function uniqueByRow is changed to try to preserve the the datatype when executing (it will probably treat 3.0 as int - I don't know how I can, or even if I should attempt to, do better - but no int nor float should be treated as a string).
    oleibman committed Jun 6, 2024
    Configuration menu
    Copy the full SHA
    08ba00b View commit details
    Browse the repository at this point in the history
  2. Formatting

    oleibman committed Jun 6, 2024
    Configuration menu
    Copy the full SHA
    856a00b View commit details
    Browse the repository at this point in the history
  3. Incorrect Case for Filename

    oleibman committed Jun 6, 2024
    Configuration menu
    Copy the full SHA
    1b21984 View commit details
    Browse the repository at this point in the history
  4. More Formatting

    Frustrating morning.
    oleibman committed Jun 6, 2024
    Configuration menu
    Copy the full SHA
    47481c6 View commit details
    Browse the repository at this point in the history
  5. Still More Formatting

    I think I should go back to bed.
    oleibman committed Jun 6, 2024
    Configuration menu
    Copy the full SHA
    6b5bf84 View commit details
    Browse the repository at this point in the history
  6. Add TODO Note

    ArrayFunctions2Test - the calculations seem too complicated for PhpSpreadsheet. The debug log is 21,300 lines, so I don't know how far I will get with it.
    oleibman committed Jun 6, 2024
    Configuration menu
    Copy the full SHA
    3daac0a View commit details
    Browse the repository at this point in the history

Commits on Jun 10, 2024

  1. Excel Handle Array Functions as Dynamic Rather than CSE

    With a number of changes, PhpSpreadsheet can finally generate a spreadsheet which Excel will recognize as a Dynamic Array function rather than CSE. In particular, changes are needed to ContentTypes, workbook.xml.rels, cell definitions in the worksheet, and a new metadata.xml is added.
    oleibman committed Jun 10, 2024
    Configuration menu
    Copy the full SHA
    ef176f3 View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    846fec7 View commit details
    Browse the repository at this point in the history