Looping code to continue making charts with different series - vba

This is my first time learning and working with VBA so bear with me please.
I've worked out this makeshift code to plot xvalues vs. y values and everything's great so far (I think). Now I'd like to create something that makes a second, third, fourth (and so on) graph using data that simply needs to shift down by 4 rows. Can someone help?!
Sub VOCChartMaker()
Sheets("HousevGarageCharts").Select
With ActiveSheet
.Shapes.AddChart.Select
With ActiveChart
.ChartType = xlXYScatter
.HasTitle = True
.ChartTitle.Text = "='Data'!$C$2"
Do Until ActiveChart.SeriesCollection.Count = 0
ActiveChart.SeriesCollection(1).Delete
Loop
.SeriesCollection.NewSeries
.SeriesCollection(1).Name = "='Data'!$A$2"
.SeriesCollection(1).XValues = "='Data'!$D$2:$BB$2"
.SeriesCollection(1).Values = "='Data'!$D$3:$BB$3"
.SeriesCollection(1).MarkerSize = 5
.SeriesCollection.NewSeries
.SeriesCollection(2).Name = "='Data'!$A$4"
.SeriesCollection(2).XValues = "='Data'!$D$4:$BB$4"
.SeriesCollection(2).Values = "='Data'!$D$5:$BB$5"
.SeriesCollection(2).MarkerSize = 5
.Axes(xlCategory, xlPrimary).HasTitle = True
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Garage"
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "House"
End With
End With
End Sub
Thanks a bunch!
Megan

Instead of providing complete solution I add some key point+comments to part of your code. I think the rest will go easy after that.
Sub VOCChartMaker()
Sheets("HousevGarageCharts").Select
'>> we need a simple loop which will star here
Dim i As Byte '>>required declaration
For i=1 To 4 '>>for four charts
With ActiveSheet
.Shapes.AddChart.Select
With ActiveChart
.ChartType = xlXYScatter
.HasTitle = True
'>> title for every fourth row starting from 2nd
.ChartTitle.Text = "='Data'!$C$" & 2 + (i-1)*4
'>> as far as you create new chart you don't need it _
as there is nothing to delete
'Do Until ActiveChart.SeriesCollection.Count = 0
'ActiveChart.SeriesCollection(1).Delete
'Loop
'changes made to create chart series for every fourth row starting from 2nd
.SeriesCollection.NewSeries
.SeriesCollection(1).Name = "='Data'!$A$" & 2 + (i-1)*4
.SeriesCollection(1).XValues = "='Data'!$D$" & 2 + (i-1)*4 & ":$BB$" & 2 + (i-1)*4
.SeriesCollection(1).Values = "='Data'!$D$" & 3 + (i-1)*4 & ":$BB$" & 3 + (i-1)*4
.SeriesCollection(1).MarkerSize = 5
'>> change the second series accordingly on your own!!!!!
.SeriesCollection.NewSeries
.SeriesCollection(2).Name = "='Data'!$A$4"
.SeriesCollection(2).XValues = "='Data'!$D$4:$BB$4"
.SeriesCollection(2).Values = "='Data'!$D$5:$BB$5"
.SeriesCollection(2).MarkerSize = 5
.Axes(xlCategory, xlPrimary).HasTitle = True
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Garage"
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "House"
End With
End With
Next i '>> the end of the loop
End Sub

Related

Attempt at creating a chart that changes data with time too laggy?

