使用行号在 Arrayformula 中连接
Concat in Arrayformula using row numbers
更新 - 修改后的答案
在@player0 的帮助下,找到了也处理行分隔符的解决方案:
=ARRAYFORMULA(REGEXREPLACE(TRANSPOSE(QUERY(TRANSPOSE(SPLIT(TRANSPOSE(SPLIT(QUERY( IF(D1:D="[task]", "♦"&D1:D, "♣♀"&D1:D),,999^99), "♦", )), "♀")),,999^99)),"\s*♣\s*",char(10)))
这会将每个 [task] 部分移动到它自己的单元格中,保留所有其他格式,并停止添加在 joined/concat 在一起的每个单元格内容周围的额外空白。
原版Post
似乎在其他任何地方都找不到这样做的地方,也很高兴评论中有任何链接:)
我有一栏文字,一百多个文件的内容,每个文件的顶部都有 [task]
。
超过 50,000 个字符,所以他们将每个单元格粘贴到一个换行符中 ('paste as values')。
我可以很容易地告诉行号工作并有一个可拖动的工作公式,只是不能正确地得到它 ARRAYFORMULA capable,因为输入可能很容易改变千行因此需要优雅地处理。
只有公式,没有代码
示例传播sheet
https://docs.google.com/spreadsheets/d/1yaETa3Pvq47DpcAyojSlf6p5N1Tt_hpvoqp7WEtC6pI/edit?usp=sharing
示例输入(50,000+ 个字符)
https://drive.google.com/file/d/1sMl0ZQfbXZUjpB0fic2VkX5Ze5H_IEGL/view?usp=sharing
注意 - 如果在我清理驱动器时删除了输入文件,只需复制粘贴下面的示例直到 50,000 多个字符,或者查看链接的传播sheet
输入
[task]
SpriteNE = floor_metal_01.dds
SpriteSE = floor_metal_01.dds
SpriteSW = floor_metal_01.dds
SpriteNW = floor_metal_01.dds
guilevel = 1
guiindex = 10
type = COMPONENT
locked = 0
name = category_advanced_manufacturing
parent
[task]
SpriteNE = floor_metal_01.dds
SpriteSE = floor_metal_01.dds
SpriteSW = floor_metal_01.dds
SpriteNW = floor_metal_01.dds
guilevel = 1
guiindex = 9
type = COMPONENT
locked = 0
name = category_facilities
parent
[task]
tilelable
SpriteNE = conveyor_NE.dds
SpriteSE = conveyor_SE.dds
SpriteSW = conveyor_SW.dds
SpriteNW = conveyor_NW.dds
exitdirectionoffsets = 0
inputdirectionoffsets = 2
guilevel = 1
parent
guiindex = 0.5
name = task_conveyor
is_conveyor = 1
[components]
[resources]
[subtasksrequired]
[subtasksapplied]
[tile]
texture = conveyor_SE.dds
[task]
tilelable
SpriteNE = conveyor_converge3_NE.dds
SpriteSE = conveyor_converge3_SE.dds
SpriteSW = conveyor_converge3_SW.dds
SpriteNW = conveyor_converge3_NW.dds
exitdirectionoffsets = 0,
inputdirectionoffsets = 1,2,3
guilevel = -1
parent
guiindex = 1
name = task_conveyor_converge3
is_conveyor = 1
[components]
[resources]
[subtasksrequired]
[subtasksapplied]
[tile]
texture = conveyor_converge3_SE.dds
[task]
tilelable
SpriteNE = conveyor_crossover_NE.dds
SpriteSE = conveyor_crossover_SE.dds
SpriteSW = conveyor_crossover_SW.dds
SpriteNW = conveyor_crossover_NW.dds
exitdirectionoffsets = 0,3
inputdirectionoffsets = 1,2
guilevel = -1
parent
guiindex = 1
name = task_conveyor_crossover
is_conveyor = 1
[components]
[resources]
[subtasksrequired]
[subtasksapplied]
[tile]
texture = conveyor_crossover_SE.dds
[task]
tilelable
SpriteNE = conveyor_left_NE.dds
SpriteSE = conveyor_left_SE.dds
SpriteSW = conveyor_left_SW.dds
SpriteNW = conveyor_left_NW.dds
exitdirectionoffsets = 3
inputdirectionoffsets = 2
guilevel = -1
parent
guiindex = 1
name = task_conveyor_left
is_conveyor = 1
[components]
[resources]
[subtasksrequired]
[subtasksapplied]
[tile]
texture = conveyor_left_SE.dds
[task]
tilelable
SpriteNE = conveyor_right_NE.dds
SpriteSE = conveyor_right_SE.dds
SpriteSW = conveyor_right_SW.dds
SpriteNW = conveyor_right_NW.dds
exitdirectionoffsets = 1
inputdirectionoffsets = 2
guilevel = -1
parent
guiindex = 1
name = task_conveyor_right
is_conveyor = 1
[components]
[resources]
[subtasksrequired]
[subtasksapplied]
[tile]
texture = conveyor_right_SE.dds
[task]
tilelable
SpriteNE = conveyor_split3_NE.dds
SpriteSE = conveyor_split3_SE.dds
SpriteSW = conveyor_split3_SW.dds
SpriteNW = conveyor_split3_NW.dds
exitdirectionoffsets = 0,1,3
inputdirectionoffsets = 2
guilevel = -1
parent
guiindex = 1
name = task_conveyor_split3
is_conveyor = 1
[components]
[resources]
[subtasksrequired]
[subtasksapplied]
[tile]
texture = conveyor_split3_SE.dds
[task]
tilelable
SpriteNE = conveyor_t_NE.dds
SpriteSE = conveyor_t_SE.dds
SpriteSW = conveyor_t_SW.dds
SpriteNW = conveyor_t_NW.dds
exitdirectionoffsets = 3,1
inputdirectionoffsets = 2
guilevel = -1
parent
guiindex = 1
name = task_conveyor_t
is_conveyor = 1
[components]
[resources]
[subtasksrequired]
[subtasksapplied]
[tile]
texture = conveyor_t_SE.dds
[task]
tilelable
SpriteNE = conveyor_t_join_NE.dds
SpriteSE = conveyor_t_join_SE.dds
SpriteSW = conveyor_t_join_SW.dds
SpriteNW = conveyor_t_join_NW.dds
exitdirectionoffsets = 0
inputdirectionoffsets = 1,3
guilevel = -1
parent
guiindex = 1
name = task_conveyor_t_join
is_conveyor = 1
[components]
[resources]
[subtasksrequired]
[subtasksapplied]
[tile]
texture = conveyor_t_join_SE.dds
[task]
tilelable
SpriteNE = conveyor_t_join_left_NE.dds
SpriteSE = conveyor_t_join_left_SE.dds
SpriteSW = conveyor_t_join_left_SW.dds
SpriteNW = conveyor_t_join_left_NW.dds
exitdirectionoffsets = 0
inputdirectionoffsets = 2,3
guilevel = -1
parent
guiindex = 1
name = task_conveyor_t_join_left
is_conveyor = 1
[components]
[resources]
[subtasksrequired]
[subtasksapplied]
[tile]
texture = conveyor_t_join_left_SE.dds
[task]
tilelable
SpriteNE = conveyor_t_join_right_NE.dds
SpriteSE = conveyor_t_join_right_SE.dds
SpriteSW = conveyor_t_join_right_SW.dds
SpriteNW = conveyor_t_join_right_NW.dds
exitdirectionoffsets = 0
inputdirectionoffsets = 1,2
guilevel = -1
parent
guiindex = 1
name = task_conveyor_t_join_right
is_conveyor = 1
[components]
[resources]
[subtasksrequired]
[subtasksapplied]
[tile]
texture = conveyor_t_join_right_SE.dds
[task]
tilelable
SpriteNE = conveyor_t_left_NE.dds
SpriteSE = conveyor_t_left_SE.dds
SpriteSW = conveyor_t_left_SW.dds
SpriteNW = conveyor_t_left_NW.dds
exitdirectionoffsets = 0,3
inputdirectionoffsets = 2
guilevel = -1
parent
guiindex = 1
name = task_conveyor_t_left
is_conveyor = 1
[components]
[resources]
[subtasksrequired]
[subtasksapplied]
[tile]
texture = conveyor_t_left_SE.dds
[task]
tilelable
SpriteNE = conveyor_t_right_NE.dds
SpriteSE = conveyor_t_right_SE.dds
SpriteSW = conveyor_t_right_SW.dds
SpriteNW = conveyor_t_right_NW.dds
exitdirectionoffsets = 0,1
inputdirectionoffsets = 2
guilevel = -1
parent
guiindex = 1
name = task_conveyor_t_right
is_conveyor = 1
[components]
[resources]
[subtasksrequired]
[subtasksapplied]
[tile]
texture = conveyor_t_right_SE.dds
期望输出
每个 [task].* 都是一个新文件,因此将它们分隔成一个单元格,每个单元格在一个单独的列中,使用换行符 (\n
) 作为内部分隔符。
换句话说,[任务]之后到下一个[任务](或列末尾,如果没有更多[任务])的所有内容都合并到一个单元格中。
只需能够使用 arrayformula 并避免 50,000 个字符的 concat 等函数的字符限制。
当前输出
获取行号
$D:D
是输入列
$G
是选择了 "[task]"
的下拉列表
$M =ARRAYFORMULA(QUERY({$D1:$D, row($D1:$D)},"select * where Col1 = '"&$G&"'"))
$O =ARRAYFORMULA(QUERY({$M1:$M,{$M2:$M;0}},"select *"))
然后我尝试使用这些数字
有效,必须拖过,并且没有任何分隔符。
=ARRAYFORMULA(CONCATENATE(INDIRECT("$D"&$O1:$O&":$D"&$P1:$P-1)))
没用,我一直在添加更多数组公式,但仍然只有第一个结果
=ARRAYFORMULA(IF($P1:P<>"",CONCATENATE(ARRAYFORMULA(INDIRECT("$D"&ARRAYFORMULA(INDIRECT("$O"&IF($P1:$P<>"",row($P1:$P),"")&":$O"))&":$D"&ARRAYFORMULA(INDIRECT("$P"&IF($P1:$P<>"",row($P1:$P),"")&":$P"))-1))),""))
就是前面INDIRECT
中使用的字符串
=ARRAYFORMULA(IF($O1:O<>"","$D"&ARRAYFORMULA(INDIRECT("$O"&IF($P1:$P<>"",row($P1:$P),"")&":$O"))&":$D"&ARRAYFORMULA(INDIRECT("$P"&IF($P1:$P<>"",row($P1:$P),"")&":$P"))-1,""))
不起作用,有分隔符但仍然只循环第一个结果。
$U1:U
是间接的字符串列表(见上文)
=ARRAYFORMULA(IF($U1:U<>"",TEXTJOIN(";",FALSE,INDIRECT($U1:U)),""))
示例中还有一些其他公式 sheet,我在继续操作的过程中大部分删除了无效的公式。
我在那里发现了很多有趣的资源,但似乎没有任何内容是针对使用行号的,甚至只是允许 ARRAYFORMULA
(AND 避免了 50,000 个字符限制的 SPLIT + JOIN 类型方法 单个 CONCAT 或类似调用的问题。
尝试:
=ARRAYFORMULA(SPLIT(TRANSPOSE(SPLIT(QUERY(
IF(A2:A="[task]", "♦"&A2:A, "♀"&A2:A),,999^99), "♦", )), "♀"))
这是我之前在评论中所说的示例,不幸的是,您只是在单元格“=GroupMacro”中调用函数,这不能自动刷新:
var rtrn=[];
var rslt=[];
var rslt2='';
function GroupMacro() {
var spreadsheet = SpreadsheetApp.getActive();
var bomo=spreadsheet.getRange('D1:D' + spreadsheet.getLastRow()).getValues();
for (a=0; a<bomo.length; a++)
{
if(bomo[a]=='test') //this is separator, this can be applied as parameter in function
{
if(a>0)
{
rslt2=rslt.join();
rtrn.push(rslt2);
rslt=[];
}
rslt.push(bomo[a]);
}
else
{
rslt.push(bomo[a]);
}
}
rslt2=rslt.join();
rtrn.push(rslt2);
return rtrn;
};
更新 - 修改后的答案
在@player0 的帮助下,找到了也处理行分隔符的解决方案:
=ARRAYFORMULA(REGEXREPLACE(TRANSPOSE(QUERY(TRANSPOSE(SPLIT(TRANSPOSE(SPLIT(QUERY( IF(D1:D="[task]", "♦"&D1:D, "♣♀"&D1:D),,999^99), "♦", )), "♀")),,999^99)),"\s*♣\s*",char(10)))
这会将每个 [task] 部分移动到它自己的单元格中,保留所有其他格式,并停止添加在 joined/concat 在一起的每个单元格内容周围的额外空白。
原版Post
似乎在其他任何地方都找不到这样做的地方,也很高兴评论中有任何链接:)
我有一栏文字,一百多个文件的内容,每个文件的顶部都有 [task]
。
超过 50,000 个字符,所以他们将每个单元格粘贴到一个换行符中 ('paste as values')。
我可以很容易地告诉行号工作并有一个可拖动的工作公式,只是不能正确地得到它 ARRAYFORMULA capable,因为输入可能很容易改变千行因此需要优雅地处理。
只有公式,没有代码
示例传播sheet
https://docs.google.com/spreadsheets/d/1yaETa3Pvq47DpcAyojSlf6p5N1Tt_hpvoqp7WEtC6pI/edit?usp=sharing
示例输入(50,000+ 个字符) https://drive.google.com/file/d/1sMl0ZQfbXZUjpB0fic2VkX5Ze5H_IEGL/view?usp=sharing
注意 - 如果在我清理驱动器时删除了输入文件,只需复制粘贴下面的示例直到 50,000 多个字符,或者查看链接的传播sheet
输入
[task]
SpriteNE = floor_metal_01.dds
SpriteSE = floor_metal_01.dds
SpriteSW = floor_metal_01.dds
SpriteNW = floor_metal_01.dds
guilevel = 1
guiindex = 10
type = COMPONENT
locked = 0
name = category_advanced_manufacturing
parent
[task]
SpriteNE = floor_metal_01.dds
SpriteSE = floor_metal_01.dds
SpriteSW = floor_metal_01.dds
SpriteNW = floor_metal_01.dds
guilevel = 1
guiindex = 9
type = COMPONENT
locked = 0
name = category_facilities
parent
[task]
tilelable
SpriteNE = conveyor_NE.dds
SpriteSE = conveyor_SE.dds
SpriteSW = conveyor_SW.dds
SpriteNW = conveyor_NW.dds
exitdirectionoffsets = 0
inputdirectionoffsets = 2
guilevel = 1
parent
guiindex = 0.5
name = task_conveyor
is_conveyor = 1
[components]
[resources]
[subtasksrequired]
[subtasksapplied]
[tile]
texture = conveyor_SE.dds
[task]
tilelable
SpriteNE = conveyor_converge3_NE.dds
SpriteSE = conveyor_converge3_SE.dds
SpriteSW = conveyor_converge3_SW.dds
SpriteNW = conveyor_converge3_NW.dds
exitdirectionoffsets = 0,
inputdirectionoffsets = 1,2,3
guilevel = -1
parent
guiindex = 1
name = task_conveyor_converge3
is_conveyor = 1
[components]
[resources]
[subtasksrequired]
[subtasksapplied]
[tile]
texture = conveyor_converge3_SE.dds
[task]
tilelable
SpriteNE = conveyor_crossover_NE.dds
SpriteSE = conveyor_crossover_SE.dds
SpriteSW = conveyor_crossover_SW.dds
SpriteNW = conveyor_crossover_NW.dds
exitdirectionoffsets = 0,3
inputdirectionoffsets = 1,2
guilevel = -1
parent
guiindex = 1
name = task_conveyor_crossover
is_conveyor = 1
[components]
[resources]
[subtasksrequired]
[subtasksapplied]
[tile]
texture = conveyor_crossover_SE.dds
[task]
tilelable
SpriteNE = conveyor_left_NE.dds
SpriteSE = conveyor_left_SE.dds
SpriteSW = conveyor_left_SW.dds
SpriteNW = conveyor_left_NW.dds
exitdirectionoffsets = 3
inputdirectionoffsets = 2
guilevel = -1
parent
guiindex = 1
name = task_conveyor_left
is_conveyor = 1
[components]
[resources]
[subtasksrequired]
[subtasksapplied]
[tile]
texture = conveyor_left_SE.dds
[task]
tilelable
SpriteNE = conveyor_right_NE.dds
SpriteSE = conveyor_right_SE.dds
SpriteSW = conveyor_right_SW.dds
SpriteNW = conveyor_right_NW.dds
exitdirectionoffsets = 1
inputdirectionoffsets = 2
guilevel = -1
parent
guiindex = 1
name = task_conveyor_right
is_conveyor = 1
[components]
[resources]
[subtasksrequired]
[subtasksapplied]
[tile]
texture = conveyor_right_SE.dds
[task]
tilelable
SpriteNE = conveyor_split3_NE.dds
SpriteSE = conveyor_split3_SE.dds
SpriteSW = conveyor_split3_SW.dds
SpriteNW = conveyor_split3_NW.dds
exitdirectionoffsets = 0,1,3
inputdirectionoffsets = 2
guilevel = -1
parent
guiindex = 1
name = task_conveyor_split3
is_conveyor = 1
[components]
[resources]
[subtasksrequired]
[subtasksapplied]
[tile]
texture = conveyor_split3_SE.dds
[task]
tilelable
SpriteNE = conveyor_t_NE.dds
SpriteSE = conveyor_t_SE.dds
SpriteSW = conveyor_t_SW.dds
SpriteNW = conveyor_t_NW.dds
exitdirectionoffsets = 3,1
inputdirectionoffsets = 2
guilevel = -1
parent
guiindex = 1
name = task_conveyor_t
is_conveyor = 1
[components]
[resources]
[subtasksrequired]
[subtasksapplied]
[tile]
texture = conveyor_t_SE.dds
[task]
tilelable
SpriteNE = conveyor_t_join_NE.dds
SpriteSE = conveyor_t_join_SE.dds
SpriteSW = conveyor_t_join_SW.dds
SpriteNW = conveyor_t_join_NW.dds
exitdirectionoffsets = 0
inputdirectionoffsets = 1,3
guilevel = -1
parent
guiindex = 1
name = task_conveyor_t_join
is_conveyor = 1
[components]
[resources]
[subtasksrequired]
[subtasksapplied]
[tile]
texture = conveyor_t_join_SE.dds
[task]
tilelable
SpriteNE = conveyor_t_join_left_NE.dds
SpriteSE = conveyor_t_join_left_SE.dds
SpriteSW = conveyor_t_join_left_SW.dds
SpriteNW = conveyor_t_join_left_NW.dds
exitdirectionoffsets = 0
inputdirectionoffsets = 2,3
guilevel = -1
parent
guiindex = 1
name = task_conveyor_t_join_left
is_conveyor = 1
[components]
[resources]
[subtasksrequired]
[subtasksapplied]
[tile]
texture = conveyor_t_join_left_SE.dds
[task]
tilelable
SpriteNE = conveyor_t_join_right_NE.dds
SpriteSE = conveyor_t_join_right_SE.dds
SpriteSW = conveyor_t_join_right_SW.dds
SpriteNW = conveyor_t_join_right_NW.dds
exitdirectionoffsets = 0
inputdirectionoffsets = 1,2
guilevel = -1
parent
guiindex = 1
name = task_conveyor_t_join_right
is_conveyor = 1
[components]
[resources]
[subtasksrequired]
[subtasksapplied]
[tile]
texture = conveyor_t_join_right_SE.dds
[task]
tilelable
SpriteNE = conveyor_t_left_NE.dds
SpriteSE = conveyor_t_left_SE.dds
SpriteSW = conveyor_t_left_SW.dds
SpriteNW = conveyor_t_left_NW.dds
exitdirectionoffsets = 0,3
inputdirectionoffsets = 2
guilevel = -1
parent
guiindex = 1
name = task_conveyor_t_left
is_conveyor = 1
[components]
[resources]
[subtasksrequired]
[subtasksapplied]
[tile]
texture = conveyor_t_left_SE.dds
[task]
tilelable
SpriteNE = conveyor_t_right_NE.dds
SpriteSE = conveyor_t_right_SE.dds
SpriteSW = conveyor_t_right_SW.dds
SpriteNW = conveyor_t_right_NW.dds
exitdirectionoffsets = 0,1
inputdirectionoffsets = 2
guilevel = -1
parent
guiindex = 1
name = task_conveyor_t_right
is_conveyor = 1
[components]
[resources]
[subtasksrequired]
[subtasksapplied]
[tile]
texture = conveyor_t_right_SE.dds
期望输出
每个 [task].* 都是一个新文件,因此将它们分隔成一个单元格,每个单元格在一个单独的列中,使用换行符 (\n
) 作为内部分隔符。
换句话说,[任务]之后到下一个[任务](或列末尾,如果没有更多[任务])的所有内容都合并到一个单元格中。
只需能够使用 arrayformula 并避免 50,000 个字符的 concat 等函数的字符限制。
当前输出
获取行号
$D:D
是输入列
$G
是选择了 "[task]"
的下拉列表
$M =ARRAYFORMULA(QUERY({$D1:$D, row($D1:$D)},"select * where Col1 = '"&$G&"'"))
$O =ARRAYFORMULA(QUERY({$M1:$M,{$M2:$M;0}},"select *"))
然后我尝试使用这些数字
有效,必须拖过,并且没有任何分隔符。
=ARRAYFORMULA(CONCATENATE(INDIRECT("$D"&$O1:$O&":$D"&$P1:$P-1)))
没用,我一直在添加更多数组公式,但仍然只有第一个结果
=ARRAYFORMULA(IF($P1:P<>"",CONCATENATE(ARRAYFORMULA(INDIRECT("$D"&ARRAYFORMULA(INDIRECT("$O"&IF($P1:$P<>"",row($P1:$P),"")&":$O"))&":$D"&ARRAYFORMULA(INDIRECT("$P"&IF($P1:$P<>"",row($P1:$P),"")&":$P"))-1))),""))
就是前面INDIRECT
=ARRAYFORMULA(IF($O1:O<>"","$D"&ARRAYFORMULA(INDIRECT("$O"&IF($P1:$P<>"",row($P1:$P),"")&":$O"))&":$D"&ARRAYFORMULA(INDIRECT("$P"&IF($P1:$P<>"",row($P1:$P),"")&":$P"))-1,""))
不起作用,有分隔符但仍然只循环第一个结果。
$U1:U
是间接的字符串列表(见上文)
=ARRAYFORMULA(IF($U1:U<>"",TEXTJOIN(";",FALSE,INDIRECT($U1:U)),""))
示例中还有一些其他公式 sheet,我在继续操作的过程中大部分删除了无效的公式。
我在那里发现了很多有趣的资源,但似乎没有任何内容是针对使用行号的,甚至只是允许 ARRAYFORMULA
(AND 避免了 50,000 个字符限制的 SPLIT + JOIN 类型方法 单个 CONCAT 或类似调用的问题。
尝试:
=ARRAYFORMULA(SPLIT(TRANSPOSE(SPLIT(QUERY(
IF(A2:A="[task]", "♦"&A2:A, "♀"&A2:A),,999^99), "♦", )), "♀"))
这是我之前在评论中所说的示例,不幸的是,您只是在单元格“=GroupMacro”中调用函数,这不能自动刷新:
var rtrn=[];
var rslt=[];
var rslt2='';
function GroupMacro() {
var spreadsheet = SpreadsheetApp.getActive();
var bomo=spreadsheet.getRange('D1:D' + spreadsheet.getLastRow()).getValues();
for (a=0; a<bomo.length; a++)
{
if(bomo[a]=='test') //this is separator, this can be applied as parameter in function
{
if(a>0)
{
rslt2=rslt.join();
rtrn.push(rslt2);
rslt=[];
}
rslt.push(bomo[a]);
}
else
{
rslt.push(bomo[a]);
}
}
rslt2=rslt.join();
rtrn.push(rslt2);
return rtrn;
};