Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
DiscussionsAccessExcelInfoPathOutlookPowerPointPublisherWord
DirectoryUser Groups
Related Topics
Outlook ExpressInternet ExplorerWindowsMS Server ProductsMore Topics ...

MS Office Forum / Word / Programming / December 2006

Tip: Looking for answers? Try searching our database.

Efficient line walking

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
J - 09 Dec 2006 02:31 GMT
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
----------------------------------------------------
ViEmu - http://www.viemu.com - vi/vim emulation for Visual Studio
Helmut Weber - 09 Dec 2006 13:05 GMT
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

Signature

Greetings from Bavaria, Germany

Helmut Weber, MVP WordVBA

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

J - 09 Dec 2006 16:33 GMT
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
----------------------------------------------------
ViEmu - http://www.viemu.com - vi/vim emulation for Visual Studio
Jezebel - 09 Dec 2006 20:22 GMT
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.

> Hello everyone,
>
[quoted text clipped - 25 lines]
> ----------------------------------------------------
> ViEmu - http://www.viemu.com - vi/vim emulation for Visual Studio
Helmut Weber - 09 Dec 2006 20:37 GMT
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

Signature

Greetings from Bavaria, Germany

Helmut Weber, MVP WordVBA

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

J - 09 Dec 2006 20:53 GMT
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
----------------------------------------------------
ViEmu - http://www.viemu.com - vi/vim emulation for Visual Studio
J - 09 Dec 2006 20:51 GMT
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
----------------------------------------------------
ViEmu - http://www.viemu.com - vi/vim emulation for Visual Studio
Jonathan West - 09 Dec 2006 22:36 GMT
> 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.

Signature

Regards
Jonathan West - Word MVP
www.intelligentdocuments.co.uk
Please reply to the newsgroup

 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.