I am trying to create a chart that changes the data with time. The Y data are the same but only the X data are changed. I am using Application.Wait to allow for some time between each change in X values (So I can see it with my eye). However when I run the code its very laggy and I am not sure if I am using the Application.Wait function properly but I want between each change a time of 0.5 seconds. Is there a way to make it more smooth so that I can see the graph as it changes with time (as the code loops through the rows)
Here is my code:
Sub UpdateChart()
Dim ChtObj As ChartObject
Dim counter As Integer
Dim timecount As Double
Set ChtObj = ActiveSheet.ChartObjects.Add(200, 50, 500, 500)
'Creating intial graph
With ChtObj.Chart
'Chart Type
.ChartType = xlXYScatterSmooth
'Datainput
.SeriesCollection.NewSeries
.SeriesCollection(1).Name = "Bending moment"
.SeriesCollection(1).Values = Range("D3:H3")
.SeriesCollection(1).XValues = Application.Union(Cells(5, 4), Cells(5, 5), Cells(5, 6), Cells(5, 7), Cells(5, 8))
.HasLegend = False
'Title
.HasTitle = True
.ChartTitle.Text = "Bending moment along pile " & ActiveSheet.Name & " at time 0 seconds"
'X-Axis
.Axes(xlCategory, xlPrimary).HasTitle = True
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Bending moment (kN.m)"
'Y-Axis
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "Length along pile (m)"
End With
'Loopingthrough data to be done**
counter = 6
timecount = 0
While (Not IsEmpty(Cells(counter, 4)))
'Pausing for half a second and recording cumulative time
timecount = timecount + 0.5
Application.Wait (Now() + TimeValue("0:00:005"))
'Updating Chart data
With ChtObj.Chart
.SeriesCollection(1).XValues = Application.Union(Cells(counter, 4), Cells(counter, 5), Cells(counter, 6), Cells(counter, 7), Cells(counter, 8))
.ChartTitle.Text = "Bending moment along pile " & ActiveSheet.Name & " at time " & timecount & " s"
End With
'Next row
counter = counter + 1
Wend
End Sub
This seemed to solve my problem:
Public Function PauseEvent(ByVal Delay As Double)
Dim dblEndTime As Double
dblEndTime = Timer + Delay
Do While Timer < dblEndTime
DoEvents
Loop
End Function

Scatter Plot of date and numeric value in vba

To store the dates irrespective of the system format i made it string because the excel will be used by many users on different systems. Below is the code:
Range("Z:Z").NumberFormat = "#"
Range("AC:AC").NumberFormat = "#"
Range("AF:AF").NumberFormat = "#"
dateArr = Array("4/1/2016", "4/15/2016", "5/1/2016", "5/15/2016", "6/1/2016", "6/15/2016", "7/1/2016", "7/15/2016", "8/1/2016", "8/15/2016", "9/1/2016", "9/15/2016", "10/1/2016", "10/15/2016", "11/1/2016", "11/15/2016", "12/1/2016", "12/15/2016")
For i = 2 To UBound(dateArr)
ActiveSheet.Cells(i, 26).Value = Format(dateArr(i - 2), "yyyy/mm/dd")
Next
But i need to plot the scatter plot for it, so i again changed it to the date format as shown below:
Columns("Z:Z").Select
Selection.NumberFormat = "yyyy/mm/dd"
And when i plotted the scatter plot,its not plotting it properply.
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlXYScatterLines
ActiveChart.SetSourceData Source:=Range("Plot!$Z$2:$AA$" & date_no_row)
ActiveChart.Axes (xlCategory)
With ActiveChart.Axes(xlCategory)
.MinimumScale = 42401
.TickLabels.Orientation = 30
.TickLabels.NumberFormat = "yyyy/mm/dd"
.BaseUnitIsAuto = True
.MajorUnit = 14
.MinorUnitIsAuto = True
.Crosses = xlAutomatic
.ReversePlotOrder = False
End With
ActiveChart.Parent.Name = "Plot"
With ActiveChart.Parent
.Height = 325 ' resize
.Width = 900 ' resize
.Top = Range("C3").Top
.Left = Range("B2").Left
End With
ActiveSheet.ChartObjects("Plot").Chart.HasLegend = False
With ActiveSheet.ChartObjects("Plot").Chart
.HasTitle = True
.Axes(xlCategory, xlPrimary).HasTitle = True
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Dates"
.Axes(xlCategory, xlPrimary).AxisTitle.Font.Size = 15
End With
ActiveSheet.ChartObjects("Plot").Activate
ActiveChart.Axes(xlCategory).HasMajorGridlines = True
column AA contains numeric values. And the plot i m getting is as shown in the picture below
And expected plot is
You set column Z to text. After that, you try to set a number format, but the cells are text, so the number format never takes. Try it. Apply the first two code snippets and then manually change the cell format. It will have no effect.
So, start off with the correct format for column Z,
Range("Z:Z").NumberFormat = "yyyy/mm/dd"

Data is graphing in Excel 2010, but not in Excel 2013

I'm using VBA to graph data in a program I created in Excel 2010. I sent it to another computer, which has Excel 2013 instead, and I found that everything worked perfectly except for this graphing issue.
My code will create the graphs, and size them perfectly, but it won't actually graph any of the data points. In my code, I also add and delete series, and I notice that the number of series is correct on the side, but that the series didn't retain the custom names I gave them.
But here's the twist. When I right click on the chart and click "select data", all of the data immediately pops up, including all of my custom names for the series. I don't even go into select data or anything. The moment I click it, all of the values just pop up immediately.
Here is an imgur album of what it looks like before/after. Note that I do absolutely nothing other than right click and select the option "select data". It's like the data is already selected, but just doesn't show up until I click 'select data".
Why would Excel 2013 be doing this? How do I make these values actually show up via VBA methods? I'll add a sample of the graphing code I use below.
'Setting the range the chart will cover
Set rngChart = ActiveSheet.Range(Cells(Counter + 3, 4), Cells(Counter + 27, 10))
'Dimensioning the chart and choosing chart type
Set co = ActiveSheet.Shapes.AddChart(xlXYScatter, rngChart.Cells(1).Left, rngChart.Cells(1).Top, rngChart.Width, rngChart.Height)
Set cht = co.Chart
Set sc = cht.SeriesCollection
'Remove any default series
Do While sc.Count > 0
sc(1).Delete
Loop
'Setting chart data
'Series 1
With sc.NewSeries
.Name = "=Sheet1!$C$1"
.XValues = "=Sheet2!$A$2:$A$" & SimpleTracker + 1
.Values = "=Sheet2!$B$2:$B$" & SimpleTracker + 1
.MarkerSize = 3
.MarkerStyle = xlMarkerStyleCircle
End With
'Series 2
With sc.NewSeries
.Name = "=Sheet1!$B$1"
.XValues = "=Sheet1!$A$2:$A$" & Counter + 1
.Values = "=Sheet1!$B$2:$B$" & Counter + 1
.MarkerSize = 5
.MarkerStyle = xlMarkerStyleCircle
.MarkerBackgroundColorIndex = 10
.MarkerForegroundColorIndex = 10
End With
'Setting chart labels
With cht
.HasTitle = True
If n = 0 Then
.ChartTitle.Characters.Text = "Simple Fit - CFL Over Time"
ElseIf Range("I" & n) = "Regression Title" Then
.ChartTitle.Characters.Text = Range("J" & n).Text
Else
.ChartTitle.Characters.Text = "Simple Fit - CFL Over Time"
End If
.Axes(xlCategory, xlPrimary).HasTitle = True
If DayTracker = 1 Then
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Time (Days)"
ElseIf HourTracker = 1 Then
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Time (Hours)"
Else
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Time (Minutes)"
End If
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "CFL"
.Axes(xlCategory).HasMajorGridlines = True
.Axes(xlCategory).HasMinorGridlines = True
End With
I also want to note that this code still works perfectly in Excel 2010, and that the graphing still works there. It just doesn't work in Excel 2013.
Thank you for reading! If you have any questions or need any clarification, just let me know.
Replace
With sc.NewSeries
with
With cht.SeriesCollection.NewSeries
I had the same issue in Excel 2013. I don't know why, but this solution works for me.
The short story is I wasn't able to replicate the misbehavior.
The long story: I assumed that your code was the body of a Sub, so I created a module that contained the following:
Sub DoItOriginal()
'Setting the range the chart will cover
Set rngChart = ActiveSheet.Range(Cells(Counter + 3, 4), Cells(Counter + 27, 10))
'Dimensioning the chart and choosing chart type
Set co = ActiveSheet.Shapes.AddChart(xlXYScatter, rngChart.Cells(1).Left, rngChart.Cells(1).Top, rngChart.Width, rngChart.Height)
Set cht = co.Chart
Set sc = cht.SeriesCollection
'Remove any default series
Do While sc.Count > 0
sc(1).Delete
Loop
'Setting chart data
'Series 1
With sc.NewSeries
.Name = "=Sheet1!$B$1"
.XValues = "=Sheet2!$A$2:$A$" & SimpleTracker + 1
.Values = "=Sheet2!$B$2:$B$" & SimpleTracker + 1
.MarkerSize = 3
.MarkerStyle = xlMarkerStyleCircle
End With
'Series 2
With sc.NewSeries
.Name = "=Sheet1!$B$1"
.XValues = "=Sheet1!$A$2:$A$" & Counter + 1
.Values = "=Sheet1!$B$2:$B$" & Counter + 1
.MarkerSize = 5
.MarkerStyle = xlMarkerStyleCircle
.MarkerBackgroundColorIndex = 10
.MarkerForegroundColorIndex = 10
End With
'Setting chart labels
With cht
.HasTitle = True
If n = 0 Then
.ChartTitle.Characters.Text = "Simple Fit - CFL Over Time"
ElseIf Range("I" & n) = "Regression Title" Then
.ChartTitle.Characters.Text = Range("J" & n).Text
Else
.ChartTitle.Characters.Text = "Simple Fit - CFL Over Time"
End If
.Axes(xlCategory, xlPrimary).HasTitle = True
If DayTracker = 1 Then
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Time (Days)"
ElseIf HourTracker = 1 Then
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Time (Hours)"
Else
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Time (Minutes)"
End If
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "CFL"
.Axes(xlCategory).HasMajorGridlines = True
.Axes(xlCategory).HasMinorGridlines = True
End With
End Sub
Next, I needed some data to work with, so in another module I wrote a data generator that populated Sheet1 and Sheet2. Here is the content of that module:
Option Explicit
Sub Setup()
SetupSheet "Sheet1", 5
SetupSheet "Sheet2", 2.5
End Sub
Sub SetupSheet(nm As String, divisor As Double)
Dim i As Long
With ThisWorkbook.Worksheets(nm)
.[A2].CurrentRegion.ClearContents
.[B1].Value = "Chart" & Right(nm, 1)
With .[A1]
For i = 1 To SimpleTracker
.Offset(i).Value = i
.Offset(i, 1).FormulaR1C1 = "=1-EXP(-RC[-1]/" & divisor & ")"
Next i
End With
End With
End Sub
I then executed Setup() from the VB Editor, and created a third worksheet and activated it.
Then I ran DoItOriginal() from the VB editor, and I did not observe the issue you described. It occurred to me that one possible explanation is that switching back to the Excel user interface from the VBE did something to hide the misbehavior, so I installed a button on the sheet and executed DoItOriginal from there, and still did not observe the behavior in 2010, 2011, or 2013.
On thing I noticed is the line
.Name = "=Sheet1!$B$1"
in the setup for Series 1 probably wants to refer to Sheet2.
Try the code above and see if you still observe the misbehavior. If you do and I don't that might be interesting. If you don't, then the puzzle is how does this arrangement differ from the context in which you do see the misbehavior. Since you didn't post that, I'll wait in suspense. -hth
Try adding
DoEvents
After adding each chart element, especially after adding each series.

