Sum multiple 2-way lookup values in one equation - google-sheets

I've conquered a 2-way lookup for one Y axis and one X axis value using
=SUMPRODUCT((Y_AXIS_VALUE_ARRAY = Y_LOOKUP_VALUE)*(X_AXIS_VALUE_ARRAY = X_LOOKUP_VALUE), LOOKUP_ARRAY)
However what if I had multiple Y_LOOKUP values and multiple X_LOOKUP values and wanted to sum the results of all of them in one equation is this possible.
The example below shows what I'm after in this example the formula should return 105.78 (80.45 + 25.33).
The formula mentioned above when used to where X/Y Lookup values are an array of values returns Error
Array arguments to MULTIPLY are of different size.
Here is my test google sheet: https://docs.google.com/a/rentping.com/spreadsheets/d/1GWQHAclo19f1VxLBixI4eyKJDN1QRk6SzXKJDWj6ZaE/edit?usp=sharing
The "Test" sheet contains the interface where X/Y Look up values are selected, and the "Items" sheet contains the table that is being referenced.
Columns L, M, N, O are where the selection is made and Column K is where the formula goes. As you can see when only ONE column has a selection the formula accurately gets the value, but as soon as a second value is selected in the those columns the formula breaks down.

An easier way to perform double lookup is to use filter twice: for rows and for columns. The wrapper iferror suppresses output when nothing is found.
=iferror(filter(filter(Items!A:Z, Items!A:A = L2), Items!A1:Z1 = L3))
With 4 columns to choose from, I'd go with
=iferror(filter(filter(Items!A:Z, Items!A:A = L2), Items!A1:Z1 = L3))
+iferror(filter(filter(Items!A:Z, Items!A:A = M2), Items!A1:Z1 = M3))
+iferror(filter(filter(Items!A:Z, Items!A:A = N2), Items!A1:Z1 = N3))
+iferror(filter(filter(Items!A:Z, Items!A:A = O2), Items!A1:Z1 = O3))
Alternatively, have additional hidden columns with lookups (one hidden column for each input column), and then column K can be a simple sum over hidden columns.

Related

Query function with multiple criteria

So I have a spreadsheet and I want to search for two criteria in two different columns. When i entre my equations it returns no data except the column headings.
=QUERY(MukuluFarmsMasterData,"select A,B,N,O,P,Q,R,S,T,U,V where B = 'SERVICING' and F = 1")
So I want the table to return all the information that satisfy both conditions. So in column B I want everything that is Servicing and From column F = 1. I would also like to sort the date in Descending order.
This is a screenshot of the spreadsheet.
enter image description here

Find Last Non-zero (+Non-blank) Row Meeting Criteria in Google Sheets

I am trying to get the last non-zero, non-blank value of a row within a column (Column F in my example image) wherein that row ALSO matches a Campaign name (Column D).
Most search results yield an Excel-specific variation of =LOOKUP(1,1/(L:L>0),L:L), but this doesn't work in Google Sheets.
I am trying to solve for Cell F23 = 2374.
I found and modified a formula which returns the last non-zero, non-blank value within a column reliably, but I don't know where to mix the additional filter (basically, D$2:D22 = D23) into the INDEX function.
Here is what I'm working with:
=if(
{{separate_formula_that_fetches_value_from_other_sheet}})=0,
INDEX((FILTER(D$2:F22,NOT(ISBLANK(D$2:F22)))), (ROWS(FILTER(D$2:F22,NOT(ISBLANK(D$2:F22))))),3)
)
Here is the example table:
Thank you for any help!
If you are trying to find inside RANGE B2:F22 which...
value in Column F is not empty and greater than 0, and
value in Column D matches D23,
try this, didn't test it, but it should work I think:
=LAMBDA(FILTER,
INDEX(FILTER,COUNTA(FILTER))
)(FILTER($F$2:$F$22,$F$2:$F$22>0,$D$2:$D$22=$D23))

