Combine data across multiple sheets while keeping columns but ignoring blanks - google-sheets

I have three sheets in a workbook where people enter data (text values) in different columns, with different row lengths.
For example:
Sheet 1
Group 1
Group 2
Group 3
Apple
Apple
Apple
Orange
Orange
Banana
Banana
Peach
Pear
Sheet 2
Group 1
Group 2
Group 3
Onion
Onion
Onion
Tomato
Tomato
Leek
Leek
Garlic
Potato
I'm looking to combine this data into a single sheet, displayed as such:
Group 1
Group 2
Group 3
Apple
Apple
Apple
Orange
Orange
Banana
Onion
Banana
Peach
Tomato
Pear
Onion
Leek
Onion
Leek
Tomato
Garlic
Potato
I've tried this formula:
=QUERY({Sheet1!A3:G;Sheet2!A3:G;Sheet3!A3:G},"select * where Col1<>'' or Col2<>'' or Col3<>''",0)
But it adds in blanks for as many as the longest column is on each sheet, like so:
Group 1
Apple
Orange
Onion
Tomato
Leek
Is there anything I can change to have it just list the items per column in the order queried, skipping blank cells as opposed to rows? I found lots of guidance in other questions about consolidating into a single column, but I want to keep the columns separated and consolidate rows instead.

You have to use multiple queries, one for each column. Even after that, we can't stack the arrays horizontally using {,} because arrays are jagged(jagged-arrays). We can use SORT each column to give a appearance of removing blanks, as blanks are sorted to the bottom. Then stack them back. To automate this process, we can use REDUCE to loop:
=REDUCE(
,
SEQUENCE(COLUMNS(A:C)),
LAMBDA(a,c,
LAMBDA(
s,
IF(a="",s,{a,s})
)(SORT(INDEX({Sheet1!A2:C;Sheet2!A2:C},0,c)))
)
)
This removes the original order though

use:
=INDEX(TRANSPOSE(SPLIT(FLATTEN(QUERY(
IF({Sheet1!A2:C; Sheet2!A2:C}="",,"​"&{Sheet1!A2:C; Sheet2!A2:C}),,9^9)), "​")))

Related

Stack multiple queried Importranges with a single word between the two sets of imported data?

