Create Pivot Table Based on Dynamic Range - excel

I am trying to create a macro that will take data that starts at A18, find the last row and last column then generate a pivot table. I searched around to take bits and pieces from code I found online to try to make something work.
I keep getting a 1004 error, and I suspect it is because my code isn't actually selecting the data range properly.
this is the code that the error happens on:
Set pvtable = pvcache.CreatePivotTable(TableDestination:=pvsheet.Cells(1, 1), TableName:="Payroll")
this is all of the code:
Dim pvtable As PivotTable
Dim pvcache As PivotCache
Dim ptrange As Range
Dim pvsheet As Worksheet
Dim pdsheet As Worksheet
Dim plr As Long
Dim plc As Long
Dim startCell As Range
On Error Resume Next
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Worksheets("Pivot table").Delete 'to delete the existing pivot table in the worksheet
Worksheets.Add After:=ActiveSheet ' to add a new worksheet
ActiveSheet.Name = "Pivot Table" ' to rename the worksheet
On Error GoTo 0
Set pvsheet = Worksheets("Pivot table")
Set pdsheet = Worksheets("sheet1")
Set startCell = Range("A18")
'two variable to find Last used row and column in sheet 1, raw data'
plr = pdsheet.Cells(pdsheet.Rows.Count, startCell.Column).End(xlUp).Row
plc = pdsheet.Cells(startCell.Row, pdsheet.Columns.Count).End(xlToLeft).Column
'set range from selected data
Set ptrange = pdsheet.Cells(1, 1).Resize(plr, plc)
'pivot cahe needed for data load
Set pvcache = ActiveWorkbook.PivotCaches.Create(xlDatabase, SourceData:=ptrange)
'create empty pivot table
Set pvtable = pvcache.CreatePivotTable(TableDestination:=pvsheet.Cells(1, 1), TableName:="Payroll")
'Insert worker to Row Filed
With pvsheet.PivotTables("Payroll").PivotFields("Worker")
.Orientation = xlRowField
.Position = 1
End With
'Insert Street to Row Filed & position 2
With pvsheet.PivotTables("Payroll").PivotFields("Actual Hours")
.Orientation = xlRowField
.Position = 2
End With
'to show the pivot table in Tabular form
pvsheet.PivotTables("Payroll").RowAxisLayout xlTabularRow
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
I am suspecting the issue is within this area here where the data range is selected to make the pivot table:
Set pvsheet = Worksheets("Pivot table")
Set pdsheet = Worksheets("sheet1")
Set startCell = Range("A18")
'two variable to find Last used row and column in sheet 1, raw data'
plr = pdsheet.Cells(pdsheet.Rows.Count, startCell.Column).End(xlUp).Row
plc = pdsheet.Cells(startCell.Row, pdsheet.Columns.Count).End(xlToLeft).Column
'set range from selected data
Set ptrange = pdsheet.Cells(1, 1).Resize(plr, plc)
any help appreciated, thank you

Try defining your range as follows...
Set ptrange = pdsheet.Range(startCell, pdsheet.Cells(plr, plc))
Or, alternatively...
Set pdsheet = Worksheets("sheet1")
Set startCell = pdsheet.Range("A18")
With pdsheet
plr = .Cells(.Rows.Count, startCell.Column).End(xlUp).Row
plc = .Cells(startCell.Row, .Columns.Count).End(xlToLeft).Column
Set ptrange = .Range(startCell, .Cells(plr, plc))
End With

Related

Using Variable/Range as Worksheet and Table name

