Is there recommended ways to convert table in A2:F6 to H2:K10?
Thanks.
Here is the sample Google Sheet https://docs.google.com/spreadsheets/d/1QOZVMIRvM_9lhvAflhQtA9H6KOpfHycPo5qgF1y-GzA/edit?usp=sharing
There is a relatively simple way to do than using FLATTEN:
={
ARRAYFORMULA(A1:C1), "Product";
ARRAYFORMULA(
VLOOKUP(
FILTER(
FLATTEN(ROW(D2:F) + 0 * ISBLANK(D2:F)),
FLATTEN(D2:F <> "")
),
FILTER(
{ROW(A2:A), A2:C},
A2:A <> ""
),
{2, 3, 4},
0
)
),
FILTER(
FLATTEN(D2:F),
FLATTEN(D2:F <> "")
)
}
Not sure why ARRAYFORMULA(ROW(D2:F)) gives row wise row numbers and not a 2d matrix with the row numbers. Could've remove 0 * ISBLANK(D2:F) otherwise...
Please use the following query formula:
=QUERY(QUERY({A:D;A2:C,E2:E;A2:C,F2:F},"where Col1 is not null order by Col1"), "where Col4 is not null")
Functions used:
QUERY
Related
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)
Trying to combine range E4:I into J4:J with the Array Formula of:
=ArrayFormula( regexreplace( regexreplace( transpose( trim( query( transpose( regexreplace( trim( E4:I ) , " " , "~" ) ) ,, 9^99 ) ) ) , " " , ", " ) , "~" , " " ) )
This formula works well but I want to exclude duplicates in each row.
Here is a link to the sheet. Link
You can try this modified formula from a similar post:
=INDEX(
REGEXREPLACE(SORT(
SPLIT(
TRANSPOSE(QUERY(
QUERY(
UNIQUE(
SPLIT(
FLATTEN(
ROW(E2:I11) & "♦♥" & E2:I11
), "♥"
) & ", "
),
"SELECT MAX(Col2)
WHERE Col2 IS NOT NULL
GROUP BY Col2
PIVOT Col1",
),,99
)),"♦"
), 1, TRUE),
"^(?:,\s*)+|(?:,\s*)+$|(,\s)\s*(?:,\s*)*",
"$1"
),,2)
Output:
Note:
Output is automatically sorted alphabetically
You can change E2:I11 to E2:I but it will be slower than limiting your range. If you have a column that can identify until what row is populated, add an IF statement and limit your formula to only process those rows.
Reference:
https://stackoverflow.com/a/67837006/17842569
I need the range values to go from A:A, B:B, ..., [Current Column]. it needs to be dynamic for multiple columns, i.e Column D be =MAX(A:A, B:B, C:C), while Column E will be =MAX(A:A, B:B, C:C, D:D).
=MAX(COUNTIF(A:A, “*Text*”), COUNTIF(B:B, “*[Text String]*”), ..., [until current COLUMN() - 1])
Or something like
=MAX(
Loop ( COLUMN() - 1 )
{
COUNTIF(
INDIRECT(
ADDRESS(3, [Loop Iteration]) & ":" & ADDRESS([Dynamic Number], [Loop Iteration])
)
, “*[Text String]*” )
}
)
dragging solution:
=MAX(INDIRECT(ADDRESS(3, 1)&":"&ADDRESS(ROWS(A3:A), COLUMN()-1)))
non-dragging automated solution:
=INDEX(QUERY(QUERY(SPLIT(FLATTEN(COLUMN(A:E)&"×"&IFNA(HLOOKUP(
IF(FLATTEN(COLUMN(A:E)-1)>=COLUMN(A:E),,COLUMN(A:E)-(FLATTEN(COLUMN(A:E))-1)),
QUERY(SPLIT(FLATTEN(IF(A3:E="",, COLUMN(A:E)&"×"&A3:E)), "×"),
"select max(Col2) pivot Col1")*1, 2, 0))), "×"),
"select max(Col2) pivot Col1"), "offset 1", 0))
I am trying to execute the following in google sheets by repeating certain cell values from a range of cells (number of repetitions) and iterating it horizontally till the end of the row.
Formula used for current output:
={ARRAYFORMULA(TRIM(TRANSPOSE(SPLIT(QUERY(REPT(A1&",",A2:A4 ), ,999^99), ","))));ARRAYFORMULA(TRIM(TRANSPOSE(SPLIT(QUERY(REPT(C1&",",C2:C4 ), ,999^99), ","))));ARRAYFORMULA(TRIM(TRANSPOSE(SPLIT(QUERY(REPT(E1&",",E1:E4 ), ,999^99), ","))))}
use:
=ARRAYFORMULA(FLATTEN(SPLIT(TEXTJOIN("×", 1,
REPT({A1&"×", C1&"×", E1&"×"}, {A2:A, C2:C, E2:E})), "×")))
shorter:
=INDEX(FLATTEN(SPLIT(TEXTJOIN("×", 1,
REPT({A1, C1, E1}&"×", {A2:A, C2:C, E2:E})), "×")))
update:
=INDEX(QUERY(FLATTEN(SPLIT(QUERY(FLATTEN(QUERY(FLATTEN(
REPT("×"&{A1, C1, E1}&"×", {A2:A, C2:C, E2:E})),,9^9)),,9^9), "×")),
"where not Col1 starts with ' '"))
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), "")
)
)