Fill in blank cells from several columns in ={ARRAYFORMULA()} - google-sheets

I have a human-friendly sheet with sparse hierarchical data:
SEASON | FRUIT | LETTER
-----------------------------
Winter | |
| Lemons |
| | Delta
Summer | |
| | Alpha
| | Beta
| Pears |
| | Gamma
(Note how Alpha and Beta don't have a FRUIT entry.)
I want to generate a new column, using ARRAYFORMULA(), to contain a full "path" to the LETTER:
SEASON | FRUIT | LETTER | PATH
------------------------------------
Winter | | | Winter//
| Lemons | | Winter/Lemons/
| | Delta | Winter/Lemons/Delta
Summer | | | Summer//
| | Alpha | Summer//Alpha
| | Beta | Summer//Beta
| Pears | | Summer/Pears/
| | Gamma | Summer/Pears/Gamma
Please help me to understand how to write such ARRAYFORMULA().
I'm trying approach, based on answers in Fill in blank cells in ={ARRAYFORMULA()}, but I'm stuck at resetting FRUIT to empty string for a new SEASON. I.e. this naïve implementation would yield Summer/Lemons/Alpha instead of Summer//Alpha:
={ ARRAYFORMULA(
IFERROR(VLOOKUP(ROW(SEASON), IF(SEASON<>"", { ROW(SEASON), SEASON }), 2, 1), "")
& "/" & IFERROR(VLOOKUP(ROW(FRUIT), IF(FRUIT<>"", { ROW(FRUIT), FRUIT }), 2, 1), "")
& "/" & LETTER
) }

Here is a sample spreadsheet created specifically to answer this question.
you will find this formula in cell E1 on a tab called Possible Solution.
=ARRAYFORMULA(IF(LEN(A:A&B:B&C:C),VLOOKUP(ROW(A:A),FILTER({ROW(A:A),A:A},LEN(A:A)),2,1)&"/"&VLOOKUP(ROW(B:B),FILTER({ROW(B:B),B:B},LEN(A:A&B:B)),2,1)&"/"&C:C,))
It uses the VLOOKUP(ROW(),FILTER(),[index],TRUE) technique to append the relevant parts of the path to one another.
Note the portion of the formula in the image which i believe was the crux of the trouble with the strategy you were trying...

Related

Google Sheets Return Any(All) Row Value(s) For MAX-GROUP Query

I am looking to return non-grouped row values from a query of a table sorted by the MAX value of a column, within a group.
DATA TABLE
| NAME | ASSET | ACTION | DATE |
|--|--|--|--|
| JOE | CAR | BOUGHT | 1/1/2020 |
| JANE | HORSE | BOUGHT | 1/1/2021 |
| JOE | HORSE | BOUGHT | 2/1/2021 |
| JANE | HORSE | SOLD | 3/1/2021 |
| JOE | CAR | SOLD | 1/1/2022 |
| JOE | CAR | BOUGHT | 2/1/2022 |
For the table above, I presented the following code.
=QUERY(A1:D5,"SELECT A,B,C,D, MAX(D) GROUP BY A,B",TRUE)
The following TARGET TABLE is output I'm looking for:
| NAME | ASSET | ACTION | DATE |
|--|--|--|--|
| JANE | HORSE | SOLD | 3/1/2021 |
| JOE | HORSE | BOUGHT | 2/1/2021 |
| JOE | CAR | BOUGHT | 2/1/2022 |
However, because 'C' is not included in the GROUP, the formula returns an error. "Unable to parse query string for Function QUERY parameter 2: ADD_COL_TO_GROUP_BY_OR_AGG: C"
If I were to omit COL C & D, "ACTION" & "DATE" from the SELECT: =QUERY(A1:D5,"SELECT A,B, MAX(D) GROUP BY A,B",TRUE) , I have the correct record rows, but am missing the STATUS.
MAX-DATE TABLE
| NAME | ASSET | max DATE |
|--|--|--|
| JANE | HORSE | 3/1/2021 |
| JOE | HORSE | 2/1/2021 |
| JOE | CAR | 2/1/2022 |
OR, when I add COL C as a "PIVIOT": =QUERY(A1:D5,"SELECT A,B, MAX(D) GROUP BY A,B PIVOT C",TRUE)I have the correct record rows, but do not have the 'current' STATUS within the record row.
PIVOT ACTION TABLE
| NAME | ASSET | BOUGHT | SOLD |
|--|--|--|--|
| JANE | HORSE | 1/1/2021 | 3/1/2021 |
| JOE | HORSE | 2/1/2021 | |
| JOE | CAR | 2/1/2022 | 1/1/2022 |
Still I have not found a method to create my TARGET TABLE.
Am I overlooking a method to include a non-grouped field into a query using MAX()? Or is it impossible within Google Sheets Query without JOIN functions?
(I hope it is obvious that I desire to apply this to a large and dynamic dataset.)
Thank you for your insight. Cheers!
It's not that flexible to work with QUERYs with its aggregation requisites and so on.
You can create a filter, by comparing column D with a "fictional" column created with BYROW: = BYROW(A2:A,LAMBDA(each,MAXIFS($D$2:$D,$A$2:$A,each,$B$2:$B,OFFSET(each,,1))))
That would look like this (I highlighted the matches and added extra rows for reference):
Then, you can set this filter (don't create this column, it's just a visualization of what I did):
=FILTER(A2:D,D2:D = BYROW(A2:A,LAMBDA(each,MAXIFS($D$2:$D,$A$2:$A,each,$B$2:$B,OFFSET(each,,1)))))
This way, you're comparing the dates with the maximum for each category

How to prevent rows from shifting when syncing with main data source?

I am creating a directory of people in a group. In the first sheet are the names, address, phone, and email info. The basics.
Then in Sheet 2 I am keeping a record of attendance.
In the third sheet I am keeping a record of some goals that are accomplished.
I used =ARRAYFORMULA(BASE!A:A) to get the first column and put that in the second and third sheets.
This worked great for a while. Then we got a new member. I added their info to the base sheet. His name was brought over to the second and third sheet. That's good. But it didn't keep the rows connected on the second and third sheet. They were off by one row since adding the new member shifted the cells that he was added on.
SO...
Base Sheet
|--------------|------------|------------|------------------|
|First Name | Last Name | Address | and so on...... |
|--------------|------------|------------|------------------|
|John | Doe | 123 Main | |
|--------------|------------|------------|------------------|
|Jim | Smith | 123 Elm | |
|--------------|------------|------------|------------------|
|Jill | Summers | 123 Aspen | |
|--------------|------------|------------|------------------|
Then I have another sheet for tracking attendance taking the first name and last name from the base sheet.
The top row and first two columns are frozen on both sheets.
|--------------|------------|------------|---------|---------------|
| First Name | Last Name | 10/1/19 | 10/7/19 | and so on.....|
|--------------|------------|------------|---------|---------------|
| John | Doe | x | x | |
|--------------|------------|------------|---------|---------------|
| Jim | Smith | | x | |
|--------------|------------|------------|---------|---------------|
| Jill | Summers | x | | |
|--------------|------------|------------|---------|---------------|
What I would like to do is be able to add a new row for a new name and it create a new row in the secondary sheets as well. For example...
|--------------|------------|------------|------------------|
|First Name | Last Name | Address | and so on...... |
|--------------|------------|------------|------------------|
|John | Doe | 123 Main | |
|--------------|------------|------------|------------------|
|Julie | Fry | 123 Oak | |
|--------------|------------|------------|------------------|
|Jim | Smith | 123 Elm | |
|--------------|------------|------------|------------------|
|Jill | Summers | 123 Aspen | |
|--------------|------------|------------|------------------|
which would result in ...
|--------------|------------|------------|---------|---------------|
| First Name | Last Name | 10/1/19 | 10/7/19 | and so on.....|
|--------------|------------|------------|---------|---------------|
| John | Doe | x | x | |
|--------------|------------|------------|---------|---------------|
| Julie | Fry | | | |
|--------------|------------|------------|---------|---------------|
| Jim | Smith | | x | |
|--------------|------------|------------|---------|---------------|
| Jill | Summers | x | | |
|--------------|------------|------------|---------|---------------|
Is there a way to fix this situation? Or perhaps just a better way to do this?
I know I could add the name to the bottom of the list and that would "kinda" work, but then I wouldn't be able to sort by first of last name. The sort would work on the base page, but it would also sort the name on the attendance page, but the data in the rows would be unaffected.
you can try to lock it down with INDIRECT like:
=ARRAYFORMULA(INDIRECT("BASE!B:B"))

Partial transpose of Sheet

I have a Google Sheet with this format:
+---------+---------+---------+------------+------------+------------+------------+--------+--------+
| Field_A | Field_B | Field_C | 24/09/2019 | 25/09/2019 | 26/09/2019 | 27/09/2019 | day... | day... |
+---------+---------+---------+------------+------------+------------+------------+--------+--------+
| ValX | ValY | ValZ | Val1 | Val2 | Val3 | Val4 | | |
| ValW | ValY | ValZ | Val5 | Val6 | Val7 | Val8 | | |
+---------+---------+---------+------------+------------+------------+------------+--------+--------+
First 3 columns are specific fields and all other columns are related to one specific day in a given (and static) range.
I need to convert the table in the following format:
+---------+---------+---------+------------+-----------+
| Field_A | Field_B | Field_C | Date | DateValue |
+---------+---------+---------+------------+-----------+
| ValX | Valy | Valz | 24/09/2019 | Val1 |
| ValX | Valy | Valz | 25/09/2019 | Val2 |
| ValX | Valy | Valz | 26/09/2019 | Val3 |
| ... | | | | |
+---------+---------+---------+------------+-----------+
Basically, the first 3 columns are gathered as-is, but the day-column in transposed (is even the correct term?) with 2 values:
The date
The value in the cell related to date
Is something that can be achieved with formula or do I need to create a bounded AppsScript?
Following a sample Sheet demo: https://docs.google.com/spreadsheets/d/1cprzD96i-4NQ8tieA_nwd8s43yKF-M8Kww4yWNfB6tg/edit#gid=505040170
In Sheet Start you can see the initial data and format, 3 static columns and one column for every da
In Sheet End you can see the output format I'm looking for, the same 3 static columns, but the date and cell value related to date are transposed as a row.
You can see the Formula I used, TRANSPOSE for every row, where I select the days for the IV column and one row at a time for the V row.
For the 3 static columns, I replicated the Formula for every instance of the day related to that row.
This is working but requires much manual work to set up every single TRANSPOSE. I'm wondering if there is a more automatic way of doing this (except for using AppsScript, in that case, I'm already planning on doing this if not other solutions are available)
=ARRAYFORMULA(TRIM(SPLIT(TRANSPOSE(SPLIT(QUERY(TRANSPOSE(QUERY(TRANSPOSE(
IF(Start!D2:F<>""; "♦"&TRANSPOSE(QUERY(TRANSPOSE(Start!A2:C&"♠");;999^99))&
TEXT(Start!D1:F1; "dd/mm/yyyy")&"♠"&Start!D2:F; ));;999^99));;999^99); "♦")); "♠")))

