Scatter plot references row numbers rather than selected data - excel

EDIT: The problem is that the scatter graph is plotting my data against the row number, rather than the selected x-axis. When i change to a line graph, it does it correctly, but my VBA only works on scatter plots so i need to either make this graph reference the correct data or alter my code to make it work on line charts. I checked that the data is formatted as numbers, not text, but still no improvements.
I created a spreadsheet for work in which my coworkers drag and drop data into a sheet. A report is generated on another sheet which includes a graph of the raw data.
I used "define names" for each column of data so that the correct range would be selected no matter how large the dataset is. This worked beautifully, graph would update itself every time data was changed. Then I ran VBA to scale the axes and it all got messed up
When I run the code below, The axes get scaled just like I intended them to, but now, instead of having nice cycles in the data, the graph just shows a straight horizontal line for each set of data. I checked "select data" and everything is still selected correctly, and the data is the same as it was before I hit "run," only the graph doesn't look right. Here is the code:
Private Sub Worksheet_Calculate()
ScaleAxes
End Sub
Sub ScaleAxes()
'With Application.ActiveChart.Axes(xlCategory, xlPrimary)
With ChartObjects(1).Chart.Axes(xlCategory, xlPrimary)
.MinimumScale = ActiveSheet.Range("B26").Value
.MaximumScale = ActiveSheet.Range("B25").Value
.MajorUnit = 5
End With
'With Application.ActiveChart.Axes(xlValue, xlPrimary)
With ChartObjects(1).Chart.Axes(xlValue, xlPrimary)
.MinimumScale = ActiveSheet.Range("C26").Value
.MaximumScale = ActiveSheet.Range("C25").Value
.MajorUnit = 10
End With
End Sub
I really can't see what the problem is. The data is correct, it displayed on the graph correctly before code was run. Code works fine for scaling axes, but for some reason ruins the data inside the graph.

Related

When I add a chart into excel using VBA sometimes it becomes a pivot chart and causes errors

I have a pivot table with 3 values in it. Volume Processed, Volume Billed, and Billed Revenue. VB is always a subset of VP, and BR is often in the 100,000s compared to VB and VP which are usually less than 1,000. Additionally, there are over 1000 data points in my test data. I've only loaded in 2 months, and when it's done it has to be able to quickly handle an entire year. So Pivot Charts won't work. BR is a currency and VB and VP are just numbers. The chart I want is to show (VP-VB) stacked on top of VB where the height of VB = BR and the height of (VP-VB)+VB = (VP*BR)/VB. I also try to use a smaller amount of data points. If all the IDs are showing, that's over 1000 columns on the graph, it's much easier to see them group by buildings until you use a slicer to bring down the number of IDs to something more manageable.
My solution is to use VBA to make my own graph, scrape the data from the pivot table, figure out what graph the user wants to see, and then build it from scratch.
The problem is that sometimes the chart preloads with a pivot chart and then when I try to add in my data it throws a Run-time error. I am having trouble even creating the error because it doesn't always happen.
Dim MyChart as Object
Dim chtrng as Range
Dim srs as Series
Dim arrayvalues() as Double
Dim areayXvalues() as Variant
Set chtrng = Sheets("Pivot").Range("H30:T50")
Set MyChart = ThisWorkbook.Sheets("Pivot").ChartObjects.Add(Left:=chtrng.left,Width:=chtrng.width,Top:=chtrng.Top,Height:=chrrng.Height)
With MyChart.Chart
.ChartType = xlColumnStacked
.Has title = True
.ChartTitle.text = GraphName(0)
For j = 1 to 2
For I = 1 to GraphList.Count
Arrayvalues(i-1) = GraphList(I)(j)
Next I
Set srs = .Series collection.NewSeries
With srs
.Xvalues = areayXvalues
.Values = areayvalues
.Name = GraphName(j)
End With
Next j
End With
"Set srs" is where the error comes in. This is also the first pass of j. When I step through the code, the times that it works, at "Set MyChart" the graph is empty, but the times it doesn't work, the graph has a pivot chart inside. At the beginning of the actual code I delete all charts on the sheet.
Every scenario I try, with different data displayed in the pivot table has done both. I can't figure out what is even causing the issue.
I've tried making sure MyChart is set to nothing. I have code that calls the makegraph sub when the pivot table updates, I created a on/off switch for that. I've tried to disconnect all of my data scraping from the pivot table so that by the time I start on the graph none of my variables are attached to the table.
Most of the time the graph works exactly as expected, but every now and then it gives me a Run-time error '1004' on "Set srs"

Excel keyboard ability to change a value in a displayed dynamic chart range line

