Results 1 to 11 of 11
  1. #1
    4 Star Lounger
    Join Date
    Mar 2002
    Location
    Sacramento, California, USA
    Posts
    509
    Thanks
    4
    Thanked 1 Time in 1 Post

    'for each document' bug - workaround? (Word 2000)

    I've long known about a bug in VBA which causes the following code to execute incorrectly:

    Dim doc As document
    For Each doc in Documents
    ' Do something useful.
    next doc

    Under certain conditions the loop does not visit each document once; it misses the active document, and visits one of the other documents twice. Does anyone know a reliable fix for this problem?

  2. #2
    Plutonium Lounger
    Join Date
    Mar 2002
    Posts
    84,353
    Thanks
    0
    Thanked 29 Times in 29 Posts

    Re: 'for each document' bug - workaround? (Word 2000)

    If the "Do something useful" modifies the Documents collection (closing a document, opening or creating a document, perhaps other things like saving a document) the results of For Each doc In Documents can be unpredictable.

    In some cases, you can get around it by looping through the collection backwards:

    Dim intIndex As Integer, intDocCount As Integer
    Dim doc As Document
    intDocCount = Documents.Count
    For intIndex= intDocCount To 1 Step -1
    Set doc = Documents(intIndex)
    ' Do something useful (or not)
    Next intIndex

  3. #3
    Platinum Lounger
    Join Date
    Feb 2001
    Location
    Yilgarn region of Toronto, Ontario
    Posts
    5,453
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: 'for each document' bug - workaround? (Word 20

    > reliable fix for this problem?

    I'm not sure that it is a bug. It may just be the nature of the world, not even a "design feature".


    Like Hans says "work backwards".

    As far as I know this applies to any VBA collection. If you are working through a collection of fields and deleting or changing some of them, work backwards.

    It is true with a collection of controls on a GUI form, if one is deleting the odd control (happens when working with GUI forms that respond dynamically to the situation)

    It should be true in Excel/VBA if one is working through a collection of cells, deleting some of them.

    I suspect that it is true in other modern languages that implement "collections".

  4. #4
    4 Star Lounger
    Join Date
    Mar 2002
    Location
    Sacramento, California, USA
    Posts
    509
    Thanks
    4
    Thanked 1 Time in 1 Post

    Re: 'for each document' bug - workaround? (Word 20

    You make a good point, but the bug is more general than that, and in this case "Do something useful" does not modify the set of open documents. I am simply counting the open documents that have certain property values.

  5. #5
    Super Moderator jscher2000's Avatar
    Join Date
    Feb 2001
    Location
    Silicon Valley, USA
    Posts
    23,112
    Thanks
    5
    Thanked 93 Times in 89 Posts

    Re: 'for each document' bug - workaround? (Word 20

    This sounds vaguely familiar, and you might be able to find something on it in a Lounge search.

    I'd substitute an old fashioned integer counter (For intCounter = 1 to Documents.Count) as an index into the Documents collection, rather than For Each, if that works around it.

  6. #6
    4 Star Lounger
    Join Date
    Mar 2002
    Location
    Sacramento, California, USA
    Posts
    509
    Thanks
    4
    Thanked 1 Time in 1 Post

    Re: 'for each document' bug - workaround? (Word 20

    > This sounds vaguely familiar, and you might be able to find something
    > on it in a Lounge search.

    I tried that first, but came up empty. I may have been searching for the wrong magic words -- various permutations of "document," "for each," and "duplicate." If you can think of something else to search for, I'll try it.

    >I'd substitute an old fashioned integer counter... rather than For Each, if that works around it.

    I thought of that too, earlier today... alas, it did not work.

    I have a hunch that another mysterious problem in my program related to this one. Maybe a description of that problem will give somebody and "aha!"

    When the program opens a form (just one particular form, out of several it uses), it spontaneously for activates a different document. Always same document, no matter which document was previously active. If the document that deaths activated is already active when the form is opened, it just stays active.

    I set a breakpoint on the first statement of the form's Activate event handler, and confirmed that the switch is happening after "Show" is called but before the Activate handler is entered. In other words, Word is doing it; my code is not.

  7. #7
    Super Moderator jscher2000's Avatar
    Join Date
    Feb 2001
    Location
    Silicon Valley, USA
    Posts
    23,112
    Thanks
    5
    Thanked 93 Times in 89 Posts

    Re: 'for each document' bug - workaround? (Word 20

    Yes, activating a different document could change the order of items in the collection. Ruins either approach.

    Why could the other document be activated. Does it contain a form of the same name? Probably not. Why is that other document open?

    So anyway, another workaround would be to capture all of the document names to an array:

    <pre>Sub IterateOverDocsDemo()
    ' Create a dynamic array so can resize with a variable
    Dim strArray() As String, intCounter As Integer
    ReDim strArray(1 To Documents.Count)
    ' Slap document full paths into an array
    For intCounter = 1 To Documents.Count
    strArray(intCounter) = Documents(intCounter).FullName
    Next
    ' Use array to access the documents
    For intCounter = 1 To Documents.Count
    Debug.Print Documents(strArray(intCounter)).FullName, _
    Documents(strArray(intCounter)).ActiveWindow.Capti on
    Next
    End Sub</pre>

    Hope this helps.

  8. #8
    4 Star Lounger
    Join Date
    Mar 2002
    Location
    Sacramento, California, USA
    Posts
    509
    Thanks
    4
    Thanked 1 Time in 1 Post

    Re: 'for each document' bug - workaround? (Word 20

    > Yes, activating a different document could change the order of items in the collection. Ruins either approach.

    You may have misinterpreted when I said. I have a hunch that the two problems are related -- that they have a common source. One does not cause the other. They are not happening in the same part of the program.

    >Why could the other document be activated.

    That's the $65,536 question!

    > Does it contain a form of the same name?

    Yes, it does, as a matter of course. In this application there are typically several identical documents (identical except for content) open at once. That's not something I can avoid; if I did, the application would be close to useless.

    Quite possibly having two documents which contain the same form as part of the condition that generates the problem. It should not be a problem, though, and is not with any of the other forms in the program.

    I could unload the form after each use and see if that helps, but I don't think it would be a viable solution. This form does a lot of initialization, and having to load it each time I open it is likely to produce significant delays.

    > So anyway, another workaround would be to capture all of the document names to an array...

    Yes, that's the best solution if I can't find the root of the problem. I thought it would be very inefficient, but last night I found a shortcut which will eliminate that difficulty.

  9. #9
    4 Star Lounger
    Join Date
    Mar 2002
    Location
    Sacramento, California, USA
    Posts
    509
    Thanks
    4
    Thanked 1 Time in 1 Post

    Re: 'for each document' bug - workaround? (Word 20

    Good news and bad news.

    The good news is that your guess about before been opened in another document was correct, and unloading the form after each use solved the problem. I don't know why it's necessary, but it works. Surprisingly, performance is not objectionably bad.

    The bad news is that after I rewrote the "for each document..." loop to count each document exactly once, the program still doesn't work. That is due to another problem which appears to be unsolvable! I recently asked about the other problem in another thread and got a solution which appeared to work, but now does not. (It probably appeared to work only because of the bug which I have now fixed.)

    In case you enjoy the puzzling over other peoples' head scratchers, here's the other problem. My application maintains a "scratch document" along with a variable number of "real" documents, and it is supposed to close the scratch document automatically when the last real document is closed. It does this in the Application_DocumentBeforeClose event handler. Here's what happens when I close last real document. Before Word calls the event handler it looks at its windows and decides that when it closes this document it can close document window, since another document (the scratch document) is still open. But when it gets control back from the event handler, the scratch document and its window have been closed! Word proceeds to close the last open document and its window, leaving no windows open, but does not shut itself down as it normally would when closing its last window. Crash.

  10. #10
    Super Moderator jscher2000's Avatar
    Join Date
    Feb 2001
    Location
    Silicon Valley, USA
    Posts
    23,112
    Thanks
    5
    Thanked 93 Times in 89 Posts

    Re: 'for each document' bug - workaround? (Word 20

    Ah, you refer to this thread.

    It would be cheating, but if your DocumentBeforeClose routine detects that the only documents open are (1) your last real document and (2) your scratch document, how about creating a new blank document before closing the last real document? You can at least do this as a workaround until a genuine solution emerges.

  11. #11
    4 Star Lounger
    Join Date
    Mar 2002
    Location
    Sacramento, California, USA
    Posts
    509
    Thanks
    4
    Thanked 1 Time in 1 Post

    Re: 'for each document' bug - workaround? (Word 20

    > It would be cheating, but... how about creating a new blank document before closing the last real document?

    Well, not exactly cheating, but... to all intents and purposes the scratch document IS a new blank document! It never gets saved, and its contents is deleted after each use. Its only distinction is a special custom property value which has no significance after my application is closed.

    I'm just leaving the scratch document open until I find a real solution, which is a simpler way of reaching the same result.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •