Efficient line walking

J

J

Hello everyone,

I need to implement efficient "line-walking" within Word.

Walking efficiently by paragraphs took a while to get right, but I was able
to: after a few trials, I found out that the best way was to use Range.Next()
with args (wdParagraph, 1), and use the returned range.

Using the story range's paragraphs was really slow, where it seems every
direct item access involved completely walking the range for every call. But
Range.Next(wdParagraph) fixed. it.

But no, for actual "visual" lines, this doesn't work. I'm using
Range.Goto(wdGoToLine, wdGotoRelative, 1), but it's still very slow.
Range.Next() ain't usable for lines.

Any suggestions for a fast way to walk all lines in a document?

BTW, the goal is the underlying layer on top of which to iimplement my
vi/vim emulator. It's already working, but it's pretty slow.

Thanks and best regards,

- Jon
 
H

Helmut Weber

Hi J,

ranges aren't *always* faster than the selection,
especially if you process all of the doc,
and set screenupdating to false.

Still, most often they are.

For a doc with 1000 lines,
this one takes 1.2 seconds, here and now.

Option Explicit
Public Declare Function GetTickCount Lib "kernel32" () As Long

Sub WalklineA()
Dim t As Long ' time
ActiveDocument.Range(0, 0).Select
Application.ScreenUpdating = False
t = GetTickCount
With selection
While .Range.End <> ActiveDocument.Range.End - 1
.Bookmarks("\line").Select
.MoveDown unit:=wdLine
Wend
End With
MsgBox (GetTickCount - t) / 1000 ' 1.2xxx
selection.HomeKey unit:=wdLine
MsgBox selection.Bookmarks("\line").Range.Text ' last line
End Sub

HTH

--
Greetings from Bavaria, Germany

Helmut Weber, MVP WordVBA

Win XP, Office 2003
"red.sys" & Chr$(64) & "t-online.de"
 
J

J

Hi Helmut,

Thanks a lot for your help. I have yet to try it, but I think your timings
are in the ballpark of what I'm getting with my previous method: 2.5 seconds
to scan a 4 page, 180 paragraphs, 1,500 lines document. It's too slow for my
needs - since Word doesn't provide a "TextChanged" event, I need to do this
scan very often (at every keypress). Paragraph scanning is fast enough (about
400ms tops for a 21 page, 600 paragraphs document).

I will do more detailed timing analysis to tell exactly where this time is
going, try to scan less than the whole file for each keypress, and possibly
even try to avoid the full-lines scanning need altogether.

I'll post my results here, in case anyone runs into the same type of trouble.

Best regards,

- Jon
 
J

Jezebel

Have you tried going directly to the pages/lines collections? I don't know
whether this will be faster, and it has some additional complications, but
experiment with --

with activedocument.ActiveWindow.Panes(1)
For i = 1 to .Pages.Count
for j = 1 to .pages(i).Rectangles(1).Lines.count
... [do whatever with] .pages(i).Rectangles(1).Lines(j)
Next
Next
Eng With

The complication is knowing which rectangle to use: there will be more than
one if your page has headers and footers (amongst other things) and the
rectangle containing the body text isn't necessarily the first.
 
H

Helmut Weber

Hi Jezebel,

Sub WalklineJezebel()
Dim t As Long ' time
Dim s As String
Dim i As Long
Dim j As Long
t = GetTickCount
With ActiveDocument.ActiveWindow.Panes(1)
For i = 1 To .Pages.Count
For j = 1 To .Pages(i).Rectangles(1).Lines.Count
s = .Pages(i).Rectangles(1).Lines(j).Range.Text
Next
Next
End With
MsgBox (GetTickCount - t) / 1000 ' = 0.17xx
End Sub

Yes, gets it down to 0.17

--
Greetings from Bavaria, Germany

Helmut Weber, MVP WordVBA

Win XP, Office 2003
"red.sys" & Chr$(64) & "t-online.de"
 
J

J

Thanks Jezebel, I didn't even know about the Rectangles collection, so it
will let me experiment with more approaches.

Thanks a lot and best regards,

- Jon
 
J

J

Thanks Helmut, that certainly proves the speed is up to par. Now my only
other gotcha is to get the proper mapping between range indices and lines (I
have the mapping to paragraphs separately), but hopefully it will be doable.

Thanks again a lot to both of you for helping me out!! Let me know if you're
interested in using vi/vim emulation.

In any case, I will post what I end up doing with the issue, hopefully
during this next week.

Best regards,

- Jon
 
J

Jonathan West

J said:
Thanks Jezebel, I didn't even know about the Rectangles collection, so it
will let me experiment with more approaches.

Beware, it is relatively new - it only became available in Word 2003, and so
is no use if you still need to support older versions of Word.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top