From 08ced34dfd831ef76e74f8ca464b23c8f895bbb0 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 19 Mar 2017 14:17:20 +0000 Subject: [PATCH] SUBTOTAL options for ignoring hidden cells --- src/PhpSpreadsheet/Calculation.php | 3 +- src/PhpSpreadsheet/Calculation/MathTrig.php | 39 +++++++++++++++++++-- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/PhpSpreadsheet/Calculation.php b/src/PhpSpreadsheet/Calculation.php index 930bf9ea..9383c37c 100644 --- a/src/PhpSpreadsheet/Calculation.php +++ b/src/PhpSpreadsheet/Calculation.php @@ -1767,6 +1767,7 @@ class Calculation 'category' => Category::CATEGORY_MATH_AND_TRIG, 'functionCall' => [MathTrig::class, 'SUBTOTAL'], 'argumentCount' => '2+', + 'passCellReference' => true, ], 'SUM' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, @@ -3721,6 +3722,7 @@ class Calculation } // Reverse the order of the arguments krsort($args); + if (($passByReference) && ($argCount == 0)) { $args[] = $cellID; $argArrayVals[] = $this->showValue($cellID); @@ -3744,7 +3746,6 @@ class Calculation } unset($arg); } - $result = call_user_func_array($functionCall, $args); if ($functionName != 'MKMATRIX') { diff --git a/src/PhpSpreadsheet/Calculation/MathTrig.php b/src/PhpSpreadsheet/Calculation/MathTrig.php index 6ea7ba66..2d7b6da8 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig.php @@ -1123,6 +1123,16 @@ class MathTrig return Functions::VALUE(); } + protected static function filterHiddenArgs($cellReference, $args) { + return array_filter($args, + function ($index) use ($cellReference) { + list(, $row, $column) = explode('.', $index); + return $cellReference->getWorksheet()->getRowDimension($row)->getVisible() && + $cellReference->getWorksheet()->getColumnDimension($column)->getVisible(); + }, + ARRAY_FILTER_USE_KEY + ); + } /** * SUBTOTAL. * @@ -1136,33 +1146,56 @@ class MathTrig */ public static function SUBTOTAL(...$args) { - $aArgs = Functions::flattenArray($args); + $aArgs = Functions::flattenArrayIndexed($args); + $cellReference = array_pop($aArgs); + $subtotal = array_shift($aArgs); +// var_dump($cellReference->getValue(), $aArgs); die(); // Calculate - $subtotal = array_shift($aArgs); - if ((is_numeric($subtotal)) && (!is_string($subtotal))) { switch ($subtotal) { + case 101: + $aArgs = self::filterHiddenArgs($cellReference, $aArgs); case 1: return Statistical::AVERAGE($aArgs); + case 102: + $aArgs = self::filterHiddenArgs($cellReference, $aArgs); case 2: return Statistical::COUNT($aArgs); + case 103: + $aArgs = self::filterHiddenArgs($cellReference, $aArgs); case 3: return Statistical::COUNTA($aArgs); + case 104: + $aArgs = self::filterHiddenArgs($cellReference, $aArgs); case 4: return Statistical::MAX($aArgs); + case 105: + $aArgs = self::filterHiddenArgs($cellReference, $aArgs); case 5: return Statistical::MIN($aArgs); + case 106: + $aArgs = self::filterHiddenArgs($cellReference, $aArgs); case 6: return self::PRODUCT($aArgs); + case 107: + $aArgs = self::filterHiddenArgs($cellReference, $aArgs); case 7: return Statistical::STDEV($aArgs); + case 108: + $aArgs = self::filterHiddenArgs($cellReference, $aArgs); case 8: return Statistical::STDEVP($aArgs); + case 109: + $aArgs = self::filterHiddenArgs($cellReference, $aArgs); case 9: return self::SUM($aArgs); + case 110: + $aArgs = self::filterHiddenArgs($cellReference, $aArgs); case 10: return Statistical::VARFunc($aArgs); + case 111: + $aArgs = self::filterHiddenArgs($cellReference, $aArgs); case 11: return Statistical::VARP($aArgs); }