Unique values horizontally every *n cell (Gsheets) - google-sheets

I am trying to convert unique values of vertical range to horizontal however I wish to have the output every second cell (see desired output on the image). I have tried offset() and mod() function however it does not seem to work. Could you please give me a clue of how to modify my function?
Function:
=unique(transpose(T2:T10))

try this formula
=transpose(flatten(query(unique(T2:T10),"select Col1, ' ' label ' ''' ") ))

An alternative solution you can go with by using SPLIT, JOIN, CONCATENATE, REPT and ARRAYFORMULA and it gives you easier way to adjust for every n cells by just changing a number of many cells you want skipped.
Formula for 1 cell skipped:
=SPLIT(ARRAYFORMULA(JOIN(CONCATENATE(REPT(", ", 1), ",") ,UNIQUE(A2:A10))),",")
Change 1 inside REPT function to choose how many cells are to be skipped
Behavior:
Repeats the ", " via REPT and pair with a comma at the end using CONCATENATE
Joins the UNIQUE(A2:A10) with the delimiter generated above via JOIN in an ARRAYFORMULA (resulting to 1, ,2, ,3, ,4...)
Lastly, SPLIT by ",", thus having a blank cell in between the numbers (These blank cells are those spaces in between commas we inserted)
Output:

My simple approach is:
=arrayformula(split(join(",,",unique(T4:T10)),",",1,0))
Then JOIN puts them in a line, separated by two commas.
SPLIT pushes them into different columns. The 'remove_empty_text' parameter in SPLIT is set to false 0, following the 'split_by_each' parameter 1. This splits by each comma in the join. Hence, ",,," would be two spaces apart.
If you need to ignore gaps, then wrap a query around the data range:
query({T4:T10},"where Col1 is not null",0)
The query can also sort the results:
query({T4:T10},"where Col1 is not null order by Col1",0)
So the final formula would be:
=arrayformula(split(join(",,",unique(query({T4:T10},"where Col1 is not null order by Col1",0))),",",1,0))

Related

Summing specific values in a joined list

I am having some difficulties summing up some values in Google Sheets. In my spreadsheet, from multiple other tabs, values and bonuses are combined into one cell (Cell B1 in this example). The format of each "unit" of data is Name,5%xxx (Where "Name" is the name of the item, "5%" represents the sum I want to add, mostly always a percentage, and "xxx" separates one unit from the next). As you can see in cell B1, there are two instances where "Parkour" receives a bonus to sum up (from different sources).
Parkour,5%xxxParkour (Subskill: Sense of Balance),10%xxxParkour,2%xxx
Parkour
0.07
Parkour (Subskill: Sense of Balance)
H2H Combat: Parkour
The formula in cell B2 is:
=IFERROR(SUM(ARRAYFORMULA(IFERROR(VALUE(MID(FILTER(SPLIT(TEXTJOIN("",TRUE,filter(B$1,regexmatch(B$1,$A2)=TRUE)),"xxx"),SEARCH($A2,SPLIT(TEXTJOIN("",TRUE,filter(B$1,regexmatch(B$1,$A2)=TRUE)),"xxx"))),len($A2)+2,1000)),""))),"")
(Dragged down through the rest of the list) (Could not figure out how to make the formula "in line" on the question.)
Expected Results:
B2 = .07 (Working)
B3 = .1 (Not working)
B4 = Blank (Working)
The goal of the formula is to look into cell B1, and split everything out by "xxx". Then, filter the array of items with only exact matches with the line item in column A, then split again by the comma and add up those values. It worked for the first line item, but not the second. (Unsure why, but I strongly believe it has something to do with the parenthesis. When I removed the parenthesis from the name in Column A (and adjusted cell B1 to not have parenthesis), it worked. However, given the structure of the data, parenthesis are required, and I need to find a way for it to work with them.)
When I removed the IFERROR wrap around it in cell B3, I get this error note:
Function SUM parameter 1 expects number values. But " is a text and cannot be coerced to a number.
Any help is greatly appreciated.
You may find useful combining SPLIT with QUERY like this. It will group names and sum percentages:
=QUERY(INDEX (IFERROR(SPLIT(FLATTEN(INDEX(SPLIT(B1:B100,"xxx"))),","))),"SELECT Col1,SUM(Col2) where Col1 is not null group by Col1")
PS: invented a couple of extra line
UPDATE
I've thought you had another goal, try this formula. Having the previous chart generated by QUERY, I used VLOOKUP to match first column and return second one:
=INDEX(IFERROR (VLOOKUP(A2:A,QUERY(INDEX (SPLIT(FLATTEN(SPLIT(B1,"xxx")),",")),"SELECT Col1,SUM(Col2) where Col1 is not null group by Col1"),2,0)))