I have a master sheet that contains all of the data for other sheets. Column A in the master sheet is the name for who's sheet it will import to. So if the name is "John" then every row that has "John" in column A from the master sheet will be imported into John's sheet. I have the person's name in cell G1 of their own respective sheet and use the following formula.
=ARRAYFORMULA(IFNA(QUERY(IMPORTRANGE("LINK_TO_SHEET","Assignments!A2:Q"),"SELECT Col2,Col3,Col4,Col5,Col6,Col7,Col8,Col9,Col10,Col11,Col12,Col13 WHERE Col1='"&G1&"'",0),""))
Master sheet looks like this:
Assigned To
Name
State
City
John
Blake G.
Arizona
Phoenix
Andy
Chase C.
Arizona
Phoenix
John
Amy B.
New Mexico
Santa Fe
John
Bill S.
Texas
Austin
John's sheet will look like this:
Name
State
City
Blake G.
Arizona
Phoenix
Amy B.
New Mexico
Santa Fe
Bill
Texas
Austin
I want to separate the data based on what is in Col17 and put a single word between the two data sets. Col17 has either a Y or a N so I can just add AND Col17='N' to the existing formula. I double up the formula, but changed the last condition to be Col17='Y' so that I can pull the two data sets separately and on top of each other.
={ARRAYFORMULA(IFNA(QUERY(IMPORTRANGE("LINK_TO_SHEET","Assignments!A2:Q"),"SELECT Col2,Col3,Col4,Col5,Col6,Col7,Col8,Col9,Col10,Col11,Col12,Col13 WHERE Col1='"&G1&"' AND Col17='N'",0),""));ARRAYFORMULA(IFNA(QUERY(IMPORTRANGE("LINK_TO_SHEET","Assignments!A2:Q"),"SELECT Col2,Col3,Col4,Col5,Col6,Col7,Col8,Col9,Col10,Col11,Col12,Col13 WHERE Col1='"&G1&"' AND Col17='Y'",0),""))}
What I want to do is add a single word between the two imported sets of data. It should like kinda like this:
Name
State
City
Blake G.
Arizona
Phoenix
Amy B.
New Mexico
Santa Fe
Inactive
Bill
Texas
Austin
I added the word inactive so the middle looks like ""));"Inactive";ARRAY between the two formulas but because of how Query works I get an error saying the array lengths for each formula do not match. Is there alternative to help make this happen or will I need to figure out a workaround with something that isn't Query?
SUGGESTION
Feel free to comment below if ever your question has been misunderstood.
In my understanding, here's your process:
The first formula will list all data that has N value in Col17 .
The second formula will list all data that has Y value in Col17.
This second formula should also have an Inactive title header.
Merge the two formulas separated by the word "Inactive".
If I got it correctly, you could use the label clause to add "Inactive" in your second Query function as seen on this tweaked formula:
={ARRAYFORMULA(IFNA(QUERY(IMPORTRANGE("SHEET_URL","A1:Q"),"SELECT Col2,Col3,Col4,Col5,Col6,Col7,Col8,Col9,Col10,Col11,Col12,Col13 WHERE Col1 = '"&G1&"' AND Col17 = 'Y'"),0));ARRAYFORMULA(IFNA(QUERY(IMPORTRANGE("SHEET_URL","A1:Q"),"SELECT Col2,Col3,Col4,Col5,Col6,Col7,Col8,Col9,Col10,Col11,Col12,Col13 WHERE Col1 = '"&G1&"' AND Col17 = 'N' label Col2 'Inactive'"),0))}
Demo
Sample result.
E.g. If there's new data added that should be under "Inactive".
Main Sheet
John's Sheet
#SputnikDrunk2 is a very good workaround. Just in case you decide to stack different types of ranges that are not queries, you should consider that they need to have the same amount of columns. So if you add a new row it should have the 12 columns you have from your Queries. One way would be like this:
={ARRAYFORMULA(IFNA(QUERY(IMPORTRANGE("LINK_TO_SHEET","Assignments!A2:Q"),"SELECT Col2,Col3,Col4,Col5,Col6,Col7,Col8,Col9,Col10,Col11,Col12,Col13 WHERE Col1='"&G1&"' AND Col17='N'",0),""));
{"Inactive","","","","","","","","","","",""};
ARRAYFORMULA(IFNA(QUERY(IMPORTRANGE("LINK_TO_SHEET","Assignments!A2:Q"),"SELECT Col2,Col3,Col4,Col5,Col6,Col7,Col8,Col9,Col10,Col11,Col12,Col13 WHERE Col1='"&G1&"' AND Col17='Y'",0),""))}
Another option to avoid creating so many "","","","" is to use this "trick" that divides a range by 0, and with IFERROR it returns empty cells:
{"Inactive",INDEX (IFERROR(SEQUENCE(1,11)/0,))};
Here's another approach:
=lambda(z,
{filter(choosecols(z,2,3,4,5,6,7,8,9,10,11,12,13),index(z,,1)=A1,index(z,,17)="N");
{"Inactive",makearray(1,11,lambda(r,c,iferror(1/0)))};
filter(choosecols(z,2,3,4,5,6,7,8,9,10,11,12,13),index(z,,1)=A1,index(z,,17)="Y")}
)(A1:Q4)
A1:Q4 part in the formula should be replaced with your importrange Fx
2,3,4,5,6,7,8,9,10,11,12,13 part can also be replaced with shorter sequence(1,12,2,1)

I am trying to filter out and match exact text in Google Sheets

