generated from jric11/baseProject
105 lines
4.5 KiB
PHP
105 lines
4.5 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace PhpOffice\PhpSpreadsheet\Calculation\Internal;
|
||
|
|
|
||
|
|
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||
|
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||
|
|
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
|
||
|
|
use PhpOffice\PhpSpreadsheet\Cell\Cell;
|
||
|
|
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||
|
|
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||
|
|
|
||
|
|
class ExcelArrayPseudoFunctions
|
||
|
|
{
|
||
|
|
public static function single(string $cellReference, Cell $cell): mixed
|
||
|
|
{
|
||
|
|
$worksheet = $cell->getWorksheet();
|
||
|
|
|
||
|
|
[$referenceWorksheetName, $referenceCellCoordinate] = Worksheet::extractSheetTitle($cellReference, true, true);
|
||
|
|
if (preg_match('/^([$]?[a-z]{1,3})([$]?([0-9]{1,7})):([$]?[a-z]{1,3})([$]?([0-9]{1,7}))$/i', "$referenceCellCoordinate", $matches) === 1) {
|
||
|
|
$ourRow = $cell->getRow();
|
||
|
|
$firstRow = (int) $matches[3];
|
||
|
|
$lastRow = (int) $matches[6];
|
||
|
|
if ($ourRow < $firstRow || $ourRow > $lastRow || $matches[1] !== $matches[4]) {
|
||
|
|
return ExcelError::VALUE();
|
||
|
|
}
|
||
|
|
$referenceCellCoordinate = $matches[1] . $ourRow;
|
||
|
|
}
|
||
|
|
$referenceCell = ($referenceWorksheetName === '')
|
||
|
|
? $worksheet->getCell((string) $referenceCellCoordinate)
|
||
|
|
: $worksheet->getParentOrThrow()
|
||
|
|
->getSheetByNameOrThrow((string) $referenceWorksheetName)
|
||
|
|
->getCell((string) $referenceCellCoordinate);
|
||
|
|
|
||
|
|
$result = $referenceCell->getCalculatedValue();
|
||
|
|
while (is_array($result)) {
|
||
|
|
$result = array_shift($result);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $result;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** @return array<mixed>|string */
|
||
|
|
public static function anchorArray(string $cellReference, Cell $cell): array|string
|
||
|
|
{
|
||
|
|
//$coordinate = $cell->getCoordinate();
|
||
|
|
$worksheet = $cell->getWorksheet();
|
||
|
|
|
||
|
|
[$referenceWorksheetName, $referenceCellCoordinate] = Worksheet::extractSheetTitle($cellReference, true, true);
|
||
|
|
$referenceCell = ($referenceWorksheetName === '')
|
||
|
|
? $worksheet->getCell((string) $referenceCellCoordinate)
|
||
|
|
: $worksheet->getParentOrThrow()
|
||
|
|
->getSheetByNameOrThrow((string) $referenceWorksheetName)
|
||
|
|
->getCell((string) $referenceCellCoordinate);
|
||
|
|
|
||
|
|
// We should always use the sizing for the array formula range from the referenced cell formula
|
||
|
|
//$referenceRange = null;
|
||
|
|
/*if ($referenceCell->isFormula() && $referenceCell->isArrayFormula()) {
|
||
|
|
$referenceRange = $referenceCell->arrayFormulaRange();
|
||
|
|
}*/
|
||
|
|
|
||
|
|
$calcEngine = Calculation::getInstance($worksheet->getParent());
|
||
|
|
$result = $calcEngine->calculateCellValue($referenceCell, false);
|
||
|
|
if (!is_array($result)) {
|
||
|
|
$result = ExcelError::REF();
|
||
|
|
}
|
||
|
|
|
||
|
|
// Ensure that our array result dimensions match the specified array formula range dimensions,
|
||
|
|
// from the referenced cell, expanding or shrinking it as necessary.
|
||
|
|
/*$result = Functions::resizeMatrix(
|
||
|
|
$result,
|
||
|
|
...Coordinate::rangeDimension($referenceRange ?? $coordinate)
|
||
|
|
);*/
|
||
|
|
|
||
|
|
// Set the result for our target cell (with spillage)
|
||
|
|
// But if we do write it, we get problems with #SPILL! Errors if the spreadsheet is saved
|
||
|
|
// TODO How are we going to identify and handle a #SPILL! or a #CALC! error?
|
||
|
|
// IOFactory::setLoading(true);
|
||
|
|
// $worksheet->fromArray(
|
||
|
|
// $result,
|
||
|
|
// null,
|
||
|
|
// $coordinate,
|
||
|
|
// true
|
||
|
|
// );
|
||
|
|
// IOFactory::setLoading(true);
|
||
|
|
|
||
|
|
// Calculate the array formula range that we should set for our target, based on our target cell coordinate
|
||
|
|
// [$col, $row] = Coordinate::indexesFromString($coordinate);
|
||
|
|
// $row += count($result) - 1;
|
||
|
|
// $col = Coordinate::stringFromColumnIndex($col + count($result[0]) - 1);
|
||
|
|
// $arrayFormulaRange = "{$coordinate}:{$col}{$row}";
|
||
|
|
// $formulaAttributes = ['t' => 'array', 'ref' => $arrayFormulaRange];
|
||
|
|
|
||
|
|
// Using fromArray() would reset the value for this cell with the calculation result
|
||
|
|
// as well as updating the spillage cells,
|
||
|
|
// so we need to restore this cell to its formula value, attributes, and datatype
|
||
|
|
// $cell = $worksheet->getCell($coordinate);
|
||
|
|
// $cell->setValueExplicit($value, DataType::TYPE_FORMULA, true, $arrayFormulaRange);
|
||
|
|
// $cell->setFormulaAttributes($formulaAttributes);
|
||
|
|
|
||
|
|
// $cell->updateInCollection();
|
||
|
|
|
||
|
|
return $result;
|
||
|
|
}
|
||
|
|
}
|