Google Sheets: Find a Row that Matches Only a Few Specific Characteristics

I can't seem to find the right equation to find a cell from a row that matches only a few specific characteristics. In this example, I am trying to find the equation for Column D which would be the cell in A that has the same cells for B & C.
Hope this makes sense!
I'll provide two options.
If you're sure your data will only ever have zero or one match, you can place the following formula into D2 of an otherwise empty range D2:D...
=ArrayFormula(IF(A2:A="",,SUBSTITUTE(VLOOKUP(B2:B&C2:C,{B2:B&C2:C,A2:A},2,FALSE)&VLOOKUP(B2:B&C2:C,SORT({B2:B&C2:C,A2:A,ROW(A2:A)},3,0),2,FALSE),A2:A,"")))
However, if you think more than one match may turn up and you want "None" to be returned if there is no match, you can use the following formula in D2 or an otherwise empty range D2:D...
=ArrayFormula(IF(A2:A="",,REGEXREPLACE(REGEXEXTRACT(REGEXREPLACE(SUBSTITUTE(VLOOKUP(B2:B&C2:C,TRIM(SPLIT(FLATTEN(QUERY(QUERY({B2:B&C2:C&"~",A2:A&","}, "Select MAX(Col2) where Col2 IS NOT NULL GROUP BY Col2 PIVOT Col1"),, 9^9)),"~")),2,FALSE),A2:A,""),"^[,\s]+$","None"),"([^,\s].+[^,\s])[,\s]*$"),"[,\s]+",", ")))
The second formula will work even if there will only ever be zero or one match; it's just not necessary to have it be that lengthy. And the second formula is only as lengthy because it was unclear from your posted examples whether the data in Col A, B and C will really only ever be one word or not; so the formula is built to assume there will not always be one-word strings in those columns.
Either formula will provide results for the entire column without dragging.
Here's an option, You can use this formula in column D2:
=iferror(textjoin(", ",true,query($A$2:$C,"Select A where A is not null and A != '"&$A2&"' and B = '"&$B2&"' and C = '"&$C2&"'",0)),"None")
Limitation:
You need to manually drag the formula to its succeeding rows. Arrayformula() cannot be used in looping the query string values.
What it does?
Using query(), filter the data from A2:C that has the same current row last name(Column B) and food(Column C) at the same time having a different first name(Column A)
If there are multiple results, use textjoin() to combine them with ", " as its delimiter.
If there is no matched found, it will return an error, hence use iferror() to set the default value to "None"
Output

Google Sheets - Concatenate 2 rows across columns into 1 cell

I'd like to achieve what's in the Desired Output column in the image below. I need to take what's in row 1 (id1, id2, etc.), add ":" to that, then concatenate it with the values under each of the Field columns, add "|" to each ID-Value pair, and get that all together into one cell. I need the formula to also work for empty cells, as the number of fields to concatenate together is dynamic.
So far I've tried a big CONCATENATE formula in one cell, but I can only get it to work for as many non-blank cells as I include in the formula.
Thanks in advance!
google-sheets
Use JOIN:
=arrayformula(join("|",filter($B$1:$E$1& ":" & B2:E2,B2:E2<>"")))
excel-formula
Use TEXTJOIN
=TEXTJOIN("|",,IF(B2:E2<>"",$B$1:$E$1 & ":" & B2:E2,""))
This will be an array formula and must be confirmed with ctrl-Shift-Enter instead of Enter when exiting edit mode.

