65.9K
CodeProject 正在变化。 阅读更多。
Home

PowerPoint 演示文稿中的动态 MSGraph.Chart

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2014年8月26日

CPOL

7分钟阅读

viewsIcon

17238

在PowerPoint幻灯片中添加和处理MSGraph

引言

几周前,我的同事告诉我他们想做一个“应用程序”来推广我们的一款新产品。虽然我喜欢新想法,但我们缺乏时间和资源来制作“应用程序”。所以我提议用 PowerPoint 和 VBA 来制作。他们的要求和需求(一些图表、一些选择……)看起来并不难实现……但我花了很长时间才弄清楚如何正确地处理 PowerPoint 上的图表。

在本文中,我将简要介绍如何将这个旧软件添加到您的 PowerPoint 应用程序中,其中有哪些陷阱以及如何处理以获得整洁的效果。我使用的是 PowerPoint 2010。

目的是向您展示如何将图表添加到现有的幻灯片中,管理数据并为后续使用准备幻灯片。

背景

我假设您知道如何在 PowerPoint 中打开 “开发工具”选项卡

Microsoft 提供的关于查看 MSGraph.Chart 对象模型 的最佳资源之一。不要对此抱有太大期望。

Microsoft 提供的另一个很棒的 资源,它讨论了 MSChart 的实现。

一个关于您可以在 MSGraph 中使用的 炫丽的颜色 的概览。

使用代码

在幻灯片中添加 MSGraph.Chart

代码说明

添加 MSGraph.Chart 本身就是一种不错的体验。它带有自己的数据集和数据处理方式。我们不会将它拖放到幻灯片上,而是通过代码添加。因此,打开一个 PowerPoint 幻灯片,转到“开发工具”选项卡,单击“Visual Basic”,然后查看左侧树视图中的第一个文件夹。它应该显示“Microsoft Powerpoint Objects”以及至少一张列出的幻灯片。

单击幻灯片名称,现在我们将添加插入 MSGraph 的代码。我们将把它添加为一个 Shape,尽管它也可以作为 MSGraph.Chart 访问。这是一个令人困惑的情况。

它通过距左上角的偏移量进行定位。此图表的大小相对于页面宽度和高度。请参阅下图以评估结果。

添加后,我们将不得不清除单元格,因为 MSGraph 始终附带数据集。

我们正在设置图表的一些方面,例如它的类型 (ChartType)。随意尝试以查看结果。Intellisense 可以正常工作,所以请使用它(按 Ctrl + 空格键)。

接下来是最困难的部分……添加实际数据。您必须清除单元格才能摆脱原始数据集。然后,您可以构建自己的数据集。将下面的代码片段与代码和屏幕截图进行比较,您将看到它是如何工作的。它看起来像 Excel,但又不完全一样。
“创建一个新的数据系列:数据系列条目位于“0”列中,并通过 .Range("0#") 引用,其中 # 是工作表中的行号。列标题位于第“0”行,并通过 .Range("$0") 引用,其中“&”是列字母。”

令人困惑?右键单击 MSGraph,选择“图表对象”和“编辑”。查看下面的屏幕截图,看看弄清楚什么放在哪里会变得多么容易。

您还没有看到 MSGraph 吗?确实如此!请继续阅读……我从未告诉过您会很简单。我的建议:在纸上绘制它,它很快就会变得令人困惑。

最后,我们将调整一些颜色,以避免 MSGraph.Chart 带来的可爱的九十年代风格。上面有一个链接,它确实是痛苦的亮绿色(4)和纯白色(2),使用 ColorIndex 属性。我只需要将“Aanvullend pensioen”更改为不同的颜色,所以我选择了“SeriesCollection(3)”。第二次颜色更改会影响图表后面的区域,而不是图表区域本身。

总而言之,我更新了 MSGraph,使其显示我想要的效果。

实际的 VBA 代码

Option Explicit

Dim myChart As Graph.Chart