Add a chart on excel with vba

I'm trying to add a Scatter chart on a sheet, when I doit manually it works just fine, but when I try to use the recorded macro it give me an 1004 error on
" Sheets("Mapa Riesgos").Shapes.AddChart.Select "
here's the code
Sheets("Mapa Riesgos").Shapes.AddChart.Select
ActiveChart.ChartType = xlXYScatter
ActiveChart.SetSourceData Source:=Range("A11:B35")
With ActiveChart
.Parent.name = "Riesgo Inherente"
.Legend.Delete
.Axes(xlValue).MinimumScale = 0.5
.Axes(xlValue).MaximumScale = 5.5
.Axes(xlCategory).MinimumScale = 0.5
.Axes(xlCategory).MaximumScale = 5.5
.Axes(xlValue).MajorGridlines.Delete
.Axes(xlValue).Delete
.Axes(xlCategory).Delete
.SeriesCollection(1).MarkerStyle = -4142
'chart name
.HasTitle = True
.ChartTitle.Characters.Text = "Riesgo Inherente"
.ChartTitle.Font.Size = 20
'X axis name
.Axes(xlCategory, xlPrimary).HasTitle = True
.Axes(xlCategory, xlPrimary).AxisTitle.Font.Size = 13
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "Impacto"
'y-axis name
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Font.Size = 13
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "Probabilidad"
.Parent.Width = 400
.Parent.Height = 400
.Parent.Left = 60
.Parent.Top = 100
End With
I've used this code before, but for some reason when I used here it work just the first run and then the error start appearing
If your triggering it from another sheet you'll need to update the source data line to include the sheet name like this:
ActiveChart.SetSourceData Source:=Range("'Mapa Riesgos'!A11:B35")
Also, if your coming from another sheet you'll need to set your chart sheet as active in order to use ActiveChart. Do this before you create your chart.
Sheets("Mapa Riesgos").Select

