Results 1 to 11 of 11
  1. #1
    2 Star Lounger
    Join Date
    Sep 2002
    Posts
    180
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Figuring out how many lines are in a paragraph (2000/XP)

    Is there any way to programmatically determine how many lines are in a
    paragraph? In addition, is there any way to determine what page(s) a
    paragraph lies on, and how many lines of text (not including header and
    footers) lie on a given page of a document?

    Thanks...

    Dan

  2. #2
    Plutonium Lounger
    Join Date
    Nov 2001
    Posts
    10,550
    Thanks
    0
    Thanked 7 Times in 7 Posts

    Re: Figuring out how many lines are in a paragraph (2000/XP)

    Here is a function that counts the number of lines in a range, and a sub that calls it twice to display the lines in the current paragraph and in the current page.
    I have not included the checks needed for a paragraph that spills over to the next page, this is left as "an exercise for the reader".

    StuartR


    Function CountLines(rngIn As Range) As Integer

    Dim lStart As Long
    Dim lEnd As Long

    lStart = rngIn.Information(wdFirstCharacterLineNumber)
    rngIn.Collapse Direction:=wdCollapseEnd
    rngIn.MoveStart Unit:=wdCharacter, Count:=-1
    lEnd = rngIn.Information(wdFirstCharacterLineNumber)
    CountLines = lEnd - lStart
    End Function

    Sub TestIt()

    MsgBox CountLines(Selection.Paragraphs(1).Range)
    MsgBox CountLines(ActiveDocument.Bookmarks("Page").Range)

    End Sub

  3. #3
    2 Star Lounger
    Join Date
    Sep 2002
    Posts
    180
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Figuring out how many lines are in a paragraph (2000/XP)

    Thanks very much Stuart! That was a big help.

    I have a couple of detail oriented question/comments about the CountLines function.

    Is there any reason why you're moving backward one character after rngIn.Collapse Direction:=wdCollapseEnd?

    The reason I ask is that I end up getting incorrect results (-1) if the paragraph is an empty one (i.e. containing only vbCR).

    Also, I believe the last line should read:

    CountLines = (lEnd - lStart) + 1

    Otherwise, a one line paragraph ends up being counted as having 0 lines.

    Thanks once again...

    Dan

  4. #4
    Plutonium Lounger
    Join Date
    Nov 2001
    Posts
    10,550
    Thanks
    0
    Thanked 7 Times in 7 Posts

    Re: Figuring out how many lines are in a paragraph (2000/XP)

    I step back one to deal with the situation where the Range is a whole page. Otherwise I go from Line 1 of one page to Line 1 of the next when I collapse the range. I guess I could fix this with a special case check: for lEnd = 1

    <font face="Georgia">
    If lEnd = 1 then
    rngIn.MoveStart Unit:=wdChar, Count := -1
    lEnd = rngIn.Information(wdFirstCharacterLineNumber)
    End If
    </font face=georgia>
    I need to think about what this would do on a page with only one [Next Page] break.
    Maybe it would be easier to have a special case when the range consists of only one character.

    <font face="Georgia">
    If inRng.Characters.Count < 2 then
    CountLines = 1
    Else
    <font color=448800> ' The rest of the original code goes here </font color=448800>
    End If
    </font face=georgia>

    You are of course right about the need to add 1 to the difference, so
    <font face="Georgia">
    CounLines = lEnd - lStart + 1
    </font face=georgia>

    I think it would be quite difficult to create special case code for every possibility, we could write something to deal with a paragraph that starts on one page and finishes on the next, but what if a single paragraph extends for 3 or 4 pages?

    How accurate do you need this to be?

    StuartR

  5. #5
    Plutonium Lounger
    Join Date
    Nov 2001
    Posts
    10,550
    Thanks
    0
    Thanked 7 Times in 7 Posts

    Re: Figuring out how many lines are in a paragraph (2000/XP)

    Thanks for the feedback, I decided it was worth writing this properly in case I need it again, especially because there is a bug in the version I posted so that it will give the wrong answer if called for a range that is not on the same page as the insertion point.

    This version will handle ranges that cover multiple pages and seems to do the right thing for any variation I could throw at it.

    I usually use Range objects but I had to use a selection this time because I don't know any way to get the current page from a Range!

    <font face="Georgia">

    Function CountLines(rngIn As Range) As Integer

    Dim iStart As Integer
    Dim iEnd As Integer
    Dim lStartPage As Long
    Dim lEndPage As Long
    Dim rngSel As Range

    <font color=448800> ' Remember the current selection so we can return here at the end</font color=448800>
    Set rngSel = Selection.Range
    rngIn.Select

    <font color=448800> ' Note character positions of the beginning and end of the page</font color=448800>
    lStartPage = ActiveDocument.Bookmarks("Page").Range.Start
    lEndPage = ActiveDocument.Bookmarks("Page").Range.End

    iStart = Selection.Information(wdFirstCharacterLineNumber) <font color=448800> ' First line number</font color=448800>
    Selection.Collapse Direction:=wdCollapseEnd
    iEnd = Selection.Information(wdFirstCharacterLineNumber) <font color=448800> ' Last line number</font color=448800>

    If ActiveDocument.Bookmarks("Page").Range.Start <> lStartPage Then
    <font color=448800> ' Range extends over more than one page </font color=448800>
    While ActiveDocument.Bookmarks("Page").Range.End > lEndPage
    <font color=448800> ' Count the lines on each page back to the original starting page </font color=448800>
    ActiveDocument.Range(Start:=ActiveDocument.Bookmar ks("Page").Range.Start - 1, _
    End:=ActiveDocument.Bookmarks("Page").Range.Start - 1) _
    .Select
    iEnd = iEnd + Selection.Information(wdFirstCharacterLineNumber) <font color=448800> ' Add Number of lines on this page </font color=448800>
    Wend
    End If

    <font color=448800> ' If we are checking the very last line of the document then add 1 as the Range.Collapse doesn't go to next para </font color=448800>
    If rngIn.End = ActiveDocument.Range.End Then iEnd = iEnd + 1
    CountLines = iEnd - iStart
    rngSel.Select

    End Function
    </font face=georgia>

  6. #6
    2 Star Lounger
    Join Date
    Sep 2002
    Posts
    180
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Figuring out how many lines are in a paragraph (2000/XP)

    Stuart--

    This is very cool. I had been about to send you a response to your earlier posting when this arrived. I particularly like the way you looped back through the pages; I'd been thinking about how to do that and hadn't come up with anything nearly that clever.

    I know what you mean about need to select the range in order to get the page--I guess it's just one of those "things".

    Thanks a lot for all this. I learned a lot.

    Regards,

    Dan

  7. #7
    Plutonium Lounger
    Join Date
    Nov 2001
    Posts
    10,550
    Thanks
    0
    Thanked 7 Times in 7 Posts

    Re: Figuring out how many lines are in a paragraph (2000/XP)

    I think the code could be simplified a bit more by removing the lines

    lStartPage = ActiveDocument.Bookmarks("Page").Range.Start

    If ActiveDocument.Bookmarks("Page").Range.Start <> lStartPage Then
    and
    End If

    But it's late, I'm tired, and I have to get up for work early tomorrow. Maybe I'll nake this change and test it when I get some time.

    Good night.

    StuartR

  8. #8
    Super Moderator jscher2000's Avatar
    Join Date
    Feb 2001
    Location
    Silicon Valley, USA
    Posts
    23,112
    Thanks
    5
    Thanked 93 Times in 89 Posts

    Re: Figuring out how many lines are in a paragraph (2000/XP)

    > Is there any way to programmatically determine how many lines are in a paragraph?

    Word has a built in line counter, but it's not always completely accurate:

    lngLines = Selection.Range.ComputeStatistics(wdStatisticLines )
    lngLines = ActiveDocument.Paragraphs(4).Range.ComputeStatisti cs(wdStatisticLines)

    > In addition, is there any way to determine what page(s) a paragraph lies on, and how many
    > lines of text (not including header and footers) lie on a given page of a document?

    Trick question: a paragraph can lie on more than one page. <img src=/S/wink.gif border=0 alt=wink width=15 height=15>

    I'm hoping Stuart's code answers this question, 'cause it seems to involve a lot of math.

    Anyway, the following old code shows how to retrieve the starting and ending page numbers of a selection, which could be adapted for a paragraph.

    <img src=/w3timages/blueline.gif width=33% height=2><img src=/w3timages/blueline.gif width=33% height=2><img src=/w3timages/blueline.gif width=33% height=2>
    Subject: Re: How to replace Section Breaks with Page Breaks (XP) [#204230]
    Poster: jscher2000
    Posted on: 07-Dec-02 21:58

    I realize that p1s2 syntax is a hassle, so how about a macro? Try this out on your document:

    <pre>Option Explicit
    Sub PrintSelectedPageRange()
    ' Jefferson Scher 7 Dec 2002
    ' Macro to print the range of pages in the selection
    Dim rngStart As Range, rngEnd As Range, strPrintRange As String
    ' To retrieve page and section numbers, set two range variables
    With Selection
    Set rngStart = ActiveDocument.Range(.Start, .Start)
    Set rngEnd = ActiveDocument.Range(.End, .End)
    End With
    ' Note that we used the user-assigned "logical" page number,
    ' not the physical page number in the p1s2 syntax
    strPrintRange = _
    "p" & rngStart.Information(wdActiveEndAdjustedPageNumber ) & _
    "s" & rngStart.Information(wdActiveEndSectionNumber) & "-" & _
    "p" & rngEnd.Information(wdActiveEndAdjustedPageNumber) & _
    "s" & rngEnd.Information(wdActiveEndSectionNumber)
    ' Clean up the objects
    Set rngStart = Nothing
    Set rngEnd = Nothing
    ' Pre-populate and display the File|Print... dialog
    With Dialogs(wdDialogFilePrint)
    .Range = wdPrintRangeOfPages
    .pages = strPrintRange
    .Show ' displays and executes
    End With
    End Sub</pre>

    This was tested in Word 2000. Does it work as expected in XP?

  9. #9
    2 Star Lounger
    Join Date
    Sep 2002
    Posts
    180
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Figuring out how many lines are in a paragraph (2000/XP)

    After a pause, I'm returning to this issue again. I'm trying to figure out the most efficient way to go up to the first character in a line which is 'x' lines above a given character. The best way I can think of thus far is to create a range which goes from the end character to the top of the page, and do a binary search through the characters looking for one in which the wdFirstCharacterLineNumber property is what I'm looking for; from there, I'd have to do a linear search to the beginning of the line. This seems clunky. Does anybody know of any clever ways to do this?

    Thanks,

    Dan

  10. #10
    Plutonium Lounger
    Join Date
    Mar 2002
    Posts
    84,353
    Thanks
    0
    Thanked 29 Times in 29 Posts

    Re: Figuring out how many lines are in a paragraph (2000/XP)

    Is the following too naive?

    Sub SelectionGoUp(n As Integer)
    Selection.MoveUp Unit:=wdLine, Count:=n
    Selection.HomeKey Unit:=wdLine
    End Sub

    Example of use: SelectionGoUp 5.

    Note: if n is larger than the number of lines above the current selection, you will end up at the start of the document; you won't get an error message.

  11. #11
    2 Star Lounger
    Join Date
    Sep 2002
    Posts
    180
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Figuring out how many lines are in a paragraph (2000/XP)

    Thanks Hans! That should do it!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •