From 76ac0089110e959e810e4611490d42c62580892c Mon Sep 17 00:00:00 2001 From: Nathan Dench Date: Tue, 4 May 2021 14:45:04 +1000 Subject: [PATCH] R1C1 conversion should handle absolute A1 references --- src/PhpSpreadsheet/Cell/AddressHelper.php | 19 ++++++++++++++++--- .../data/Cell/A1ConversionToR1C1Relative.php | 15 +++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/PhpSpreadsheet/Cell/AddressHelper.php b/src/PhpSpreadsheet/Cell/AddressHelper.php index b0e34e25..e5f4e952 100644 --- a/src/PhpSpreadsheet/Cell/AddressHelper.php +++ b/src/PhpSpreadsheet/Cell/AddressHelper.php @@ -102,14 +102,27 @@ class AddressHelper ?int $currentRowNumber = null, ?int $currentColumnNumber = null ): string { - $validityCheck = preg_match('/^\$?([A-Z]{1,3})\$?(\d{1,7})$/i', $address, $cellReference); + $validityCheck = preg_match('/^(\$?[A-Z]{1,3})(\$?\d{1,7})$/i', $address, $cellReference); if ($validityCheck === 0) { throw new Exception('Invalid A1-format Cell Reference'); } - $columnId = Coordinate::columnIndexFromString($cellReference[1]); - $rowId = (int) $cellReference[2]; + if ($cellReference[1][0] === '$') { + $columnId = Coordinate::columnIndexFromString(substr($cellReference[1], 1)); + // Column must be absolute address + $currentColumnNumber = null; + } else { + $columnId = Coordinate::columnIndexFromString($cellReference[1]); + } + + if ($cellReference[2][0] === '$') { + $rowId = (int) substr($cellReference[2], 1); + // Row must be absolute address + $currentRowNumber = null; + } else { + $rowId = (int) $cellReference[2]; + } if ($currentRowNumber !== null) { if ($rowId === $currentRowNumber) { diff --git a/tests/data/Cell/A1ConversionToR1C1Relative.php b/tests/data/Cell/A1ConversionToR1C1Relative.php index 76a6aee8..dd9b2391 100644 --- a/tests/data/Cell/A1ConversionToR1C1Relative.php +++ b/tests/data/Cell/A1ConversionToR1C1Relative.php @@ -2,18 +2,33 @@ return [ ['R[2]C[2]', 'O18', 16, 13], + ['R18C15', '$O$18', 16, 13], ['R[-2]C[2]', 'O14', 16, 13], + ['R[-2]C15', '$O14', 16, 13], ['R[2]C[-2]', 'K18', 16, 13], + ['R18C[-2]', 'K$18', 16, 13], ['R[-2]C[-2]', 'K14', 16, 13], ['RC[3]', 'P16', 16, 13], + ['R16C[3]', 'P$16', 16, 13], ['RC[-3]', 'J16', 16, 13], + ['RC10', '$J16', 16, 13], ['R[4]C', 'M20', 16, 13], + ['R[4]C13', '$M20', 16, 13], ['R[-4]C', 'M12', 16, 13], + ['R12C', 'M$12', 16, 13], ['RC', 'E5', 5, 5], + ['R5C5', '$E$5', 5, 5], ['R5C', 'E5', null, 5], + ['R5C5', '$E5', null, 5], + ['R5C', 'E$5', null, 5], ['RC5', 'E5', 5, null], + ['RC5', '$E5', 5, null], + ['R5C5', 'E$5', 5, null], ['R5C[2]', 'E5', null, 3], + ['R5C5', '$E5', null, 3], + ['R5C[2]', 'E$5', null, 3], ['R[2]C5', 'E5', 3, null], + ['R5C5', '$E$5', 3, null], ['R5C[-2]', 'E5', null, 7], ['R[-2]C5', 'E5', 7, null], ];