Google Docs - SUMIF - SUM range if single cell contains a string - google-sheets

I'd like to quickly include or exclude an entire range of values in a SUM.
Presently I'm SUMing select cells for a grand total: [E19] =SUM(E13,E20,E30,E45,E55,E70,E80)
These are in turn SUMs of selected ranges:
... [E30] =SUM(E31:E44), [E55] =SUM(E56:E69), ...etc.
One of these ranges I would like to toggle it's inclusion in the Grand Total.
It seemed the best way to do it was this:
[E45] =SUMIF(D45,"☑",E46:E54)
In short, in cell E45 I'd like to SUM E46 to E54 only if D45 contains a ☑.
However Google Doc's SUMIF seems to only work with matched ranges: =SUMIF(D46:D54,"☑",E46:E54)
Is there a way to SUM a range only if a specific value exists in a single cell?

You're right about SUMIF, it allows you to sum values from a range, which meet a certain criteria (on another range of the same length). For example, if you had two columns called "status" and "price", you could use it to sum all the prices for a given status.
What you're trying to do can be done, instead, with the use of the IF function:
=IF(D45="☑";SUM(E46:E54);0)
If the condition specified in the first argument is true, it will return the second argument, that is, the sum. Otherwise, it will return the third argument, 0.

After working through the logic to share the issue I wound up identifying a solution. Rather than trying to force SUMIF to check a single cell against a range. I just nested the 1:1 SUMIF inside my 'Grand SUM': =SUM(E13,E20,E30,SUMIF(D45,"☑",E45),E55,E70,E80).

Related

Google sheets percentage of values where the difference between two columns in another sheet, is less than the value in a third column of the sheet

I'm on google sheets trying to find the percentage of values where the difference between two columns in another sheet, is less than the value in a third column of the sheet. I've tried a bunch of things but all come up with err0rs or parse error. Any help is appreciated.
This is what I came up with.
=COUNTIF((sum(Data!($E$2:$E$229):Data!($F$2:$F$229)),"<Data!$C$2:$C$229"))/count(Data!$C$2:$C$229)
then I make it a percentage value
Thanks for your help!
If possible, the simplest strategy would probably be something like this:
In the sheet with the two columns, calculate another column that is the difference of the first two. E.g.:
=A1-B1.
Then, write an if statement that checks whether that difference is less than the value in the third column. If it is, return 1, if it isn't return 0. E.g.:
=IF(C1<D1, 1, 0)
Finally, calculate the percentage of values that are less with a formula like this:
=SUM(if_column) / COUNTA(if_column) * 100
SUM returns the count of all cells whose difference is less than the third column and COUNTA returns the total number of non-blank cells.

Is there a way to specify an input is a single cell in Google Sheets?

