How to Loop Through All Open Word Documents in VBA
🔍 WiseChecker

How to Loop Through All Open Word Documents in VBA

If you work with multiple Word documents at once, you may need to apply the same formatting, extract data, or run a macro across all open files. Manually switching between documents and repeating the same action wastes time and introduces errors. VBA macros can automate this task by looping through the Documents collection. This article explains how to use the For Each loop with the Documents object to process every open document in Word. You will learn the syntax, a working example, and what to watch out for when writing these macros.

Key Takeaways: Looping Through Open Word Documents in VBA

  • Documents collection: Use For Each doc In Application.Documents to reference all currently open documents.
  • Activate vs direct reference: Avoid doc.Activate unless needed; use doc.Content directly for speed.
  • Error handling: Check doc.Saved and wrap in On Error Resume Next to skip unsaved or protected documents.

Understanding the Documents Collection in Word VBA

Word VBA stores every open document in the Documents collection. This collection is part of the Application object. Each document in the collection is a Document object. The collection is zero-based or one-based depending on how you access it, but the For Each loop handles this automatically. You do not need to know the index number. The loop runs once for every open document, including new blank documents that have not been saved.

Prerequisites for Using This Macro

Before writing the macro, you must have the Developer tab visible in Word. To enable the Developer tab, go to File > Options > Customize Ribbon and check Developer in the right column. You also need basic familiarity with the VBA editor. Press Alt+F11 to open the editor. Insert a new module by clicking Insert > Module. All code in this article goes into a standard module.

Basic Loop Structure

The core loop uses the For Each keyword. The variable doc is declared as a Document object. The loop iterates over Application.Documents. Inside the loop, you can read or modify properties of doc. The macro finishes when the last document is processed.

Steps to Write a Loop That Processes All Open Documents

Follow these steps to create a VBA macro that loops through every open document in Word. The example macro counts the number of paragraphs in each document and displays the result in a message box.

  1. Open the VBA Editor
    Press Alt+F11 in Word. The Visual Basic for Applications editor opens. If the Project Explorer is not visible, press Ctrl+R to show it.
  2. Insert a New Module
    In the Project Explorer, right-click Normal or your current project, then click Insert > Module. A blank code window appears.
  3. Declare the Sub Procedure
    Type Sub LoopAllDocuments() and press Enter. The editor automatically adds the End Sub line.
  4. Declare the Document Variable
    Inside the sub, type Dim doc As Document. This variable will hold each open document one at a time.
  5. Write the For Each Loop
    Type For Each doc In Application.Documents. This starts the loop. Press Enter and type the code that runs for each document.
  6. Add Actions Inside the Loop
    Type MsgBox doc.Name & " has " & doc.Paragraphs.Count & " paragraphs.". This line displays the document name and paragraph count.
  7. Close the Loop
    Type Next doc. This tells VBA to move to the next document in the collection.
  8. Run the Macro
    Press F5 while the cursor is inside the sub. Word processes each open document and shows a message box for each one. Click OK to move to the next document.

Common Mistakes and Limitations When Looping Through Documents

Several issues can cause errors or unexpected behavior when running this macro. Understanding these problems helps you write robust code.

Word Crashes When the Loop Modifies the Documents Collection

If your macro tries to close or open a document inside the loop, the Documents collection changes during iteration. This can cause a runtime error or crash. To avoid this, collect the document names into an array first, then loop through the array. For example:

Sub CloseAllExceptOne()
    Dim doc As Document
    Dim docNames() As String
    Dim i As Integer
    
    ReDim docNames(Application.Documents.Count - 1)
    i = 0
    For Each doc In Application.Documents
        docNames(i) = doc.Name
        i = i + 1
    Next doc
    
    For i = LBound(docNames) To UBound(docNames)
        If docNames(i) <> "KeepMe.docx" Then
            Documents(docNames(i)).Close SaveChanges:=wdDoNotSaveChanges
        End If
    Next i
End Sub

Loop Fails When a Document Is Protected or Read-Only

A document with editing restrictions can throw an error if the macro tries to modify its content. Use On Error Resume Next before the modification and check Err.Number afterward. Alternatively, check the ProtectionType property of the document. If doc.ProtectionType <> wdNoProtection, skip that document or unprotect it with a known password.

Macro Runs Slowly With Many Open Documents

Activating each document with doc.Activate inside the loop slows the macro significantly. Word must redraw the screen for every document switch. Set Application.ScreenUpdating = False at the start of the macro and restore it to True at the end. Also set Application.DisplayAlerts = False to suppress prompts.

VBA Loop Methods: For Each vs For Index

Item For Each doc In Documents For i = 1 To Documents.Count
Syntax Simpler, no index needed Requires index variable and manual access
Speed Faster for most operations Slightly slower due to index lookup
Safety with deletion Breaks if documents are removed during loop Must adjust index or loop backward
Readability Clear and self-documenting More verbose
Use case Read-only operations or modifications When you need to close or delete documents

You can now write a VBA macro that loops through all open Word documents and applies any action you need. Start with the simple For Each loop for reading data. For operations that change the document collection, use the index-based loop with an array. Always disable screen updating and display alerts to improve performance. As an advanced tip, combine the loop with a Select Case statement inside to apply different logic based on the document name or content type.