mirror of
https://github.com/PHPOffice/PhpSpreadsheet.git
synced 2026-09-20 15:16:36 +00:00
3a690a755c
SINGLE function can be used to return first value from a dynamic array result, or to return the value of the cell which matches the current row (VALUE error if not match) for a range. Excel allows you to specify an at-sign unary operator rather than SINGLE function; this PR does not permit that. Add support for reading CSE array functions for Gnumeric. Throw an exception if setValueExplicit Formula is invalid (not a string, or doesn't begin with equal sign. This is equivalent to what happens when setValueExplicit Numeric specifies a non-numeric value. Added a number of tests from PR #2787.
115 lines
4.3 KiB
PHP
115 lines
4.3 KiB
PHP
<?php
|
|
|
|
namespace PhpOffice\PhpSpreadsheetTests\Cell;
|
|
|
|
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
|
use PhpOffice\PhpSpreadsheet\Exception;
|
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
class CellArrayFormulaTest extends TestCase
|
|
{
|
|
private string $arrayReturnType;
|
|
|
|
private bool $skipUpdateInSpillageRange = true;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->arrayReturnType = Calculation::getArrayReturnType();
|
|
}
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
Calculation::setArrayReturnType($this->arrayReturnType);
|
|
}
|
|
|
|
public function testSetValueArrayFormulaNoSpillage(): void
|
|
{
|
|
Calculation::setArrayReturnType(Calculation::RETURN_ARRAY_AS_ARRAY);
|
|
$spreadsheet = new Spreadsheet();
|
|
$cell = $spreadsheet->getActiveSheet()->getCell('A1');
|
|
$cell->setValue('=MAX(ABS({5, -3; 1, -12}))');
|
|
|
|
self::assertSame(12, $cell->getCalculatedValue());
|
|
|
|
$spreadsheet->disconnectWorksheets();
|
|
}
|
|
|
|
public function testSetValueArrayFormulaWithSpillage(): void
|
|
{
|
|
Calculation::setArrayReturnType(Calculation::RETURN_ARRAY_AS_ARRAY);
|
|
$spreadsheet = new Spreadsheet();
|
|
$cell = $spreadsheet->getActiveSheet()->getCell('A1');
|
|
$cell->setValue('=SEQUENCE(3, 3, 1, 1)');
|
|
|
|
self::assertSame([[1, 2, 3], [4, 5, 6], [7, 8, 9]], $cell->getCalculatedValue());
|
|
|
|
$spreadsheet->disconnectWorksheets();
|
|
}
|
|
|
|
public function testSetValueInSpillageRangeCell(): void
|
|
{
|
|
Calculation::setArrayReturnType(Calculation::RETURN_ARRAY_AS_ARRAY);
|
|
$spreadsheet = new Spreadsheet();
|
|
$sheet = $spreadsheet->getActiveSheet();
|
|
$cell = $sheet->getCell('A1');
|
|
$cell->setValue('=SEQUENCE(3, 3, 1, 1)');
|
|
|
|
$cellAddress = 'C3';
|
|
$sheet->getCell($cellAddress)->setValue('x');
|
|
|
|
self::assertSame('#SPILL!', $sheet->getCell('A1')->getCalculatedValue());
|
|
self::assertSame('x', $sheet->getCell('C3')->getCalculatedValue());
|
|
|
|
$spreadsheet->disconnectWorksheets();
|
|
}
|
|
|
|
public function testUpdateValueInSpillageRangeCell(): void
|
|
{
|
|
Calculation::setArrayReturnType(Calculation::RETURN_ARRAY_AS_ARRAY);
|
|
$spreadsheet = new Spreadsheet();
|
|
$sheet = $spreadsheet->getActiveSheet();
|
|
$sheet->getCell('A1')->setValue('=SEQUENCE(3, 3, 1, 1)');
|
|
$sheet->getCell('A1')->getCalculatedValue();
|
|
$attributes = $sheet->getCell('A1')->getFormulaAttributes();
|
|
if (!isset($attributes, $attributes['ref'])) {
|
|
self::fail('No formula attributes for cell A1');
|
|
}
|
|
$cellRange = $attributes['ref'];
|
|
$cellAddress = 'C3';
|
|
self::assertTrue($sheet->getCell($cellAddress)->isInRange($cellRange));
|
|
if ($this->skipUpdateInSpillageRange) {
|
|
$spreadsheet->disconnectWorksheets();
|
|
self::markTestIncomplete('Preventing update in spill range not yet implemented');
|
|
}
|
|
|
|
$this->expectException(Exception::class);
|
|
$this->expectExceptionMessage("Cell {$cellAddress} is within the spillage range of a formula, and cannot be changed");
|
|
$sheet->getCell($cellAddress)->setValue('PHP');
|
|
|
|
$spreadsheet->disconnectWorksheets();
|
|
}
|
|
|
|
public function testUpdateArrayFormulaForSpillageRange(): void
|
|
{
|
|
Calculation::setArrayReturnType(Calculation::RETURN_ARRAY_AS_ARRAY);
|
|
$spreadsheet = new Spreadsheet();
|
|
$calculation = Calculation::getInstance($spreadsheet);
|
|
$sheet = $spreadsheet->getActiveSheet();
|
|
$sheet->getCell('A1')->setValue('=SEQUENCE(3, 3, 1, 1)');
|
|
$sheet->getCell('A1')->getCalculatedValue();
|
|
self::assertSame([[1, 2, 3], [4, 5, 6], [7, 8, 9]], $sheet->toArray(formatData: false, reduceArrays: true));
|
|
|
|
$sheet->getCell('A1')->setValue('=SEQUENCE(2, 2, 4, -1)');
|
|
$calculation->clearCalculationCache();
|
|
$sheet->getCell('A1')->getCalculatedValue();
|
|
self::assertSame([[4, 3, null], [2, 1, null], [null, null, null]], $sheet->toArray(formatData: false, reduceArrays: true));
|
|
|
|
$cellAddress = 'C3';
|
|
$sheet->getCell($cellAddress)->setValue('PHP');
|
|
self::assertSame('PHP', $sheet->getCell($cellAddress)->getValue(), 'change cell formerly in spill range');
|
|
|
|
$spreadsheet->disconnectWorksheets();
|
|
}
|
|
}
|