在用户窗体中选择图表

5
我希望编写一个宏,可以将一个图表的格式复制并应用到多个其他图表上。
我遇到的难题是如何让用户设置模板图表,然后选择多个其他图表。虽然如果用户知道图表名称,可以使用组合框来完成此操作,但我尝试在不知道图表名称的情况下完成此操作。
因此,我考虑使用用户对话框,让用户选择基本图表,然后选择要应用格式的图表,就像对于范围的refedit一样。但是我无法找出如何从用户窗体中引用图表。
这是否可行?如果可以,怎么做?

1
通常情况下,我会将这样的问题标记为“宽泛”,但在这种情况下,我会做出例外,因为如果您将问题缩小到具体问题,这可能是一个好问题 :) - Siddharth Rout
2个回答

6
这里是开始的内容。
在用户窗体上放置两个组合框和两个图像控件。
假设你的工作表看起来像这样。
在“UserForm_Initialize()”事件中填充两个组合框中的图表名称。例如。
Dim ws As Worksheet

'~~> Prepare your form
Private Sub UserForm_Initialize()
    Set ws = ThisWorkbook.Sheets("Sheet1")

    Dim ChartObj As ChartObject

    For Each ChartObj In ActiveSheet.ChartObjects
        ComboBox1.AddItem ChartObj.Name
        ComboBox2.AddItem ChartObj.Name
    Next ChartObj
End Sub

当您运行表单时,它将看起来像这样: enter image description here 在组合框的点击事件中,使用Stephen Bullen的PastePicture代码,可以从此处显示用户窗体中的图表。例如:
Private Sub ComboBox1_Click()
    ws.Shapes(ComboBox1.Value).CopyPicture
    Set Me.Image1.Picture = PastePicture(xlPicture)
End Sub

Private Sub ComboBox2_Click()
    ws.Shapes(ComboBox2.Value).CopyPicture
    Set Me.Image2.Picture = PastePicture(xlPicture)
End Sub

这是表格的样子。接下来,您现在拥有图表的名称。只需根据自己的需要使用它们即可。
希望这有所帮助。 enter image description here

我知道这是一个老问题,但是当将此代码复制到Excel 2016中时,图表不会调整大小以适应图像控件。如果我尝试使用PastePicture(xlBitmap),则在图像控件中什么也没有显示。我是否遗漏了需要调整图表或图片以适应图像控件的内容? - pheeper

2
以下代码应该允许您使用所选的图表区域进行操作,您可以选择一个或多个图表:
Public Sub ProcessSelectedCharts()
    Dim i As Integer
    Dim chart_obj As ChartObject
    Dim chart_area As chartArea

    If TypeOf Selection Is DrawingObjects Then
        For i = 1 To Selection.Count
            If TypeOf Selection(i) Is ChartObject Then
                Set chart_obj = Selection(i)
                Set chart_area = chart_obj.Chart.chartArea
                Call ProcessChart(chart_area)
            End If
        Next i
    ElseIf TypeOf Selection Is chartArea Then
        Set chart_area = Selection
        Call ProcessChart(chart_area)
    End If

End Sub

Public Sub ProcessChart(obj As chartArea)
    ' Do something...
End Sub

您可能需要稍微修改一下,即如果用户只选择图表中的特定元素,则此方法可能不起作用。
好的,下一个问题是,何时从用户表单中调用此功能。首先,您的用户表单当然应该是模态的,以允许用户选择任何内容。那么如何知道用户实际上选择了什么? 我可以想到三种方法,并将它们按最佳到最差的顺序列出(后两种方法仅简要描述,因为我不建议使用它们):
  1. 在工作表上使用“Worksheet_SelectionChange”事件,并使其调用用户表单内的方法以通知其选择已更改。现在,您只需要检查是否选择了哪些图表(参见上面的代码),并运行算法即可。
  2. 在用户表单中运行计时器,并定期检查活动选择。
  3. 通过DLL调用挂钩鼠标事件并注册任何鼠标点击,然后检查选择变化。
这样,您就可以创建一个像RefEdit一样的功能,从用户表单中选择工作表中的图表。

我刚看到你发了一个答案。我也正准备发布一个答案,因为我已经在上面工作了一段时间。希望你不介意我发表一个答案。而且它采用了不同的方法 :) - Siddharth Rout
+1 为另一种选择 :) - Siddharth Rout
博吉,我结合了你和@SiddharthRout的答案。我已经让Siddharth的代码片段可以选择我的基本图表,然后使用你的代码将格式应用于已选择的图表。但是我还无法让你的代码工作。你能帮忙吗?我在未来的代码片段中使用Set chart_area = chart_obj.Chart.chartArea时遇到了困难。所以我想在循环中使用代码获取图表名称,使用targetName = Selection(i).Name,然后只需使用这个名称。 - MatthewK
现在假设所选的图表是“Chart 75”和“Chart 76”。然而,Selection(i).Name将等于“Chart i”,而不是“Chart 75”或“Chart 76”。我该如何获取所选图表的实际名称? - MatthewK
这可能取决于你所拥有的对象类型;如果 Selection(i) 是 ChartArea 类型,你可以尝试使用 Selection(i).parent.Name 来获取包含图表的名称。 - Bogey

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