Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1550
  • Last Modified:

VBA: How to controllably scroll a Word document?

The question is how to controllably scroll a MS Word document using VBA/VB6, so that a Selection or a specified Range is positioned e.g. 2 rows (lines) or e.g. about 10% from the top of the “visible page area”? And by “visible page area” I mean the document space between the Toolbar/Ruler and the Status bar in Word.
0
npaun
Asked:
npaun
  • 9
  • 6
  • 6
  • +1
1 Solution
 
aikimarkCommented:
I think that will entail controlling the window.  Do you have some specific example or document you'd like to use for a test case?
0
 
aikimarkCommented:
It's getting late, so I'll probably turn in soon.  Play with the following statement and I'll check back in the morning.
ActiveWindow.ScrollIntoView activedocument.Range(1120),true

Open in new window

0
 
vb_elmarCommented:
Private Sub Command1_Click()
Dim o
Set o = GetObject(, "Word.Application")
'o.Selection.HomeKey Unit:=wdStory                      '... go to Top of Document
o.Selection.GoTo What:=wdGoToLine, Which:=wdGoToAbsolute, Count:=5 '... go to Line 5
o.Selection.MoveDown Unit:=wdLine, Count:=2, Extend:=wdExtend   'Highlight 2 Lines under Line5
o.ActiveWindow.ActivePane.VerticalPercentScrolled = 75          'scroll page to 75 percent
End Sub

Open in new window

0
Free Backup Tool for VMware and Hyper-V

Restore full virtual machine or individual guest files from 19 common file systems directly from the backup file. Schedule VM backups with PowerShell scripts. Set desired time, lean back and let the script to notify you via email upon completion.  

 
npaunAuthor Commented:
@aikimark
-nothing in particular, any text document is ok
-I checked your suggestion: it scrolls the document so that the page containing the specified range is in the view... I need more control... this way, the range (e.g.) selection is now on the current page, but if page is zoomed, the range often is not actually visible, because it is just out of the “visible page area” (I don't konw the official name), i.e. it would need some additional manual scrolling to get the range actually in the view...

@vb_elmar: in my test, lne 5 and 6 indeed highlight 2 lines after line5, but than, the line 7 does not scroll page to 75% but entire document to 75%, which is usually complacently different page...
======
To clarify what I need, I uploaded a picture: specify range (or selection), and then scroll the document so that the range/selection is e.g. 2 lines below the top of the “visible page area” (red line in the picture); alternately, it could be defined that the range/selection is at about 10% from the mentioned top of the “visible page area”, wher the 100% would correspond to the blue bar on the picture...

Word3.tif
0
 
aikimarkCommented:
If you offset the selection by a few lines it will nudge the display in the direction you want.
Example:
ActiveWindow.ScrollIntoView selection.Next(wdline,5), True

Open in new window

0
 
npaunAuthor Commented:
@aikimark

1) The suggested line doesn't seem to change anything: the selection is scrolled at the same place regardless if the "nudging" line present or not...

2) The other problem is that I don't know for how much would have to nudge the selection. This is because, the exact position at which the selection will be positioned seem to depend on various factors: position of selection the page (closer to top, center, bottom...), zoom level of the page, is the Word application maximized over entire screen or "restored down" so that take just a part of the screen...
For this to work, it seems I would need:
      a) To have a way to know position of the selection/range, i percent of something as the blue bar arrea in picture my previous post
      b) To have a way to move the selection for a percent of the blue bar arrea in picture in my previous post

?
Word3.tif
0
 
aikimarkCommented:
Is the selection already visible in the window when you execute the code?
0
 
npaunAuthor Commented:
it's the same if it is already visible, or not...
0
 
aikimarkCommented:
I've tried the following with different zoom settings and it does position the selection near the top of the window.  Please play with the settings until you are happy with them.
Public Sub testscroll()
    Dim lngZoom As Long
    lngZoom = ActiveWindow.View.Zoom
    ActiveWindow.ScrollIntoView ActiveDocument.Range, True
    Select Case lngZoom
        Case Is > 200
            ActiveWindow.ScrollIntoView Selection.Range, True
        Case Is >= 150
            ActiveWindow.ScrollIntoView Selection.Next(wdLine, 4), True
        Case Is >= 100
            ActiveWindow.ScrollIntoView Selection.Next(wdLine, 5), True
        Case Is >= 50
            ActiveWindow.ScrollIntoView Selection.Next(wdLine, 8), True
    End Select
