【问题标题】:Deleting dataseries in a chart删除图表中的数据系列
【发布时间】:2021-06-11 16:48:08
【问题描述】:

我有一个动态图表,我在清除数据序列时遇到了困难。

据我了解,数据序列索引是累积的。意思是,如果我从另一张干净地制作了 12 个数据系列的工作表中复制“图表 4”。 dataseries 的数量 = 12 = ActiveSheet.ChartObjects("Chart 4").Chart.SeriesCollection.count 并且这些系列的索引从 1 到 12。

现在,如果我删除一个系列并添加一个,数据系列的数量将继续为 12,但索引现在将从 1-11 和 13 运行。

因此,当我尝试通过计算系列数量并删除索引为 1 的系列来删除它们时:ActiveSheet.ChartObjects("Chart 4").Chart.SeriesCollection.count 如果系列已被删除和添加,它将失败。

为了克服这个问题,我尝试了“for each.. in chart 4..”选项:

For Each Series In ActiveSheet.ChartObjects("Chart 4")
'For Each FullSeriesCollection In ActiveSheet.ChartObjects("Chart 4")
    ActiveChart.FullSeriesCollection.Delete
Next

我收到一条错误消息:

“对象不支持此属性或方法”

我在stackoverflow上查看了这里的问题,发现计数器需要下降:

我从VBA deleting chart series复制调整:

Dim iSrs As Long
With ActiveChart
    For iSrs = .SeriesCollection.count To 1 Step -1
        If InStr(LCase$(.SeriesCollection(iSrs).name), "series") > 0 Then
            .SeriesCollection(iSrs).Delete
        End If
    Next
End With
MsgBox (count_non_existant_series & " and the nr of series still present = " & ActiveSheet.ChartObjects("Chart 4").Chart.SeriesCollection.count)

这不会删除所有数据系列,因为之后它仍然显示:count = 27。

我尝试了其他几种公式,结果不是全部删除,(有时“on error resume next”打开,它会删除一半,奇数时向下舍入)完整的代码是:

'select workbook, worksheet
Workbooks("N.xlsm").Worksheets("day_visual").Activate
Workbooks("N.xlsm").Worksheets("day_visual").range("A1").Select
'select chart
ActiveSheet.ChartObjects("Chart 4").Activate
ActiveSheet.ChartObjects("Chart 4").Select
'remove all series(0 to xx?)
MsgBox (ActiveSheet.ChartObjects("Chart 4").Chart.SeriesCollection.count)
'For Remove = 1 To ActiveSheet.ChartObjects("Chart 4").Chart.SeriesCollection.count
'    'On Error Resume Next
'    ActiveChart.FullSeriesCollection(Remove).Select
'    Selection.Delete
'
'    'ActiveChart.FullSeriesCollection(Remove).Delete
'    'MsgBox ("hi")
'    count_non_existant_series = 1 + count_non_existant_series
'Next Remove

ActiveSheet.ChartObjects("Chart 4").Activate
ActiveSheet.ChartObjects("Chart 4").Select
'For x = Workbooks("N.xlsm").Worksheets("day_visual").ChartObjects("Chart 4").SeriesCollection.count To 2 Step -1
'For x = Workbooks("N.xlsm").Worksheets("day_visual").ChartObjects("Chart 4").FullSeriesCollection.count To 2 Step -1
'   ActiveSheet.ChartObjects("Chart 4").SeriesCollection(x).Delete
'Next x
Dim iSrs As Long
With ActiveChart
    For iSrs = .SeriesCollection.count To 1 Step -1
        If InStr(LCase$(.SeriesCollection(iSrs).name), "series") > 0 Then
            .SeriesCollection(iSrs).Delete
        End If
    Next
End With
'For Each Series In ActiveSheet.ChartObjects("Chart 4")
For Each FullSeriesCollection In ActiveSheet.ChartObjects("Chart 4")
    ActiveChart.FullSeriesCollection.Delete
Next


MsgBox (count_non_existant_series & " and the nr of series still present = " & ActiveSheet.ChartObjects("Chart 4").Chart.SeriesCollection.count)

'With ActiveSheet.ChartObjects("Chart 4")
''Do While .SeriesCollection.count >= 1
'.SeriesCollection(.SeriesCollection.count).Delete
'Loop
'End With
Dim add_chartlabels As Long