I have text in a Google Spreadsheet that is the result of a query.
In cell A2, I have a student's name.
In cell B2, I have a list of all of their courses.
For example, B2 may look like:
English I
Math I
World History
PE
Photography 1
(one course per line, all in the same cell)
In column E, I have a list of the courses.
In column F, I need a list of all of the students that have that course in Column B. I need each list to be in one cell.
For example in E2, it would say English I. And in F2, it would read:
Student 1
Student 2
Student 3
(one cell, one student per line)
With this formula, I get a list of all students that have that course, but also any where it contains that course.
=IFERROR(if(E2="","",(JOIN( char(10) , FILTER(A:A,search(E2,B:B))))))
So, it returns all the students taking English I, but also all the ones taking English II.
Is there anyway to make it exactly match English I and only English I?
https://docs.google.com/spreadsheets/d/1l53sEQHc6SqZW-3ycYVkGtTKaj3ZCJFRk4NXlMQR4xE/edit?usp=sharing. I need it to be formatted like the yellow column on the 'All Recs by Course' Tab.
Edit:
If I pull it in from a different sheet using this formula:
=IFERROR(if(E2="","",(JOIN(char(10),(FILTER(FEED!X:X,search(E2,FEED!V:V)))))))
I seem to be able to pull the right courses, but instead of the cell looking like:
Student 1
Student 2
Student 3
(one cell, one student per line)
It looks like:
Student 1, Student 2, Student 3
(all students in a horizontal list in a single cell - which is how it is on that original sheet).
Thanks in advance,
Beth
in H2
=sort(unique(arrayformula(flatten(split(B2:B7,char(10))))))
in I2 (drag to the next cells below)
=textjoin(char(10),,query(arrayformula(split(flatten(split(B$2:B,char(10))&"~"&A$2:A),"~")),"select Col2 where Col1='"&H2&"' "))

Google Sheets: "Text to Columns", but in single column?

I have a huge data file. Each line may contain one or more entries separated by a pipe:
one|two|three
alpha
uno|dos
beta
gamma
I can use "Text to Columns" to remove the | and put each entry in its own column:
one two three
alpha
uno dos
beta
gamma
But my desired result is to have all items in a single column:
one
alpha
uno
beta
gamma
two
three
dos
How can I easily get all entries into a single column? (order does NOT matter)
try:
=ARRAYFORMULA(QUERY(FLATTEN(IFERROR(SPLIT(FLATTEN(A:Z), "|"))), "where Col1 is not null"))
Assume Range A1:A5 is your data
=TRANSPOSE(SPLIT(JOIN("|",A1:A5),"|"))
JOIN them to add "|" to all of them first
then SPLIT text that has "|" to be 1 row, many columns
then TRANSPOSE to get just one column going
This is the basic one I can think of, anyways there are a lot of ways to do this

Using SEARCH function to count occurrence of multiple values

