我正在Excel中创建图表仪表板。最终用户无需显示数据,因此我尝试使用数组来设置SeriesCollection.Values。这是有问题的代码块:
'test sub to declare and pass header_arr and series_arr
Sub test()
Dim arr1(), arr2() As Variant
With ThisWorkbook.ActiveSheet
arr1 = .Range(.Range("I2"), .Range("AI2")).Value
arr2 = .Range(.Range("I25"), .Range("AI28")).Value
End With
Call CreateWaterfall(arr1, arr2, , , , Range("I30"))
Erase arr1, arr2
End Sub
'sub to create chart
Sub CreateWaterfall(header_arr As Variant, series_arr As Variant, Optional colors As Boolean = True, Optional target_wb = Nothing, Optional target_ws = Nothing, Optional target As Range = Nothing)
'whole bunch of parameter checks that work fine
'trim header_arr
Dim temp() As Variant
ReDim temp(LBound(header_arr, 1) To LBound(header_arr, 1), LBound(header_arr, 2) To UBound(header_arr, 2))
For i = LBound(header_arr, 2) To UBound(header_arr, 2)
temp(LBound(header_arr, 1), i) = header_arr(1, i)
Next i
ReDim header_arr(LBound(temp, 1) To LBound(temp, 1), LBound(temp, 2) To UBound(temp, 2))
For i = LBound(temp, 2) To UBound(temp, 2)
header_arr(LBound(temp, 1), i) = temp(LBound(temp, 1), i)
Next i
'declare chart object, start with block...
'...stuff that works...
For i = 1 To 4
With .SeriesCollection(i)
If LBound(series_arr, 1) = 0 Then i = i - 1 'handle base 0 case-operation is reversed at end of loop to avoid incorrect steps
ReDim temp(LBound(series_arr, 1) To LBound(series_arr, 1), LBound(series_arr, 2) To UBound(series_arr, 2))
For j = LBound(series_arr, 2) To UBound(series_arr, 2)
temp(LBound(series_arr, 1), j) = series_arr(i, j)
Next j
.Values = temp '<--problem with this line
.XValues = header_arr
End With
If LBound(series_arr, 1) = 0 Then i = i + 1
Next i
'...other stuff that works...
'end with block
End Sub
这是在With
块内创建图表并设置其属性。 sub的所有其余部分都正常工作,甚至是设置.XValues
的行,但.Values
都不正确。当我在电子表格上检查它们时,它们是一系列的0和#N / As。检查显示这不是因为数组填充形式的范围中的空单元格。对于我在调试阶段,使用电子表格范围填充series_arr
和header_arr
;最终草案中不会出现这种情况。以下是我希望子处理的数据的一个小例子(对不起;我不知道如何让它比这更漂亮......):
215.56空空432.73
空43.184空56.442空
空136.65 186.8 345.67空
空空87.653空空
所有数组都包含通过单步执行确定的正确数据。
我已经查看了here并且卡住了;据我所知,.Values
行完全类似。除了使用电子表格范围设置.Values
之外,我还使用了与其他图表完全类似的代码,因此我知道问题不存在。
有什么想法吗?
答案 0 :(得分:0)
我能够自己解决这个问题:它是变体数组与变体数组问题。我添加了一些代码来强制数据在temp中用于将SeriesCollection.Values
设置为double类型。我最初发布的片段中的最后一个块现在是:
Dim dbl As Double '<--var to hold contents of series_arr in loop
Dim j As Integer
For i = 1 To 4
With .SeriesCollection(i)
If LBound(series_arr, 1) = 0 Then i = i - 1 'handle base 0 case-operation is reversed at end of loop to avoid incorrect steps
ReDim temp(LBound(series_arr, 2) To UBound(series_arr, 2))
For j = LBound(series_arr, 2) To UBound(series_arr, 2)
If series_arr(i, j) = "" Then '<--convert series_arr recs
temp(j) = 0
Else
dbl = series_arr(i, j)
temp(j) = dbl
End If
Next j
.Values = temp
.XValues = header_arr
End With
If LBound(series_arr, 1) = 0 Then i = i + 1
Next i
它有效!这是我(相对)受过教育的猜测,为什么;不过,我会很感激能够提供更好答案的人。
类型Variant
的变量原则上可以隐式转换为类型Double
,但它们也可以隐式转换为类型String
(以及其他类型)。这意味着Empty
记录含糊不清;当Excel必须决定将其转换为“”或0时,它需要一些其他标准才能重新开始。
我认为temp
在用于设置.Values
时包含一些数字这一事实会导致Excel将Empty
记录转换为0,但我想这不是'这种情况。我的结论是Excel只会将Variant
类型的数组元素转换为正确的类型,如果它们的所有可以转换为仅另一种类型。因此,即使我通过删除header_arr
中的一个元素来测试此假设,String
也正确地转换为header_arr
类型。另一方面,series_arr
因为它包含只能转换为Double
类型的元素,但也包含可转换为多种数字类型的元素,但未正确转换。