Please Note: This article is written for users of the following Microsoft Word versions: 2007 and 2010. If you are using an earlier version (Word 2003 or earlier), this tip may not work for you. For a version of this tip written specifically for earlier versions of Word, click here: Generating a Count of Word Occurrences.

Generating a Count of Word Occurrences

by Allen Wyatt
(last updated July 13, 2017)

28

As you are analyzing your documents, you may wonder if there is a way to create a count of the number of words in the document. Unfortunately, Word doesn't include such a feature, but there are a couple of things you can do.

First, if you want to know the number of times a specific word or phrase is used, you can follow these steps:

  1. Press Ctrl+H to display the Replace tab of the Find and Replace dialog box. (See Figure 1.)
  2. Figure 1. The Replace tab of the Find and Replace dialog box.

  3. In the Find What box, enter the word or phrase you want counted.
  4. In the Replace With box, enter ^&. This character sequence tells Word that you want to replace what you find with whatever you placed in the Find What box. (In other words, you are replacing the word or phrase with itself.)
  5. If you are searching for individual words, make sure you click the Find Whole Words Only check box.
  6. Click on Replace All. Word makes the replacements and shows you how many instances it replaced. That is the number you want.

This approach works great if you just have one or two words or phrases you want to know about. You can automate the process a bit by using a macro to search through the document and count for you. The following macro prompts the user for a word, and then counts the number of times that word appears in the document. It will continue to ask for another word until the user clicks on the Cancel button.

Sub FindWords()
    Dim sResponse As String
    Dim iCount As Integer

    ' Input different words until the user clicks cancel
    Do
        ' Identify the word to count
        sResponse = InputBox( _
          Prompt:="What word do you want to count?", _
          Title:="Count Words", Default:="")
    
        If sResponse > "" Then
            ' Set the counter to zero for each loop
            iCount = 0
            Application.ScreenUpdating = False
            With Selection
                .HomeKey Unit:=wdStory
                With .Find
                    .ClearFormatting
                    .Text = sResponse
                    ' Loop until Word can no longer
                    ' find the search string and
                    ' count each instance
                    Do While .Execute
                        iCount = iCount + 1
                        Selection.MoveRight
                    Loop
                End With
                ' show the number of occurences
                MsgBox sResponse & " appears " & iCount & " times"
            End With
            Application.ScreenUpdating = True
        End If
    Loop While sResponse <> ""
End Sub

If you want to determine all the unique words in a document, along with how many times each of them appears in the document, then a different approach is needed. The following macro will do just that.

