none
Change font style and size and reverse the changes RRS feed

  • Question

  • Hello Support,

    I want to use one macro to change the font style to Times New Roman and the font size to 25 for the active document (the entire document).  Then I want to utilize a different macro to reverse the changes.  I used the code in "Sub SetFontStyleAndSize" to change/set the font style Times New Roman 25, which seems to work fine.  I used the code in "Sub RemoveFontStyleAndSize"  to reverse what I did with "Sub SetFontStyleAndSize".  However, the problem we have encountered is that the code in Sub "RemoveFontStyleAndSize" removes all direct formatting including direct formatting applied before the macro was run. We only want the code to reverse the changes that I applied.  Now I am trying to figure out what's the best way to accomplish this. The following are the subs I am using.

    ****Thank you and I appreciate the help.

    Sub SetFontStyleAndSize()

    'Change font style and increase font size in entire document

    ' http://word.mvps.org/faqs/customization/ReplaceAnywhere.htm

    Dim rngStory  As Word.Range

    Dim lngJunk   As Long

        'Fix the skipped blank Header/Footer problem as provided by Peter Hewett

        lngJunk = ActiveDocument.Sections(1).Headers(1).Range.StoryType

        'Iterate through all story types in the current document

        For Each rngStory In ActiveDocument.StoryRanges

          'Iterate through all linked stories

          Do

          With rngStory.Font

            .Name = "Times New Roman"

            .Size = 25

            End With

            'Get next linked story (if any)

            Set rngStory = rngStory.NextStoryRange

          Loop Until rngStory Is Nothing

      Next

    End Sub

     

     

     

    Sub RemoveFontStyleAndSize

    'Change font style and increase font size in entire document

    ' http://word.mvps.org/faqs/customization/ReplaceAnywhere.htm

    Dim rngStory  As Word.Range

    Dim lngJunk   As Long

        'Fix the skipped blank Header/Footer problem as provided by Peter Hewett

        lngJunk = ActiveDocument.Sections(1).Headers(1).Range.StoryType

        'Iterate through all story types in the current document

        For Each rngStory In ActiveDocument.StoryRanges

          'Iterate through all linked stories

          Do

          With rngStory.Font

    .Rest

            End With

            'Get next linked story (if any)

            Set rngStory = rngStory.NextStoryRange

          Loop Until rngStory Is Nothing

      Next

    End Sub



    • Edited by Fox245 Wednesday, July 1, 2015 4:35 AM
    Wednesday, July 1, 2015 4:34 AM

