how to Create a varios graphs in excel VBA - excel

I made a code to create a one chart by vba excel. But I am not able to make a code where I can generate several graphs in the same worksheet, that is, I have 4 columns, I want to create 4 graphs.
Could someone help me with this task?
This is my code:
Sub create_BarChart()
Dim myWorksheet As Worksheet
Dim mySourceData As Range
Dim myChart As Chart
Dim myShape As Shape
Dim myChartDestination As Range
Set myWorksheet = ThisWorkbook.Worksheets("corelacao")
Set myChartDestination = myWorksheet.Range("D36:H45")
Set myShape = myWorksheet.Shapes.AddChart(Excel.XlChartType.xl3DBarClustered)
Set myChart = myShape.Chart
With myChart
.SetSourceData Source:=myWorksheet.Range("B1:C32")
.ChartTitle.Text = "Analise de correlações"
.Legend.Left = 250 'posição vertical
.Legend.Width = 300 '100
.Parent.Height = 200
.Parent.Width = 269
.Parent.Left = 95
End With
With myShape
.Height = 325 ' resize
.Top = 300 ' reposition
.Left = 100 ' reposition
.Fill.ForeColor.RGB = RGB(230, 225, 220)
.Fill.Solid
End With
End Sub

I would specify input ranges for the chart in an array variable and look thru the array to generate the charts:
Dim arr(2) As String
Dim mySourceData As Range
Dim myChart As Chart
Dim myShape As Shape
Dim myChartDestination As Range
Dim myWorksheet As Worksheet
Set myWorksheet = ActiveSheet
'Data area for each chart
arr(1) = "B1:C32"
arr(2) = "B1:B31,D1:D31"
For a = 1 To 2
Set myChartDestination = myWorksheet.Range("D36:H45")
Set myShape = myWorksheet.Shapes.AddChart(Excel.XlChartType.xl3DBarClustered)
Set myChart = myShape.Chart
With myChart
.SetSourceData Source:=myWorksheet.Range(arr(a))
.ChartTitle.Text = "Analise de correlações"
.Legend.Left = 250
.Legend.Width = 300
.Parent.Height = 200
.Parent.Width = 269
.Parent.Left = 95
End With
With myShape
.Height = 325
.Top = 300
.Left = 100 + ((a - 1) * 250)
.Fill.ForeColor.RGB = RGB(230, 225, 220)
.Fill.Solid
End With
Next

Related

VBA-Excel - Graph creator

I'm trying to create a code for generate some graphs with some data already stored in arrays.
The actual final result of the macro is this graph:
The code used for it is the following:
Dim sht As Worksheet
Set sht = ActiveSheet
Dim chtObj As ChartObject
Set chtObj = sht.ChartObjects.Add(100, 10, 500, 300)
Dim cht As Chart
Set cht = chtObj.Chart
If IsZeroLengthArray(yData_TSI) = False Then
Dim ser As Series
Set ser = cht.SeriesCollection.NewSeries
ser.Values = yData_TSI
ser.XValues = xData_TSI
ser.Name = "TSI Predicant"
ser.ChartType = xlXYScatterSmooth
End If
If IsZeroLengthArray(yData_Pallet) = False Then
Dim ser2 As Series
Set ser2 = cht.SeriesCollection.NewSeries
ser2.Values = yData_Pallet
ser2.XValues = xData_Pallet
ser2.Name = "Pallet Decant"
ser2.ChartType = xlXYScatterSmooth
End If
If IsZeroLengthArray(yData_Vendor) = False Then
Dim ser3 As Series
Set ser3 = cht.SeriesCollection.NewSeries
ser3.Values = yData_Vendor
ser3.XValues = xData_Vendor
ser3.Name = "Vendor Decant"
ser3.ChartType = xlXYScatterSmooth
End If
If IsZeroLengthArray(yData_Prep) = False Then
Dim ser4 As Series
Set ser4 = cht.SeriesCollection.NewSeries
ser4.Values = yData_Prep
ser4.XValues = xData_Prep
ser4.Name = "Each"
ser4.ChartType = xlXYScatterSmooth
End If
If IsZeroLengthArray(yData_Each) = False Then
Dim ser5 As Series
Set ser5 = cht.SeriesCollection.NewSeries
ser5.Values = yData_Each
ser5.XValues = xData_Each
ser5.Name = "Prep"
ser5.ChartType = xlXYScatterSmooth
End If
I have in other arrays (tData_XXX) numbers that I would like to add as a label to the bullet points in the graph. To make myself clear, for the same graph generated before, let's imagine than for the "Vendor Decant" data the tData_Vendor array has the numbers (34, 5, 12). The desired result should be something like this:
How can I do this on the code?
Thanks!
Note:
All the arrays (yData_XXX, xData_XXX and tData_XXX) are always the same size
Untested, but something like this should work:
Sub CreateChart()
Dim sht As Worksheet, chtObj As ChartObject, cht As Chart
Set sht = ActiveSheet
Set chtObj = sht.ChartObjects.Add(100, 10, 500, 300)
Set cht = chtObj.Chart
AddSeries cht, "TSI Predicant", yData_TSI, xData_TSI, tData_TSI
AddSeries cht, "Pallet Decant", yData_Pallet, xData_Pallet, tData_Pallet
AddSeries cht, "Vendor Decant", yData_Vendor, xData_Vendor, tData_Vendor
AddSeries cht, "Each", yData_Prep, xData_Prep, tData_Prep '???
AddSeries cht, "Prep", yData_Each, xData_Each, tData_Each '???
End Sub
Sub AddSeries(cht As Chart, seriesName As String, xVals, yVals, labelVals)
Dim i As Long
If Not IsZeroLengthArray(yVals) Then
With cht.SeriesCollection.NewSeries
.ChartType = xlXYScatterSmooth
.Values = yVals
.XValues = xVals
.Name = seriesName
.ApplyDataLabels
'loop over series points and apply label from array
For i = 1 To .Points.Count
.Points(i).DataLabel.Text = labelVals(i - 1) 'assuming arrays are zero-based
Next
End With
End If
End Sub
Note you can reduce your code volume by factoring out the repeated "add a series" steps into a separate method.

