How to control excel chart source range through VBA - excel

I want to be able to control and update the source (range) of an excel chart through VBA. The chart is ultimately going to be presented in a powerpoint presentation and the whole process shall update automatically.
I have tried using tables which doesn't give me the level of control I want. For example if i delete one datapoint the chart doesn't "shrink" accordingly.
ActiveChart.SetSourceData (Sheets("Sheet2").Range("E5:E9"))
The current script doesn't run. But I just want to "set" a source range for a particular chart, preferably accessed by name. And if new datapoints are added I just run the script again and the new range will be the top cell in the column down to .End(xlDown)

Thanks guys! I manged to find a solution that works for me and made a function of it, if anyone else has the same problem. Nothing fancy but you can set a range like "A2:A14" and the chart will update with the new range. The function is called by sheet name, chart name and range like below:
Call changecharts("Sheet2", "Chart1", "A2:A11")
Public Function changecharts(sheeet As String,chartname As String, rnge As String)
Worksheets(sheeet).ChartObjects(chartname).Activate
With ActivateChart
ActiveChart.SetSourceData Source:=ActiveWorkbook.Sheets(sheeet).Range(rnge)
End With
End Function

Related

How to disable the user to delete a chart in vba?

i made a chart on my excel sheet, and i want the user not to be able to delete it...
how can i do it?
I already tried this options from here:
https://peltiertech.com/Excel/ChartsHowTo/ChartProtection.html
The code is like this:
'Draw a chart
Dim rng As range
Dim cht As ChartObject
'Your data range for the chart
Set rng = Worksheets("Sheet1").range("$A$2:$A$100")
'Activate chart
Worksheets("Sheet1").ChartObjects(1).Activate
'Populate chart with data
ActiveChart.SetSourceData Source:=rng
'Determine type
ActiveChart.SeriesCollection.NewSeries.ChartType = xlLineMarkers
'Delete the 5th series
If ActiveChart.SeriesCollection.Count = 5 Then
ActiveChart.SeriesCollection(5).Delete
End If
I need something like this:
ActiveChart.preventDeleting
Now, the protection I had in mind was to prevent the user, from actively deleting the chart....a simple select and remove, or button press delete, or something...
In simple terms, block any attempt to delete the chart...
But, i dont know if this is relevant, but the table can change its range, and the chart should be still able to get updated...
Please let me know, if you need something else...
Also, it does not nessesary need to be a vba code, it can also be a manual solution, I am using MS excel 2007
Thanks...
You can protect the chart by protecting the sheet. If you want the user to be able to edit some of the cells, simply right click on the cells that you want to be able to be edited and select Format Cells -> Protection -> Locked and make sure this is unchecked.
Then protect the worksheet via Review -> Protect Sheet on the menu bar. This will prevent the deletion of the chart and allow users to continue editing the cell content

Adding X-Y plots to an existing chart in VBA

I’d like to write visual basic code that adds a “new series” to an existing plot. I’ve already managed to write the code that will select that data I want to add. So to complete the operation I did it in excel, recording the following macro:
‘desired data already selected a column of x values and one of y values to be plotted
Selection.Copy
Sheets("XVSER").Select
ActiveSheet.ChartObjects("Chart 3").Activate
ActiveChart.Paste
However, what this recorded macro does not show is I wanted to add the data as a “new series”, even though this option was explicitly selected while recording the macro. So when I run the macro it does not do the same thing I did will recording it, and adds the data to an existing series instead of creating a new series for it.
Surely there must be a way of specifying in VBA that I’d like a new series. I just don’t know how, or where to find documentation, and what I found already on stackoverflow, was difficult for me to understand, and seemed to require a different approach, which I’d rather avoid, since I’ve already developed the code to successfully select the data I want, and to select the chart I want to paste it in.
When recording MACROS with charts, not allways the result comes out the same as when recorded it. You will need to familiarize yourself with some of the ChartObject properties.
Try the code below:
Option Explicit
Sub AddSelectionasNewSeries()
Dim ChtRng As Range
Dim ChtObj As ChartObject
Dim Ser As Series
' set the selection as range >> However, try avoid using slection
Set ChtRng = Selection
' set the chart object
Set ChtObj = Sheets("XVSER").ChartObjects("Chart 3")
' add a new series with the Selection
ChtObj.Chart.SeriesCollection.Add ChtRng
End Sub
You have to use SeriesCollection.Paste, which has parameters to specify whether to add points or series and so forth. The Macro Recorder doesn't know this.
Replace
ActiveChart.Paste
with
ActiveChart.SeriesCollection.Paste Rowcol:=xlColumns, Serieslabels:=False, _
CategoryLabels:=True, NewSeries:=True