I plan to have a chart plotted line consisting of 20 values set up as a dynamic chart range. I then can manually go into the sheet and update these values one at a time and the chart will change its display.
But instead of manually changing the sheet values, I want to be able to;
1. Move the cursor to one of the displayed points on the line [using mouse?].
2. Use the up/down arrow keys to change the value of the point [to the value of the y axis where the point is moved to]. The incremental value the point is moved up/down with the arrow keys can be a tunable value in the sheet.
3. As the point value changes, the line should re-plot using the latest updated 20 values in the range.
Thank you.
Don
Tried nothing yet. Just an idea I want to use in possible applications.
No code for this change.
The problem summary details the results.
P.S. Since I got a -1 vote, I thought I should add more about what this would be used for in real life.
I have Macular Degeneration, but slowed it down from getting worse many years ago, and get regular shots in the one bad eye. Over the years, the original Amsler Grid has been manually used by patients to check for a deterioration in the condition, so they can quickly see their Eye Doc to get a shot before it gets worse. Lately, machines have been built that can test for the condition worsening, and report it to the user and/or their doctor. However, these machines are expensive. And the Amsler grid results are very subjective.
My idea is to develop an Excel sheet with chart to replace the Amsler Grid with one straight line that can be shown at any angle through a center point and allow anyone with Excel to test their eyes with this dynamic replacement. The Amsler grid has a Dot in the center and a bunch of horizontal and vertical grid lines. You cover one eye and with the other, look at the centered dot and then subjectively determine if you see the grid lines perfectly, of if they appear distorted.
What I want to do is to have a chart on which the user can selectively spot any distorted portions of the line, click on a distorted spot on the line, then "move" the spot to line up with the users view of the rest of the line. After the user has "straightened" out the line, he submits it. The logic then inverts the corrected line [which in reality is inversely distorted by the users movements of points on the line] and then this line is sent to the doctor involved via email. The doc can then determine how bad the distortion is by comparing it to past emailed lines from the same user and comparisons to the perfect straight line the user started with, and an appointment can be made for an office visit.
I can handle the best fit quadratic logic for displaying the line through the points, starting with linear, then fitting to what the users distorted results are. I just need help on the originally stated questions.
So here is my take on this (maybe there are more elegant ways), it's oversimplyfied to what you want I guess and not all your questions get answered, but maybe you'll get to implement some of it.
1) Create a chart on it's own seperate sheet, my example data on a line graph:
2) Assign code to Private Sub Chart_Activate and Private Sub Chart_Deactivate, for example:
Private Sub Chart_Activate()
Application.OnKey "{UP}", "GoUp"
Application.OnKey "{DOWN}", "GoDown"
End Sub
Private Sub Chart_Deactivate()
Application.OnKey "{UP}", ""
Application.OnKey "{DOWN}", ""
End Sub
3) The OnKey will activate two modules called GoUp or GoDown, I have written them as follows (maybe it can be done better)
Sub GoUp()
If TypeName(Selection) = "Point" Then
For Each pt In ActiveChart.SeriesCollection(1).Points
x = x + 1
If pt.Name = Selection.Name Then
With ThisWorkbook.Sheets("Sheet1")
.Range("A" & x).Value = .Range("A" & x).Value + 1
End With
Exit For
End If
Next pt
End If
End Sub
Sub GoDown()
If TypeName(Selection) = "Point" Then
For Each pt In ActiveChart.SeriesCollection(1).Points
x = x + 1
If pt.Name = Selection.Name Then
With ThisWorkbook.Sheets("Sheet1")
.Cells(x, 1) = .Cells(x, 1) - 1
End With
Exit For
End If
Next pt
End If
End Sub
Change the +1 and -1 to an assigned variable if need be.
4) Result on pressing arrow down or up when a point is selected:

How to Select Multiple, Specific Charts to be Re-Scaled in Excel with VBA?

I have some VBA code that allows me to re-scale the axes on several different charts. However, I'm trying to adjust that code so that I can select multiple charts to be re-scaled without having to duplicate the code.
A sample of the code I have so far is this:
Sheets("Sheet1").ChartObjects("Chart 1.1").Activate
ActiveChart.Axes (xlValue)
With ActiveChart.Axes(xlValue)
.MinimumScale = Sheets("Sheet2").Range("A1").Value
.MaximumScale = Sheets("Shee2").Range("B1").Value
End With
Sheets("Sheet1").ChartObjects("Chart 1.2").Activate
ActiveChart.Axes (xlValue)
With ActiveChart.Axes(xlValue)
.MinimumScale = Sheets("Sheet2").Range("B1").Value
.MaximumScale = Sheets("Sheet2").Range("B2").Value
End With
However, I am eventually going to have 50 charts (Chart 1.1 thru 1.5, Chart 2.1 thru 2.5, ..., Chart 5.1 thru Chart 5.5). I've been trying to figure out whether I can do more with the first line of the code that allows me to select specific charts all at once, but have so far been unsuccessful. Ideally, I'm hoping for something like this:
Sheets("Sheet1").ChartObjects("Chart 1.1", "Chart 2.1", "Chart 3.1", "Chart 4.1", "Chart 5.1").Activate
My VBA coding skills currently consist of what I can figure out via Google, so any suggestions would be greatly appreciated. Thanks.

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/

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