Sum of a range of cells that may contain + sign - google-sheets

I have a google sheet table with the cells A1, B1 and C1 containing
either an integer, e.g., 12 or an expression <integer> + <integer>, e.g., 12 + 1 or 12+1.
I want to compute the sum of the cells in D1. Situation
|A1| B1 | C1|
--------------
|1 | 1+1 | 3 |
should result in 6. Simply saying D1 = SUM(A1:C1) does not work:
it ignores the cell B1.
I have found two partial solutions that I cannot combine:
SUM(SPLIT(B1;"+")) results in 2
if I had A2: 1, B2: 4 and C2: 9, then ArrayFormula(SUM(SQRT(A2:C2))) results in 6 (sum of square roots of these cells).
(e.g., ArrayFormula(SUM(SUM(SPLIT(A1:C1;"+")))) does not work properly)
How can I solve this problem? Two-step solution i) compute SUM(SPLIT(<cell>;"+")) in a new cell, and ii) compute the sum, is not an option.

Try this:
=SUM(SPLIT(JOIN("+",A1:C1),"+"))
In this solution you just need to join them first.
BTW this formula works too:
=SUM(SPLIT(JOIN("+",A1:C1),"+:)"))

Related

Sheets ArrayFormula. Find nearest number by group

Master Data
Group-Value pairs
1 | 1
1 | 2
1 | 3
2 | 5
2 | 8
3 | 10
3 | 12
Work Data
Group-Value pairs + desired result
1 | 4 | 3 (3≤4, max in group 1)
1 | 2 | 2 (2≤2, max in group 1)
2 | 6 | 5 (5≤6, max in group 2)
3 | 7 | no result (both 10 and 12 > than 7)
The task is to find the maximum possible matched number from a group, the number should be less or equal to the given number.
For Group 1, value 4:
=> filter Master Data (1,2,3) => find 3
Will have no problem with doing it once, need to do it with arrayformula.
My attempts to solve it were using modifications of the vlookup formula, with wrong outputs so far.
Samples and my working "arena":
https://docs.google.com/spreadsheets/d/11Cd2BGpGN-0h2bL0LQ_EpIDBKKT2hvTVHoxGC6i8uTE/edit?usp=sharing
Notes: no need to solve it in a single formula, because it may slow down the result.
I used
=ArrayFormula(VLOOKUP(D4:D8&text(E4:E8,"0000"),A4:A10&text(B4:B10,"0000"),1,true))
starting in J4
then
=ArrayFormula(if(--left(J4:J8)=D4:D8,--right(J4:J8,4),""))
starting in K4.
Needs further refinement but doesn't make any assumptions about max of previous group.
EDIT
So after further work it would look like this
=ArrayFormula(if(D4:D="",,
if(D4:D=
vlookup(D4:D&text(E4:E,"0000"),filter({A4:A&text(B4:B,"0000"),A4:A},A4:A<>""),2,true),
vlookup(D4:D&text(E4:E,"0000"),filter({A4:A&text(B4:B,"0000"),B4:B},A4:A<>""),2,true),"")))
A lot like #player0's solution in fact.
I guess you could make it a bit more general by doing something like
=text(B4,rept("0",ceiling(log10(max(B4:B)))))
assuming these are positive integers.
Alternative method
I think this is a better way. Find the start row of each group and how many rows r less than or equal to the required group/value pair are in that group. Then just go forward r-1 rows from the first line of the group to find the matching value:
=ArrayFormula(if(countifs(A4:A,D4:D,B4:B,"<="&E4:E)>0,
vlookup(
vlookup(D4:D,{A4:A,row(A4:A)},2,false)+countifs(A4:A,D4:D,B4:B,"<="&E4:E)-1,{row(A4:A),B4:B},2,false),))
Assuming of course that the Master data is sorted by group and value - otherwise you would have to use sort():
=ArrayFormula(if(countifs(A4:A,D4:D,B4:B,"<="&E4:E)>0,
vlookup(
vlookup(D4:D,{sort(A4:A,A4:A,1,B4:B,1),row(A4:A)},2,false)+countifs(A4:A,D4:D,B4:B,"<="&E4:E)-1,{row(A4:A),SORT(B4:B,A4:A,1,B4:B,1)},2,false),))
My solution was based on the technique of finding the maximum number by a row. The sample formula is here:
https://docs.google.com/spreadsheets/d/1VY157ykKsCVDqEKDBp3oAVaG0LTXAz8wUCggCrFXMDM/edit#gid=628408999
My whole solution is here:
https://docs.google.com/spreadsheets/d/11Cd2BGpGN-0h2bL0LQ_EpIDBKKT2hvTVHoxGC6i8uTE/edit#gid=0
Step 1
Get joined numbers by groups from a Master Table.
1 | 3,2,1
2 | 8,5
3 | 12,10
Used offset to achieve this ↑. And used vlookup to match this semi-result with work table.
Step 2
Used if + split to check if the resulted value was ≤ than my work value, and in the same formula used query to find the maximum by each row.
compose a query: used join + sequence
=IF(M3=0,,"select "&JOIN(", ",INDEX("max(Col"&SEQUENCE(M3)&")")))
result:
select max(Col1), max(Col2), max(Col3), max(Col4), max(Col5)
Found the maximum by each group:
=index(TRANSPOSE(QUERY(TRANSPOSE(data), "select ...")))
This final formula was the 🔑 to solving the problem.
Note: the result: 0 of my formula means "no matches". This is fine for me.
try:
=INDEX(IFNA(IF(E4:E>=
VLOOKUP(D4:D&TEXT(E4:E, "00000"), {A4:A&TEXT(FILTER(B4:B, B4:B<>""), "00000"), B4:B}, 2),
VLOOKUP(D4:D&TEXT(E4:E, "00000"), {A4:A&TEXT(FILTER(B4:B, B4:B<>""), "00000"), B4:B}, 2), 0)))