VBA place two charts on one sheet

How can I place two different sheets on one page.
I create a chart with this code
'Create a chart
Set cht = Worksheets("Dashboard").Shapes.AddChart2
'Set cht = ActiveSheet.Shapes.AddChart2
With cht
.Chart.SetSourceData Source:=rng 'Give chart some data
.Chart.ChartType = xlColumnStacked 'Determine the chart type
.Chart.PlotBy = xlColumns
.ScaleHeight 1.7, msoFalse
.Chart.SetElement (msoElementLegendRight)
.Chart.ChartTitle.Text = Range("E1")
End With
Worksheets("Dashboard").Select
ActiveSheet.ChartObjects(1).Name = "FalseCall"
Range("A1") = ActiveSheet.ChartObjects(1).Name
ActiveSheet.Shapes("FalseCall").Left = Range("A1").Left
ActiveSheet.Shapes("FalseCall").Top = Range("A1").Top
ActiveSheet.Shapes("FalseCall").Width = Range("A1:G1").Width
ActiveSheet.Shapes("FalseCall").Height = Range("A1:A26").Height
It will add a chart on sheet "Dashboard".
Next I want to add a new chart with another name on the same page on H1 with
ActiveSheet.ChartObjects(1).Name = "Ng"
The existing chart will be renamed with the name of the second Chart and moves to H1, instead of the new chart is getting that name and moving the H1
It's not more complicated than repeating the steps with new ranges specified.
Sub InsertTwoCharts()
Dim ws As Worksheet
Set ws = Worksheets("Dashboard")
' CHART 1
' range that chart will cover
Dim ChtRng1 As Range
Set ChtRng1 = ws.Range("A1:G26")
' chart data range
Dim ChtData1 As Range
Set ChtData1 = Worksheets("Whatever").Range("A1:E12") ' or whatever
' insert and modify the chart
Dim cht1 As ChartObject
Set cht1 = ws.Shapes.AddChart2
With cht1
.Name = "FalseCall"
.Chart.SetSourceData Source:=ChtData1, PlotBy:=xlColumns
.Chart.ChartType = xlColumnStacked
.Chart.SetElement msoElementLegendRight
.Chart.ChartTitle.Text = ws.Range("E1").Value ' pick a worksheet and cell
.Left = ChtRng1.Left
.Top = ChtRng1.Top
.Width = ChtRng1.Width
.Height = ChtRng1.Height
End With
' CHART 2
' range that chart will cover
Dim ChtRng2 As Range
Set ChtRng2 = ws.Range("H1:N26")
' chart data range
Dim ChtData2 As Range
Set ChtData2 = Worksheets("Whatever").Range("G1:K12") ' or whatever
' insert and modify the chart
Dim cht2 As ChartObject
Set cht2 = ws.Shapes.AddChart2
With cht2
.Name = "TrueCall"
.Chart.SetSourceData Source:=ChtData1, PlotBy:=xlColumns
.Chart.ChartType = xlColumnStacked
.Chart.SetElement msoElementLegendRight
.Chart.ChartTitle.Text = ws.Range("H1").Value ' pick a worksheet and cell
.Left = ChtRng2.Left
.Top = ChtRng2.Top
.Width = ChtRng2.Width
.Height = ChtRng2.Height
End With
End Sub

