Related
We have two tables in Google Sheets.
First:
Date
Amount
Currency
Worth
01.01.2021
100
USD
373
02.01.2021
100
EUR
451
03.01.2021
100
PLN
100
04.01.2021
100
USD
373
05.01.2021
100
USD
372
Second:
Date
PLN
EUR
USD
01.01.2021
1
4,50
3,73
02.01.2021
1
4,51
3,75
03.01.2021
1
4,50
3,74
04.01.2021
1
4,48
3,73
05.01.2021
1
4,49
3,72
I tried find array formula for first table, column Worth. Formula should take proper value from second table (based on two columns from table one - Date and Currency) and multiply that values by worth in column Amount. I really want to use array formula. Is it possible?
Use VLOOKUP to find the correct date row and MATCH to find which column the value is in:
=ARRAYFORMULA(IFERROR(VLOOKUP(A2:A,I2:L,MATCH(C2:C,I1:L1,0))*B2:B))
Option 01: Getting the result with one cell one formula.
Paste this in B3 "Amount" column in the first table, take a look at this Sheet.
=ArrayFormula(IF(ArrayFormula(IF(A3:A="",,VLOOKUP(A3:A,G3:J,ArrayFormula(IF(D3:D="",,MATCH(D3:D,$H$2:$J$2,0)+1)),0)))="",,ArrayFormula(IF(A3:A="",,VLOOKUP(A3:A,G3:J,ArrayFormula(IF(D3:D="",,MATCH(D3:D,$H$2:$J$2,0)+1)),0)))*E3:E))
Explanation ...
1 - MATCH(D3:D,$H$2:$J$2,0) To get the index you want to VLOOKUP the "Currency" column from the second table with, we need that in the next step.
2 - VLOOKUP the "date" found in First table A3:A from Range in the second table G3:J, with Index set to MATCH(D3:D,$H$2:$J$2,0), and [is_sorted] set to 0
3 - till now we have the value of the exchange rate if we can call it that for each Currency chosen in the first Table, we need to multiply it by Worth to get Amount
ArrayFormula(IF(A3:A="",,VLOOKUP(A3:A,G3:J,ArrayFormula(IF(D3:D="",,MATCH(D3:D,$H$2:$J$2,0)+1)),0)))*E3:E is structured like this Exchange rate * Amount note that E3:E is the Amount, and this IF(A3:A="",, to calculate only when A3:A range is not blank.
4 - ArrayFormula and a IF is needed to be wrapped around like this ArrayFormula(IF(Range=Empty,Do nothing,formula)
Range:
ArrayFormula(IF(A3:A="",,VLOOKUP(A3:A,G3:J,ArrayFormula(IF(D3:D="",,MATCH(D3:D,$H$2:$J$2,0)+1)),0)))
Empty
""
Do nothing :
,,
Formula:
ArrayFormula(IF(A3:A="",,VLOOKUP(A3:A,G3:J,ArrayFormula(IF(D3:D="",,MATCH(D3:D,$H$2:$J$2,0)+1)),0)))*E3:E
Option 02: Getting the result with intermediate steps.
Same as option 01 but in seprate columns take a look at this Sheet.
With this code
={"Row 1 is row "&ROW();"Row 2 is row "&ROW()}
I get this
Row 1 is row 1
Row 2 is row 1
I assume this is because ROW() returns the row the formula is actually input to. How do I get the correct row number in an array?
EDIT:
What I actually have is this
=ARRAY_CONSTRAIN({
TEXT(DATE(2022,1,1),"MMMM");ARRAYFORMULA(DATE(2022,1,SEQUENCE(DAY(EOMONTH(DATE(2022,1,1),0)))));
TEXT(DATE(2022,2,1),"MMMM");ARRAYFORMULA(DATE(2022,2,SEQUENCE(DAY(EOMONTH(DATE(2022,2,1),0)))));
TEXT(DATE(2022,3,1),"MMMM");ARRAYFORMULA(DATE(2022,3,SEQUENCE(DAY(EOMONTH(DATE(2022,3,1),0)))));
TEXT(DATE(2022,4,1),"MMMM");ARRAYFORMULA(DATE(2022,4,SEQUENCE(DAY(EOMONTH(DATE(2022,4,1),0)))));
TEXT(DATE(2022,5,1),"MMMM");ARRAYFORMULA(DATE(2022,5,SEQUENCE(DAY(EOMONTH(DATE(2022,5,1),0)))));
TEXT(DATE(2022,6,1),"MMMM");ARRAYFORMULA(DATE(2022,6,SEQUENCE(DAY(EOMONTH(DATE(2022,6,1),0)))));
TEXT(DATE(2022,7,1),"MMMM");ARRAYFORMULA(DATE(2022,7,SEQUENCE(DAY(EOMONTH(DATE(2022,7,1),0)))));
TEXT(DATE(2022,8,1),"MMMM");ARRAYFORMULA(DATE(2022,8,SEQUENCE(DAY(EOMONTH(DATE(2022,8,1),0)))));
TEXT(DATE(2022,9,1),"MMMM");ARRAYFORMULA(DATE(2022,9,SEQUENCE(DAY(EOMONTH(DATE(2022,9,1),0)))));
TEXT(DATE(2022,10,1),"MMMM");ARRAYFORMULA(DATE(2022,10,SEQUENCE(DAY(EOMONTH(DATE(2022,10,1),0)))));
TEXT(DATE(2022,11,1),"MMMM");ARRAYFORMULA(DATE(2022,11,SEQUENCE(DAY(EOMONTH(DATE(2022,11,1),0)))));
TEXT(DATE(2022,12,1),"MMMM");ARRAYFORMULA(DATE(2022,12,SEQUENCE(DAY(EOMONTH(DATE(2022,12,1),0)))))},379,1)
This lists all the days of the year with one line added for the month's name. Next to it I have numbers corresponding to each day, and I want to sum all the numbers in each month using the same arrayformula. The problem is that some years are leapyears, so february is dynamic and I need ROW() to tell me what row march starts on but it seems now I need to rethink that formula.
should be:
={"Row 1 is row "&ROW();"Row 2 is row "&ROW()+1}
or:
={"Row 1 is row "&ROW(A1);"Row 2 is row "&ROW(A2)}
but its better this way:
=INDEX({"Row "&ROW(A1:A2)&" is row "&ROW(A1:A2)})
Looking to convert
Task id
John
Jan
Juliet
1
1
1
0
2
1
0
1
3
0
1
1
4
0
0
1
5
0
1
1
6
1
1
0
7
0
1
0
8
1
0
0
9
0
1
1
10
1
1
0
To
John
Jan
Juliet
John
3
1
Jan
3
3
Juliet
1
3
I have set up a new sheet ("Erik Help") in your sample spreadsheet.
In B1:
=SORT(FILTER(Sheet1!B1:1,Sheet1!B1:1<>""))
This simply fills the top row with your names list, sorted alphabetically.
In A2:
=TRANSPOSE(SORT(FILTER(Sheet1!B1:1,Sheet1!B1:1<>"")))
This fills A2 down with the same names list as above, just vertically.
In B2 is the main formula for the grid (which is then dragged over and down):
=ArrayFormula(IF( ($A2="") + (B$1="") + ($A2=B$1),, SUM(MMULT(IF((FILTER(Sheet1!$B$2:$L,Sheet1!$A$2:$A<>"")=1) * (Sheet1!$B$1:$L$1=$A2),1,0), SEQUENCE(COLUMNS(Sheet1!$B$1:$L$1),1,1,0)) * MMULT(IF((FILTER(Sheet1!$B$2:$L,Sheet1!$A$2:$A<>"")=1) * (Sheet1!$B$1:$L$1=B$1),1,0), SEQUENCE(COLUMNS(Sheet1!$B$1:$L$1),1,1,0)))))
The first ( ) + ( ) + ( ) tests three OR conditions. If any is true, the cell will be left blank. This is what allows the formula to be dragged all the way right and down without throwing errors and, in essence, "waiting" for new data from the first two formulas above that it can process.
The rest of the formula is too complex to warrant full explanation (e.g., how MMULT works in detail), this being a volunteer-run site. (Writing the formula took more time than I generally spend in a day on this or other forums.) But here's the gist.
Two grids — each formed by an MMULT (matrix multiplication) — are SUMmed. The first MMULT will produce a grid the same size as the Sheet1 grid, filled with 1 only if two conditions are met: that there was already a 1 in that slot and that the name above matches the name to the right in the "Erik Help" grid. Otherwise, the result for that slot is a zero. The second MMULT forms the same size grid based on the same conditions, only this time it gets a 1 only if there is already a 1 and the name above matches the name above the cell in "Erik Help." These two grids are multiplied, and if the product is a 1, we know that BOTH names had a 1 there. Once SUMmed, we get the count of shared projects for those two names.
As this formula is dragged, cell references not locked with a dollar sign will adjust, so that two different names will be compared by the two MMULT grids.
Because this solution requires comparing arrays with arrays with arrays, I don't currently see how a further array solution is possible, hence the need for the formulas to be dragged. That is, each of these formulas is already jam-packed with array processing.
Again, the formula is currently dragged all the way to Column Z and down to Row 200. However, it only references up to Column L (which is as far as your current names list goes). If your real world application has more names and thus carries over past Column L, the easiest way to change all of the formulas at once is this:
Go to the "Erik Help" sheet (which you can, of course, rename as you like).
Hit Ctrl-H to open the Find/Replace dialog box.
Enter $L in the FIND field and $? in the REPLACE field (where ? will be the new column to which you want the results to extend, e.g., $M or $P, etc.)
Choose "This sheet" from the "Search" drop-down.
Check the box next to "Also search within formulas."
Click the "Replace all" button.
If the data set shrinks or grows again, do the same steps, just changing the old furthest column reference for the new furthest column reference.
Here is a super-simple way of doing it which just changes the pair of columns selected in the countifs as the formula moves across and down by relative addressing:
=countifs(index($B$2:$D,0,row(A1)),1,index($B$2:$D,0,column(A1)),1)
pulled down and across.
Attempt at more general solution.
The question is tagged pivot-table. Although a pivot table approach seems useful, the data is in exactly the wrong format to achieve it. The task would be to transform the data from ones and zeroes to column numbers so
1 1 0 => 1 2
1 0 1 => 1 3
1 1 1 => 1 2, 1 3 and 2 3.
This can be achieved by generating pairs of numbers as follows and performing a lookup in the original data:
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
The formulas to generate these sequences are
=ArrayFormula(quotient(mod(sequence(90,1,0),9),3)+1)
and
=ArrayFormula(mod(sequence(90,1,0),3)+1)
(9 because there are 3X3 pairs per row of data, 90 because there are 10 rows of data).
The following generates a lookup for each row of data
=ArrayFormula(quotient(sequence(90,1,0),9)+1)
Putting all this together and wrapping it in a pivot query gives
=ArrayFormula(query({vlookup(quotient(sequence(90,1,0),9)+2,{row(B2:D),B2:D},quotient(mod(sequence(90,1,0),9),3)+2,0)*(quotient(mod(sequence(90,1,0),9),3)+1),
vlookup(quotient(sequence(90,1,0),9)+2,{row(B2:D),B2:D},mod(sequence(90,1,0),3)+2,0)*(mod(sequence(90,1,0),3)+1)},
"select count(Col1) where Col1<>0 and Col2<>0 group by Col1 pivot Col2"))
The formula can be generalised to different numbers of rows and columns.
I just wanted a simple way to number columns or rows in a Google Sheet, and most answers I've found offer many options that are far more complicated than I needed them to be.
Example: I want to number every column in the active sheet, starting with 1 for Column A and counting up by 1, regardless of the content of any other cells on the sheet and if I add columns to the sheet later, I want them to automatically update with the correct column numbers.
Another way is to use SEQUENCE.
So putting =SEQUENCE(99) in A1 would number the first 99 rows, from 1 to 99.
To number columns, just rotate that array, with TRANSPOSE.
So if A1 held =TRANSPOSE(SEQUENCE(26))
that would number columns A to Z with the numbers 1 to 26.
If you want to number both columns and rows,try:
in A1: =SEQUENCE(999), and
in B1: =TRANSPOSE(SEQUENCE(25,1,2))
I realise that this is numbering a specific number of rows, or columns, but I often find that very useful. You could modify this to number all columns or rows by adding some count to determine the total number of rows or columns, and using that in place of the first parameter for the SEQUENCE function.
The simplest way I've found to do this is by putting either of the following formulas in A1:
For numbering rows: =ArrayFormula(ROW(A:A))
And for columns: =ArrayFormula(COLUMN(1:1))
After putting the formula in A1, I'll usually hide the column or row the formula is in so I don't accidentally change or delete it.
If I want the counting to start at 1 on the 2nd, 3rd, or 4th row or column, then adding a -1,-2, or -3 respectively to the end of the formula gets that done.
For example: To number columns starting with 1 in Column C, the formula I put in A1 is =ArrayFormula(COLUMN(1:1)-2).
This may be way more basic than most people on this site are generally looking for, but for some reason it took me an unexpectedly long time to find it/ figure it out, so I thought maybe someone else would find it useful in the future.
Name Number
Alpha 5
Echo 2
Charlie 6
Alpha 1
Delta 5
Bravo 7
Alpha 3
Echo 2
Charlie 5
Bravo 2
For example from above, I have names in column A and numbers in column B.
I need a formula to get all the last value of a specific name, for example:
Alpha should return 3,
Bravo should return 2,
Charlie should return 5 etc.
I currently only know how to return the last value in the entire column with:
=INDEX(FILTER(I:I,NOT(ISBLANK(I:I))),ROWS(FILTER(I:I,NOT(ISBLANK(I:I)))))
But it cannot return the last value of a specific value from another column.
Please help, thank you in advance.
Assuming that
The first row is a header row
Name column is A
Number column is B
The specific name whose last number value you want is listed in cell C2
Your formula (in column D2) should be
=INDEX(FILTER(B2:B, A2:A=C2), COUNTA(FILTER(B2:B, A2:A=C2)), 1)
=SORTN(SORT(A1:B10,ROW(A1:A10),0),2^9,2,1,1)
SORT the array in reverse with ROW numbers
SORTN to remove duplicates
Try,
=index(I:I, max(filter(row(I:I), H:H=K2)))