So I've Two lists in Google sheets. one is a (relatively short) list of names, let's say a rooster of employees. The second list is (rather a long) list of shifts, which notes the employees who were present.
for example:
List A - (rooster):
___________________
Mike
Linda
Carrie
Dave
List B - (Import_shift_data):
____________________________
Mike, John
Dave, Linda, Mike
Carrie
Dave, John
Linda
Mike
Dave, Carrie, John, Mike
My goal is to count the presence of each employee.
Now, here are the tricky parts:
List B updates every day, and each cell contains more than one name.
List A also updates, as some employees join the team and other leave.
Each shift could by a day shift, or a night shift (listed in another column next to List B) and I need to count them separately.
The Day/night column is in a parallel column next to shift column, and has one of two values, "Day" or "Night"
So my notion was to create an array formula, who can expand or shrink based on the number of values in List A. The problems is, I Can't yield and results from using the whole {list A} as the first argument in the SEARCH function.
I've tried the foloowing:
=Arrayformula(IF(INDIRECT("A2"):INDIRECT(CONCATENATE("A",MAX(Arrayformula(IF(isblank($A:$A),"",Row($A:$A)))))) = 0,"",COUNTIFs('Import_shift_data'!$P:$P,INDIRECT("A2"):INDIRECT(CONCATENATE("A",MAX(Arrayformula(IF(isblank($A:$A),"",Row($A:$A)))))),'Import_shift_data'!$M:$M,"Night")))
.
But this formula only works for a shift with a single employee.
I also wrote this one:
=Countifs(Arrayformula(ISNUMBER(SEARCH(A2,'Import_shift_data'!$P:$P))),"true",'Import_shift_data'!$M:$M,"Night")
which works fine, but I need to manually drag it up or down every time List A (The rooster) is updated.
So my end game is to have two arrays, one that counts night shifts for each employee, and one who counts day shifts. those arrays should automatically shrink or expand by the size of the rooster. (List A)
Note: If relevant, I may also note that the names in {List A} may contain more than one word, in case there are two employees with the same first name.
A copy of the spreadsheet:
https://drive.google.com/open?id=1HRDAy9-T_rflFpzanZq0fmHpV0jTZg6Rc4vHyOu-1HI
day shift:
=ARRAYFORMULA(QUERY(TRIM(TRANSPOSE(SPLIT(TEXTJOIN(", ", 1, B2:B), ","))),
"select Col1,count(Col1) group by Col1 label count(Col1)''", 0))
night shift:
=ARRAYFORMULA(QUERY(TRIM(TRANSPOSE(SPLIT(TEXTJOIN(", ", 1, C2:C), ","))),
"select Col1,count(Col1) group by Col1 label count(Col1)''", 0))
I Think I've found the Solution, I've used player0's idea of rearranging the data vector and split non-single shifts into single cells.
so basically it goes:
=Arrayformula(CountiF(Transpose(SPlit(Textjoin(" , ",TRUE,QUERY('Import_shift_data'!A:P, "select P where M = 'Night' ", 1))," , ",False)),INDIRECT("A2"):INDIRECT(CONCATENATE("A",MAX(Arrayformula(IF(isblank($A:$A),"",Row($A:$A))))))))
Thanks player0 !

How do I order a mixed text and integer field in a pivot table in Google Sheets?

Let's say that we have two columns on a sheet:
Name Room
-------------
Steve A1
Jill A1
Sam A1
Steve A2
...
Lisa A10
Sally A11
Jim A11
My actual dataset has up to a hundred of these rooms.
The issue I'm running into is with pivot tables. When I want to get a list of rooms and the count (counta is the one I'm using) it works, but the order is not what I wanted. It comes out as:
Room Count
--------------
A1 3
A10 1
A11 2
...
A2 1
I guess I can kind of see why it would be doing that. I'd much rather have it list it out in order. A1, A2, A3... A10, A11, A12, etc.
Is there an easy way to do this without some sort of data manipulation?
An "easy" way to do this without "data manipulation" is to copy the PT, Paste special, Paste values only and then drag the relevant rows (presumably at most only 8) to where you want them. The easiest way is probably with "data manipulation", for example:
=if(len(A1)=2,SUBSTITUTE(A1,"A","A0"),A1)
(Though in you case, whichever column would be the right one, it would not be ColumnA.)
I suggest you transform the string elements into number values using a lookup table.
I've created a sample spreadsheet here.
The input data in the 'input' sheet has the keys as you described.
The next sheet is the "lookup table" to translate each key into a value number. I suggest choosing large numbers to leave room for future intermediate numbers if needed
Pivot 1 is based on the original data as you described
Pivot 2 is based on the re-calculated room name using the lookup table.
The formula I used for the re-calculation is:
=VALUE(SUBSTITUTE(A2,MID(A2,1,1),VLOOKUP(MID(A2,1,1),'Lookup table'!$A$1:$B$2,2)))
I was a little lazy with the string lookup in the original name (MID), assuming your string is the first character and is 1 character long. This can be mended specifically with pattern matching.

Resources