Unpivot an Excel matrix/pivot-table?

∥☆過路亽.° 提交于 2020-01-27 08:40:28

问题


Is there a quick way to "unpivot" an Excel matrix/pivot-table (in Excel or elsewhere), without writing macros or other code ?
Again, I can write code (C# or VBA or whatever) that does that myselfs.
I want to know if it is possible to do it without code, quickly ?

E.g. I need to convert this permission matrix (given as Excel-table/matrix)

into this half-normalized table (so I can insert it into a SQL database):

e.g. in SQL I could do it like this:

CREATE TABLE dbo.T_DocumentMatrix
(
    [Function] [varchar](255) NULL,
    [GROUP-Admin] [varchar](255) NULL,
    [GROUP-SuperUser] [varchar](255) NULL,
    [GROUP-Manager] [varchar](255) NULL,
    [GROUP-OLAP] [varchar](255) NULL,
    [GROUP-1] [varchar](255) NULL,
    [GROUP-2] [varchar](255) NULL,
    [GROUP-3] [varchar](255) NULL,
    [GROUP-4] [varchar](255) NULL,
    [GROUP-5] [varchar](255) NULL,
    [GROUP-6] [varchar](255) NULL,
    [GROUP-7] [varchar](255) NULL,
    [GROUP-8] [varchar](255) NULL,
    [Externals] [varchar](255) NULL
); 

copy-paste the data from excel, and then

SELECT * 
FROM 
(
    SELECT 
         [Function]
        ,[GROUP-Admin]
        ,[GROUP-SuperUser]
        ,[GROUP-Manager]
        ,[GROUP-OLAP]
        ,[GROUP-1]
        ,[GROUP-2]
        ,[GROUP-3]
        ,[GROUP-4]
        ,[GROUP-5]
        ,[GROUP-6]
        ,[GROUP-7]
        ,[GROUP-8]
        ,[Externals]
    FROM T_DocumentMatrix
) AS p
UNPIVOT
(
    Rights FOR GroupName IN 
    (
         [GROUP-Admin]
        ,[GROUP-SuperUser]
        ,[GROUP-Manager]
        ,[GROUP-OLAP]
        ,[GROUP-1]
        ,[GROUP-2]
        ,[GROUP-3]
        ,[GROUP-4]
        ,[GROUP-5]
        ,[GROUP-6]
        ,[GROUP-7]
        ,[GROUP-8]
        ,[Externals]
    )
) AS unpvt
;

However, that requires I change the table-create script and the unpivot-script for every change in groups...


回答1:


Oh, well, it's a little complicated. One of the problems is, the wizard-callup shortcuts don't work in non-english versions of excels (damn, at home I would have the English version, but here at work...)

Here's a good video: https://www.youtube.com/watch?v=pUXJLzqlEPk

But youtube videos can be deleted, so to make it a solid SO answer:

First, you need to go to "Options", and add the menuband-item "Pivot table and PivotChart Wizard".

Create a multiple consolidation pivot table

and use the custom variant

and select the range, and in new work sheet

then delete rows and columns fields

Double click on the NUMBER (54 in the picture)

and excel will give you the halfway normalized data.




回答2:


There's another way now through Power Query:

  • select your cells
  • menu Data > From a table or a range screenshot
  • in the Power Query editor, chose all columns save the first one and then Transform > Unpivot screenshot
  • the table is unpivoted. go to Home > Close and load screenshot
  • your unpivoted table is here. right-click it and choose Refresh if your original table is updated screenshot



回答3:


I am using this VBA code

Sub Unpivot()
'
Dim Rowlabel As Range
Dim Columnlabel As Range
Dim Pap As Range
Dim Tabl As Range
Dim i As Integer
Dim j As Integer
Dim a As Integer
Dim b As Integer
Dim Data As Range
Dim k As Integer
Dim Label As Range
Dim pvtCache As PivotCache
Dim pvt As PivotTable
Dim SrcData As String
'
ActiveSheet.Copy Before:=Worksheets(1)
Set Tabl = Selection
    For Each Pap In Tabl
     If Pap.MergeCells Then
        With Pap.MergeArea
            .UnMerge
            .Value = Pap.Value
        End With
    End If
    Next
i = Application.InputBox("Number of row contain label:", "Excel", i, Type:=2)
j = Application.InputBox("Number of column contain label:", "Excel", j, Type:=2)
On Error Resume Next
Sheets("Unpivot_Table").Delete
Sheets.Add.Name = "Unpivot_Table"
Set Pap = Range("Unpivot_Table!B2")
b = Tabl.Rows.Count
a = Tabl.Columns.Count
Set Data = Range(Tabl.Cells(i + 1, j + 1), Tabl.Cells(b, a))
Set Columnlabel = Range(Tabl.Cells(i + 1, 1), Tabl.Cells(b, j))
Set Rowlabel = Range(Tabl.Cells(1, j + 1), Tabl.Cells(i, a))
Pap.Select
For Each Column In Data.Columns
    Column.Copy
    Selection.PasteSpecial Paste:=xlPasteValues
    Columnlabel.Copy
    Selection.Offset(0, 1).PasteSpecial Paste:=xlPasteValues
    Column.Copy
    Selection.Offset(b - i, -1).Select
Next Column
Pap.Offset(0, j + 1).Select
For Each Column In Rowlabel.Columns
    Column.Copy
    Range(Selection, Selection.Offset(b - i - 1, 0)).PasteSpecial Paste:=xlPasteValues, Transpose:=True
    Selection.End(xlDown).Offset(1, 0).Select
Next Column
Set Label = Range(Pap.Offset(-1, 0), Pap.Offset(0, i + j + 1))
    For k = 1 To i + j + 1
    Label.Cells(1, k).Value = Application.InputBox(Label.Cells(2, k).Value & " is belong to Fieldname", "Hoang", k, Type:=2)
    Next
Range(Pap.End(xlUp), Pap.End(xlDown).End(xlToRight)).Select
SrcData = ActiveSheet.Name & "!" & Selection.Address
On Error Resume Next
    Sheets("Pivot").Delete
    Sheets.Add.Name = "Pivot"
  Set pvtCache = ActiveWorkbook.PivotCaches.Create( _
    SourceType:=xlDatabase, _
    SourceData:=SrcData)
  Set pvt = pvtCache.CreatePivotTable( _
    TableDestination:="Pivot!" & Sheets("Pivot").Range("A3").Address(ReferenceStyle:=xlR1C1), _
    TableName:="PivotTable1")
End Sub


来源:https://stackoverflow.com/questions/32115219/unpivot-an-excel-matrix-pivot-table

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!