Class_Terminate的奇怪调用

时间:2013-12-13 14:11:10

标签: vba scripting powerpoint

我真的不知道为什么会这样:

这个hier是一个小小的演示包装器:

' Class PPTGenPresentation

Private m_Presentation As Presentation

Public Sub Class_Initialize()
    Set m_Presentation = Nothing
End Sub

Public Sub Class_Terminate()
    If Not m_Presentation Is Nothing Then
        m_Presentation.Close
    End If
End Sub

Public Sub Initialize(ByVal presentationPath As String)
    On Error GoTo Error

    Set m_Presentation = Presentations.Open(presentationPath, , , msoFalse)

    Exit Sub
Error:
    MsgBox ("Could not open " & presentationPath)
End Sub


Public Property Get Instance() As Presentation
    ' After this line Class_Terminate() gets called somehow ..
    Instance = m_Presentation
End Property

在我打开ppt之后,我想通过访问该属性来访问实际的演示文稿:

For Each filePath In filePaths
    Set safePresentation = New PPTGenPresentation
    safePresentation.Initialize (filePath)

    Dim tmp As Presentation
    Set tmp = savePresentation.Instance

    For Each oSlide In tmp.Slides
        Set oShape = oSlide.Shapes(1)

        If oShape.HasTextFrame Then
            If oShape.TextFrame.HasText Then
                MsgBox oShape.TextFrame                    
            End If
        End If
    Next
Next

但是在访问了属性Instance之后,不知怎的Class_terminate被调用了。

我不知道为什么会这样。有人可以向我解释问题是什么吗?

2 个答案:

答案 0 :(得分:1)

我已在您的代码中添加了评论。

基本上,当你使用set=new来覆盖一个对象时(正如你在For Each循环中的每次后续迭代中所发生的那样),从理论的角度来看,前一个对象有两种情况之一:

  1. 引用丢失但对象存在,现在会产生内存泄漏
  2. 当引用消失时,对象会自动清理并销毁
  3. VBA自动导致第二个为真。当您再次使用“新建”时,第一个演示文稿将无法再引用它,因此它将被清理并销毁。这会调用Class_Terminate

    请注意,在没有此类代码的其他语言中,您现在可能会开始导致内存泄漏(例如C ++)。

    For Each filePath In filePaths
        'Each subsequent iteration the following basically happens:
        'when you set the presentation to a new one, you are effectively
        'ending the previous version. So for example, the following *basically* happens:
    
        ' if not safePresentation is nothing then set safePresentation=nothing 
    
        Set safePresentation = New PPTGenPresentation
        safePresentation.Initialize (filePath)
    
        Dim tmp As Presentation
        Set tmp = savePresentation.Instance
    
        For Each oSlide In tmp.Slides
            Set oShape = oSlide.Shapes(1)
    
        Next
    Next
    

    要解决此问题,请将Set safePresentation = New PPTGenPresentation移到For Each循环上方。

答案 1 :(得分:1)

当你的代码中出现语法错误时会调用它,我怀疑你在调用代码中有On Error Resume Next

Public Property Get Instance() As Presentation
    ' After this line Class_Terminate() gets called somehow ..
    Instance = m_Presentation
End Property

生成一个错误,由下一个简历抑制,尝试:

Public Property Get Instance() As Presentation
    ' After this line Class_Terminate() gets called somehow ..
    Set Instance = m_Presentation
End Property

你最好不要压制错误,当然不是在测试