Word VBA, Loop through all words in a document

Using VBA for Word, how do I loop through all the "Words" in the Active document?

I've used this in Access, but don't know the synatx for Word.

I'm thinking it should look something like this:

Sub Loop()
Dim wd as Word
    for each wd in ActiveDocument
        'Do Something
    Next wd
End Sub

I'm guessing I could use something like "Loop Until End of Document"

but I still nee th correct Word syntax fo a "Word"

I hope I have made myself clear
LVL 74
Jeffrey CoachmanMIS LiasonAsked:
Who is Participating?
 
GrahamSkanConnect With a Mentor RetiredCommented:
Done it again. Typed it all in a few hours ago. Come back to check & find that I haven't submitted it.

I don't know why your weekday name is one day out. To get around you could do this.

.Text = Format$(DateAdd("d", 1, .Text), "dddd, ") & Format$(.Text, "mmmm, dd yy")
0
 
GrahamSkanRetiredCommented:
You're so close

Sub Loop()
Dim wd as Range
    for each wd in ActiveDocument.words
        'Do Something
    Next wd
End Sub
0
 
GrahamSkanRetiredCommented:
Just be aware that the extracted range might include a trailing space or a non-printing character.
0
Cloud Class® Course: Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

 
Jeffrey CoachmanMIS LiasonAuthor Commented:
GrahamSkan,

Well... It did not work as I expected.

Let me give you the whole story.

I get a word document every month with scheduling information. The schedule first has the "Day", (ex. 11/20/04) then underneath that day is a Table listing all of the people working that day. This is repeated for the remaining 29 days.

The day is always formatted dd/mm/yy, I would like to see the Full (Long) date. For example: Saturday, November 20 2004.

I would like the code to loop through all words in the document and change all the Short Dates to Full (Long) dates.

I got this code from a previous post a while ago:

If IsDate(Selection.Text) Then
    Selection.Text = Format$(Selection.Text, "dddd, mmmm, dd yyyy")
End If

I tested the code, and it worked fine.

Then I inserted it into your code to get:

Sub Loop()
Dim wd as Range
    For each wd in ActiveDocument.words
        If IsDate(Selection.Text) Then
            Selection.Text = Format$(Selection.Text, "dddd, mmmm, dd yyyy")
        End If
    Next wd
End Sub

It did not work as expected.

I then substituted "wd" for "Selection.Text" and it still did not work.

Any ideas?

Thanks

0
 
GrahamSkanRetiredCommented:
Yes Word will split a date like that into five words.: 24, /, 10, /, 04
0
 
GrahamSkanRetiredCommented:
Try this:

Sub FormatDates()
Dim rng As Range

Set rng = ActiveDocument.Range
    Do While True
        With rng.Find
            .Text = "[0-9]{1,2}/[0-9]{1,2}/[0-9]{1,2}"
            .Forward = True
            .Format = True
            .MatchWildcards = True
            .Execute
            If .Found = False Then
                Exit Sub
            End If
        End With
        With rng
            If IsDate(.Text) Then
                .Text = Format$(.Text, "dddd, mmmm, dd yyyy")
            End If
        .Collapse wdCollapseEnd
        .End = ActiveDocument.Range.End
        End With
    Loop
End Sub
0
 
Jeffrey CoachmanMIS LiasonAuthor Commented:
GrahamSkan,

Good news and bad news.

The code works, except that I mistakenly gave you the incorrect original date format. The date format in my schedule is 10/25/2005 (mm,dd,yyyy) , not 10/25/04 (mm,dd,yy), sorry.

So when I ran your code it put the characters "20" in front of all the years like this:
Monday, October 25, 202004 (even if the year was 1997, it would show "201997")

So after several attempts at modifying your code, I just simply changed the date format to "yy", and it looks like what I want.

If you notice, because of your help, I have doubled the points of this question.

I would like to know:

Why did it put the "20" in front of all the years?
Was my code modification acceptable?
Can you "lightly" comment the code, please?
And ultimately: Why does Word NOT provide this functionality? You can do WITHOUT VBA in Excel and Access, but not in Word? I looked all over the web and could not find a solution! Am I the only person on the Planet who needs to reformat dates in Word???

(OK, so the last question was really a rant)

Thanks a million (I mean 250!)

:)
0
 
