Confusing index out of bounds in shapes collection

Viewed 167

I am attempting to fix an inconsistent problem in some VB NET code that uses the MS Office Interop libraries. Running using the same files and data, the following code throws this exception:

The index into the specified collection is out of bounds.
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
at System.Runtime.InteropServices.CustomMarshalers.EnumeratorViewOfEnumVariant.MoveNext()
at myProject.TableNotePages(clsUsrDoc& usrdoc) in path\file.vb:line 1454
...

Line 1454 is the iShp += 1 line

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

There are a few questions that might help me solve this:

  1. Why doesn't this happen every time?
  2. Is the framework moveNext method in the trace called on the last non-conditional line of the loop instead of on the "for each" or "next" lines(adding another line between iShp += 1 and End If causes it to fail on that line instead)?
  3. Is there something unusual about VB foreach loops (My expertise is more in C/Java) or interop collections that would cause it to attempt iterating beyond the end of the shapes collection?

Any insight to what might be occurring here is appreciated.

1 Answers

It seems like once in a while vb/word interop arbitrarily walks off the end of the shapes collection. The below code, replacing "for each" with "for x to y," has run successfully a statistically significant number of times (about 50) across a few environments. I know this is not a good answer and still does not answer the question as to why this happens, but does solve the problem so posting as an answer in case an example helps someone else:

    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
Related