有些背景,我有一个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
答案 0 :(得分:0)
您可以尝试:
使用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
使用Sleep 1 ' Pause for 1 ms
的循环:
DoEvents
见:
另见:
https://www.myonlinetraininghub.com/pausing-or-delaying-vba-using-wait-sleep-or-a-loop
使用它们的组合,可以根据等待时间提高系统性能。
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实际上并不能解决这个问题呢?