Sub WordFrequency()
    Const maxwords = 9000          'Maximum unique words allowed
    Dim SingleWord As String       'Raw word pulled from doc
    Dim Words(maxwords) As String  'Array to hold unique words
    Dim Freq(maxwords) As Integer  'Frequency counter for unique words
    Dim WordNum As Integer         'Number of unique words
    Dim ByFreq As Boolean          'Flag for sorting order
    Dim ttlwds As Long             'Total words in the document
    Dim Excludes As String         'Words to be excluded
    Dim Found As Boolean           'Temporary flag
    Dim j, k, l, Temp As Integer   'Temporary variables
    Dim ans As String              'How user wants to sort results
    Dim tword As String            '

    ' Set up excluded words
    Excludes = "[the][a][of][is][to][for][by][be][and][are]"

    ' Find out how to sort
    ByFreq = True
    ans = InputBox("Sort by WORD or by FREQ?", "Sort order", "WORD")
    If ans = "" Then End
    If UCase(ans) = "WORD" Then
        ByFreq = False
    End If
    
    Selection.HomeKey Unit:=wdStory
    System.Cursor = wdCursorWait
    WordNum = 0
    ttlwds = ActiveDocument.Words.Count

    ' Control the repeat
    For Each aword In ActiveDocument.Words
        SingleWord = Trim(LCase(aword))
        'Out of range?
        If SingleWord < "a" Or SingleWord > "z" Then
            SingleWord = ""
        End If
        'On exclude list?
        If InStr(Excludes, "[" & SingleWord & "]") Then
            SingleWord = ""
        End If
        If Len(SingleWord) > 0 Then
            Found = False
            For j = 1 To WordNum
                If Words(j) = SingleWord Then
                    Freq(j) = Freq(j) + 1
                    Found = True
                    Exit For
                End If
            Next j
            If Not Found Then
                WordNum = WordNum + 1
                Words(WordNum) = SingleWord
                Freq(WordNum) = 1
            End If
            If WordNum > maxwords - 1 Then
                j = MsgBox("Too many words.", vbOKOnly)
                Exit For
            End If
        End If
        ttlwds = ttlwds - 1
        StatusBar = "Remaining: " & ttlwds & ", Unique: " & WordNum
    Next aword

    ' Now sort it into word order
    For j = 1 To WordNum - 1
        k = j
        For l = j + 1 To WordNum
            If (Not ByFreq And Words(l) < Words(k)) _
              Or (ByFreq And Freq(l) > Freq(k)) Then k = l
        Next l
        If k <> j Then
            tword = Words(j)
            Words(j) = Words(k)
            Words(k) = tword
            Temp = Freq(j)
            Freq(j) = Freq(k)
            Freq(k) = Temp
        End If
        StatusBar = "Sorting: " & WordNum - j
    Next j

    ' Now write out the results
    tmpName = ActiveDocument.AttachedTemplate.FullName
    Documents.Add Template:=tmpName, NewTemplate:=False
    Selection.ParagraphFormat.TabStops.ClearAll
    With Selection
        For j = 1 To WordNum
            .TypeText Text:=Trim(Str(Freq(j))) _
              & vbTab & Words(j) & vbCrLf
        Next j
    End With
    System.Cursor = wdCursorNormal
    j = MsgBox("There were " & Trim(Str(WordNum)) & _
      " different words ", vbOKOnly, "Finished")
End Sub

When you open a document and run this macro, you are asked if you want to create a list sorted by word or by frequency. If you choose word, then the resulting list is shown in alphabetical order. If you choose frequency, then the resulting list is in descending order based on how many times the word appeared in the document.

While the macro is running, the status bar indicates what is happening. Depending on the size of your document and the speed of your computer, the macro may take a while to complete. (I ran it with a 719-page document with over 349,000 words and it took about five minutes to complete.)

Note that there is a line in the macro that sets a value in the Excludes string. This string contains words that the macro will ignore when putting together the word list. If you want to add words to the exclusion list, simply add them to the string, between [square brackets]. Also, make sure the exclusion words are in lowercase.

If you don't like to use macros for some reason, there are other programs you can use to create word counts. For instance, the NoteTab text editor (the "light" version can be downloaded free at http://www.notetab.com) includes a feature that provides a word count. All you need to do is copy your entire document and paste it into NoteTab. Then, within NoteTab, choose Tools | Text Statistics | More. It presents an analysis of the word frequency, including percentages.

WordTips is your source for cost-effective Microsoft Word training. (Microsoft Word is the most popular word processing software in the world.) This tip (10761) applies to Microsoft Word 2007 and 2010. You can find a version of this tip for the older menu interface of Word here: Generating a Count of Word Occurrences.

Author Bio

Allen Wyatt

With more than 50 non-fiction books and numerous magazine articles to his credit, Allen Wyatt is an internationally recognized author. He  is president of Sharon Parq Associates, a computer and publishing services company. ...

MORE FROM ALLEN

Default Numbering Format for Endnotes

The default format for endnote numbers is lowercase Roman numerals. If you want the numbers to use a different format, such ...

Discover More

Converting Time Notation to Decimal Notation

Want to convert an elapsed time, such as 8:37, to a decimal time, such as 8.62? If you know how Excel stores times ...

Discover More

Forcing a Workbook to Close after Inactivity

Tired of your workbooks being left open on the screen where they can be seen by anyone passing by? Here's a way to have Excel ...

Discover More

Create Custom Apps with VBA! Discover how to extend the capabilities of Office 2013 (Word, Excel, PowerPoint, Outlook, and Access) with VBA programming, using it for writing macros, automating Office applications, and creating custom applications. Check out Mastering VBA for Office 2013 today!

More WordTips (ribbon)

Generating a List of Unique Words

Need to grab a list of unique words appearing in a document? You can tap the power of VBA's Words collection to perform the ...

Discover More

Displaying the Document Map

One of the viewing modes you can use for a document involves the use of the Document Map. This shows a quick outline of your ...

Discover More

Using Executive Summaries

An executive summary for a longer document may be a nice finishing touch. One of the lesser-known features of Word is that it ...

Discover More
Subscribe

FREE SERVICE: Get tips like this every week in WordTips, a free productivity newsletter. Enter your address and click "Subscribe."

View most recent newsletter.

Comments

If you would like to add an image to your comment (not an avatar, but an image to help in making the point of your comment), include the characters [{fig}] in your comment text. You’ll be prompted to upload your image when you submit the comment. Maximum image size is 8Mpixels. Images larger than 600px wide or 1000px tall will be reduced. Up to three images may be included in a comment. All images are subject to review. Commenting privileges may be curtailed if inappropriate images are posted.

What is three more than 5?

2017-06-17 01:15:20

Ema

I'm an author, not a program. How do I use the macros in this article? To me, they just look like a bunch of letters and symbols, but if I could figure out how to use them, that would be game changing. Any help would be appreciated. Thanks in advanced.


2017-04-02 14:11:46

Ylonda

Allen,
Thank you for this post. It's just what I needed, I am new to Marcos and I having a problem with the section If Words(j) = Single word Then I keep getting and error sub or function not defined. Please help, thank you


2016-10-26 01:02:40

WoX

Great tip. But it does not work for words in which first character is accented (Á, É, Í, Ó, Ú, á, é, í, ó, ú), like Árbol or árbol. It would be great if you could fix it for the latest Office 2016 for Mac. Thanks.


2016-04-05 22:25:47

Ly

Hi,

The macro kept running for about 20 minutes for a 100-word document and the results never seemed to come out. What's wrong?

Your help will be appreciated.

Thanks,

Ly


2016-02-07 08:07:09

Kamal Erfani

Dear Sir,

Hello and thank you for your great website. I tried to use the "Sub WordFrequency()" macro in a persian word file, but it didn't work. what should I do to have the macro to work?

Kamal Erfani


2015-12-11 01:48:54

V.S.Rawat

To: Ken Endacott

Your modifications do improve this macro a lot and proved very helpful.

That was also counting only lower ascii character words, so changing to this would count all unicode char words also.

If SingleWord < "a" Or (SingleWord > "z" And SingleWord < ChrW(255)) Then
SingleWord = ""
End If

Further required is a method for ignoring or separating punctuation for individual unicode character range, e.g. the characters । ॥ are punctuations specifically used in Hindi devanagari unicode character range, so these characters should be removed while counting otherwise, it is counting the words WITH these character and WITHOUT these characters separately.

Thanks for sharing.

--
Rawat
India


2015-12-11 01:02:47

V.S.Rawat

didn't work on Unicode.

I ran it on a 15 page 5300 words file in HIndi Devanagari, and it counted just 4 words which were actually roman list numbering, the only non-unicode words in the entire file.

Commenting out this file did count all the unicode words.

'Out of range?
'If SingleWord < "a" Or SingleWord > "z" Then
'SingleWord = ""
'End If

So, I guess, this was a bug that it counts only English words which can be corrected as above.

Thanks.
--
Rawat


2015-05-18 06:12:47

Ken Endacott

Emil

The macro to compare the word counts of two documents could be a modification of the WordFrequency macro that would open the documents one after the other and store the counts in a two dimensional array Freq(doc,j). The output would then be sorted in word order displaying each word followed by the counts for each document.

word1 57 43
word2 12 0
etc


2015-05-17 10:42:41

Emil

Thanks for the great ideas.
I would like to develop an application which finds the common words in two doc/docx files and their order of repetitiveness. This would be very helpful. Thank you again.


2015-04-04 18:06:41

Ken Endacott

Here is the macro modified to count words in all Story items and in textboxes. Also, to speed up things the status bar is updated only every 100th word.

Sub WordFrequency()
Const maxwords = 9000 'Maximum unique words allowed
Dim words(maxwords) As String 'Array to hold unique words
Dim Freq(maxwords) As Integer 'Frequency counter for unique words
Dim WordNum As Integer 'Number of unique words
Dim ByFreq As Boolean 'Flag for sorting order
Dim ttlwds As Long 'Total words in the document
Dim Excludes As String 'Words to be excluded
Dim j As Integer, k As Integer
Dim l As Integer, Temp As Integer
Dim ans As String 'How user wants to sort results
Dim tword As String '
Dim aWord As Range
Dim tmpName As String
Dim sRange As Range
Dim aShape As Shape

' Set up excluded words
Excludes = "[the][a][of][is][to][for][by][be][and][are][in][as][it][on][or][an][at]"

' Find out how to sort
ByFreq = True
ans = InputBox("Sort by WORD or by FREQ?", "Sort order", "WORD")
If ans = "" Then End
If UCase(ans) = "WORD" Then
ByFreq = False
End If

Selection.HomeKey Unit:=wdStory
System.Cursor = wdCursorWait
WordNum = 0

For Each sRange In ActiveDocument.StoryRanges

Select Case sRange.StoryType
' 1=main, 2=footnotes, 3=endnotes, 4=comments, 5=textframes, 6=even headers
' 7=primary header, 8=even footer, 9=primary footer, 10=firstpage header, 11= first footer,
Case 1, 2, 3, 4, 6, 7, 8, 9, 10, 11
ttlwds = sRange.words.Count
For Each aWord In sRange.words
If Not CheckWords(aWord, Excludes, words(), Freq(), WordNum, maxwords) Then GoTo TooMany
ttlwds = ttlwds - 1
If (ttlwds Mod 100) = 0 Then _
StatusBar = "Story" & Str(sRange.StoryType) & " Remaining: " & ttlwds & ", Unique: " & WordNum
Next aWord
Case 5
StatusBar = "Checking textboxes"
For Each aShape In ActiveDocument.Range.ShapeRange
With aShape.TextFrame
If .HasText Then
For Each aWord In .TextRange.words
If Not CheckWords(aWord, Excludes, words(), Freq(), WordNum, maxwords) Then GoTo TooMany
Next aWord
End If
End With
Next aShape
End Select
Next sRange

' Now sort it into word order
For j = 1 To WordNum - 1
k = j
For l = j + 1 To WordNum
If (Not ByFreq And words(l) < words(k)) _
Or (ByFreq And Freq(l) > Freq(k)) Then k = l
Next l
If k <> j Then
tword = words(j)
words(j) = words(k)
words(k) = tword
Temp = Freq(j)
Freq(j) = Freq(k)
Freq(k) = Temp
End If
If (j Mod 10) = 0 Then _
StatusBar = "Sorting: " & WordNum - j
Next j

' Now write out the results
tmpName = ActiveDocument.AttachedTemplate.FullName
Documents.Add Template:=tmpName, NewTemplate:=False
Selection.ParagraphFormat.TabStops.ClearAll
With Selection
For j = 1 To WordNum
.TypeText Text:=Trim(Str(Freq(j))) _
& vbTab & words(j) & vbCrLf
Next j
End With
System.Cursor = wdCursorNormal
j = MsgBox("There were " & Trim(Str(WordNum)) & _
" different words ", vbOKOnly, "Finished")
Exit Sub
TooMany:
System.Cursor = wdCursorNormal
Call MsgBox("Too many words.", vbOKOnly)
End Sub

