有没有办法将列组转置为 excel 中的行?
Is there a way to transpose groups of columns to rows in excel?
我在 excel 中的来源 table 如下所示:
code name1 perc1 name2 perc2 name3 perc3
11 x 10 x2 20 x3 70
12 y 20 y2 80
13 z 100
45 q 15 q2 85
这是最后的 table 我需要:
code name1 perc1
11 x 10
11 x2 20
11 x3 70
12 y 20
12 y2 80
13 z 100
45 q 15
45 q2 85
您也可以使用 PowerQuery.The 执行此操作,步骤如下:
- 合并列 name1 和 perc1、name2 和 perc2、name3 和 perc3,使用分隔符(比如 equalsign)。现在你的左边有 4 列。
- Right-click 列 [代码] 和 select
Unpivot Other Columns
- Right-click 列 [属性] 和 select
Remove
- Right-click 列 [值] 和 select
Split Columns
=> By Delimeter
=> OK
- 使用列 [Value.2] 中的 dropdown-menu:deselect 空值。
- 重命名列 [Value.1] 和 [Value.2]
- 点击
Close & Load
这是 PowerQuery 中的结果(就在第 7 步之前)
这是高级编辑器生成的脚本:
let
Source = Excel.CurrentWorkbook(){[Name="Table"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"code", Int64.Type}, {"name1", type text}, {"perc1", Int64.Type}, {"name2", type text}, {"perc2", Int64.Type}, {"name3", type text}, {"perc3", Int64.Type}}),
#"Merged Columns" = Table.CombineColumns(Table.TransformColumnTypes(#"Changed Type", {{"perc1", type text}}, "en-US"),{"name1", "perc1"},Combiner.CombineTextByDelimiter("=", QuoteStyle.None),"Merged"),
#"Merged Columns1" = Table.CombineColumns(Table.TransformColumnTypes(#"Merged Columns", {{"perc2", type text}}, "en-US"),{"name2", "perc2"},Combiner.CombineTextByDelimiter("=", QuoteStyle.None),"Merged.1"),
#"Merged Columns2" = Table.CombineColumns(Table.TransformColumnTypes(#"Merged Columns1", {{"perc3", type text}}, "en-US"),{"name3", "perc3"},Combiner.CombineTextByDelimiter("=", QuoteStyle.None),"Merged.2"),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Merged Columns2", {"code"}, "Attribute", "Value"),
#"Removed Columns" = Table.RemoveColumns(#"Unpivoted Other Columns",{"Attribute"}),
#"Split Column by Delimiter" = Table.SplitColumn(#"Removed Columns", "Value", Splitter.SplitTextByDelimiter("=", QuoteStyle.Csv), {"Value.1", "Value.2"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Value.1", type text}, {"Value.2", Int64.Type}}),
#"Filtered Rows" = Table.SelectRows(#"Changed Type1", each ([Value.2] <> null)),
#"Renamed Columns" = Table.RenameColumns(#"Filtered Rows",{{"Value.1", "Name1"}, {"Value.2", "Perc1"}})
in
#"Renamed Columns"
为了保持这个关于转置,我使用转置数组来构建目标。
Option Explicit
Sub TransposeGroups()
Dim i As Long, j As Long, arr1 As Variant
Dim m As Long, n As Long, arr2 As Variant
With Worksheets("sheet1")
arr1 = .Cells(1, "A").CurrentRegion.Value2
ReDim arr2(1 To 3, 1 To (UBound(arr1, 2) - 1) / 2 * (UBound(arr1, 1) - 1))
m = 1
For n = 1 To 3
arr2(n, m) = arr1(m, n)
Next n
For i = 2 To UBound(arr1, 1)
For j = 2 To UBound(arr1, 2) Step 2
If arr1(i, j) = vbNullString Then Exit For
m = m + 1
arr2(1, m) = arr1(i, 1)
arr2(2, m) = arr1(i, j)
arr2(3, m) = arr1(i, j + 1)
Next j
Next i
With .Parent.Worksheets.Add(after:=.Parent.Worksheets(.Index))
.Cells(1, "A").Resize(UBound(arr2, 2), UBound(arr2, 1)) = _
Application.Transpose(arr2)
End With
End With
End Sub
例如像这样:
J2
中的公式:
=IFERROR(INDEX($A:$A,SMALL(($B:$G<>"")*(ISEVEN(COLUMN($B:$G)))*(ROW($B:$G)-1),COUNTA($B:$G)-SUMPRODUCT((ISEVEN(COLUMN(B2:G5))))+(ROW()-1))),"")
通过CtrlShiftEnter
确认
K2
中的公式:
=INDEX($A:$G,MATCH(J2,$A:$A,0),COUNTIF($J:J2,J2)*2)
L2
中的公式:
=INDEX($A:$G,MATCH(J2,$A:$A,0),(COUNTIF($J:J2,J2)*2)+1)
拖下去....
我在 excel 中的来源 table 如下所示:
code name1 perc1 name2 perc2 name3 perc3
11 x 10 x2 20 x3 70
12 y 20 y2 80
13 z 100
45 q 15 q2 85
这是最后的 table 我需要:
code name1 perc1
11 x 10
11 x2 20
11 x3 70
12 y 20
12 y2 80
13 z 100
45 q 15
45 q2 85
您也可以使用 PowerQuery.The 执行此操作,步骤如下:
- 合并列 name1 和 perc1、name2 和 perc2、name3 和 perc3,使用分隔符(比如 equalsign)。现在你的左边有 4 列。
- Right-click 列 [代码] 和 select
Unpivot Other Columns
- Right-click 列 [属性] 和 select
Remove
- Right-click 列 [值] 和 select
Split Columns
=>By Delimeter
=>OK
- 使用列 [Value.2] 中的 dropdown-menu:deselect 空值。
- 重命名列 [Value.1] 和 [Value.2]
- 点击
Close & Load
这是 PowerQuery 中的结果(就在第 7 步之前)
这是高级编辑器生成的脚本:
let
Source = Excel.CurrentWorkbook(){[Name="Table"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"code", Int64.Type}, {"name1", type text}, {"perc1", Int64.Type}, {"name2", type text}, {"perc2", Int64.Type}, {"name3", type text}, {"perc3", Int64.Type}}),
#"Merged Columns" = Table.CombineColumns(Table.TransformColumnTypes(#"Changed Type", {{"perc1", type text}}, "en-US"),{"name1", "perc1"},Combiner.CombineTextByDelimiter("=", QuoteStyle.None),"Merged"),
#"Merged Columns1" = Table.CombineColumns(Table.TransformColumnTypes(#"Merged Columns", {{"perc2", type text}}, "en-US"),{"name2", "perc2"},Combiner.CombineTextByDelimiter("=", QuoteStyle.None),"Merged.1"),
#"Merged Columns2" = Table.CombineColumns(Table.TransformColumnTypes(#"Merged Columns1", {{"perc3", type text}}, "en-US"),{"name3", "perc3"},Combiner.CombineTextByDelimiter("=", QuoteStyle.None),"Merged.2"),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Merged Columns2", {"code"}, "Attribute", "Value"),
#"Removed Columns" = Table.RemoveColumns(#"Unpivoted Other Columns",{"Attribute"}),
#"Split Column by Delimiter" = Table.SplitColumn(#"Removed Columns", "Value", Splitter.SplitTextByDelimiter("=", QuoteStyle.Csv), {"Value.1", "Value.2"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Value.1", type text}, {"Value.2", Int64.Type}}),
#"Filtered Rows" = Table.SelectRows(#"Changed Type1", each ([Value.2] <> null)),
#"Renamed Columns" = Table.RenameColumns(#"Filtered Rows",{{"Value.1", "Name1"}, {"Value.2", "Perc1"}})
in
#"Renamed Columns"
为了保持这个关于转置,我使用转置数组来构建目标。
Option Explicit
Sub TransposeGroups()
Dim i As Long, j As Long, arr1 As Variant
Dim m As Long, n As Long, arr2 As Variant
With Worksheets("sheet1")
arr1 = .Cells(1, "A").CurrentRegion.Value2
ReDim arr2(1 To 3, 1 To (UBound(arr1, 2) - 1) / 2 * (UBound(arr1, 1) - 1))
m = 1
For n = 1 To 3
arr2(n, m) = arr1(m, n)
Next n
For i = 2 To UBound(arr1, 1)
For j = 2 To UBound(arr1, 2) Step 2
If arr1(i, j) = vbNullString Then Exit For
m = m + 1
arr2(1, m) = arr1(i, 1)
arr2(2, m) = arr1(i, j)
arr2(3, m) = arr1(i, j + 1)
Next j
Next i
With .Parent.Worksheets.Add(after:=.Parent.Worksheets(.Index))
.Cells(1, "A").Resize(UBound(arr2, 2), UBound(arr2, 1)) = _
Application.Transpose(arr2)
End With
End With
End Sub
例如像这样:
J2
中的公式:
=IFERROR(INDEX($A:$A,SMALL(($B:$G<>"")*(ISEVEN(COLUMN($B:$G)))*(ROW($B:$G)-1),COUNTA($B:$G)-SUMPRODUCT((ISEVEN(COLUMN(B2:G5))))+(ROW()-1))),"")
通过CtrlShiftEnter
确认K2
中的公式:
=INDEX($A:$G,MATCH(J2,$A:$A,0),COUNTIF($J:J2,J2)*2)
L2
中的公式:
=INDEX($A:$G,MATCH(J2,$A:$A,0),(COUNTIF($J:J2,J2)*2)+1)
拖下去....