I have a data set that has 50+ columns and it contains monthly sales data. I do not have access to underlying data but I need to be able to manipulate the data. Below is an example of the data set, is there a way to put Jan, Feb, Mar to a Column called “Month” and underlying data in a new column called “Values”? I am aware this can be easily done in Excel Power Query but I do not have the option of using Power Query.
1
I do not believe you can do this using Power Pivot.
Since you have excluded using Power Query (which would be the simplest method) you could do this with an Excel worksheet formula, if you have 365
.
Note that I used Structured References
in the formula below, but you can use regular addressing if you prefer. If not, change Table12
to whatever your named table is.
The formula as written should adjust for additional rows and columns. If you change to regular addressing, you will need to change the references yourself near the beginning of the formula:
=LET(
d, Table12,
hdrs, DROP(Table12[#Headers], , 1),
rws, QUOTIENT(SEQUENCE(ROWS(d) * (COLUMNS(hdrs)), , 0), COLUMNS(hdrs)) + 1,
a, TAKE(CHOOSEROWS(d, rws), , 1),
v, TOCOL(DROP(d, , 1)),
cols, MOD(SEQUENCE(ROWS(d) * COLUMNS(hdrs), , 0), COLUMNS(hdrs)) + 1,
mnths, TOCOL(CHOOSECOLS(hdrs, cols)),
pivot, VSTACK({"Country", "Month", "Value"}, HSTACK(a, mnths, v)),
pivot
)
0
Do you have the option SQLServer? There is a simple piece of code you can write to unpivot data in excel. As far as I am aware in excel and SQL you will only have the data that is shown in the screenshot when you unpivot. So if the pivot table is excluding data I’m unsure if you will ever get that back
Universal macro to unpivot a table
You can use the next macro to unpivot any table:
Sub Unpivot()
Dim cws As Worksheet, vs As Long, cr As Long, cc As Long, i As Long, k As Long
Dim dr As Long, dc As Long, da As Long, ca As Variant, cb As Variant
Dim left As Long, right As Long, up As Long, down As Long
cr = ActiveCell.Row: cc = ActiveCell.Column
left = Cells(cr - 1, cc).End(xlToLeft).Column: up = Cells(cr, cc - 1).End(xlUp).Row
right = cc: While Not IsEmpty(Cells(up, right + 1)): right = right + 1: Wend
down = cr: While Not IsEmpty(Cells(down + 1, left)): down = down + 1: Wend
Set cws = ActiveSheet: ThisWorkbook.Sheets.Add: i = 1
cws.Range(cws.Cells(cr - 1, left), cws.Cells(cr - 1, cc - 1)).Copy
[A1].PasteSpecial xlPasteValues: dr = cr - up: dc = cc - left + 1
If dr > 1 Then
cws.Range(cws.Cells(up, cc - 1), cws.Cells(cr - 2, cc - 1)).Copy
Cells(1, dc).PasteSpecial Paste:=xlPasteValues, Transpose:=True
End If
da = dc + dr: Cells(1, da - 1) = "TBD": Cells(1, da) = "Value"
k = 2: vs = right - cc + 1: dr = dr + 1
cb = WorksheetFunction.Transpose(cws.Cells(up, cc).Resize(cr - up, right - cc + 1))
For i = cr To down
ca = cws.Range(cws.Cells(i, left), cws.Cells(i, cc - 1))
Cells(k, 1).Resize(vs, dc - 1) = ca: Cells(k, dc).Resize(vs, dr) = cb
cws.Cells(i, cc).Resize(1, vs).Copy
Cells(k, da).PasteSpecial Paste:=xlPasteValues, Transpose:=True
k = k + vs
Next
End Sub
In the table (it can be located anywhere on the sheet and should be limited by empty cells), select the pivot cell:
Then run the macro. The resulting table will be created on the new sheet:
It’s expected the cells to left from one cell above the pivot cell, up from one cell to left from it, the leftmost column and the topmost row are not empty.
The source table can contain any number of common columns and header rows:
Alternatively, if empty cells are inside the table
the next macro can be used:
Sub Unpivot2()
Dim cws As Worksheet, vs As Long, cr As Long, cc As Long, i As Long, k As Long
Dim dr As Long, dc As Long, da As Long, ca As Variant, cb As Variant
Dim left As Long, right As Long, up As Long, down As Long
cr = ActiveCell.Row: cc = ActiveCell.Column
left = Selection.Column: up = Selection.Row
right = Selection.Column + Selection.Columns.Count - 1
down = Selection.Row + Selection.Rows.Count - 1
Set cws = ActiveSheet: ThisWorkbook.Sheets.Add: i = 1
cws.Range(cws.Cells(cr - 1, left), cws.Cells(cr - 1, cc - 1)).Copy
[A1].PasteSpecial xlPasteValues: dr = cr - up: dc = cc - left + 1
If dr > 1 Then
cws.Range(cws.Cells(up, cc - 1), cws.Cells(cr - 2, cc - 1)).Copy
Cells(1, dc).PasteSpecial Paste:=xlPasteValues, Transpose:=True
End If
da = dc + dr: Cells(1, da - 1) = "TBD": Cells(1, da) = "Value"
k = 2: vs = right - cc + 1: dr = dr + 1
cb = WorksheetFunction.Transpose(cws.Cells(up, cc).Resize(cr - up, right - cc + 1))
For i = cr To down
ca = cws.Range(cws.Cells(i, left), cws.Cells(i, cc - 1))
Cells(k, 1).Resize(vs, dc - 1) = ca: Cells(k, dc).Resize(vs, dr) = cb
cws.Cells(i, cc).Resize(1, vs).Copy
Cells(k, da).PasteSpecial Paste:=xlPasteValues, Transpose:=True
k = k + vs
Next
End Sub
It’s necessary to select the whole table then activate the pivot cell using “Enter” and “Tab” keys
3