Fix VLOOKUP whose return was impacted by order for a $not_exact_match (#854)
* Highlight VLOOKUP bug with a new test * Remove useless statements + fix VLOOKUP bug Please not that we have still inconsistencies in Excel (See LOOKUP and VLOOKUP.php test files) * Base strtolower on our StringHelper in LookupRef
This commit is contained in:
		
							parent
							
								
									dfd9c5bb3e
								
							
						
					
					
						commit
						ccebf0f288
					
				@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
 | 
			
		||||
 | 
			
		||||
- Fix handling for escaped enclosures and new lines in CSV Separator Inference
 | 
			
		||||
- Fix MATCH an error was appearing when comparing strings against 0 (always true)
 | 
			
		||||
- Fix VLOOKUP 
 | 
			
		||||
- Fix return type hint
 | 
			
		||||
 | 
			
		||||
## [1.6.0] - 2019-01-02
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation;
 | 
			
		||||
 | 
			
		||||
use PhpOffice\PhpSpreadsheet\Cell\Cell;
 | 
			
		||||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
 | 
			
		||||
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
 | 
			
		||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
 | 
			
		||||
 | 
			
		||||
class LookupRef
 | 
			
		||||
@ -473,8 +474,9 @@ class LookupRef
 | 
			
		||||
        $lookupValue = Functions::flattenSingleValue($lookupValue);
 | 
			
		||||
        $matchType = ($matchType === null) ? 1 : (int) Functions::flattenSingleValue($matchType);
 | 
			
		||||
 | 
			
		||||
        $initialLookupValue = $lookupValue;
 | 
			
		||||
        // MATCH is not case sensitive
 | 
			
		||||
        $lookupValue = strtolower($lookupValue);
 | 
			
		||||
        $lookupValue = StringHelper::strToLower($lookupValue);
 | 
			
		||||
 | 
			
		||||
        // Lookup_value type has to be number, text, or logical values
 | 
			
		||||
        if ((!is_numeric($lookupValue)) && (!is_string($lookupValue)) && (!is_bool($lookupValue))) {
 | 
			
		||||
@ -502,7 +504,7 @@ class LookupRef
 | 
			
		||||
            }
 | 
			
		||||
            // Convert strings to lowercase for case-insensitive testing
 | 
			
		||||
            if (is_string($lookupArrayValue)) {
 | 
			
		||||
                $lookupArray[$i] = strtolower($lookupArrayValue);
 | 
			
		||||
                $lookupArray[$i] = StringHelper::strToLower($lookupArrayValue);
 | 
			
		||||
            }
 | 
			
		||||
            if (($lookupArrayValue === null) && (($matchType == 1) || ($matchType == -1))) {
 | 
			
		||||
                $lookupArray = array_slice($lookupArray, 0, $i - 1);
 | 
			
		||||
@ -665,7 +667,9 @@ class LookupRef
 | 
			
		||||
    {
 | 
			
		||||
        reset($a);
 | 
			
		||||
        $firstColumn = key($a);
 | 
			
		||||
        if (($aLower = strtolower($a[$firstColumn])) == ($bLower = strtolower($b[$firstColumn]))) {
 | 
			
		||||
        $aLower = StringHelper::strToLower($a[$firstColumn]);
 | 
			
		||||
        $bLower = StringHelper::strToLower($b[$firstColumn]);
 | 
			
		||||
        if ($aLower == $bLower) {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -711,11 +715,14 @@ class LookupRef
 | 
			
		||||
            uasort($lookup_array, ['self', 'vlookupSort']);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $lookupLower = StringHelper::strToLower($lookup_value);
 | 
			
		||||
        $rowNumber = $rowValue = false;
 | 
			
		||||
        foreach ($lookup_array as $rowKey => $rowData) {
 | 
			
		||||
            $firstLower = StringHelper::strToLower($rowData[$firstColumn]);
 | 
			
		||||
 | 
			
		||||
            // break if we have passed possible keys
 | 
			
		||||
            if ((is_numeric($lookup_value) && is_numeric($rowData[$firstColumn]) && ($rowData[$firstColumn] > $lookup_value)) ||
 | 
			
		||||
                (!is_numeric($lookup_value) && !is_numeric($rowData[$firstColumn]) && (strtolower($rowData[$firstColumn]) > strtolower($lookup_value)))) {
 | 
			
		||||
                (!is_numeric($lookup_value) && !is_numeric($rowData[$firstColumn]) && ($firstLower > $lookupLower))) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            // remember the last key, but only if datatypes match
 | 
			
		||||
@ -723,17 +730,15 @@ class LookupRef
 | 
			
		||||
                (!is_numeric($lookup_value) && !is_numeric($rowData[$firstColumn]))) {
 | 
			
		||||
                if ($not_exact_match) {
 | 
			
		||||
                    $rowNumber = $rowKey;
 | 
			
		||||
                    $rowValue = $rowData[$firstColumn];
 | 
			
		||||
 | 
			
		||||
                    continue;
 | 
			
		||||
                } elseif ((strtolower($rowData[$firstColumn]) == strtolower($lookup_value))
 | 
			
		||||
                } elseif (($firstLower == $lookupLower)
 | 
			
		||||
                    // Spreadsheets software returns first exact match,
 | 
			
		||||
                    // we have sorted and we might have broken key orders
 | 
			
		||||
                    // we want the first one (by its initial index)
 | 
			
		||||
                    && (($rowNumber == false) || ($rowKey < $rowNumber))
 | 
			
		||||
                ) {
 | 
			
		||||
                    $rowNumber = $rowKey;
 | 
			
		||||
                    $rowValue = $rowData[$firstColumn];
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@ -786,8 +791,11 @@ class LookupRef
 | 
			
		||||
            // break if we have passed possible keys
 | 
			
		||||
            $bothNumeric = is_numeric($lookup_value) && is_numeric($rowData);
 | 
			
		||||
            $bothNotNumeric = !is_numeric($lookup_value) && !is_numeric($rowData);
 | 
			
		||||
            $lookupLower = StringHelper::strToLower($lookup_value);
 | 
			
		||||
            $rowDataLower = StringHelper::strToLower($rowData);
 | 
			
		||||
 | 
			
		||||
            if (($bothNumeric && $rowData > $lookup_value) ||
 | 
			
		||||
                ($bothNotNumeric && strtolower($rowData) > strtolower($lookup_value))) {
 | 
			
		||||
                ($bothNotNumeric && $rowDataLower > $lookupLower)) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -797,7 +805,7 @@ class LookupRef
 | 
			
		||||
                    $rowNumber = $rowKey;
 | 
			
		||||
 | 
			
		||||
                    continue;
 | 
			
		||||
                } elseif (strtolower($rowData) === strtolower($lookup_value)
 | 
			
		||||
                } elseif ($rowDataLower === $lookupLower
 | 
			
		||||
                    && ($rowNumber === null || $rowKey < $rowNumber)
 | 
			
		||||
                ) {
 | 
			
		||||
                    $rowNumber = $rowKey;
 | 
			
		||||
 | 
			
		||||
@ -106,6 +106,21 @@ return [
 | 
			
		||||
            ['author_100'],
 | 
			
		||||
            ['author_101']
 | 
			
		||||
        ]
 | 
			
		||||
    ],
 | 
			
		||||
 | 
			
		||||
    [
 | 
			
		||||
        '#N/A',
 | 
			
		||||
        '10y2',
 | 
			
		||||
        [
 | 
			
		||||
            ['5y-1'],
 | 
			
		||||
            ['10y1'],
 | 
			
		||||
            ['10y2'],
 | 
			
		||||
        ],
 | 
			
		||||
        [
 | 
			
		||||
            [2.0],
 | 
			
		||||
            [7.0],
 | 
			
		||||
            [10.0],
 | 
			
		||||
        ],
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
@ -311,5 +311,17 @@ return [
 | 
			
		||||
        ],
 | 
			
		||||
        2,
 | 
			
		||||
        false
 | 
			
		||||
    ],
 | 
			
		||||
 | 
			
		||||
    [
 | 
			
		||||
        '#N/A',
 | 
			
		||||
        '10y2',
 | 
			
		||||
        [
 | 
			
		||||
            ['5y-1', 2.0],
 | 
			
		||||
            ['10y1', 7.0],
 | 
			
		||||
            ['10y2', 10.0]
 | 
			
		||||
        ],
 | 
			
		||||
        2.0
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user