I have functional VBA code that creates a XYScatter chart of data provided to it in the form of an "X" array and a "Y" array (as opposed to data that exists inside a range on a worksheet). Both arrays are declared as doubles (i.e. Locals window lists the arrays as type "Double(# to #)" and each array element as type "Double"). They are assigned respectively to the .XValues and .Values properties of a series in the chart, and everything appears to be displayed as expected.
A separate sub attempts to adjust the .MinimumScale & .MaximumScale properties of the chart's axes scales based on the extent of the data it finds in .XValues and .Values, and it does so successfully for the Y-axis (the .Values). However, it fails for the X-axis. Somehow, although I've provided the same data types to those two properties, doubles passed to .XValues are getting converted into strings while those within .Values remain doubles. To be precise, they're listed respectively in the Locals window as arrays of "Variant/String" and "Variant/Doubles".
Thus, when I try to retrieve the min and max X values in order to set the X-axis scale Application.Max(.XValues)
all I ever get back is 0, presumably because Excel's Max function doesn't recognize the strings as numbers.
It's worth noting that if I attempt the same axis scaling on a chart with XY data from a range in a worksheet I don't encounter this issue, and when I use the Locals window to peer into such a chart it lists both the .XValues and .Values properties as arrays of Variant/Doubles.
Below I've pulled together the relevant pieces of my originally separate subs to troubleshoot and/or illustrate the issue. Please keep in mind that while it would appear the simple solution is to use the max of xArray to set the X-axis scale, my original code has creation of charts occurring in one sub and rescaling of charts occurring in another; xArray is only accessible by the first sub, and I'd like to keep it that way.
Sub test()
Dim MaxX As Double, MaxY As Double, MinX As Double, MinY As Double
Dim xArray(1 To 5) As Double, yArray(1 To 5) As Double
Dim CHRT As Chart, SER As Series
xArray(1) = 0: xArray(2) = 0.000001: xArray(3) = 9.99999
xArray(4) = 10: xArray(5) = 20
yArray(1) = 0: yArray(2) = 0.000001: yArray(3) = 9.99999
yArray(4) = 10: yArray(5) = 20
Set CHRT = ActiveSheet.Shapes.AddChart2(-1, xlXYScatter).Chart
With CHRT
.SeriesCollection.NewSeries
Set SER = .SeriesCollection(1)
With SER
.XValues = xArray
.Values = yArray
End With
End With
With Application
MaxX = .Max(SER.XValues)
MinX = .Min(SER.XValues)
MaxY = .Max(SER.Values)
MinY = .Min(SER.Values)
End With
Stop '...to check Locals window; we expect MaxX = MaxY
End Sub
CDbl( expression )
to convert and value to `Double'.... Also +1 for neat and tidy code – alowflyingpigCdbl()
ing them into some new array which doesn't mess withApplication.Max()
. – dmorchardChartType = xlXYScatter
for both objects, Chart and Series. The Series has a second property,Type = -4169
(which is the Enum for "xlXYScatter"). – dmorchard