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

"3D Range references are not yet supported" error when trying to use GROUPBY, is there a way to support it? #4282

Open
2 of 8 tasks
cuartas15 opened this issue Dec 17, 2024 · 6 comments

Comments

@cuartas15
Copy link

cuartas15 commented Dec 17, 2024

This is:

- [x] a bug report?
- [x] a feature request
- [ ] **not** a usage question (ask them on https://stackoverflow.com/questions/tagged/phpspreadsheet or https://gitter.im/PHPOffice/PhpSpreadsheet)

What is the expected behavior?

That a =GROUPBY formula works

What is the current behavior?

It doesn't work, throwing the error "3D Range references are not yet supported"

What are the steps to reproduce?

Have a table with dates and values, in a different sheet try to group them by dates and values so it sums the total on each date, like this:
$workSheet2->setCellValue('A1', '=GROUPBY(Report!B2:B' . (count($data) + 1) . ';Report!D2:D' . (count($data) + 1) . ';SUM)');

Please provide a Minimal, Complete, and Verifiable example of code that exhibits the issue without relying on an external Excel file or a web server:

<?php
$spreadsheet = new Spreadsheet();
$workSheet = $spreadsheet->getSheet(0);
$workSheet->setTitle('Report');

$data = array(
    ['anything', '2024-12-10', 'anything', '5000'],
    ['anything', '2024-12-10', 'anything', '2500'],
    ['anything', '2024-12-09', 'anything', '12000'],
    ['anything', '2024-12-09', 'anything', '100'],
);

$workSheet->fromArray($data, '', 'A2');

$workSheet2 = new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet($spreadsheet, 'Dynamic');
$spreadsheet->addSheet($workSheet2);
$workSheet2->setTitle('Dynamic table');

$workSheet2->setCellValue('A1', '=GROUPBY(Report!B2:B' . (count($data) + 1) . ';Report!D2:D' . (count($data) + 1) . ';SUM)');
?>

What features do you think are causing the issue

  • Reader
  • Writer
  • Styles
  • Data Validations
  • Formula Calculations
  • Charts
  • AutoFilter
  • Form Elements

Does an issue affect all spreadsheet file formats? If not, which formats are affected?

At least xlsx

Which versions of PhpSpreadsheet and PHP are affected?

PhpSpreadsheet 1.29.6
PHP 7.4

@oleibman
Copy link
Collaborator

I am not aware of any imminent plans to support GROUPBY.

However, I am puzzled by your "3D Range references". I run your code and don't see such a message. And I don't see any 3D references in your code. Is there a section of code that you have not provided?

@oleibman
Copy link
Collaborator

Ah, yes, when I try to save the file, I see the 3D message. I'll take a look.

@oleibman
Copy link
Collaborator

When I change the semi-colons in your formula to commas, the 3D message goes away.

@cuartas15
Copy link
Author

cuartas15 commented Dec 17, 2024

When I change the semi-colons in your formula to commas, the 3D message goes away.

Yeah I remember trying it with commas yesterday but the file wouldn't just open, excel would say the file is broken.
But in any case, by your comments, it's confirmed GROUPBY isn't supported by the library at all?

@oleibman
Copy link
Collaborator

When I save, Excel does not object to the result, but the GROUPBY cells aren't particularly useful. I can put support for GROUPBY on my to-do list, but I'm sure it will take me a while before I can get to it. Apart from implementing the function, Excel has added a whole new means of tagging the third (function) argument, e.g. the formula stored in the XML might be:

<f t="array" ref="E3:F8">_xlfn.GROUPBY(B2:B32, C2:C32, _xleta.SUM, 3)</f>

The _xlfn part we're long used to, but _xleta is new and potentially difficult.

oleibman added a commit to oleibman/PhpSpreadsheet that referenced this issue Dec 19, 2024
This is a partial response to issue PHPOffice#4282. The actual logic to implement GROUPBY is probably very complicated. And, even worse, Excel has thrown a whole new way of (internally) specifying one of the arguments into the mix. That argument is a function name, expressed not as a mapped integer (as SUBTOTAL does), nor even as a string, but as the unquoted function name prefixed by `_xleta.`. And, unlike its `_xlfn.` and `_xlws.` predecessors, it is difficult to figure out when the new prefix needs to be added, and when it needs to be ignored. I am not even going to attempt that task with this ticket.

So, what does this change do? Like earlier attempts to introduce limited functionality (such as with form controls), it is there so that using GROUPBY can be passed through - you can load a spreadsheet that contains it, and save it to a new spreadsheet, and the function and its results are preserved. Some cautionary notes. Dynamic arrays must be enabled (the function makes no sense without doing that). Changing any of the inputs used in the function may result in internal inconsistencies between PhpSpreadsheet and Excel; this is especially so if the dimensions of the returned array change as a result of changes to the input data. The programmer can avoid some of these problems by changing the formulatAttributes of the cell where the function is used; this may be difficult to do in practice. Oh, yes, using the GROUPBY cell as an argument in another formula will probably lead to problems. Finally, I confess that part of this solution looks awfully kludgey to me.

With its limitations and those cautions, is it worth proceeding with this change? My gut feel is that it is more useful to proceed than not. However, I will give others the opportunity to weigh in. I will wait at least a couple of weeks into the new year before proceeding with this.
@oleibman
Copy link
Collaborator

PR #4283 will provide some relief for you. In particular, note #4283 (comment). It's far from ideal, but it may help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants