How to use SUMIF with the criteria as text within a string - google-sheets

I have column A that has dates in the "8-Oct-2021" format, I have column B that has numbers I want summed.
=SUMIF(A2:A, "*Oct*", B2:B)
I currently have the formula above, with the criteria as "*Oct*" because there's text before and after the 'Oct'. I have other months so I want each month added up.
=SUMIFS(B2:B, A2:A, ">="&DATE(2021,10,1), A2:A, "<="&DATE(2021,10,30))
Above does the trick, but I'd like to keep it simple with the first formula. Suggestions?

At the moment you have numbers in range A2:A, not text, because the dates in GS are numbers, so your formula SUMIF() will return 0.
You can shorten your SUMIFS() formula to =ARRAYFORMULA(SUMIF(month(A2:A), 10, B2:B)) or to =ARRAYFORMULA(SUMIF(text(A2:A, "mmm"), "Oct", B2:B))

Related

Google sheets sumif with odd data

I have sales data that gives me dates in a bad format. Every new sale gets automatically added to the sheet. Looks like this:
Column A
Column B
Column C
Order 1
2022-12-02T02:09:37Z
$1025.19
Order 2
2022-12-02T01:25:15Z
$873.65
This will continue on for all sales. Now the date format is UTC for whatever reason and I can't adjust that, so within this formula I have to subtract 6 hours to get it to central time. I'm trying to create an auto-updating chart that shows an average day for 7 days, so I'm trying to do a sumif formula.
Here's what I have on Sheet2:
=sumif(Sheet1!C:C,index(split((index(split(Sheet1!B:B,"T"),1)+index(split(left(Sheet1!B:B,19),"T"),2))-0.25,"."),1),A1)
Where A1 is a single date. Testing this with one date and not the range shows that it does match. When I do the range, the total comes to 0, even though multiple different dates should match. What am I doing wrong?
Assume A1 has the value: 2022-12-02T02:09:37Z
Apply this formula:
=LAMBDA(RAW,TUNEHOUR,
LAMBDA(DATE,TIME,
TEXT((DATE&" "&TIME)+TUNEHOUR/24,"yyyy-mm-dd hh:mm:ss")
)(TEXT(INDEX(RAW,,1),"yyyy-mm-dd"),REGEXREPLACE(INDEX(RAW,,2),"Z",""))
)(SPLIT(A1,"T"),-6)
returns:
2022-12-01 20:09:37
And assume you have a set of data like this:
you can apply this formula:
=ArrayFormula(
LAMBDA(DATES,AMOUNTS,START,END,DFORMAT,TFORMAT,SKIPBLANK,TUNEHOUR,
LAMBDA(DATES,AMOUNTS,DTFORMAT,START,END,
LAMBDA(DATES,TIMES,
LAMBDA(VALIDDATES,AMOUNTS,
TEXT(SUM(FILTER(AMOUNTS,VALIDDATES>=START,VALIDDATES<=END)),"$#,##0.00")
)(TEXT((DATES&" "&TIMES)+TUNEHOUR/24,DTFORMAT),IF(ISNUMBER(AMOUNTS),AMOUNTS,VALUE(REGEXEXTRACT(AMOUNTS,"^\$(.+)"))))
)(TEXT(INDEX(DATES,,1),DFORMAT),REGEXREPLACE(INDEX(DATES,,2),"Z",""))
)(SPLIT(QUERY({DATES},SKIPBLANK),"T"),QUERY({AMOUNTS},SKIPBLANK),DFORMAT&" "&TFORMAT,TEXT(START,DFORMAT)&" 00:00:00",TEXT(END,DFORMAT)&" 23:59:59")
)($B$5:$B,$C$5:$C,$B$1,$B$2,"yyyy-mm-dd","hh:mm:ss","WHERE Col1 IS NOT NULL",-6)
)
Where you enter a start date and an end date at B1 & B2 to sum up the amount with.
The provided date column will be deducted by 6 hours.
What this formula does is...
format the date column into a valid date,
compare dates from step 1 with a given start and end date as filter condition,
filter the given amount column with conditions from step 2,
sum the result of filter from step 3 as an array,
format the output as price.
Use regexreplace() and query(), like this:
=arrayformula(
query(
{
weeknum(
regexreplace(B2:B, "([-\d]+)T(\d\d:\d\d).+", "$1 $2")
-
"6:00"
),
C2:C
},
"select Col1, avg(Col2)
where Col1 is not null
group by Col1
label Col1 'week #' ",
0
)
)
I think you're trying to split the values and sum them. I can't understand fully what's the purpose of 19 in LEFT function, and why are you again splitting it? Maybe some approach similar to yours is use LEFT function with 10 characters for the date, and MID from 12th character to get the time. Then substract .25 for the 6 hours as you did, and ROUNDDOWN with 0 digits to get the only the day
=ARRAYFORMULA(ROUNDDOWN(LEFT('Sheet1'!B:B,10)+MID('Sheet1'!B:B,12,8)-0.25,0))
And then you can insert it in your SUMIF:
=SUMIF(Sheet1!C:C,ARRAYFORMULA(ROUNDDOWN(LEFT(Sheet1!B:B,10)+MID(Sheet1!B:B,12,8)-0.25,0)),A1)

Using ARRAYFORMULA with SUMIF for multiple conditions combined with conditions using a wildcard. Result by Months

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:
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
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)))
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:
Here the solution when ALL token is not used:
Note: The only difference with expected result and #player0 solution is that it returns 0when there is no match.

Google sheets - List of dates between a list of start and end dates

I want to list all the dates between a list of start and end dates. I have used sequence formula for each row of dates but I am looking for one single formula to work irrespective of any number of rows I have. Any help is highly appreciated
While there is already an answer for this, if the same date is repeated in multiple columns, that won't be reflected in the resulting list. Therefore, if you want the dates included in multiple intervals to be repeated, here is an alternative:
=ARRAYFORMULA(QUERY(FLATTEN(IF(DAYS(B2:B4,A2:A4)>=SEQUENCE(1,1000,0),A2:A4+SEQUENCE(1,1000,0),"")),"where Col1 is not null"))
Use DAYS, SEQUENCE and IF to get a list of all the dates in between the intervals.
Use FLATTEN to put all values in a single column.
Use QUERY to remove the null values.
I entered this formula in cell E2
=sort(query(sequence(max(A2:B)-min(A2:B)+1,1,min(A2:B)),
"where "&join(" or ","(Col1>="&filter(A2:A,A2:A<>"")&"
and Col1<="&filter(B2:B,B2:B<>"")&")")&
" format Col1 'dd.mmm.yyyy'"))
First, we list all the dates from the lowest one to the greatest one in the range A2:B, then we use query to remove all those who aren't between the specified intervals.
try:
=ARRAYFORMULA(QUERY(FLATTEN(IF(DAYS(B2:B, A2:A)>=SEQUENCE(1, 10000, 0),
A2:A+SEQUENCE(1, 10000, 0), )), "where Col1>0 format Col1'dd.mmm.yyyy'"))

google sheets, Make letters separated by comma given number of following columns. Not using app script, just formulas please

I'm using the query function in google sheets... I want to select columns F to AB.
I need a cell that has the output F,G,H,I... ,AB so I can put it in the Select statement.
This formula should have 2 inputs, the starting letter (F in this case) and number of following columns (22 in this case)
No app script code please. I know someone can do it with just formulas in one cell.
I believe your goal as follows.
You want to create the value of F,G,H,I... ,AB by giving the start column letter of "F" and the number of columns of 22.
For example, when the start column letter of "F" and the number of columns of 22 are given, you want to retrieve the value of F,G,H,I... ,AB and you want to use this like =QUERY(A1:AB,"SELECT F,G,H,I... ,AB").
You want to achieve this using the built-in functions of Google Spreadsheet without the Google Apps Script.
For this, how about this answer?
Sample formula 1:
In this sample formula, in order to create the value of F,G,H,I... ,AB by giving the start column letter of "F" and the number of columns of 22, I would like to propose the following formula.
=TEXTJOIN(",",TRUE,ARRAYFORMULA(REGEXREPLACE(ADDRESS(1,COLUMN(INDIRECT(A1&"1:"&ADDRESS(1,B1+COLUMN(INDIRECT(A1&"1")),4))),4),"\d+","")))
When A1 and B1 have the values of F and 22, respectively, the flow of this formula is as follows.
Using COLUMN, retrieve the column numbers.
Using ADDRESS, retrieve the column letters from the column numbers. At that time, the row number os removed using REGEXREPLACE.
Above formulas are used with ARRAYFORMULA.
Using TEXTJOIN, join the column letters with ,.
Result:
Sample formula 2:
In this sample formula, =QUERY(A1:AB,"SELECT F,G,H,I... ,AB") is created using above sample formula 1.
=QUERY(A1:AB,"SELECT "&TEXTJOIN(",",TRUE,ARRAYFORMULA(REGEXREPLACE(ADDRESS(1, COLUMN(INDIRECT(A1&"1:"&ADDRESS(1, B1 + COLUMN(INDIRECT(A1&"1")), 4))), 4),"\d+",""))))
Result:
In this sample result, the range of A2:AB7 is used for QUERY. So please be careful this. When the cells "A1" and "B1" are changed, the result of this formula is also changed.
Note:
In this case, when the start column and the number of columns are more than the existing maximum columns, an error occurs, please be careful this.
References:
COLUMN
ADDRESS
REGEXREPLACE
ARRAYFORMULA
TEXTJOIN
Added:
When you want to create Col6, Col7, Col8 ... Col28 by giving the start column letter of "F" and the number of columns of 22, how about the following sample formula?
Sample formula:
="Col"&TEXTJOIN(",Col",TRUE,ARRAYFORMULA(COLUMN(INDIRECT(A1&"1:"&ADDRESS(1,B1+COLUMN(INDIRECT(A1&"1")),4)))))
In this case, please put F and 22 to the cells "A1" and "B1", respectively.
if your range is F:AB then you can skip select parameter or use:
=QUERY(F1:AB; "select *"; 0)
if the range is larger put the range in curly brackets and try:
=ARRAYFORMULA(QUERY({A1:AB}; "select "&TEXTJOIN(","; 1; "Col"&COLUMN(F:AB)); 0))

Calculate weekly sum in spreadsheet using array formula

I'm trying to calculate weekly sums in a single column, but I'm having trouble writing the formula. I'm found the the weeknum for every date in the year, but I can't find a way to sum up values if they have the same weeknum.
Link to my spreadsheet: https://docs.google.com/spreadsheets/d/1WIeBpRndO9ZBlkCcWQuNO1X4e9I6bGeQiYDTZqhaOeA/edit#gid=0
I'd like column "D" to automatically calculate the weekly sum using an array formula -- is there a way to do this?
This thread introduces the problem: Calculate weekly and monthly total in spreadsheet.
Chang sum() to sumif()
=ARRAYFORMULA(IF(ROW(A:A)=1,"Weekly Sum", IF(WEEKDAY(A:A)=7, sumif(C:C,C:C,B:B),)))
You have: A2:A with dates and B2:B with values. So:
F2=arrayformula(if(isblank(A2:A),,weeknum(A2:A)))
G2=if(F2<>F1,sum(iferror(filter(B$2:B,F$2:F=F2),0)),0)
And then copy G2 through G3:G.

Resources