Excel VBA - Adjust Color Line and X-Axis Interval

I used Excel VBA to create a chart and I want to adjust the line color and x-axis interval.
Below is the code:
Sub add_cpu_chart(server_hostname, site)
On Error Resume Next
Dim rpt_site As String
rpt_site = site
Set tbl = ThisWorkbook.Sheets(server_hostname).ListObjects(1)
strTableName = tbl.Name
strTableRange = tbl.Range.Address
Dim m_s_name, m_e_name As Date
m_s_name = CDate(fromDateStr)
m_e_name = CDate(toDateStr)
'Create new embedded chart
Set shp = ThisWorkbook.Sheets(server_hostname).Shapes.AddChart
'Position Shape over range
shp.Top = 100
shp.Left = 200
With shp
With .Chart
'Specify source data and orientation
'.SetSourceData Source:=ActiveSheets.Range(Table1 & "[#All]"), _
'PlotBy:=xlRows
.SetSourceData Source:=ThisWorkbook.Sheets(server_hostname).Range(strTableName & "[#All]")
.ChartType = xlLineMarkers
.SetElement (msoElementChartTitleAboveChart)
.HasTitle = True
.ChartTitle.Text = "CPU Utilization of " & server_hostname & " in " & _
rpt_site & " (" & Format(m_s_name, "dd-Mmm") & " to " & Format(m_e_name, "dd-Mmm yyyy") & ")"
.ChartTitle.Font.Size = 14
'.ChartArea.Font.Size = 14
.Legend.Delete
.SetElement (msoElementPrimaryValueAxisTitleRotated)
.Axes(xlValue, xlPrimary).AxisTitle.Text = "CPU Utlization (%)"
.Axes(xlValue, xlPrimary).AxisTitle.Font.Size = 10
.Axes(xlValue).MinimumScale = 0
.Axes(xlValue).MinorUnit = 2
.Axes(xlValue).MaximumScale = 100
.Axes(xlValue).MajorUnit = 20
.Axes(xlValue).TickLabels.NumberFormat = "General"
.SetElement (msoElementPrimaryCategoryAxisTitleAdjacentToAxis)
.Axes(xlCategory, xlPrimary).AxisTitle.Text = "Date of the Month"
.Axes(xlCategory, xlPrimary).AxisTitle.Font.Size = 10
'.Axes(xlCategory).MajorUnit = 1
.Axes(xlCategory).TickLabels.NumberFormat = "d"
With .PlotArea.Format.Fill
.Visible = msoTrue
.ForeColor.ObjectThemeColor = msoThemeColorBackground1
.ForeColor.TintAndShade = 0
.ForeColor.Brightness = -0.150000006
.Transparency = 0
.Solid
End With
End With
End With
End Sub
I want to change the line color to red - as in excel 2003 - as well as change the data in interval separated by 2 days. Currently, the data is in the form 1,2,3,4... I want to display the data in the form 1,3 ,5....
In a line chart, the X axis' minimumscale, maximum scale, majorunit, and minorunit are meaningless. The X values are merely categories which have no interpreted numerical values even if the labels show numerals.
You should probably change to an XY chart, which will allow full control over the axis scale using minimumscale, maximum scale, majorunit, and minorunit. Of course, an XY chart allows the same formatting of series markers and lines as in a line chart, but the confusing terminology will live on forever.
If for some reason you decide to stick with a line chart, you can use
ActiveChart.Axes(xlCategory).TickLabelSpacing = 2