Reputation: 999
I am using ExcelDNA and Microsoft.Office.Interop.Excel to set some of the y values of a given Excel chart series to #N/A. (*)
This is what I am trying to achieve in VBA. This works as expected:
Sub test()
Dim xdata As Variant, ydata As Variant
Dim chrt As Chart
Set chrt = ActiveWorkbook.Worksheets("Sheet1").ChartObjects("Chart 1").Chart
With chrt
xdata = Array(0, 1, 2, 3, 4, 5)
ydata = Array(0, 10, 20, CVErr(xlErrNA), 40, 50) 'Works as expected
.SeriesCollection(1).XValues = xdata
.SeriesCollection(1).Values = ydata
End With
End Sub
In F# I have tried the 2 following approaches, and none worked:
module TEST =
open Microsoft.Office.Interop.Excel
open ExcelDna.Integration
let series : Series =
let app = ExcelDnaUtil.Application :?> Application
let wks = (app.Sheets.Item "Sheet1") :?> Worksheet
let cho = wks.ChartObjects("Chart 1") :?> ChartObject
let ch = cho.Chart
let s = ch.SeriesCollection(1) :?> Series
s
[<ExcelFunction(Category="Chart", Description="")>]
let setYSeries1() : obj =
let s = series
s.XValues <- [| 0.0; 1.0; 2.0; 3.0; 4.0; 5.0 |]
s.Values <- [| 0.0; 10.0; 20.0; 30.0; 40.0; 50.0 |] |> Array.map box // Works as expected.
box "Done."
[<ExcelFunction(Category="Chart", Description="")>]
let setYSeries2() : obj =
let s = series
s.XValues <- [| 0.0; 1.0; 2.0; 3.0; 4.0; 5.0 |]
s.Values <- [| box 0.0; box 10.0; box 20.0; ExcelError.ExcelErrorNA |> box; box 40.0; box 50.0 |] |> Array.map box // y = 42 for x = 3, instead of y = #N/A
box "Done."
[<ExcelFunction(Category="Chart", Description="")>]
let setYSeries3() : obj =
let s = series
s.XValues <- [| 0.0; 1.0; 2.0; 3.0; 4.0; 5.0 |]
s.Values <- [| box 0.0; box 10.0; box 20.0; ((int32) -2146826246) |> box; box 40.0; box 50.0 |] // y = -2146826246 for x = 3, instead of y = #N/A
box "Done."
setYSeries1
is the base case without #N/A values. It works fine.
setYSeries2
was the natural way, using ExcelDNA's ExcelError.ExcelErrorNA
enum, but #N/A is replaced by its enum value in the chart (y = 42).
I tried setYSeries3
after I read in this article that, internally, Excel uses integers to represent errors like #N/A (while Excel uses doubles to represent numbers), substituting (int) -2146826246
for #N/A value. No luck either.
My question: what should I do to pass #N/A values to the series' .Values array?
(*) I need to set the series' .Values properties via an array, rather than via a sheet range.
Upvotes: 1
Views: 156
Reputation: 16907
You need to convert the error value to a type that .NET will understand as a COM error type (like CVErr
in VBA).
There is an Excel-DNA helper that maps the C API error enums to COM error:
ExcelDna.Integration.ExcelErrorUtil.ToComError(ExcelError.ExcelErrorNA)
Internally this will do
new System.Runtime.InteropServices.ErrorWrapper(-2146826246)
Upvotes: 2