GrahamSkanRetiredCommented:
Q1
Yes that would be expected. The find stops at what is, in fact the century digits, but the date conversion, using only two digits, interprets them as 2020 or 2019. The other two digits are left in place.

Q2
You haven't actually shown your modification, but if it works, I guess you've got the idea.

Q3

Sub FormatDates()
Dim rng As Range

Set rng = ActiveDocument.Range
    Do While True
        With rng.Find
       'in the following find string:
        '[0-9] any character from 0 to 9
       '{1,2} one or two of those characters
        '/ the "/" character          
        .Text = "[0-9]{1,2}/[0-9]{1,2}/[0-9]{1,2}"


            .Forward = True
            .Format = True
            .MatchWildcards = True 'the find string is not plain text, but uses wildcards
            .Execute
            If .Found = False Then
                Exit Sub
            End If
        End With
        With rng
            If IsDate(.Text) Then
                .Text = Format$(.Text, "dddd, mmmm, dd yyyy")
            End If
          'change range to current position to the end of the document
        .Collapse wdCollapseEnd
        .End = ActiveDocument.Range.End
        End With
    Loop
End Sub

Q4
Access has a field or column type. A date is stored as a number. It can be displayed as the user requires. Changing the format does not change the underlying data. Excel is in a similar position.

In Word, everything is text, and it is not divided up into cells/fields, and while you can put a date in using some special fields, dates are mostly undistinguished.
0
 
Jeffrey CoachmanMIS LiasonAuthor Commented:
GrahamSkan,

I also noticed that the full day ("dddd") is off by one. For example 10/25/2004 is a Monday (Monday, October 25, 2004). The code shows it as a Sunday (Sunday, October 25, 2004). It's OK when it is formatted as "dd" (25), but when changed to "ddd" it displays "Sun". When changed to "dddd" it displays "Sunday". Is there any way to fix this? (add 1 to the first "dddd"?)

BTW, here is my code, I just changed your format form "dddd, mmmm dd, yyyy" to  "dddd, mmmm dd, yy" to get rid of the Century.

Sub FormatDates7()
Dim rng As Range

Set rng = ActiveDocument.Range
    Do While True
        With rng.Find
       'in the following find string:
        '[0-9] any character from 0 to 9
       '{1,2} one or two of those characters
        '/ the "/" character
        .Text = "[0-9]{1,2}/[0-9]{1,2}/[0-9]{1,2}"


            .Forward = True
            .Format = True
            .MatchWildcards = True 'the find string is not plain text, but uses wildcards
            .Execute
            If .Found = False Then
                Exit Sub
            End If
        End With
        With rng
            If IsDate(.Text) Then
                .Text = Format$(.Text, "dddd, mmmm, dd yy")
            End If
          'change range to current position to the end of the document
        .Collapse wdCollapseEnd
        .End = ActiveDocument.Range.End
        End With
    Loop
End Sub


P.S. Points bumped to 350
0
 
Jeffrey CoachmanMIS LiasonAuthor Commented:
GrahamSkan,

Thanks, works fine now.

500 points!
0
 
GrahamSkanRetiredCommented:
Thanks for the extra points, and the grade.

I wasn't explicit about it, but I'm still a bit bothered about the need to adjust the day name. Be aware that a system change could correct the problem and your program would then be wrong.
You might like to test the result for a known day before actually doing the DataAdd bit:

If Format$(#10/27/2004#, "dddd") = "Tuesday" Then
    .Text = Format$(DateAdd("d", 1, .Text), "dddd, ") & Format$(.Text, "mmmm, dd yy")
Else
    .Text = Format$(.Text, "dddd, mmmm, dd yy")
End If

Cheers, Graham
0
 
Jeffrey CoachmanMIS LiasonAuthor Commented:
GrahamSkan  ,

Funny thing though, when I used the modified code (add 1 day) it works fine for the current schedule. But when I entered my birthday (11/20/1964) it was 2 days off!

Instead of bugging you about it. I am running my own tests (Changing the first day of the week and year of the Format)

I also generated a file in Excel with sequential dates from 01/01/1960 to 12/31/2010, the first column is the date the second column is the date formatted for full date.

I'll copy this range and pasted it into a word doc and run the code.  and compare the Full dates. Perhaps I will see some sort of trend?

You have helped me out a lot here so I did not want to bother you.

Thanks agailn, I'll try to keep you posted
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.