SUMIFS sum values only once

Values were summed multiple times if it matched several conditions
whereas it should only be summed once.

Fixes #704
Fixes #710
This commit is contained in:
marcusblevin 2018-10-08 15:38:50 -04:00 committed by Adrien Crivelli
parent ed6a3a0148
commit 98d10475f2
No known key found for this signature in database
GPG Key ID: B182FD79DC6DE92E
4 changed files with 80 additions and 9 deletions

View File

@ -9,7 +9,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Fixed ### Fixed
- Support numeric condition in SUMIF, SUMIFS, AVERAGEIF, COUNTIF, MAXIF and MINIF [#683](https://github.com/PHPOffice/PhpSpreadsheet/issues/683) - Support numeric condition in SUMIF, SUMIFS, AVERAGEIF, COUNTIF, MAXIF and MINIF - [#683](https://github.com/PHPOffice/PhpSpreadsheet/issues/683)
- SUMIFS containing multiple conditions - [#704](https://github.com/PHPOffice/PhpSpreadsheet/issues/704)
## [1.5.0] - 2018-10-21 ## [1.5.0] - 2018-10-21

View File

@ -1256,27 +1256,37 @@ class MathTrig
$returnValue = 0; $returnValue = 0;
$sumArgs = Functions::flattenArray(array_shift($arrayList)); $sumArgs = Functions::flattenArray(array_shift($arrayList));
$aArgsArray = [];
$conditions = [];
while (count($arrayList) > 0) { while (count($arrayList) > 0) {
$aArgsArray[] = Functions::flattenArray(array_shift($arrayList)); $aArgsArray[] = Functions::flattenArray(array_shift($arrayList));
$conditions[] = Functions::ifCondition(array_shift($arrayList)); $conditions[] = Functions::ifCondition(array_shift($arrayList));
} }
// Loop through each set of arguments and conditions // Loop through each sum and see if arguments and conditions are true
foreach ($conditions as $index => $condition) { foreach ($sumArgs as $index => $value) {
$aArgs = $aArgsArray[$index]; $valid = true;
// Loop through arguments foreach ($conditions as $cidx => $condition) {
foreach ($aArgs as $key => $arg) { $arg = $aArgsArray[$cidx][$index];
// Loop through arguments
if (!is_numeric($arg)) { if (!is_numeric($arg)) {
$arg = Calculation::wrapResult(strtoupper($arg)); $arg = Calculation::wrapResult(strtoupper($arg));
} }
$testCondition = '=' . $arg . $condition; $testCondition = '=' . $arg . $condition;
if (Calculation::getInstance()->_calculateFormulaValue($testCondition)) { if (!Calculation::getInstance()->_calculateFormulaValue($testCondition)) {
// Is it a value within our criteria // Is not a value within our criteria
$returnValue += $sumArgs[$key]; $valid = false;
break; // if false found, don't need to check other conditions
} }
} }
if ($valid) {
$returnValue += $value;
}
} }
// Return // Return

View File

@ -568,6 +568,22 @@ class MathTrigTest extends TestCase
return require 'data/Calculation/MathTrig/SUMIF.php'; return require 'data/Calculation/MathTrig/SUMIF.php';
} }
/**
* @dataProvider providerSUMIFS
*
* @param mixed $expectedResult
*/
public function testSUMIFS($expectedResult, ...$args)
{
$result = MathTrig::SUMIFS(...$args);
self::assertEquals($expectedResult, $result, '', 1E-12);
}
public function providerSUMIFS()
{
return require 'data/Calculation/MathTrig/SUMIFS.php';
}
/** /**
* @dataProvider providerSUBTOTAL * @dataProvider providerSUBTOTAL
* *

View File

@ -0,0 +1,44 @@
<?php
return [
[
2,
[
[1],
[1],
[1],
],
[
['Y'],
['Y'],
['N'],
],
'=Y',
[
['H'],
['H'],
['H'],
],
'=H',
],
[
1,
[
[1],
[1],
[1],
],
[
['A'],
['B'],
['C'],
],
'=B',
[
['C'],
['B'],
['A'],
],
'=B',
],
];