nfTlWNl rn Ѻq$³*%yNk9S[H}$Λ@?7 ~ CѶͫ\]*uQlf^ZL~`^ǥ_ 6E~/6._#1Iķխ}`[W">/m6NZDrjt(a_W Ѻq$³*%yNk9Sz ] 𓼾,_Ng= E%o6cWmQXuΙL[n8qRZ#cuN xj2n6&cREASt<͘yd)|-޹N.Ol$>7,[zs뱃"V$:?opN]D[6~'G4321B/QK&luIDE0ǐUi46 걥A]) @{[mU YJC?/Rٗ?aiM7>b fA "BDቾ$cXbd׻*KM:=`[iP\YM, n5$R劗eU@'dǪ ĢQ$3^]2=#,WՈd /; :!e>x,ED'4X=;.Ӱ#T,s ?s*\Ab{խO܆g2;Agq||6(}Κ [vb9K6s+P1Q7ˠLorL\/?=OC*+] {KRLB e3j] +myښ HJ_v:b@ 6 S~E|sUj\GO}ۊ9mQ\3o/{u8=wo,hy βz*u3G3REP`aʭGY\WkO ӧn٫~J2Ɠ3*}esWAWtf(:9Q2KdmnmF|IaH3_6xE\+էRzZM A :)ixu J;4ʾ%Bu> f:0ȍ\$0N&MfBMprcg4IŹy6i dʣ?6'R?XT{􍰂3_6xE\Wy^KBQ$7PX-.\eϯ[K'+ dZF.Y'}s|{ǏN#_oYFg\ LmNv9p\=I:Pcj۽3upwF !5Avz֮&BhK*M%ZnjDwe3c$cH+۝@}nK B<^ o)<n4 i$SFM8⅏! <{KRi_ǹ4AcH+ۭѴuO|h{P-S}FtLv,˓jsȧTMbݗၘ6aٳeΏV嘣CiC%gTG8N Aܨ095i|{u Oi_ǹ4AcH+_(\:iZ|"-ڶaeײ<&sN[KP0<݂1N=.w;!~ͦ8|ˑ~'Z*tf2af4K-צ msL]`GPQ ӭ>V`;~㝯#@%3f^7壉E~ q9!tAp]OiΗ`fC(UvL3N+/AHUEk V$Egf\Ƶ t ,dhOh{ڲ KuX*SMHxV$K^o\%d|ߋQu ~HoKM/ikCtLEzyJײ<&s $lookupArrayValue) { if (is_string($lookupArrayValue) && WildcardMatch::compare($lookupArrayValue, $wildcard)) { return $i; } } } else { foreach ($lookupArray as $i => $lookupArrayValue) { if ($lookupArrayValue === $lookupValue) { return $keySet[$i]; } } } } $valueIsNumeric = is_int($lookupValue) || is_float($lookupValue); foreach ($lookupArray as $i => $lookupArrayValue) { if ($valueIsNumeric && (is_int($lookupArrayValue) || is_float($lookupArrayValue))) { if ($lookupArrayValue <= $lookupValue) { return array_search($i, $keySet); } } $typeMatch = gettype($lookupValue) === gettype($lookupArrayValue); if ($typeMatch && ($lookupArrayValue <= $lookupValue)) { return array_search($i, $keySet); } } return null; } /** * @param mixed $lookupValue * * @return mixed */ private static function matchSmallestValue(array $lookupArray, $lookupValue) { $valueKey = null; if (is_string($lookupValue)) { if (Functions::getCompatibilityMode() === Functions::COMPATIBILITY_OPENOFFICE) { $wildcard = WildcardMatch::wildcard($lookupValue); foreach ($lookupArray as $i => $lookupArrayValue) { if (is_string($lookupArrayValue) && WildcardMatch::compare($lookupArrayValue, $wildcard)) { return $i; } } } } $valueIsNumeric = is_int($lookupValue) || is_float($lookupValue); // The basic algorithm is: // Iterate and keep the highest match until the next element is smaller than the searched value. // Return immediately if perfect match is found foreach ($lookupArray as $i => $lookupArrayValue) { $typeMatch = gettype($lookupValue) === gettype($lookupArrayValue); $bothNumeric = $valueIsNumeric && (is_int($lookupArrayValue) || is_float($lookupArrayValue)); if ($lookupArrayValue === $lookupValue) { // Another "special" case. If a perfect match is found, // the algorithm gives up immediately return $i; } if ($bothNumeric && $lookupValue == $lookupArrayValue) { return $i; // exact match, as above } if (($typeMatch || $bothNumeric) && $lookupArrayValue >= $lookupValue) { $valueKey = $i; } elseif ($typeMatch && $lookupArrayValue < $lookupValue) { //Excel algorithm gives up immediately if the first element is smaller than the searched value break; } } return $valueKey; } /** * @param mixed $lookupValue */ private static function validateLookupValue($lookupValue): void { // Lookup_value type has to be number, text, or logical values if ((!is_numeric($lookupValue)) && (!is_string($lookupValue)) && (!is_bool($lookupValue))) { throw new Exception(ExcelError::NA()); } } /** * @param mixed $matchType */ private static function validateMatchType($matchType): int { // Match_type is 0, 1 or -1 // However Excel accepts other numeric values, // including numeric strings and floats. // It seems to just be interested in the sign. if (!is_numeric($matchType)) { throw new Exception(ExcelError::Value()); } if ($matchType > 0) { return self::MATCHTYPE_LARGEST_VALUE; } if ($matchType < 0) { return self::MATCHTYPE_SMALLEST_VALUE; } return self::MATCHTYPE_FIRST_VALUE; } private static function validateLookupArray(array $lookupArray): void { // Lookup_array should not be empty $lookupArraySize = count($lookupArray); if ($lookupArraySize <= 0) { throw new Exception(ExcelError::NA()); } } /** * @param mixed $matchType */ private static function prepareLookupArray(array $lookupArray, $matchType): array { // Lookup_array should contain only number, text, or logical values, or empty (null) cells foreach ($lookupArray as $i => $value) { // check the type of the value if ((!is_numeric($value)) && (!is_string($value)) && (!is_bool($value)) && ($value !== null)) { throw new Exception(ExcelError::NA()); } // Convert strings to lowercase for case-insensitive testing if (is_string($value)) { $lookupArray[$i] = StringHelper::strToLower($value); } if ( ($value === null) && (($matchType == self::MATCHTYPE_LARGEST_VALUE) || ($matchType == self::MATCHTYPE_SMALLEST_VALUE)) ) { unset($lookupArray[$i]); } } return $lookupArray; } }