Given a long spreadsheet table, is there a function to wrap it (break it) into multiple column tables?
What I tried
=query(dataTable, "select A, B limit "&floor(ROWS(dataTable)*0.5))
=query(dataTable, "select A, B offset "&floor(ROWS(dataTable)*0.5))
but maybe there is a better solution, especially that it is not flexible in the number of columns (e.g: I want the table to be distributed on 3 or 4 tables not 2).
One other problem is if the input table is created using query, and that query is changed to include additional columns, the cells where they include =query(dataTable, "select ... must be separated more to give space.
especially that it is not flexible in the number of columns
you can skip the select like:
=QUERY(dataTable, "limit "&FLOOR(ROWS(dataTable)*0.5))
=QUERY(dataTable, "offset "&FLOOR(ROWS(dataTable)*0.5))
but maybe there is a better solution
you can use single formula:
={QUERY(dataTable, "limit "&FLOOR(ROWS(dataTable)*0.5)),
QUERY(dataTable, "offset "&FLOOR(ROWS(dataTable)*0.5))}
just make sure total rows are divisible by 2
UPDATE:
=ARRAYFORMULA(SUBSTITUTE(TRIM(SPLIT({REPT(TEXTJOIN(, 1, A1:D1&"×"), F1);
FLATTEN(QUERY(TRANSPOSE(IFNA(VLOOKUP(
TRANSPOSE(SEQUENCE(F1, ROUNDUP(MAX(IF(A:A="",,ROW(A:A)))/F1))),
{ROW(A2:A)-1, FLATTEN(QUERY(TRANSPOSE(IF(A2:D="", "♀×", A2:D&"×")),,9^9))},
2, ))),,9^9))}, "×", 1, )), "♀", ))
spreadsheet demo
Related
I believe what I am trying to do should be simple in Google Sheets formulae, but any solution based on an Excel formula should be easily transferable.
Because additional characters will be added periodically, I have a named range: "Heroes".
Heroes
Bilbo
Gandalf
Saruman
Wormtongue
Tom Bombadil
For each hero, I have a worksheet in one overall workbook. On these worksheets, there are columns for Date, Time, Quest, and Count. Several times per day, a hero will venture out on a quest of a certain type, returning with a certain count as a prize. Each venture has its own row distinguishable by date and time. Eg-:
Date
Time
Quest
Count
12/4
3:00P
Ring
9
12/5
8:00A
Mordor
6
12/5
4:15P
Sting
3
Meanwhile, I have a summary worksheet, on which I am manually entering (for now... bonus points to help create an =arrayformula() or equivalent to grab all unique date/time combinations from each character's worksheet) the date and time at which one or a batch of heroes are sent to quest. I am trying to figure out the formula template that will sum the counts for each quest type for each hero at the specific date and time signified by its corresponding row (starting at 12/4, 3:00P, Ring, the count should be 9, for example, which is Bilbo's prize for questing at that time; of course, other heroes are also sent out at 3:00P, resulting in prizes for the other quests, and multiple heroes may venture on the same type of quest at any given time):
Date
Time
Ring
Sting
Mordor
Moria
12/4
3:00P
9
3
4
1
12/4
9:30P
1
0
8
0
12/5
8:00A
5
3
6
9
12/5
12:10A
3
1
3
8
12/5
4:15P
4
5
2
5
Since not every date and time in the summary sheet will exist on each hero's worksheet, I seem unable to use "SUMIFS", which functions in such a way that each sum_range and criteria_range are added on only across the same row when conditions are met. I think there is a SUMPRODUCT(), or INDEX(MATCH()) way to do this, but when including the named range to read across multiple worksheets, only the first hero's numbers were added in my tinkering with this.
I'm dancing around the solution here. Anyone care to tango ? Many thanks !
Sample Workbook for support: https://docs.google.com/spreadsheets/d/142IE9r2ip6YHsGdMr-zt_IHd6W7glqUId_UiGQnCUZs/edit?usp=sharing
it would be done like this:
=QUERY({Bilbo!A:D; Gandalf!A:D; Saruman!A:D; Wormtongue!A:D; 'Tom Bombadil'!A:D},
"select Col1,Col2,sum(Col4) where Col1 is not null group by Col1,Col2 pivot Col3", 1)
if you want a specific order of places you can do:
=TRANSPOSE(SORT(TRANSPOSE(QUERY(
{Bilbo!A:D; Gandalf!A:D; Saruman!A:D; Wormtongue!A:D; 'Tom Bombadil'!A:D},
"select Col1,Col2,sum(Col4) where Col1 is not null
group by Col1,Col2 pivot Col3", 1)),
MATCH(FLATTEN(QUERY(QUERY(
{Bilbo!A:D; Gandalf!A:D; Saruman!A:D; Wormtongue!A:D; 'Tom Bombadil'!A:D},
"select Col1,Col2,sum(Col4) where Col1 is not null
group by Col1,Col2 pivot Col3", 1), "limit 0", 1)),
{"Date"; "Time"; "Ring"; "Sting"; "Mordor"; "Moria"}, ), 1))
or manually like this:
=QUERY(QUERY({Bilbo!A:D; Gandalf!A:D; Saruman!A:D; Wormtongue!A:D; 'Tom Bombadil'!A:D},
"select Col1,Col2,sum(Col4) where Col1 is not null group by Col1,Col2 pivot Col3", 1),
"select Col1,Col2,Col5,Col6,Col3,Col4")
if you thinking to outsmart it with the list of Heroes... don't. referring a range from other sheets requires the usage of INDIRECT. and surprise surprise, INDIRECT is not supported under ARRAYFORMULA so you cant build an array. at this point, you either re-think your life choices or you use a script where there is support for such indirected arrays. the best you can do without script is to hardcode it like:
=QUERY({
INDIRECT(Main!A2&"!A:D");
INDIRECT(Main!A3&"!A:D");
INDIRECT(Main!A4&"!A:D");
INDIRECT(Main!A5&"!A:D");
INDIRECT(Main!A7&"!A:D")},
"select Col1,Col2,sum(Col4) where Col1 is not null
group by Col1,Col2 pivot Col3", 1)
and ofc this will only work if sheet exists on the list and list does not contain empty cells otherwise you will get ARRAY error like this because Main!A6 sheet does not exist:
so to counter it we can do some slide of hand tricks with IFERROR which will allow us to not get the error and still use non-existent sheets and even empty cells so we can pre-program it for future additions like this:
=QUERY({
IFERROR(INDIRECT(IF(Main!A2="", 0, Main!A2)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A3="", 0, Main!A3)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A4="", 0, Main!A4)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A5="", 0, Main!A5)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A6="", 0, Main!A6)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A7="", 0, Main!A7)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A8="", 0, Main!A8)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A9="", 0, Main!A9)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A10="", 0, Main!A10)&"!A:D"),{"","","",""});
IFERROR(INDIRECT(IF(Main!A11="", 0, Main!A11)&"!A:D"),{"","","",""})},
"select Col1,Col2,sum(Col4) where Col1 is not null
group by Col1,Col2 pivot Col3", 1)
note: 4 columns in range A:D = 4 empty cells {"","","",""}
I am trying to transpose data from column A to single rows. The original data has 3 rows for each name. But there could be either 1 or several jobs for each day. Each day needs to be treated separately, but this maybe best handled by manually adding at the beginning of each day.
This is for a fortnightly timesheet, therefore the number of rows in unpredictable.
The 1st image is my original data. the 2nd is the desired end result.
The data is to transposed to any blank rows in columns b, c, d, e,
as long as there are no blank rows, I can then reference them with my formulas.
to place the information into the appropriate cells within
the timesheet. I already have working formulas to do this.
the transpose section is what I need help with
Here is a link to my file
https://docs.google.com/spreadsheets/d/1PhuFXDB2H1c9ua6szjhJEgJR91yXHhZAmn_2UGOBvIo/edit?usp=sharing
try:
=ARRAYFORMULA({QUERY(IF(REGEXMATCH(A12:A, "\d+:\d+.*"), VLOOKUP(ROW(A12:A),
IF(IF(IFERROR(RIGHT(A12:A, 4)*1)>2000, A12:A, )<>"", {ROW(A12:A),
IF(IFERROR(RIGHT(A12:A, 4)*1)>2000, A12:A, )}), 2, 1), ), "where Col1 is not null"),
QUERY(IF((IFERROR(RIGHT(A12:A, 4)*1)>2000)+(REGEXMATCH(A12:A, "\d+:\d+.*")),, A12:A),
"where Col1 is not null skipping 2"),
QUERY(QUERY(IF((IFERROR(RIGHT(A12:A, 4)*1)>2000)+(REGEXMATCH(A12:A, "\d+:\d+.*")),, A12:A),
"where Col1 is not null offset 1", 0), "skipping 2"),
FILTER(A12:A, REGEXMATCH(A12:A, "\d+:\d+.*"))})
If you want a solution with a formula in one cell only, try:
=arrayformula({"date","name","job type","start - end time";query(split(flatten(query(iferror(datevalue(A12:A),),"where Col1 is not null",0)&split(flatten(split(textjoin(char(9999),1,if(regexmatch(to_text(A12:A),":+.*-+"),A12:A&char(9998),if(iferror(datevalue(A12:A),)<>"",char(10001),A12:A))),char(10001))),char(9998))),char(9999)),"where Col2 is not null",0)})
in put B12 :
=IFERROR(if(FIND("2021",A12)>=1,0,""),B11+1)
in put C12 :
=if(B12=0,A12,C11)
in D12 :
=if(mod(B12,3)=1,TRANSPOSE(A12:A14),"")
and drag downwards. Then in F12 put :
=FILTER(C:F,F:F<>"")
and drag downwards.
Idea : use transpose() with a conditional counter. use (F12)filter to remove blank.
Please if it works/understandable/not.
I am attempting to get the column to essentially lookup any submissions and only take into account the ones that apply to the numbers in column B. If any of the form submissions match the number in the respective row in Column B then I want it to essentially add the 1 to Column B. This is the formula that I've used but it doesn't seem to be working as I'd hoped it would.
=arrayformula(if(isnumber(B2:B150),countifs('Activity Logs'!E4:E,B2:B150,month('Activity Logs'!E4:E),month(edate(today(),-0)),year('Activity Logs'!E4:E),YEAR(edate(today(),-0))),))
Here's the spreadsheet: https://docs.google.com/spreadsheets/d/1T6TUzySQTLzjMni9ZyDWOFs6YnRqSwtzJ317ilJ0Y0Q/edit?usp=sharing
use in M9:
={""; ARRAYFORMULA(IFNA(VLOOKUP($B$10:$B, QUERY(
FILTER('Activity Logs'!$E$5:$E, MONTH('Activity Logs'!$C$5:$C)=MONTH(M5&1)),
"select Col1,count(Col1) group by Col1"), 2, 0)))}
Have been researching several places for a solution and found something that quasi works but doesn't work in the ArrayFormula for Sheets. I have data in a single column as an example below. It's a combination of letters and text but would otherwise been sortable when parsed. The goal is to populate the cell with the single most recent event (as measured by the highest number at the end of the string). The value "Sprint" is consistent text. This formula seems to work for that purpose, however, I would ideally like this to work within the ArrayFormula so that it would adjust and populate with the data rows it's referencing which is dynamic. Thanks in advance.
TRIM(CHOOSE(1,SPLIT(JOIN(";",SORT(TRANSPOSE(SPLIT([#CELL],";",FALSE)),1,FALSE)),";")))
Below is a sample set of data:
Sprint 1
Sprint 2
Sprint 3
Sprint 3;Sprint 1
Sprint 1;Sprint 2
try:
=ARRAYFORMULA(B1&" "&QUERY(TRANSPOSE(QUERY(TRANSPOSE(
REGEXREPLACE(IFERROR(SPLIT(B2:B, ";")), "\D+", )*1),
"select "&TEXTJOIN(",", 1, IF(B2:B<>"",
"max(Col"&ROW(B2:B)-ROW(B2)+1&")", ))&"")),
"select Col2"))
UPDATE:
=ARRAYFORMULA(IF(REGEXMATCH(B2:B, B1),
B1&" "&QUERY(TRANSPOSE(QUERY(TRANSPOSE(
REGEXREPLACE(IFERROR(SPLIT(B2:B, ";")), "\D+", )*1),
"select "&TEXTJOIN(",", 1,
"max(Col"&ROW(B2:B)-ROW(B2)+1&")")&"")),
"select Col2"), ))
I'm wondering if there is a decent way to do this (without scripts) - if not, I can attempt creating a script for it but some users of this sheet will be using Excel on their computers so I'm trying to keep it scriptless as much as possible.
I have a sheet set up to display text based on certain conditions that is meant to be copied and pasted into an external program.
There is a column for months jan-dec and a column next to that where the user can input a number from 1-10 (and those numbers are associated with strings that are found with Vlookup on another sheet. They're basically "error codes" just to keep the sheet clean. But I'm just omitting this part because it's not needed for this question)
Right now, the text that populates shows:
Jan: 1
Feb: 2
Apr: 1
How could I group these by the value instead of listing them separately? Something like:
1: Jan, Apr
2: Feb
Is it possible to grab the items from that months list and put them in their own lists?
This is the current formula for reference:
=if(countif(Calculator!B2:B13,">0"),CONCATENATE(C2:C13),"None")
(Calculator sheet)B2:B13 --> column with the numbers
(Data sheet)C2:C13 --> a concatenated string that contains the month name from one cell and the number (or technically the string associated with that number as I mentioned before)
Each cell in the C column has the Jan: 1, Feb: 2 data and any month without data is left blank. When I concatenate the C cells together, it automatically omits the blank cells which is helpful but now I'd really like to group them by that value instead.
Here is the example sheet that reflects this
delete A15 and paste this in A14:
={""; ARRAYFORMULA(TEXTJOIN(CHAR(10), 1, REGEXREPLACE(TRIM(
TRANSPOSE(QUERY(QUERY({A2:A13&",", B2:B13&":"},
"select max(Col1)
where not Col2 matches ':'
group by Col1
pivot Col2"),,9^9))), ",$", )))}
UPDATE:
if order matters...
={""; ARRAYFORMULA(TEXTJOIN(CHAR(10), 1, REGEXREPLACE(TRIM(
TRANSPOSE(QUERY(QUERY({"♦"&ROW(A2:A13)&"♦"&A2:A13&",", B2:B13&":"},
"select max(Col1)
where not Col2 matches ':'
group by Col1
pivot Col2"),,9^9))), "♦\d+♦|,$", )))}
UPDATE:
={""; ARRAYFORMULA(JOIN(CHAR(10), SUBSTITUTE(REGEXREPLACE(TRIM(QUERY(QUERY({
SORT(FILTER({SUBSTITUTE(A1:A12, "'", "/"&20)*1, B1:B12&":"}, B1:B12<>""), 2, 1, 1, 1)},
"select max(Col1)
group by Col1
pivot Col2
format max(Col1) 'Mmm♦yy,'"),,99^99)), ",$", ), "♦", CHAR(39))))}