Function CheckWords(aWord As Range, Excludes As String, words() As String, _
Freq() As Integer, WordNum As Integer, maxwords As Integer) As Boolean
Dim SingleWord As String
Dim Found As Boolean
Dim j As Integer
SingleWord = Trim(LCase(aWord))
If SingleWord < "a" Or SingleWord > "z" Then
SingleWord = ""
End If
If InStr(Excludes, "[" & SingleWord & "]") Then
SingleWord = ""
End If
If Len(SingleWord) > 0 Then
Found = False
For j = 1 To WordNum
If words(j) = SingleWord Then
Freq(j) = Freq(j) + 1
Found = True
Exit For
End If
Next j
If Not Found Then
WordNum = WordNum + 1
words(WordNum) = SingleWord
Freq(WordNum) = 1
End If
If WordNum > maxwords - 1 Then
CheckWords = False
Exit Function
End If
End If
CheckWords = True
End Function


2015-04-04 06:26:12

Ken Endacott

The macros only count words in the main story and not in other story types such as headers, footers and textboxes.

Some documents have a lot of text in textboxes and this text will be missed in the count. It is not difficult to add additional code to do this.

With headers and footers the words should probably be counted only once and not for every page. There are several types of headers and footers and they can change over sections hence the code to count words in them is a little more complex.


2015-04-03 07:24:40

Brian

This works great. Awesome job coding and free to boot! Thanks!


2014-11-05 15:59:51

Louis

Hi Glenn

I tried to run the second maccro on Word 2013. I does not work. Apparently, there is an issue with this line : "Selection.HomeKey Unit:=wdStory". I would very appreciate some help on this !

Thanks a lot.


2014-06-08 06:57:51

ritvik

thumbs up awesome website awesome info awesome macros


2014-06-05 10:30:29

Glenn Case

I have a couple suggestions to improve the second macro a bit. I wanted to add a note to the top of the list to record the document to which the list refers, and also to list out the excluded words.

I added a new variable DocName by adding after the last DIM statement the following:

Dim DocName As String
DocName = ActiveDocument.Name

Then I added just above the comment
'now write out the results
the following:

Excludes = Left(Excludes, Len(Excludes) - 1)
Excludes = Replace(Excludes, "]", ",")
Excludes = Replace(Excludes, "[", " ")

This code replaces the brackets with commas and spaces.

Then after the With Selection statement and before the For j statement I added the following:

.TypeText Text:="List of unique words in " & DocName & vbCrLf
If Excludes = "" Then GoTo SkipIt
.TypeText Text:="Excludes the following: " & Excludes & vbCrLf

SkipIt:

The net reuslt is a couple of lines at the top of the list in the new document as follows:

List of Unique words in 300E492208-IGW-DRAFT2.docx
Excludes the following: the, a, an, and, as, are, be, by, for, is, of, to

The list of Excluded words will match whatever your list is; mine is slightly different than that published above. If the list is blank then the second line is omitted.

Thanks again to Allen for this useful tip!



2014-06-04 06:36:37

karim

Very useful tip. just a question:
Is there anyway to support non-latin language?
once again, THANK YOU.


2014-03-26 10:19:07

Shane

Excellent, just what I needed, saved me hours of coding and error checking. Many thanks.


2014-03-01 01:14:13

shereen

Hello,

I want a count of words in a section or a selection. I don't want the count to include the words that appear in a TOC or header/footer.


2014-01-08 07:42:56

Gianni

Love it and thank you! exactly what I was looking for to analyse survey results with "open" answers (free text input)


2013-09-14 08:52:49

Bryan

Allen, when you charge money for these tips (via memberships, premium memberships, eBooks, and advertising) I find it really hard to hold my tongue when basic concepts are being missed. I try to be more politic about it but sometimes I can't help my sarcastic nature.

There certainly is no need for you to show Option Explicit on every macro you write. I agree that would be more confusing than helpful, especially since you don't currently have an article that explains what Option Explicit does (that I could find, anyway). However, as Glenn pointed out, there are two variables that aren't dimensioned in your code. There are only three explanations as to how this could happen:

1) You have dimensioned them as public variables somewhere.
2) You used Option Explicit in the module, but didn't test your code before publishing.
3) You didn't use Option Explicit at all.

