首页 > 解决方案 > VB.NET - 以编程方式关闭图表数据对象

问题描述

我的程序正在使 PowerPoint 自动循环遍历一系列图表参数并为每个参数集创建一个新图表。到目前为止,它适用于第一个图表 - 但是,在尝试创建第二个图表时它会引发错误,因为图表数据网格已经打开,并且我找不到正确关闭或处理数据网格之后的方法生成图表。

精简代码:

Imports Powerpoint = Microsoft.Office.Interop.PowerPoint
Imports Excel = Microsoft.Office.Interop.Excel

Private Sub generatePowerPoint(Qnum As String)
Try
   'Create PowerPoint object and assign a presentation / slide to it
        Dim oApp As Powerpoint.Application
        Dim oPres As Powerpoint.Presentation
        Dim oSlide As Powerpoint.Slide

        oApp = New Powerpoint.Application()
        oApp.Visible = True
        oApp.WindowState = Powerpoint.PpWindowState.ppWindowMinimized

        oPres = oApp.Presentations.Add

        'Prepare to generate charts based on parameters in a listbox
        Dim slideCount = lbQuestions.Items.Count


        For slideN = 1 To slideCount
         'Add a blank slide per graph request   
         oSlide = oPres.Slides.Add(slideN, Powerpoint.PpSlideLayout.ppLayoutBlank)

            'Create a new shape object for each slide
            Dim chartShape(slideCount) As Powerpoint.Shape

            ' What's causing the error: assign a chart object to the next shape object.
            ' This works for the first slide, but then throws an error that the PowerPoint 
            'Chart Data Grid is still open, preventing it from creating a new chart.

            chartShape(slideN - 1) = oSlide.Shapes.AddChart2(-1, ChartFind(chartType), 50, 50, 775, 410)
            Dim cData = chartShape(slideN - 1).Chart.ChartData 'Activate to refresh

            Dim workbook = cData.Workbook
            workbook.Application.Visible = False

            Dim datasheet = workbook.Worksheets(1)

            Dim colNumber As Integer = 2
            Dim firstRowNumber As Integer = 2

            datasheet.rows.clear()
            datasheet.columns.clear()

            For r = categoryNames.Count - 1 To 0 Step -1 

                datasheet.Cells(r + firstRowNumber, 1) = categoryNames(r)

            Next

      ... Code to assign data and format the chart object ...

           'Refresh the range accepted by the chart object
            chartShape(slideN-1).Chart.Refresh
     'Loop again
       Next

我花了一些时间在 msdn 上浏览 PowerPoint Interop 文档和 PowerPoint Chart Object Model 文档(例如https://docs.microsoft.com/en-us/previous-versions/office/developer/office-2010/ff760412 (v=office.14) , https://msdn.microsoft.com/en-us/vba/powerpoint-vba/articles/chartdata-object-powerpoint ),似乎有一种方法可以调用图表数据网格 (chartdata.activate()) ,没有关闭图表数据网格的方法。

抛出的确切错误消息是“System.Runtime.InteropServices.COMException (0xBFFF64AA):图表数据网格已经在 'Presentation 1 - PowerPoint' 中打开。要编辑此图表的数据,您需要先将其关闭。在 Microsoft .Office.Interop.PowerPoint.Shapes.AddChart2( ..."

有人有建议吗?

标签: vb.netautomationpowerpoint

解决方案


解决了,大部分。对于那些可能有同样问题的人:

chartShape.Chart.ChartData.Workbook.close()

这是一个未记录的方法/IntelliSense 不会提供它(因此在关闭时大写),但在打开图表对象并编辑数据后,请确保在尝试创建新图表对象之前完成代码块。

现在,如果打开的工作簿不是您打开的工作簿,这将不起作用(例如,我无法测试用户是否打开了工作簿,如果有,请关闭它)。我通过在 Try Catch 方法中封装 AddChart2 方法来解决这个问题,如果抛出错误,我会让用户知道关闭窗口并退出子例程,这样程序就不会崩溃。


推荐阅读