Excel 每次找到电子邮件地址时动态转置
Excel dynamically transpose every time an email address is found
我在 excel 中有一列包含类似于以下内容的长列表:
alfa.zulu@test.com
9v46by8
9016767312
TX961779
1DM90F4
bravo.zulu@test.com
B935536
24086942
9486388284
UAUG350583
0P47MB2
asd65f4
813asdg
357yvjy
jxvn97
iopu634
charlie.zulu@test.com
1DM90F4
0P47MB2
delta.zulu@test.com
9016767312
asd65f4
357yvjy
iopu634
echo.zulu@test.com
9v46by8
TX961779
B935536
我需要转置列表,但是每次我有一个电子邮件地址时,我都需要跳到下一行并重新开始,例如:
alfa.zulu@test.com 9v46by8 9016767312 TX961779 1DM90F4
bravo.zulu@test.com B935536 24086942 9486388284 UAUG350583 0P47MB2 asd65f4 813asdg 357yvjy
charlie.zulu@test.com 1DM90F4 0P47MB2
delta.zulu@test.com 9016767312 asd65f4 357yvjy iopu634
echo.zulu@test.com 9v46by8 TX961779 B935536
有没有不使用 vba 就可以实现的方法?
提前致谢!
这可以通过组合 INDEX
、AGGREGATE
和 SEARCH
函数来完成。
但有一些先决条件:
SEARCH
函数将搜索带有 @
符号的单元格 - 因此它应该只在电子邮件地址中
- 在列表末尾,必须在第一个空白单元格中输入
@
符号
公式:
=IFERROR(INDEX(INDEX($A:$A,AGGREGATE(15,6,(1/ISNUMBER(SEARCH("@",$A:$A)))*ROW($A:$A),ROW())):INDEX($A:$A,AGGREGATE(15,6,(1/ISNUMBER(SEARCH("@",$A:$A)))*(ROW($A:$A)-1),ROW()+1)),COLUMN()-2),"")
如果列表很长,最好听从 Ron 的建议。
使用 Power Query:
使列数据类型=文本
测试条目是否为电子邮件 - 使用 @
但可以更复杂
添加索引列
添加另一列,每当第 1 列中有一封电子邮件时,该列包含一个唯一编号
填写唯一编号,以便每个“组”都有相同的编号
在唯一编号列上对行进行分组
将每一行的数据提取到分隔列表中
添加一些逻辑以启用潜在列数的变化,否则高级查询将无法适应。
根据分隔符将数据列表拆分为新列
在此过程中,我们删除了无关的列
- 将下面的代码粘贴到 Power Query 编辑器中
- 更改第 2 行中的 Table 以反映工作表中的真实 table 姓名。
- 双击
Applied Steps
window 中的语句,探索每一步都做了什么
- 如果您的数据 table 发生变化,只需刷新即可。
M码
let
Source = Excel.CurrentWorkbook(){[Name="Table3"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Column1", type text}}),
#"Added Custom" = Table.AddColumn(#"Changed Type", "isEmail", each Text.Contains([Column1],"@")),
#"Added Index" = Table.AddIndexColumn(#"Added Custom", "Index", 0, 1, Int64.Type),
#"Added Custom1" = Table.AddColumn(#"Added Index", "Grouper", each if [isEmail] then [Index] else null),
#"Filled Down" = Table.FillDown(#"Added Custom1",{"Grouper"}),
#"Removed Columns" = Table.RemoveColumns(#"Filled Down",{"isEmail", "Index"}),
#"Grouped Rows" = Table.Group(#"Removed Columns", {"Grouper"}, {{"Grouped", each _, type table [Column1=nullable text, Grouper=number]}}),
#"Added Custom2" = Table.AddColumn(#"Grouped Rows", "Value", each Table.Column([Grouped],"Column1")),
#"Removed Columns2" = Table.RemoveColumns(#"Added Custom2",{"Grouper", "Grouped"}),
#"Added Custom3" = Table.AddColumn(#"Removed Columns2", "numSplits", each List.Count([Value])),
//Make column splitting dynamic for each refresh, in case maximum number of columns changes
splits = List.Max(Table.Column(#"Added Custom3","numSplits")),
newColList = List.Zip({List.Repeat({"Value"},splits),List.Generate(() => 1, each _ <= splits, each _ +1)}),
#"Converted to Table" = Table.FromList(newColList, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
newColNamesTbl = Table.TransformColumns(#"Converted to Table", {"Column1", each Text.Combine(List.Transform(_, Text.From)), type text}),
newColNamesList = Table.Column(newColNamesTbl,"Column1"),
#"Extracted Values" = Table.TransformColumns(#"Added Custom3", {"Value", each Text.Combine(List.Transform(_, Text.From), ";"), type text}),
#"Removed Columns1" = Table.RemoveColumns(#"Extracted Values",{"numSplits"}),
#"Split Column by Delimiter" = Table.SplitColumn(#"Removed Columns1", "Value", Splitter.SplitTextByDelimiter(";", QuoteStyle.Csv), newColNamesList)
in
#"Split Column by Delimiter"
源数据
结果
我在 excel 中有一列包含类似于以下内容的长列表:
alfa.zulu@test.com
9v46by8
9016767312
TX961779
1DM90F4
bravo.zulu@test.com
B935536
24086942
9486388284
UAUG350583
0P47MB2
asd65f4
813asdg
357yvjy
jxvn97
iopu634
charlie.zulu@test.com
1DM90F4
0P47MB2
delta.zulu@test.com
9016767312
asd65f4
357yvjy
iopu634
echo.zulu@test.com
9v46by8
TX961779
B935536
我需要转置列表,但是每次我有一个电子邮件地址时,我都需要跳到下一行并重新开始,例如:
alfa.zulu@test.com 9v46by8 9016767312 TX961779 1DM90F4
bravo.zulu@test.com B935536 24086942 9486388284 UAUG350583 0P47MB2 asd65f4 813asdg 357yvjy
charlie.zulu@test.com 1DM90F4 0P47MB2
delta.zulu@test.com 9016767312 asd65f4 357yvjy iopu634
echo.zulu@test.com 9v46by8 TX961779 B935536
有没有不使用 vba 就可以实现的方法? 提前致谢!
这可以通过组合 INDEX
、AGGREGATE
和 SEARCH
函数来完成。
但有一些先决条件:
SEARCH
函数将搜索带有@
符号的单元格 - 因此它应该只在电子邮件地址中- 在列表末尾,必须在第一个空白单元格中输入
@
符号
公式:
=IFERROR(INDEX(INDEX($A:$A,AGGREGATE(15,6,(1/ISNUMBER(SEARCH("@",$A:$A)))*ROW($A:$A),ROW())):INDEX($A:$A,AGGREGATE(15,6,(1/ISNUMBER(SEARCH("@",$A:$A)))*(ROW($A:$A)-1),ROW()+1)),COLUMN()-2),"")
如果列表很长,最好听从 Ron 的建议。
使用 Power Query:
使列数据类型=文本
测试条目是否为电子邮件 - 使用
@
但可以更复杂添加索引列
添加另一列,每当第 1 列中有一封电子邮件时,该列包含一个唯一编号
填写唯一编号,以便每个“组”都有相同的编号
在唯一编号列上对行进行分组
将每一行的数据提取到分隔列表中
添加一些逻辑以启用潜在列数的变化,否则高级查询将无法适应。
根据分隔符将数据列表拆分为新列
在此过程中,我们删除了无关的列
- 将下面的代码粘贴到 Power Query 编辑器中
- 更改第 2 行中的 Table 以反映工作表中的真实 table 姓名。
- 双击
Applied Steps
window 中的语句,探索每一步都做了什么 - 如果您的数据 table 发生变化,只需刷新即可。
M码
let
Source = Excel.CurrentWorkbook(){[Name="Table3"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Column1", type text}}),
#"Added Custom" = Table.AddColumn(#"Changed Type", "isEmail", each Text.Contains([Column1],"@")),
#"Added Index" = Table.AddIndexColumn(#"Added Custom", "Index", 0, 1, Int64.Type),
#"Added Custom1" = Table.AddColumn(#"Added Index", "Grouper", each if [isEmail] then [Index] else null),
#"Filled Down" = Table.FillDown(#"Added Custom1",{"Grouper"}),
#"Removed Columns" = Table.RemoveColumns(#"Filled Down",{"isEmail", "Index"}),
#"Grouped Rows" = Table.Group(#"Removed Columns", {"Grouper"}, {{"Grouped", each _, type table [Column1=nullable text, Grouper=number]}}),
#"Added Custom2" = Table.AddColumn(#"Grouped Rows", "Value", each Table.Column([Grouped],"Column1")),
#"Removed Columns2" = Table.RemoveColumns(#"Added Custom2",{"Grouper", "Grouped"}),
#"Added Custom3" = Table.AddColumn(#"Removed Columns2", "numSplits", each List.Count([Value])),
//Make column splitting dynamic for each refresh, in case maximum number of columns changes
splits = List.Max(Table.Column(#"Added Custom3","numSplits")),
newColList = List.Zip({List.Repeat({"Value"},splits),List.Generate(() => 1, each _ <= splits, each _ +1)}),
#"Converted to Table" = Table.FromList(newColList, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
newColNamesTbl = Table.TransformColumns(#"Converted to Table", {"Column1", each Text.Combine(List.Transform(_, Text.From)), type text}),
newColNamesList = Table.Column(newColNamesTbl,"Column1"),
#"Extracted Values" = Table.TransformColumns(#"Added Custom3", {"Value", each Text.Combine(List.Transform(_, Text.From), ";"), type text}),
#"Removed Columns1" = Table.RemoveColumns(#"Extracted Values",{"numSplits"}),
#"Split Column by Delimiter" = Table.SplitColumn(#"Removed Columns1", "Value", Splitter.SplitTextByDelimiter(";", QuoteStyle.Csv), newColNamesList)
in
#"Split Column by Delimiter"
源数据
结果