Sub SetChartData()
          
	Dim lHeight As Single
	Dim lWidth As Single
   
    	' Graph will not cover the entire page   
    	lHeight = ActivePresentation.PageSetup.SlideHeight
    	lWidth = ActivePresentation.PageSetup.SlideWidth
  
	' We'll add the chart here, I'm already on Slide44 but you could as well have slide1
	' the lWidth/5 provides an offset from the left upper corner of 20%, 1/5th), of the page
	Set myChart = Slide44.Shapes.AddOLEObject(Left:=(lWidth / 5), _
                                Top:=(lHeight / 4), _
                                Width:=(lWidth / 1.3), _
                                Height:=(lHeight / 1.4), _
                                ClassName:="MSGraph.Chart", _
                                Link:=0).OLEFormat.Object
     	
	' remove dummy data
    	myChart.Application.DataSheet.Cells.Clear
   
    	myChart.ChartType = xlColumnStacked
    	myChart.WallsAndGridlines2D = False
   
       	' Create a new data series on row 4. Data series
	' entries are in the "0" column, and are referenced
	' by .Range("0#") where # is the row in the datasheet.
	' Comumn titles are in row "O", and are referenced
	' by .Range("$0") where "&" is the row letter.
	'
    	myChart.Application.DataSheet.Range("01").Value = "Loon"
	myChart.Application.DataSheet.Range("02").Value = "Wettelijk pensioen"
	myChart.Application.DataSheet.Range("03").Value = "Aanvullend pensioen"
  
    	myChart.Application.DataSheet.Range("A0").Value = "Pensioen"
    	myChart.Application.DataSheet.Range("B0").Value = "Loon"
   
    	myChart.Application.DataSheet.Range("A1").Value = "0"
    	myChart.Application.DataSheet.Range("A2").Value = "0"
    	myChart.Application.DataSheet.Range("A3").Value = "0"
   
    	myChart.Application.DataSheet.Range("B1").Value = "0"
    	myChart.Application.DataSheet.Range("B2").Value = "0"
    	myChart.Application.DataSheet.Range("B3").Value = "0"
       
    	myChart.SeriesCollection(3).Interior.ColorIndex = 4
    	myChart.ChartArea.Interior.ColorIndex = 2
       
    	myChart.Application.Update
   
End Sub

两张屏幕截图来说明位置和数据

使用上面示例中的参数查看 MSGraph 的位置。

Position of the Graph

右键单击图表,选择“图表对象”>“编辑”的结果。

您可以将行和列与数据最终出现的位置进行比较。

在幻灯片上显示 MSGraph

您通过代码添加 MSGraph.Chart 时,在幻灯片上看不到它。即使打开幻灯片也没有帮助,因为没有什么可以触发 Sub。PowerPoint 中没有 autolaunch、onPageOpen、onPresentationStart 或任何类似的东西。有一个 Autoevents 插件,但当演示文稿的目的是分发时,这是一个麻烦,因为插件必须安装在 PowerPoint 中。所以……必须有另一种方法。

代码解释

只需添加一个新幻灯片,将其放在您之前的幻灯片之前。在此新幻灯片上,添加一个按钮,单击它,并将其 Click 事件设置为在上一个章节中创建的添加 MSGraph 的 Sub。现在单击此按钮可以将您的 MSGraph 设置到页面上。

此外,由于 MSGraph 或 PowerPoint 中都没有“SuspendLayout”:如果您有大型图表需要更新和修改,您可以真正给您的朋友留下深刻印象,因为所有操作都在屏幕上实时进行,而 PowerPoint 正在消化您的代码。在实际情况下,这意味着图表会显示并使用默认数据库绘制,然后几乎消失,因为单元格被清除,然后随着数据系列的添加而增长,最后接收新的颜色。这……至少可以说是尴尬。

所以,准备好按钮,添加代码,最重要的是,用它开始演示文稿(我将按钮命名为 START)。别忘了,我使用的是 Slide44,您可能使用的是任何其他编号。在我的代码中,我让按钮将演示文稿移动到下一张幻灯片,以真正将其定位为演示文稿的“启动者”。

实际的 VBA 代码

