Reputation: 371
I currently have data that I'm plotting into charts that looks like:
Period 0 1 2 3
Variable 2.1 2.5 2.8 3.0
I currently have VBA that expands the range of my charts by one column everytime I run it. However, I would like to know if there's a more efficient way to code it such that VBA calculates the very last column of my sheet that has data and plots the datapoints accordingly. The one problem with my current code is that if I accidentally run the VBA too many times, I will have blank cells plotted on my chart.
Sub ChangeChartRange()
'Defines objects
Dim i As Integer, r As Integer, n As Integer, p1 As Integer, p2 As Integer, p3 As Integer
Dim rng As Range
Dim ax As Range
Dim wks As Worksheet
Dim cht As ChartObject
Set CurrentSheet = ActiveSheet
'For () loop statement that cycles through each worksheet
For Each wks In ActiveWorkbook.Worksheets
'Activates workbook
wks.Activate
'For () loop statement that cycles through each chart
For Each cht In ActiveSheet.ChartObjects
'Activates chart
cht.Activate
'Start counter at 0
r = 0
'Finds the current range of the series and the axis
For i = 1 To Len(ActiveChart.SeriesCollection(1).Formula) Step 1
If Mid(ActiveChart.SeriesCollection(1).Formula, i, 1) = "," Then
r = r + 1
If r = 1 Then p1 = i + 1
If r = 2 Then p2 = i
If r = 3 Then p3 = i
End If
Next i
'Defines new range
Set rng = Range(Mid(ActiveChart.SeriesCollection(1).Formula, p2 + 1, p3 - p2 - 1))
Set rng = Range(rng, rng.Offset(0, 1))
'Sets new range for each series
ActiveChart.SeriesCollection(1).Values = rng
'Updates axis
Set ax = Range(Mid(ActiveChart.SeriesCollection(1).Formula, p1, p2 - p1))
Set ax = Range(ax, ax.Offset(0, 1))
ActiveChart.SeriesCollection(1).XValues = ax
Next cht
Next wks
End Sub
Help would be much appreciated! I'm still very new to VBA - I pulled this code somewhere online. Still trying my best to learn as I go along!
Upvotes: 0
Views: 345
Reputation: 1728
If you don't have any blank cells in the middle of your data, and the next column to the right is blank, you can use the rng.End(xlToRight)
to find the last cell with data in it. You can see in the code below, that I replaced the .Offset(0,1)
with .End(xlToRight)
for the new range and the axis.
'Defines new range
Set rng = Range(Mid(ActiveChart.SeriesCollection(1).Formula, p2 + 1, p3 - p2 - 1))
Set rng = Range(rng, rng.End(xlToRight)) 'was Set rng = Range(rng, rng.Offset(0, 1))
'Sets new range for each series
ActiveChart.SeriesCollection(1).Values = rng
'Updates axis
Set ax = Range(Mid(ActiveChart.SeriesCollection(1).Formula, p1, p2 - p1))
Set ax = Range(ax, ax.End(xlToRight)) 'was Set ax = Range(ax, ax.Offset(0, 1))
ActiveChart.SeriesCollection(1).XValues = ax
Explanation of ActiveChart.SeriesCollection(1).Formula
In a graph I have, I extracted the SeriesCollection(1).Formula
. It looks like this: "=SERIES('Jan 17'!$D$7:$D$8,'Jan 17'!$C$9:$C$33,'Jan 17'!$D$9:$D$33,1)"
In this string the first range is the description, the second the axis, and the third the relevant data.
The following code steps through this string one character at a time. If the current character is a comma, r
gets updated and the conditional values for p1
,p2
, and p3
get assigned when r
reaches the correct value. p1
is the 1st character after the first comma (the beginning of the axis string). p2
is the location of the second comma (divider between axis and data). p3
is the location of the third comma (the 1st character after the data string).
For i = 1 To Len(ActiveChart.SeriesCollection(1).Formula) Step 1
If Mid(ActiveChart.SeriesCollection(1).Formula, i, 1) = "," Then
r = r + 1
If r = 1 Then p1 = i + 1
If r = 2 Then p2 = i
If r = 3 Then p3 = i
End If
Next i
The next section of code extracts the section of the string starting at the data, for the length of the data. 'Jan 17'!$D$9:$D$33
This is converted to a range object, which is then extended.
'Defines new range
Set rng = Range(Mid(ActiveChart.SeriesCollection(1).Formula, p2 + 1, p3 - p2 - 1))
Set rng = Range(rng, rng.Offset(0, 1))
The following code extracts the section of the string starting at the beginning of the axis, for the length of the axis. 'Jan 17'!$C$9:$C$33
This is converted to a range object, which is then extended and reassigned to the axis values.
'Updates axis
Set ax = Range(Mid(ActiveChart.SeriesCollection(1).Formula, p1, p2 - p1))
Set ax = Range(ax, ax.Offset(0, 1))
ActiveChart.SeriesCollection(1).XValues = ax
Upvotes: 1