MS Word VBA To Get Paragraphs Within Cell

Posted on 2007-12-03
Last Modified: 2010-04-21
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

Question by:dsacker
  • 4
  • 2
  • 2
LVL 76

Expert Comment

Comment Utility
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.

LVL 20

Author Comment

Comment Utility
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.

Accepted Solution

jan_boven_al earned 500 total points
Comment Utility
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

LVL 20

Author Comment

Comment Utility

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)?
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

LVL 20

Author Closing Comment

Comment Utility
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.

Expert Comment

Comment Utility
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 ;-)
LVL 76

Expert Comment

Comment Utility
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
LVL 20

Author Comment

Comment Utility
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.

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

A few years ago I was very much a beginner at VBA, and that very much remains the case today.  I'll do my best to explain things as I go in the hope that other beginners can follow.  If you just want to check out a tool that creates a Select Case fu…
Using Word 2013, I was experiencing some incredible lag when typing.  Here's what worked for me....
This video walks the viewer through the process of creating a watermark for their document, customizing it, and saving it for viewing/printing needs.
This video shows where to find templates, what they are used for, and how to create and save a custom template using Microsoft Word.

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now