Skip to content

Commit db21d04

Browse files
author
Mark Baker
authored
Implementation of the ISREF() information function (#2613)
1 parent 0ee4d96 commit db21d04

File tree

4 files changed

+80
-6
lines changed

4 files changed

+80
-6
lines changed

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org).
99

1010
### Added
1111

12-
- Nothing
12+
- Implementation of the ISREF() information function
1313

1414
### Changed
1515

1616
- Nothing
17-
-
17+
1818
### Deprecated
1919

2020
- All Excel Function implementations in `Calculation\Functions` (including the Error functions) have been moved to dedicated classes for groups of related functions. See the docblocks against all the deprecated methods for details of the new methods to call instead. At some point, these old classes will be deleted.

src/PhpSpreadsheet/Calculation/Calculation.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1526,8 +1526,10 @@ class Calculation
15261526
],
15271527
'ISREF' => [
15281528
'category' => Category::CATEGORY_INFORMATION,
1529-
'functionCall' => [Functions::class, 'DUMMY'],
1529+
'functionCall' => [Information\Value::class, 'isRef'],
15301530
'argumentCount' => '1',
1531+
'passCellReference' => true,
1532+
'passByReference' => [true],
15311533
],
15321534
'ISTEXT' => [
15331535
'category' => Category::CATEGORY_INFORMATION,

src/PhpSpreadsheet/Calculation/Information/Value.php

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
88
use PhpOffice\PhpSpreadsheet\Cell\Cell;
99
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
10+
use PhpOffice\PhpSpreadsheet\NamedRange;
11+
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
1012

1113
class Value
1214
{
@@ -28,11 +30,39 @@ public static function isBlank($value = null)
2830
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $value);
2931
}
3032

31-
if ($value !== null) {
32-
$value = Functions::flattenSingleValue($value);
33+
return $value === null;
34+
}
35+
36+
/**
37+
* IS_REF.
38+
*
39+
* @param mixed $value Value to check
40+
*
41+
* @return bool
42+
*/
43+
public static function isRef($value, ?Cell $cell = null)
44+
{
45+
if ($cell === null || $value === $cell->getCoordinate()) {
46+
return false;
3347
}
3448

35-
return $value === null;
49+
$cellValue = Functions::trimTrailingRange($value);
50+
if (preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/ui', $cellValue) === 1) {
51+
[$worksheet, $cellValue] = Worksheet::extractSheetTitle($cellValue, true);
52+
if (!empty($worksheet) && $cell->getWorksheet()->getParent()->getSheetByName($worksheet) === null) {
53+
return false;
54+
}
55+
[$column, $row] = Coordinate::indexesFromString($cellValue);
56+
if ($column > 16384 || $row > 1048576) {
57+
return false;
58+
}
59+
60+
return true;
61+
}
62+
63+
$namedRange = $cell->getWorksheet()->getParent()->getNamedRange($value);
64+
65+
return $namedRange instanceof NamedRange;
3666
}
3767

3868
/**
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Information;
4+
5+
use PhpOffice\PhpSpreadsheet\NamedRange;
6+
use PhpOffice\PhpSpreadsheetTests\Calculation\Functions\LookupRef\AllSetupTeardown;
7+
8+
class IsRefTest extends AllSetupTeardown
9+
{
10+
public function testIsRef(): void
11+
{
12+
$sheet = $this->getSheet();
13+
14+
$sheet->getParent()->addDefinedName(new NamedRange('NAMED_RANGE', $sheet, 'C1'));
15+
16+
$sheet->getCell('A1')->setValue('=ISREF(B1)');
17+
$sheet->getCell('A2')->setValue('=ISREF(B1:B2)');
18+
$sheet->getCell('A3')->setValue('=ISREF(B1:D4 C1:C5)');
19+
$sheet->getCell('A4')->setValue('=ISREF("PHP")');
20+
$sheet->getCell('A5')->setValue('=ISREF(B1*B2)');
21+
$sheet->getCell('A6')->setValue('=ISREF(Worksheet2!B1)');
22+
$sheet->getCell('A7')->setValue('=ISREF(NAMED_RANGE)');
23+
$sheet->getCell('A8')->setValue('=ISREF(INDIRECT("' . $sheet->getTitle() . '" & "!" & "A1"))');
24+
$sheet->getCell('A9')->setValue('=ISREF(INDIRECT("A1"))');
25+
$sheet->getCell('A10')->setValue('=ISREF(INDIRECT("Invalid Worksheet" & "!" & "A1"))');
26+
$sheet->getCell('A11')->setValue('=ISREF(ZZZ1)');
27+
$sheet->getCell('A12')->setValue('=ISREF(CHOOSE(2, A1, B1, C1))');
28+
29+
self::assertTrue($sheet->getCell('A1')->getCalculatedValue()); // Cell Reference
30+
self::assertTrue($sheet->getCell('A2')->getCalculatedValue()); // Cell Range
31+
self::assertTrue($sheet->getCell('A3')->getCalculatedValue()); // Complex Cell Range
32+
self::assertFalse($sheet->getCell('A4')->getCalculatedValue()); // Text String
33+
self::assertFalse($sheet->getCell('A5')->getCalculatedValue()); // Result of a math expression
34+
self::assertTrue($sheet->getCell('A6')->getCalculatedValue()); // Cell Reference with worksheet
35+
self::assertTrue($sheet->getCell('A7')->getCalculatedValue()); // Named Range
36+
self::assertTrue($sheet->getCell('A8')->getCalculatedValue()); // Indirect to a Cell Reference
37+
self::assertTrue($sheet->getCell('A9')->getCalculatedValue()); // Indirect to a Worksheet/Cell Reference
38+
self::assertFalse($sheet->getCell('A10')->getCalculatedValue()); // Indirect to an Invalid Worksheet/Cell Reference
39+
self::assertFalse($sheet->getCell('A11')->getCalculatedValue()); // Invalid Cell Reference
40+
self::assertTrue($sheet->getCell('A12')->getCalculatedValue()); // returned Cell Reference
41+
}
42+
}

0 commit comments

Comments
 (0)