Combine Text in ArrayFormula

I have a table using Google Sheets. It has three columns that will always have a null value or a specific value for that column. Each line will have one, two, or three values; it will never have three null values on one line. In the fourth column, I want an ArrayFormula that will combine those values and separate the values with a comma if there is more than one.
Here is a photo of what I am trying to accomplish.
I've tried several ideas so far and this formula is the closest I've gotten so far but it's still not quite working correctly; I think it is treating each column as an array before joining rather than doing the function line by line. I'm using the LEN function rather than A2="" or ISBLANK(A2) because columns A-C are ArrayFormulas as well. I realize this probably isn't the most efficient formula to use but I think it covers every possibility. I'm definitely open to other ideas as well.
={"Focus";
ArayFormula(
IFS(
$A$2:$A="", "",
(LEN(A2:A)>0 & LEN(B2:B)>0 & LEN(C2:C)>0), TEXTJOIN(", ", TRUE, A2:A, B2:B, C2:C),
(LEN(A2:A)>0 & LEN(B2:B)>0 & LEN(C2:C)=0), TEXTJOIN(", ", TRUE, A2:A, B2:B),
(LEN(A2:A)>0 & LEN(B2:B)=0 & LEN(C2:C)>0), TEXTJOIN(", ", TRUE, A2:A, C2:C),
(LEN(A2:A)=0 & LEN(B2:B)>0 & LEN(C2:C)>0), TEXTJOIN(", ", TRUE, B2:B, C2:C),
(LEN(A2:A)>0 & LEN(B2:B)=0 & LEN(C2:C)=0), A2:A,
(LEN(A2:A)=0 & LEN(B2:B)>0 & LEN(C2:C)=0), B2:B,
(LEN(A2:A)=0 & LEN(B2:B)=0 & LEN(C2:C)>0), C2:C
)
)
}
Is it possible to achieve this with Google Sheets?
Sample File
Please try:
=ARRAYFORMULA(SUBSTITUTE(TRIM(TRANSPOSE(QUERY(TRANSPOSE(FILTER(A2:C,ROW(A2:C)<=MAX(IF(LEN(A2:C),ROW(A2:C)*COLUMN(A2:C)^0,0)))),,2^99)))," ",", "))
Notes:
The formula will work incorrectly if some names have space inside: like "Aston Martin"
So if you have spaces, please try this:
=ARRAYFORMULA(SUBSTITUTE(
SUBSTITUTE(TRIM(TRANSPOSE(QUERY(TRANSPOSE(FILTER(SUBSTITUTE(A2:C," ",char(9)),ROW(A2:C)<=MAX(IF(LEN(A2:C),ROW(A2:C)*COLUMN(A2:C)^0,0)))),,2^99)))," ",", "),
CHAR(9)," "))
EDIT
Noticed the shorter variant (without *COLUMN(A2:C)^0) will work:
=ARRAYFORMULA(SUBSTITUTE(
SUBSTITUTE(TRIM(TRANSPOSE(QUERY(TRANSPOSE(FILTER(SUBSTITUTE(A2:C," ",char(9)),ROW(A2:C)<=MAX(IF(LEN(A2:C),ROW(A2:C),0)))),,2^99)))," ",", "),
CHAR(9)," "))
Notes:
I used an old trick to join strings with an array-formula. See sample file
Explanations
If you like to understand any tiered formula, the best way is to split it by parts:
Part 1. Filter the data
FILTER(any_columns,ROW(A2:C)<=MAX(IF(LEN(A2:C),ROW(A2:C)*COLUMN(A2:C)^0,0))). this is my way to limit the data range.
The range is open, means it starts from the second row (A2) and
ends in any row.
I want to get the limited array in this step to reduce work that the formula should do. This is done with a condition, if.
ROW(A2:C) must be less or equal to the max row of data.
MAX(IF(LEN(A2:C), some_rows) gives the max row.
If(len.. part checks if a cell has some text inside it.
Note some_rows part:
MAX(IF(LEN(A2:C),ROW(A2:C)*COLUMN(A2:C)^0,0)))),,2^99))).
ROW(A2:C) must be multiplied by columns, because filter formula
takes only one row into its condition. That is why I multiply by
COLUMN(A2:C)^0 which is columns with 1s. Edit. Now noticed,
that the formula works fine without *COLUMN(A2:C)^0, so it's an
overkill.
Part 2. Join the text
query formula has 3 arguments: data, query_text, and a number_of_header_rows.
data is made with a filter.
query_text is empty, which gives us equivalent to select all
("select *").
And the number of rows of a header is some big number (2^99).
This is a trick: when a query has more headers then one row,
it will join them with space.
After a union is made, transpose function will convert the result back to the column.
Part 3. Substitute and trim
The function trim deletes extra spaces.
Then we replace spaces with the delimiter: ", ". That is why the
formula needs to be modified if spaces are in strings. Correct
result: "Ford, Aston Martin". Incorrect: "Ford, Aston, Martin". But
if we previously replace spaces with some char (char(9) is Tab),
then we do not replace it in this step.

