VBA Pie Chart Legend - How to set legend text? - excel

A similar question was asked (Set Legend Text Pie Chart) but the solution doesn't work for me, maybe I'm missing something. I'm fairly new to working with VBA/Excel/Access and reports and I'm on a limited deadline so I am hoping somebody can enlighten me.
What I am doing is populating a range of cells with values pulled from an access database and then programatically generating pie charts based on these cell values. The pie charts are fairly simple and contain 2 pieces of data. I am generating 1-4 of them based on the users' selections. So for example, the user can choose A, B, C And/Or D and each letter corresponds to 2 cell columns that contain # of Correct & # of Incorrect for each chart
The reports are being generated inside of a loop (1 to 4) corresponding to A/B/C/D
The Code I'm using to create the charts looks like this:
Charts.Add
ActiveChart.ChartType = xlPie
ActiveChart.SetSourceData Source:=Sheets("Sheet1").Range(Cells(20,shift(shiftIndex)), Cells(21, shift(shiftIndex))
ActiveChart.HasLegend = True
Which is saying to use the range B20:B21, C20:C21, etc for the Correct/Incorrect values. The problem is that the legend is showing "1" & "2" as labels and I want it to show "Correct" & "Incorrect"
In the other question, the person suggested using the syntax:
ActiveChart.SetSourceData Source:=Sheets("Sheet1").Range("b6:c6," & "b" & x & ":c" & x)
Where b6 would contain "Correct" and c6 would contain "Incorrect" in my case for my labels but when I use this:
ActiveChart.SetSourceData Source:=Sheets("Sheet 1").Range("a26:a27, a20:a21")
Where a26 contains "Correct", a27 contains "Incorrect" and a20 & a21 contain my correct and incorrect values - it tries to use all 4 values in my pie chart. Am I missing something here? Separating the parameters by a comma should indicate the first range as my legend and the second as my data source?

you can directly control this using the XValues property of the Series object...
Assuming you have only one series in the chart try:
Activechart.Seriescollection(1).XValues=Activesheet.Range("a26:a27")
a further tip would be to do this:
Dim chMyChart as Chart
Dim chMySeries as Series
Set chMyChart = Activesheet.Activechart
Set chMySeries = chMyChart.Seriescollection(1)
and then use chMyChart in place of Active chart and chMySeries in place of ActiveChart etc.
This is more efficient, but it also activates vba's Intellisense that shows you a list of all of the properties available for these objects after you enter the ".".
For me anyway, this doesn't seem to be exposed on objects like Active??? or indexed objects like chMyChart.SeriesCollection(1)

Related

How to use name range in VBA code for a new chart series' values and X-Values?

I am enhancing a work template that requires users to create a new file each week to be able to track progress from week to week, so the file will change name each week.
This file has about 3 charts in a "Summary" worksheet.
In this "Summary" worksheet, bar chart #2 currently has 5 series. I am writing a script to be able to add a 6th series.... this I have no problem.
I would like the new Series values to use the values from a Name Range of cells the template currently has defined ("software") in a different worksheet.
I would also like the Horizontal Axis Labels to use a different Name Range of cells that template also has defined ("dates") in a different worksheet.
Here is the code I have so far:
Sub add_software()
'Update software Trend in Summary
Sheets("Summary").SelectActiveSheet.ChartObjects("Chart 2").Activate
ActiveChart.SeriesCollection.NewSeriesActiveChart.FullSeriesCollection(6).Name = "='Summary'!$C$44"
'MY PROBLEM IS HERE
ActiveChart.FullSeriesCollection(6).Value = ActiveWorkbook.Sheets("Summary").Range("Software")
ActiveChart.FullSeriesCollection(6).XValues = ActiveWorkbook.Sheets("Summary").Range("dates")
End sub
I would expect that the script will use the values in these Name Ranges (which are the same values used in the other 5 series) and populate with the values from the name range.
This is the error I get is:
Run-Time error '438': Object doesn't support this property or method
error
Try this other method to get the range. Not tested but it should work.
ActiveChart.FullSeriesCollection(6).Value = ThisWorkbook.Names("Software").RefersToRange
ActiveChart.FullSeriesCollection(6).XValues = ThisWorkbook.Names("dates").RefersToRange
Edit: Had an extra dot after "Names".
The accepted solution by #RicardoA works fine, but it assumes a static definition of the names, and places the current address of each name into the SERIES formula of the series. If the names are dynamic, the SERIES formula will not keep up with the changes. The following puts the names not addresses of the names into the series formula:
ActiveChart.SeriesCollection(6).XValues = "='" & ThisWorkbook.Name & "'!dates"
ActiveChart.SeriesCollection(6).Values = "='" & ThisWorkbook.Name & "'!software"
u have a typo. u have miss a "
where u have
.Range("Software)
replace to
.Range("Software")
good luck

excel macros - line chart loses year axis values and chart title

I am recording a macro using Excel 2013 to create a line chart.
I have one column with years and an adjacent column with population values. The column headings are "Year" and "Population" respectively.
The line chart looks good.
When I run the macro, the chart title (Population) is striped out. Additionally the year values (x axis) are replaced with a number series, 1 . . . onwards
How do I have the macro retain the year values and the chart title (Population)?
Thanks!
This is my recorded Macro
Range("A1:B29").Select
ActiveWindow.WindowState = xlMaximized
ActiveSheet.Shapes.AddChart2(227, xlLineMarkers).Select
ActiveChart.SetSourceData Source:=Range("compilation!$A$1:$B$29")
This is an example of what I want the final graph to look like when I run the macro.
Add the following line to your last line of your macro
ActiveChart.FullSeriesCollection(1).XValues = "=compilation!$A$2:$A$29"
That should get you your year back along the bottom.
ActiveChart.SetElement (msoElementChartTitleAboveChart)
ActiveChart.ChartTitle.Select
Selection.Caption = "=compilation!R1C2"
That will set your Title for you. However you still need your Primary Horizontal Title so why dont we throw in this tid bit of random code:
ActiveChart.Axes(xlCategory).Select
ActiveChart.SetElement (msoElementPrimaryCategoryAxisTitleAdjacentToAxis)
Selection.Caption = "=compilation!R1C1"
now the only outstanding issue is if you are generating 1 or 2 lines in your graph.
To get rid of the second line (technically the first since its really series 1) we have two choices.
Choice 1 is to select it with the code and delete it. I am going to opt for choice 2 though. Choice 2 is to never add it in the first place!
So to start with eliminate your first line of your Macro. When the graph is initially created, it will be created as a blank slate as there is no preselected data. So what we need to do is change 1 lettre in the line of your macro where you define the Source. (4th line of your posted code) and we are going to change the starting cell reference from $A$1 to $B$1. If the graph only has one column of data to work with for points then there can only be one series. So that line will look like the following in the end:
ActiveChart.SetSourceData Source:=Range("compilation!$B$1:$B$29")

Programmatically adding excel data labels in a bar chart

I try to add a bar chart to an excel file.
I am using ABL (4GL) to do this:
ASSIGN
vchChart = chExcelApplication:Charts:Add()
vchChart:ChartType = 57
vchChart:HasTitle = FALSE.
vchChart:SetSourceData(chWorkSheet2:Range("B1:B" + STRING(iCounter - 1))).
vchChart:ApplyDataLabels(5).
vchChart:Location(2, "Tabelle1":U).
This creates a bar chart, but the labels for the data are 1,2,3,4,...
I would like to use a range of fields in excel to display as the labels for the chart bars.
This should look something like this:
If I were to do this manually I would use the following in Excel:
How can I add those labels programmatically?
That means I would like to use a certain range of cells for the labels as indicated in this pseudy code:
SetLabels(chWorkSheet2:Range("A1:A" + STRING(iCounter - 1))).
If these labels are in a worksheet range, then something like this (this is VBA; make its syntax compatible with the program you're using):
ActiveChart.SeriesCollection(1).XValues = chWorkSheet2.Range("B1:B" + STRING(iCounter - 1))

Excel dynamic data series. Unusual data look and chart

Since I solved previous problem with collecting data from database, I need to put that data on a chart now. I am working on a report generating software called ReportWorx.
Problem is, data comes in series and looks like this:
ID DATE SAMPLE
1 XX-XX-XX VALUE
1 XX-XX-XX VALUE
1 XX-XX-XX VALUE
2 XX-XX-XX VALUE
2 XX-XX-XX VALUE
3 XX-XX-XX VALUE
3 XX-XX-XX VALUE
I can not change how it looks because it is generated automatically. What I want is linear chart in which 1, 2, 3 are series name and of course next to it DATE and VALUE are put on a linear chart (or bargraph, w/e) (Date at X axis, Value at Y axis).
I can`t specify how many records will be there (how many rows) but I found few solutions about creating dynamically increasing charts, so probably it will not be a poblem. I just do not know how to separate thos ID series from each other.
EDIT:
I have found a solution in VBA according to the first answer. Here you have VBA code below:
Sub Rewrite()
Dim row, id
For row = 38 To 1000
For id = 1 To 37
If Sheet1.Cells(row, 1).Value = id Then
Sheet2.Cells(row, 1).Value = Sheet1.Cells(row, 2)
Sheet2.Cells(row, id + 1).Value = Sheet1.Cells(row, 3)
End If
Next id
Next row
End Sub
Thank You #sancho.s
I will post a solution that I use a lot for cases like yours.
With reference to the figure (where I used sample numbers), you set up 3 new columns (D:F here), the header of which contain the corresponding labels. Then you use a formula for "splitting" the list of X data (column B here) associated with each label, and assigning a "NULL" value for data not corresponding (#N/A here, but you can choose whatever you want):
=IF($A3=D$2,$B3,$B$1)
You enter this in D3. The absolute/relative indexing used allows for copy-and-paste throughout D3:F9.
Cell B1 here contains the "NULL" value.
Then you plot 3 series: column C against columns D, E, F.
PS: I guess you could split the Y data column instead, with similar results. For some reason that I do not recall, I decided a long time ago that this was the best option, at least in my case then. You may want to try out the other option.
PS2: This also works for data that is not sorted by label.
PS3: Using NA() as the "NULL" value avoids cell values being taken as zero and then showing up in the chart, as it is the case with other errors (e.g., try using =1/0 in B1). It is the best option I found so far. Alternatively (just in case you find it useful), you can use an explicit value which is outside the actual X data range, but then you would have to manually set the X axis range. All this is for a Scatter plot, just check what works for your case.

Colouring an Excel stacked bar chart's points in relation to a value assigned in a table

I am trying to create a roadmap/timeline in Excel 2010 using a stacked bar chart. I have provided a link below to an image which should explain my intentions with the chart. I wish to present different events in the chart and they should be drawn in relation to their duration. The longer the event is, the longer its respective bar is.
I have managed to build a macro that creates a chart of my liking. However, I wish to add another functionality to it. As it can be seen from the picture below, there is a column called 'Type' in the original table. It stands for the status of the event, whether it is completed, canceled or being planned. My aim is to have the chart represent this data by coloring the bars either red (if canceled), green(if completed) or blue (if planned) depending on what value the particular event in question has in its Type row.
Below is the code behind the macro that the button 'Create a New Event View' uses. I would like to know how to implement the coloring, preferably in this very same macro so that the user only needs to click the button.
Sub CreateEventTable()
Dim timespan_start As Date
Dim timespan_end As Date
timespan_start = Application.InputBox("Type start date:")
timespan_end = Application.InputBox("Type end date:")
ActiveSheet.Shapes.AddChart(xlBarStacked, Range("E2").Left, Range("E2").Top).Select
With ActiveChart
.SetSourceData Source:=Range("$A$1:$B$12, $D$1:$D$12"), PlotBy:=xlColumns
.SeriesCollection(1).Values = Range("B2:B12")
.SeriesCollection(1).XValues = Range("A2:A12")
.SetElement msoElementLegendNone
.ChartGroups(1).GapWidth = 31
.SeriesCollection(2).ApplyDataLabels
.SeriesCollection(2).DataLabels.ShowCategoryName = True
.SeriesCollection(2).DataLabels.ShowValue = False
.SeriesCollection(1).Format.Fill.Visible = msoFalse
.Axes(xlValue).MinimumScale = timespan_start
.Axes(xlValue).MaximumScale = timespan_end
End With
End Sub
Here is the link to the image which hopefully explains the overall structure:
http://i.imgur.com/XzPoMiY.jpg
I appreciate your invaluable help! I am happy to provide more details if deemed necessary.
Best solution here is not VBA. You'll need to create multiple series for your chart, have them overlapped, and use formulas to populate if they meet the criteria. Changes automatically, and very easy to maintain.
As Skip Intro said, Jon Peltier is the chart master.
This link will get you started in the right direction.
http://peltiertech.com/WordPress/conditional-formatting-of-excel-charts/

Resources