Range argument tests with default value in cell range methods, and further

AutoFilter expression evaluation for dynamic filters
This commit is contained in:
Mark Baker 2012-08-16 22:53:13 +01:00
parent bb0d413a67
commit 960f5a32a2
2 changed files with 73 additions and 17 deletions

View File

@ -35,6 +35,14 @@
*/ */
class PHPExcel_Cell class PHPExcel_Cell
{ {
/**
* Default range variable constant
*
* @var string
*/
const DEFAULT_RANGE = 'A1:A1';
/** /**
* Value binder to use * Value binder to use
* *
@ -600,6 +608,11 @@ class PHPExcel_Cell
*/ */
public static function splitRange($pRange = 'A1:A1') public static function splitRange($pRange = 'A1:A1')
{ {
// Ensure $pRange is a valid range
if(empty($pRange)) {
$pRange = self::DEFAULT_RANGE;
}
$exploded = explode(',', $pRange); $exploded = explode(',', $pRange);
$counter = count($exploded); $counter = count($exploded);
for ($i = 0; $i < $counter; ++$i) { for ($i = 0; $i < $counter; ++$i) {
@ -642,6 +655,11 @@ class PHPExcel_Cell
*/ */
public static function rangeBoundaries($pRange = 'A1:A1') public static function rangeBoundaries($pRange = 'A1:A1')
{ {
// Ensure $pRange is a valid range
if(empty($pRange)) {
$pRange = self::DEFAULT_RANGE;
}
// Uppercase coordinate // Uppercase coordinate
$pRange = strtoupper($pRange); $pRange = strtoupper($pRange);
@ -686,6 +704,11 @@ class PHPExcel_Cell
*/ */
public static function getRangeBoundaries($pRange = 'A1:A1') public static function getRangeBoundaries($pRange = 'A1:A1')
{ {
// Ensure $pRange is a valid range
if(empty($pRange)) {
$pRange = self::DEFAULT_RANGE;
}
// Uppercase coordinate // Uppercase coordinate
$pRange = strtoupper($pRange); $pRange = strtoupper($pRange);

View File

@ -281,11 +281,17 @@ class PHPExcel_Worksheet_AutoFilter
return FALSE; return FALSE;
} }
private static function _filterTypeCustomFilters($cellValue,$ruleSet) private static function _filterTestInCustomDataSet($cellValue,$ruleSet)
{ {
echo 'CALLING _filterTestInCustomDataSet',PHP_EOL;
$dataSet = $ruleSet['filterRules']; $dataSet = $ruleSet['filterRules'];
$join = $ruleSet['join']; $join = $ruleSet['join'];
if (($cellValue == '') || ($cellValue === NULL)) {
echo 'EMPTY CELL',PHP_EOL;
return FALSE;
}
$returnVal = ($join == PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_ANDOR_AND); $returnVal = ($join == PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_ANDOR_AND);
foreach($dataSet as $rule) { foreach($dataSet as $rule) {
if (is_numeric($rule['value'])) { if (is_numeric($rule['value'])) {
@ -311,14 +317,15 @@ class PHPExcel_Worksheet_AutoFilter
break; break;
} }
} else { } else {
// String values are always tested for equality // String values are always tested for equality, factoring in for wildcards (hence a regexp test)
$retVal = preg_match('/^'.$rule['value'].'$/',$cellValue); $retVal = preg_match('/^'.$rule['value'].'$/i',$cellValue);
} }
// If there are multiple conditions, then we need to test both using the appropriate join operator // If there are multiple conditions, then we need to test both using the appropriate join operator
switch ($join) { switch ($join) {
case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_ANDOR_OR : case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_ANDOR_OR :
$returnVal = $returnVal || $retVal; $returnVal = $returnVal || $retVal;
// Break as soon as we have a match for OR joins // Break as soon as we have a TRUE match for OR joins,
// to avoid unnecessary additional code execution
if ($returnVal) if ($returnVal)
return $returnVal; return $returnVal;
break; break;
@ -333,11 +340,13 @@ class PHPExcel_Worksheet_AutoFilter
private static function _filterTypeDynamicFilters($cellValue,$testSet) private static function _filterTypeDynamicFilters($cellValue,$testSet)
{ {
echo 'CALLING _filterTypeDynamicFilters',PHP_EOL;
return TRUE; return TRUE;
} }
private static function _filterTypeTopTenFilters($cellValue,$testSet) private static function _filterTypeTopTenFilters($cellValue,$testSet)
{ {
echo 'CALLING _filterTypeTopTenFilters',PHP_EOL;
return TRUE; return TRUE;
} }
@ -430,13 +439,8 @@ class PHPExcel_Worksheet_AutoFilter
$ruleValue = $rule->getValue(); $ruleValue = $rule->getValue();
if (!is_numeric($ruleValue)) { if (!is_numeric($ruleValue)) {
// Convert to a regexp allowing for regexp reserved characters, wildcards and escaped wildcards // Convert to a regexp allowing for regexp reserved characters, wildcards and escaped wildcards
var_dump($ruleValue);
echo ' = > ';
$ruleValue = preg_quote($ruleValue); $ruleValue = preg_quote($ruleValue);
var_dump($ruleValue);
echo ' = > ';
$ruleValue = str_replace(self::$_fromReplace,self::$_toReplace,$ruleValue); $ruleValue = str_replace(self::$_fromReplace,self::$_toReplace,$ruleValue);
var_dump($ruleValue);
} }
$ruleValues[] = array( 'operator' => $rule->getOperator(), $ruleValues[] = array( 'operator' => $rule->getOperator(),
'value' => $ruleValue 'value' => $ruleValue
@ -444,7 +448,7 @@ var_dump($ruleValue);
} }
$join = $filterColumn->getAndOr(); $join = $filterColumn->getAndOr();
$columnFilterTests[$columnID] = array( $columnFilterTests[$columnID] = array(
'method' => '_filterTypeCustomFilters', 'method' => '_filterTestInCustomDataSet',
'arguments' => array( 'filterRules' => $ruleValues, 'arguments' => array( 'filterRules' => $ruleValues,
'join' => $join 'join' => $join
) )
@ -452,15 +456,44 @@ var_dump($ruleValue);
break; break;
case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER : case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER :
$ruleValues = array(); $ruleValues = array();
//var_dump($rules);
foreach($rules as $rule) {
// We should only ever have one Dynamic Filter Rule anyway
$dynamicRuleType = $rule->getGrouping();
echo '$dynamicRuleType is ',$dynamicRuleType,PHP_EOL;
if (($dynamicRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE) ||
($dynamicRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE)) {
// Number based
$averageFormula = '=AVERAGE('.$columnID.($rangeStart[1]+1).':'.$columnID.$rangeEnd[1].')';
echo 'Average Formula Result is ',$averageFormula,PHP_EOL;
$average = PHPExcel_Calculation::getInstance()->calculateFormula($averageFormula,NULL,$this->_workSheet->getCell('A1'));
$operator = ($dynamicRuleType === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE)
? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN
: PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN;
$ruleValues[] = array( 'operator' => $operator,
'value' => $average
);
$columnFilterTests[$columnID] = array(
'method' => '_filterTestInCustomDataSet',
'arguments' => array( 'filterRules' => $ruleValues,
'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_ANDOR_OR
)
);
} else {
// Date based
$columnFilterTests[$columnID] = array( $columnFilterTests[$columnID] = array(
'method' => '_filterTypeDynamicFilters', 'method' => '_filterTypeDynamicFilters',
'arguments' => $ruleValues 'arguments' => $ruleValues
); );
}
}
break; break;
case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER : case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER :
$ruleValues = array(); $ruleValues = array();
var_dump($rules);
foreach($rules as $rule) {
// We should only ever have one Dynamic Filter Rule anyway
}
$columnFilterTests[$columnID] = array( $columnFilterTests[$columnID] = array(
'method' => '_filterTypeTopTenFilters', 'method' => '_filterTypeTopTenFilters',
'arguments' => $ruleValues 'arguments' => $ruleValues
@ -489,7 +522,7 @@ var_dump($ruleValue);
) )
); );
echo (($result) ? 'VALID' : 'INVALID'),PHP_EOL; echo (($result) ? 'VALID' : 'INVALID'),PHP_EOL;
// If filter test has resulted in FALSE, exit straightaway rather than running any more tests // If filter test has resulted in FALSE, exit the loop straightaway rather than running any more tests
if (!$result) if (!$result)
break; break;
} }