How to print different values to column based on value in another column and other conditions met?

I have a spreadsheet with several columns and I want to return a different value based on the value in Column A and if any of the other columns show a true or 1.
For example
If column A has the value "A" and any column B-N is either TRUE or 1 then I want to return "Good" to column O
If column A has the value "B" and any column B-N is either TRUE or 1 then I want to return "Best" to column O
Link to spreadsheet: https://docs.google.com/spreadsheets/d/12k9usKsOgrOUhtW5WBvfY7WB5hbfnTMSPgXtrqcRFjM/edit?usp=sharing
Try this in cell O2 (where your sample sheets only has values of TRUE, FALSE, Y or N in B2:N):
=arrayformula((trim(transpose(query(transpose(iferror(regexreplace(regexreplace(text(B2:N,),"(FALSE)|(N)",),"(Y)|(TRUE)",if(A2:A="A","Good",if(A2:A="B","Best",))),)),,columns(B2:N))))))
Alternative where values in B:N are either 0 or 1:
=arrayformula((trim(transpose(query(transpose(iferror(substitute(substitute(B2:N,0,),1,ifs(A2:A="A","Good",A2:A="B","Best")),)),,columns(B2:N))))))
B2:N is the range of cells to process.
The inner SUBSTITUTE clears all 0 values.
The outer SUBSTITUTE swaps 1 values for a test to see if values in A contain "A" or "B".
IFS does the test and returns either "Good" or "Best".
IFERROR hides any #N/A values down the sheet where the rows are empty.
TRANSPOSE transposes the data for QUERY.
QUERY is used to collapse empty cells (vertically). columns(B2:N) is used in the header part of QUERY. This is a quirk of QUERY, where the header number >= the columns of data, QUERY does the collapse.
TRANSPOSE reverts the dataset to the previous orientation.
TRIM removes leading or trailing space.
ARRAYFORMULA allows the formula to automatically cascade down the sheet, rather than you needing to drag the formula down (like with =IF(AND({B2:N2}>0, A2="A"),"Good", "")).
So, you already have this partial solution. To get a second condition to be met before printing something to your cell, just add an AND() with a new COUNTIF(), comparing A column with A, and then at the else argument, repeat your original IF(), just changing A for B and the output for each case. I will look like this:
=IF(AND(countif(A2;"A");OR(countif(A2:N2;"Y");countif(A2:N2;TRUE)));"Good";
IF(AND(countif(A2;"B");OR(countif(A2:N2;"Y");countif(A2:N2;TRUE)));"Best";"BAD"))
To use it on every row, just autofill the column O. The row numbers will change accordingly and work on its own.
If you need a new if() statement for a third or fourth case, just repeat it, nesting one IF() inside the other, leaving room for a default error message at the end.

Can change shape of range with ARRAYFORMULA() in Google Sheets?