Option Explicit

Private Sub CommandButtonStart_Click()
	' prepares the next slide	
	Slide44.SetChartData

    	' kicks off the presenation!
	With ActivePresentation.SlideShowWindow
        	.View.GotoSlide (ActivePresentation.SlideShowWindow.View.Slide.SlideIndex + 1)
	End With
End Sub

从幻灯片中删除 MSGraph.Chart

哦,这里有很多乐趣……我们实际上是将 MSGraph.Chart 对象注入了幻灯片。因此,即使在演示文稿之后,当交易完成,香槟也上了……它仍然在那里。实际上,除非您手动选择 MSGraph 并将其从 PowerPoint 幻灯片中删除,否则它不会消失。

更糟的是——忘记删除它,图表就会堆叠在一起,您就会收到一个免费的错误。我真的为此问题进行了长时间的斗争,因为在我最终的演示文稿中,我使用了三张带有图表的幻灯片。我忘记删除一个,然后*砰*,不得不重新开始。

代码说明

让我们稍微修改一下上面添加的“开始”按钮相关的小块代码。它应该扩展以清理幻灯片,然后准备它们并移动到下一张幻灯片。

所以,首先,我们获取演示文稿。然后,我们将开始遍历页面、形状、嵌入式对象形状、MSGraph。然后我们删除它们。请注意——此代码仅删除 MSGraph.Chart.8。更早或更晚的版本将保留在您的幻灯片上。您可以随意使用 like "MSGraph*" 来删除所有内容。

实际的 VBA 代码

Option Explicit

Private Sub CommandButtonStart_Click()
	
	Dim sld As Long
	Dim i As Integer
	Dim j As Integer

	' let's loop through all slides
	sld = ActivePresentation.Slides.Count
	For i = 1 To sld
		' loop through all shapes
        	For j = ActivePresentation.Slides(i).Shapes.Count To 1 Step -1
			' find the embedded objects
	        	If ActivePresentation.Slides(i).Shapes(j).Type = msoEmbeddedOLEObject Then
				' check if it's a MSGraph.Chart
				If ActivePresentation.Slides(i).Shapes(j).OLEFormat.ProgID = "MSGraph.Chart.8" Then
					' remove it from the slide
					ActivePresentation.Slides(i).Shapes(j).Delete
				End If
			End If
        	Next j
	Next i

 	' prepares the next slide
	Slide44.SetChartData

    	' kicks off the presenation!
	With ActivePresentation.SlideShowWindow
        	.View.GotoSlide (ActivePresentation.SlideShowWindow.View.Slide.SlideIndex + 1)
	End With
End Sub

更改 MSGraph.Chart 对象中的数据

更新数据非常容易。我将其与滑动条关联,但您也可以使用按钮或单选按钮或其他任何东西。您所要做的就是修改数据系列。这只在图表是新添加的(因此是即时生成的)时才有效,而不是重复添加(因此在单击“开始”时会被删除)。

实际的 VBA 代码

Option Explicit

Private Sub ChangeChartData(ByVal x As Long)

	myChart.Application.DataSheet.Range("A2").Value = CStr(x * 2)
        myChart.Application.DataSheet.Range("A3").Value = CStr(x * 3)       
    	myChart.Application.DataSheet.Range("B1").Value = CStr(x)
       
	myChart.Application.Update
End Sub

在我的幻灯片上添加滑块,实际上充分利用了 MSGraph 的“动态”更新:图表随着输入的变化而平稳移动。我所要做的就是让幻灯片的 _Change() 事件将选定的值推送到 ChangeChartData()。

关注点

添加图表是一回事,删除图表是另一回事。

绘制要添加的数据,并添加行/列名称。唯一能跟踪的方法。

我没有使用 Excel 是因为……它实际上在我添加它时给了我一个错误,并且我读到它必须处于活动状态才能填充图表。这个 MSGraph.Chart 控件,尽管很老,但似乎是更快的解决方案,同时也考虑了幻灯片的广泛分发。

尽情享用!

© . All rights reserved.