From cda404d596bb5708c959800c0fab1640e1bdb86c Mon Sep 17 00:00:00 2001 From: oleibman <10341515+oleibman@users.noreply.github.com> Date: Sat, 20 Sep 2025 20:15:01 -0700 Subject: [PATCH] Handling Unions as Function Arguments Fix #4656. (Also fix #503, which went stale years ago, and which I reopened, and which I re-closed in a state of confusion.) Continuing the work of PR #4596. Calculation engine was unable to parse a formula which used union arguments. (I find it very difficult to parse as well.) This PR will, I hope, fix that. More tests are needed. --- .../Calculation/Calculation.php | 8 ++-- .../Calculation/Issue4656Test.php | 38 +++++++++++++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 tests/PhpSpreadsheetTests/Calculation/Issue4656Test.php diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index abdd4c811a..0d502e1817 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -1236,16 +1236,14 @@ private function internalParseFormula(string $formula, ?Cell $cell = null): bool // because at least the braces are paired up (at this stage in the formula) // MS Excel allows this if the content is cell references; but doesn't allow actual values, // but at this point, we can't differentiate (so allow both) - return $this->raiseFormulaError('Formula Error: Unexpected ,'); - /* The following code may be a better choice, but, with - the other changes for this PR, I can no longer come up - with a test case that gets here + //return $this->raiseFormulaError('Formula Error: Unexpected ,'); + $stack->push('Binary Operator', '∪'); ++$index; $expectingOperator = false; - continue;*/ + continue; } /** @var array $d */ diff --git a/tests/PhpSpreadsheetTests/Calculation/Issue4656Test.php b/tests/PhpSpreadsheetTests/Calculation/Issue4656Test.php new file mode 100644 index 0000000000..c4e2df933d --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Issue4656Test.php @@ -0,0 +1,38 @@ +getActiveSheet(); + $sheet->setCellValue('B1', 2); + $sheet->setCellValue('C1', 1); + $sheet->setCellValue('D1', 3); + $sheet->setCellValue('E1', 2); + $sheet->setCellValue('A1', '=RANK(B1,(C1,E1))'); + $sheet->setCellValue('A2', '=RANK(B1,C1:E1)'); + self::assertSame(1, $sheet->getCell('A1')->getCalculatedValue()); + self::assertSame(2, $sheet->getCell('A2')->getCalculatedValue()); + $spreadsheet->disconnectWorksheets(); + } + + public function testIssue4656Original(): void + { + $spreadsheet = new Spreadsheet(); + $sheet = $spreadsheet->getActiveSheet(); + $sheet->setCellValue('B1', 1); + $sheet->setCellValue('C1', 1); + $sheet->setCellValue('D1', 2); + $sheet->setCellValue('A1', '=RANK(B1,(C1,D1))'); + self::assertSame(2, $sheet->getCell('A1')->getCalculatedValue()); + $spreadsheet->disconnectWorksheets(); + } +}