Word Macro WANTED to Work, Then Stopped Working

Can't Get this Macro to work.  Worked just ONCE.  Then, stopped.  What do you think is happening?

From this question: https://www.experts-exchange.com/questions/29076881/Word-Macro-for-Shift-F3-Like-Auto-Capitalization-That-Skips-the-Words-And-But-Or-For-and-To.html

Option Explicit

Sub SetTitlecase()
    Dim strLowerWords() As String
    Dim strProperWords() As String
    Dim rng As Range
    Dim rngWord As Range
    Dim i As Integer
    
    'set up except words
    strLowerWords() = Split("and,for,to,a,of", ",")
    
    ReDim strProperWords(UBound(strLowerWords))
    For i = 0 To UBound(strLowerWords)
        strProperWords(i) = UCase(Left(strLowerWords(i), 1)) & LCase(Mid(strLowerWords(i), 2))
    Next i
    
    'set range to work on
    Set rng = Selection.Range
    
    With rng
        'capitalise first letter of every word
        .Case = wdTitleWord
        
        'set first letter of minor words to lower case
        For i = 0 To UBound(strLowerWords)
            With rng.Find
                .Text = strProperWords(i)
                .Replacement.Text = strLowerWords(i)
                .MatchWholeWord = True
                .MatchCase = True
                .Execute Replace:=wdReplaceAll
            End With
        Next i
    End With
    
    'recapitalise first letter of sentences
    rng.Case = wdTitleSentence
End Sub

Open in new window

oaktreesAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

KimputerIT ManagerCommented:
Tested, works. Probably nothing wrong with the code. Try reset all Word settings, use a new Word document and try the code again.
Martin LissOlder than dirtCommented:
You say it stopped working, what happens when you run it?
Neil FlemingConsultant and developerCommented:
My guess is that because find/replace settings are "sticky" you may inadvertently have searched for something else in between the first run of the code and the subsequent ones, using eg a wildcard, or a specific format, or a specific style, or a "stop on first occurrence" ... etc etc ... and that those settings were not cleared when you ran the code the second time.

You have:
With rng.Find
                .Text = strProperWords(i)
                .Replacement.Text = strLowerWords(i)
                .MatchWholeWord = True
                .MatchCase = True
                .Execute Replace:=wdReplaceAll
            End With

Open in new window


I would make sure nothing else can mess up the search by expanding the re-set code to:

With rng.Find
                .ClearFormatting
                .MatchWholeWord = True
                .MatchCase = True
                .Wrap = wdFindContinue
                .Format = False
                .MatchWildcards = False
                .MatchSoundsLike = False
                .MatchAllWordForms = False
                .Text = strProperWords(i)
                .Replacement.Text = strLowerWords(i)
                .Execute Replace:=wdReplaceAll
            End With

Open in new window


As I say, this is only a guess. But Word's find/replace functionality is notorious for this...
Exploring ASP.NET Core: Fundamentals

Learn to build web apps and services, IoT apps, and mobile backends by covering the fundamentals of ASP.NET Core and  exploring the core foundations for app libraries.

Martin LissOlder than dirtCommented:
The code assumes you have selected a range to be modified, and perhaps you didn't do that. If so then add lines 19 to 22 to alert you if that happens again. Even if that's not the problem, it's probably a good Idea to add them anyhow.
Sub SetTitlecase()
    Dim strLowerWords() As String
    Dim strProperWords() As String
    Dim rng As Range
    Dim rngWord As Range
    Dim i As Integer
    
    'set up except words
    strLowerWords() = Split("and,for,to,a,of", ",")
    
    ReDim strProperWords(UBound(strLowerWords))
    For i = 0 To UBound(strLowerWords)
        strProperWords(i) = UCase(Left(strLowerWords(i), 1)) & LCase(Mid(strLowerWords(i), 2))
    Next i
    
    'set range to work on
    Set rng = Selection.Range
    
    If rng = "" Then
        MsgBox "Nothing selected"
        Exit Sub
    End If
    
    With rng
        'capitalise first letter of every word
        .Case = wdTitleWord
        
        'set first letter of minor words to lower case
        For i = 0 To UBound(strLowerWords)
            With rng.Find
                .Text = strProperWords(i)
                .Replacement.Text = strLowerWords(i)
                .MatchWholeWord = True
                .MatchCase = True
                .Execute Replace:=wdReplaceAll
            End With
        Next i
    End With
    
    'recapitalise first letter of sentences
    rng.Case = wdTitleSentence
