![]() |
|
#1
|
|||
|
|||
|
Hi there, Having a small issue, I want to delete all TOCs found in ActiveDocument but whatever I do, the TOC container remains. This will delete the heading of the TOC, if any... and delete all content in range (mostly TOC fields) Code:
For Each toc In ActiveDocument.TablesOfContents
toc.Range.Previous(Unit:=wdParagraph).Delete
toc.Range.Delete
Next toc
Code:
For Each cc In ActiveDocument.ContentControls
MsgBox cc.Type
Next cc
|
|
#2
|
|||
|
|||
|
Hi,
First, fields can be locked, so unlocking is required. Secondly, TOC is composed of FieldTOC that is attached to the last paragraph mark (a bit like the end paragraph of footnote) so deleting the TOC will never delete the TOC container unless this specific paragraph containing the fields is deleted. Last, I had further issues if document has multiple TOCs. So I had a brainstorming session for the dreaded AI and proposal was to: a) Build a Collection of paragrah(1) (this is the end paragraph) b) Then delete the whole fieldTOC (this will take care of TOC heading and fields - so no need of dealing with range) c) And delete that paragraph(1) in reverse And it works!! PS. I wonder what is adding in newcollection under "parasToDelete.Add f.Code.Paragraphs(1)", is it the paragrah number? Code:
Private Sub DeleteAllTOCs()
Dim toc As TableOfContents, para As Paragraph, _
i As Long, f As Field, parasToDelete As New Collection
Application.ScreenUpdating = False
Application.StatusBar = "We are deleting tables of content... Be patient..."
For Each f In ActiveDocument.Fields
If f.Type = wdFieldTOC Then
f.Locked = False
parasToDelete.Add f.Code.Paragraphs(1)
End If
Next f
For Each f In ActiveDocument.Fields
If f.Type = wdFieldTOC Then
f.Delete
End If
Next f
For i = parasToDelete.count To 1 Step -1
parasToDelete(i).Range.Delete
Next i
Application.ScreenUpdating = True
Application.StatusBar = ""
Application.ScreenRefresh
MsgBox "Done."
Set toc = Nothing
End Sub
Last edited by TheBigBoss; 12-17-2025 at 08:25 AM. Reason: Removed my question asking how to mark it as SOLVED |
|
#3
|
|||
|
|||
|
After running your macro, the container is still there. Used first automatic TOC for one TOC, bare field for the other (Custom TOC).
The key sequence Alt, S, T, R removes it. That uses ribbon accelerators. |
|
#4
|
|||
|
|||
|
The "container" if we will call it that is just a BuildingBlock created by Microsoft and they neglected to provide a direct means to work with it within VBA. The building block consists of a TOC Heading line paragraph followed by a paragraph containing the TOC field code.
None of the Artificial Idiot suggestions that I have seen work. So, if we loop through the document TOCs and set a range to the TOC we can capture the TOC field. If we then move the range start back two paragraphs, we can check to see if the first paragraph defines the TOC Heading line (styled with TOC Heading). If so, then we can assume we have captured a TOC in a TOC container and delete if. If not, then we are likely dealing with a stand alone TOC, so restore the range and delete it. Of course moving or attempting to move a range when a TOC is at the top of a document could result in errors that have to be handled. This isn't pretty, but works for the testing document that I created: Code:
Sub DeleteTOCs_and_Containers()
Dim oRng As Range
Dim TOC As TableOfContents
Dim lngIndex As Long
For lngIndex = ActiveDocument.TablesOfContents.Count To 1 Step -1
Set TOC = ActiveDocument.TablesOfContents(lngIndex)
Set oRng = TOC.Range.Paragraphs(TOC.Range.Paragraphs.Count).Range
oRng.MoveStart wdParagraph, -2
oRng.Select
Select Case True
Case oRng.Paragraphs(1).Style = "TOC Heading"
Case Else
oRng.MoveStart wdParagraph, 1
End Select
On Error Resume Next
oRng.Delete
If Err.Number <> 0 Then
oRng.MoveStart wdParagraph, -1
oRng.Delete
End If
On Error GoTo 0
Next lngIndex
lbl_Exit:
Exit Sub
End Sub
|
|
#5
|
|||
|
|||
|
Hi Greg,
I ran your code in a document with three TOCs, one a bare field, the other in the Content Controls. None were removed. The following was offered by John Korchock in response to my question about using SendKeys: Code:
' Source - https://stackoverflow.com/a/79851355
' Posted by John Korchok
' Retrieved 2025-12-19, License - CC BY-SA 4.0
Sub DeleteAllTOCs()
Dim f As Field, TOCRange As Range
Application.ScreenUpdating = False
Application.StatusBar = "We are deleting tables of content... Be patient..."
For Each f In ActiveDocument.Fields
If f.Type = wdFieldTOC Then
f.Locked = False
f.Select
Set TOCRange = Selection.Range
With TOCRange
.MoveStart Unit:=wdParagraph, Count:=-1
.MoveEnd Unit:=wdParagraph, Count:=1
.Delete
End With
Set TOCRange = Nothing
End If
Next f
Application.ScreenUpdating = True
Application.StatusBar = ""
Application.ScreenRefresh
MsgBox "Done."
End Sub
That code does work on my sample. I am still hoping to find an answer about using SendKeys to mimic the Ribbon Accelerator buttons. |
|
#6
|
|||
|
|||
|
Charles,
Well, you are right. That code did nothing with your example. I think part of the problem will be dealing with TOCs that are in a container as well as those that are not and not with a preceding TOC Heading paragraph. Both of these seem to work with your examples: Code:
Sub DeleteTOCs_and_Containers()
Dim oRng As Range
Dim TOC As TableOfContents
Dim lngIndex As Long
For lngIndex = ActiveDocument.TablesOfContents.Count To 1 Step -1
Set TOC = ActiveDocument.TablesOfContents(lngIndex)
TOC.Range.Fields(1).Locked = False
Set oRng = TOC.Range.Fields(1).result
oRng.MoveStart Unit:=wdParagraph, Count:=-2
oRng.MoveEnd Unit:=wdCharacter, Count:=1
Select Case True
Case oRng.Paragraphs(1).Style = "TOC Heading"
Case Else
oRng.MoveStart wdParagraph, 1
End Select
oRng.Delete
Next lngIndex
lbl_Exit:
Exit Sub
End Sub
Sub DeleteTOCs_and_ContainersII()
Dim TOC As TableOfContents
Dim oRng As Range
Dim lngIndex As Long
For Each TOC In ActiveDocument.TablesOfContents
Set oRng = TOC.Range.Paragraphs.First.Previous.Range
Application.CommandBars.ExecuteMso ("TableOfContentsRemove")
On Error GoTo Skip
If oRng.Style = "TOC Heading" Then
oRng.Delete
End If
Skip:
Next TOC
lbl_Exit:
Exit Sub
End Sub
|
|
#7
|
|||
|
|||
|
Thank you, Greg.
The second one (DeleteTOCs_and_ContainersII) works on my sample. The first leaves one of the fields ithout the header. John Korchok's also works. |
|
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
Word Table of Contents - when I title a heading "table", table of contents shows "table2"
|
jncuk | Word | 8 | 04-15-2020 07:01 PM |
Manipulating Headings so Image contents is correctly referenced in Table of Contents
|
dynamictiger | Word | 2 | 05-29-2019 05:41 AM |
Table of Contents -"Permanently" Setting Table of Contents Option
|
KRoger | Word | 3 | 03-01-2019 06:36 AM |
Code to find a named (bookmarked?) table, replicate a row or table, and delete a specified table.
|
kevinbradley57 | Word VBA | 9 | 09-21-2017 04:58 PM |
| Text inside text boxes create headings inside my table of contents!!! How do I delete the created he | carstj | Word | 3 | 04-11-2016 12:46 PM |