none
Batch removing of rich text content controls and it's content RRS feed

  • Question

  • Is there a way to delete a list of tagged rich text content controls from a Word file? Can I do it in MS Word?

    I have a large Word-file with:

    -  some text/pictures without any rich text content control

    - a lot of text in a lot of different tagged rich text content controls.

    What I want to do is:

    1. Keep all the text/pictures wich is not inside any rich text content control

    2. Remove a set of tagged rich text content controls and it's content. (For example remove tag:1,3,5,10,11,12,50,57,100,102,103 and all the content inside those RTCC)

    3. Save to a new word file.

    It takes hours to remove all the RTCC and it's content manually each time, so I would like to find an easy way of doing it.

    Thursday, November 14, 2013 9:59 AM

Answers

  • Hi Tri-X

    As close as I can follow, if the table (when present) is selected at the end of a loop, you should be able to detect it:

    If Selection.Information(wdWithinTable) Then

    And delete it:

    Selection.Tables(1).Delete


    Cindy Meister, VSTO/Word MVP, my blog

    Tuesday, November 19, 2013 3:46 PM
    Moderator
  • Hi Tri-X

    I was answering this:

    <<If I run this code, without any deletion, the table is selected when the macro is finished. To delete the selected table and content I have to right click on the selection and click "Delete Table". What is the Visual basic code for that command>>

    If I follow that correctly, then you should have the code that checks whether there's a table and deletes it after deleting the content control.


    Cindy Meister, VSTO/Word MVP, my blog

    Wednesday, November 20, 2013 3:43 PM
    Moderator

