1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace PhpOffice\PhpSpreadsheet\Calculation\LookupRef; |
4
|
|
|
|
5
|
|
|
use PhpOffice\PhpSpreadsheet\Calculation\Exception; |
6
|
|
|
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; |
7
|
|
|
|
8
|
|
|
abstract class LookupBase |
9
|
|
|
{ |
10
|
|
|
/** |
11
|
|
|
* @param mixed $lookup_array |
12
|
|
|
*/ |
13
|
58 |
|
protected static function validateLookupArray($lookup_array): void |
14
|
|
|
{ |
15
|
58 |
|
if (!is_array($lookup_array)) { |
16
|
|
|
throw new Exception(ExcelError::REF()); |
17
|
|
|
} |
18
|
|
|
} |
19
|
|
|
|
20
|
|
|
/** @param float|int|string $index_number */ |
21
|
58 |
|
protected static function validateIndexLookup(array $lookup_array, $index_number): int |
22
|
|
|
{ |
23
|
|
|
// index_number must be a number greater than or equal to 1. |
24
|
|
|
// Excel results are inconsistent when index is non-numeric. |
25
|
|
|
// VLOOKUP(whatever, whatever, SQRT(-1)) yields NUM error, but |
26
|
|
|
// VLOOKUP(whatever, whatever, cellref) yields REF error |
27
|
|
|
// when cellref is '=SQRT(-1)'. So just try our best here. |
28
|
|
|
// Similar results if string (literal yields VALUE, cellRef REF). |
29
|
58 |
|
if (!is_numeric($index_number)) { |
30
|
3 |
|
throw new Exception(ExcelError::throwError($index_number)); |
31
|
|
|
} |
32
|
55 |
|
if ($index_number < 1) { |
33
|
1 |
|
throw new Exception(ExcelError::VALUE()); |
34
|
|
|
} |
35
|
|
|
|
36
|
|
|
// index_number must be less than or equal to the number of columns in lookup_array |
37
|
54 |
|
if (empty($lookup_array)) { |
38
|
|
|
throw new Exception(ExcelError::REF()); |
39
|
|
|
} |
40
|
|
|
|
41
|
54 |
|
return (int) $index_number; |
42
|
|
|
} |
43
|
|
|
|
44
|
47 |
|
protected static function checkMatch( |
45
|
|
|
bool $bothNumeric, |
46
|
|
|
bool $bothNotNumeric, |
47
|
|
|
bool $notExactMatch, |
48
|
|
|
int $rowKey, |
49
|
|
|
string $cellDataLower, |
50
|
|
|
string $lookupLower, |
51
|
|
|
?int $rowNumber |
52
|
|
|
): ?int { |
53
|
|
|
// remember the last key, but only if datatypes match |
54
|
47 |
|
if ($bothNumeric || $bothNotNumeric) { |
55
|
|
|
// Spreadsheets software returns first exact match, |
56
|
|
|
// we have sorted and we might have broken key orders |
57
|
|
|
// we want the first one (by its initial index) |
58
|
46 |
|
if ($notExactMatch) { |
59
|
21 |
|
$rowNumber = $rowKey; |
60
|
25 |
|
} elseif (($cellDataLower == $lookupLower) && (($rowNumber === null) || ($rowKey < $rowNumber))) { |
61
|
21 |
|
$rowNumber = $rowKey; |
62
|
|
|
} |
63
|
|
|
} |
64
|
|
|
|
65
|
47 |
|
return $rowNumber; |
66
|
|
|
} |
67
|
|
|
} |
68
|
|
|
|