Go Premium for a chance to win a PS4. Enter to Win


MS Word VBA To Get Paragraphs Within Cell

Posted on 2007-12-03
Medium Priority
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

ID: 20394754
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

ID: 20397042
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 2000 total points
ID: 20406210
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

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

LVL 20

Author Comment

ID: 20406956

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)?
LVL 20

Author Closing Comment

ID: 31414399
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

ID: 20410685
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 range.select 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

ID: 20410999
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

ID: 20414050
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

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Shortcuts in Word Just the other day I had a training for Microsoft and they wanted me to show how well the new Windows and Office behaved on a touch device, which by the way is great, but it was only then that I realized that using keyboard shortc…
Ever visit a website where you spotted a really cool looking Font, yet couldn't figure out which font family it belonged to, or how to get a copy of it for your own use? This article explains the process of doing exactly that, as well as showing how…
This video shows where to find the word count, how to display it, and what it breaks down to in Microsoft Word.
Learn how to make your own table of contents in Microsoft Word using paragraph styles and the automatic table of contents tool. We'll be using the paragraph styles in Word’s Home toolbar to help you create a table of contents. Type out your initial …
Suggested Courses

971 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