/** * SUMIFS * * Counts the number of cells that contain numbers within the list of arguments * * Excel Function: * SUMIFS(value1[,value2[, ...]],condition) * * @access public * @category Mathematical and Trigonometric Functions * @param mixed $arg,... Data values * @param string $condition The criteria that defines which cells will be summed. * @return float */ public static function SUMIFS() { $arrayList = func_get_args(); // Return value $returnValue = 0; $sumArgs = Functions::flattenArray(array_shift($arrayList)); while (count($arrayList) > 0) { $aArgsArray[] = Functions::flattenArray(array_shift($arrayList)); $conditions[] = Functions::ifCondition(array_shift($arrayList)); } // Loop through each set of arguments and conditions foreach ($conditions as $index => $condition) { $aArgs = $aArgsArray[$index]; // Loop through arguments foreach ($aArgs as $key => $arg) { if (!is_numeric($arg)) { $arg = \PHPExcel\Calculation::wrapResult(strtoupper($arg)); } $testCondition = '=' . $arg . $condition; if (\PHPExcel\Calculation::getInstance()->_calculateFormulaValue($testCondition)) { // Is it a value within our criteria $returnValue += $sumArgs[$key]; } } } // Return return $returnValue; }
public static function ifCondition($condition) { $condition = Functions::flattenSingleValue($condition); if (!isset($condition[0])) { $condition = '=""'; } if (!in_array($condition[0], array('>', '<', '='))) { if (!is_numeric($condition)) { $condition = \PHPExcel\Calculation::wrapResult(strtoupper($condition)); } return '=' . $condition; } else { preg_match('/([<>=]+)(.*)/', $condition, $matches); list(, $operator, $operand) = $matches; if (!is_numeric($operand)) { $operand = str_replace('"', '""', $operand); $operand = \PHPExcel\Calculation::wrapResult(strtoupper($operand)); } return $operator . $operand; } }
/** * MINIF * * Returns the minimum value within a range of cells that contain numbers within the list of arguments * * Excel Function: * MINIF(value1[,value2[, ...]],condition) * * @access public * @category Mathematical and Trigonometric Functions * @param mixed $arg,... Data values * @param string $condition The criteria that defines which cells will be checked. * @return float */ public static function MINIF($aArgs, $condition, $sumArgs = array()) { $returnValue = null; $aArgs = Functions::flattenArray($aArgs); $sumArgs = Functions::flattenArray($sumArgs); if (empty($sumArgs)) { $sumArgs = $aArgs; } $condition = Functions::ifCondition($condition); // Loop through arguments foreach ($aArgs as $key => $arg) { if (!is_numeric($arg)) { $arg = \PHPExcel\Calculation::wrapResult(strtoupper($arg)); } $testCondition = '=' . $arg . $condition; if (\PHPExcel\Calculation::getInstance()->_calculateFormulaValue($testCondition)) { if (is_null($returnValue) || $arg < $returnValue) { $returnValue = $arg; } } } return $returnValue; }
/** * filter * * Parses the selection criteria, extracts the database rows that match those criteria, and * returns that subset of rows. * * @access private * @param mixed[] $database The range of cells that makes up the list or database. * A database is a list of related data in which rows of related * information are records, and columns of data are fields. The * first row of the list contains labels for each column. * @param mixed[] $criteria The range of cells that contains the conditions you specify. * You can use any range for the criteria argument, as long as it * includes at least one column label and at least one cell below * the column label in which you specify a condition for the * column. * @return array of mixed * */ private static function filter($database, $criteria) { $fieldNames = array_shift($database); $criteriaNames = array_shift($criteria); // Convert the criteria into a set of AND/OR conditions with [:placeholders] $testConditions = $testValues = array(); $testConditionsCount = 0; foreach ($criteriaNames as $key => $criteriaName) { $testCondition = array(); $testConditionCount = 0; foreach ($criteria as $row => $criterion) { if ($criterion[$key] > '') { $testCondition[] = '[:' . $criteriaName . ']' . Functions::ifCondition($criterion[$key]); $testConditionCount++; } } if ($testConditionCount > 1) { $testConditions[] = 'OR(' . implode(',', $testCondition) . ')'; $testConditionsCount++; } elseif ($testConditionCount == 1) { $testConditions[] = $testCondition[0]; $testConditionsCount++; } } if ($testConditionsCount > 1) { $testConditionSet = 'AND(' . implode(',', $testConditions) . ')'; } elseif ($testConditionsCount == 1) { $testConditionSet = $testConditions[0]; } // Loop through each row of the database foreach ($database as $dataRow => $dataValues) { // Substitute actual values from the database row for our [:placeholders] $testConditionList = $testConditionSet; foreach ($criteriaNames as $key => $criteriaName) { $k = array_search($criteriaName, $fieldNames); if (isset($dataValues[$k])) { $dataValue = $dataValues[$k]; $dataValue = is_string($dataValue) ? \PHPExcel\Calculation::wrapResult(strtoupper($dataValue)) : $dataValue; $testConditionList = str_replace('[:' . $criteriaName . ']', $dataValue, $testConditionList); } } // evaluate the criteria against the row data $result = \PHPExcel\Calculation::getInstance()->_calculateFormulaValue('=' . $testConditionList); // If the row failed to meet the criteria, remove it from the database if (!$result) { unset($database[$dataRow]); } } return $database; }