End Sub

Open in new window

0
 
vb_elmarCommented:
Npaun, I saw the picture. There were exactly 2 lines above the selected text. I could simulate this 2 line spacing with the following code. But depending on "ActiveWindow.UsableHeight" (that's the usable area in the Winword window) we have to add a kind of "Yoffset". The menu bar of my Word App (Formatbar+Toolbar+Menubar) had e.g. 150 pixels of height. So in my case I had to add an Yoffset of "5". You must change that "Yoffset" (it's a Constant) depending on the height of your Winword window.

Const Yoffset = 5
Private Sub Command1_Click()
    Dim o As Object
    Set o = GetObject(, "Word.Application")
    o.ActiveWindow.VerticalPercentScrolled = 100'scroll page to the end
    o.ActiveWindow.ScrollIntoView o.Selection.Next(wdLine, Yoffset)
End Sub

Open in new window

0
 
vb_elmarCommented:
With this tool you can read the left, top, width, height of the selection (in pixels):
Private Sub Command1_Click()
Const Annotation = " [If value is negative, the selection is invisible]"
Dim o As Object
Set o = GetObject(, "Word.Application")
Dim pHgt As Long, pWid As Long, pTop As Long, pL As Long, kb723 As Long
o.ActiveWindow.GetPoint pL, pTop, pWid, pHgt, Selection.Range  'read the left,top,width,height of the selection
kb723 = o.ActiveWindow.UsableHeight - o.ActiveWindow.Height + pTop
MsgBox pTop & vbCrLf _
       & o.ActiveWindow.Height & vbCrLf _
       & o.ActiveWindow.UsableHeight & vbCrLf _
       & kb723 & Annotation
End Sub

Open in new window

0
 
npaunAuthor Commented:
@aikimark

a) We could be doing something differently, because for me it doesn't work
I’m using a test procedure, based on your suggestion:

Private Sub Test()
    Dim MyRange As Range
    Dim lngZoom As Long
   
    Set MyRange = WrdDoc.Range
    MyRange.SetRange WrdApl.Selection.Start, WrdApl.Selection.End
   
    lngZoom = ActiveWindow.View.Zoom
    ActiveWindow.ScrollIntoView ActiveDocument.Range, True
    'ActiveWindow.ScrollIntoView ActiveDocument.Range(MyRange.Start), True
   
    Select Case lngZoom
        Case Is > 200
            ActiveWindow.ScrollIntoView Selection.Range, True
        Case Is >= 150
            ActiveWindow.ScrollIntoView Selection.Next(wdLine, 4), True
        Case Is >= 100
            ActiveWindow.ScrollIntoView Selection.Next(wdLine, 5), True
        Case Is >= 50
            ActiveWindow.ScrollIntoView Selection.Next(wdLine, 8), True
    End Select
End Sub

after selecting  a word somewhere in the text, and executing a procedure, it doesn’t happen any strolling...
if I replace line
ActiveWindow.ScrollIntoView ActiveDocument.Range, True
with
ActiveWindow.ScrollIntoView ActiveDocument.Range(MyRange.Start), True
it does scroll but again, ActiveWindow.ScrollIntoView Selection.Next doesn't seem to have any effect...

b) Nevertheless, this doesn't take into account that the Word window doesn't have to be maximized, but it can be resized at any size, and the scrolling should be reliable regardless of the windows size and zoom level..
0
 
npaunAuthor Commented:
@vb_elmar
a)

This is interesting! After tests, at first, I was confused about the values for Height and UsableHeight which were not what I was expecting based on specific Word test windows, and value of kb723 was a little bit strange. And the reason is that GetPoint get position of the Selection.Range in PIXELS while the UsableHeight and Height return values in POINTS, and naturally they should not mix… so after converting units, I can made this function, which give me pretty accurate position of the selection (top) within the UsableHeight space, returning 0-1 and <0 and >1 if out of visibility

Private Function SelectionRangePosition() As Single
    Dim pHgt As Long, pWid As Long, pTop As Long, pL As Long, kb723 As Long
    WrdApl.ActiveWindow.GetPoint pL, pTop, pWid, pHgt, Selection.Range  'read the left,top,width,height of the selection
    y = (PixelsToPoints(pTop) - WrdApl.ActiveWindow.Top - (WrdApl.ActiveWindow.Height - WrdApl.ActiveWindow.UsableHeight - PixelsToPoints(22))) / WrdApl.ActiveWindow.UsableHeight
    SelectionRangePosition = y
