Link to home
Start Free TrialLog in
Avatar of Saqib Husain
Saqib HusainFlag for Pakistan

asked on

VBA – Defining sections/subsections in Word

I have attached a word file for a daily progress report

I would like to be able to split this file into sections and subsections using VBA.

The sections are: A, B, C.....
The subsections are i, ii, iii, iv...

Above the section A there is also a super section titled C MW-I: D P (C Ws) a T H Ws
which is currently alone and may be extended in future to have more supersections.

I would like to be able to send the sections to separate files and subsections to separate pages.

Can someone help me do this separation using VBA? To simplify, instead of sending to separate files we may add a blank page after each section.

TIA

20210308 Daily Progress Report EE.docx
Avatar of John Korchok
John Korchok
Flag of United States of America image

This is not a simple project, because Word is not a modular or page-design program. I think it prudent to hire a professional to program it for you.
Avatar of Saqib Husain

ASKER

I do programming myself.

What I do not know is how to differentiate the sections from the subsections. Currently I have found the .listparagraph collection which contains all numbered and bulletted paragraphs. What I need is to find a way to differentiate the various levels of numbering/bulleting. If I spend some time on it I think I would find a way out. The reason for asking the question here is to save that time...or to find a better approach than the .listparagraph one.
I was initially confused by your use of the word "sections" as that is normally used for Word's Section attributes — but I can see that you are probably wanting to work with the different levels of a multilevel list structure.

For that, I recommend reviewing this description of the ListTemplate object. The left navigation panel on the Microsoft Docs pages will let you easily navigate to the descriptions of other related VBA objects to see their methods and properties. I expect you'll be able to find details that will enable you to use VBA to identify the levels you need to parse your document.

In VBA, a ListTemplate object relates to the Multilevel List options available in the Paragraph group of the Home ribbon. In the UI, if you choose "Define new multilevel list" from the pull-down, it will show you the current list structure. Click "More >>" to expand the dialog to see the level controls. A multilevel list can have 9 levels, and you can associate each with a style (typically one of the 9 built-in Heading styles, but other styles can be used).
Thanks Eric, this does seem appropriate for what I intend to do.

What I cannot seem to find is how to connect a listtemplate with any listparagraph. Can you, please, help me with this?
I can see in your sample document that your multilevel list does not associate levels with heading styles. While it isn't essential to do so for a multilevel list structure, I'd strongly recommend it for what you want to do.

If you applied the Heading 1 style to your "supersection" heading, then Heading 2 to the next sections (A, B, C...), and Heading 3 to the subsections (i, ii, iii...), you could then set up the multilevel list to manage the numbering based on the styles. The screenshot below shows how the "Define new Multilevel list" dialog can be used to achieve this.

User generated image
The dialog box (1) shows the parameters I used to set up the numbering scheme to be used by the heading levels. By default, the dialog opens without the right side visible, so you need to click the "More >>" button to expand it to get to the settings that allow you to associate the numbering with named styles. Each list level needs to be defined for the type of numbering — and in this example, to associate it with a named style. This dialog is more than a bit obscure, so I suggest using this Microsoft support page to help clarify the terms and process.

The area marked 2 shows how my numbering is being applied. In the dialog, I had preceded each level with text constants "L#–" to make it easier to see the different levels, and you can see that the selected Heading 2 includes the "L2–" before the "A." style numbering. Level 1 (for Heading 1s) has no numbering (just the "L1–"); level 3 applies "i, ii, iii" type numbering to Heading 3 styled paragraphs.

Word's navigation pane (3) shows the full structure of your document using the outline levels built in to the heading styles, and makes it easy to navigate to any given section or subsection by just clicking.

Although the simple list button is shown as active in the Paragraph group, that applies only to the current selection; here, the highlighted Heading 2 paragraph. To get to the "Define new Multilevel list" dialog, you need to click the pulldown for the button circled in red (at 4). It will display the current list with illustrations of the set of other available lists and the "Define new Multilevel list" as an option below.

From my screenshot, you'll see that I entered a name for the list (eeSadiq): oddly, this does not appear in the UI as a named list — but neither does it seem to be accessible in VBA! As far as I have been able to tell, only the position of the list in the set of multilevel list dropdown is accessible, so I have never proceeded further to explore how to manage multilevel lists in VBA.

However, if you use the multilevel list feature as shown above, you could then use VBA to separate the document sections using styles instead of wrangling with the list templates. In VBA, you could define a range to include the content of & below the heading level you need.

