Есть ли способ транспонировать группы столбцов в строки в Excel? - PullRequest
0 голосов
/ 02 июня 2019

Моя исходная таблица в Excel выглядит следующим образом:

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  

, а вот финальная таблица, которая мне нужна:

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

Ответы [ 3 ]

1 голос
/ 02 июня 2019

Например, вот так:

enter image description here

Формула в J2:

=IFERROR(INDEX($A$2:$A$5,SMALL(($B$2:$G$5<>"")*(ISEVEN(COLUMN($B$2:$G$5)))*(ROW($B$2:$G$5)-1),COUNTA($B$2:$G$5)-SUMPRODUCT((ISEVEN(COLUMN(B2:G5))))+(ROW()-1))),"")

Подтвердите с помощью Ctrl Сдвиг Введите

Формула в K2:

=INDEX($A$2:$G$5,MATCH(J2,$A$2:$A$5,0),COUNTIF($J$2:J2,J2)*2)

Формула в L2:

=INDEX($A$2:$G$5,MATCH(J2,$A$2:$A$5,0),(COUNTIF($J$2:J2,J2)*2)+1)

Перетащите их вниз ...

1 голос
/ 02 июня 2019

Вы также можете сделать это с помощью PowerQuery. Шаги следующие:

  1. Объединить столбцы name1 и perc1, name2 & perc2, name3 & perc3, используя разделитель (скажем, equalsign ). Теперь у вас осталось 4 столбца.
  2. Щелкните правой кнопкой мыши столбец [код] и выберите Unpivot Other Columns
  3. Щелкните правой кнопкой мыши по столбцу [Атрибут] и выберите Remove
  4. Щелкните правой кнопкой мыши по столбцу [Значение] и выберите Split Columns => By Delimeter => OK
  5. Использование выпадающего меню в столбце [Value.2]: отменить выбор нулевых значений.
  6. Переименовать столбец [Value.1] и [Value.2]
  7. Нажмите Close & Load

Это результат в PowerQuery (непосредственно перед шагом 7)

enter image description here

И это сгенерированный скрипт из Расширенного редактора:

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"
0 голосов
/ 02 июня 2019

Чтобы сохранить это примерно в транспонировании , я использовал транспонированный массив для построения цели.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...