Related
I got this "table" (page raids) and want to do function formating for highlight duplicates (yellow).
Google Sheet
In this case there is match in 2 strings (dark blue):
Name1
Gunslinger
I already try functions VLOOKUP, Match, Filter, countifs and Quary (dont know how it works...) with Index function, but nothing seems work as I want ...
VLOOKUP and Match only gives first value.
Filter doesnt work on this strucker or I dont know how to use it in this case (I know how it works in normal table)
Can someone tell me what function conbination to use that can be put in Function formating ?
Formating for each row:
Example: =IF(B3>0;IF(B4<1490;TRUE;FALSE);FALSE)
ECT.
After some searching and testing, I came up with this:
=ArrayFormula(SUM(IFERROR(FIND(B2&B3;MID(CONCATENATE((TRANSPOSE($B$2:$I$33)));SEQUENCE(LEN(CONCATENATE((TRANSPOSE($B$2:$I$33))));1;1;1);len(B2&B3)))=1)*1))>1
Still need to make the functions more tidy (picture 2 and 3).
See if this is what you are looking for?
Conditional formatting with Custom formula in Range: A2:H:
=LAMBDA(NAME,OR(A1=NAME,A2=NAME,A3=NAME))("Gunslinger")
or do you means you want to highlight only duplicates?
If that is the case, you may try this formula:
=LAMBDA(DATARANGE,
LAMBDA(FLAT,
{{"Team","Duplicate"};{UNIQUE(FLAT),BYROW(UNIQUE(FLAT),LAMBDA(NAME,COUNTIF(FLAT,NAME)>1))}}
)(
QUERY(FLATTEN(
BYCOL(DATARANGE,LAMBDA(C,
BYROW(C,LAMBDA(R,
IF((ROW(R)+1)/4=INT((ROW(R)+1)/4),R,"")
))
))
),"SELECT Col1 WHERE Col1 IS NOT NULL",0)
)
)(A2:H)
This formula returns an array of unique Names with checking if there are Duplicates in the given datarange.
Combine this with the 1st formula should be able to highlight repeated data sets from your table.
Solution for 2 criteria matching:
The formula inside the image form the table of unique match results,
use that result with OR(), XLOOKUP(), OFFSET(), INDEX() as below for the final formula to put into the custom formula in conditional formatting.
=LAMBDA(RESULT,
LAMBDA(NAME,DUP,KEY,
LAMBDA(KEY_M2,KEY_M1,KEY_P1,
OR(
XLOOKUP(KEY_M2&"&&"&KEY_M1,NAME,DUP,FALSE),
XLOOKUP(KEY_M1&"&&"&KEY,NAME,DUP,FALSE),
XLOOKUP(KEY&"&&"&KEY_P1,NAME,DUP,FALSE)
)
)(IFERROR(OFFSET(KEY,-2,0),""),IFERROR(OFFSET(KEY,-1,0),""),IFERROR(OFFSET(KEY,1,0),""))
)(INDEX(RESULT,,1),INDEX(RESULT,,2),A2)
)(
LAMBDA(DATARANGE,
LAMBDA(FLATCLASS,
{{"Name","Duplicate"};{UNIQUE(FLATCLASS),BYROW(UNIQUE(FLATCLASS),LAMBDA(NAME,COUNTIF(FLATCLASS,NAME)>1))}}
)(
QUERY(FLATTEN(
BYCOL(DATARANGE,LAMBDA(C,
BYROW(C,LAMBDA(R,
IF((ROW(R)+1)/4=INT((ROW(R)+1)/4),IF(R="","",INDEX(C,ROW(R)-2)&"&&"&R),"")
))
))
),"SELECT Col1 WHERE Col1 IS NOT NULL",0)
)
)($A$2:$H)
)
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 ) ) ), " ", ", " ) )
How can I get just the text within the quotes?
Below shows each line as a cell
a:3:{i:0;s:5:"hello";i:1;s:5:"sdfsf";i:2;s:6:"orange";}
a:4:{i:0;s:5:"hello";i:1;s:3:"How";i:2;s:3:"Are";i:3;s:3:"You";}
a:6:{i:0;s:5:"apple";i:1;s:6:"papaya";i:2;s:6:"Orange";i:3;s:4:"Pear";i:4;s:6:"Banana";i:5;s:9:"Starfruit";}
a:2:{i:0;s:5:"apple";i:1;s:0:"";}
Result that I would like is:
hello,sdfsf,orange
hello,How,Are,You
apple,papaya,Orange,Pear,Banana,Starfruit
apple,
You can use re:
import re
data = """a:3:{i:0;s:5:"hello";i:1;s:5:"sdfsf";i:2;s:6:"orange";}
a:4:{i:0;s:5:"hello";i:1;s:3:"How";i:2;s:3:"Are";i:3;s:3:"You";}
a:6:{i:0;s:5:"apple";i:1;s:6:"papaya";i:2;s:6:"Orange";i:3;s:4:"Pear";i:4;s:6:"Banana";i:5;s:9:"Starfruit";}
a:2:{i:0;s:5:"apple";i:1;s:0:"";}"""
quoted = re.compile('"[^"]*"')
for row in data.split("\n"):
print(",".join(value for value in quoted.findall(row)).replace('"', ""))
This prints:
hello,sdfsf,orange
hello,How,Are,You
apple,papaya,Orange,Pear,Banana,Starfruit
apple,
In case you want to do it using formula, you can use something like this:
=ArrayFormula(TEXTJOIN(",", 1, FILTER(TRANSPOSE(SPLIT(A1, CHAR(34))), IFNA(REGEXEXTRACT(TRANSPOSE(SPLIT(A1, CHAR(34))), "^[a-zA-Z ]*$"), FALSE())<>FALSE())))
Assuming your data is in separate rows.
try:
=ARRAYFORMULA(REGEXREPLACE(TRIM(FLATTEN(QUERY(TRANSPOSE(IFERROR(IF(REGEXMATCH(
SPLIT(REGEXREPLACE(REGEXREPLACE(A1:A, "(:"")", "♂♀"), "("";)", ",♂"), "♂"), "♀"),
SPLIT(REGEXREPLACE(REGEXREPLACE(A1:A, "(:"")", "♂♀"), "("";)", ",♂"), "♂"), ))),,9^9))),
", ♀,|,$|♀", ))
There are a lot of good answers here, but if you want a formula in one cell that gives you the trailing , after apple on the last line (as per your requested output), then you could use:
=arrayformula(regexreplace(flatten(split(textjoin(",",1,if(A1:A<>"",split(regexreplace(regexreplace(A1:A,"""""",char(6655))&char(9999),".\:.|[\:\{\}\;""]","|"),"|"),)),char(9999))),"^,|,$|"&char(6655)&"",))
Assumes your data is in Col A from row 1.
If not:
=arrayformula(regexreplace(flatten(split(textjoin(",",1,if(A1:A<>"",split(regexreplace(A1:A&char(9999),".\:.|[\:\{\}\;""]","|"),"|"),)),char(9999))),"^,|,$",))
Let's say your raw data were in A2:A. You could place the following in cell B2 of an otherwise empty range B2:B ...
=ArrayFormula( IF( A2:A="",, REGEXREPLACE( TRIM( TRANSPOSE( QUERY( TRANSPOSE( IF( REGEXMATCH( SPLIT( A2:A, CHAR(34)), ":|;|\{|\}"),, SPLIT( A2:A, CHAR(34))&",")),, COLUMNS( SPLIT( A2:A, CHAR(34)))))), "\s|[\s,]+$", "")))
This one formula will produce all results for the column. No dragging involved. (Interposed spacing in the formula as shown above is only for the sake of readability here on the site; none of the spaces are actually necessary to the functionality of the formula, and you may remove them if you like.)
If you'd like to pad comma-separated list entries with a space, remove this portion from the formula: \s|.
As to how it works, this is such a custom requirement that I don't think it will be of use to any future site visitors. So I encourage you to dig into it, take it apart and see what the parts do separately and cumulatively. And if you get stuck (if understand it is even important to you at all), feel free to ask any specific question you may have.
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 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.