Filter out all of user's entries if one of them was selected

I am trying to write a formula that will allow you to put up to 3 values into a pool (per person) and then when one of those values is selected for use all 3 potential values are removed from the pool.
My current formula is long but fairly simple in that it takes the values from each user and adds/subtracts them based on whether they are being used.
=(SUMIF($I$2:$I$50, $A24, $L$2:$L$50) + SUMIF($J$2:$J$50, $A24, $L$2:$L$50) + SUMIF($K$2:$K$50, $A24, $L$2:$L$50)) - (SUMIF($A$2:$A$20, $A24, $L$2:$L$20) + SUMIF($B$2:$B$20, $A24, $L$2:$L$20) + SUMIF($C$2:$C$20, $A24, $L$2:$L$20) + SUMIF($D$2:$D$20, $A24, $L$2:$L$20) + SUMIF($E$2:$E$20, $A24, $L$2:$L$20))
The limiting factor here is that each user is adding a potential of 3 values to the pool but when one is selected it is only subtracting that from the pool and then leaving the other 2 which invalidates the pool as a whole.
For reference I have copied the contents over to the following sheet
https://docs.google.com/spreadsheets/d/1tbL1WuaUoR8JM8cndTBiKnoaLm-UxCaddpSOJbCVmiM/edit?usp=sharing
Does anyone have an idea for how to properly remove all available options from the pool rather than just the one that was selected? I have a few ideas from how to possibly make it work with code but I am trying to make it an automated formula rather than something that needs to be specifically "run" to calculate it.
You need some marker against each user to indicate whether their entries are still eligible for taking. Here is an example: column Eligible (L) is True if we haven't chosen from that user yet. Column Selected (N) is filled manually, by choosing from what is available in column Available (O). The formulas are:
For Eligible column (second row shown):
=and(isna(match(I2, N$2:N, 0)), isna(match(J2, N$2:N, 0)), isna(match(K2, N$2:N, 0)))
which says that neither I2, J2, or K2 match anything in N.
And in column O, only one array formula is needed:
={filter(I2:I, L2:L); filter(J2:J, L2:L); filter(K2:K, L2:L)}
which filters out non-eligible users and stacks the foods in one column using array notation {}.
+--------+---------+--------+------------+-----------+--+----------+------------+
| User | Food 1 | Food 2 | Food 3 | Eligible | | Selected | Available |
+--------+---------+--------+------------+-----------+--+----------+------------+
| User A | Chicken | Pear | Watermelon | TRUE | | Grape | Chicken |
| User B | Garlic | Grape | Rice | FALSE | | Beef | Potato |
| User C | Beef | Corn | Salt | FALSE | | | Pear |
| User D | Potato | Pepper | Orange | TRUE | | | Pepper |
| | | | | | | | Watermelon |
| | | | | | | | Orange |
+--------+---------+--------+------------+-----------+--+----------+------------+