All replies

  • You could use a macro like the following to delete those content controls:

    Sub Demo()
    Dim i As Long
    With ActiveDocument
      For i = .ContentControls.Count To 1 Step -1
        With .ContentControls(i)
          If .Type = wdContentControlRichText Then
            .LockContentControl = False
            .Range.Delete
            .Delete
          End If
        End With
      Next
    End With
    End Sub


    Cheers
    Paul Edstein
    [MS MVP - Word]


    • Edited by macropodMVP Thursday, November 14, 2013 10:33 AM
    Thursday, November 14, 2013 10:33 AM
  • Thanks. But where do I define wich tags to delete?
    Thursday, November 14, 2013 10:44 AM
  • The code as posted doesn't check tags. To add that, you could use something like:

    Sub Demo()
    Dim i As Long, StrTags As String
    StrTags = ",1,3,5,10,11,12,50,57,100,102,103,"
    With ActiveDocument
      For i = .ContentControls.Count To 1 Step -1
        With .ContentControls(i)
          If .Type = wdContentControlRichText Then
            If InStr(StrTags, "," & .Tag & ",") > 0 Then
              .LockContentControl = False
              .Range.Delete
              .Delete
            End If
          End If
        End With
      Next
    End With
    End Sub


    Cheers
    Paul Edstein
    [MS MVP - Word]


    • Edited by macropodMVP Thursday, November 14, 2013 10:55 AM
    Thursday, November 14, 2013 10:55 AM
  • I get this error:

    Run-time error`5904.

    Cannon edit Range.

    Thursday, November 14, 2013 11:03 AM
  • I'm unable to reproduce that error. You might try inserting:
    .LockContents = False
    after:
    .LockContentControl = False

    if that doesn't work, insert:
    .Select
    before:
    .LockContentControl = False
    and post back with details about where in the document the content control is located (e.g. inside a table, textbox, etc) and what it contains.         


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Thursday, November 14, 2013 11:13 AM
  • It's my tag names which causes the problem. I made a small test document with tag names like 1,2,3 and then it works.

    How can I make the code to work with different type of tag names?

    My tag names is built up like this:

    LettersDigits-LettersDigits

    Example names: PB-A1, TB-A22

    Thursday, November 14, 2013 11:47 AM
  • For that you can use:

    StrTags = ",PB-A1,TB-A22,"

    Note that there should be no spaces between the commas and the tag names.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Thursday, November 14, 2013 11:54 AM
  • In my testdocument it works great, but not in the big document.

    In the big document there are several tags with the same name, could that cause any problem?

    - If I make new RTCCs in the big document and give them tag names which not has been used anywere else in the document the macro works and removes those RTCCs.

    - If I change the tag names on the new RTCCs to a tag name already used in the document, then run the macro again, I get the error message I posted above.

    - If I rename an old tag in the big document to a tag name which has never been used before the macro works and remove that RTCC.

    In my test document it was no problem with several RTCC's with the same tag name.

    Any suggestions?

    Thursday, November 14, 2013 12:35 PM
  • In my testing, having more than one content control with the same tag doesn't cause an error - all with the same tag are deleted.

    Since changing the tag seems to work for you, try inserting:
    .Tag = "No Tag"
    before:
    .Range.Delete


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Thursday, November 14, 2013 12:43 PM
  • That didn't work either. Does the .Range.Delete have any limitations? When I go to the debugger "i" has a value of nearly 600.

    I didn't try the .Select option as you suggested, it's not possible to insert it here

    If InStr(StrTags, "," & .Tag & ",") > 0 Then
                .Select
               .LockContentControl = False
               .LockContents = False
               .Tag = "No Tag"
               .Range.Delete
               .Delete

    Thursday, November 14, 2013 12:59 PM
  • Sorry, try .Range.Select.

    The 'i' is simply a counter - at that point there were 'nearly 600' content controls in the document. I'm wondering why so many - and whether the error might be because the controls are nested or something such.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Thursday, November 14, 2013 1:29 PM
  • I do not understand why the macro works fine if I change the tag names to something not used in the document. The content inside the RTCC is the same either way.

    Could it be possible to do it the other way around? "Delete all RTCC's except tag 1,2,5,8,9" ?

    Thursday, November 14, 2013 1:54 PM
  • Hi Tri-x

    I suggest you use the Document.SelectContentControlByTag method to pick up all the tags with the same name. This returns acollection of tags. Loop the collection, deleting each tag.

    Sub DeleteByTag()
        Dim ccs As word.Contentcontrols
        Dim cc As word.ContentControl
        Dim i As Long
        
        Set ccs = ActiveDocument.SelectContentControlsByTag("1")
        For i = ccs.Count To 1 Step -1
            ccs(i).Delete
        Next
    End Sub
    


    Cindy Meister, VSTO/Word MVP, my blog

    Thursday, November 14, 2013 5:13 PM
    Moderator
  • That would probably be quicker than looping through all the content controls. Given that the OP has a series of tags, wants to delete only those that a Rich Text controls and wants to delete their content as well, you'd need something like:

    Sub DeleteByTag()
    Dim ccs As Word.ContentControls, cc As Word.ContentControl
    Dim i As Long, j As Long, StrTags As String
    StrTags = "1,3,5,10,11,12,50,57,100,102,103"
    For i = 0 To UBound(Split(StrTags, ","))
      Set ccs = ActiveDocument.SelectContentControlsByTag(Split(StrTags, ",")(i))
      For j = ccs.Count To 1 Step -1
        With ccs(j)
          If .Type = wdContentControlRichText Then
            .LockContentControl = False
            .LockContents = False
            .Range.Delete
            .Delete
          End If
        End With
      Next
    Next
    End Sub

    Even then, I suspect we'll run into the same problems.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Thursday, November 14, 2013 9:54 PM
  • Yes, I get the same problem. Any suggestion why?

    What happens in the document when I change a tag name to something else? Something must change since the macro works if I rename a tag.

    The amount of tags in the file (I guess) cannot create this problem, because the macro works superb if I change the tag name to something not used in the document.

    What exactly is the ".Range" parameter? What is it the script cannot edit ("Cannot edit Range")

    Friday, November 15, 2013 12:07 PM
  • "Range.Select

    Selection.Delete "

    seems to work partially, but it leaves empty RTCC's.

    Friday, November 15, 2013 12:23 PM
  • If I use the Range.Select and the Selection.Delete, is it possible to run a command after that to delete all the empty RTCC's?
    Friday, November 15, 2013 1:27 PM
  • I've done some testing today.

    The code

    .Range.Select

    Selection.Delete

    deletes the content (text and images) in all the content controls defined in StrTags, however it do not delete the tables in the RTCCs. Only the content in the table gets deleted.

    If the RTCC containes text/images the content is removed, but an empty RTCC remains.

    If the RTCC containes tables and text the content and the RTCC is removed, but not the table itself. (leaving an un-tagged table)

    What code can I add to delete the tables in the RTCC?

    It would also be nice to have some code for deleting all the empty RTCCs.

    This is the code I've done the testing with today:

    Sub DeleteByTag()
     Dim ccs As Word.ContentControls, cc As Word.ContentControl
     Dim i As Long, j As Long, StrTags As String
     StrTags = "1,5,6,7,9,10"
     For i = 0 To UBound(Split(StrTags, ","))
       Set ccs = ActiveDocument.SelectContentControlsByTag(Split(StrTags, ",")(i))
       For j = ccs.Count To 1 Step -1
         With ccs(j)
           If .Type = wdContentControlRichText Then
             .LockContentControl = False
             .LockContents = False
             .Range.Select
             Selection.Delete
           End If
         End With
       Next
     Next
     End Sub

    Friday, November 15, 2013 2:38 PM
  • Try:

    Sub DeleteByTag()
     Dim ccs As Word.ContentControls, cc As Word.ContentControl
     Dim i As Long, j As Long, StrTags As String
     StrTags = "1,3,5,10,11,12,50,57,100,102,103"
     For i = 0 To UBound(Split(StrTags, ","))
       Set ccs = ActiveDocument.SelectContentControlsByTag(Split(StrTags, ",")(i))
       For j = ccs.Count To 1 Step -1
         With ccs(j)
           If .Type = wdContentControlRichText Then
             .LockContentControl = False
             .LockContents = False
             .Range.Select
             Selection.Delete
             .Delete
           End If
         End With
       Next
     Next
     End Sub


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Friday, November 15, 2013 7:55 PM
  • Adding .Delete worked perfect for the RTCCs without tables inside. Both the content and the content control are removed.

    However, for the RTCCs with tables and text inside, only the RTCCs are removed. The table and all the content remain.

    Is there any option for deleting the tables?

    Something like

    If RTCC contains Table

    Select.Table

    Table.Delete

    End if

    Monday, November 18, 2013 7:00 AM
  • Perhaps the problem is the order in which things are being deleted. Try:

    Sub DeleteByTag()
      Dim ccs As Word.ContentControls, cc As Word.ContentControl, Rng As Range
      Dim i As Long, j As Long, StrTags As String
      StrTags = "1,3,5,10,11,12,50,57,100,102,103"
      For i = 0 To UBound(Split(StrTags, ","))
        Set ccs = ActiveDocument.SelectContentControlsByTag(Split(StrTags, ",")(i))
        For j = ccs.Count To 1 Step -1
          With ccs(j)
            If .Type = wdContentControlRichText Then
              Set Rng = .Range
              .LockContentControl = False
              .LockContents = False
              .Delete
              Rng.Delete
            End If
          End With
        Next
      Next
      End Sub


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Monday, November 18, 2013 7:30 AM
  • That code gave me the same error as earlier. "Run-time error 5904: Cannot edit Range"
    Monday, November 18, 2013 7:39 AM
  • OK, running out of options here. Try:

    Sub DeleteByTag()
      Dim ccs As Word.ContentControls, cc As Word.ContentControl, Rng As Range
      Dim i As Long, j As Long, StrTags As String
      StrTags = "1,3,5,10,11,12,50,57,100,102,103"
      For i = 0 To UBound(Split(StrTags, ","))
        Set ccs = ActiveDocument.SelectContentControlsByTag(Split(StrTags, ",")(i))
        For j = ccs.Count To 1 Step -1
          With ccs(j)
            If .Type = wdContentControlRichText Then
              Set Rng = .Range
              .LockContentControl = False
              .LockContents = False
              .Select
              Selection.Delete
              Rng.Delete
            End If
          End With
        Next
      Next
    End Sub


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Monday, November 18, 2013 8:22 AM
  • That didn't work either. Looks like it's mission impossible.

    Thanks for all the help.

    Monday, November 18, 2013 10:05 AM
  • Are you able to upload an extract from a document containing the problem content controls (i.e make sure the existing macro won't delete them) to a file hosting site (e.g. http://www.4shared.com/) from where I can download it, then post a link here?

    Cheers
    Paul Edstein
    [MS MVP - Word]

    Monday, November 18, 2013 11:07 AM
  • Maybe I can upload a test.

    I did one final test now.

    If I run this code, without any deletion, the table is selected when the macro is finished. To delete the selected table and content I have to right click on the selection and click "Delete Table". What is the Visual basic code for that command? If I only press the "Delete" button on my keyboard the table content and rtcc is deleted, but not the table itself. I guess it's the last option which occur in my script with the Selection.Delete command.

    Sub DeleteByTag()
      Dim ccs As Word.ContentControls, cc As Word.ContentControl
      Dim i As Long, j As Long, StrTags As String
      StrTags = "1"
      For i = 0 To UBound(Split(StrTags, ","))
        Set ccs = ActiveDocument.SelectContentControlsByTag(Split(StrTags, ",")(i))
        For j = ccs.Count To 1 Step -1
          With ccs(j)
            If .Type = wdContentControlRichText Then
              .LockContentControl = False
              .LockContents = False
              .Range.Select         
            End If
          End With
        Next
      Next
      End Sub

    Monday, November 18, 2013 12:37 PM
  • Maybe I can upload a test.

    ...

    To delete the selected table and content I have to right click on the selection and click "Delete Table". What is the Visual basic code for that command?

    It would indeed be helpful if you were to updload a document as requested.

    To delete a selected table you could use:
    Selection.Tables(1).Delete


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Tuesday, November 19, 2013 9:38 AM
  • Hi Tri-X

    As close as I can follow, if the table (when present) is selected at the end of a loop, you should be able to detect it:

    If Selection.Information(wdWithinTable) Then

    And delete it:

    Selection.Tables(1).Delete


    Cindy Meister, VSTO/Word MVP, my blog

    Tuesday, November 19, 2013 3:46 PM
    Moderator
  • Cindy: I tried your code and implemented it to this code. But this code deletes more than the tags listed in StrTags and then the macro stops with this error: "Run-time error 5941: The requested member of the collection does not exist." If I go to debug this line is yellow: With .ContentControls(i)

    Can you see something wrong in my code?

    Sub Demo()
     Dim i As Long, StrTags As String
     StrTags = ",1,5,7,"
     With ActiveDocument
       For i = .ContentControls.Count To 1 Step -1
         With .ContentControls(i)
           If .Type = wdContentControlRichText Then
             If InStr(StrTags, "," & .Tag & ",") > 0 Then
               .LockContentControl = False
               .Range.Select           
                 If Selection.Information(wdWithInTable) Then
                 Selection.Tables(1).Delete
                 
               
                 Else
                 Selection.Delete
              
                 End If
              
              
              
              
             End If
           End If
         End With
       Next
     End With
     End Sub
      

    Wednesday, November 20, 2013 10:21 AM
  • Hi Tri-X

    I was answering this:

    <<If I run this code, without any deletion, the table is selected when the macro is finished. To delete the selected table and content I have to right click on the selection and click "Delete Table". What is the Visual basic code for that command>>

    If I follow that correctly, then you should have the code that checks whether there's a table and deletes it after deleting the content control.


    Cindy Meister, VSTO/Word MVP, my blog

    Wednesday, November 20, 2013 3:43 PM
    Moderator