Correct update to named ranges and formulae when inserting/deleting columns/rows

This commit is contained in:
MarkBaker 2022-09-23 14:03:38 +02:00
parent 3b0c450742
commit d682f2f95e
4 changed files with 40 additions and 29 deletions

View File

@ -38,6 +38,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
### Fixed
- Fix update to defined names when inserting/deleting rows/columns [Issue #3076](https://github.com/PHPOffice/PhpSpreadsheet/issues/3076) [PR #3077](https://github.com/PHPOffice/PhpSpreadsheet/pull/3077)
- Fix DataValidation sqRef when inserting/deleting rows/columns [Issue #3056](https://github.com/PHPOffice/PhpSpreadsheet/issues/3056) [PR #3074](https://github.com/PHPOffice/PhpSpreadsheet/pull/3074)
- Named ranges not usable as anchors in OFFSET function [Issue #3013](https://github.com/PHPOffice/PhpSpreadsheet/issues/3013)
- Fully flatten an array [Issue #2955](https://github.com/PHPOffice/PhpSpreadsheet/issues/2955) [PR #2956](https://github.com/PHPOffice/PhpSpreadsheet/pull/2956)

View File

@ -150,7 +150,7 @@ abstract class DefinedName
// New title
$newTitle = $this->name;
ReferenceHelper::getInstance()->updateNamedFormulas($this->worksheet->getParent(), $oldTitle, $newTitle);
ReferenceHelper::getInstance()->updateNamedFormulae($this->worksheet->getParent(), $oldTitle, $newTitle);
}
return $this;

View File

@ -862,13 +862,13 @@ class ReferenceHelper
}
/**
* Update named formulas (i.e. containing worksheet references / named ranges).
* Update named formulae (i.e. containing worksheet references / named ranges).
*
* @param Spreadsheet $spreadsheet Object to update
* @param string $oldName Old name (name to replace)
* @param string $newName New name
*/
public function updateNamedFormulas(Spreadsheet $spreadsheet, $oldName = '', $newName = ''): void
public function updateNamedFormulae(Spreadsheet $spreadsheet, $oldName = '', $newName = ''): void
{
if ($oldName == '') {
return;
@ -889,6 +889,41 @@ class ReferenceHelper
}
}
private function updateDefinedNames(Worksheet $worksheet, string $beforeCellAddress, int $numberOfColumns, int $numberOfRows): void
{
foreach ($worksheet->getParent()->getDefinedNames() as $definedName) {
if ($definedName->isFormula() === false) {
$this->updateNamedRange($definedName, $worksheet, $beforeCellAddress, $numberOfColumns, $numberOfRows);
} else {
$this->updateNamedFormula($definedName, $worksheet, $beforeCellAddress, $numberOfColumns, $numberOfRows);
}
}
}
private function updateNamedRange(DefinedName $definedName, Worksheet $worksheet, string $beforeCellAddress, int $numberOfColumns, int $numberOfRows): void
{
$cellAddress = $definedName->getValue();
$asFormula = ($cellAddress[0] === '=');
if ($definedName->getWorksheet() !== null && $definedName->getWorksheet()->getHashCode() === $worksheet->getHashCode()) {
if ($asFormula === true) {
$formula = $definedName->getValue();
$formula = $this->updateFormulaReferences($formula, $beforeCellAddress, $numberOfColumns, $numberOfRows, $worksheet->getTitle());
$definedName->setValue($formula);
} else {
$definedName->setValue($asFormula . $this->updateCellReference(ltrim($cellAddress, '=')));
}
}
}
private function updateNamedFormula(DefinedName $definedName, Worksheet $worksheet, string $beforeCellAddress, int $numberOfColumns, int $numberOfRows): void
{
if ($definedName->getWorksheet() !== null && $definedName->getWorksheet()->getHashCode() === $worksheet->getHashCode()) {
$formula = $definedName->getValue();
$formula = $this->updateFormulaReferences($formula, $beforeCellAddress, $numberOfColumns, $numberOfRows, $worksheet->getTitle());
$definedName->setValue($formula);
}
}
/**
* Update cell range.
*
@ -1159,29 +1194,4 @@ class ReferenceHelper
{
throw new Exception('Cloning a Singleton is not allowed!');
}
public function updateDefinedNames(Worksheet $worksheet, string $beforeCellAddress, int $numberOfColumns, int $numberOfRows): void
{
foreach ($worksheet->getParent()->getDefinedNames() as $definedName) {
if ($definedName->isFormula() === false) {
$cellAddress = $definedName->getValue();
$asFormula = ($cellAddress[0] === '=');
if ($definedName->getWorksheet() !== null && $definedName->getWorksheet()->getHashCode() === $worksheet->getHashCode()) {
if ($asFormula === true) {
$formula = $definedName->getValue();
$formula = $this->updateFormulaReferences($formula, $beforeCellAddress, $numberOfColumns, $numberOfRows, $worksheet->getTitle());
$definedName->setValue($formula);
} else {
$definedName->setValue($asFormula . $this->updateCellReference(ltrim($cellAddress, '=')));
}
}
} else {
$formula = $definedName->getValue();
if ($definedName->getWorksheet() !== null && $definedName->getWorksheet()->getHashCode() === $worksheet->getHashCode()) {
$formula = $this->updateFormulaReferences($formula, $beforeCellAddress, $numberOfColumns, $numberOfRows, $worksheet->getTitle());
$definedName->setValue($formula);
}
}
}
}
}

View File

@ -923,7 +923,7 @@ class Worksheet implements IComparable
$this->parent->getCalculationEngine()
->renameCalculationCacheForWorksheet($oldTitle, $newTitle);
if ($updateFormulaCellReferences) {
ReferenceHelper::getInstance()->updateNamedFormulas($this->parent, $oldTitle, $newTitle);
ReferenceHelper::getInstance()->updateNamedFormulae($this->parent, $oldTitle, $newTitle);
}
}