Formula Help: IF, Countif, Split. Override - google-sheets

I am currently running the following formula
=IF(P202="","",COUNTIF(SPLIT(P202," "),"*XXX*")+COUNTIF(SPLIT(P202," "),"*YYY*"))
This is to count the values XXX & YYY in column P. This returns values 0 - 4 primarily in column AC
However I have another column. Which is column W, in this column I have values such as 'cancelled' and 'postponed'.
What I would like to happen, as an example the above formula returns a value of 2 but if Column W was updated with cancelled. Then that value would alter the return to 0 as the event is now cancelled.
Thanks

try:
=INDEX(IF(P202="",,SUM(IFERROR(REGEXMATCH(""&
IF(W202="canceled", 0, SPLIT(P202, " ")), "(?i)xxx|yyy"), 0)*1
for array try:
=INDEX(IF(P202:P="",,MMULT(IFERROR(REGEXMATCH(""&
IF(W202:W="canceled", 0, SPLIT(P202:P, " ")), "(?i)xxx|yyy"), 0)*1,
SEQUENCE(COLUMNS(SPLIT(P202:P, " ")), 1, 0

Related

Arrayformula to replace sumifs based on criteria - grouping data into categories/types

In this spreadsheet
Cols G and H give the total of each Account Type, from the data (A1:D)
If sum Dr - sum Cr > 0, then only this is shown in col G.
=if(sumifs(C:C,A:A,F2)-sumifs(D:D,A:A,F2)>0, sumifs(C:C,A:A,F2)-sumifs(D:D,A:A,F2),"")
If sum Cr - sum Dr > 0, then only this is shown in col H
=if(sumifs(D:D,A:A,F2)-sumifs(C:C,A:A,F2)>0, sumifs(D:D,A:A,F2)-sumifs(C:C,A:A,F2),"")
I am looking for an array formula which replaces these summifs formula, so that if either new Account Types (e.g. Type E, Type F etc) are added or new rows of data are added, then the formula would automatically calculate the sum Dr or sum Cr, instead of having to copy the formula down
try this in cell G2:
=BYROW(F2:F,LAMBDA(fx,IF(fx="",,LAMBDA(cx,dx,{IF(cx-dx>0,cx-dx,),IF(dx-cx>0,dx-cx,)})(SUMIF(A:A,fx,C:C),SUMIF(A:A,fx,D:D)))))
-
Use query(), like this:
=arrayformula(
lambda(
aggregated,
lambda(
account, balance,
{
"Account Type", "Dr", "Cr";
account,
if( balance >= 0, balance, iferror(1/0) ),
if( balance < 0, -balance, iferror(1/0) )
}
)(
query(aggregated, "select Col1", 0),
query(aggregated, "select Col2", 0)
)
)(
query(
A3:D,
"select A, sum(C) - sum(D)
where A is not null
group by A
label sum(C) - sum(D) '' ",
0
)
)
)
You can set a QUERY that finds both entire columns like this:
=QUERY(A2:D,"SELECT A,SUM(C)-SUM(D),SUM(D)-SUM(C) where A is not null group by A",1)
And check with LAMBDA if there are negative values and change them to null:
=LAMBDA(a,INDEX(IF(a<0,,a)))(QUERY(A2:D,"SELECT A,SUM(C)-SUM(D),SUM(D)-SUM(C) WHERE A is not null group by A",1))
If the values in your result table are just for display, you can use the QUERY format clause to hide negative values, such that the whole thing can be generated within a single QUERY:
=QUERY(A2:D,"select A,sum(C)-sum(D),sum(D)-sum(C) where A is not null group by A label sum(C)-sum(D) 'Dr',sum(D)-sum(C) 'Cr' format sum(C)-sum(D) '0;',sum(D)-sum(C) '0;'",1)

Index and Concat / Concatenate from another sheet

I have a data sheet which i want to index pull into another sheet and also concanate or concat 2 or more columns with array formula.
sheet link here
https://docs.google.com/spreadsheets/d/1GUI-Gl7HDNGg5V2wM4ossUn46cp7VHRBZ_t4la2gDH0/edit?usp=sharing
data sheet https://docs.google.com/spreadsheets/d/1GUI-Gl7HDNGg5V2wM4ossUn46cp7VHRBZ_t4la2gDH0/edit#gid=0
result required sample sheet https://docs.google.com/spreadsheets/d/1GUI-Gl7HDNGg5V2wM4ossUn46cp7VHRBZ_t4la2gDH0/edit#gid=1226812843
you can see in result sheet column B and F which are merged from "data sheet column b c d and h i simultaneously"
Use an { array expression }. Insert > Sheet and put this formula in cell A1 of the new sheet:
=arrayformula(
{
DATA!A1:A,
trim(
DATA!B1:B & " " &
if( iserror(search(DATA!C1:C, DATA!B1:B)), DATA!C1:C, "" ) & " " &
if( iserror(search(DATA!D1:D, DATA!B1:B)), DATA!D1:D, "" )
),
DATA!E1:G,
trim(DATA!H1:H & if(len(DATA!I1:I), " / " & DATA!I1:I, "")),
DATA!J1:U
}
)
The formula will only append the values in columns C and D to the value in column B when they do not not already appear in the value in column B.
the prior answer is ok but did you know...
so your issue can be solved as:
=BYROW(DATA!A2:INDEX(DATA!A:A, COUNTA(DATA!A:A)),
LAMBDA(a, {a, TEXTJOIN(" ", 1, OFFSET(a,,1,,3)), OFFSET(a,,4,,3),
TEXTJOIN(" / ", 1, OFFSET(a,,7,,2)), OFFSET(a,,9,,11)}))

Count every nth block of rows and cells

Given I have the following sheet data
What I'm trying to do is count the amount of times Yes appears in each column.
So, I'm looking for something like
Header 1:
B: 1
C: 1
D: 0
Header 2:
B: 1
C: 4
D: 1
Header 3:
B: 2
C: 1
D: 0
I've tried looking at using MOD and with the formula
=ARRAYFORMULA(MOD((ROW(B1:B14)), 5))
I can get the index, then maybe do some offset? The above formula prints
1
2
3
4
0
1
2
3
4
0
1
2
3
4
I'm not too sure where to go from here though.
Desired output
EDIT
Based on the accepted answer, I amended the formula slightly. This was because the cell in A wasn't guaranteed to be empty if it wasn't a header, so I used a REGEXMATCH
=
ArrayFormula(
query(
{
if(mod(row('Runs 93 - 300'!H:H), 14) = 0,
"",
vlookup(row('Runs 93 - 300'!H:H), {
if(regexmatch('Runs 93 - 300'!H:H, "RUN #\d+"), row('Runs 93 - 300'!H:H)),
'Runs 93 - 300'!H:H
}, 2)
),
if('Runs 93 - 300'!M:Q="Yes",1,)
},
"select Col1,count(Col2),count(Col3),count(Col4),count(Col5), count(Col6) where Col1 is not null group by Col1 label count(Col2) '',count(Col3) '',count(Col4) '', count(Col5) '', count(Col6) ''"
)
)
This does make the first cell in the formula output #RUN 300 #RUN 300 but I can accept that.
You can use Vlookup to copy the header down through the rows that are blank in column 1, then use a Group By query to do the counts:
=ArrayFormula(query({if(mod(row(A:A),5)=0,"",vlookup(row(A:A),{if(A:A<>"",row(A:A)),A:A},2)),if(B:D="Yes",1,)},"select Col1,count(Col2),count(Col3),count(Col4) where Col1 is not null group by Col1 label count(Col2) '',count(Col3) '',count(Col4) ''"))
You could avoid doing a Vlookup on every row (or rather four out of five rows) by limiting it to the rows where the data is:
=ArrayFormula(query({if(row(A:A)>counta(A:A)*5,"",vlookup(row(A:A),{if(A:A<>"",row(A:A)),A:A},2)),if(B:D="Yes",1,)},"select Col1,count(Col2),count(Col3),count(Col4) where Col1 is not null group by Col1 label count(Col2) '',count(Col3) '',count(Col4) ''"))
You can try this too:
={filter(A:A,A:A<>""),index(transpose(len(array_constrain(trim(RegexReplace(split(transpose(query(B:D,,9^9))," ",0),"No|\s",)),9^9,3))/3))}

Is there a better way to replicate a column array n times in Google Sheets

I need to formulaic solution to copy a column range stacking on top of itself a given number of times. I found one ugly solution by incorporating a sequence function (to get 1,2,3...n) into an arrayformula for a text operation (Left). The Left operation does nothing but return the original value, but gives me the opportunity to include the sequence array.
There must be a better way to do this.
Problem: Write a formula that creates a column where a named column range is stacked on top of each other an arbitrary number of times. Must be a single formula as other users will need this to self adjust to a new length automatically.
=flatten( transpose( arrayformula( left( Column_Range,len( Column_Range ) + 0 *
sign( sequence( 1,Number_of_Times_To_Repeat ) ) ) ) ) )
could be written as:
=ARRAYFORMULA(FLATTEN(TRANSPOSE(LEFT(A1:A5, LEN(A1:A5)*SIGN(SEQUENCE(1, C1))))))
or:
=INDEX(FLATTEN(TRANSPOSE(LEFT(A1:A5, LEN(A1:A5)*SIGN(SEQUENCE(1, C1))))))
or:
=INDEX(FLATTEN(TRANSPOSE(LEFT(A1:A5, LEN(A1:A5)*TRANSPOSE(ROW(INDIRECT("A1:A"&C1))^0)))))
or:
=INDEX(FLATTEN(TRANSPOSE(LEFT(A1:A5, LEN(A1:A5)*TRANSPOSE(SIGN(ROW(INDIRECT("A1:A"&C1))))))))
or:
=INDEX(FLATTEN(TRANSPOSE(LEFT(A1:A5, LEN(A1:A5)*SPLIT(REPT(1&"♀", C1), "♀")))))
or:
=INDEX(FLATTEN(TRANSPOSE(LEFT(A1:A5, LEN(A1:A5)*COLUMN(INDIRECT("A1:"&ADDRESS(1, C1)))^0))))
or:
=QUERY(FLATTEN(SPLIT(REPT("♀"&JOIN("♀", A1:A5), C1), "♀",,)), "offset 1")
or:
=FLATTEN(SPLIT(REPT(QUERY(A1:A5,,9^9)&" ", C1), " ",,))
Solution 1
Here is a way without FLATTEN:
=ARRAYFORMULA(
VLOOKUP(
1 + MOD(
SEQUENCE(C1 * MAX(ROW(A:A) * (A:A <> ""))) - 1,
MAX(ROW(A:A) * (A:A <> ""))
),
{ROW(A:A), A:A},
2,
0
)
)
MAX(ROW(A:A) * (A:A <> "") inside ARRAYFORMULA just gives you the row number of the last non-empty cell. The rest is quite straightforward.
Solution 2
And here is a FLATTEN solution without LEFT:
=FLATTEN(
ARRAYFORMULA(
ARRAY_CONSTRAIN(
TRANSPOSE(A:A),
1,
MAX(ROW(A:A) * (A:A <> ""))
) & IF(SEQUENCE(C1), "")
)
)

How can I create a range display from a list of non consecutive numbers?

I made a bash script to display numbers in range and I wonder if it's possible to do the same in Sheets without scripting.
I got in a column (let's say A) a list of numbers, for example :
001
002
004
012
013
014
...
and I have a variable prefix in a cell (let's say B1="PREFIX")
Is there a way to display the result as below :
PREFIX001-PREFIX002
PREFIX004
PREFIX012-PREFIX014
...
Thank you by advance for your help !
Could be done. For example A3:A range has the numbers, B1 will be the prefix and B3:B will have the resulting rows.
The formula is only (as it is an array formula) in B3:
=ARRAYFORMULA(
TRANSPOSE(SPLIT(
REGEXREPLACE(
REGEXREPLACE(
TEXTJOIN(
",",
True,
IF(
NOT(ISNUMBER(A3:A)),
"",
IF(
NOT(ISNUMBER({""; OFFSET(A3:A, 0, 0, ROWS(A3:A) - 1)}))
+ NOT(ISNUMBER({A4:A; ""}))
+ ( ISNUMBER({""; OFFSET(A3:A, 0, 0, ROWS(A3:A) - 1)})
* (A3:A <> {""; OFFSET(A3:A, 0, 0, ROWS(A3:A) - 1)} + 1))
+ ( ISNUMBER({A4:A; ""})
* (A3:A <> {A4:A; ""} - 1)),
TEXT(A3:A, "00#"),
""
)
)
& IF(
ISNUMBER({A4:A; ""})
* (A3:A = {A4:A; ""} - 1),
"-",
""
)
),
"(?:-,)+",
"-"
),
"\d+",
B1 & "$0"
),
","
))
)
Here is a sample sheet with step by step description of the solution: link.
#kishkin
Thank you so much for taking the time to do that ! I made a copy to check it, that's very kind of you !
I made mine with multiple columns but in the nasty way (I'm quite new with Sheets but I love it so far) :
to group consecutive numbers :
=IF(CNUM(V2)=CNUM(V1)+1,IF(REGEXMATCH(W1,"-"),LEFT(W1,CHERCHE("-",W1)-1)&"-"&V2,V1&"-"&V2),V2)
to replace lonelies that are part of a range :
=IF(LEFT(W3,2)=LEFT(W2,2),0,W2)
Split the range to calculate range value later :
=SPLIT(X2,"-")
To calculate the range except for 0 values :
=IF(Z2-Y2+1<0,1,Z2-Y2+1)
To remove all the 0 so only the ranges remain :
=filter(X2:X,X2:X>0)
To align the totals with the ranges (useful for group reservations for a project)
=filter(AA2:AA,X2:X>0)
After that, it's just adding the prefix and add some text (sorry for the french).
As I told you it's not as sexy as your solution ^^

Resources