I want to iterate over an array of cells, in this case B5:B32, and keep the values that are equal to some reference text in a new array.
However, SPLIT nowadays accepts arrays as inputs. That means that if I use the array notation of "B5:B32" within ARRAYFORMULA or FILTER, it treats it as a range, rather than the array over which we iterate one cell at a time.
Is there a way to ensure that a particular range is the range over which we iterate, rather than the range given at once as an input?
What I considered was using alternative formulations of a cell, using INDEX(ROW(B5), COLUMN(B5)) but ROW and COLUMN also accept array values, so I'm out of ideas on how to proceed.
Example code:
ARRAYFORMULA(
INDEX(
SPLIT(B5:B32, " ", 1), 1
) = "Some text here"
)
Example sheet:
https://docs.google.com/spreadsheets/d/1H8vQqD5DFxIS-d_nBxpuwoRH34WfKIYGP9xKKLvCFkA/edit?usp=sharing
Note: In the example sheet, I can get to my desired answer if I create separate columns containing the results of the SPLIT formula. This way, I first do the desired SPLITS, and then take the values I need from that output by specifying the correct range.
Is there a way to do this without first creating an output and then taking a cell range as an input to FILTER or other similar functions?
For example in cell C35 I've already gotten the desired SPLIT and FILTER done in one go, but I'd still need to find a way to sum up the values of the first character of the second column. Doing this requires that I take the LEFT value of the second column, but for that I need to output the results and continue in a new cell. Is there a way to avoid this?
Ralph, I'm not sure if your sample sheet really reflects what you are trying to end up with, since, for example, I assume you are likely to want the total of the hours per area.
In any case, this formula extracts all of the areas, and the hours worked, and is then easy to do further calculations with.
=ArrayFormula({REGEXEXTRACT({C5:C9;D5:D9;E5:E9;F5:F9;G5:G9;H5:H9},"(.*) \d"),
VALUE(REGEXEXTRACT({C5:C9;D5:D9;E5:E9;F5:F9;G5:G9;H5:H9}," (\d+)hrs"))})
Try that in cell E13, to see the output.
The first REGEXEXTRACT pulls out all the text in front of the first space and number, and the second pulls out all the digits in a string of " #hr" in each cell. These criteria could be modified, if necessary, depending on your actual requirements. Note that it requires the use of VALUE, to convert the hours from text to numeric values, since REGEXEXTRACT produces text (string) results.
It involved concatenating your multiple data columns into one long column of data, to make it simpler to process all the cells in the same way.
This next formula will give you a sum, for whatever matching room/task you type into B6, as an example.
=ArrayFormula(QUERY({REGEXEXTRACT({C5:C9;D5:D9;E5:E9;F5:F9;G5:G9;H5:H9},"(.*) \d"),
VALUE(REGEXEXTRACT({C5:C9;D5:D9;E5:E9;F5:F9;G5:G9;H5:H9}," (\d+)hrs"))},
"select Col1, sum(Col2) where Col1='"&B6&"' group by Col1 label sum(Col2) '' ",0))
I will also answer my own question given what I know from kirkg13's answer and other sources.
Short answer: no, there isn't. If you want to do really convoluted computations with particular cell values, there are a few options and tips:
Script your own functions. You can expand INDEX to accept array inputs and thereby you can select any set of values from an array without outputting it first. Example that doesn't use REGEXMATCH and QUERY to get the SUM of hours in the question's example data set: https://docs.google.com/spreadsheets/d/1NljC-pK_Y4iYwNCWgum8B4NJioyNJKYZ86BsUX6R27Y/edit?usp=sharing.
Use QUERY. This makes your formula more convoluted quite quickly, but is still a readable and universally applicable method of selecting data, for example particular columns. In the question's initial example, QUERY can retrieve only the second column just like an adapted INDEX function would.
Format your input data more effectively. The more easily you can get numbers from your input, the less you have to obfuscate your code with REGEXMATCHES and QUERY's to do computations. Doing a SUM over a RANGE is a lot more compact of a formula than doing a VALUE of a LEFT of a QUERY of an ARRAYFORMULA of a SPLIT of a FILTER. Of course, this will depend on where you get your inputs from and if you have any say in this.
Also, depending on how many queries you will run on a given data set, it may actually be desirable to split up the formula into separate parts and output partial results to keep the code from becoming an amalgamation of 12 different queries and formulas. If the results don't need to be viewed by people, you can always choose to hide specific columns and rows.

How to use AVERAGEIFS within ARRAYFORMULA

I am trying to use AVERAGEIFS inside ARRAYFORMULA. Looking at other questions, I have come to the conclusion that it is not possible without using QUERY function.
My intention is to average the values of a column whenever they share the same ID.
I think this question comes pretty close to what I need, but I haven't been able to replicate and adapt its solution on my own sheet.
In this sheet I show the result I expect (I got it by dragging the formula). I've also reviewed the Query Language Reference, unsuccessfully.
Thanks a lot for your time and effort.
So the formula should be
=ArrayFormula(iferror(sumif(A2:A,A2:A,B2:B)/countif(A2:A,A2:A)))
Note that if there were any text values in the points column, this would still return a result (because count would be greater than zero) - you could instead use
=ArrayFormula(if(isnumber(B2:B),(sumif(A2:A,A2:A,B2:B)/countif(A2:A,A2:A)),""))
If you had a mixture of rows with text and rows with numbers for any ID, this would return a smaller result than the avg or average formula. This is a limitation of this method. You can't put an extra condition in (that column B has to contain a number) because you would need countifs and countifs isn't array-friendly. It still seems strange that AFAIK countif and sumif are the only functions out of this family that are array-friendly while countifs, sumifs, averageif etc. are not.
you can do:
=ARRAYFORMULA(IFERROR(VLOOKUP(A2:A; QUERY(A2:B; "select A,avg(B) group by A"); 2; )))