how do i offset all the charts in the same worksheet in VBA?

Currently, all my charts are cramped together in the same spot in the same worksheet after running my code. So to view them i have to manually drag and move them to another spot. So is there a way such that i can place all the charts in a orderly manner as shown in expected output? If it is really impossible to do something like this, i am ok with offsetting the graph for every 20 cells even though it is abit inconvenient for viewing but still i attempted to do it but fail to make it happen when i include code with current output with the offsetting code.
Current output(looks like there is 1 chart but all the charts are in the same spot)
Below is the code for my current output
Sub plotgraphs()
'Call meangraph
Call sigmagraph
End Sub
Private Sub sigmagraph()
Dim i As Long, c As Long
Dim shp As Shape
Dim Cht As chart, co As Shape
Dim rngDB As Range, rngX As Range, rngY As Range
Dim Srs As Series
Dim ws As Worksheet
Set ws = Sheets("Data")
Set rngDB = ws.Range("A1").CurrentRegion
Set rngX = rngDB.Columns(1)
Set rngY = rngDB.Columns(4)
Do While Application.CountA(rngY) > 0
Set co = Worksheets("meangraphs").Shapes.AddChart
Set Cht = co.chart
With Cht
.ChartType = xlXYScatter
'remove any data which might have been
' picked up when adding the chart
Do While .SeriesCollection.Count > 0
.SeriesCollection(1).Delete
Loop
'add the data
With .SeriesCollection.NewSeries()
.XValues = rngX.Value
.Values = rngY.Value
End With
'formatting...
With Cht.Axes(xlValue)
.MinimumScale = 0
.MaximumScale = 0.5
.TickLabels.NumberFormat = "0.00E+00"
End With
Cht.Axes(xlCategory, xlPrimary).HasTitle = True
Cht.Axes(xlValue, xlPrimary).HasTitle = True
End With
Set rngY = rngY.Offset(0, 2) 'next y values
Loop
Code for offsetting chart for every 20 cells (fail to make it happen)
Dim OutSht As Worksheet
'
Dim PlaceInRange As Range
Set OutSht = ActiveWorkbook.Sheets("sigmagraphs") '<~~ Output sheet
Set PlaceInRange = OutSht.Range("B2:J21") '<~~ Output location
'
' To place charts at a distance between them
For Each chart In Sheets("sigmagraphs").ChartObjects
' OutSht.Paste PlaceInRange
' Code below changes the range itself to something 20 rows below
Set PlaceInRange = PlaceInRange.Offset(20, 0)
Next chart
Expected output
What you are looking for is the .Left and .Top properties of the Shape containing the Chart.
For example, a macro that would setup your charts into a 2-column grid would look like this:
Sub SetupChartsIntoGrid()
Const TopAnchor As Long = 50
Const LeftAnchor As Long = 50
Const HorizontalSpacing As Long = 10
Const VerticalSpacing As Long = 10
Const ChartHeight As Long = 211
Const ChartWidth As Long = 360
Dim shp As Shape
For Each shp In ActiveSheet.Shapes
If shp.Type = msoChart Then
Dim Counter As Long
Counter = Counter + 1
With shp
.Top = TopAnchor + (WorksheetFunction.RoundUp(Counter / 2, 0) - 1) * (VerticalSpacing + ChartHeight)
.Left = LeftAnchor + ((Counter + 1) Mod 2) * (HorizontalSpacing + ChartWidth)
End With
End If
Next
End Sub

Pasting a large table into separate slides by Excel VBA