End Function

b) Ok, that solves half of the problem, knowing pretty much exact position of the selection.
Now, in order I can use that information, I need a way to scroll the document for a specified number of pixels or points. Do you know, how to do that?
0
 
aikimarkCommented:
You might try bookmarks
ActiveDocument.Bookmarks.Add "Q_28509255",selection
ActiveDocument.GoTo what:=wdGoToBookmark, name:="Q_28509255"
ActiveDocument.Bookmarks.Item("Q_28509255").Delete

Open in new window


Although the GoTo method shows promise, I'm not convinced that it gives you the granularity that you seek.
selection.GoTo what:=wdGoToLine,which:=wdGoToAbsolute, count:=77

Open in new window

0
 
vb_elmarCommented:
I've tested this. This makes exactly 2 lines spacing above the selected text.
Private Sub Command1_Click()
    Const Yoffset = 2
    Dim o As Object
    Set o = GetObject(, "Word.Application")
    o.Application.ScreenUpdating = False
    o.ActiveWindow.VerticalPercentScrolled = 100 'scroll page to the end
    o.ActiveWindow.ScrollIntoView o.Selection.Previous(wdLine, Yoffset)
    o.Application.ScreenUpdating = True
    o.Activate
End Sub

Open in new window

0
 
npaunAuthor Commented:
@vb_elmar
a) maybe we are somehow doing tests differently, but this code simply does not work like that in my tests… To me, the selection is positioned somewhere at upper third of the UsableHeight. If the Word is maximized, it is positioned at 12th row, but if it is not maximized but in “normal” state, then it is positioned at some other row from top edge, depending on current Word window size… and even if is maximized, the exact number of rows changes somewhat with the current screen resolution… and all that is not good…
b) I simply don’t understand the behavior of the ScrollIntoView method… based on
http://msdn.microsoft.com/en-us/library/ff836655%28v=office.14%29.aspx
it says “True if the UPPER-LEFT CORNER OF THE RANGE or shape appears at the UPPER-LEFT CORNER OF THE DOCUMENT WINDOW”
so I interpret that line
oWrdApl.ActiveWindow.ScrollIntoView Selection.Range, True

should neatly align the top edge of the current selection with the top edge of the document window, i.e. the red line in my previous picture?! But, in reality it DOES NOT do that?! It positions selection in the upper third of the document, at 10th row, and that changes depending on the windows size, while from the MSDN, it should be always be on the upper-left corner, regardless of the window state…

If it would behave as MSDN stated, then your line o.ActiveWindow.ScrollIntoView o.Selection.Previous(wdLine, Yoffset) should elegantly offset the selection Yoffset rows from the top, and the problem would be solved. But, at least for me, it doesn’t work like that, and I don’t understand why…

c) o.ActiveWindow.VerticalPercentScrolled = 100 'scroll page to the end

this scrolls to the end of the entire document, not to the end of page as stated in the comment

d) My test show that the procedure gets the exact same result if o.ActiveWindow.VerticalPercentScrolled = 100 is commented?

e) What is the purpose of that line in your example?

Thanks
0
 
npaunAuthor Commented:
@vb_elmar
any help regarding my last post?
0
 
vb_elmarCommented:
@npaun
the ScrollIntoView method seems to cause different results depending on such parameters as:
1) which zoom is used
2) is normal view or page layout used?
3) which is the current screen resolution
To find out how the ScrollIntoView method works I think we have to collect some sample screenshots or sample data. Because of this I made a wiki http://officevba.wikispaces.com. It is intended from me that anyone can add pages there. -So, npaun feel free to add comments, tables and images on the website. If we will have collected 10 or 20 sample screenshots we will be able (I hope) to trace back how the ScrollIntoView method works exactly.
0
 
npaunAuthor Commented:
@vb_elmar
Thanks. I'll see to do it.
Again, to just shortly return to my last post, did I correctly understend the MSDN statment and example, that according the MSDN the ScrollIntoView example should align top of the selection with top of the "UsableHeight"? But from some reason, it doesn't behave in that way?
0
 
vb_elmarCommented:
I think the MSDN statement is simply false.
0
 
npaunAuthor Commented:
thanks
0
 
Martin LissRetired ProgrammerCommented:
I've requested that this question be deleted for the following reason:

Not enough information to confirm an answer.
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 9
  • 6
  • 6
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now