How format a result using VLOOKUP to loop inside a single cell with an arbitrary number of search keys

I have a column called "Notes (Atomic weights)" with an arbitrary (0 to n) number of search keys in it.
and a corresponding Named Range called "NOTES"
How do I do a vlookup/Query or Filter such that I get the combined column called "Note Texts" (see image below)?
If there is only one search key in the Notes column, I can use
IF(LEN(W3)>0, VLOOKUP(W3, NOTES, 2, false) , )
but now I have an arbitrary number of search keys in one column. how do I approach this without splitting and creating even more cells and then stitch them all back (adding more columns is very messy, since many other columns in my table also require the same fix).
Try this formula:
=TRANSPOSE(SPLIT(JOIN(char(10),ArrayFormula(IFERROR(VLOOKUP("["&SPLIT(JOIN("! ",A1:A4),"![",1),D1:E3,2,0),"!"))),char(10)&"!"&char(10),0))
Sample file:
https://docs.google.com/spreadsheets/d/13QFnYri6d8xvL9kXw-xAP87n1kT4wh4HwxYtHftMU9g/edit#gid=2094642927
Max's Solution works great! took me over an hour to analyse and finally understand the formula.
for my needs, I did not combine the rows and perform a single evaluation. Instead, I repeated the formula for every row using the following simplified formula (this fixes the alignment bug when there's empty rows)
= JOIN(char(10), ArrayFormula(
IFERROR(
VLOOKUP("["&SPLIT( A10 ,"[]", TRUE) &"]",NOTES,2,0),
"Error")
)
)
the following is a break down of what each part of Max's formula means.
start debugging from the inside(1) to the outside (7)
//(7) Finally, we TRANSPOSE the Columns into Rows
TRANSPOSE(
//(6) Now, we SPLIT the column up with the delimiter “\n!\n”
// that was added during Step (1)
SPLIT(
//(5) we now JOIN back all the columns, adding a new line “char(10)" before every column
JOIN(
char(10) //prepend with new line
//(4) The Magic !! ARRAYFORMULA enables the display of values returned from an array formula into multiple rows and/or columns
// Result is now displayed across multiple columns
,ArrayFormula(
IFERROR(
//(3) We can now do a VLOOKUP for each of the split search key
// (but only The first result is displayed)
VLOOKUP(
“[“ //reinsert the [ back after the split
//(2) Now, SPLIT up everything using delimiter “!”(new Row) And “[“ (new item)
& SPLIT(
//******** START FROM HERE*********
//(1) - take all the rows of interest, and then
// JOIN them together with a “!<SPACE>”
JOIN(
"! " //delimiter !<SPACE> ?
,A1:A4) //text to join (all the rows of interests)
,"![“
,TRUE) // split by each
,NOTES //Named range of interest
,2 //take second second column
,FALSE)
,”!”) // insert ! If error
) //ArrayFormula
) //JOIN
,char(10)&"!"&char(10) //delimiter "\n!\n” for split
,FALSE // do not split by each
) //SPLIT
) // TRANSPOSE

Resources