Google-Sheets Conditional Formatting based on multiple conditions

I am trying to format a cell based on multiple conditions. I am creating a spreadsheet to keep track of items borrowed. Let's say I am lending books. I want to have a list of books, one name in each cell. Then below that I want to have 3 columns: One column to enter the name of the book borrowed, the borrowing date, and the return date. I want to turn the cell with the book name RED, if the book has been borrowed AND if the return date is BLANK, meaning book is out. In my example screenshot, cell A2, and B2 should be red.
The conditional formula I have come up with is =AND($A6=A2, $C6="") for Book1 conditions, but it only works if C6 if empty, not if C8 is empty or other cells in column C where Book1 is found AND the return date is blank. There is no specific deadline to return items, just that if book has been borrowed and the return date in the same row is empty then the book name at the top should turn red.
Compare the result of COUNTA applied to the in and out ranges.
E.g. COUNTA(FILTER($B6:$B,$A6:$A=A2)) will count how many times a specific book is checked out, while COUNTA(FILTER($C6:$C, $A6:$A=A2)) will count how many times it is checked back in
Your question title asks about "multiple conditions", but very specifically you're looking to match based on any row that itself matches multiple conditions. That goes beyond the common AND operator and into a function that can process a range. You also need to be prepared for a book to be checked out and returned many times, which means there's no single row that manages the status of a given book; VLOOKUP and INDEX/MATCH are off the table too. Instead, you're effectively looking to generate a list of 0 or 1 values that match whether that book was checked out without being returned, and then coloring the cell based on whether there are any rows that match that condition.
To operate on multiple values at a time, you can use ARRAYFORMULA and then combine the output array with OR. However, one of the tricks about ARRAYFORMULA is that, to preserve the invariant about making single-value functions into array-valued functions, you can't use functions that can take arrays. This means that AND and ISBLANK don't work the way you'd like them to, but you can resolve that by using * instead of AND and = "" for ISBLANK.
One such solution (working example):
=OR(ARRAYFORMULA((A1 = $A$5:$A) * ($C$5:$C = "")))
ARRAYFORMULA isn't the only function to operate on a list of values, though; you could also use FILTER directly to only return matching rows. Here, you're checking whether any row has a matching book name and a blank return value, and then confirming that the value is not the #N/A that FILTER returns when nothing matches.
One such solution (working example):
=NOT(ISNA(FILTER($A$8:$C, $A$8:$A = A1, $C$8:$C = "")))
Of course, you can also take advantage of the fact that you're only checking blanks to use tehhowch's solution with COUNTA and FILTER above. However, since that solution won't work for arbitrary expressions, you can use ARRAYFORMULA or FILTER if your needs become more complex.

Google Spreadsheet: SUMIF sum single cell iteratively for each met criteria

I am trying to sum a single value (in a single cell) for every cell that mets a certain criterion within a range. Consider the following scenario:
My objective is to sum the reference value 10 every time a cell is equal to V, giving a result of 30, in this case. I thought the formulae SUMIF might fit my requirements, so I tried assigning a single cell (the reference cell) as sum_range (more info here), but It only sums the value the very first time the criterion is met by a cell. So far, my approach looks like the following:
=SUMIF(A1:A7;"=V";A4) // Where A4 is '10'
I am aware that the proper usage of this function is to indicate a sum_range that at least equals the size of the range on which the criterion is looked up. The first logical solution would be to create an additional column next to the analysed range so that:
However, my current project does not allow me doing that, and I would rather prefer keeping the structure as in the first example. I would like to know if there exists any alternative to achieve what I am looking for in the first example.
What about:
=ArrayFormula(sum(if(A1:A7="V"; 10; 0)))

Resources