1
votes

TL;DR:

How can I capture the paragraph numbering as a 'part' of the text and export it to a DOCX?


Problem

I have a document that's split into sections and sub-sections that reads similarly to a set of state statutes (Statute 208, with subsections Statute 208.1, Statute 208.2, etc.). We created this by modifying the numbering.xml file within the .docx zip.

I want to export a 'sub-section' (208.5) and its text to a separate .docx file. My VSTO add-in exports the text well enough, but the numbering resets to 208.1. This does make some sense as it's now the first paragraph with that <ilvl> in the document.

PDF works okay

Funnily enough, I'm able to call Word.Range's ExportAsFixedFormat function and export this selection to PDF just fine - even retaining the numbering. This led me down a path of trying to 'render' the selection, possibly as it would be printed, in order to throw it into a new .docx file, but I haven't figured that out, either.


What I've tried:

  • Range.ExportFragment() using both wdFormatStrictOpenXMLDocument and wdFormatDocumentDefaultas the wdSaveType values.

    • These export but also reset the numbering.
  • Document.PrintOut() using PrintToFile = true and a valid filename. I realize now that this, quite literally, generates 'printout instructions' and won't inject a new file at path filename with any valid file structure.

    • Plainly doesn't work. :)
  • Application.Selection.XML to a variable content and calling Document.Content.InsertXML(content) on a newly added Document object.

    • Still resets the numbering.

Code Section for Context

using Word = Microsoft.Office.Interop.Word;

Word.Range range = Application.ActiveDocument.Range(startPosition, endPosition);
range.Select();

//export to DOCX?
Application.Selection.Range.ExportFragment(
    filename, Word.WdSaveFormat.wdFormatDocumentDefault);
2
Can you please try setting Range.ListFormat.ListLevelNumber to see if that helps?Jazimov
@Jazimov The ListLevelNumber is 1, and I think that's because it's a top-level 'section' (domain term).. however, I do see ListString under ListLevelNumber as well, and that's got the 208.5 that I'm talking about.. Maybe when I export that content, I can set the ListLevelString after the fact.. giving that a shot.ebwb
Excellent! Let us all know if your idea ended up working.Jazimov
That find led me to ListValue, representing the 'index' of the List object within the list.. that would have worked too, but it only has a getter - no setter. Next, I found the ListFormat.ConvertNumbersToText() method. That worked!! ... but, I haven't yet found how to un-convert the original text..ebwb
Did you try to set ListLevelNumber? It's read/write.Jazimov

2 Answers

1
votes

You could use ConvertNumbersToText(wdNumberAllNumbers) before exporting, then _Document.Undo() or close without saving after the export.

1
votes

There is some good information at this (dated) link that still should work with current Word APIs: https://forums.windowssecrets.com/showthread.php/27711-Determining-which-ListTemplates-item-is-in-use-(VBA-Word-2000)

Information at that link suggests that you can create a name/handle for your ListTemplate so that you can reference it in code--as long as your statute-style bullets are associated with a named style for the document. The idea is to first name the ListTemplate that's associated with the statute bullet style for the active document and then reference that name when accessing the ListLevels collection.

For instance, you could have code that looks something like this:

ActiveDocument.Styles("StatutesBulletStyle").ListTemplate.Name = "StatuteBulletListTemplate";

After the above assignment, you can refer to the template by name:

ActiveDocument.ListTemplates("StatuteBulletListTemplate").ListLevels(1).StartAt = 5;

Using the above technique no longer requires that you try to figure out what the active template is...

Does that help?