Change formula array for every X number of rows in Excel - arrays

I have large number of rows of data in Excel where I need to change the row array of the formula for every 3 rows but I can't figure out how to adjust the formula without an error.
How do I add a formula like this to the formula below?
=INT(((ROW(a1)-1)/11))*1+1
This is the formula I have been using, but I need to change it for every 3 rows.
=IF(COUNTIF($N$4:$N$6, ""), "",MAX($N$4:$N$6))
=IF(COUNTIF($N$7:$N$9, ""), "",MAX($N$7:$N$9))
And so on
Example
I have 3 approvers, if "product" is approved, the date is for the approval date of last said approval, if no approval has been made then the cell is blank. Outcome is what I want to collect from column 3 when product was approved from all 3 approvers which is the newest date of the 3 rows, if one approver has not approved, then I'd like column 4 to be blank.
Product
Approvers
Dates
Outcome
A
1
04.01.2016
04.01.2016
A
2
17.12.2015
04.01.2016
A
3
21.12.2015
04.01.2016
B
1
11.04.2017
11.04.2017
B
2
30.01.2017
11.04.2017
B
3
04.04.2017
11.04.2017
C
1
C
2
13.10.2016
C
3
14.02.2017
D
1
01.03.2022
01.03.2022
D
2
02.12.2019
01.03.2022
D
3
30.01.2020
01.03.2022
Picture of data

