Results 1 to 10 of 10
  1. #1
    New Lounger
    Join Date
    Jun 2015
    Posts
    5
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Question How to remove character styles from a series of paragraphs?

    Hello all,

    This is my first post after a couple weeks lurking the forums and trying to absorb the massive amounts of expertise on display here. I have been trying to create a basic Word macro with no prior VBA experience and with just a wee smidgen of Python knowledge to build upon, and I am hoping that you can help me overcome a few nagging issues.

    Here is what I am trying to achieve: I want Word to search the active document for text formatted with one of a given list of paragraph styles and remove any character styles applied to text in that paragraph. The goal is to be able to later import the document into a third-party tool that really does not like character styles for some reason.

    Here is my best shot at translating that into VBA so far. I apologise in advance for any horrible, overcomplicated and generally incompetent coding I only have a rough idea of how basic stuff like loops, etc. works in VBA. I mean to get myself a book and learn the basics properly, but for now I have mostly been hacking things together from bits of code found in this forum and MSDN. ^_^,

    Code:
    Sub MultiStyleCleanup()
    'Contains the list of paragraph styles where the text needs to be stripped of character styles, and starts a loop that iterates through that list.
        Dim StylesToClean() As Variant
        StylesToClean = Array("Style1", "Style2", "Style3")
        For i = 0 To UBound(StylesToClean)
            StyleCleanup(StylesToClean(i))
            Next i
                   
    End Sub
    Code:
    Sub StyleCleanup(strStyle As String)
    'Selects text formatted with each paragraph style and clears character styles.
        Selection.HomeKey Unit:=wdStory
        'MsgBox strStyle
            With Selection.Find
                .Text = ""
                .ClearFormatting
                .Style = strStyle
                .Replacement.Text = ""
                .Replacement.ClearFormatting
            Do While .Execute
            Selection.ClearCharacterStyle
        
            Loop
            End With
    End Sub
    As it is, these two macros seem to be close to achieving what I want: they restrict the search to the relevant paragraph styles only, and remove character styles successfully when they are present. The main issue at the moment is that the macro crashes with a 4605 error whenever it reaches a paragraph where *no character styles* have been used.

    Since the character styles I am attempting to remove are not always present (just some documents have them, and not necessarily in all paragraphs), this is a showstopper. Unfortunately, I cannot figure out how to tell Word to handle disappointment gracefully and just move on if it does not detect any character styles it can remove.

    Could the hive mind give me a hand here and point me in the right direction? It goes without saying that any comments or improvements on my terrible coding are more than welcome.

    Thanks in advance!

    Fran

  2. #2
    Super Moderator
    Join Date
    May 2002
    Location
    Canberra, Australian Capital Territory, Australia
    Posts
    5,055
    Thanks
    2
    Thanked 417 Times in 346 Posts
    Try:
    Code:
    Sub Demo()
    Dim Para As Paragraph
    For Each Para In ActiveDocument.Paragraphs
      Para.Range.Font.Reset
    Next
    End Sub
    Cheers,

    Paul Edstein
    [MS MVP - Word]

  3. #3
    New Lounger
    Join Date
    Jun 2015
    Posts
    5
    Thanks
    1
    Thanked 0 Times in 0 Posts
    Hello Paul,

    Unfortunately, Font.Reset removes all manual character formatting (i.e. formatting not applied using a style), and I need to remove all character styles while preserving manual character formatting. It's an oddly precise requirement, I guess, but the ClearCharacterStyle method appears to do exactly what our users need... if only I could get it to work reliably. :/

    Is there any way I could write an IF clause to only try to use ClearCharacterStyle on the current selection if the selection includes any character styles?

    Cheers,

    Fran

  4. #4
    Super Moderator
    Join Date
    May 2002
    Location
    Canberra, Australian Capital Territory, Australia
    Posts
    5,055
    Thanks
    2
    Thanked 417 Times in 346 Posts
    Do you want to remove the character Style's formatting, or just the Style? Assuming the latter, try:
    Code:
    Sub Demo()
    Application.ScreenUpdating = False
    Dim wdDoc As Document, oSty As Style
    Set wdDoc = ActiveDocument
    For Each oSty In wdDoc.Styles
      With oSty
        If .Type = wdStyleTypeCharacter Then
          If .NameLocal <> "Default Paragraph Font" Then
            If .InUse = True Then
              With wdDoc.Content
                With .Find
                  .ClearFormatting
                  .Replacement.ClearFormatting
                  .Forward = True
                  .Wrap = wdFindStop
                  .Format = True
                  .Style = oSty.NameLocal
                  .Execute
                End With
                Do While .Find.Found = True
                  .Font.Reset
                  .Font = oSty.Font
                  .Find.Execute
                Loop
              End With
            End If
          End If
        End If
      End With
    Next
    Set wdDoc = Nothing
    Application.ScreenUpdating = True
    End Sub
    If the former, comment-out or delete '.Font = oSty.Font'.
    Last edited by macropod; 2015-06-11 at 09:03.
    Cheers,

    Paul Edstein
    [MS MVP - Word]

  5. #5
    Super Moderator
    Join Date
    Jan 2001
    Location
    Melbourne, Victoria, Australia
    Posts
    3,853
    Thanks
    4
    Thanked 259 Times in 239 Posts
    It would be simpler to do a search and replace for each of the (other) character styles and replace it with the 'Default Paragraph Font'.
    Andrew Lockton, Chrysalis Design, Melbourne Australia

  6. #6
    Super Moderator
    Join Date
    Jan 2001
    Location
    Melbourne, Victoria, Australia
    Posts
    3,853
    Thanks
    4
    Thanked 259 Times in 239 Posts
    Just replacing instances of char styles other than default paragraph font, the macro would look like this
    Code:
    Sub ClearCharStylesOnly()
      Application.ScreenUpdating = False
      Dim wdDoc As Document, oSty As Style
      Set wdDoc = ActiveDocument
      With wdDoc.Content.Find
        .ClearFormatting
        .Replacement.ClearFormatting
        .Forward = True
        .Wrap = wdFindStop
        .Format = True
        .Replacement.Style = "Default Paragraph Font"
        For Each oSty In wdDoc.Styles
          If oSty.Type = wdStyleTypeCharacter And oSty.NameLocal <> "Default Paragraph Font" Then
            .Style = oSty.NameLocal
            Debug.Print oSty.NameLocal
            .Execute Replace:=wdReplaceAll
          End If
        Next oSty
      End With
    Set wdDoc = Nothing
    Application.ScreenUpdating = True
    End Sub
    Andrew Lockton, Chrysalis Design, Melbourne Australia

  7. #7
    Super Moderator
    Join Date
    May 2002
    Location
    Canberra, Australian Capital Territory, Australia
    Posts
    5,055
    Thanks
    2
    Thanked 417 Times in 346 Posts
    Hi Andrew,

    My reply in post #4 already showed how to do that - or replace the Style while keeping its attributes.
    Cheers,

    Paul Edstein
    [MS MVP - Word]

  8. #8
    New Lounger
    Join Date
    Jun 2015
    Posts
    5
    Thanks
    1
    Thanked 0 Times in 0 Posts
    Hi Andrew, hi Paul,

    Thanks a million for your ideas and apologies for the radio silence — I meant to do some tinkering on this over the weekend, but forgot to take the files home with me so I could test your suggestions there. Sorry!

    In any event, I have now had the chance to try both your macros and... I can definitely see that they are doing their thing, but they do not seem to affect the specific formatting properties that I am trying to get rid of, probably due to me lacking the vocabulary needed to explain what I am trying to achieve with the required degree of precision.

    To try and give you a better idea of what exactly I am trying to achieve: the document I am trying to clean up is based on a template that includes a number of linked styles. The problem comes when users of this template copy and paste formatted text from online sources or other documents, which results in parts of some paragraphs being formatted with character styles that deviate from the template styles in some way.

    For example, a paragraph formatted with the paragraph style "Body Text" may have a bunch of words formatted as "Body Text + (Asian) SimSun", while another might have some spaces formatted with the "apple-converted-space" character style. It is not always predictable what these styles will be —or whether they will appear at all— on any given document, as it depends on the regional settings of the user's computer and the sources they paste text from.

    These minor style changes then cause issues when we import the document into a third party tool; essentially, this tool represents each style change as an HTML-style tag, and documents where character styles have been misapplied tend to degenerate into an unreadable "tag soup". Unfortunately, the code you two have so kindly provided does not seem to get rid of these "SimSun" and "apple-converted-space" tags.

    As I mentioned earlier, the Selection.ClearCharacterStyle method (which, as far as I can tell, reproduces the functionality of the "Clear character style" button in the Style Inspector) seems to do the trick, i.e. reverting any character styles to the underlying paragraph style without affecting manual formatting. This would be the ideal solution if it did not fail when used on a paragraph without any character styles. I feel like I have already taken up a massive amount of your time, but... would you, by any chance, know of a way to address that specific shortcoming?

    Once again, thanks for all your ideas so far — although I have not yet achieved my end goal, I am learning a ton from your code and I am confident I will reach a solution eventually!

    Ever grateful for your help,

    Fran

  9. #9
    Super Moderator
    Join Date
    May 2002
    Location
    Canberra, Australian Capital Territory, Australia
    Posts
    5,055
    Thanks
    2
    Thanked 417 Times in 346 Posts
    Hi Fran,

    The code I posted is designed to work without needing to know beforehand what the character Styles are. Regardless of whether they're linked, they should be replaced with either the paragraph's underlying font or with the character formatting but not the Style definition - depending on whether you retained the '' line. Is that not happening with linked Styles? Having to update an array of Styles to process would seem to create some unnecessary maintenance overheads. That said, you could probably work around your current problem by inserting:
    On Error Resume Next
    after:
    Sub StyleCleanup(strStyle As String)

    Alternatively, you could re-code the 'MultiStyleCleanup' macro as:
    Code:
    Sub MultiStyleCleanup()
    Dim i As Long
    'Contains the list of paragraph styles where the text needs to be stripped of character styles, and starts a loop that iterates through that list.
        Dim StylesToClean() As Variant
        StylesToClean = Array("Style1", "Style2", "Style3")
        On Error Resume Next
        For i = 0 To UBound(StylesToClean)
            StyleCleanup (ActiveDocument.Styles(StylesToClean(i)).NameLocal)
        Next i
    End Sub
    FWIW, the following macro deletes all user-defined Linked Styles in a document.
    Code:
    Sub CleanStyles()
    Dim oSty As Style
    With ActiveDocument
      On Error Resume Next
      For Each oSty In .Styles
        If oSty.Linked = True Then
          .Styles.Add Name:="TmpSty"
          oSty.LinkStyle = "TmpSty"
          .Styles("TmpSty").Delete
        End If
        If oSty.BuiltIn = False Then oSty.Delete
      Next
    End With
    End Sub
    Cheers,

    Paul Edstein
    [MS MVP - Word]

  10. #10
    New Lounger
    Join Date
    Jun 2015
    Posts
    5
    Thanks
    1
    Thanked 0 Times in 0 Posts
    Hi Paul,

    Again, sorry for the late response — things have been so busy at work lately that my beloved macro pet project had to be put on the back burner for a couple weeks.

    I am very happy to report that adding "On Error Resume Next" does indeed fix the problem. The macro now goes through the paragraphs as instructed and does exactly what it says on the tin, without crashing in frustration if it can't find anything to do. Thanks a million for pointing me to the magical piece of code that made it work!

    The code you posted in #4 certainly looks like it should have the intended effect, and I honestly am not sure why it doesn't. I need to dig a fair bit deeper into the subtleties of character VS paragraph VS linked styles if I am to understand why Selection.ClearCharacterStyle works where alternative approaches don't, but for the time being the macro does exactly what I need.

    Mind you, my loop is probably a bit wonky, as it seems to run endlessly when I play the macro step-by-step, but it works fine when run normally. I guess I'll need to approach VBA more systematically and learn the basics properly; I already have a reference book on the way, so hopefully I'll be able to get to work on that soon.

    In any event, thanks so much for getting me out of this pickle and for spending your valuable time helping me out with this. If you ever drop by Madrid, I owe you a beer.

    (Oh, about maintaining an array of styles to process is concerned: that is intentional, as I wanted the processing to apply only to specific sections of the document, and the easiest way to do so seemed to be restricting processing to paragraphs formatted with the paragraph styles used in those sections.)

    Once again, thanks so much. You have been a massive help!

    Cheers,

    Fran

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •