自动化错误服务器在PPT SetSourceData上引发了异常

时间:2018-02-23 08:23:09

标签: excel vba excel-vba powerpoint powerpoint-vba

有些背景,我有一个VBA循环,在Excel数据透视表上创建带有各种过滤器/视图的PPT幻灯片。它正在工作(在我添加DoEvents之后)。我最近添加了一些功能,可以在填充数据之前从头开始创建一个新的PPT文件。它不再工作了。

两种理论: 1)不知何故,内存在新的PPT文件创建循环中陷入困境,现在数据填充循环错误输出。 2)关于如何格式化默认图表的事情搞砸了。如果我手动编辑图表,保存并填充,则没有错误。但是,如果我创建然后自动尝试填充,则会出现错误。

由于脚本的复杂性,创建幻灯片的循环与循环完全分开,以重新打开和填充幻灯片。

以下是出错的部分:

'Paste the final temp dataset into PPT

Range("A1000").Activate

tempdata = Range(Selection, Selection.Offset(months, categories - 1)).Value

Set oChart = oPres.Slides(pages(b)).Shapes(metrics(a)).Chart

oChart.ChartData.Activate

Set wb = oChart.ChartData.Workbook
Set ws = wb.Worksheets(1)

ws.Range("A1:Z1000").ClearContents
ws.Range("A1", Range("A1").Offset(months, categories - 1)).Value = tempdata

'Let code catch up

Application.Wait (Now + TimeValue("00:00:02"))
DoEvents

'Redraw the selected dataset of the chart based on the # of categories and rows

oChart.SetSourceData Source:="='Sheet1'!$A$1:" & toChar(categories + 0) & months + 1, PlotBy:=xlColumns

尽管同时使用了Application.Wait和DoEvents,它仍然悬而未决。

这纯粹是一个计时问题,因为如果我单击Debug并继续运行代码而没有更改,它可以正常工作。我也通过Set Object语句使用后期绑定(可能是?),在循环结束时我总是设置oChart = Nothing。

有时它可以多次编写DoEvents,但随着流程变得越来越复杂,即使这样也行不通。我完全没有想法。有什么建议吗?

'Let code catch up

DoEvents
DoEvents
DoEvents
DoEvents
DoEvents
DoEvents
DoEvents
DoEvents
DoEvents
DoEvents
DoEvents
DoEvents

'Redraw the selected dataset of the chart based on the # of categories and rows

oChart.SetSourceData Source:="='Sheet1'!$A$1:" & toChar(categories + 0) & months + 1, PlotBy:=xlColumns

2 个答案:

答案 0 :(得分:0)

您可以尝试:

  1. 使用table.to_hdf('test.h5', key= 'csdkc', mode='w') ,此行位于模块顶部(功能之外):

    Sleep

    然后添加此行代替Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

    DoEvents

    https://stackoverflow.com/a/3891017/2707864

    另见

    https://www.myonlinetraininghub.com/pausing-or-delaying-vba-using-wait-sleep-or-a-loop

  2. 使用Sleep 1 ' Pause for 1 ms 的循环:

    DoEvents

    https://www.mrexcel.com/forum/excel-questions/36052-when-how-use-doevents-solved-post166114.html#post166114

    另见

    https://www.myonlinetraininghub.com/pausing-or-delaying-vba-using-wait-sleep-or-a-loop

  3. 使用它们的组合,可以根据等待时间提高系统性能。

    Dim PauseTime, Start, Finish, TotalTime
    PauseTime = 4 ' Set duration.
    Start = Timer ' Set start time.
    Do While Timer < Start + PauseTime
        DoEvents ' Yield to other processes.
    Loop
    Finish = Timer ' Set end time.
    TotalTime = Finish - Start ' Calculate total time.
    

    http://www.fmsinc.com/microsoftaccess/modules/examples/avoiddoevents.asp

答案 1 :(得分:0)

@ sancho.s,谢谢你的帮助。事实证明,错误与DoEvents无关。我一直在使用它作为一个草率的修复,而不了解它的功能。鉴于此,三个选项都没有奏效。我整天都在尝试各种组合而没有成功。相反,我不得不暴力关闭嵌入式PPT工作簿,将oChart设置为Nothing,重新实现oChart,重新打开工作簿,然后再次关闭它。

这使得进程慢了2倍(但不会比强制它等待一个计时器慢),它完全消除了所有错误。显然,它并不像在第一次打开工作簿时粘贴原始数据并重新选择数据一样。不知道为什么。

Sub UpdateChart(ByVal a As Integer, ByVal b As Integer, ByVal months As Integer, ByVal categories As Integer, ByRef pages() As Integer, ByRef metrics() As String, ByVal oPres As Object, ByVal legend_flag As Boolean)

Dim tempdata As Variant

'Paste the final temp dataset into PPT

tempdata = Range(Worksheets("calc").Range("A1000"), Worksheets("calc").Range("A1000").Offset(months, categories - 1)).Value

If legend_flag Then

    Set oChart = oPres.Slides(pages(b)).Shapes("legend").Chart

Else

    Set oChart = oPres.Slides(pages(b)).Shapes(metrics(a)).Chart

End If

oChart.ChartData.Activate

Set wb = oChart.ChartData.Workbook
Set ws = wb.Worksheets(1)

ws.Range("A1:Z1000").ClearContents
ws.Range(ws.Range("A1"), ws.Range("A1").Offset(months, categories - 1)).Value = tempdata

'Close workbook

wb.Close

Set oChart = Nothing

If legend_flag Then

    Set oChart = oPres.Slides(pages(b)).Shapes("legend").Chart

Else

    Set oChart = oPres.Slides(pages(b)).Shapes(metrics(a)).Chart

End If

oChart.ChartData.Activate

'Redraw the selected dataset of the chart based on the # of categories and rows

oChart.SetSourceData Source:="='Sheet1'!$A$1:" & toChar(categories + 0) & months + 1, PlotBy:=xlColumns

'Close workbook

oChart.ChartData.Workbook.Close

Set oChart = Nothing

Exit Sub

End Sub

我还将代码片段放在子例程中,并在末尾添加了Exit Sub,以便在之前的尝试中硬复位所有参数,但这些参数不起作用。因此,所有对象和参数都已被清除,以便进行良好的测量。

有没有人有任何想法为什么对象定义/打开工作簿会像这样绊倒?为什么DoEvents实际上并不能解决这个问题呢?