Two options:
To answer the original question, to make your formula change every n rows, use =-MOD(ROW()+c, n) to adjust this (where 'c' is a constant just to get them in line, if your data starts on row 2 then c would be 1).
Your formula for row 2 would be:
=IF(COUNTIF(OFFSET($N2,-MOD(ROW($N2)+1,3),0,3),""),"",MAX(OFFSET($N2,-MOD(ROW($N2)+1,3),0,3)))
Another option, not as direct an answer to the question but potentially useful if the number of products changed in future from 3 to something else, would be:
=IF(COUNTIFS(L:L, L2, N:N, ""), "", MAX(IF(L:L=L2, L:L)))
and click Ctrl+Shift+Enter after typing that in (because it's an Array formula, see here, here and here).
The advantage of this approach is that it looks at all rows where the product column is the same (I'm assuming unique products), so no need to limit it to 3 rows per product or have those 3 rows next to each other.

Related

Google sheets Find next numeric value from the colnums

I have two rows with SKUs, one comes from one database, and another one from another one. As you can see in the visual example SKUs with values 1, 2, 4 & 5 are present in both databases.
https://i.stack.imgur.com/KlTCr.png
I start with number 1 and I need a formula that would bring up the next valid number (in this case number 2) that is present in both columns.
I would need a formula that would do the following:
If I lookup 1 it should bring 2
If I lookup 2 it should bring 4
If I lookup 4 it should bring 5
Thank you in advance
try:
={FILTER(B2:B16, COUNTIF(E2:E16, B2:B16)),
{QUERY(FILTER(B2:B16, COUNTIF(E2:E16, B2:B16)), "offset 1", ); ""}}

Conditionally Sum a googlesheet column based on entries in related tables

Say I have two related sheets/tabs within a google sheet. One sheet/tab is titled "Categories", the other is "Measures".
Categories:
userid
catcode
1
a
1
b
2
a
3
c
Measures:
userid
catcode
points
1
a
5
1
b
5
1
c
3
2
a
4
3
c
3
For each user I'd like to be able to sum the points from the Measures table where the catcode is present for the user in the categories table. Ideally using an auto-extending/filling formula (like an arrayformula or query).
I have some idea how I'd approach this with SQL statements (joining the related tables, or doing a select where exists), but I'm new to googlesheets and would appreciate some direction here. I've experimented with this a bit and assuming a third table named "Users" with userids in column A, I can add this formula:
=sum(filter(measure!C2:C4, measure!A2:A4=users!A2, not(iserror(vlookup(measure!B2:B4, unique(filter(categories!B2:B5, categories!A2:A5=users!A2)), 1, false)))))
However this approach doesn't seem to be compatible with arrayformula and won't allow me to autofill down the Users tab for newly added userids. Sum itself is apparently incompatible with arrayformula. Additionally, if I enclose the above in arrayformula and replace sum with sumproduct or some other approach to the summation, I'm unable to get the users!A2 references to extend down as I'd expect via something like users!A2:A.
Any help/direction would be appreciated. Thanks!
Try:
=ARRAYFORMULA(QUERY({A1:A, VLOOKUP(A1:A&B1:B, {D1:D&E1:E, F1:F}, 2, 0)},
"select Col1,sum(Col2) where Col1 is not null group by Col1 label sum(Col2)''"))

Nested 'for' loops in native Google Sheets (no scripts)

I'm aware that it's possible to emulate a for loop in Google Sheets via the following:
=ARRAYFORMULA(IF(LEN({range_0 to iterate over}),{function_0 for each element in range_0}))
I've not been able to expand on the above approach to achieve the effect of a multi nested for loop. Is this possible? Ideally this would look something like:
=ARRAYFORMULA(IF(LEN({range_0 to iterate over}),IF(LEN({range_0.1 to iterate over for each parent element in range_0}),{function_0.1 for each element in range_0.1},{OPTIONAL: function_0 for each element in range_0})))
Example application:
Iterating over each cell in a row for each row in a column (see below; I'm sure there are ways to achieve this effect via other methods, but I have use for the requested and specified method for cases where a single dynamic formula is necessary to keep up with an unknown and changing number of rows, columns, and functions involved):
Raw data:
Thing
Type
Feature
Cost
Apple
Fruit
Seeds
$1
Car
Automobile
Wheels
$6,000
Laptop
Computer
Keyboard
$500
Grape
Fruit
Tastiness
$0.50
Theoretical formula:
=ARRAYFORMULA(IF(LEN(`Thing`),IF(LEN(COLUMNS({current row of `Thing`})),{current cell in current row of `Thing`} & " of column " & COLUMN({*current cell*}) & " and row " & ROW(`Thing`),""),""))
Output of above theoretical formula:
Thing
Type
Feature
Cost
Apple of column 1 and row 3
Fruit of column 2 and row 3
Seeds of column 3 and row 3
$1 of column 4 and row 3
Car of column 1 and row 4
Automobile of column 2 and row 4
Wheels of column 3 and row 4
$6,000 of column 4 and row 4
Laptop of column 1 and row 5
Computer of column 2 and row 5
Keyboard of column 3 and row 5
$500 of column 4 and row 5
Grape of column 1 and row 6
Fruit of column 2 and row 6
Tastiness of column 3 and row 6
$0.50 of column 4 and row 6
Thank you for your help!
try:
=ARRAYFORMULA(IF(LEN(A3:E7), A3:E7&" of column "&COLUMN(A3:E7)&" and row "&ROW(A3:E7), ))

Keep the order of current and future posts

One of my curiosities these days is how to order some posts. I will give you a clear example, maybe one the majority of you experimented in the past.
The Facebook Timeline, which you can add posts and events to, at any point in time you want. In this case, I assume, the posts are ordered by the date. When you add a new status for the past, you have to assign it a date, so it is easy to get them in order.
What I want to do is to have posts and the option to add a new post after a specific one. I don't have the option to add a date to it but I have to have a way to get them in that order.
So, if every post has an id and a date (the creation date). If a new post is added between 2 posts, I can't increment all the ids of the "upper" posts, so that I can order by the id. Neither is the date, because I can add a post between two older posts in the future.
What solution do you imagine for this? What criteria should I order by (I am ready to make some database scheme changes if needed)?
OK, there's another possible solution. Use two columns for ordering: Order1 is basic order, and Order2 is order within group defined by Order1. You assign your posts to some arbitrary groups (i.e. all posts from single day or every 100 posts) by setting Order1. Within each group posts are ordered according to value in Order2.
If a new post must be inserted into some group you only need to renumber Order2 values for posts in this particular group - not all posts in table.
Of course when retrieving the rows you order by Order1, Order2.
So your table looks like this:
PostName Order1 Order2
------------------------
A 1 1
B 1 2
C 1 3
D 1 4
E 2 1
F 2 2
G 2 3
Now if you want to insert X between F and G you renumber only items in group Order1 = 2, so that rows become:
PostName Order1 Order2
------------------------
A 1 1
B 1 2
C 1 3
D 1 4
E 2 1
F 2 2
G 2 4
X 2 3
Now, if you want to insert Z between A and B you only renumber Order2 in posts in group Order1 = 1:
PostName Order1 Order2
------------------------
A 1 1
B 1 3
C 1 4
D 1 5
E 2 1
F 2 2
G 2 4
X 2 3
Z 1 2
IF you're not going order by a criteria (Date, for example), you will need something to order them. Not necessary have to use column Id to order, you could add a column that is not the PK, and makes the function of ordinalPosition.
So, when you insert at the end, you will get the max ordinalPosition, and then do ordinalPosition+1.
If you want to insert between two of those, then you look the ordinal position of the two post you have (to insert between them), update incrementing in 1 all ordinalColumns, from the major of those two post, and then (now you got a "hole" in the ordinalPosition), insert the new ordinalPosition, and that will be the the minor of those two post + 1 (which equally the mayor of those two post)
Then, you will get the posts ordered by your ordinalPosition:
Select fields from Posts
-- where your criteria goes here
order by ordinalPosition
Maybe you consider that's not a good way, because everytime you insert a post between two another one, you will have to do an update - but the Db is not magic, has to order by some criteria. And have to make sure there is no posts with same order id, so probably will have to add some Unique Constraint or something as you want.
You're not gonna update very old posts probably, so I don't think will be so much update's everytime you add a posts between other two.

How do I have a Row Group "under" a Column Group in SSRS?

I have some data that relates to some production inputs and outputs.
What I want to do is, for each production run, show what went in and what came out.
I have, at this point, something that looks like this:
Run# Item Input Output
1 X 1
Y 1
2 A 2
B 3 2
C 3
Where Input/Output is derived from a 'direction' column group, and there are row groups on Run# and Item.
What I want is something like this:
Run# Item Input Item Output
1 X 1 Y 1
2 A 2 B 2
B 3 C 3
Is this even possible? I feel like it should be, but as you can probably see from the title, I don't even know what to begin searching.
The way to do this is to add a rank() over the query like so:
dense_rank() OVER (Run#, Direction Order By ItemCode) as rank
You can then perform a row grouping by the rank field (you don't have to display the column), and add ItemCode as a column in the column grouping.

Resources