Named range reverts to normal range in chart

I have encountered strange problem. I have made named range SomeName
=OFFSET(Source!$B$29:$C$29,1,0, COUNTIF(Source!$B$30:$B$55, "<>x"),2)
And then I have tried to used in chart as a chart data range:
=Source!SomeName
As far, it worked fine. But when I switched to the sheet Source and went back I have realised that the data range went back to the normal range =Source!$B$30:$C$33. I guess I could fix it with macro (like setting named range to chart everytime when somebody activate the sheet) but there must be some other way.
Anyway know how to make it without VBA?
You cannot set whole chart source data to be named dynamic range. It will always transfer to hardcoded values. what you can do and will work, is to create named range for each series in chart, than add it manually (for more info take a look at this site). this way your chart will be somewhat dynamic. But the best way to get what you want is by using a macro. Something similar to this code...
Sub Test()
Dim CHARTDATA As Range
Set CHARTDATA = Range(or your dynamic range)
ActiveSheet.ChartObjects("Chart 1").Chart.SetSourceData Source:=CHARTDATA
End Sub

VBA Paste Special on Existing Chart

I would like to use VBA to paste a range of data into an existing chart, using the options shown in the following screenshot:
If I record a macro whilst doing so manually, the code only states ActiveChart.Paste. Thus, when I re-run this code the series is pasted regularly without the 'Series Name In First Row' deactivated. How can I code this correctly? I haven't found much in the way of help in my research so far.
Well, I tried a simple code and it works.
Suppose you have a data like below and you made a simple Clustered Column Chart:
Now you want to paste special Data2 as in your screen shot.
VBA code which works at my end is below:
Sub test()
Dim ch As Chart: Set ch = Sheet1.ChartObjects(1).Chart
Range("A1:A4,C1:C4").Copy '~~> you need to include the x axis labels when copying
ch.SeriesCollection.Paste RowCol:=xlColumns, SeriesLabels:=False, _
CategoryLabels:=True, Replace:=False, NewSeries:=True
End Sub
Result:
I don't know what chart you're working on or how you want it constructed.
Above just shows how to execute Copy and Paste Special of data from a Range to an Existing Chart. HTH

Run VBA code automatically after running a filter

I've got a code written that categorizes employees along with their qualifications. In order to weed out employees with unwanted qualifications I have applied a filter to each column that titles the category of their qualification.
I've written my VBA code in order that repetitious names and qualifications are made invisible for ease of location. However, I am unable to get the code to run automatically.
Currently the only way I can get the code to run is by setting it to
Private Sub Worksheet_Change(ByVal Target As Range) and then changing the value of an arbitrary cell.
i found what I believe to be the correct solution at:
http://www.ozgrid.com/forum/showthread.php?t=72860
But I cannot make sense of it.
Is there a way to run this code without having to select and deselect a cell after the filter has run?
The key points from my article Trapping a change to a filtered list with VBA
There is more detail and a sample file with the article, the key points are summarised below
A "dummy" WorkSheet is added with a single SUBTOTAL formula in A1 pointing back to the range being filtered on the main sheet.
A Worksheet_Calculate() Event is added to the "dummy" WorkSheet, this Event fires when the SUBTOTAL formula updates when the filter is changed.
The next two setps are needed if it is desired to run the Workbook Calculation as Manual
Add a Workbook_Open Event to set the EnableCalculation property of all sheets other than "Dummy" to False.
Run the Workbook in Calculation mode
The ozgrid code you mentioned tells you that you can put your code in a worksheet_calculate event (in the worksheet module), as long as you have something that will recalculate when you change your autofilter. This something can be a subtotal formula that you can hide in your worksheet, e.g. =subtotal(3,A:A)
Still need to investigate but looks like Chart Calculate event is triggered when Calculation = xlCalculationManual. At least works on my Excel 2007. So the steps are:
create a chart (saying "Chart 1" on Sheet1) which actually uses data from any of your table column
check that it updates its picture when you change the filter
create a new class e.g. clsChartEvents:
Public WithEvents Chart As Chart
Private Sub Chart_Calculate()
Stop
End sub
add this code to some module or class:
Private chartEvents as new ChartEvents 'create a module-scope variable
sub SubscribeToChartEvents
set chartEvents.Chart = Sheet1.ChartObjects("Chart 1").Chart
end sub
execute SubscribeToChartEvents
change a filter and you should appear in Sub Chart_Calculate()

Resources