Merge pull request #4577 from oleibman/issue1203

Copy Cell Adjusting Formula
This commit is contained in:
oleibman
2025-08-17 03:55:42 +00:00
committed by GitHub
3 changed files with 62 additions and 0 deletions
+13
View File
@@ -42,6 +42,19 @@ $spreadsheet->getActiveSheet()
If you make a call to `getCell()`, and the cell doesn't already exist, then
PhpSpreadsheet will create that cell for you.
### Copying a Cell's Value And Style Adjusting Formulas
If cell A1 contains `5`, cell A2 contains `10`, and cell `B1` contains `=A1`, the formula in B1 will be evaluated as `5`. In Excel, if you copy B1 to B2, B2 will wind up with the adjusted formula `=A2` and will be evaluated as 10. Until release 5.1.0, PhpSpreadsheet requires the program to perform its own formula adjustment. In 5.1.0, a new method is introduced to handle formula adjustments:
```php
$worksheet->copyformula($fromCell, $toCell);
```
This will behave as Excel does. If $fromCell does not contain a formula, its contents will be copied as-is.
If you also want to copy $fromCell's style, as Excel does, you can use the following (available in all supported releases):
```php
$worksheet->duplicateStyle($fromCell->getStyle(), $toCell);
```
### BEWARE: Cells and Styles assigned to variables as a Detached Reference
As an "in-memory" model, PHPSpreadsheet can be very demanding of memory,
@@ -3984,4 +3984,22 @@ class Worksheet
return true;
}
public function copyFormula(string $fromCell, string $toCell): void
{
$formula = $this->getCell($fromCell)->getValue();
$newFormula = $formula;
if (is_string($formula) && $this->getCell($fromCell)->getDataType() === DataType::TYPE_FORMULA) {
[$fromColInt, $fromRow] = Coordinate::indexesFromString($fromCell);
[$toColInt, $toRow] = Coordinate::indexesFromString($toCell);
$helper = ReferenceHelper::getInstance();
$newFormula = $helper->updateFormulaReferences(
$formula,
'A1',
$toColInt - $fromColInt,
$toRow - $fromRow
);
}
$this->setCellValue($toCell, $newFormula);
}
}
@@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace PhpOffice\PhpSpreadsheetTests\Worksheet;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
class Issue1203Test extends TestCase
{
public static function testCopyFormula(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', 1);
$sheet->setCellValue('A5', 5);
$sheet->setCellValue('E5', '=A5+$A$1');
$sheet->insertNewRowBefore(5, 1);
$e5 = $sheet->getCell('E5')->getValue();
self::assertNull($e5);
self::assertSame('=A6+$A$1', $sheet->getCell('E6')->getValue());
$sheet->copyFormula('E6', 'E5');
self::assertSame('=A5+$A$1', $sheet->getCell('E5')->getValue());
$sheet->copyFormula('E6', 'H9');
self::assertSame('=D9+$A$1', $sheet->getCell('H9')->getValue());
$sheet->copyFormula('A6', 'Z9');
self::assertSame(5, $sheet->getCell('Z9')->getValue());
$spreadsheet->disconnectWorksheets();
}
}