1

This is a similar problem to Using ARRAYFORMULA with SUMIF for multiple conditions combined with a wildcard to select all values for a given condition, but trying to get the sum of the first column by all months of a given year. I was trying to extrapolate the same solution provided by @player0, but group by doesn't work because I would like to get a result for each month of the year, regardless of the month's data on the source. Here is the sample:

Screenshot of the Spreadsheet

In column G we have different filter conditions and it can include a special token: ALL to include all values for each criterion. For the year we can select the given year for which we want to sum the result by each month of the year.

Column I has the expected result using the similar idea of the referred question, but it cannot be expressed in an ArrayFormula (query result doesn't expand):

=IFNA(QUERY(QUERY(FILTER($A$2:$E, 
 IF($G$2="All", $B$2:$B<>"×", $B$2:$B=$G$2), 
 IF($G$4="All", $C$2:$C<>"×", $C$2:$C=$G$4), 
 IF($G$6="All", $D$2:$D<>"×", $D$2:$D=$G$6),
 YEAR($E$2:$E) = $G$8
 ), 
 "select sum(Col1) where month(Col5) =" & MONTH($H2) - 1), 
  "offset 1", 0),"")

On column J the array try doesn't work because we cannot use the virtual range with SUMIF it can be resolved by creating auxiliary columns with the FILTER, but I am looking for a solution that doesn't require that.

=Arrayformula(if(not(ISBLANK(H2:H)), sumif(
Filter(FILTER($A$2:$E, IF($G$3="All", $B$2:$B<>"×",
 $B$2:$B=$G$3), IF($G$5="All", $C$2:$C<>"×", $C$2:$C=$G$5), 
 IF($G$7="All", $D$2:$D<>"×", $D$2:$D=$G$7), 
 YEAR($E$2:$E) = $G$9),{1,0,0,0,0}), H2:H,
Filter(FILTER($A$2:$E, IF($G$3="All", $B$2:$B<>"×", 
 $B$2:$B=$G$3), IF($G$5="All", $C$2:$C<>"×", $C$2:$C=$G$5), 
 IF($G$7="All", $D$2:$D<>"×", $D$2:$D=$G$7), 
  YEAR($E$2:$E) = $G$9), {0,0,0,0,1})
),))

Here is the sample spreadsheet: https://docs.google.com/spreadsheets/d/1Lqjim3c_j8KNr_7LVlKjlR4BXi9_1HFoGDuwsuX1XS0/edit?usp=sharing

player0
  • 124,011
  • 12
  • 67
  • 124
David Leal
  • 6,373
  • 4
  • 29
  • 56
  • You have been asking various versions of this question and about this particular problem for a few days now right? on a couple different help forums? – MattKing Apr 20 '22 at 01:57
  • No @MattKing I asked only in Stackoverflow for an Arrayformula solution. The only similarity is with the question I linked in my post. In this post, the ask is how to sum based on every month of the year, and on the previous question, the need is to group by year. The solutions are different because of that. I hope it helps. – David Leal Apr 20 '22 at 16:57

2 Answers2

2

try:

=INDEX(IFNA(VLOOKUP(MONTH(H2:H13), QUERY(QUERY(FILTER(A2:E, 
 IF(G3="All", B2:B<>"×", B2:B=G3), 
 IF(G5="All", C2:C<>"×", C2:C=G5), 
 IF(G7="All", D2:D<>"×", D2:D=G7)), 
 "select month(Col5)+1,sum(Col1) 
  where Col1 is not null "&IF(G9="",," 
    and year(Col5)="&G9)&  
 "group by month(Col5)+1"), 
  "offset 1", 0), 2, 0)))

enter image description here

player0
  • 124,011
  • 12
  • 67
  • 124
  • Thanks again @player0 I was able to understand your solution, and learn from it. I have only one question, why on this particular case you use `INDEX` instead of `ARRAYFORMULA` replacing one with another produces the same result. Thanks – David Leal Apr 20 '22 at 03:31
  • 1
    @DavidLeal I tend to use index over arrayformula just because its shorter to type in. – player0 Apr 20 '22 at 08:10
1

This formula is in cell L2 of your sample Sheet1. It is a sumif() that uses a regex and MMULT to create an array of 3's where the conditions are met and &'s it with the month for the 'sumif' criterium.

=ARRAYFORMULA(SUMIF(MMULT(N(REGEXMATCH(B2:D,SUBSTITUTE({G3,G5,G7},"ALL",))),
 {1;1;1})&EOMONTH(E2:E,-1)+1,3&H2:H13,A2:A))

Detail Explanation (The formula, then in the following lines the explanation)

SUBSTITUTE({G3,G5,G7},"ALL",)

Generate a 1x3 array with G3,G5,G7 values, if "ALL" then will be replaced by empty string. In case of ("ALL", ALL", "ALL") returns: (,,). The result of SUBSTITUTE will be the regular expression to be used in REGEXMATCH. In case of ("ALL", ALL", "ALL") REGEXMATCH will return (TRUE, TRUE, TRUE) on each row.

REGEXMATCH(B2:D,SUBSTITUTE({G3,G5,G7},"ALL",))

Return an array of the same size as B2:D (let's say Mx3 array) where the condition are met (TRUE|FALSE) values and the function N()converts it into (0|1) values.

MMULT(N(REGEXMATCH(B2:D,SUBSTITUTE({G3,G5,G7},"ALL",))),
 {1;1;1})

Multiplies two matrixes: Mx3 x 3x1 and returns an array Mx1. If all filters conditions are satisfied will return on a given cell the number 3 (we have three conditions), otherwise a number lower than 3.

EOMONTH(E2:E,-1)+1

Calculate the last day of the previous month of the cells E2:E and add one day resulting the first day of the month of E2:E. We need to compare such dates with the dates in H2:Hthat represent the first day of the month.

SUMIF(range, criterion, [sum_range])
  • range: will contain an array of Mx1 with one of the values: {0,1,2,3} depending on how many conditions are met. It appends &EOMONTH(E2:E,-1)+1. Remember dates are stored as an integer number.

  • criterium: 3&H2:H13the reference dates prefixed by number 3.

  • sum_range: The range A2:A we want to sum based on the range and criterium match, so only rows with 3 values of MMULT will be considered.

Here the result in case of filters have the value ALL: Using ALL token

Here the solution when ALL token is not used: Not using ALL token

Note: The only difference with expected result and @player0 solution is that it returns 0when there is no match.

David Leal
  • 6,373
  • 4
  • 29
  • 56
MattKing
  • 7,373
  • 8
  • 13
  • 2
    @player0 sometimes nice to use REGEXMATCH for "ALL" stuff. – MattKing Apr 20 '22 at 02:25
  • Thanks @MattKing for your response, I am trying to understand it. I don't see on my shared Spreadsheet your formula on `I1`. The result returns sum as a header and two columns, the first one with the dates. Is it possible to remove that column? The result is returned on the following row, not on the cell the formula is provided. On my question I indicated the other linked question, I was only posted about this similar problem here, not in other forums. – David Leal Apr 20 '22 at 02:55
  • 1
    @DavidLeal Updated my answer based on your request that it just be a simple sumif() type thing rather than the more complicated QUERY() that returns everything. See cell M2 on the MK.idea tab. – MattKing Apr 20 '22 at 18:14
  • Thanks, I saw it, your solution also works, I marked the @Player0 solution as the accepted answer because I was able to understand it better, I am still trying to understand your solution, but both work. Thanks! – David Leal Apr 21 '22 at 01:02
  • Your last update @MattKing using `MMULT`is really an elegant one solution, it is a shorter formula. I was able to understand it. It provides a solution using `SUMIF`. Thanks – David Leal Apr 21 '22 at 02:13
  • I have a question @MattKing, how do you take into account the year filter on `G9` I don't see it as part of your formula and I guess it should be. The fact is that when I change the reference year to 2021 it works, but I don't know how it could. Thanks – David Leal Apr 21 '22 at 02:25
  • 1
    Good question @DavidLeal. I neglected to include a separate month-generating column because you had that part working on your original attempt. So i was kind of cheating by referring to the months generated in my other formula. I've since updated the formula one more time to refer to your copied month-generating formula (which does refer to the year in G9). – MattKing Apr 21 '22 at 11:44
  • Thanks, @MattKing, I see your point `G9` is considered on your formula because `H2:H13` is built based on the `G9` value. Great! It brought to my attention that in the formula: `SUBSTITUTE({G3,G5,G7},"ALL",)` `G9` was not present. There was no need to update the Spreadsheet, my bad that I didn't realize the `G9` condition was hidden on `H2:H13`. On my real problem, I am using player0 solution, it is easier for me to manage and control the steps. Your solution is great, but it is less intuitive to track and follow the steps – David Leal Apr 21 '22 at 14:58