Skip to content

Commit 78c27c0

Browse files
author
Mark Baker
authored
Merge pull request #2687 from PHPOffice/Bugfix_Support-Row/Column-Ranges-in-INDIRECT()-Function
Allow `INDIRECT()` to accept row/column ranges as well as cell ranges
2 parents 0b9207a + ec15c7a commit 78c27c0

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
3939

4040
### Fixed
4141

42+
- Allow `INDIRECT()` to accept row/column ranges as well as cell ranges [PR #2687](https://github.com/PHPOffice/PhpSpreadsheet/pull/2687)
4243
- Fix bug when deleting cells with hyperlinks, where the hyperlink was then being "inherited" by whatever cell moved to that cell address.
4344
- Fix bug in Conditional Formatting in the Xls Writer that resulted in a broken file when there were multiple conditional ranges in a worksheet.
4445
- Fix Conditional Formatting in the Xls Writer to work with rules that contain string literals, cell references and formulae.

src/PhpSpreadsheet/Calculation/LookupRef/Indirect.php

+26-2
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,17 @@ public static function INDIRECT($cellAddress, $a1fmt, Cell $cell)
7272

7373
[$cellAddress, $worksheet, $sheetName] = Helpers::extractWorksheet($cellAddress, $cell);
7474

75+
if (preg_match('/^' . Calculation::CALCULATION_REGEXP_COLUMNRANGE_RELATIVE . '$/miu', $cellAddress, $matches)) {
76+
$cellAddress = self::handleRowColumnRanges($worksheet, ...explode(':', $cellAddress));
77+
} elseif (preg_match('/^' . Calculation::CALCULATION_REGEXP_ROWRANGE_RELATIVE . '$/miu', $cellAddress, $matches)) {
78+
$cellAddress = self::handleRowColumnRanges($worksheet, ...explode(':', $cellAddress));
79+
}
80+
7581
[$cellAddress1, $cellAddress2, $cellAddress] = Helpers::extractCellAddresses($cellAddress, $a1, $cell->getWorkSheet(), $sheetName);
7682

7783
if (
78-
(!preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $cellAddress1, $matches)) ||
79-
(($cellAddress2 !== null) && (!preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $cellAddress2, $matches)))
84+
(!preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/miu', $cellAddress1, $matches)) ||
85+
(($cellAddress2 !== null) && (!preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/miu', $cellAddress2, $matches)))
8086
) {
8187
return ExcelError::REF();
8288
}
@@ -95,4 +101,22 @@ private static function extractRequiredCells(?Worksheet $worksheet, string $cell
95101
return Calculation::getInstance($worksheet !== null ? $worksheet->getParent() : null)
96102
->extractCellRange($cellAddress, $worksheet, false);
97103
}
104+
105+
private static function handleRowColumnRanges(?Worksheet $worksheet, string $start, string $end): string
106+
{
107+
// Being lazy, we're only checking a single row/column to get the max
108+
if (ctype_digit($start) && $start <= 1048576) {
109+
// Max 16,384 columns for Excel2007
110+
$endColRef = ($worksheet !== null) ? $worksheet->getHighestDataColumn((int) $start) : 'XFD';
111+
112+
return "A{$start}:{$endColRef}{$end}";
113+
} elseif (ctype_alpha($start) && strlen($start) <= 3) {
114+
// Max 1,048,576 rows for Excel2007
115+
$endRowRef = ($worksheet !== null) ? $worksheet->getHighestDataRow($start) : 1048576;
116+
117+
return "{$start}1:{$end}{$endRowRef}";
118+
}
119+
120+
return "{$start}:{$end}";
121+
}
98122
}

tests/data/Calculation/LookupRef/INDIRECT.php

+4
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,8 @@
3434
'supply a1 argument as int' => [900, 'A2:A4', 1],
3535
'supply a1 argument as float' => [900, 'A2:A4', 7.3],
3636
'supply a1 argument as string not permitted' => ['#VALUE!', 'A2:A4', '1'],
37+
'row range' => [600, '1:3'],
38+
'column range' => [1500, 'A:C'],
39+
'row range on different sheet' => [66, 'OtherSheet!1:3'],
40+
'column range on different sheet' => [165, 'OtherSheet!A:C'],
3741
];

0 commit comments

Comments
 (0)