Can I have a cucumber example with several values in a single column x row position

Hi here is what I what I have:
Scenario Outline: Seatching for stuff
Given that the following simple things exists:
| id | title | description | temp |
| 1 | First title | First description | low |
| 2 | Second title | Second description with öl | Medium |
| 3 | Third title | Third description | High |
| 11 | A title with number 2 | can searching numbers find this 2 | Exreme |
When I search for <criteria>
Then I should get <result>
And I should not get <excluded>
Examples
|criteria|results | excluded |
| 1 | 1 | 2,3,11 |
| 11 | 11 | 1,2,3 |
| title | 1,2,3 | 11 |
| öl | 2 | 1,3,11 |
| Fir* | 1 | 2,3,11 |
| third | 3 | 1,2,11 |
| High | 3 | 1,2,11 |
As you can see I'm trying to test a search field for a web-application using cucumber and the scenario outline structure in order to test several search criteria.
I'm not sure how to handle the input I would get as result and excluded in my steps.
Maybe this doesn't work at all?
Is there a workaround?
There's nothing wrong with what you're doing. Cucumber will just take that as a single string. The fact that it's actually comma-separated values means nothing to Cucumber.
Your step definition would still look like this:
Then /^I should not get ([^"]*)$/ do |excluded|
# excluded will be a string, "2,3,11"
values = excluded.split(",")
# Do whatever you want with the values
end

Resources