I seem to have an arrayformula which is generating duplicates for me.
I'll show you the code in column D and then explain the problem:
=arrayformula(
if (C1225:C$1684="A",A1225:A$1684,
if (C1225:C$1684="B",B1225:B$1684,
if (C1225:C$1684="AB",{A1225:A$1684, B1225:B$1684},""))))
If A or B, it should take the content of A or B and put it in D. So I want cell E to be blank UNLESS the content in C was "AB" - only then do I want two cells populated with the data from A and B.
At the moment it's putting out A twice.
For No One|No Reply|ab|For No One|No Reply
Across The Universe (Let It Be Naked...)|The End|a|Across The Universe (Let It Be Naked...)|Across The Universe (Let It Be Naked...)
All You Need Is Love|Twist And Shout|b|Twist And Shout|Twist And Shout
So the first row is OK, but the second two are generating unwanted duplicates.
The problem you are experiencing is because the ARRAYFORMULA is making all responses an Array of 2 items. Since the end result has this size, all results must have the same size.
Try this, changing the ranges to match your needs as well as the 10:
=arrayformula(
if (C2:C$11="A",{A2:A$11, transpose(split(rept(", ", 10), ",", TRUE))},
if (C2:C$11="B",{B2:B$11, transpose(split(rept(", ", 10), ",", TRUE))},
if (C2:C$11="AB",{A2:A$11, B2:B$11},))))
The rept(", ", 10) portion creates a text string which is ", " repeated 10 times, or ", , , , , , , , , , "
Split() then splits this into an entry for each comma, removing the comma, so a series of spaces in this case. The TRUE tells Split to do this for every occurrence of the comma, so it becomes:
split(", , , , , , , , , , ", ",", TRUE)
I then use transpose () to change this into rows instead of columns. This needs to be the same number of rows as the other items in the array I am creating using the brackets so I basically get:
{A2:A$10, [Make_Blank_Entries_For_Each_Row]}
So if I did my math correctly, you should use:
=arrayformula(
if (C1225:C$1684="A",{A1225:A$1684, transpose(split(rept(", ", 460), ",", TRUE))},
if (C1225:C$11="B",{B1225:B$1684, transpose(split(rept(", ", 460), ",", TRUE))},
if (C1225:C$11="AB",{A1225:A$1684, B2:B$11},))))
Related
This question already has an answer here:
Concatenate non empty cells in each row with arrayformula in google sheets
(1 answer)
Closed 6 months ago.
The shared sheet shows multiple column rows which can be individually concatenated horizontally with a comma & space between using TEXTJOIN(", ", TRUE, A2:D2) and blank spaces are ignored. But textjoin cannot be used in Arrayformula as far as I know and I would like ot find a suitable replacement that can also be combined as a string along with other strings of information.
I want to be able to use this as an independent formula string that might be added to other strings of information. For example, "Favorite colors: "& textjoin(", ",1,A2:D2)&"Favorite foods:"&textjoin(", ",1,E2:G2)&"...
Possible solutions
May be a variant of one of the following:
Modifying this so it could be used w/ an array formula JOIN("~", SPLIT(JOIN(CHAR(60000), B3:E3), CHAR(60000)))
Modifying this formula works with join also JOIN(", ",FILTER(H2:H,H2:H<>""))
Using a combination of IF(a2:A<>"" along with a regex replacement at the end (see my answer below) but this could be very long formula compared to textjoin if there are many columns)
An ideal solution would be concise and look closest to something this:
arrayformula(TEXTJOIN(", ", TRUE, A2:A,B2:B,C2:C)
Shared sheet is here
use:
=INDEX(REGEXREPLACE(TRIM(FLATTEN(QUERY(TRANSPOSE(IF(A2:D="",,A2:D&",")),,9^9))), ",$", ))
Using a series of IF statements, adding a delimiter and then removing any trailing delimiters can be accomplished using: Arrayformula(regexreplace(if(A2:A100<>"",A2:A100&", ","")&if(B2:B100<>"",B2:B100&", ","")&if(C2:C100<>"",C2:C100&", ","")&if(D2:D100<>"",D2:D100&", ",""),", $",""))
Use a query smush, like this:
=transpose(query(transpose(A2:D), "", 9^9))
The formula will separate values with spaces. To separate with commas and remove unwanted white space, use trim() and substitute() or regexreplace(), like this:
=arrayformula( substitute( trim( transpose( query( transpose(A2:D), "", 9^9 ) ) ), " ", ", " ) )
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))
I am trying to consolidate some data and running into a bizarre issue. I am using a query function that is working perfectly in some instances but not in other. When referencing a particular sheet, it keeps outputting the values in the row beneath, which is causing aa #REF error.
Here is a copy of the Google Sheet.
Here is the formula I'm using (which again, works perfectly sometimes, but not when pulling data from certain sheets)
=QUERY(INDIRECT($B125&"!$A$2:$1000"), "SELECT E WHERE A = date '"& text($C125, "yyyy-mm-dd") &"' and B contains '"&SUBSTITUTE(SUBSTITUTE(SUBSTITUTE($E125, " " , ""),"AM", ""), "PM", "")&"' ")
You need to specify the number of headers otherwise it will try to guess which eventually results in rows being magically merged into the header causing all sorts of unpredictable behavior:
=QUERY(INDIRECT($B125&"!$A$2:$1000"), "SELECT E WHERE A = date '"& text($C125, "yyyy-mm-dd") &"' and B contains '"&SUBSTITUTE(SUBSTITUTE(SUBSTITUTE($E125, " " , ""),"AM", ""), "PM", "")&"' ",1)
All I did was add a ,1 just before the closing parenthesis so that it specifies always 1 row of headers. The format of your data is really messed up and you need to think about cleaning up your data.
I would like to use a formula to capitalize just the first letter of an array of words. Sometimes the array might have just 1 word, and sometimes 2, 3, 4 or more words. The source is dynamic, so I need my formula to be flexible. I know about Proper(text), but that capitalizes every word.
For example, in cell A1 I might have the text "aidan is a good boy,"
or I might just have "hi,"
or maybe it will say, "drive in your own lane please!"
My formula over in B1 needs a result of "Aidan is a good boy,"; "Hi,"; or "Drive in your own lane please!"
I wish I could say, B1: =Proper(index(split(M1, " "), 1)) & " " & lower(index(split(M1, " "), *everything except 1*)), but I don't know how to fill in the *everything except 1* part of the formula.
Please try:
=REPLACE(A1,1,1,UPPER(left(A1)))
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.