Vba 根据工作簿中嵌入的图表的位置(例如,左-右和上-下顺序)按顺序循环浏览工作簿中的图表

Vba 根据工作簿中嵌入的图表的位置(例如,左-右和上-下顺序)按顺序循环浏览工作簿中的图表,vba,excel,charts,Vba,Excel,Charts,我尝试循环查看特定工作表中的图表,然后使用以下代码将它们移动到所有工作表末尾的新图表工作表: Dim ws As Worksheet, co As ChartObject, c As Chart Set ws = ThisWorkbook.Sheets("nameofSheet") ws.Activate For Each co In ws.ChartObjects Set c = co.Chart 'do stuff with c Next co 问题是,这遵循了它们的创

我尝试循环查看特定工作表中的图表,然后使用以下代码将它们移动到所有工作表末尾的新图表工作表:

Dim ws As Worksheet, co As ChartObject, c As Chart

Set ws = ThisWorkbook.Sheets("nameofSheet")
ws.Activate

For Each co In ws.ChartObjects
    Set c = co.Chart
    'do stuff with c
Next co
问题是,这遵循了它们的创建顺序。随着时间的推移,我慢慢地在这里和那里添加了更多的“功能”,所以按照图表创建的顺序处理图表是没有意义的

有没有办法根据图表在工作表中的位置循环浏览工作表上的图表?例如,从左到右,然后从上到下。我至少需要一些已知的顺序,这样我才能正确地处理图表


如果没有,简单地将图表名称分别更改为“图表1”、“图表2”、“图表n”会使我使用的上述代码正常工作吗?

解决方案是遍历列表并构建一个包含
co.BottomRightCell.Address
内容的数组

若图形重叠并从同一单元格开始,那个么也可以使用解决方案

 co.Top 
 co.Left
然后对该列表进行排序,例如先列,然后行,这样您就有了“位置排序”列表

我的解决方案-不是最优的,因为我不知道如何在vba中制作hashmap:

Sub macro()
    Dim ws As Worksheet, co As ChartObject, c As Chart
    Dim arr As Object
    Set arr = CreateObject("System.Collections.ArrayList")
    Set ws = ThisWorkbook.Sheets("Sheet1")
    ws.Activate

    For Each co In ws.ChartObjects
        ' Initialise the ArrayList, for instance by taking values from a range:
        arr.Add co.Top + 10000 * co.Left
    Next co

    arr.Sort
    ' Optionally reverse the order
    'arr.Reverse

    For Each x In arr
        For Each co In ws.ChartObjects
            If (co.Top + 10000 * co.Left = x) Then
                'MsgBox x
                Set c = co.Chart
                ' do stuff with c
                co.Select
                co.Activate
            End If
        Next co
    Next x
End Sub

只需对初始语法稍加修改,就可以按顺序选择图表,代码将按所选顺序处理它们

请注意,Excel在未选中的图表对象之间循环的顺序是根据它们的Z顺序,从后到前。这通常是插入图表的顺序,但您可以前后移动图表以影响插入顺序,也可以在选择窗格中重新排列图表

这是一张有六张图表的简单表格。它们的标题按创建顺序显示图表对象名称,从图表1到图表6

以下是我用来重命名图表的代码:

Sub RenameCharts()
  Dim sh As Shape
  Dim i As Long
  For Each sh In Selection.ShapeRange
    i = i + 1
    sh.Name = "CHART_" & Format(i, "00")
    sh.Chart.ChartTitle.Text = sh.Name
  Next
End Sub
我按顺序选择图表,第一行从左到右,然后第二行从左到右;单击可选择第一个图表,单击时按住Ctrl键可选择第二个图表和后续图表,因此全部选中。选中所有图表后,我运行了代码

结果如下所示。这些图表是按照我选择它们的顺序命名的。请注意,我没有影响他们的Z顺序,只影响他们的名字

现在,您可以使用图表对象名称来处理图表:

For i = 1 To 6 ' or whatever
  With ActiveSheet.ChartObjects("CHART_" & Format(i, "00")).Chart
    ' process the chart
  End With
Next
或者,您可以跳过重命名过程,按照我重命名图表的顺序选择图表,然后按照以下顺序处理图表:

For Each sh In Selection.ShapeRange
  With sh.Chart
    ' process the chart
  End With
Next

若图表中有一个.TOP和.LEFT值,那个么您可以使用它来创建自己的有序数组,以便在foor循环中使用。更改图表名称不会更改顺序,但您可以通过在for循环中执行类似ChartObjects(“chart”&Cstr(i)”)的操作来访问对象。我手动更改了图表名称,并执行了
Set co=ws.ChartObjects(“chart”&Cstr(k))
在for循环中。它是有效的,但它的硬编码比我喜欢的要多。我将尝试您和其他用户建议的。做得很好!为了我的具体安排,我将您的订购公式更改为
1000*co.Top+co.Left