I am working with a workbook where you can choose a list of countries in a dropdown menu.
When changing the name, the Pivot table is updated to the corresponding Worksheet and Table.
The Pivot updating works and it changes the source depending on the country chosen.
The next step is that I want some data from the table that we connected to the worksheet to do some calculations.
If I choose the name of the worksheet and table directly in the "set" step, they are not changing depending on my dropdown selection.
Sub NORDICS()
Dim tblName As String
Dim ws1 As Worksheet
Dim ams As Long
Dim Target As Variant
Dim average As Variant
Dim tbl As ListObject
Set ws1 = Worksheets("Nordics")
Set tbl = ws1.ListObjects("TableNordics")
''What is the Table Name
Range("E3").Formula = "=""Table""&F3"
''Set tblName to the "calculated" table name above
tblName = Range("E3")
''Update the source to "PivotTable1" to be the tblName
Application.CutCopyMode = False
ActiveSheet.PivotTables("PivotTable1").ChangePivotCache ActiveWorkbook. _
PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
tblName, Version:=6)
ActiveSheet.ChartObjects("Chart 1").Activate
ActiveChart.FullSeriesCollection(2).Points(53).Select
Selection.Format.Line.EndArrowheadStyle = msoArrowheadStealth
''Collect the Last row of the Table Body
ans = tbl.DataBodyRange.Rows.Count
''Collect the Last cell value of column 8 and last row calculated above
Target = tbl.DataBodyRange(ans, 8).Value
''Collect the Total Rows Value from the Table
With tbl
average = .TotalsRowRange.Cells(.ListColumns.Count).Value
End With
''Calculate the average vs Target value and put in "W3"
Range("W3") = average - Target
''Remove Calculations done on worksheet that is not needed any more
Range("E3").Formula = "="""""
Range("E3").Value = Range("E3").Value
End Sub
My end goal would be that
Set ws1 = Worksheets("Nordics")
Set tbl = ws1.ListObjects("TableNordics")
is
Set ws1 = Worksheets = Range("F3")
Set tbl = ws1.ListObjects = Range("E3")

How to move a data set from one sheet to another based on criteria using VBA

I am trying to move data from one Table called Raw_Data on sheet Raw Data to another table called Phone_Number on sheet No Quality.
I have 16 columns on the tables and I need to confirm if the Raw Data table has the words No Quality or PH Phone on the 15th column. If it does then I want to move the data to the No Quality sheet and paste it into the table there. Once it is pasted I want to erase the data off of the Raw Data table.
I have tried a few different methods but can't seem to get them to work. Here is the first method I'm using
Sub Numbers()
Dim dataSheet As Worksheet, newSheet As Worksheet
Dim dataTable As ListObject, newTable As ListObject
Dim dataCount As Long
Dim checkOne As String, checkTwo As String
Dim copyRange As Range
Set dataSheet = Worksheets("Raw Data")
Set newSheet = Worksheets("No Quality")
Set dataTable = dataSheet.ListObjects("Raw_Data")
Set newTable = newSheet.ListObjects("Phone_Number")
checkOne = "PH Phone"
checkTwo = "No Quality"
dataCount = dataSheet.ListObjects("Raw_Data").ListRows.Count
dataValue = dataSheet.ListObjects("Raw_Data").DataBodyRange(dataCount, "O").Value
dataLocation = dataSheet.ListObjects("Raw_Data").DataBodyRange(dataCount, "O").row - 1
For i = 2 To dataLocation
valueToCheck = dataSheet.ListObjects("Raw_Data").DataBodyRange(i, "O")
If valueToCheck = checkOne Or valueToCheck = checkTwo Then
'Errors out on the line below
Worksheets("Raw Data").Range(Cells(i, "A"), Cells(i, "P")).Copy
Worksheets("No Quality").Cells(Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).row, 1).PasteSpecial
End If
Next i
End Sub
I can get it to partially run but it will never complete. I attempted to use the following code but I'm not sure how to change it to run in the way that I needed it.
Sub NoQuality()
Dim dataTable As Range
Dim newTable As Range
Application.ScreenUpdating = False
Set dataTable = Worksheets("Raw Data").ListObjects("Raw_Data").DataBodyRange
Set newTable = Worksheets("No Quality").ListObjects("Phone_Number").DataBodyRange
dataTable.Copy newTable.Offset(tbl2.Rows.Count)
Application.CutCopyMode = False
tbl1.ClearContents
Application.ScreenUpdating = True
End Sub
Results of New Code
You could probably get away with a lot less code. Please try the following & let me know how it goes.
Option Explicit
Sub Numbers()
Dim ws1 As Worksheet, ws2 As Worksheet
Set ws1 = Sheets("Raw Data")
Set ws2 = Sheets("No Quality")
With ws1.ListObjects("Raw_Data").Range
.AutoFilter 15, "No Quality", 2, "PH Phone"
.Offset(1).Resize(.Rows.Count - 1).Copy ws2.Cells(2, 1)
.Offset(1).Resize(.Rows.Count - 1).EntireRow.Delete
ws1.ListObjects("Raw_Data").AutoFilter.ShowAllData
End With
End Sub

How can I create a chart from unique values in a range

I have items that are being populated on a worksheet via userform. When I open the workbook I'm trying to get the tool to go to the sheet grab the data and generate a chart/dashboard on the main landing sheet.
In the range of data contains statuses. I want VBA to look through one column of data and create a chart that counts each different status and put that in a bar chart.
yaxis = the different statuses
xaxis = count
my code so far
Sub populatecharts()
Dim ws As Worksheet
Dim ch As Chart
Dim tablerng As Range
Dim rng1 As Range
Dim rng2 As Range
Dim rng3 As Range
Dim sh As String
Set ws = ActiveSheet
'When the workbook opens it should always check the data and populate the BA Dashboard
'I need to check for sheets and if they exist generate a chart from the data
sh = "Action"
On Error Resume Next
Worksheets("Action").Visible = True
If CheckSheetExist(sh) = False Then
GoTo nextchart1
Else
Worksheets(sh).Activate
'Set ws = ActiveSheet
Set rng1 = Range("G4", Range("G4", "G4").End(xlDown))
rng1.Select
'Set rng2 = Range("B2")
'Set rng3 = Range("C3")
'Set tablerng = rng1 '& rng2 & rng3
Set ch = ws.Shapes.AddChart2(Width:=200, Height:=200, Left:=Range("B4").Left, Top:=Range("B4").Top).chart
With ch
.SetSourceData Source:=rng1
.ChartType = xlBarClustered
.ChartTitle.Text = "Action Items by Status"
End With
ws.Activate
Worksheets("Action").Visible = False
End If
Seems easy but I'm not able to think through it, also the location is hit or miss even though I define the top and bottom and size. Sometimes it's to the right of the cell I chose to be the left.
Try the next way, please. It uses a dictionary to extract the unique values and their count and array to feed the necessary series. Try running it on active sheet and adapt it to your situation only after having the confirmation that what it returns is what you need:
Sub populatecharts()
Dim shT As Worksheet, ch As Chart, lastRow As Long
Dim arrY, arrX, i As Long, dict As Object
Set shT = ActiveSheet 'use here the sheet you need
lastRow = shT.Range("G" & shT.Rows.count).End(xlUp).row
arrX = shT.Range("G4:G" & lastRow).Value 'put the range in a array
Set dict = CreateObject("Scripting.Dictionary") 'needed for the next step
On Error Resume Next
shT.ChartObjects("MyChartXY").Delete 'for the case of re running need
On Error GoTo 0
For i = 1 To UBound(arrX)
If Not dict.Exists(arrX(i, 1)) Then
dict(arrX(i, 1)) = 1 'create the unique keys
Else
dict(arrX(i, 1)) = dict(arrX(i, 1)) + 1 'increment the key next occurrrence
End If
Next i
arrX = dict.Keys: arrY = dict.Items 'extract the necessary arrays
Set ch = shT.ChartObjects.Add(left:=shT.Range("B4").left, _
top:=shT.Range("B4").top, width:=200, height:=200).Chart
With ch
.ChartType = xlBarClustered
.HasTitle = True
.ChartTitle.Text = "Action Items by Status"
.SeriesCollection.NewSeries.Values = arrY 'feed it with the array elements
.SeriesCollection(1).XValues = arrX 'feed it with the array elements
End With
End Sub
Please, test it and send some feedback.

VBA-PIVOT TABLE WIZARD METHOD

I am trying to create a macro to build pivottable using the code at the following website:
http://msdn.microsoft.com/en-us/library/office/hh243933.aspx
but I kept getting
Error 1004: "UNABLE TO GET THE PIVOTFIELDS PROPERTY OF THE PIVOT TABLE
CLASS"
Any suggestions on the reason behind this problem and possible ways to fix it?
THIS IS MY CODE:
Sub CreatePivot()
' Creates a PivotTable report from the table on Sheet1
' by using the PivotTableWizard method with the PivotFields
' method to specify the fields in the PivotTable.
Dim objTable As PivotTable, objField As PivotField
' Select the sheet and first cell of the table that contains the data.
ActiveWorkbook.Sheets("Sheet1").Select
Range("A2").Select
' Create the PivotTable object based on the Employee data on Sheet1.
Set objTable = Sheet1.PivotTableWizard
' Specify row and column fields.
***Set objField = objTable.PivotFields("v1")*** ' <-- This where I get the Error
objField.Orientation = xlColumnField
Set objField = objTable.PivotFields("Temperature")
objField.Orientation = xlRowField
' Specify a data field with its summary
' function and format.
Set objField = objTable.PivotFields("clkui")
objField.Orientation = xlDataField
objField.Function = xlSum
objField.NumberFormat = "$ #,##0"
' Specify a page field.
Set objField = objTable.PivotFields("db")
objField.Orientation = xlPageField
' Preview the new PivotTable report.
ActiveSheet.PrintPreview
' Prompt the user whether to delete the PivotTable.
Application.DisplayAlerts = False
If MsgBox("Delete the PivotTable?", vbYesNo) = vbYes Then
ActiveSheet.Delete
End If
Application.DisplayAlerts = True
End Sub
enter image description here
Try the code below to create a new table in Sheet1 (not sure what's the sheet's name) from the data in "Sheet1" :
Option Explicit
Sub CreatePivot()
' Creates a PivotTable report from the table on Sheet1
' by using the PivotTableWizard method with the PivotFields
' method to specify the fields in the PivotTable.
Dim objTable As PivotTable
Dim objTblCache As PivotCache
Dim objField As PivotField
Dim PvtSht As Worksheet
Dim LastRow As Long, LastCol As Long
Dim SrcRng As Range
' Select the sheet and first cell of the table that contains the data
With ThisWorkbook.Sheets("Sheet1")
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
LastCol = .Cells(2, .Columns.Count).End(xlToLeft).Column
Set SrcRng = .Range(.Cells(2, "A"), .Cells(LastRow, LastCol)) ' <-- set the Pivot's dynamic Range (starts from "A2")
End With
' Option 1: Define Pivot Cache
Set objTblCache = ActiveWorkbook.PivotCaches.Create(xlDatabase, SrcRng)
' Option 2: Define Pivot Cache
Set objTblCache = ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:=SrcRng.Address(True, True, xlA1, True))
' Create the PivotTable object based on the Employee data on Sheet1.
Set objTable = Sheet1.PivotTables.Add(PivotCache:=objTblCache, TableDestination:=Sheet1.Cells(1, LastCol + 2), TableName:="PivotTable1")
' Specify row and column fields.
With objTable
.PivotFields("v1").Orientation = xlColumnField
.PivotFields("Temperature").Orientation = xlRowField
' Specify a data field with its summary
' function and format.
Set objField = .PivotFields("clkui")
With objField
.Orientation = xlDataField
.Function = xlSum
.NumberFormat = "$ #,##0"
End With
' Specify a page field.
.PivotFields("db").Orientation = xlPageField
End With
' rest of your code goes here ....
End Sub

Pivot Table error whilecreating using VBA

Good mrng!
I am trying to create pivot table using vba and i am very new to pivot using vba and i tried to research in google as much as possible to get this corrected but didnt find much info which can help me to fix it, would be of great help if anyone can help me with this.
Range - always starts from A10, columns will be fixed until H but number of rows are not fixed hence i tried to define the range and use it in the code but its throwing me below error message, please check and correct me
Issues faced-Not able to define Rng as Range and not able to use this range in the pivot table.
Rng as Range
Run time error '91': Object variable or with black variance not set
Pivot cache
Run Time error '438': Object doesn't support this property or method
Data
ACT AN Currency CB LC Type CB FC Type SI
1001 c USD 2,031 Dr 2,031 Dr 0005
1002 a BHD 1,194 Dr 1,194 Dr 0105
1003 P EUR 326 Dr 326 Dr 0110
1004 AR GBP 60,467 Dr 60,467 Dr 0125
1005 AP DHS (73,080) Cr (73,080) Cr 0190
Sub Pivot()
Dim ws As Worksheet
Dim pc As PivotCache
Dim pt As PivotTable
'Dim Rng As Range
'Defining Range
Rng = Range("A10").Select
Rng = Range(Selection, Selection.End(xlToRight)).Select
Rng = Range(Selection, Selection.End(xlDown)).Select
'Adding new worksheet
Set ws = Worksheets.Add
'Creating Pivot cache
Set pc = ActiveWorkbook.PivotCaches.Create(xlDatabase, "Working!Rng").Select
'Creating Pivot table
Set pt = pc.CreatePivotTable(ws.Range("B3"))
'Setting Fields
With pt
'set row field
With .PivotFields("SI")
.Orientation = xlRowField
.Position = 1
End With
'set column field
With .PivotFields("Currency")
.Orientation = xlColumnField
.Position = 1
End With
End With
End Sub
Thanks for your help!
Regards
Suresh7860
Try and use the below code as a sample for what you need. If anything is unclear I will be happy to answer. But you won't learn if I write the code for you.
Sub BuildPT()
Dim pvtTbl As PivotTable
Dim pvtCha As PivotCache
Dim pvtDestWS As Worksheet
Dim pvtSrcWS As Worksheet
Dim pvtWB As Workbook
Dim pvtSrcRng As Range
Dim pvtStrt As Range
Dim keyRng As Range
Dim LastRow As Integer
Dim LastCol As Integer
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
On Error Resume Next
pvtWB.Worksheets("Total").Delete 'Delete PT destination sheet
On Error GoTo 0
Set pvtSrcWS = pvtWB.Worksheets("Data") 'Set source sheet name
'Here I find the last row and column containing data
LastRow = pvtSrcWS.Cells.Find(What:="*", After:=pvtSrcWS.Range("A1"), LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False, MatchByte:=False).row
LastCol = pvtSrcWS.Cells.Find(What:="*", After:=pvtSrcWS.Range("A1"), LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False, MatchByte:=False).Column
Set pvtSrcRng = Range(pvtSrcWS.Cells(1, 3), pvtSrcWS.Cells(LastRow, LastCol)) 'Set the range that contains the source data
Set pvtDestWS = pvtWB.Sheets.Add 'Add the destination sheet
pvtDestWS.Name = "Total" 'Rename destination sheet
Set pvtStrt = pvtDestWS.Cells(1, 1) 'Set the PT start location
'Here I create the pivot cache, the container that holds pivot table data
'Then I create the pivot table itself
Set pvtCha = pvtWB.PivotCaches.Create(xlDatabase, pvtSrcRng)
Set pvtTbl = pvtCha.CreatePivotTable(TableDestination:=pvtStrt, TableName:="Test PT")
'Now I add the fields I need
With pvtTbl
With .PivotFields("Amount")
.Orientation = xlDataField
.Function = xlSum
.NumberFormat = "#,##0"
End With
With .PivotFields("Account")
.Orientation = xlPageField
.CurrentPage = "513035"
End With
.PivotFields("Key").Orientation = xlRowField
.RepeatAllLabels xlRepeatLabels
End With
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub

Resources