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.Documentsto reference all currently open documents. - Activate vs direct reference: Avoid
doc.Activateunless needed; usedoc.Contentdirectly for speed. - Error handling: Check
doc.Savedand wrap inOn Error Resume Nextto 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.
- 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. - Insert a New Module
In the Project Explorer, right-click Normal or your current project, then click Insert > Module. A blank code window appears. - Declare the Sub Procedure
TypeSub LoopAllDocuments()and press Enter. The editor automatically adds theEnd Subline. - Declare the Document Variable
Inside the sub, typeDim doc As Document. This variable will hold each open document one at a time. - Write the For Each Loop
TypeFor Each doc In Application.Documents. This starts the loop. Press Enter and type the code that runs for each document. - Add Actions Inside the Loop
TypeMsgBox doc.Name & " has " & doc.Paragraphs.Count & " paragraphs.". This line displays the document name and paragraph count. - Close the Loop
TypeNext doc. This tells VBA to move to the next document in the collection. - 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.