在许多列表段落上循环Word宏会导致内存问题

时间:2011-02-15 10:05:49

标签: list vba for-loop ms-word

我遇到了一个相当简单的用于Microsoft Word的vba宏的问题,它旨在解决我们在从Word文档创建PDF版本时使用列表缩进看到的一些问题。

宏基本上遍历文档中的每个列表,并且对于与列表相关联的每个列表段落,它设置列表模板的项目符号和文本位置以匹配在段落级别应用的内容(代码需要与Word一起使用) 2000所以不使用列表样式。)

当处理大型文档(60多个列表,~350个列表段落)时,宏第一次运行良好,但是第二次中断“此方法或属性不可用,因为有内存或磁盘问题“。

我已经按照通常的路线取消了循环中使用的任何对象引用,所以我看不出内存中可能存在的内容。

代码非常简单,由一个程序组成,目前存储在ThisDocument:

Option Explicit

Sub test2()
    Dim i As Integer, n As Integer
    Dim curList As List, curPar As Paragraph, templ As ListTemplate
    Dim gapSize As Double, level As Integer

    Application.ScreenUpdating = False
    Application.Options.Pagination = False

    For i = 1 To Lists.Count
        Set curList = Lists(i)

        For n = 1 To curList.ListParagraphs.Count
            Set curPar = curList.ListParagraphs(n)

            Set templ = curPar.Range.ListFormat.ListTemplate
            level = curPar.Range.ListFormat.ListLevelNumber
            gapSize = templ.ListLevels(level).TextPosition - templ.ListLevels(level).NumberPosition

            templ.ListLevels(level).NumberPosition = curPar.LeftIndent - gapSize
            templ.ListLevels(level).TextPosition = curPar.LeftIndent
            templ.ListLevels(level).TabPosition = curPar.TabStops.After(curPar.LeftIndent - gapSize).position

            Set templ = Nothing
            Set curPar = Nothing
        Next n

        UndoClear
        Set curList = Nothing

    Next i

    Application.ScreenUpdating = True
    Application.Options.Pagination = True

End Sub

3 个答案:

答案 0 :(得分:0)

你的代码看起来还不错,我的说法只是尝试以同样的方式做同样的想法...... 想法1:在内环中的某处插入DoEvents,以方便垃圾收集 想法2:使用FOR EACH构造简化代码:

For Each curlist in Lists
    For each curPar in curList.ListParagraphs
       With curPar.Range.ListFormat.ListTemplate
          .....
       End With
    Next curPar
Next curList

答案 1 :(得分:0)

除了UndoClear,您还可以在每个循环中保存文档。

但它可能会严重影响您的宏观表现。

这里有一个类似的问题http://social.msdn.microsoft.com/Forums/en-US/vsto/thread/de7a88b4-914f-4895-a88a-659b732e8d87/

希望这有帮助。

答案 2 :(得分:0)

我发现了一个讨厌的,肮脏的解决方案,可以解决这个问题,但实际上是一个非常糟糕的解决方案。基本上,一旦我们完成了一次完整的宏运行,关闭并保存文档并立即重新打开。然后,这允许立即或在任何阶段重新运行宏,因为关闭文档似乎最终正确地刷新内存。显然,这只能在用户乐于保存作为运行宏的一部分时使用,但在我的情况下它是