Reputation: 135
I have a row which look like this:
|Data A-1|Data A-2|Data A-3|Data A-4|Data A-5|Data A-6|Data B-1|Data B-2|Data B-3|Data B-4|Data B-5|Data B-6|Data C-1|Data C-2|Data C-3|Data C-4|Data C-5|Data C-6|
There are 5 columns that are related to each Data. I need to convert all the data in a row into fix rows and columns which look like this:
|Data A-1|Data A-2|Data A-3|Data A-4|Data A-5|Data A-6|
|Data B-1|Data B-2|Data B-3|Data B-4|Data B-5|Data B-6|
|Data C-1|Data C-2|Data C-3|Data C-4|Data C-5|Data C-6|
How can I achieve this in Google Sheets?
Upvotes: 2
Views: 1214
Reputation: 201408
In your case, I thought that this thread might be able to be used.
For the goal in your question, how about the following sample formula?
=ARRAYFORMULA(TRIM(SPLIT(TRANSPOSE(SPLIT(REGEXREPLACE(TEXTJOIN(",",TRUE,A1:1),"(([\w\s\S]+?,){6})","$1@"),"@")),",")))
A1:1
is used as the range. But when you have several rows, please modify the range. And, the row is splitted by 6 column. So (([\w\s\S]+?,){6})
is used as the regex.TEXTJOIN
.@
to the joined text value for 6 columns using REGEXREPLACE
.@
using SPLIT
.TRANSPOSE
.,
using SPLIT
.For your shared Spreadsheet, how about the following sample formula?
=ARRAYFORMULA(TRIM(SPLIT(TRANSPOSE(SPLIT(REGEXREPLACE(TEXTJOIN(",",TRUE,A8:8),"(([\w\s\S]+?,){8})","$1@"),"@")),",")))
A8:8
is used as the range. But when you have several rows, please modify the range. And, the row is splitted by 8 column. So (([\w\s\S]+?,){8})
is used as the regex.In this case, because of REGEXREPLACE(TEXTJOIN(",",TRUE,A8:8),"(([\w\s\S]+?,){8})","$1@")
, when the characters are over 50,000, an error occurs. In that case, I would like to propose to use the Google Apps Script as the custom function. The sample script is as follows. Please copy and paste the following script to the script editor of Spreadsheet, and put =SAMPLE(A8:8, 8)
to a cell when your shared Spreadsheet is used. In this case, the arguments of A8:8
and 8
are the range and the splitted number, respectively. By this, your goal can be achieved.
const SAMPLE = (values, split) => values.flatMap(r => {
const temp = [];
while (r.length > 0) temp.push(r.splice(0, split));
return temp
});
About your additional question by your comment as follows,
Is there any way to make the first column to be sorted?
how about the following sample formula?
=SORT(ARRAYFORMULA(TRIM(SPLIT(TRANSPOSE(SPLIT(REGEXREPLACE(TEXTJOIN(",",TRUE,A8:8),"(([\w\s\S]+?,){8})","$1@"),"@")),","))),1,TRUE)
In this case, the rows are sorted by the 1st column as the ascending order.
When you use the custom formula created by Google Apps Script, you can also use SORT
as follows.
=SORT(SAMPLE(A8:8, 8),1,TRUE)
Or, you can also use the following script. When you use this, please put =SAMPLE2(A8:8, 8)
to a cell.
const SAMPLE2 = (values, split) => values.flatMap(r => {
const temp = [];
while (r.length > 0) temp.push(r.splice(0, split));
return temp.sort((a, b) => a[0] - b[0]);
});
Upvotes: 4
Reputation: 1
or try:
=QUERY(
{FLATTEN(FILTER(A8:15, MOD(COLUMN(A1:1)-1, 8)=0)),
FLATTEN(FILTER(A8:15, MOD(COLUMN(A1:1)-2, 8)=0)),
FLATTEN(FILTER(A8:15, MOD(COLUMN(A1:1)-3, 8)=0)),
FLATTEN(FILTER(A8:15, MOD(COLUMN(A1:1)-4, 8)=0)),
FLATTEN(FILTER(A8:15, MOD(COLUMN(A1:1)-5, 8)=0)),
FLATTEN(FILTER(A8:15, MOD(COLUMN(A1:1)-6, 8)=0)),
FLATTEN(FILTER(A8:15, MOD(COLUMN(A1:1)-7, 8)=0)),
FLATTEN(FILTER(A8:15, MOD(COLUMN(A1:1)-8, 8)=0))},
"where Col1 is not null", 0)
Upvotes: 2