I don't think option (1) is the case here, because there's no reason for it, and you don't explain to your readers that you have publicly declared the variables. This would only be a disservice to anyone trying to use your code.

I'm giving you the benefit of the doubt and assuming that with this much code you would have had to run it at least a few times to make sure it works (I usually test run my code in stages when I'm building), so we can safely assume that (2) is not the case.

Therefore, I'm only left with (3). The only way this code can compile and run is if you don't have OE in the module. It could be that you don't have the option checked to always include it and then you forgot to use it this one time, however given the wealth of evidence on other articles on the site, I've concluded that you simply don't use it at all. That's certainly your choice and you are entitled to your own decisions, but I'm going to point it out every time to help your (potentially paying) readers become better programmers. As I said, I can't think of any reason not to use Option Explicit, especially when you can set the IDE to add it for you in every module. I learned a TREMENDOUS amount of VBA over the last year from online sites and forums, and it's the least I can do to teach one of your readers this simple concept.

Next time I'll try and be more constructive and less snarky, but I was in a mood after comments on another article (not you)...


2013-09-13 15:18:15

awyatt

Bryan,

Do you really have to be so snarky? ;-)

Of course I'm "part of the choir." However, Option Explicit is a statement used outside of any Sub or Function construct, in the Declarations section of a project. What I show in these examples is the macros -- the Subs and Functions -- without anything that might go into the rest of the project.

I very rarely include the Declarations section because there are several different statements that could be placed in there to improve how the coding works. (One that comes to mind is Option Base, which can save memory depending on how you use arrays.)

Why do I not include the Declarations section with all the macros I publish? For brevity, clarity, and to reduce redundancy. I assure you it was purely an editorial decision, imperfectly applied, and not an affront to good programming practice.

-Allen


2013-09-13 13:30:42

Bryan

Preaching to the choir, Glenn :) I'm just not sure Allen is yet part of the chorus. I really can't come up with any reason not to use it.


2013-09-12 09:13:55

Glenn Case

Bryan:

I agree that Option Explicit was likely not used by whomever wrote the macro. The point I was trying to make (not to clearly, I see after re-reading my note) is that undimensioned variables are implicitly declared as Variant, which results in higher memory usage than necessary. I like to use Option Explicit as good prctive to avoid this issue, as the compiler will advise of any undeclared variables, thus preventing that issue.

In addition, it prevents errors due to mistyping. I've had issues in the past when I mistyped a variable name in the code. If you don't use Option Explicit, such an error can result in code which runs, but which produces incorrect results. If you recognize that you are getting bad results, you may spend a lot of time chasing the error. If not, the result can be even worse. Use of Option Explicit prevents this by flagging the undeclared variable. I would urge everyone to use this as a best practice.


2013-09-11 11:39:01

Bryan

Glenn, I don't think Allen uses Option Explicit, which prevents these types of problems


2013-09-10 08:58:15

Glenn Case

There are two undimensioned variables which s/b dimensioned:

Aword as Object
tmpName as String

Not strictly necessary to dimension these explicitly unless you have declared Option Explicit, but better practice to do so as otherwise they default to Variant, which uses more memory.


2012-05-27 04:17:33

Anna

Thanks for this, I have been looking for something like this as well and you made it possible! :)

Thanks!


2011-12-03 18:09:24

Eric

Love it! That's exactly what I have been looking for.

THANK YOU! :)


2011-11-18 04:08:07

Heather

You could also use Ctrl+F to search for the text and click on Highlight All.
This saves you having to do any replacing and still tells you how many occurrences it found.


This Site

Got a version of Word that uses the ribbon interface (Word 2007 or later)? This site is for you! If you use an earlier version of Word, visit our WordTips site focusing on the menu interface.

Newest Tips
Subscribe

FREE SERVICE: Get tips like this every week in WordTips, a free productivity newsletter. Enter your address and click "Subscribe."

(Your e-mail address is not shared with anyone, ever.)

View the most recent newsletter.