End Sub

Open in new window

oaktreesAuthor Commented:
Hi Martin & Neil,

Combined both your codes.  

It works, but only randomly.  And never on single words, or 4 or 5 words, but on 10 and 20s of words, selecting huge blocks of text.

Set it in the quick access toolbar.

What do you think is happening?

Sincerely,

Alex
Martin LissOlder than dirtCommented:
Please show the combined code and tell us in some detail what you want the macro to do.
oaktreesAuthor Commented:
Hi Martin,

Thanks for all your help! :)))

Sub SetTitlecase()
    Dim strLowerWords() As String
    Dim strProperWords() As String
    Dim rng As Range
    Dim rngWord As Range
    Dim i As Integer
    
    'set up except words
    strLowerWords() = Split("and,for,to,a,of", ",")
    
    ReDim strProperWords(UBound(strLowerWords))
    For i = 0 To UBound(strLowerWords)
        strProperWords(i) = UCase(Left(strLowerWords(i), 1)) & LCase(Mid(strLowerWords(i), 2))
    Next i
    
    'set range to work on
    Set rng = Selection.Range
    
    If rng = "" Then
        MsgBox "Nothing selected"
        Exit Sub
    End If
    
    With rng
        'capitalise first letter of every word
        .Case = wdTitleWord
        
        'set first letter of minor words to lower case
        For i = 0 To UBound(strLowerWords)
With rng.Find
                .ClearFormatting
                .MatchWholeWord = True
                .MatchCase = True
                .Wrap = wdFindContinue
                .Format = False
                .MatchWildcards = False
                .MatchSoundsLike = False
                .MatchAllWordForms = False
                .Text = strProperWords(i)
                .Replacement.Text = strLowerWords(i)
                .Execute Replace:=wdReplaceAll
            End With
        Next i
    End With
    
    'recapitalise first letter of sentences
    rng.Case = wdTitleSentence
End Sub

Open in new window

Martin LissOlder than dirtCommented:
You still haven't explained what exactly you want to do so if this was selected
this is a test
what should the result look like.

BTW you say that  
And never on single words,
but if I select
test
the result is
Test
oaktreesAuthor Commented:
Hi Martin,

this is a test and always for tweed jackets to flying fish

>

This Is a Test and Always for Tweed Jackets to Flying Fish

Automatically capitalizing ALL Words except designated ones [and,for,to,a,of]

For me, it works, but...inconsistently.  Click on the associated icon in the toolbar: works - on more than 5 words.  Or, won't work on single words.
 Or, stops completely after one use.

What do you think is happening?

Thanks!

OT
KimputerIT ManagerCommented:
Sadly, during these moment, it's best to debug the code yourself. Step through each line, watch the variables' contents during each step.
Does the code step to the parts you want it to go, or suddenly skipping code (why? because statement?). When it does go through the correct path, at the replace step are the contents correct, i.e. strProperWords/strLowerWords content are correct?
Martin LissOlder than dirtCommented:
Should the first word always be capitalized? In other words "for" is in your don't capitalize list, but if it's the first word as in this

for every action there is an equal and opposite reaction

should it be changed to

For Every Action There Is An Equal and Opposite Reaction
Martin LissOlder than dirtCommented:
And can you supply a document with the "icon in the toolbar"?

BTW, I've never seen it fail and so it may be that you have a problem with Word and I suggest that you quit (not merely close) the application and see if that corrects the problem.
oaktreesAuthor Commented:
Still not working for me.