How to Compare 2 Columns of Numbers in One Function for an Average

I'm trying to take a column of numbers, parse them in some way, divide them by another column of numbers in the same row, and return the average of each quotient. For example:
| A | B |
|:-:|:-:|
| 6 |210|
| 8 |225|
| 12|240|
I would like to divide A2 by B2, A3 by B3, etc., and then take the average of every quotient and return it (without manually typing in each division). Is there a simple or effective solution to fix this? Very new to Sheets, so over-simplified explanations/answers are highly appreciated :)
You can use Sumproduct to return a single result with the following formula:
=SUMPRODUCT(B1:B3/A1:A3)/COUNTA(B1:B3)

How to apply MID function to range or column in Google Sheets

I have a google sheet document. In there I have a column of text. I want to fill another column with substrings from each value from the first column, like this:
A | B
a.123 | 123
b.456 | 456
c.789 | 789
If a value is added to column A I want it to automatically appear in column B.
I tried (to no avail):
=ARRAYFORMULA(MID(A2:A, 3, 3))
=MID(ARRAYFORMULA({A2:A}), 3, 3)
=MID({A2:A}, 3, 3)
Which formula in the B2 cell will solve this? Or is it impossible to do from a single cell?
try like this:
=ARRAYFORMULA(MID(A1:A; 3; 3))
and this shall work too:
=ARRAYFORMULA(IFERROR(REGEXEXTRACT(A1:A; ".(\d+)")))
or even:
=ARRAYFORMULA(RIGHT(A1:A; 3))

Query to View only top counts and counted by group

I wanted to use this query
=query(G2:I80,"select G,H,I where H=max(H) group by I",-1)
From this:
Cdd Cts T
NWH 4 A1
LBB 3 A1
MP 3 A1
DC 2 A1
AK 10 A10
CC 3 A10
SC 2 A11
JL 1 A11
VT 1 A11
To This:
T Cdd Cts
A1 NWH 4
A10 AK 10
A11 SC 2
Am I doing it right? Or I have to come up with something to manually count them?
Try
=ArrayFormula(iferror(vlookup(unique(I2:I), sort({I2:I, G2:H},3,), {1,2,3},0)))
and see if that works for you ?
How does it work:
1: with sort() a new 'virtual' table is created with col I as the first column. That new table is sorted on col H (latest dates appear on top).
2: a list with the unique values is retrieved from col I (with the unique function)
3: that list is 'looked up' (with vlookup). When a match is found it retrieves the first 3 columns ({1, 2, 3} or: col I, G and H). Vlookup only returns the first match found: since our list is sorted, that will be the entry with the latest date.
4: if nothing is found an error is suppressed with the iferror().

Is there a multiple-and-add formula in Google's spreadsheet?

What I want is to easily multiply a number by another number for each column and add them up at the end in Google Sheets. For example:
User | Points 1 | Points 2 | Points 3 | Total
| 5 | 1 | 4 |
-----+----------+----------+----------+------
Jane | 2 | 3 | 0 | 13 (2*5 + 3*1 + 0*4)
John | 1 | 11 | 4 | 32 (1*5 + 11*1 + 4*4)
So it's easy enough to make this formula for the total:
= B3*$B$2 + C3*$C$2 + D3*$D$2
The problem is I frequently need to insert additional columns or even remove some columns. So then I have to mess with all the formulas. It's a pain... we have many spreadsheets with these formulas. I wish there was a formula like SUM(B3:D3) where I could just specify a range. Is there anything like MULTIPLY_AND_SUM(B2:D2, B3:D3) that would do this? Then I could insert columns in the middle and the range would still work.
There is a built in function in Google Sheets that does exactly what you are looking for: SUMPRODUCT.
In your example the formula would be:
=sumproduct(B$2:D$2,B3:D3)
Click here for more information about this function.
You can accomplish that without requiring a special-purpose function.
In E3, try this (and copy it to the rest of your rows):
=sum(arrayformula(B3:D3*B$2:D$2))
You can read about arrayformula here.
As long as you introduce new columns between B and D, this formula will automatically adjust. If you add new columns outside of that range, you'll need to edit (and cut & paste).
On it's own, arrayformula(B3:D3*B$2:D$2) operates over each value in B3:D3 in turn, multiplying it by the corresponding value in B$2:D$2. (Note the use of absolute references to 'lock down' to row 2.) The result in this case is three values, [10,3,0], arranged horizontally in three rows because that matches the dimensions of the ranges.
The enveloping sum() function adds up the values of the array produced by arrayformula, which is 13 in this case.
As you copy that formula to other rows, the relative range references get updated for the new row.

Resources