I would like to paste a table from excel to power point using VBA. However, as I have dynamic range therefore I would like to create slides with 15 rows only for better visualization. For example, it will paste row 1 to row 15 into slide number 1 then row 1, and row 16 to row 29 into slide number 2 and so on. Here row 1 is the header of the table. I have attached the code where I can create only one slide. I would highly appreciate if anyone can help me.
Sub SortingandSlidecreation()
Dim pptName As String
Dim ppt As PowerPoint.Application
Dim myPres As PowerPoint.Presentation
Dim slds As PowerPoint.Slides
Dim sld As PowerPoint.slide
Dim pptextbox As PowerPoint.Shape
Dim oLayout As CustomLayout
Dim wb As Workbook
Dim ws As Worksheet
Dim y As Workbook, LastRow&
Dim r As Range
Set wb = ThisWorkbook
Set ws = wb.Sheets("SortedTable")
'This will open a PowerPoint template (I didn't attach the function)
pptName = openDialog()
Set ppt = CreateObject("PowerPoint.Application")
Set myPres = ppt.Presentations.Open(pptName)
Set slds = myPres.Slides
' creating slides at the end of the template
Set sld = slds.Add(myPres.Slides.Count + 1, ppLayoutBlank)
'Here data is selected for pasting
Set r = ThisWorkbook.Worksheets("SortedTable").Range("A1:L" & LastRow)
r.Copy
sld.Shapes.PasteSpecial DataType:=0
sld.Shapes(1).Top = 100
sld.Shapes(1).Left = 100
'Here title of the table is added
Set pptextbox = sld.Shapes.AddTextbox(msoTextOrientationHorizontal, 22, 60, 700, 60)
With pptextbox.TextFrame
.TextRange.Text = "Summary of Current Projects"
.TextRange.Font.Bold = msoTrue
.TextRange.Font.Name = "Arial(Headings)"
.TextRange.Font.Size = 20
.TextRange.Font.Color.RGB = RGB(0, 51, 102)
End With
End Sub
Remove your current definition of LastRow. Then delete everything after your Set slds = myPres.Slides line and paste this code instead.
Dim LastRow as Long, i as Long, j as Integer, rngH as Range, wss as Worksheet
LastRow = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
Set rngH = ws.Range("A1:L1") 'Header Row
i = 2
Set wss = wb.Worksheets.Add
Do While i <= LastRow
j = Application.Min(i + 13, LastRow)
Union(rngH, ws.Range("A" & i, ws.Range("L" & j))).Copy Destination:= wss.Range("A1")
Set sld = slds.Add(myPres.Slides.Count + 1, ppLayoutBlank)
wss.Range("A1:L" & j-i+2).Copy
sld.Shapes.PasteSpecial DataType:=0
sld.Shapes(1).Top = 100
sld.Shapes(1).Left = 100
'Here title of the table is added
Set pptextbox = sld.Shapes.AddTextbox(msoTextOrientationHorizontal, 22, 60, 700, 60)
With pptextbox.TextFrame
.TextRange.Text = "Summary of Current Projects"
.TextRange.Font.Bold = msoTrue
.TextRange.Font.Name = "Arial(Headings)"
.TextRange.Font.Size = 20
.TextRange.Font.Color.RGB = RGB(0, 51, 102)
End With
i = j + 1
Loop
Application.DisplayAlerts = False
wss.Delete
Application.DisplayAlerts = True
Set wss = Nothing
End Sub

VBA Plot of box and whiskers chart

I'm trying to automate plotting of a box and whiskers chart. The code below compiles and runs but the error bars do not appear in the chart.
Dim ws As Worksheet
Dim datarange As Range
Dim chtChart As Chart
Dim objChrt As ChartObject
Set ws = Sheets("sheet1")
Set datarange = ws.Range("F8:G10")
Set chtChart = Charts.add
With chtChart
chtChart.ChartType = xlColumnStacked
chtChart.SetSourceData Source:=datarange, PlotBy:=xlColumns
With .Axes(xlCategory, xlPrimary)
.CategoryNames = ws.Range("A2:A13")
.TickLabels.Font.Bold = True
End With
.SeriesCollection(1).Format.Fill.Visible = msoFalse
.SeriesCollection(2).Format.Fill.Visible = msoTrue
Dim Sec1 As Series
Set Sec1 = .SeriesCollection.NewSeries
.SeriesCollection(3).HasErrorBars = True
.SeriesCollection(3).ErrorBars.EndStyle = xlCap
.SeriesCollection(3).ErrorBars.Format.Line.Visible = msoTrue
.SeriesCollection(3).ErrorBars.Format.Line.ForeColor.RGB = RGB(0, 0, 0)
.SeriesCollection(3).ErrorBars.Format.Line.Transparency = 0
.SeriesCollection(3).ErrorBars.Format.Line.Weight = 1.5
.SeriesCollection(3).ErrorBar Direction:=xlX, Include:=xlErrorBarIncludeBoth, Type:=xlErrorBarTypeCustom, Amount:="=CHART!F12:G12", MinusValues:="=CHART!F12:G12"
Solved.
.SeriesCollection(3).values= <data range for whisker length>
type variant, data values required to plot whiskers
IMPORTANT: this overwrites the series collection values (seriescollection(3) in this case)
values can be replaced after plotting whiskers

Resources