![]() |
#1
|
|||
|
|||
![]() Is there a way to delete an individual line within a Table of Contents using VBA? |
#2
|
||||
|
||||
![]()
Not in any practical sense. A Table of Contents in Word uses a TOC field. Anytime something causes the field to refresh, it will restore the deleted line.
__________________
Cheers, Paul Edstein [Fmr MS MVP - Word] |
#3
|
|||
|
|||
![]()
It’s fine if they reappear when the TOC is updated. This document is a bit unusual and will have very circulation/updates. It has multiple TOCs, a main heading style that is level 1, and multiple subheading styles that are level 2. Each of the subheading styles are unique to a single TOC. Each of the TOCs are setup to pick up the level 1 headings (which are throughout the document) and their unique subheadings. That part works fine. The trouble is there isn’t always a subheading of each unique style after each level 1 heading, and I only want them to appear in the TOCs when there is. In other words, I don't want the level 1 heading in the TOCs unless a subheading appears after it.
I’ve been manually deleting the entries without subheadings, but I was hoping to automate it someway. I’ve tried looping through the paragraphs and using the Paragraph.Range.Delete method to delete them but I’ve not been able to get that to work reliably. I can change the background and/or font color but can't delete them. I also thought about using the “if” statement in the TOC field codes to check for the subheading before including the level 1 heading, but I’m not sure if that’s possible. That would be a great solution if it would work. |
#4
|
||||
|
||||
![]()
Assuming each Section has only one Level 1 Heading, then to do something like that for your various Section TOCs, you could use a field code like:
{IF{TOC \o "2"}= "Error!*" "" {TOC}} Doing this will render the TOC references unlinkable (i.e. you can't click on them and be taken to the headings). You will, of course, need to supplement both of the TOC fields in the field coding above with your existing TOC field switches for determining the bookmarked range the TOC applies to. Note: The field brace pairs (i.e. '{ }') for the above example are all created in the document itself, via Ctrl-F9 (Cmd-F9 on a Mac or, if you’re using a laptop, you might need to use Ctrl-Fn-F9); you can't simply type them or copy & paste them from this message. Nor is it practical to add them via any of the standard Word dialogues. The spaces represented in the field constructions are all required.
__________________
Cheers, Paul Edstein [Fmr MS MVP - Word] |
#5
|
|||
|
|||
![]()
Thank you for the help. I will play around with the IF statement but each TOC does have 2 levels. Here are couple of the field codes from 2 of them.
{ TOC \O "1-1" \H \Z \T "ITEM HEADING - FIRSTLIST,2" \W } { TOC \O "1-1" \H \Z \T "ITEM HEADING - SECONDLIST,2" \W } There are 7 TOCs in the document total, with the only difference in the field codes being the name of the subheadings, e.g. "ITEM HEADING - FIRSTLIST". The challenging part is that the subheadings are throughout the document under various level 1 headings. Some level 1 headings only have 1 of the subheadings under it while others may have them all. Each TOC needs include only the level 1 heading and any of its subheadings, except that if there are no subheadings of a specific style under the level 1 heading then that TOC should also exclude the level 1 heading. I know, highly unusual. It's not necessary for the hyperlinks to work. What I was attempting to do in VBA was update the TOCs, which adds all of the level 1 headings, as well as all of each TOCs subheadings, then loop back through the TOC paragraphs and remove the unwanted level 1 headings. I could can the formatting of them but have not been able to figure out how to remove them reliably. I'm not that familiar with using VBA in Word though. |
#6
|
||||
|
||||
![]()
With multiple TOCs in your document, I'd have expected there to be a \b switch pointing to the bookmarked range used for each. I don't see that in the code you posted. Something like:
{ TOC \O "1-2" \H \Z \W \B BkMk1} without the need to have a separate FIRSTLIST, SECONDLIST, etc. Styles. For which you could then code along the lines of: {IF{TOC \o "2" \B BkMk1}= "Error!*" "" {TOC \O "1-2" \Z \W \B BkMk1}} Just changing the bookmark names. As it is, you should be able to use something like: {IF{TOC \T "ITEM HEADING - FIRSTLIST,2"}= "Error!*" "" {TOC \O "1-1" \Z \T "ITEM HEADING - FIRSTLIST,2" \W}}
__________________
Cheers, Paul Edstein [Fmr MS MVP - Word] |
#7
|
|||
|
|||
![]()
It doesn't use bookmarks because the document is not arranged in the traditional way. The subheadings I'm pulling into each TOC are located throughout the entire document under various level 1 headings which are also throughout the entire document. The TOCs are basically being used as lists, where each TOC has it's own subheading style. Those subheading styles may appear anywhere in the document under any of the level 1 headings. Each TOC should only list the specific subheading style associated with it, as well as the level 1 heading it appears under. If the level 1 heading has no subheadings of a specific style under it, then that level 1 heading should not appear in the TOC associated with that style.
|
#8
|
||||
|
||||
![]()
Paul, I think you are not understanding what the OP is trying to do. My interpretation of what they are saying could be addressed by this macro.
This refreshes the TOC and then steps backwards through the entries and removes any TOC1s that are followed immediately by another TOC1 (doesn't have a child) Code:
Sub TOC_Fiddler() Dim aPar As Paragraph, aTOC As TableOfContents, i As Integer, aRng As Range Set aTOC = ActiveDocument.TablesOfContents(1) aTOC.Update Set aRng = aTOC.Range For i = aRng.Paragraphs.Count - 1 To 1 Step -1 If aRng.Paragraphs(i).Style = "TOC 1" And aRng.Paragraphs(i).Next.Style = "TOC 1" Then aRng.Paragraphs(i).Range.Delete Next i End Sub
__________________
Andrew Lockton Chrysalis Design, Melbourne Australia |
#9
|
|||
|
|||
![]() Quote:
Thank you! With a slight mod to work on each of the TOCs, that works exactly as I want except I get a "Cannot edit Range." error if it attempts to delete the top entry in the TOC. I was getting that same error before using similar code that used paragraph.range.delete but I didn't realize it was the just on the top entry that caused the error until I ran your code which steps backwards through the TOC. |
#10
|
||||
|
||||
![]()
My understanding is that the OP has a series of TOCs, each with a single level 1 heading and, perhaps, none, one, or more level 2 headings under that. If there is no level 2 heading, he wants the level 1 heading hidden.
__________________
Cheers, Paul Edstein [Fmr MS MVP - Word] |
#11
|
|||
|
|||
![]()
The modified version of Guessed's code below works as intended. Instead of trying to delete the top entry in the TOC, I changed the formatting to make it invisible. There may be a better way of doing it, but this seems to work very well.
Thanks guys for all of the help! Code:
Sub TOC_Fiddler() Dim aPar As Paragraph, aTOC As TableOfContents, i As Integer, aRng As Range, lngNumTOC As Long lngNumTOC = ActiveDocument.TablesOfContents.Count For Each TOC In ActiveDocument.TablesOfContents Set aTOC = ActiveDocument.TablesOfContents(lngNumTOC) aTOC.Update Set aRng = aTOC.Range For i = aRng.Paragraphs.Count - 1 To 1 Step -1 If aRng.Paragraphs(i).Style = "TOC 1" And aRng.Paragraphs(i).Next.Style = "TOC 1" Then If i > 1 Then aRng.Paragraphs(i).Range.Delete Else aRng.Paragraphs(i).SpaceAfter = 0 aRng.Paragraphs(i).SpaceBefore = 0 aRng.Paragraphs(i).Range.Font.Size = 1 aRng.Paragraphs(i).Range.Font.ColorIndex = wdWhite End If End If Next i lngNumTOC = lngNumTOC - 1 Next End Sub |
#12
|
|||
|
|||
![]() Quote:
Not exactly. Within the content of the document there are multiple level 1 headings throughout that are all the same style. Each level 1 heading may have 1 or more subheadings that are associated with 1 or more TOCs that are different styles. Each TOC has a unique subheading style that is used solely for it. The different subheading styles also appear under different level 1 headings. The TOCs themselves should contain only the level 1 headings that have subheadings associated with that TOC, as well as the subheadings. It's a bit unorthodox and hard to explain. I apologize for any confusion. |
#13
|
||||
|
||||
![]()
The first paragraph is particularly hard to delete and I guess this is because the field code is held within it. To keep things simple, I would first create a style in the document that has your 'hidden' attributes. I would actually use the font hidden property but making it white and tiny is similar in result and doesn't matter if the user has their options set to view hidden text.
There is no need to step backwards through the TOCs - just the paragraphs within the TOCs. Then this code could be as simple as... Code:
Sub TOC_Fiddler() Dim aTOC As TableOfContents, i As Integer, aRng As Range 'Assumes you have a style called 'TOC Hidden' to apply to lines you want to hide For Each aTOC In ActiveDocument.TablesOfContents aTOC.Update With aTOC.Range For i = .Paragraphs.Count - 1 To 1 Step -1 If .Paragraphs(i).Style = "TOC 1" And .Paragraphs(i).Next.Style = "TOC 1" Then .Paragraphs(i).Style = "TOC Hidden" End If Next i End With Next End Sub
__________________
Andrew Lockton Chrysalis Design, Melbourne Australia |
#14
|
|||
|
|||
![]()
That’s awesome! I learned a lot from both of you in this thread. Thanks again and happy Thanksgiving.
|
#15
|
||||
|
||||
![]()
Normally the stepping backwards through objects is necessary when items in the list are being deleted.
Now that the last posted code is not actually deleting the paragraphs we could step forwards but if we did, we would need to handle the logic because we may have just changed away from TOC 1.
__________________
Andrew Lockton Chrysalis Design, Melbourne Australia |
![]() |
|
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
![]() |
goingvirtual | Word | 2 | 09-09-2018 02:58 AM |
![]() |
Helend269 | Word VBA | 5 | 01-09-2018 12:08 PM |
![]() |
JackDaniels | Word | 2 | 10-01-2016 08:04 AM |
If Statement in vba to Delete a Line | mbesspiata | Excel Programming | 4 | 04-08-2014 04:32 AM |
Cannot delete line | adkr | Office | 1 | 04-07-2010 09:26 PM |