I am getting data from Access, copying into Excel sheet and creating a chart using Excel VBA. The data looks like this:
And the chart looks like this:
I want to show all transactions in sheet but in chart I want to show sum of amount of dates. For example on 19/08/2015 total amount 2695, 20/08/2015 total amount 287.
How can I create a chart in VBA Excel to show the sum of each day?
I agree with #ChipsLetten
1.- From SQL you could use something like this:
---- This is the sum for each day
SELECT
t.DOT, SUM(t.Amount)
---- You can add an extra Column with the SUM by Dates
/*
t.Dot, t.Category, t.Item, t.Amount
, SUM(t.Amount) OVER(PARTITION BY t.Dot ORDER BY t.Dot) [SumTrans]
*/
FROM Transactions t
GROUP BY t.DOT
-- If you add the Column you must change "GROUP BY"
-- GROUP BY t.Dot, t.Category, t.Item, t.Amount
Adding the column you could use the DOT and SumTrans series to create the Chart
2.- With pivot table is even better, you can clone your Recordset to create a pivot table that allows you to SUM Amount by DOT
*Wkb is a Workbooks object, Wks is a Worksheet object*
Dim oRstChrt As ADODB.Recordset, oStrm As ADODB.Stream
Dim oChrt As Chart
'' Copy Recordset for the pivot table cache
Set oRstChrt = New ADODB.Recordset
Set oStrm = New ADODB.Stream
'' Create an alternative Recordset for the new pivot table
oRst.Save oStrm
oRstChrt.Open oStrm
'' Set Recordset to cache for a pivot table
Set objPivotCache = _
Wkb.PivotCaches.Create(SourceType:=xlExternal, Version:=xlPivotTableVersion14)
'' Recordset with Data
Set objPivotCache.Recordset = oRstChrt
'' Assign Range for the pivot table and Name it.
With objPivotCache
.CreatePivotTable TableDestination:=Wks.Range([Cell]), TableName:=[PivotTable_Name]
End With
Afterwards put the fields you need,
in this case DOT and Amount
With Wks.PivotTables([PivotTable_Name])
With .PivotFields("DOT")
.Orientation = xlRowField
.Position = 1
End With
'' You can create a second level, but
'' if the field is not collapse, your chart will change,
'' so keep the field collapse
'' To Collapse the field put this
'' Wks.PivotTables([PivotTable_Name]). _
'' PivotFields([PivotTableField]).ShowDetail = False
'With .PivotFields("Item")
'.Orientation = xlRowField
'.Position = 2
'End With
'' This allows you to SUM the Amount field
.AddDataField .PivotFields("Amount"), "Total Amount", xlSum
End
'' After the Pivot Table was created you can create your chart
'' Set the object
Set oChrt = Charts.Add
'' Give a name and format
With oChrt
.Name = "[Chart_Name]"
.ChartType = xlColumnClustered '' you could change to 3D
'' Source Range in this case from the pivot table
.SetSourceData Source:=Wks.PivotTables([PivotTable_Name]).TableRange2, _
PlotBy:=xlRows
'' Format chart
.HasTitle = True
.ChartTitle.Text = "Total Transactions"
.Axes(xlCategory, xlPrimary).HasTitle = True
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Dates"
' .Axes(xlValue, xlPrimary).HasTitle = True
' .Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "Transactions"
End With
You have two choices:
Run another SQL query using SUM and GROUP BY to give you the totals. This is the data for your chart.
Look at using Pivot Charts in Excel. This will calc the totals for you and also draw the chart.
Related
Im trying to filter a pivot table column (GP#) from an array (shortened in this example).
The filter does work but when I get to a number (in this case 83292) that is not in the filter, the excel crashes with the error :
Runtime error 1004, application-defined or object-defined error
Is there a way of checking if a number/name etc is in the filter and if it is then apply to filter?
My code:
vGP = Array("83041", "83327", "83292")
ActiveSheet.PivotTables("PivotTable1").ManualUpdate = True
With ActiveSheet.PivotTables("PivotTable1").PivotFields("GP#")
.PivotItems(1).Visible = True
' below code ensure pivot table filter does not cause error by not having anything in the filter
For i = 2 To .PivotItems.Count
.PivotItems(i).Visible = False
If .PivotItems(i).Visible Then .PivotItems(i).Visible = False
Next i
' goes through array and adds any value in array
For Each i In vGP
.PivotItems(i).Visible = True
Next i
On Error GoTo 0
Can anyone please help ensuring that the values in the array can be added to the filter and values in the array that are not present in the pivot table are ignored
Try the code below to find if a certain array element is found within the PivotField you use named GP#.
Dim PvtTbl As PivotTable
Dim PvtFld As PivotField
Dim MatchFound As Boolean, i As Long
' set the Pivot Table
Set PvtTbl = ActiveSheet.PivotTables("PivotTable1")
' set the Pivot Field
Set PvtFld = PvtTbl.PivotFields("GP#")
MatchFound = False ' reset flag
For i = 1 To PvtFld.PivotItems.Count ' loop through all pivot items
If PvtFld.PivotItems(i).Name = vGP(1) Then ' check if the second array element is found in one of the Pivot items
MatchFound = True ' raisw flag
Exit For
End If
Next i
If MatchFound Then
PvtFld.PivotItems(i).Visible = True ' apply filter if the array element found
End If
Currently working on a vba script that makes charts automatically. I would like to add a datatable which is done using: .HasDataTable = True
However I would like to show the values of series as percentages. Currently the value is defined as a Double containing all the values but not the right formatting. Using Format() or FormatPercent() will give the right values but returned in a String. This works for the datatable but not for the chart itself since it doesn't recognize the values anymore.
My question comes down to whether it is possible to show the values as percentages in both the datatable and the chart? Without VBA it is easily done by formatting the data in the cells itself. The problem is that for formatting a String is returned but for the graph Integers or Doubles are needed.
Below is part of the code. If I dim Ratio as String and use FormatPercent() I get the requested formatting but then the values in Ratio ar no longer doubles so it doesn't give the required chart.
Dim Ratio() As Double
Dim labels() As String
ReDim Ratio(1 To Height)
ReDim labels(1 To Height)
For Each Column In sArray
labels(i) = Sheets(DataSheetName).Cells(LabelsRow, Column)
Ratio(i) = Math.Round(Sheets(DataSheetName).Cells(LabelsRow + 3, Column), 2)
i = i + 1
Next Column
Set myChtObj = Sheets(DrawSheetName).ChartObjects.Add(Left:=Left, Width:=Width, Top:=Top, Height:=HeightGraph)
Dim srsNew1 As Series
' Add the chart
With myChtObj.Chart
.ChartArea.Fill.Visible = False
.ChartArea.Border.LineStyle = xlNone
.PlotArea.Format.Fill.Solid
.PlotArea.Format.Fill.Transparency = 1
.HasTitle = True
.ChartTitle.text = Title
.HasLegend = False
.Axes(xlValue).TickLabels.NumberFormat = "0%"
.Axes(xlCategory, xlPrimary).HasTitle = False
'add data table
.HasDataTable = True
' Make Line chart
.ChartType = xlLine
' Add series
Set srsNew1 = .SeriesCollection.NewSeries
With srsNew1
.Values = Ratio
.XValues = labels
.Name = "Ratio"
.Interior.Color = clr3 'RGB(194, 84, 57)
End With
End With
I am trying to deselect all pre-set values in a slicer and then select values based on a list that will be updated on a daily basis. I managed to write the following code but it is running very very slow since my pre-set list was long. Is there a way to make the following run faster?
Sub cmdTop10PrioritySlicer()
Dim i As Integer
Dim MemberID As String
Application.ScreenUpdating = False
ThisWorkbook.SlicerCaches("Slicer1").ClearManualFilter
'Deselect all prior set values
For Each slc In ThisWorkbook.SlicerCaches("Slicer1").SlicerItems
slc.Selected = False
Next slc
'Select values in Slicer based on Top 10 Priority List
For i = 1 To 10
ID = ThisWorkbook.Worksheets("Summary").Range("A" & 57 + i).Value
ThisWorkbook.SlicerCaches("Slicer1").SlicerItems(ID).Selected = True
Next i
Application.ScreenUpdating = True
End Sub
I am trying to hide columns based on name using VBA inside Excel 2010. Each of my columns have a product version and some results below it. The product version does repeat throughout the spreadsheet since I have it categorized by OS. Thus, I'm hiding multiple columns based on selection, like a filter would do. If I could hide based on the name and not the column letter (A,B,C,...), then adding columns in between in the future would prevent more code changes on the location of those columns.
What I'm currently doing right now is fixed to the column letter. This limits me in the sense that I cannot add columns in between without having to change the code (column letter). Example:
`If productver_2dot5.Value = True Then
Columns("E").Hidden = False
Columns("M").Hidden = False
Columns("AC").Hidden = False
Columns("AT").Hidden = False
Columns("BD").Hidden = False
Columns("BR").Hidden = False
Else
Columns("E").Hidden = True
Columns("M").Hidden = True
Columns("AC").Hidden = True
Columns("AT").Hidden = True
Columns("BD").Hidden = True
Columns("BR").Hidden = True
End If`
What I would like to do is to hide any columns that contains the name 'Product Ver 2" (example) in one of its cells.
Sub HideBlahs()
Dim col As Range
For Each col In ActiveSheet.UsedRange.Columns
If Application.CountIf(col, "blah") > 0 Then
col.EntireColumn.Hidden = True
End If
Next col
End Sub
FYI your posted code reduces to:
Range("E1,M1,AC1,AT1,BD1,BR1").EntireColumn.Hidden = Not productver_2dot5.Value
I am creating a PivotTable from an Excel Sheet using VBA PivotTableWizard method.
I do define two row fields and two data fields with sum function. By default the name of the data fields appear in the Pivot Table as row description right from the row field names.
I wish to display the name of the data fields as column headers. In the Wizard the user would drag the "Sum sign - Values" field into the Column Labels box. How can this be done by code?
This is what I do have so far:
' Create the PivotTable object based on the data on the selected sheet
Set tm_volumes_pivot_table = ActiveSheet.PivotTableWizard
'Page fields
Set tm_volumes_pivot_field = tm_volumes_pivot_table.PivotFields("Article Type")
tm_volumes_pivot_field.Orientation = xlPageField
'Row fields
Set tm_volumes_pivot_field = tm_volumes_pivot_table.PivotFields("Main Area")
tm_volumes_pivot_field.Orientation = xlRowField
Set tm_volumes_pivot_field = tm_volumes_pivot_table.PivotFields("Subarea")
tm_volumes_pivot_field.Orientation = xlRowField
'Column fields
'Must be Names of Data Fields - how?
'Data fields
Set tm_volumes_pivot_field = tm_volumes_pivot_table.PivotFields("Initial Volume")
tm_volumes_pivot_field.Orientation = xlDataField
tm_volumes_pivot_field.Function = xlSum
tm_volumes_pivot_field.NumberFormat = "#"
Set tm_volumes_pivot_field = tm_volumes_pivot_table.PivotFields("Final Volume")
tm_volumes_pivot_field.Orientation = xlDataField
tm_volumes_pivot_field.Function = xlSum
tm_volumes_pivot_field.NumberFormat = "#"
Transfer OP's answer from question:
When a pivot table is going to have more than one data field, there is a virtual field named Values in the drop zones of the PivotTable Field List. In VBA, this equivalent virtual field is named "Data". - This will be used to arrange the Data in columns.
'Define Pivot Fields (Rows / Columns - Attention to "Data" / Page)
tm_volumes_pivot_table.AddFields Array("Main Area", "Subarea"), "Data", "Article Type"