Consulting

Results 1 to 16 of 16

Thread: Advice: Line and Paragraph Numbers - Reading into VBA

  1. #1

    Advice: Line and Paragraph Numbers - Reading into VBA

    Hello all -- from someone who's comortable (sort of) around Excel VBA but feeling a trifle unsettled by some of Word's (2000) differences

    This is one that I'm sure is staring me in the face somewhere since setting the following is obvious enough. But reading it? ...

    OK, is there a ready way to return an absolute Word line number or paragraph number (either will do) to a VBA variable --

    1. for the current cursor location (or current selection), and

    2. for a nominated bookmark (without going to it) ?

    FWIW my end purpose is to limit code execution to within defined regions of a document.


    Thanks in advance,

    Mike

  2. #2
    Just A Dude VBAX Tutor Scottie P's Avatar
    Joined
    May 2004
    Location
    Remote from 18901 USA
    Posts
    263
    Location
    Hi Mike! Welcome to VBAX!


    Perhaps I am reading you wrong but lets take a shot at the bookmark part.
    Are you saying to address the bookmark in VBA? If so, it would be something like [VBA]
    ActiveDocument.Bookmarks("MikesBkMk").Range
    [/VBA]

    so that we can prescribe an action involving the bookmark of choice?

    Sorry if I am off the course here.

    Scott
    Life is Visual: Presence is Perception...
    How we see the world is how we respond to it. ~* Peace *~

  3. #3
    VBAX Tutor
    Joined
    May 2004
    Location
    Germany, Dresden
    Posts
    217
    Location

    Post

    Hi Mike,

    getting the line number should be easy enough (at least once you know where to look for it ):

    [VBA]
    MsgBox ActiveDocument.Bookmarks("tm_Test").Range.Information(wdFirstCharacterLineN umber)[/VBA]
    or (for the cursor location)
    [VBA]
    MsgBox Selection.Range.Information(wdFirstCharacterLineNumber)
    [/VBA]

    Getting the paragraph number is a bit more difficult as there is no such function in Word :
    [VBA]
    Function GetParNum(r As Range) As Integer
    Dim rParagraphs As Range
    Dim CurPos As Integer

    r.Select
    CurPos = ActiveDocument.Bookmarks("\startOfSel").Start
    Set rParagraphs = ActiveDocument.Range(Start:=0, End:=CurPos)
    GetParNum = rParagraphs.Paragraphs.Count
    End Function
    [/VBA]

    Call this one the following way for the cursor position:
    [VBA] MsgBox GetParNum(Selection.Range)[/VBA]

    And for the bookmark:
    [VBA]
    MsgBox GetParNum(ActiveDocument.Bookmarks("tm_Test").Range)
    [/VBA]

    Greets
    Daniel
    Last edited by Steiner; 06-16-2004 at 11:03 PM. Reason: The VBA-Code lines looked too ugly (formatting??)

  4. #4
    Quote Originally Posted by Scott
    Hi Mike! Welcome to VBAX!


    Perhaps I am reading you wrong but lets take a shot at the bookmark part.
    Are you saying to address the bookmark in VBA? If so, it would be something like [VBA]
    ActiveDocument.Bookmarks("MikesBkMk").Range
    [/VBA]

    so that we can prescribe an action involving the bookmark of choice?

    Sorry if I am off the course here.

    Scott
    Thanks Scott, however I don't want to operate on the bookmarks themselves, but constrain different text cleanup regimens to growing amounts of text that are either located between 2 bookmarks, or else follow the second one. And since they can float, I need to identify where the bookmarks are positioned at the current revision state of the document, and then test that the text to be subjected to a Replace operation (for example) is located somewhere in between them.

    Anyway, it would seem that Steiner's illustration of the "Information" property is going to be the key to it.

    Thanks again,

    Mike

  5. #5
    Hi Daniel,

    Thanks for this -- the Information property looks like doing what I want. As you mention, knowing where to look is the gimmick. I'd actually tried "linenumber" in Help, and of course no prizes for guessing that it's unsearchable...

    Quote Originally Posted by Steiner
    Hi Mike,

    getting the line number should be easy enough (at least once you know where to look for it ):

    ...snip...

    Getting the paragraph number is a bit more difficult as there is no such function in Word :

    ...snip...

    Greets
    Daniel
    Again, no real surprises at the end of the day. Just another of those "any app. designer with half a brain couldn't possibly have left THAT out, so it must be ME" things

    Speaking of which, I've so far discovered that "Information(wdFirstCharacterLineNumber)" returns the line number relative to the current page, so I'll have to extract the page number as well. Simple enough now that you've pointed me to the relevant property list which contains other useful resources.

    But since it's possible to put an absolute (from the start of the document) line number into the GoTo [count] argument, logic suggests that there should also exist, under some rock or another, a property that will likewise return the absolute number. But then using "logic" and "Microsoft" in the same breath does tend to expose one to ridicule...

    As noted, I can look at both the page and line numbers but, just out of curiosity, does a property exist that holds the absolute number?

    Thanks again,

    Mike

  6. #6
    VBAX Tutor
    Joined
    May 2004
    Location
    Germany, Dresden
    Posts
    217
    Location
    Absolute line number ... yepp thanks MS, I guess will have to write my own function again :

    [VBA]
    Function GetAbsoluteLineNum(r As Range) As Integer
    Dim i1 As Integer, i2 As Integer, Count As Integer

    r.Select
    Do
    i1 = Selection.Information(wdFirstCharacterLineNumber)
    Selection.GoTo what:=wdGoToLine, which:=wdGoToPrevious, Count:=1, Name:=""
    Count = Count + 1
    i2 = Selection.Information(wdFirstCharacterLineNumber)
    Loop Until i1 = i2

    r.Select
    GetAbsoluteLineNum = Count
    End Function

    [/VBA]

    Now this one is really crude, but at least it seems to work. Just call it the same way as you did with the last ones.

    @Dreamboat & Co:
    Should you ever read this, could these small functions be worth adding to the KB?

  7. #7
    Site Admin
    The Princess
    VBAX Guru Anne Troy's Avatar
    Joined
    May 2004
    Location
    Arlington Heights, IL
    Posts
    2,530
    Location
    ALL things that one might use should be added to the KB. I try to use what I feel might be searched keywords in either the Title of the entry or in the description. The answer is "definitely!"

    ~Anne Troy

  8. #8
    Just A Dude VBAX Tutor Scottie P's Avatar
    Joined
    May 2004
    Location
    Remote from 18901 USA
    Posts
    263
    Location
    Mike, my apologies for misreading you at first - as soon as Daniel posted I realized that you were working outside of the bookmarks (using them only as reference points to define actions between...and not inclusive).

    I find that the Help file for Word 2000 is not as helpful as it could be - and the MVP site really had nothing comprehensive available (though I am sure that it is probably in there somewhere...if one could only find it )

    Steiner, nice function! And thanks for putting that info together in your previous post; I am sure it will be helpful.

    Scott
    Life is Visual: Presence is Perception...
    How we see the world is how we respond to it. ~* Peace *~

  9. #9
    VBAX Master TonyJollans's Avatar
    Joined
    May 2004
    Location
    Norfolk, England
    Posts
    2,291
    Location

    But then using "logic" and "Microsoft" in the same breath does tend to expose one to ridicule...

    ROFL - so true!!

    AFAIK there is no direct way to obtain an absolute line number. Gerry (fumei) will probably come up with something I don't know - he usually does - but, till then, this will give you the number of lines between the start of the document and the selection:

    [VBA]
    ActiveDocument.Range(0, Selection.Start).ComputeStatistics(wdStatisticLines)
    [/VBA]

    The one problem with this is that if the Selection is at the start of a line, the number will not include that line, so a correction is needed for that, giving ..

    [VBA]ActiveDocument.Range(0, Selection.Start).ComputeStatistics(wdStatisticLines) _
    - (ActiveDocument.Bookmarks("\Line").Start = Selection.Start)[/VBA]
    Enjoy,
    Tony

    ---------------------------------------------------------------
    Give a man a fish and he'll eat for a day.
    Teach him how to fish and he'll sit in a boat and drink beer all day.

    I'm (slowly) building my own site: www.WordArticles.com

  10. #10
    VBAX Wizard
    Joined
    May 2004
    Posts
    6,713
    Location
    Thanks Tony, but I don't think I can do any better.

    I am not not sure I followed all of this. If the idea was to determine, or identify, if text is between bookmarks, as part of a clean up routine, could you not just use the .End of the first bookmark, and the .Start of the second?

    The current location can in fact be determined:

    Dim CurPos as Long
    CurPos = Selection.Range.Start

    This can also apply to the location of the bookmarks. Therefore you can test, by number, the range between them.

    Here is some long winded code (as I am sure Tony will find) , that determines if the current location is between two bookmarks.

    [vba]Sub InRange()
    Dim aDoc As Document
    Dim pos1 As Long
    Dim pos2 As Long
    Dim CurPos As Long
    Dim bolRightHere As Boolean

    Set aDoc = ActiveDocument
    pos1 = aDoc.Bookmarks("startme").End
    pos2 = aDoc.Bookmarks("endme").Start
    CurPos = Selection.Range.Start

    bolRightHere = CurPos > pos1 And _
    CurPos < pos2
    If bolRightHere = True Then
    MsgBox "Current location is: " & CurPos & vbCrLf & _
    "This is within the defined input range." & vbCrLf & _
    "Start= " & pos1 & ", End = " & pos2
    Else
    MsgBox "Current location is: " & CurPos & vbCrLf & _
    "This is outside of the defined input range ." & vbCrLf & _
    "Start= " & pos1 & ", End = " & pos2
    End If
    Set aDoc = Nothing
    End Sub[/vba]
    Last edited by fumei; 06-18-2004 at 06:28 PM.

  11. #11
    VBAX Wizard
    Joined
    May 2004
    Posts
    6,713
    Location
    Oh, you may also want to collapse the selection first. While the code uses Selection.Start (which is not going to change - the start is the start), there may be issues in your clean up routines if the Selection.End is beyond the range you want to work with.

    Not likely, but hey, it is that error trapping thing.

  12. #12
    VBAX Wizard
    Joined
    May 2004
    Posts
    6,713
    Location
    Sorry, not together at all. My point was that you can determine ANY location by absolute number from the start of the document.

    Dim r As Range
    Set r = ActiveDocument.Range(Start:=672, End:=1236)
    r.Select

    will make the selection everything between the 672nd character, and the 1236th character. These were the absolute numbers for pos1 and pos2 in my test document. Of course, it is kind of dumb to use actual numbers since those locations can move. However, you certainly could determine the numbers at run time, and then use them. Say to grab a range except for the first three characters. Just increase the number of Start by 3.

  13. #13

    Thanks folks!

    Thanks to all who've thrown in ideas on this. You've given me plenty of very useful material to work with. Much appreciated!

    Mike Fitzgerald

  14. #14
    VBAX Wizard
    Joined
    May 2004
    Posts
    6,713
    Location
    Just reading back through this. Was it clear that the absolute number for ANY location, be it the Selection, a Range, a Bookmark - anything that uses a range, is very easy.

    object.Range.Start gives the absolute number as Long. "Absolute" meaning the way Word counts, that is, by character. Duly noting that InlineShapes are counted as 1 character.

  15. #15
    Quote Originally Posted by Steiner
    Hi Mike,

    getting the line number should be easy enough (at least once you know where to look for it ):

    [VBA]
    MsgBox ActiveDocument.Bookmarks("tm_Test").Range.Information(wdFirstCharacterLineN umber)[/VBA]
    or (for the cursor location)
    [VBA]
    MsgBox Selection.Range.Information(wdFirstCharacterLineNumber)
    [/VBA]

    Getting the paragraph number is a bit more difficult as there is no such function in Word :
    [VBA]
    Function GetParNum(r As Range) As Integer
    Dim rParagraphs As Range
    Dim CurPos As Integer

    r.Select
    CurPos = ActiveDocument.Bookmarks("\startOfSel").Start
    Set rParagraphs = ActiveDocument.Range(Start:=0, End:=CurPos)
    GetParNum = rParagraphs.Paragraphs.Count
    End Function
    [/VBA]

    Call this one the following way for the cursor position:
    [VBA] MsgBox GetParNum(Selection.Range)[/VBA]

    And for the bookmark:
    [VBA]
    MsgBox GetParNum(ActiveDocument.Bookmarks("tm_Test").Range)
    [/VBA]

    Greets
    Daniel
    For Steiner: Greatly appreciate your GET PARAGRAPH NUMBER function - Many thanks: I've been looking for this solution for over a year! HOWEVER, I think it has one small but significant flaw: If the cursor is at the very start of a paragraph you get the previous paragraph number. You can see that by testing the same function at the start of the paragraph and one character to the right of the start.
    This can be solved by adding "+1" at the end of the fifth line, i.e.:
    CurPos = ActiveDocument.Bookmarks("\startOfSel").Start + 1
    I hope you agree.
    Lee

  16. #16
    Quote Originally Posted by Steiner
    Hi Mike,

    getting the line number should be easy enough (at least once you know where to look for it ):

    [VBA]
    MsgBox ActiveDocument.Bookmarks("tm_Test").Range.Information(wdFirstCharacterLineN umber)[/VBA]
    or (for the cursor location)
    [VBA]
    MsgBox Selection.Range.Information(wdFirstCharacterLineNumber)
    [/VBA]

    Getting the paragraph number is a bit more difficult as there is no such function in Word :
    [VBA]
    Function GetParNum(r As Range) As Integer
    Dim rParagraphs As Range
    Dim CurPos As Integer

    r.Select
    CurPos = ActiveDocument.Bookmarks("\startOfSel").Start
    Set rParagraphs = ActiveDocument.Range(Start:=0, End:=CurPos)
    GetParNum = rParagraphs.Paragraphs.Count
    End Function
    [/VBA]

    Call this one the following way for the cursor position:
    [VBA] MsgBox GetParNum(Selection.Range)[/VBA]

    And for the bookmark:
    [VBA]
    MsgBox GetParNum(ActiveDocument.Bookmarks("tm_Test").Range)
    [/VBA]

    Greets
    Daniel
    For Steiner: Greatly appreciate your GET PARAGRAPH NUMBER function - Many thanks: I've been looking for this solution for over a year! HOWEVER, I think it has one small but significant flaw: If the cursor is at the very start of a paragraph you get the previous paragraph number. You can see that by testing the same function at the start of the paragraph and one character to the right of the start.
    This can be solved by adding "+1" at the end of the fifth line, i.e.:
    CurPos = ActiveDocument.Bookmarks("\startOfSel").Start + 1
    I hope you agree.
    Lee

Posting Permissions

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