Now, I get lots of Macro warning.

Seems like I should start over.

How can I:

delete all macros saved to normal template
add a Macro correctly

Word 2016

Alternatively, is there a unmodified, out of the box normal template for Word 2016 that I could download and overwrite on my computer, so that I's start out with no Macros at al.

Thanks!

OT
Martin LissOlder than dirtCommented:
Now, I get lots of Macro warning.
In the code below please tell me what error you get and on what line of code.

Alternatively, is there a unmodified, out of the box normal template for Word 2016 that I could download and overwrite on my computer, so that I's start out with no Macros at al.
  1. File->New
  2. Select 'Blank Document'
  3. Click 'Create'
  4. Go to Visual Basic
  5. From the menu line Insert->Module
  6. Copy this code into that module

Sub SetTitlecase()
    Dim varLowerCaseWords As Variant
    Dim varUpperCaseWords As Variant
    
    Dim rng As Range
    Dim rngWord As Range
    Dim i As Integer
    Dim strWas As String
    
    varLowerCaseWords = Array("and", "for", "to", "a", "of")
    varUpperCaseWords = Array("And", "For", "To", "A", "Of")
    
    'set range to work on
    Set rng = Selection.Range
    
    If rng = "" Then
        MsgBox "Nothing selected"
        Exit Sub
    End If
    
    strWas = Selection
    
    With rng
        'capitalise first letter of every word
        .Case = wdTitleWord
        
        'set first letter of minor words to lower case
        For i = 0 To UBound(varLowerCaseWords)
            With rng.Find
                .ClearFormatting
                .MatchWholeWord = True
                .MatchCase = True
                .Wrap = wdFindContinue
                .Format = False
                .MatchWildcards = False
                .MatchSoundsLike = False
                .MatchAllWordForms = False
                .Text = varUpperCaseWords(i)
                .Replacement.Text = varLowerCaseWords(i)
                .Execute Replace:=wdReplaceAll
            End With
        Next i
    End With
    
    'recapitalise first letter of sentences
    rng.Case = wdTitleSentence
   
    If strWas = Selection Then
        MsgBox "No changes made", vbInformation
    End If
End Sub

Open in new window

oaktreesAuthor Commented:
Hi,

First, I did this: https://answers.microsoft.com/en-us/msoffice/forum/all/where-can-i-download-a-fresh-normaldotm/a033f7fd-91a3-45b7-87b5-3341b6c37506

Testing your module now.  Seems to be working!  :)))  Will update soon.

Thanks for all your help! :DDDD

Sincerely,

OT
oaktreesAuthor Commented:
Hi Martin,

I created a shortcut to the Macro in Word's Quick Access toolbar: https://wordribbon.tips.net/T006011_Adding_a_Macro_to_the_Quick_Access_Toolbar.html

Now, whenever I click the shortcut to run the Macro I get this message:

The macro cannot be found or has been disabled because of your Macro security settings

What do you think is happening?

Thanks!

OT
quick-access-shortcut.png
2019-04-12_21-00-34-601.png
Martin LissOlder than dirtCommented:
If the code works then I believe that you should accept my solution as the answer to your original question and then create a new question concerning the quick access toolbar.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
oaktreesAuthor Commented:
Thanks to all! :DDDDDDDDDDDDDDDDDD
Martin LissOlder than dirtCommented:
You’re welcome and I’m glad I was able to help.

If you expand the “Full Biography” section of my profile you’ll find links to some articles I’ve written that may interest you.

Marty - Microsoft MVP 2009 to 2017
              Experts Exchange Most Valuable Expert (MVE) 2015, 2017
              Experts Exchange Top Expert Visual Basic Classic 2012 to 2018
              Experts Exchange Top Expert VBA 2018
              Experts Exchange Distinguished Expert in Excel 2018
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
VB Script

From novice to tech pro — start learning today.