How do I add sort to column headings in a caxlsx Pivot Table - axlsx

I've got a pivot table (see code below) where the source raw data is already sorted by client, year, and month. This means the row headings (A=Client, B=Year) are automatically sorted with the data, but the column headings (C2:N2=months of the year) become random ordered.
package.workbook.add_worksheet(name: "Samples Pivot") do |sheet|
data_range = "A1:E#{#raw_client_data_total_rows}"
sheet.add_pivot_table "A1:F1", data_range do |pivot_table|
pivot_table.data_sheet = package.workbook.worksheets.first
pivot_table.rows = %w[Client Year]
pivot_table.columns = %w[Month]
pivot_table.data = %w[Count]
end
end
If I open the spreadsheet in Excel, I can click on the auto-filter arrow on C1, which pops up an auto-filter dialog, and then I can manually sort the column headings by selecting "Ascending" and sort by "Month".
So is there a way to add this sort in caxlsx? I don't see any auto_filter attribute in PivotTable.

At the time of the question, that option wasn't available yet.
Feature implemented in PR#143

Related

How to move parts of a dynamic pivot table to a separate table?

I have pivot table pulling data from a query from a proprietary database system we use at work. I'm trying to figure out a way to move certain parts of the pivot table to a different sheet where it wouldn't exist as a pivot table there. My problem I'm running into is that the table changes the number of columns and rows depending upon the types and amounts of things that we shipped that shift, so I can't have it simply have my new table equal the cell values in the pivot table.
This is an example of the pivot data having fewer columns and rows based on what occurred that shift at work.
The reason why I would like this in a regular table as opposed to a pivot table is because there's other calculations I'd like to put into the table that extend beyond a pivot table's capabilities (ex. have the user id be displayed as their name, and have a weighted system based off of what the driver moves, but I suppose that's irrelevant.)
I've been poking around the internet, and it seems that the majority of answers to this issue deal with static tables. Any help would be appreciated!
Let's assume you want the cell to have the value from "BEER Total" for "M307577". Then this would be the formula you put in the cell:
=VLOOKUP("M307577",A5:Z100,MATCH("BEER Total",A5:Z5,0),FALSE)
"A5:Z100" would be the whole pivot table and "A5:Z5" would be the first row containing variables.
As you mentioned you are not familiar with VBA, I would suggest this approach:
Use the first column and first row of the second sheet as a reference. Refer to all the variables from the pivot table there (refer to the cell containing IDs and Variables, and pull the formula to the last row for IDs and last column for variables (or a reasonable range as last column and row would not be sufficient)). This will leave you with zeros, empty cells from the pivot table sheet, but will have all the names that you need.
Then refer to those cells and use the aforementioned formula (instead of names, use the cells that you just created).
Whenever the pivot table updates, those cells will be updated as well and you will see the values for the corresponding ID and Variable.
I think you want the GETPIVOTDATA function. Determine what your logic will look like and click on the appropriate combination of cells. Excel will automatically setup the GETPIVOTDATA function appropriately for you.
http://www.contextures.com/xlPivot06.html
Also, if the last used columns and last used rows are changing, you will probably need a Macro to help you with your task.
Sub LastRowInOneColumn()
'Find the last used row in a Column: column A in this example
Dim LastRow As Long
With ActiveSheet
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
MsgBox LastRow
End Sub
Sub LastColumnInOneRow()
'Find the last used column in a Row: row 1 in this example
Dim LastCol As Integer
With ActiveSheet
LastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
End With
MsgBox LastCol
End Sub
You can use a combination of functions to help you get the last used cell in a specific range.
https://exceljet.net/formula/address-of-last-cell-in-range
From there, I think you can figure out your next steps.
Post back with more information if you still have trouble with this, or start a new post if your question is answered.

Excel Autofilter, Copy selection, Paste to new sheet

