Programmatically adding excel data labels in a bar chart - excel

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))

Related

Hide/add legend to graph with conditions

I have 2 columns of data for my chart, but the second one is optional (with an IF formula).
I want the legend to only show the relevant series.
Because the legend is visible even if there is no data for the second column, I wrote this in the cell for the series name:
=IF(…………;"blabla";"")
Now the legend has no label and only the (yellow dashed) line appears:
How can I hide both the label and the line in this legend if the series has no data?
You can use VBA to realize this.
in Excel 2013 onward model
you can use Chart.FullSeriesCollection to select your series and toggle its Isfiltered properties
Like
If.....Then
ChartObjects("xxxx").Chart.FullSeriesCollection(2).IsFiltered = True
Else
ChartObjects("xxxx").Chart.FullSeriesCollection(2).IsFiltered = False
End if
If you are using old excel, like excel 2007, excel 2010.. you should only use Chart.legend.legendEntries(2).Delete to get rid of the legend. if you wanna toggle it back, you should use chart.hasLegend = false, Chart.hasLegend = true to make it back

Change orientation of chart and legend using excel VBA

For some reason if there is less than four rows of data and you try and scatter chart it the cluster (column A) is shown on the legend, but if more than 4 rows of data exist then the other columns (A, B, C) are on the legend (Y axis).
Can you please show me using VBA how do I re orientate this graph to look like graph (2)?
I need to reorient the legend series to be on the horizontal category axis using VBA(since the macro recorder doesn't show how to do this.
GRAPH 1 STARTS OFF LOOKING LIKE THIS
GRAPH 2 THIS IS HOW I DO IT MANUALLY
(reorient legend entries - left, and category labels - right)
GRAPH 3 The scatterchart dialog ends up looking like this, which is what I want to do in VBA
GRAPH 4 Final Graph looks like this, This is what I want to achieve in VBA
Lastly this is what the macro recorder creates, but when I try and run it, its missing, the range and Plotby parameters and fails
Range("A1:D3").Select
Range("D3").Activate
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlXYScatter
ActiveChart.SetSourceData
Your columns and rows are reversed. When you have the chart selected go und "Design" contextual tab and click "Switch Row/Column". Does that fix it? If yes you can use:
ActiveChart.PlotBy = xlRows or ActiveChart.PlotBy = xlColumns
to do it programatically.

VBA Pie Chart Legend - How to set legend text?

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)

Excel: How can I add custom gridline to a chart?

How can I add a custom horizontal line that has a label and it is at the exact same level as the first column in the chart (see the screenshot below).
Can this be done in VBA?
This could be done in VBA, or it could be done without VBA:
http://peltiertech.com/Excel/Charts/AddLineHorzSeries.html
This method involves creating a secondary Y-axis, and plotting another series of data in a "line" on the second axis.
This is a fairly clean solution.
Otherwise with VBA you would need add a shape/line to the chart (important to add it to the chartObject and not to the Worksheet).
Then compute the height of points and make the line's .Left = the chart's .PlotArea.Left and make the line's .Width = to the chart's .PlotArea.Width. Then set the line's .Top value based on the chart's .PlotArea.Height minus the "height" you calculated for the point.
using vba, you can add a new series:
With ActiveChart.SeriesCollection.NewSeries
.Values = "={6.9,6.9,6.9,6.9}"
'create string beforehand if number and values are unknown
.ChartType = xlLine
'and whatever other formatting is needed
End With
not using VBA, you can add a new column to the data, and put all of it equal to the first item, using =$B$2 in each cell to add the line to the graph

How to plot chart values outside axis maximum?

In previous versions of Excel there was a registry entry that you could create to allow Excel to display values/labels that would be positioned outside the axis min/max using QFE_Bonn dword=1. This is what I have used for Excel 2003: Plot lines that contain labels disappear ...)
I have not been able to find a similar patch or native functionality in Excel 2010 (Office Pro Plus). Any ideas how this can be accomplished, or did MS remove this functionality altogether?
Here are screenshots of examples in Excel 2003. I create a series of data which uniformly exceeds the y-axis maximum. This series' color fill has been removed already
To finish the look, remove the series' border so that it appears invisible. Then replace the series' value labels with the relevant data.
There is a workaround using the DataLabels.Left property which positions the DataLabel relative to the ChartArea.
Here is an example VB solution:
sub FakeLabels()
Dim sF As Double
Dim lOff As Double
Dim p As Double
ActiveSheet.ChartObjects(1).Activate
With ActiveChart
For sF = 1 To .SeriesCollection.Count
If .SeriesCollection(sF).Name = "FakeSeries" Then
'Define the lOff variable by adding 100, or some other value
lOff = .SeriesCollection(sF).Points(1).DataLabel.Left + 100
For p = 1 To .SeriesCollection(sF).Points.Count
.SeriesCollection(sF).Points(p).DataLabel.Left = lOff
Next p
End If
Next sF
End With
It yields the same results, the only new requirement is to keep the values for the "dummy" series within the axis min/max values for the chart.
A pleasant surprise is that re-sizing the chart doesn’t appear to affect the relative placement of the labels.
UPDATED 9-25-2013
I have used the "textbox" approach since first asking this question. But it is extremely clunky to manage the interplay between the labels' position and the textbox positions, their relative position of the PlotArea i.e., when to use .InsideWidth vs. .Width or .InsideLeft vs. .Left and whether there needs to be any sort of hedonic "adjustments" to the points values, as always seem to be the case, they are never quite perfectly aligned.
While perusing the PPT object model reference for some other chart-related inquiries, I stumbled upon this property which appears to replicate the functionality of the previous hotfix/registry hack.
.ShowDataLabelsOverMaximum

Resources