My intention is to convert a single line of data into rows consist of a specific number of columns in Google Sheets.
For example, starting with the raw data:
A
B
C
D
E
F
1
id1
attr1-1
attr2-1
id2
attr2-1
attr2-2
And the expected result is:
(by dividing columns by three)
A
B
C
1
id1
attr1-1
attr1-2
2
id2
attr2-1
attr2-2
I already know that it's possible a bit manually, like:
=ARRAYFORMULA({A1:C1;D1:F1})
But I have to start over with it every time the target range is moved OR the subset size needs to be changed (in the case above it was three)!
So I guess there will be a much more graceful way (i.e. formula does not require manual update) to do the same thing and suspect ARRAYFORMULA() is the key.
Any help will be appreciated!
I added a new sheet ("Erik Help") where I reduced your manually entered parameters from two to one (leaving only # of columns to be entered in A2).
The formula that reshapes the grid:
=ArrayFormula(IFERROR(VLOOKUP(SEQUENCE(ROUNDUP(COUNTA(7:7)/A2),A2),{SEQUENCE(COUNTA(7:7),1),FLATTEN(FILTER(7:7,7:7<>""))},2,FALSE)))
SEQUENCE is used to shape the grid according to whatever is entered in A2. Rows would be the count of items in Row 7 divided by the number in A2 (rounded to the nearest whole number); and the columns would just be whatever number is entered in A2.
Example: If there are 11 items in Row 7 and you want 4 columns, ROUNDUP(11/4)=3 rows to the SEQUENCE and your requested 4 columns.
Then, each of those numbers in the grid is VLOOKUP'ed in a virtual array consisting of a vertical SEQUENCE of ordered numbers matching the number of data pieces in Row 7 (in Column 1) and a FLATTENed (vertical) version of the Row-7 data pieces themselves (in Column 2). Matches are filled into the original SEQUENCE grid, while non-matches are left blank by IFERROR
Though it's a bit messy, managed to get it done thanks to SEQUENCE() function anyway.
It constructs a grid by accepting number of rows/columns input, and that was exactly I was looking for.
For reference set up a sheet with the sample data here:
https://docs.google.com/spreadsheets/d/1p972tYlsPvC6nM39qLNjYRZZWGZYsUnGaA7kXyfJ8F4/edit#gid=0
Use a custom formula
Although you already solved this. If you are doing this kind of thing a lot, it could be beneficial to look into Apps Script and custom formulas.
In this case you could use something like:
function transposeSingleRow(range, size) {
// initialize new range
let newRange = []
// initialize counter to keep track
let count = 0;
// start while loop to go through row (range[0])
while (count < range[0].length){
// add a slice of the original range to the new range
newRange.push(
range[0].slice(count, count + size)
);
// increment counter
count += size;
}
return newRange;
}
Which works like this:
The nice thing about the formula here is that you select the range, and then you put in a number to represent its throw, or how many elements make up a complete row. So if instead of 3 attributes you had 4, instead of calling:
=transposeSingleRow(A7:L7, 3)
you could do:
=transposeSingleRow(A7:L7, 4)
Additionally, if you want this conversion to be permanent and not dependent on formula recalculation. Making it in run fully in Apps Script without using formulas would be neccesary.
Reference
Apps Script
Custom Functions

Create a table based on a ledger

Give a ledger-like set of data with 3 columns:
Name,Type,Amount
Foo,A,-100
Bar,A,-200
Baz,A,-500
Foo,B1,200
Foo,A,-100
Bar,A,-300
Baz,B2,2000
Bar,A,-300
If I want to make a table that has these headers:
Name,X,Y,Z
where Name is a distinct list of Name in the first table,
where X is sum of the values from the first table where Names match, Type is A, and Value is negative
where Y is the sum of values from the first table where Names match, Type starts with B, and Value is positive
where Z is Y / X
How might I do this?
Right now I have this implemented as 2 different queries for X and Y, but they repeat the Name column, and it's not combine-able into Z because those two queries don't return the same set of Names since some Names don't have any values that match the query for both X and Y.
Here's a concrete example in a sheet I made:
https://docs.google.com/spreadsheets/d/1qbwLqRncgo8pQNU4oAeYfEHr5o4L8EGB-Skhu869fGE/edit?usp=sharing
This might work for you.
I added a tab to your sheet, Sheet1-GK. In it, I first calculate the amounts that are either distributed, or invested, for each row of your data - see formulas in cells D1 and E1. Then I use the following query, in G8, to produce the result that you were asking for.
=query(A1:E12,"select A, sum(D), sum(E), sum(E)/sum(D) group by A label sum(D) ' Invested', sum(E) 'Distributed', sum(E)/sum(D) 'MoM'",1)
The only issue is having the MoM value return as negative. This could be handled with another column, if necessary, to force the absolute value. I'm not sure if there is any way to incorporate that in the query statement.
Let me know if this is useful, or if you need something different.

Resources