I have a table with source data in columns Regions!A6:R553.
In Regions!A3:R3, I have formulas that pull specific information out of my data table in Regions!A6:R553 that I want copied to a different sheet.
Column A acts as my project name column, while column B holds ID numbers. In my case, there are multiple ID numbers per project.
I am looking for a script to filter and loop through all the unique order numbers in Column B one by one, then copy cells A3:R3 to RegionsSummary!A12:R12 for as many rows as there are unique order numbers (i.e, add rows to the table).
Here is a screengrab of my data sheet, "Regions":
i.stack.imgur.com/aTPuw.png
Here is a screengrab of the empty template sheet "RegionsSummary":
i.stack.imgur.com/9Ukz5.png
Example: Assume there are 5 projects in my data sheet. I will filter the data using another macro to select Project_1. I would then like a command button to active a macro that will filter to the first order number in Column B, copy Regions!A3:R3 to RegionsSummary!A12:R12, then filter to the second order number in Project_1, and repeat the process. This should go on until all unique ID numbers have been filtered and looped through.
Here is a screengrab of what a final product should look like:
i.stack.imgur.com/9Ukz5.png
Here is a link to the file: Final Output Example
I would go with an easier solution than a Macro with certain constraints. I am not able to access your sheet, so I will make a sample excel.
STEPS:
Create a list of unique projects for a dropdown (COPY Regions!A5:A10000 to a new sheet > Data > Remove Duplicates) . Create the dropdown (Data Validation > List > Select Range) using Data Validation in "Example_Result" sheet- C7.
In "Regions", in Col S, put the below formula
=S6&"_"&COUNTIF($S$6:S6,S6)
Copy this formula down for the entire sheet or as long as you expect the sheet to grow
In "Example_Result", insert an index column (1 to 1000, in Col A if you expect each project to have 1000 or less order numbers) from A12 onwards.
Along the columns (B onwards) of Row 11 include the names of the variables from Regions (Assessment Project, Highway etc).
Insert the below formula in B12 to S1000 (depending on number of variables) of Example_Result:
=IFERROR(INDEX(Regions!$A$5:$S$10000,MATCH($C$7&"_"&A$12,Regions!$S$5:$S$10000,0),MATCH(B$11,Regions!$A$5:$H$5,0)),"")

Macro or method to pivot data in Excel?

I am looking for a way to dynamically pivot data in an Excel sheet to put the data in a universal format no matter how wide the data set is.
For example: I want to be able to take a spreadsheet that could have 5 columns, 30 columns, or x number of columns to make it pivot to a universal format that is only three columns wide.
Here is a sample of how the original data could look:
I want it to look like this:
Is there a way to do it, either by macro or using any other Excel functions?
Assumes labels/data is in Sheet1 starting A1.
Insert a new ColumnA.
For Excel 2003: Activate any cell in your summary table and choose Data - PivotTable and PivotChart Report:
For later versions access the Wizard with Alt+D, P:
Select Multiple consolidation ranges and PivotTable and click Next >.
In “Step 2a of 3”, choose I will create the page fields and click Next >.
In “Step 2b of 3” (not shown in the modal!) specify your summary table range in the Range: field (A2:E6 for the sample data) and click Add, then Next >.
In “Step 3 of 3”, select a location for the PivotTable (the existing sheet should serve, as the PT is only required temporarily):
Click Finish to create the PivotTable:
Drill down (ie double-click) on the intersect of the Grand Totals (here Cell L4 or 16):
The PT may now be deleted.
In A2 of Table:
="Summary"&RIGHT(B2)
Convert the resulting Table into a conventional array of cells by selecting Table in the Quick Menu (right-click in the Table) and Convert to Range.
In a spare column starting in Row2 series fill integers down, from 1 to however many rows of data you started with (4, in the example). Then series fill that series to suit.
Sort sheet by that (spare) column, Smallest to Largest, with My data has headers checked.
Delete Row1 and spare column and hopefully you will end up with:

Copying values across a dynamic column and row range