我缺乏对 Excel 如何存储索引的理解,导致我尝试不正确的解决方案。

  1. 我对图表系列指数的理解有误吗?
  2. 为什么“for each”方法会产生运行时 483 错误?
  3. 为什么手动迭代代码不删除所有系列?
  4. 如何从图表中删除所有系列而不删除 图表本身?

【问题讨论】:

  • #3 -- 你只是删除一个系列如果系列名称包含子字符串"series"
  • @a.t.您是否尝试过以下任何答案?有什么反馈吗?

标签: excel vba charts


【解决方案1】:

For Each 方法的运行时 483 错误 - 因为使用此方法意味着您正在从第一个循环到最后一个。删除对象时,您需要向后循环。因此,为此您需要使用For iSrs = .SeriesCollection.count To 1 Step -1

试试下面的代码,代码里面的解释(作为cmets):

Option Explicit

Sub DeleteChartSer()

Dim Sht As Worksheet
Dim ChtObj As ChartObject
Dim Ser As Series
Dim iSrs As Long

' set the worksheet object (this will work only if "Nutrition planner v42.xlsm" is open)
Set Sht = Workbooks("Nutrition planner v42.xlsm").Worksheets("day_vita_visual")

' set the ChartObject
Set ChtObj = Sht.ChartObjects("Chart 4")

MsgBox ChtObj.Chart.SeriesCollection.Count

With ChtObj.Chart ' <-- there's no need to select the Chart, use fullay qualified objects instead
    If .SeriesCollection.Count >= 0 Then
        For iSrs = .SeriesCollection.Count To 1 Step -1 ' allways loop backwards when deleting objects
            If LCase(.SeriesCollection(iSrs).Name) Like "*series*" Then
                .SeriesCollection(iSrs).Delete
            End If
        Next iSrs
    End If
End With

'MsgBox (count_non_existant_series & " and the nr of series still present = " & ActiveSheet.ChartObjects("Chart 4").Chart.SeriesCollection.Count)

End Sub

编辑1:如果你想删除所有Series,只需评论一个If,下面的一个,因为这里你检查Series.Name是否包含作品“系列” :

If LCase(.SeriesCollection(iSrs).Name) Like "*series*" Then

所以将代码的最后一部分替换为:

With ChtObj.Chart ' <-- there's no need to select the Chart, use fullay qualified objects instead
    If .SeriesCollection.Count >= 0 Then
        For iSrs = .SeriesCollection.Count To 1 Step -1 ' allways loop backwards when deleting objects
            .SeriesCollection(iSrs).Delete
        Next iSrs
    End If
End With

【讨论】:

  • 谢谢 Shai Rado,它让我度过了一个美好的夜晚,它就像一个魅力!我将研究为什么您的负面步骤有效,为什么我的无效,是否是我的编程/打字错误,或者代码的实际方法是否存在差异。感谢您通过首先标注完全合格的对象来向我展示礼仪方面的改进。最重要的是一个手写的、有效的解决方案!我打算在我自己提出这个问题时对1.和2.给出确切的解释,一旦我认为我完全理解它。
  • For Each srs In .SeriesCollection 不关心它是否继续前进,因为它不是使用索引,而是使用集合。
【解决方案2】:

删除 if 语句后,它会起作用。

With ActiveChart
    If  .SeriesCollection.count >0 then
      For iSrs = .SeriesCollection.count To 1 Step -1
        'If InStr(LCase$(.SeriesCollection(iSrs).name), "series") > 0 Then
            .SeriesCollection(iSrs).Delete
        'End If
      Next
    end if
End With

【讨论】:

  • 谢谢!确实如此,我认为 Shai Rado 的答案更完整一些,所以我接受了它作为答案。然而,imo你的回答也符合条件。感谢您的贡献和努力!
【解决方案3】:
Do While ActiveChart.SeriesCollection.Count > 0
  ActiveChart.SeriesCollection(1).Delete
Loop

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-30
    • 1970-01-01
    • 1970-01-01
    • 2021-05-03
    • 1970-01-01
    • 1970-01-01
    • 2012-09-21
    • 1970-01-01
    相关资源
    最近更新 更多