重复调用Chart.SetSourceData会出现1004错误。

48

我公司使用Excel 2003创建了一个应用程序,该应用程序存在问题。该应用程序从数据源检索数据,并使用VBA例程中的SetSourceData更新图表,传递包含编写相关数据的单元格的范围。

该应用程序在Office 2003中运行良好,但当在Office 2010中执行应用程序时,它会显示以下错误:

  

运行时错误“1004”:对象“_Chart”的方法“SetSourceData”失败。

我已在Office 2010的简单Excel文件中创建了一个For循环,并根据传递给图表的范围中的列数,错误将更快或更晚地出现。传递的列数越多,错误就越快出现。我认为这必须与图表中系列的数量有关(列数越多,系列越多)。

这是Office 2010中的Chart对象或Series中实施的某种机制/缓冲区吗?当在Office 2003中运行时,相同的For循环永远不会出现问题,我不确定如何解决此问题。

到目前为止,我只能通过使用Goto指令删除所有Series来控制错误,然后使用For Each循环选择Chart的SeriesCollection中的所有对象来删除所有Series。如果我这样做并在再次传递范围时恢复应用程序的执行,则所有数据都会正确地绘制在Chart对象中。

重现错误的示例。将以下代码放入新的Excel 2010工作簿的VBA模块中。运行子setDataChart,应用程序会运行直到显示错误消息。

    Sub setDataChart()
    Call createAColValues
    ActiveSheet.Shapes.AddChart.Select
    ActiveChart.ChartType = xlXYScatterSmoothNoMarkers
    ActiveChart.SetSourceData Source:=Range("A1:FA6"), PlotBy:=xlColumns
    ActiveSheet.ChartObjects(1).Activate
    With ActiveChart.Parent
         .Height = 325
         .Width = 900
         .Top = 120
         .Left = 10
    End With
    Call updateValues
    Call sendData
End Sub

    Sub sendData()
    Dim cht As ChartObject
    Set cht = ActiveSheet.ChartObjects(1)

    'On Error GoTo delSeries:
    For i = 0 To 1000
        cht.Chart.SetSourceData Source:=ActiveSheet.Range("A1:FA6"), PlotBy:=xlColumns
    Next i
End Sub

Sub createAColValues()
    Range("A1").Select
    ActiveCell.FormulaR1C1 = "1"
    Range("A2").Select
    ActiveCell.FormulaR1C1 = "2"
    Range("A1:A2").Select
    Selection.AutoFill Destination:=Range("A1:A6"), Type:=xlFillDefault
    Range("A1:A6").Select
End Sub

Sub updateValues()
    Range("B1").Select
    ActiveCell.FormulaR1C1 = "=RANDBETWEEN(0,10)"
    Range("B1").Select
    Selection.AutoFill Destination:=Range("B1:B6"), Type:=xlFillDefault
    Range("B1:B6").Select
    Selection.AutoFill Destination:=Range("B1:FA6"), Type:=xlFillDefault
    Range("B1:FA6").Select
End Sub

1
它在第209次迭代后失败了,我不知道为什么。但是,如果我删除每次迭代开始时的所有系列(例如使用 For j = cht.Chart.SeriesCollection.Count To 1 Step -1 : cht.Chart.SeriesCollection(j).Delete : Next j),那么它就可以正常工作。 - Jean-François Corbett
嗨,Jean-François,如果您更改系列的数量,它将在不同的迭代次数失败,系列数量越大,它将越早失败。我只是好奇为什么相同的对象和相同的代码在不同版本的Office中产生不同的结果。我想我将不得不控制错误并使用您的代码删除图表中的系列,然后恢复代码的执行。非常感谢您的帮助。 - Pocerus
2
Excel 2007的图表引擎已经完全重建,自那以后一直在使用。有很多变化,大多数是好的,有一些是不好的。此外,VBA中许多小行为也是不同的。你可以问为什么会这样,除了引用更新的图表引擎之外,没有人真正知道。如果你能找到任何问题的解决方法,比如Jean-François发布的方法,就采用它吧。 - Jon Peltier
谢谢您的评论Jon,我想我将不得不坚持使用Jean-François建议的解决方法,以继续在最新版本的MS Office中使用该应用程序。 - Pocerus
2个回答

15

这并没有解释错误发生的原因,而是一个变通方法。

在调用SetSourceData之前,删除图表中所有现有的系列,代码将如预期运行。

For j = cht.Chart.SeriesCollection.Count To 1 Step -1 
    cht.Chart.SeriesCollection(j).Delete
Next j

我不确定为什么会出现这个错误,但这样做可以让它消失。


感谢您的帮助,Jean-François。不幸的是,我目前还没有找到有关图表/系列问题的任何信息。我将尝试进一步调查此问题,并暂时使用您提出的解决方案。 - Pocerus

0
另一种可能性是为使用Offset公式和适当的参考单元格定义的数据定义命名范围。这需要数据是连续的,不改变它开始的初始行和列,并且您至少设置一个参考公式(在包含数据的列/行上使用=COUNTA()),该公式可用于设置偏移范围的高度/宽度。

否则,一个非常方便的小技巧是将其从宏中取出并放入工作表逻辑中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接