首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何引用同名但在不同工作表上的图表?

如何引用同名但在不同工作表上的图表?
EN

Stack Overflow用户
提问于 2016-08-12 11:04:37
回答 3查看 2.5K关注 0票数 11

我有两个工作表包含图表,并使用宏运行所有工作表中的图表,并更新绘制的值。

但是,在尝试引用第一个工作表之后的图表时,我遇到了一个问题--尽管工作表的引用发生了更改,但对图表的引用却没有改变。

循环如下所示:

代码语言:javascript
复制
For Each ws In ThisWorkbook.Worksheets
  Debug.Print ws.Name
  Debug.Print ws.ChartObjects("Kortsone").Chart.Name
  With ws.ChartObjects("Kortsone").Chart
    ...
  End With
Next ws

直接窗口的输出如下:

代码语言:javascript
复制
Grafar ovn 3
Grafar ovn 3 Kortsone
Grafar ovn 4
Grafar ovn 3 Kortsone

如您所见,对工作表的引用会发生更改,但图表引用不会更改。

有什么方法可以解决这个问题吗?或者我必须用唯一的名字重命名我的所有图表吗?

我正在使用Excel 2013

-编辑-我现在已经根据注释中的建议做了一些测试,似乎打印到即时窗口的内容取决于当前的活动工作表。

尝试使用for each chartobject遇到了与前面相同的问题:

代码语言:javascript
复制
Sub test2()
  Dim ws As Worksheet
  Dim ch As ChartObject

  For Each ws In ThisWorkbook.Worksheets
    For Each ch In ws.ChartObjects
      If ws.CodeName = "Graf4" Then
      Debug.Print ws.Name
      Debug.Print ch.Name
      Debug.Print ch.Chart.Name
      End If
    Next ch
  Next ws
End Sub

给予:

代码语言:javascript
复制
Grafar ovn 4
Kortsone
Grafar ovn 3 Kortsone
Grafar ovn 4
Langsone
Grafar ovn 3 Langsone
...
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-09-10 08:42:06

正如您已经发现的,Workheet.ChartObjects方法将找到正确的ChartObject,但是访问Chartobject.Chart属性将返回ActiveSheet的图表。您是否按名称或索引号引用ChartObject并不重要。

如果使用Worksheet.Shapes方法查找ChartObject,则行为是相同的。

此行为与早期版本的Excel不同。我确认该代码在Excel /2002中有效,在2016年不起作用。我不确定行为是什么时候改变的。可能是2013年,还是2013年和2016年的补丁?2016年Office for mac的行为也是一样的(即。不起作用)

在微软想出解决方案之前,你必须先激活工作表,或者激活ChartObject,然后才能访问图表属性。

代码语言:javascript
复制
Sub test()
  Dim ws As Worksheet
  Dim co As ChartObject
  For Each ws In ThisWorkbook.Worksheets
    Debug.Print ws.Name
    Set co = ws.ChartObjects("Kortsone")

    ws.Activate
    'or
    co.Activate

    Debug.Print co.Chart.Name
    With ws.ChartObjects("Kortsone").Chart
    End With
  Next ws
End Sub

我建议您暂时禁用ScreenUpdating,并在完成之后重新激活原来的激活表。

票数 5
EN

Stack Overflow用户

发布于 2016-09-14 13:43:57

GetChart将在特定工作表上返回图表对象。

getChart将图表对象存储在Static Collection中。Static Collection将留在内存中,直到出现代码中断或工作簿关闭为止。

第一次调用getChart时,所有图表对象都被激活,每个工作表上的每个图表都被添加到集合中。之后,图表只是在静态集合中查找。

如果图表(例如,调用函数后添加图表)不在集合中,则函数将重新加载自身。

获取图表

代码语言:javascript
复制
Function getChart(ChartName As String, WorkSheetName As String, Optional Reload As Boolean) As Chart
    Dim ws As Worksheet, ActiveWS As Worksheet
    Dim co As ChartObject
    Static ChartCollection As Collection

    If ChartCollection Is Nothing Or Reload Then
        Application.ScreenUpdating = False

        Set ChartCollection = New Collection
        Set ActiveWS = ActiveSheet
        For Each ws In ThisWorkbook.Worksheets
            ws.Activate
            For Each co In ws.ChartObjects
                ChartCollection.Add co.Chart, ws.Name & "!" & co.Name
            Next
        Next ws

        ActiveWS.Activate
        Application.ScreenUpdating = True
    End If

    On Error Resume Next
    Set getChart = ChartCollection(WorkSheetName & "!" & ChartName)

    If Err.Number <> 0 And Not Reload Then Set getChart = getChart(ChartName, WorkSheetName, True)

    On Error GoTo 0

End Function

测试

代码语言:javascript
复制
Sub Test()
    Dim ws As Worksheet
    Dim ch As Chart
    Dim msg As String
    Dim Start: Start = Timer

    For Each ws In ThisWorkbook.Worksheets
        Set ch = getChart("Kortsone", ws.Name)
        If Not ch Is Nothing Then

            msg = msg & ws.Name & "!" & ch.Name & " - Validated:" & (ws.Name = ch.Parent.Parent.Name) & vbCrLf

        End If
    Next ws
    msg = msg & "Time in Seconds: " & Timer - Start
    MsgBox msg
End Sub
票数 1
EN

Stack Overflow用户

发布于 2016-09-17 01:02:57

ChartWorksheet.ChartObject.Chart是有区别的。

清楚地表明

  • 当您在工作表中创建图表时,Excel会创建一个包含ChartChartObject。因此,ChartChildObject的子代,而后者又是Worksheet的子代。
  • 当您将图表创建为工作表时,它是一个Chart (或者您可以称它为“图表表”),相当于Worksheet

因此,Worksheet.ChartObject.ChartChart工作表的区别如下:

  • 来自ChartWorksheet.ChartObject.Chart包含图表的所有属性。
  • Chart工作表包含图表的所有属性和工作表的某些属性。

所以.Name属性应该是Chart工作表的属性,而不是Worksheet.ChartObject.Chart的属性。

我想说,调用ChartObject.Chart.Name时激活表名称的附加显示不是bug,而是调试过的bug。ChartObject.Chart一开始不会也不应该有一个Name。您可以调用ChartObject.Chart.Name,因为在Chart的对象模型intellisense中存在重叠。如果微软没有考虑到这一点,就会有一个bug。

所以简单地说,记住一个图表没有名字,是ChartObject Sheet Sheet,它的名字是。对比一下,图表中有ChartTitle

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38916459

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档