(Note that the screenshot shows my current Home ribbon. The options in the Paragraph group haven't been changed, but the next one is a custom group to give me access to tools I use frequently.)
Hi, Eric, sorry for being away.

I do understand and appreciate the use of headings but...

My current problem is that I already have a few hundreds of such documents and it would not be a simple tast to modify all those documents. The people preparing the document are at a construction site and hardly find the time to prepare this report...let alone learn the various word options. And believe me, I having a mediocre knowledge/experience in word have never been comfortable with these formatting tools. More often than none I have had to redo many works as these headings get messed up.

That is why I have been attempting to automate the deciphering process with VBA. I only hope to know how to identify the change point....Word does that anyways.

Maybe I would have to go for brute force.
I have started working on a macro but am stuck at a point. The liststring property does not seen to get or return the bullets in my select case block. Can someone help me with sorting this out.
I hear you about getting non-Word users to adhere to standards! For a large contract involving many authors contributing highly technical chapters to research reports many years ago, we'd prepared details specs for how to use Word features. It was like herding cats: after beating our heads against the wall and alienating several users who deemed themselves experts (not!), I decided the only reasonable solution was to develop a series of macros to clean up the content. It worked very well for all involved, and I still use many of the macros 2-+ years later. (Most have been modified from their original WordBasic, but a couple still run in the latest incarnation of Word.)

For your situation, you will be running up against an annoying quirk in how Word manages bullets & numbering. While the default buttons in the Paragraph group of the Home ribbon are handy, they just apply the default bullets (or numbering) set up for the current template. For most users, this is the Normal.dotx template. Not only can it easily be changed inadvertently, different localizations will affect the default settings. In consequence, your macros will not necessarily be encountering the same set-ups in every document. Some differences are obvious: the language attribute will affect punctuation (e.g. for English Canada, I'll see “quotes”, but for French Canada, I'll see « quotes »); others like bullets are harder to notice.

Here's an example. Try the same on your system to see if there are differences.
  1. First, press Shift-F1 to display the Reveal Formatting panel that will display all formatting for the current selection. At the bottom of the panel, turn on the "Distinguish style source" to include the name of the underlying style, and "Show all formatting marks" to display non-printing symbols.
  2. When I click the Bullet button for a new paragraph with my current Normal template, it will indent the paragraph 0.25" and apply a hanging indent of 0.25". The paragraph style is shown as "List Paragraph", and in the Bullets and Numbering section, the Reveal Formatting shows "List | Bulleted | Level: 1 —with no indication of what bullet is being applied, and with alignment matching the indentation noted above (albeit in different terms than "left" and "hanging").
  3. Type in enough content to spillover to a second line to confirm the hanging indent, then press Enter to start a new paragraph.
  4. As expected, the new paragraph will retain the same formatting, and have the List Paragraph style.
  5. But now click the "Increase Indent" button: the new paragraph will have a different bullet, and be indented further in — but the style is still List Paragraph!
The key here is that the list definition manages what bullets you will get (as well as the indent levels). If you (or one of your users) used the Bullet button's dropdown "Define New Bullet..." option to set up a different bullet (say the × symbol), the Reveal Formatting will report identical formatting when you use its "Compare to another selection" feature. In other words, no way to detect the details of different bullet.

So, can this be detected in VBA? Not as reliably as I would expect. According to this Microsoft Docs page, you'll see that “if there is already a list defined in your document, you can access a List object by using the Lists property.” I have yet to determine how to evaluate which symbol is being used for the various ListGalleries possibilities after I've added new bullets.

What to do then? Since the above shows that the same style may have different bullets, I prefer to apply specific styles. Many built-in styles are available (List Bullet, List Bullet 2, List Continue, List Number...), and you can create a custom group to have easily-accessible icons to enable users to apply them.

For your document, I suggested using heading levels because that can accomplish the "numbering" via a multi-level list, but also can be reliably applied with styles — both through the style definition's "Style for following paragraph" setting to get an automatic next style after main headings, and via custom buttons to make it easier for your users to apply the styles.

I find that styles are much easier to manage in VBA than detecting list attributes. The multi-level list feature is still complex, but once set up, it does seem to behave well with the levels defined by the Outline level in the heading styles.

 
Oops... I missed pasting the macro which is giving trouble.

Sub a()
Dim doc As Document
Dim para As Paragraph
Dim paras As Paragraphs
Dim pg As Range
Set doc = ActiveDocument
Set paras = ActiveDocument.Paragraphs
For Each para In paras
    Set pg = para.Range
    pg.Select
    If pg.ListFormat.ListString <> "?" Then
    Select Case pg.ListFormat.ListString
        Case "?", ""
        Case "A." To "Z."
        Case "i." To "iv."
        Case "a)" To "d)"
        Case Else
            Debug.Print """"; pg.ListFormat.ListString; """"
            Stop
    End Select
    End If
Next para
End Sub

Open in new window

Debug.Print gives me the ? character. And its Asc as 63. But neither the if statement is picking it up nor is the select case block seeing it. Can you check out why?


As far as your rundown on the programming part...I appreciate you taking time and pain to guide me. Most of them I already am aware of and others I find as useful.
I'm not sure what you are looking for with the "?". Is it defined as the number format for a level in your multilevel list?
  • I added "Debug.Print pg.ListFormat.ListString" after your line 10 to see what it detects from a test document with a multi-level list. The revised code correctly printed the list string for each paragraph that was part of the sample multi-level list I set up (and it printed a blank line for any paragraphs I had included with a style that was not part of the multi-level list).
  • When I altered the multi-level list definition to use a "?" as the fourth level, any  paragraphs using it were detected, and the "?" was included in the debug print list.
  • When I demoted a paragraph to a fifth level, it triggered your Case Else condition as I would expect (since the Select Case doesn't include it). The Immediate window displayed the list string (from my debug line), then the string from your debug print in the Case Else part — and then stopped.
  • Similarly, when I added a fifth paragraph of level 2 (i.e. one that will have "v." as its list string), it failed your “Case "i." To "iv."” line. As expected, the Immediate window displayed v., then " v. " — and stopped.

BTW, I found your code useful, as I had never tried getting the list string as you've done here!
The ? character is probably the bullet in wingdings.

The problem is that the code does not detect it and gets trapped in the case else.
This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.