diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 8aaa2e7098..41701eae38 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -3470,11 +3470,15 @@ public function calculateCellValue(?Cell $cell = null, $resetLog = true) 'cell' => $cell->getCoordinate(), ]; + $cellAddressAttempted = false; + $cellAddress = null; + try { $result = self::unwrapResult($this->_calculateFormulaValue($cell->getValue(), $cell->getCoordinate(), $cell)); if ($this->spreadsheet === null) { throw new Exception('null spreadsheet in calculateCellValue'); } + $cellAddressAttempted = true; $cellAddress = array_pop($this->cellStack); if ($cellAddress === null) { throw new Exception('null cellAddress in calculateCellValue'); @@ -3485,6 +3489,16 @@ public function calculateCellValue(?Cell $cell = null, $resetLog = true) } $testSheet->getCell($cellAddress['cell']); } catch (\Exception $e) { + if (!$cellAddressAttempted) { + $cellAddress = array_pop($this->cellStack); + } + if ($this->spreadsheet !== null && is_array($cellAddress) && array_key_exists('sheet', $cellAddress)) { + $testSheet = $this->spreadsheet->getSheetByName($cellAddress['sheet']); + if ($testSheet !== null && array_key_exists('cell', $cellAddress)) { + $testSheet->getCell($cellAddress['cell']); + } + } + throw new Exception($e->getMessage()); } diff --git a/tests/PhpSpreadsheetTests/Calculation/CyclicTest.php b/tests/PhpSpreadsheetTests/Calculation/CyclicTest.php new file mode 100644 index 0000000000..c754520bd0 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/CyclicTest.php @@ -0,0 +1,49 @@ +cyclicFormulaCount = 0; + + $worksheet = $spreadsheet->getActiveSheet(); + $worksheet->fromArray($table_data, ''); + + try { + $result = $worksheet->getCell('C2')->getCalculatedValue(); + } catch (CalcException $e) { + $result = $e->getMessage(); + } + self::assertSame( + 'Worksheet!C2 -> Worksheet!A3 -> Worksheet!C2 -> Cyclic Reference in Formula', + $result + ); + + try { + $result = $worksheet->getCell('A3')->getCalculatedValue(); + } catch (CalcException $e) { + $result = $e->getMessage(); + } + self::assertSame( + 'Worksheet!A3 -> Worksheet!C2 -> Worksheet!A3 -> Cyclic Reference in Formula', + $result + ); + $spreadsheet->disconnectWorksheets(); + } +}