PDA

View Full Version : [SOLVED:] How do I move to first and Last lines on a page column?



MacOCD
09-15-2017, 09:54 AM
Using Office 2011 on Mac (But VBA is pretty much the same)

For Context
I've created some large 2 column song lists for my karaoke (currently 108 pages) that I wish to modify with VBA to make sure each column on each page begins with an Artist Name (or Artist Name - Continued) and ends with either a Song Title or Blank Line.

20357


I've worked out how to do all I need except jump to the first and last lines in a column. or detect whether the currently selected line is the first or last line in a column.


The Problem
Using VBA For each page I need to be able to go to:

Column1 First Line on Page
Column1 Last Line on Page
Column2 First Line on Page
Column2 Last Line on Page

then make edits/insertions/deletion as required.

I've tried using


Selection.HomeKey Unit:=wdColumn

Selection.EndKey Unit:=wdColumn


I get an error message:

Run-time error '4605':

This method or property is not available because some or all of the object does not refer to a table.

Selection.Homekey works with the Unit:= wdStory or wdLine, but it appears that wdColumn can only refer to a column within a table? I don't wish to use tables and I need every last millimetre of space on the page with the amount of information I need on each line, also the source data would be very difficult to load into a table.

How to I move to the first and last lines in a word page column?

Thanks,

Mark.

macropod
09-15-2017, 05:46 PM
If you want to select the entire current page, simply use:

Sub Demo()
Selection.GoTo what:=wdGoToBookmark, Name:="\page"
End Sub
With that, you can do whatever you want with the first & last 'lines' - not that you actually need to select anything for that purpose.

MacOCD
09-16-2017, 04:09 AM
If you want to select the entire current page, simply use:

Sub Demo()
Selection.GoTo what:=wdGoToBookmark, Name:="\page"
End Sub
With that, you can do whatever you want with the first & last 'lines' - not that you actually need to select anything for that purpose.

Thank you for the reply. I did actually also try the Selection.Goto approach, but that gives me the entire page's text as my selection. It'll probably help with finding the text in the first & last lines of each PAGE, but it doesn't allow me to discover what the text in the last line of the first COLUMN on each page is, and make my changes based on that.

In my original example the first line of column 2 needs to be either the "ARTIST NAME" or "ARTIST NAME - CONTINUED" I can work out the artist's information based on the last occurrence of an Artist's name, where that is relative to the first line of column 2, have been any other songs by that artist at the bottom of column 1 etc.

Selecting only the text in the bottom line/row of column 1, or in the first line of column 2, is what I'm trying to figure out, I can move around from that insertion point and I think I can do everything else I need to.

Thanks again,
Mark.

gmayor
09-16-2017, 05:31 AM
Although aimed at pages rather than columns, http://www.gmayor.com/catchwords.htm may be helpful.

MacOCD
09-16-2017, 06:54 AM
gmayor

Unfortunely not, I have differing things I need to do with the text at the top and bottom of each column depending on what the content is

At the bottom of each column
If the last line is a song title I need to discover what artists name was, then insert a line AFTER that (top of next column/page) with "ARTIST NAME - CONTINUED"

At the top of each column
If the first line is a blank line then delete it

You'd think it's be easy to move to the end of a column in Word with VBA, but I'm beginning to think it's not possible.

The only "Solution" I have currently is to always stick to the same font & size and know that there are 63 lines possible per column, then check the contents of line 63 (and each multiple of) and act accordingly. This however isn't ideal as I really wanted to have the Artist names in a different font & size. I also wanted to make blank lines between artists have a lower height that lines with information on them, that's not possible when each line has to be the same height to maintain 63 lines per column. Also sometimes I like to print in a larger font for older people to be able to read the list or easily.

Thanks anyway,
Mark.

macropod
09-16-2017, 11:17 PM
Perhaps something based on:

Sub Demo()
Dim i As Long, j As Long
i = Selection.Information(wdActiveEndAdjustedPageNumber)
With ActiveDocument.ActiveWindow.Panes(1).Pages(i)
For j = 1 To .Rectangles.Count
With .Rectangles(j).Range.Paragraphs
MsgBox .First.Range.Text & vbCr & .Last.Range.Text
End With
Next
End With
End Sub

MacOCD
09-18-2017, 07:54 AM
I couldn't get your macro to work Paul, I got:

Compile error:

Method or data member not found.

I have actually solved the problem now using Selection.Information(wdVerticalPositionRelativeToPage)

I just check the vertical position of each line and when the value reduces I know I've changed to another column or page :)

Slow running Macro, but does the job.

Thanks to Paul & everyone else for your efforts.
Mark.

macropod
09-18-2017, 01:12 PM
Perhaps Macs don't support the Rectangles property.

MacOCD
09-18-2017, 03:38 PM
Perhaps Macs don't support the Rectangles property.

Could be, I have found the odd function that doesn't behave as expected previously. Status bar notifications spring to mind, it'd be great to know that my macro (that can take 40 min
+ to run) hasn't frozen. I've used it on PCs previously, but now we're all Macs it doesn't work as expected.

macropod
09-18-2017, 09:41 PM
Try something based on:

Sub Demo()
Application.ScreenUpdating = False
Dim p As Long, l As Long, RngPg As Range, RngLn As Range
Dim vPos As Single
With ActiveDocument
For p = 1 To .ComputeStatistics(wdStatisticPages)
' Point to the pages we want to process
Set RngPg = .Range.GoTo(What:=wdGoToPage, Name:=p)
Set RngPg = RngPg.GoTo(What:=wdGoToBookmark, Name:="\page")
With RngPg
If .PageSetup.TextColumns.Count > 1 Then
'vPos = 0
' Point to the lines we want to process
For l = 1 To .ComputeStatistics(wdStatisticLines)
Set RngLn = RngPg.GoTo(What:=wdGoToLine, Which:=wdGoToRelative, Count:=l)
With RngLn
If .Information(wdVerticalPositionRelativeToTextBoundary) < vPos Then
' We've found the start of a new column.
.MoveEnd Unit:=wdWord, Count:=1
.MoveStart Unit:=wdWord, Count:=-1
' We now have the last word in the previous column plus the first word in our column,
' so now we can do whatever further processing is required.
MsgBox RngLn.Text
End If
vPos = .Characters.Last.Information(wdVerticalPositionRelativeToTextBoundary)
End With
Next
End If
End With
Next
End With
Application.ScreenUpdating = True
End Sub
Note the comment-out 'vPos = 0' line. Uncommenting it means the code will only consider the column changes within the page.