All replies

  • The only reliable ways of doing this would be to:
    1. Turn on 'Track Changes' before making the font change, then reject that change later on, so all the fonts are returned to their original state; or
    2. Make the changes, then use Undo to undo them later on; or
    3. Make the changes, then close the document without saving later on.

    Only the first option provides a means of retaining edits made after the font change.

    Of course, if the creator of your document applied all formatting via Styles, you wouldn't have problems of the 'removes all direct formatting' kind.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Wednesday, July 1, 2015 7:27 AM
  • Multiple people work on the documents, and they use styles in majority of the documents, and sometimes they also use direct formatting such as underline, bold, and italic.  I am willing to try the first proposed option (To Turn on 'Track Changes' before making the font change), but since they collaborate and will some times use track changes in the doc; is it best to check to see if track changes is already turned on and have the user accept or reject changes before running my macro?  The other thing, the users will make changes in the document after the macro make the font changes.


    • Edited by Fox245 Wednesday, July 1, 2015 8:04 PM
    Wednesday, July 1, 2015 8:04 PM
  • Formatting such as underline, bold, and italic can all be applied via Styles - there is no need to use direct formatting for that.

    Your code doesn't need to test whether 'Track Changes' is on beforehand - it can simply turn it on explicitly, via code like:
    With ActiveDocument
      .TrackRevisions = True
      .TrackFormatting = True
    End With

    The real issue you're going to have, though, is whether your colleagues are going to do anything in their subsequent editing that compromises what you're trying to achieve. For example, if they accept your changes, the record you've so carefully created will be wiped out. If you or they turn off Track Changes and anyone:
    • changes font sizes to something else, your font change might be recorded, but the edits won't;
    • pastes content into the document and set its font size to 25pt, that pasting and resizing won't be tracked,
    and so on.

    Another approach that might be taken is to use a macro that goes through all the paragraph Styles in use in the document and changes their point sizes. If you store the Style names and original point sizes in the document's metadata as Custom Document Properties or as Document Variables, you could run another macro later on to retrieve those data and restore the fonts. Of course, if direct formatting is being used to override a paragraph Style's font size, this approach too will have its problems.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Wednesday, July 1, 2015 10:30 PM
  • Ok. I see. I could emphasize to the user to use style instead of direct formatting, but that will not hold up due to the collaborative situation. Also, the users confirmed they will be doing edits after I change the font size. With that said, is there is away to find or determine the direct formatted text and convert them to styles? If yes, then I am thinking, on the first macro we could first convert the direct formatted text to styles, then allow the macro to change the font and increase the font size. Then on the second macro that suppose to reverse the font changes, only rest formatting that is Times New Roman and size 25. Do you see a flaw with this thinking?
    Thursday, July 2, 2015 4:20 PM
  • is there is away to find or determine the direct formatted text and convert them to styles? If yes, then I am thinking, on the first macro we could first convert the direct formatted text to styles, then allow the macro to change the font and increase the font size.

    Yes, that's possible, but beyond checking for simple applications of direct formatting like bold, underline & italics, converting to Styles is problematic. What happens, for instance, if the user has completely overridden a paragraph's Style to make it look the same as a paragraph that actually uses a different Style? Checking all the possibilities to apply the correct Style could take a huge amount of processing. Also, what happens if the user made some other change that doesn't conform to any existing Style?

    Furthermore, if your users lack the discipline to use Styles consistently, your second macro that undoes the font changes could have unintended effects. There are other issues to consider too. For example, suppose the editor inserts their own edit in 25pt text, is that supposed to be reverted, even though it hasn't been tracked? What about if it's 18pt? Finally, if the editor deletes something you've tracked, and they haven't used Track Changes while doing so, there'll be no way to recover that content.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Friday, July 3, 2015 12:04 AM
  • Hi Fox

    I'd like to throw in a thought...

    Word does provide the capability to limit the formatting options available to users. It's not 100% secure, but would prevent users from "casually" clicking the "Bold" button (for example). That combined with an interface that provides the styles the users are allowed to use, could help - especially if the users are aware of the requirement and the reason.

    For this to work, however, you (or someone working with you on this project) would need to set up the documents/templates associated with the project.


    Cindy Meister, VSTO/Word MVP, my blog

    Friday, July 3, 2015 4:00 PM
    Moderator
  • Paul,

    Yes, from my first solution some users already experienced the unintended effects where the second macro removed/reset all their direct formatting.  I understand your explanation, but conform the existing documents direct formatting to styles, I still would like to know how to find the direct formatted text and convert them to styles.  Since using styles is the best option, then what I would to do then with macro 1 is find and converts the direct formatted text to styles, make the font changes, then at the end display a msgbox telling user any formatting changes from this point needs to done using style.

    Friday, July 3, 2015 8:50 PM
  • Cindy,

    Thanks for jumping in. Three brains are better than one.  Unfortunately, I would be the one working on this macro solution.  It would be good to know how to implement the Word option that limits the formatting options available to users. The concern I have is that this solution would need to work with all
    documents (created from Normal template and custom templates),  and at the same time
    I would NOT want to do this for their whole Word environment. Because I think people will get upset if they simple starts a new document and can't use the direct format functionality such as bold, underline, and italic. 

    Friday, July 3, 2015 9:00 PM
  •  I still would like to know how to find the direct formatted text and convert them to styles.  Since using styles is the best option, then what I would to do then with macro 1 is find and converts the direct formatted text to styles, make the font changes.

    The following macro looks for text with italic, bold and/or underline formatting and, if it doesn't match the underlying paragraph's format, applies a Character Style from the ArrStyl array to the text. You would need to have all the Styles concerned in the document before running the macro. As it stands, only the Emphasis, Strong and Intense Emphasis Styles would ordinarily be found; the others are just names I made up to fill the array. Of course, it would also be possible to programmatically add/redefine character Styles, but it would be better to add them to the document's template instead.

    A couple of caveats:
    • No attempt is made to manage hard formatting that's been applied to a whole paragraph to make it look like a paragraph for which a different Paragraph Style exists.
    • No attempt is made to manage hard formatting within a paragraph that changes font sizes, colours, etc. with or without italics, etc.
    In such cases, you may end up with the font size, colour, etc. changing as a result of the application of the Character Styles. There's only so much undisciplined formatting one can reasonably manage programmatically; wrist-slapping is in order for anything else...

    Sub ApplyCharacterStyles()
    Application.ScreenUpdating = False
    Dim Para As Paragraph, i As Long, ArrItal, ArrBold, ArrUlin, ArrStyl
    Dim bItal As Boolean, bBold As Boolean, bUlin As Boolean
    ArrItal = Array(True, False, False, True, False, True, True)
    ArrBold = Array(False, True, False, True, True, False, True)
    ArrUlin = Array(False, False, True, False, True, True, True)
    ArrStyl = Array("Emphasis", "Strong", "Stress", "Intense Emphasis", "Strong Stress", "Intense Stress", "Over The Top")
    'Look for text with italic, bold and/or underline formatting, as specified in the attribute arrays
    For i = 0 To UBound(ArrStyl)
      With ActiveDocument.Range
        With .Find
          .ClearFormatting
          With .Replacement
            .ClearFormatting
            .Text = ""
          End With
          .Text = ""
          .Forward = True
          .Format = True
          .MatchWildcards = True
          With .Font
            .Italic = ArrItal(i)
            .Bold = ArrBold(i)
            .Underline = ArrUlin(i)
          End With
          .Execute
        End With
        Do While .Find.Found
          'Check whether the found text is formatted in our style
          If .Style <> ArrStyl(i) Then
            'If the found text spans less than a full paragraph, apply our Style
            If .Start <> .Paragraphs.First.Range.Start Or .End <> .Paragraphs.First.Range.End Then
              .Style = ArrStyl(i)
            Else
            'If the found text spans a full paragraph, check the paragraph Style
              With ActiveDocument.Styles(.Paragraphs.First.Style).Font
                bItal = .Italic
                bBold = .Bold
                bUlin = .Underline
              End With
              'If the found text doesn't match the paragraph Style, apply our Style
              If bItal <> ArrItal(i) Or bBold <> ArrBold(i) Or bUlin <> ArrUlin(i) Then
                .Style = ArrStyl(i)
              End If
            End If
          End If
          .Collapse wdCollapseEnd
          .Find.Execute
        Loop
      End With
    Next
    Application.ScreenUpdating = True
    MsgBox "Finished applying Character Styles"
    End Sub


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Saturday, July 4, 2015 3:27 AM
  • Hi Fox

    Can you predict/know under what circumstances the control is necessary? And in such circumstances, which styles are allowed?


    Cindy Meister, VSTO/Word MVP, my blog

    Saturday, July 4, 2015 3:55 PM
    Moderator
  • Hi Fox

    Can you predict/know under what circumstances the control is necessary? And in such circumstances, which styles are allowed?


    Cindy Meister, VSTO/Word MVP, my blog

    Cindy,

    I defined the default font and default paragraph style in the template, but I can't really predict what other style or formatting they might do.  If were going to restrict the direct formatting options, we would have to do it in the template that we are working on.

    Tuesday, July 7, 2015 3:55 PM
  • Paul,

    Thank you for doing the ApplyCharacterStyles macro. Very nice of you, especially for doing it so quickly.  My wrist might hurt from all the wrist-slapping required.

    When I create the styles that will be added to the array, should the Styles be created based on the "default paragraph font" or "(underlying properties)" style?

    Style type: Characters
    Style based on:  Default paragraph font

    Thanks

    Tuesday, July 7, 2015 9:21 PM
  • When you create a Character Style, you'd ordinarily base it on the default paragraph font.

    Cheers
    Paul Edstein
    [MS MVP - Word]

    Tuesday, July 7, 2015 9:49 PM
  • Paul,

    I added my styles in the template as follows:
    MyDefaultParagraphStyle, MyBoldStyle, MyItalicStyle, MyUnderlineStyle, MyBIStyle,, MyBIUStyle, MyBUStyle, MyIUStyle

    I also added the exact name of the styles in to the following line of the macro code
    ArrStyl = Array("MyBoldStyle", "MyItalicStyle", "MyUnderlineStyle", "MyDefaultParagraphStyle", "MyBIStyle", "MyBIUStyle", "MyBUStyle", "MyIUStyle")

    I created a test paragraph in the new document (based on the template file with the styles) and applied direct format as follows:

    Sentence1 as is bold.
    Sentence2 as in italic
    Sentence3 underlined.
    Sentence4 as bold and italic
    Sentence5 as bold, italic, and underlined.
    Sentence6 bold and underline
    Sentence7 as italic and underline

    When I ran the ApplyCharacterStyles macro, I got the following error: Run-time error '9': Subscript out of range.
    What I am I doing wrong? Do I need to put them in a certain order? Thanks for your continued help with this.

    Thursday, July 9, 2015 3:52 PM
  • The problem is that you've inserted an element named "MyDefaultParagraphStyle" into the ArrStyl array, for which there is no provision in the ArrItal, ArrBold & ArrUlin arrays. Those arrays only hold 7 elements, but you now have ArrStyl array with 8 elements. As for the ArrStyl array order, yes, that's important - the order needs to conform to that of the code I posted:
    italics, bold, underline, bold italics, bold underline, italics underline, bold italics underline.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Thursday, July 9, 2015 11:38 PM
  • Thanks again. I removed the extra element and put the other elements in the order you specified and that works as expected, converting the direct formatting to styles. However, after running my macro to rest the font size and type, it still removed/reset the formatting applied to the text (the direct format converted to styles).
    Saturday, July 11, 2015 9:16 PM
  • Nothing my macro does can prevent anything you do later from undoing what it's done. Evidently your macro is doing more than just changing the font name & size. Furthermore, if your macro were to apply the font changes at the paragraph Style level, you'd probably get more consistent results.

    Cheers
    Paul Edstein
    [MS MVP - Word]

    Saturday, July 11, 2015 9:52 PM