public static function VLOOKUP($lookup_value, $lookup_array, $index_number, $not_exact_match=true) {
		$lookup_value	= PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value);
		$index_number	= PHPExcel_Calculation_Functions::flattenSingleValue($index_number);
		$not_exact_match	= PHPExcel_Calculation_Functions::flattenSingleValue($not_exact_match);

		// index_number must be greater than or equal to 1
		if ($index_number < 1) {
			return PHPExcel_Calculation_Functions::VALUE();
		}

		// index_number must be less than or equal to the number of columns in lookup_array
		if ((!is_array($lookup_array)) || (empty($lookup_array))) {
			return PHPExcel_Calculation_Functions::REF();
		} else {
			$f = array_keys($lookup_array);
			$firstRow = array_pop($f);
			if ((!is_array($lookup_array[$firstRow])) || ($index_number > count($lookup_array[$firstRow]))) {
				return PHPExcel_Calculation_Functions::REF();
			} else {
				$columnKeys = array_keys($lookup_array[$firstRow]);
				$returnColumn = $columnKeys[--$index_number];
				$firstColumn = array_shift($columnKeys);
			}
		}

		if (!$not_exact_match) {
			uasort($lookup_array,array('self','_vlookupSort'));
		}

		$rowNumber = $rowValue = False;
		foreach($lookup_array as $rowKey => $rowData) {
			if (strtolower($rowData[$firstColumn]) > strtolower($lookup_value)) {
				break;
			}
			$rowNumber = $rowKey;
			$rowValue = $rowData[$firstColumn];
		}

		if ($rowNumber !== false) {
			if ((!$not_exact_match) && ($rowValue != $lookup_value)) {
				//	if an exact match is required, we have what we need to return an appropriate response
				return PHPExcel_Calculation_Functions::NA();
			} else {
				//	otherwise return the appropriate value
				return $lookup_array[$rowNumber][$returnColumn];
			}
		}

		return PHPExcel_Calculation_Functions::NA();
	}