Skip to content

Commit efa0c0f

Browse files
authored
Merge pull request #4577 from oleibman/issue1203
Copy Cell Adjusting Formula
2 parents 08f2f1b + fe12201 commit efa0c0f

File tree

3 files changed

+62
-0
lines changed

3 files changed

+62
-0
lines changed

docs/topics/accessing-cells.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,19 @@ $spreadsheet->getActiveSheet()
4242
If you make a call to `getCell()`, and the cell doesn't already exist, then
4343
PhpSpreadsheet will create that cell for you.
4444

45+
### Copying a Cell's Value And Style Adjusting Formulas
46+
47+
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:
48+
```php
49+
$worksheet->copyformula($fromCell, $toCell);
50+
```
51+
This will behave as Excel does. If $fromCell does not contain a formula, its contents will be copied as-is.
52+
53+
If you also want to copy $fromCell's style, as Excel does, you can use the following (available in all supported releases):
54+
```php
55+
$worksheet->duplicateStyle($fromCell->getStyle(), $toCell);
56+
```
57+
4558
### BEWARE: Cells and Styles assigned to variables as a Detached Reference
4659

4760
As an "in-memory" model, PHPSpreadsheet can be very demanding of memory,

src/PhpSpreadsheet/Worksheet/Worksheet.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3984,4 +3984,22 @@ public function applyStylesFromArray(string $coordinate, array $styleArray): boo
39843984

39853985
return true;
39863986
}
3987+
3988+
public function copyFormula(string $fromCell, string $toCell): void
3989+
{
3990+
$formula = $this->getCell($fromCell)->getValue();
3991+
$newFormula = $formula;
3992+
if (is_string($formula) && $this->getCell($fromCell)->getDataType() === DataType::TYPE_FORMULA) {
3993+
[$fromColInt, $fromRow] = Coordinate::indexesFromString($fromCell);
3994+
[$toColInt, $toRow] = Coordinate::indexesFromString($toCell);
3995+
$helper = ReferenceHelper::getInstance();
3996+
$newFormula = $helper->updateFormulaReferences(
3997+
$formula,
3998+
'A1',
3999+
$toColInt - $fromColInt,
4000+
$toRow - $fromRow
4001+
);
4002+
}
4003+
$this->setCellValue($toCell, $newFormula);
4004+
}
39874005
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpOffice\PhpSpreadsheetTests\Worksheet;
6+
7+
use PhpOffice\PhpSpreadsheet\Spreadsheet;
8+
use PHPUnit\Framework\TestCase;
9+
10+
class Issue1203Test extends TestCase
11+
{
12+
public static function testCopyFormula(): void
13+
{
14+
$spreadsheet = new Spreadsheet();
15+
$sheet = $spreadsheet->getActiveSheet();
16+
$sheet->setCellValue('A1', 1);
17+
$sheet->setCellValue('A5', 5);
18+
$sheet->setCellValue('E5', '=A5+$A$1');
19+
$sheet->insertNewRowBefore(5, 1);
20+
$e5 = $sheet->getCell('E5')->getValue();
21+
self::assertNull($e5);
22+
self::assertSame('=A6+$A$1', $sheet->getCell('E6')->getValue());
23+
$sheet->copyFormula('E6', 'E5');
24+
self::assertSame('=A5+$A$1', $sheet->getCell('E5')->getValue());
25+
$sheet->copyFormula('E6', 'H9');
26+
self::assertSame('=D9+$A$1', $sheet->getCell('H9')->getValue());
27+
$sheet->copyFormula('A6', 'Z9');
28+
self::assertSame(5, $sheet->getCell('Z9')->getValue());
29+
$spreadsheet->disconnectWorksheets();
30+
}
31+
}

0 commit comments

Comments
 (0)