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.
This commit is contained in:
oleibman
2025-09-20 20:15:01 -07:00
parent 21ef57e46d
commit cda404d596
2 changed files with 41 additions and 5 deletions
@@ -1236,16 +1236,14 @@ class Calculation extends CalculationLocale
// 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<string, int> $d */
@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace PhpOffice\PhpSpreadsheetTests\Calculation;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
class Issue4656Test extends TestCase
{
public function testIssue4656(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->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();
}
}