MS Word VBA To Get Paragraphs Within Cell

Using a VBA Macro in my Word document, I need to get multiple paragraphs within a table cell and convert them into separate XML objects, each with positioning tags.

For instance, consider the following two cells, of which I will only deal with Cell 1, and consider the two paragraphs within cell 1:

.          Cell 1         .         Cell 2        .
|    Paragraph 1    |                          |
|                            |                          |
| Paragraph 2 will |                          |
| wrap within the  |                          |
| same cell.           |                          |

I need to convert cell 1 to something like the following:

            <Value>Paragraph 1</Value>
            <Value>Paragraph 2 will wrap within the same cell</Value>

Word indeed exposes 2 separate paragraph objects within that cell object. However, I have scratched around and cannot find the properties of each paragraph object that tell me the relative positioning within that cell.

How do I get the positioning of each paragraph object within its cell object?

Any help is appreciated. Thank you.

Below is some of my code which gets me partially there and may help explain what I am seeking.
    For Each myRow In myTable.Rows
        For Each myCell In myRow.Cells
            For Each myParagraph In myCell.Range.Paragraphs
                myTopMargin = myParagraph.TopMarginWithinThisCell    ' Does not exist as is, but is what I need
                myHeight = myParagraph.Height                        ' Does not exist as is, but is what I need
                myText = myParagraph.Range.Text                      ' This exists
                Print #1, "<TextBox>"
                Print #1, "    <Top>" & PointsToInches(myTopMargin) & "</Top>"
                Print #1, "    <Height>" & PointsToInches(myHeight) & "</Height>"
                Print #1, "    <Value>" & myText & "</Value>"
                Print #1, "</TextBox>"
            Next myParagraph
        Next myCell
    Next myRow

Open in new window

LVL 20
dsackerContract ERP Admin/ConsultantAsked:
Who is Participating?
jan_boven_alConnect With a Mentor Commented:
Not the nicest piece of code I've ever written but this does it.
Note that I prefer centimeters to inches so you'll have to turn that back to inches.
Sub testtable()
    Dim tbl As Word.Table
    Dim myrow As Word.Row
    Dim mycell As Word.Cell
    Dim myParagraph As Word.Paragraph
    Dim myText As String
    Dim myTopMargin As Long
    Dim myHeight As Long
    Dim cellpTop As Long
    Dim parapTop As Long
    Dim parapbottom As Long
    Dim cellpBottom As Long
    For Each tbl In ActiveDocument.Tables
        For Each myrow In tbl.Rows
            For Each mycell In myrow.Cells
                Dim curpara As Integer
                Dim allPara As Integer
                allPara = mycell.Range.Paragraphs.Count
                cellpTop = mycell.Range.Information(wdVerticalPositionRelativeToPage)
                For curpara = 1 To allPara
                    parapTop = mycell.Range.Paragraphs(curpara).Range.Information(wdVerticalPositionRelativeToPage)
                    myTopMargin = parapTop - cellpTop
                    parapbottom = mycell.Range.Paragraphs(curpara + 1).Range.Information(wdVerticalPositionRelativeToPage)
                    myHeight = parapbottom - parapTop
                    myText = mycell.Range.Paragraphs(curpara).Range.Text                      ' This exists
                    Debug.Print "<TextBox>"
                    Debug.Print "    <Top>" & PointsToCentimeters(myTopMargin) & "</Top>"
                    Debug.Print "    <Height>" & PointsToCentimeters(myHeight) & "</Height>"
                    Debug.Print "    <Value>" & myText & "</Value>"
                    Debug.Print "</TextBox>"
                Next curpara
                ActiveDocument.Undo (2)
            Next mycell
        Next myrow
    Next tbl
End Sub

Open in new window

The original and still the main purpose of Word in to produce nicely formatted printed documents.
Therefore the editor provides the text and tables along with instructions about how the text is to be treated ('align left', 'use arial font size 12', 'keep paragraphs together', etc). At times, especially when the document is about to be printed, the whole document is formatted according to the instructions and according to the chosen printer's capabilities.

This is much easier than making the editor designate the co-ordinates for any of the text, since any change would need the editor to re-assess the positioning. In this way the positions are calculated by Word and liable to change from time to time.. The same document on a different computer could print out slightly differently. For this reason there is not a comprehensive set of properties related to the results of pagination process.

However, all is not lost. There is an Information property for both Range objects and the Selection object and which can return some metrics, including horizontal and vertical positioning.

Cell margins might be a bit more difficult. I don't think the can be read directly. They are adjusted according to a two sets of 'padding' properties (TopPadding, BottomPadding, LeftPadding and RightPadding). One set belongs to the table objects and applies a default for the whole table. There is also a set for each table cell.

dsackerContract ERP Admin/ConsultantAuthor Commented:
Range.Information does not return the position of the Paragraph relative to its container (in this case, the cell). And the position of both Paragraphs relative to the page are returned as the same value as the parent cell itself.

My question posted here is the product of a business requirement. The doc and the objective are non-negotiable (ain't life grande? *lol*).

Anything akin to a solution is needed. :)

And appreciated.
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

dsackerContract ERP Admin/ConsultantAuthor Commented:

A most excellent posting. I had been doing everything except the Paragraph.Add method (of which I see you doing a resulting .Undo).


Without doing those paragraph "Adds", there isn't an applicable definition for their heights and Vertical Position relative to page, is that correct?

If that is correct, why are you putting in TWO adds? Should I adjust that to do a variable number of "Add" methods (for whatever number of paragraphs are counted within a cell)?
dsackerContract ERP Admin/ConsultantAuthor Commented:
I'm not sure why the adding of extra paragraphs all of a sudden makes the existing ones exposed, as far as their relative positions, but this was the solution. And a very good one. Thank you.
I searched for a height function but didn't find anything sutable. Doesn't mean there is nothing though.
So I changed to the basic Idea that you subtracting 2 sequentional tops gives you the height.
That worked fine except for the last paragraph though. So I added an extra pragraph.
Didn't do it as well. I tested this with the method and found out that when you select the last paragraph word selects the whole cell :(
So I added 2 paragraphs.
A matter of trial and error. Not really brains at work.
I see no reason (right now) why you would need to add more then 2 paragraps.

PS to be very honest it was genius GrahamSkan remark that made me look at this. Never done this kind of paper calculation before ;-)
I don't know why you describe your code as 'not the nicest'. The rest must be pretty good indeed.

EE have arbitrarily decided that you get called 'genius' over a certain number of points. However it is obvious that your solution is very INgenious.

Hmm. That works better said than written, but I'll let it stand, anyway
dsackerContract ERP Admin/ConsultantAuthor Commented:
I concur with GrahamSkan: jan_boven_al, your solution was truly a fine discovery.

I played around with the paragraph.add method after reading your posting, just to see how the original paragraphs' relative positions and heights changed. Indeed, adding two paragraphs is safest, because the final paragraph is reset to the same offset as the first paragraph and/or the cell top margin.

I hope your solution is made available to others at a higher level of visibility, for it fills a vital gap of needed information when it comes to converting Word documents via VBA code, where positioning is critical.

Again, thanks.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.