首页 > 解决方案 > 形状集合中的混淆索引越界

问题描述

我正在尝试修复一些使用 MS Office 互操作库的 VB NET 代码中的不一致问题。使用相同的文件和数据运行,以下代码抛出此异常:

指定集合的​​索引超出范围。
在 System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
在 System.Runtime.InteropServices.CustomMarshalers.EnumeratorViewOfEnumVariant.MoveNext()
在 myProject.TableNotePages(clsUsrDoc& usrdoc) 在 path\file.vb:line 1454
.. .

第 1454 行是 iShp += 1 行

Dim MyDoc As Word.Document = usrdoc.Document
Dim NoteBoxes As New Collections.Generic.SortedDictionary(Of Integer, Word.TextFrame)
Dim iShp As Integer = 1
For Each shp As Word.Shape In MyDoc.Sections.First.Headers(Word.WdHeaderFooterIndex.wdHeaderFooterPrimary).Shapes
    If Not shp.TextFrame.Next Is Nothing Then
        NoteBoxes.Add(iShp, shp.TextFrame)
        iShp += 1
    End If
Next

有几个问题可以帮助我解决这个问题:

  1. 为什么不是每次都这样?
  2. 跟踪中的框架 moveNext 方法是否在循环的最后一个非条件行而不是“for each”或“next”行上调用(在 iShp += 1 和 End If 之间添加另一行会导致它失败行代替)?
  3. VB foreach 循环(我的专长更多是 C/Java)或互操作集合是否有一些不寻常的地方会导致它尝试迭代超出形状集合的末尾?

感谢您对此处可能发生的情况的任何见解。

标签: vb.netvisual-studio-2013ms-wordoffice-interop

解决方案


似乎偶尔 vb/word 互操作会任意离开形状集合的末尾。下面的代码将“for each”替换为“for x to y”,已经在几个环境中成功运行了统计上显着的次数(大约 50 次)。我知道这不是一个好的答案,并且仍然没有回答为什么会发生这种情况的问题,但确实解决了问题,因此发布作为答案以防示例对其他人有帮助:

    Dim MyDoc As Word.Document = usrdoc.Document
    Dim NoteBoxes As New Collections.Generic.SortedDictionary(Of Integer, Word.TextFrame)
    Dim iShp As Integer = 1
    Dim loopLength As Integer = MyDoc.Sections.First.Headers(Word.WdHeaderFooterIndex.wdHeaderFooterPrimary).Shapes.Count
    Dim shp As Word.Shape = Nothing
    For i As Integer = 1 To loopLength '1-indexed
        shp = MyDoc.Sections.First.Headers(Word.WdHeaderFooterIndex.wdHeaderFooterPrimary).Shapes(i)
        If Not shp.TextFrame.Next Is Nothing Then
            NoteBoxes.Add(iShp, shp.TextFrame)
            iShp += 1
        End If
    Next

推荐阅读