I have the following code that:
copies the column headings (in row 1) from column C across to the second last column
pastes these column headings in row 1 in the column 2 across from the last column with data
pastes the column headings alongside each row of data through to the bottom row
Sub GLDR()
'use End(xlUp) to determine Last Row with Data, in column A of the GLDRYYPP tab
Dim lastRowDR As Long
lastRowDR = Sheets("GLDRYYPP").Range("A" & Rows.Count).End(xlUp).Row
'copy the cost type categories and paste alongside the cost centres
CTNameCol = "S2:AF" & lastRowDR
Sheets("GLDRYYPP").Range("C1", Range("C1").End(xlToRight).Offset(0, -1)).Copy
Sheets("GLDRYYPP").Paste Destination:=Sheets("GLDRYYPP").Range("C1").End(xlToRight).Offset(0, 2)
Sheets("GLDRYYPP").Range(Range("C1").End(xlToRight).Offset(0, 2), Range("C1").End(xlToRight).Offset(0, 2).End(xlToRight)).Copy
Sheets("GLDRYYPP").Paste Destination:=Sheets("GLDRYYPP").Range(CTNameCol)
End Sub
The first two steps have been set to be dynamic for any additional columns added but I am having trouble writing some code that will paste the data through to the bottom row. As you can see the range "S2:AF(last row)" has been written to make use of the result from the lastRowDR dimension.
Is there a way to write the code which will make the copy dynamic across the columns and rows?
Yes there is a way to write the code which will make the copy dynamic across the columns and rows. What you need to do is to identify a distinct quality about the cost centres so that you locate it using something like ActiveSheet.Cells.Find(Txt).
Then you'll be able to determine what CTNameCol should be. There is some helpful info here: Range.Find Method.
If you add add a picture of your spreadsheet I will update this answer with more precise information.

Sorting Worksheet data by column values using Excel VBA

I have next userform developed in vba, which takes info from a worksheet for displaying info
I want to order all the info aphabetically by a Segment, this is the code:
Function llenarDatosTabla()
Dim vList As Variant
Dim ws As Worksheet: Set ws = Worksheets(BD_PRODXSIST)
ListBox1.Clear
With ws
If (IsEmpty(.Range("AA2").Value) = False) Then
Dim ultimoRenglon As Long: ultimoRenglon = devolverUltimoRenglonDeColumna("A1", BD_PRODXSIST)
vList = ws.Range("AA2:AA" & ultimoRenglon & ":AL2").Value
If IsArray(vList) Then
Me.ListBox1.List = vList
Else
Me.ListBox1.AddItem (vList)
End If
End If
Me.ListBox1.ListIndex = -1
End With
Set vList = Nothing
Set ws = Nothing
End Function
how to make it ordered by 'AD' (SEGMENTO) column???
You can sort your Excel Worksheet in ascending order using VBA statement like the following:
Columns("A:XFD").Sort key1:=Range("AD:AD"), order1:=xlAscending, Header:=xlYes
Note: in the column range Columns("A:XFD") instead of XFD enter the last used column pertinent to your case, e.g. Columns("A:DD").
Hope this will help.
To sort a data table, use Excel Names in conjunction with the CurrentRegion function. This is less risky than hard-coding column references and can be done in two simple steps.
The reason it's preferable to specifying columns is that if you get the columns wrong or they change later, you'll scramble your data! When you perform the sort, the cells in any omitted column(s) will remain where they are, becoming part of the wrong rows. And this is exactly what will happen if you add further columns later, unless you remember to update your VBA.
Here are the two simple steps for using this approach. For this example, I've chosen a data table with four columns and four rows:
We are going to sort by COL3 descending. The cells in the other three columns share identical values, enabling us to readily verify they all stay with the correct rows.
Step 1: choose a cell in the data table that's unlikely to ever be removed, such as the header of a column you intend to make permanent, and define a Name for this cell. You can define the name by selecting the cell and typing directly in Excel's Name dropdown above the worksheet. Here I've used the name RegionTag:
Straight away, CurrentRegion can reference the whole data table just from this. You can see it in action if you code a line of VBA to select the table:
Range("RegionTag").CurrentRegion.Select
This is the result:
That's just for illustration, showing the power of the Name/CurrentRegion combination. We don't need to select the table in order to sort it.
Step 2: define a second Name, this time for the column you want to sort by:
Make sure the Name refers to the entire column, selected by clicking the column header, rather than just a range of cells in the column.
That's it! With these two Names defined, we can sort the data table without concerning ourselves with its rows and columns, even if more are added later:
Range("RegionTag").CurrentRegion.Sort _
key1:=Range("SortCol"), order1:=xlDescending, Header:=xlYes
Here is our data table sorted using the above statement: