Set Range to be Footnotes on the Current Page

J

John HB

Hello,

I am new to VBA programming - thank you for your help in advance.

I would like to set a Range to be the footnotes on a given page. For
example, in this loop:

For var = 1 To intPageCount
Set oRange = ActiveDocument.Range(0, 0)
Set oRange = oRange.GoTo(What:=wdGoToPage, Name:=var)
Set oRange = oRange.GoTo(What:=wdGoToBookmark, Name:="\page")
If oRange.Revisions.Count > 0 Then [print page]


oRange cycles through each page. The purpose of this is that I can then see
if there are any revisions on a given page, and if there are, print the page
(hence the macro only prints pages with revisions on).

However, sometimes there are revisiosn in a footnote on a page, and no
revisions in the text on that page, and that page wouldn't be printed. So
effectively, I need to be able to set the range to be the footnote text on a
given page, if there is any.

Any advise would be much appreciate
 
D

Doug Robbins - Word MVP

The following code will print out the pages on which there are revisions,
whether they are in the main body of the document or the footnotes:

Dim pnum As Long
Dim i As Long
Dim j As Long
Dim flag As Boolean
Dim arev As Revision
Dim revpages As String
Dim revarray As Variant
revpages = ""
pnum = 0
Dim astory As Range
For Each astory In ActiveDocument.StoryRanges
For Each arev In astory.Revisions
i = arev.Range.Information(wdActiveEndPageNumber)
If i <> pnum Then
pnum = i
If Not IsEmpty(revarray) Then
flag = False
For j = 0 To UBound(revarray)
If i = revarray(j) Then
flag = True
End If
Next j
If flag = False Then
revpages = revpages & "," & i
End If
Else
revpages = revpages & i
End If
revarray = Split(revpages, ",")
End If
Next arev
Next astory
ActiveDocument.PrintOut Range:=wdPrintRangeOfPages, Pages:=revpages


--
Hope this helps.

Please reply to the newsgroup unless you wish to avail yourself of my
services on a paid consulting basis.

Doug Robbins - Word MVP, originally posted via msnews.microsoft.com
 
J

John HB

Doug,

This is incredible helpful, thank you. A few questions:

1) If I understand correctly, this will list all the pages with changes in
the main text, and then all the pages with changes in the footnotes, so the
pages will print out of order. This isn't ideal.

2) If a revision splits across more than one page (i.e., starts on page 2,
goes to page 3), I think this will only print page 3?

3) If a document has multiple sections (and pages that restart numbering in
each section), I think the code will not quite return the pages that word
needs to print - i.e., I guess it needs to return something like s1p1,s3p1,
unles theres a way of making word print absolute page numbers?)

4) In a long document, there can easily be more than 100 pages with changes,
and if the string is more than 256 characters, word can't print. I found
something on the MVP site to handle this I think, along the lines of:

If Len(revpages) <= 256 Then
With Dialogs(wdDialogFilePrint)
.Pages = revpages
.Range = wdPrintRangeOfPages
.Show
End With
Else

Do While Len(revpages) > 256
PagesToPrintChunk(k) = Left$(revpages, 256)
Pos = InStrRev(PagesToPrintChunk(k), ",")
PagesToPrintChunk(k) = Left$(PagesToPrintChunk(k), Pos - 1)
revpages = Mid$(revpages, Pos + 1)
k = k + 1
Loop
PagesToPrintChunk(k) = revpages

which makes an array of pages needing printing. I also came up with some
code that builds the revpages array to include -s if multiple pages next to
each other need printing, which shorten it somewhat.

5) In a document that has 1000s of revisions, might it be better to use my
mehtod of going from page to page and seeing if there is 0 or more than 0
revisioins, and deciding if to print that page? Then the loop would be
limited to the number of pages, not checking which page each revision is on?
That's why, if it's possible to somehow set the range to be the footnotes of
the page the rnage is on, if there are any, I think it might be a little
quicker.

Any advice on the above points wouild be much appreciated on the above points.

Thanks!
John


Doug Robbins - Word MVP said:
The following code will print out the pages on which there are revisions,
whether they are in the main body of the document or the footnotes:

Dim pnum As Long
Dim i As Long
Dim j As Long
Dim flag As Boolean
Dim arev As Revision
Dim revpages As String
Dim revarray As Variant
revpages = ""
pnum = 0
Dim astory As Range
For Each astory In ActiveDocument.StoryRanges
For Each arev In astory.Revisions
i = arev.Range.Information(wdActiveEndPageNumber)
If i <> pnum Then
pnum = i
If Not IsEmpty(revarray) Then
flag = False
For j = 0 To UBound(revarray)
If i = revarray(j) Then
flag = True
End If
Next j
If flag = False Then
revpages = revpages & "," & i
End If
Else
revpages = revpages & i
End If
revarray = Split(revpages, ",")
End If
Next arev
Next astory
ActiveDocument.PrintOut Range:=wdPrintRangeOfPages, Pages:=revpages


--
Hope this helps.

Please reply to the newsgroup unless you wish to avail yourself of my
services on a paid consulting basis.

Doug Robbins - Word MVP, originally posted via msnews.microsoft.com
John HB said:
Hello,

I am new to VBA programming - thank you for your help in advance.

I would like to set a Range to be the footnotes on a given page. For
example, in this loop:

For var = 1 To intPageCount
Set oRange = ActiveDocument.Range(0, 0)
Set oRange = oRange.GoTo(What:=wdGoToPage, Name:=var)
Set oRange = oRange.GoTo(What:=wdGoToBookmark, Name:="\page")
If oRange.Revisions.Count > 0 Then [print page]


oRange cycles through each page. The purpose of this is that I can then
see
if there are any revisions on a given page, and if there are, print the
page
(hence the macro only prints pages with revisions on).

However, sometimes there are revisiosn in a footnote on a page, and no
revisions in the text on that page, and that page wouldn't be printed. So
effectively, I need to be able to set the range to be the footnote text on
a
given page, if there is any.

Any advise would be much appreciate
 
G

Graham Mayor

I spotted your query yesterday afternoon, just before I packed up for the
day and didn't have time to test my approach to the problem, and as Doug had
answered the question this morning I didn't bother to contribute; however I
think that my approach addresses all your concerns. The macro looks for any
revisions on the page or in the footnotes and prints just one copy of the
page in the order in which it appears in the document. Any page that has a
revision carried over from the previous page will also print.. It does not
matter whether there are sections in teh document as the macro processes the
current page.


Sub PrintRevisions()
Dim oRng As Range
Dim i, j As Long
Dim iPageCount As Long
Selection.EndKey wdStory
iPageCount = Selection.Information(wdActiveEndPageNumber)
For i = 1 To iPageCount
Selection.GoTo what:=wdGoToPage, name:=i
Set oRng = Selection.Bookmarks("\page").Range
For j = 1 To oRng.Footnotes.Count
If oRng.Footnotes(j).Range.Revisions.Count <> 0 Then
'MsgBox "Revisions in footnotes on page " & i
ActiveDocument.PrintOut Range:=wdPrintCurrentPage
GoTo NextPage
End If
Next j
If oRng.Revisions.Count > 0 Then
'MsgBox "Revisions on page " & i
ActiveDocument.PrintOut Range:=wdPrintCurrentPage
End If
NextPage:
Next i
End Sub

--
<>>< ><<> ><<> <>>< ><<> <>>< <>><<>
Graham Mayor - Word MVP


<>>< ><<> ><<> <>>< ><<> <>>< <>><<>


John said:
Doug,

This is incredible helpful, thank you. A few questions:

1) If I understand correctly, this will list all the pages with
changes in the main text, and then all the pages with changes in the
footnotes, so the pages will print out of order. This isn't ideal.

2) If a revision splits across more than one page (i.e., starts on
page 2, goes to page 3), I think this will only print page 3?

3) If a document has multiple sections (and pages that restart
numbering in each section), I think the code will not quite return
the pages that word needs to print - i.e., I guess it needs to return
something like s1p1,s3p1, unles theres a way of making word print
absolute page numbers?)

4) In a long document, there can easily be more than 100 pages with
changes, and if the string is more than 256 characters, word can't
print. I found something on the MVP site to handle this I think,
along the lines of:

If Len(revpages) <= 256 Then
With Dialogs(wdDialogFilePrint)
.Pages = revpages
.Range = wdPrintRangeOfPages
.Show
End With
Else

Do While Len(revpages) > 256
PagesToPrintChunk(k) = Left$(revpages, 256)
Pos = InStrRev(PagesToPrintChunk(k), ",")
PagesToPrintChunk(k) = Left$(PagesToPrintChunk(k), Pos
- 1) revpages = Mid$(revpages, Pos + 1)
k = k + 1
Loop
PagesToPrintChunk(k) = revpages

which makes an array of pages needing printing. I also came up with
some
code that builds the revpages array to include -s if multiple pages
next to each other need printing, which shorten it somewhat.

5) In a document that has 1000s of revisions, might it be better to
use my mehtod of going from page to page and seeing if there is 0 or
more than 0 revisioins, and deciding if to print that page? Then the
loop would be limited to the number of pages, not checking which page
each revision is on? That's why, if it's possible to somehow set the
range to be the footnotes of the page the rnage is on, if there are
any, I think it might be a little quicker.

Any advice on the above points wouild be much appreciated on the
above points.

Thanks!
John


Doug Robbins - Word MVP said:
The following code will print out the pages on which there are
revisions, whether they are in the main body of the document or the
footnotes:

Dim pnum As Long
Dim i As Long
Dim j As Long
Dim flag As Boolean
Dim arev As Revision
Dim revpages As String
Dim revarray As Variant
revpages = ""
pnum = 0
Dim astory As Range
For Each astory In ActiveDocument.StoryRanges
For Each arev In astory.Revisions
i = arev.Range.Information(wdActiveEndPageNumber)
If i <> pnum Then
pnum = i
If Not IsEmpty(revarray) Then
flag = False
For j = 0 To UBound(revarray)
If i = revarray(j) Then
flag = True
End If
Next j
If flag = False Then
revpages = revpages & "," & i
End If
Else
revpages = revpages & i
End If
revarray = Split(revpages, ",")
End If
Next arev
Next astory
ActiveDocument.PrintOut Range:=wdPrintRangeOfPages, Pages:=revpages


--
Hope this helps.

Please reply to the newsgroup unless you wish to avail yourself of my
services on a paid consulting basis.

Doug Robbins - Word MVP, originally posted via msnews.microsoft.com
John HB said:
Hello,

I am new to VBA programming - thank you for your help in advance.

I would like to set a Range to be the footnotes on a given page. For
example, in this loop:

For var = 1 To intPageCount
Set oRange = ActiveDocument.Range(0, 0)
Set oRange = oRange.GoTo(What:=wdGoToPage, Name:=var)
Set oRange = oRange.GoTo(What:=wdGoToBookmark,
Name:="\page") If oRange.Revisions.Count > 0 Then [print
page]


oRange cycles through each page. The purpose of this is that I can
then see
if there are any revisions on a given page, and if there are, print
the page
(hence the macro only prints pages with revisions on).

However, sometimes there are revisiosn in a footnote on a page, and
no revisions in the text on that page, and that page wouldn't be
printed. So effectively, I need to be able to set the range to be
the footnote text on a
given page, if there is any.

Any advise would be much appreciate
 
J

John HB

This is incredibly helpful. But I don't think it quite works with multiple
sections, because this code:

For i = 1 To iPageCount
Selection.GoTo what:=wdGoToPage, Name:=i
Set oRng = Selection.Bookmarks("\page").Range

doesn't cycle through all the pages in the document if thre are multiple
sections when the page numbering restart. So I guess there's need to be a way
to jump to an absolute page in a document, not a numbered page?

Best,
John



Graham Mayor said:
I spotted your query yesterday afternoon, just before I packed up for the
day and didn't have time to test my approach to the problem, and as Doug had
answered the question this morning I didn't bother to contribute; however I
think that my approach addresses all your concerns. The macro looks for any
revisions on the page or in the footnotes and prints just one copy of the
page in the order in which it appears in the document. Any page that has a
revision carried over from the previous page will also print.. It does not
matter whether there are sections in teh document as the macro processes the
current page.


Sub PrintRevisions()
Dim oRng As Range
Dim i, j As Long
Dim iPageCount As Long
Selection.EndKey wdStory
iPageCount = Selection.Information(wdActiveEndPageNumber)
For i = 1 To iPageCount
Selection.GoTo what:=wdGoToPage, name:=i
Set oRng = Selection.Bookmarks("\page").Range
For j = 1 To oRng.Footnotes.Count
If oRng.Footnotes(j).Range.Revisions.Count <> 0 Then
'MsgBox "Revisions in footnotes on page " & i
ActiveDocument.PrintOut Range:=wdPrintCurrentPage
GoTo NextPage
End If
Next j
If oRng.Revisions.Count > 0 Then
'MsgBox "Revisions on page " & i
ActiveDocument.PrintOut Range:=wdPrintCurrentPage
End If
NextPage:
Next i
End Sub

--
<>>< ><<> ><<> <>>< ><<> <>>< <>><<>
Graham Mayor - Word MVP


<>>< ><<> ><<> <>>< ><<> <>>< <>><<>


John said:
Doug,

This is incredible helpful, thank you. A few questions:

1) If I understand correctly, this will list all the pages with
changes in the main text, and then all the pages with changes in the
footnotes, so the pages will print out of order. This isn't ideal.

2) If a revision splits across more than one page (i.e., starts on
page 2, goes to page 3), I think this will only print page 3?

3) If a document has multiple sections (and pages that restart
numbering in each section), I think the code will not quite return
the pages that word needs to print - i.e., I guess it needs to return
something like s1p1,s3p1, unles theres a way of making word print
absolute page numbers?)

4) In a long document, there can easily be more than 100 pages with
changes, and if the string is more than 256 characters, word can't
print. I found something on the MVP site to handle this I think,
along the lines of:

If Len(revpages) <= 256 Then
With Dialogs(wdDialogFilePrint)
.Pages = revpages
.Range = wdPrintRangeOfPages
.Show
End With
Else

Do While Len(revpages) > 256
PagesToPrintChunk(k) = Left$(revpages, 256)
Pos = InStrRev(PagesToPrintChunk(k), ",")
PagesToPrintChunk(k) = Left$(PagesToPrintChunk(k), Pos
- 1) revpages = Mid$(revpages, Pos + 1)
k = k + 1
Loop
PagesToPrintChunk(k) = revpages

which makes an array of pages needing printing. I also came up with
some
code that builds the revpages array to include -s if multiple pages
next to each other need printing, which shorten it somewhat.

5) In a document that has 1000s of revisions, might it be better to
use my mehtod of going from page to page and seeing if there is 0 or
more than 0 revisioins, and deciding if to print that page? Then the
loop would be limited to the number of pages, not checking which page
each revision is on? That's why, if it's possible to somehow set the
range to be the footnotes of the page the rnage is on, if there are
any, I think it might be a little quicker.

Any advice on the above points wouild be much appreciated on the
above points.

Thanks!
John


Doug Robbins - Word MVP said:
The following code will print out the pages on which there are
revisions, whether they are in the main body of the document or the
footnotes:

Dim pnum As Long
Dim i As Long
Dim j As Long
Dim flag As Boolean
Dim arev As Revision
Dim revpages As String
Dim revarray As Variant
revpages = ""
pnum = 0
Dim astory As Range
For Each astory In ActiveDocument.StoryRanges
For Each arev In astory.Revisions
i = arev.Range.Information(wdActiveEndPageNumber)
If i <> pnum Then
pnum = i
If Not IsEmpty(revarray) Then
flag = False
For j = 0 To UBound(revarray)
If i = revarray(j) Then
flag = True
End If
Next j
If flag = False Then
revpages = revpages & "," & i
End If
Else
revpages = revpages & i
End If
revarray = Split(revpages, ",")
End If
Next arev
Next astory
ActiveDocument.PrintOut Range:=wdPrintRangeOfPages, Pages:=revpages


--
Hope this helps.

Please reply to the newsgroup unless you wish to avail yourself of my
services on a paid consulting basis.

Doug Robbins - Word MVP, originally posted via msnews.microsoft.com
Hello,

I am new to VBA programming - thank you for your help in advance.

I would like to set a Range to be the footnotes on a given page. For
example, in this loop:

For var = 1 To intPageCount
Set oRange = ActiveDocument.Range(0, 0)
Set oRange = oRange.GoTo(What:=wdGoToPage, Name:=var)
Set oRange = oRange.GoTo(What:=wdGoToBookmark,
Name:="\page") If oRange.Revisions.Count > 0 Then [print
page]


oRange cycles through each page. The purpose of this is that I can
then see
if there are any revisions on a given page, and if there are, print
the page
(hence the macro only prints pages with revisions on).

However, sometimes there are revisiosn in a footnote on a page, and
no revisions in the text on that page, and that page wouldn't be
printed. So effectively, I need to be able to set the range to be
the footnote text on a
given page, if there is any.

Any advise would be much appreciate
 
J

John HB

I think the following code may solve all of my problems (except one tiny
one). There does not seem to be an easy way in VBA to have Word jump the
cursor to a particular section and page number, or a particular absolute page
number. This works by simple going from page to page.

This will always output the pages for printing in the p1s1 format, even if
it's not necessary. It seemed easier that way.

I've never programmed in VBA before Friday, and so this could be an awful
programme, though ti seems to work on pretty big documents for me. Thank you
for all the great resources, particularly of Word MVP on the internet, I
could never have done it without.

Sub ChangedPages()
'
' Print only Changed Pages Macro
'
'
Dim oRange As Word.Range
Dim intPageCount As Integer
Dim var As Integer
Dim response As Integer
Dim Add, bot, top, fnrevisions As Integer

Dim botstr As String, topstr As String
Dim pagerange As String
Dim Pos As Long, PagesToPrintChunk(10) As String, PagesForClipboard As
String
Dim i As Integer, j As Integer, k As Integer, fn As Integer, FootNote As
Integer

Dim MyData As DataObject

PagesForClipboard = "There are two many pages to be printed in one go.
Please print the following page ranges separately:"

i = 0 ' dummy variable
j = 0 ' dummy variable
Add = 0 'Variable used to determine if pages need to be added
top = -2 ' Variable used to define the top of a page range
bot = -2 ' Variable used to define the bottom of a page range

fnrevsision = 0 'Variable used to determine if any footnotes with
revisions in the document

Application.ScreenUpdating = False ' Prevents the screen from flashing
System.Cursor = wdCursorWait ' Switches the cursor to egg-timer
Selection.EndKey wdStory


If ActiveDocument.Footnotes.Count >= 1 Then fnrevisions =
ActiveDocument.StoryRanges(wdFootnotesStory).Revisions.Count

If ActiveDocument.Range.Revisions.Count + fnrevisions > 0 Then

intPageCount =
ActiveDocument.Range.Information(wdNumberOfPagesInDocument)

Set oRange = ActiveDocument.Range(0, 0)
Set oRange = oRange.GoTo(What:=wdGoToPage, Name:=1)

On Error Resume Next
For var = 1 To intPageCount
Application.StatusBar = "Checking page " & var & " of " &
intPageCount
Set oRange = oRange.GoTo(What:=wdGoToBookmark, Name:="\page") '
Sets the range to be the page numbered var

For k = 1 To oRange.Footnotes.Count
If oRange.Footnotes(k).Range.Revisions.Count <> 0 Then
GoTo FootNote
End If
Next k

If oRange.Revisions.Count > 0 Then
FootNote:
Add = 1

If var = top + 1 Then
top = var
topstr = "p" &
oRange.Information(wdActiveEndAdjustedPageNumber) _
& "s" & oRange.Information(wdActiveEndSectionNumber)
Else
bot = var
top = var
botstr = "p" &
oRange.Information(wdActiveEndAdjustedPageNumber) _
& "s" & oRange.Information(wdActiveEndSectionNumber)
End If
If var = intPageCount Then
If bot = top Then
pagerange = pagerange & "," & botstr
Else
pagerange = pagerange & "," & botstr & "-" & topstr
End If
End If
Else
If Add = 1 Then
If bot = top Then
pagerange = pagerange & "," & botstr
Else
pagerange = pagerange & "," & botstr & "-" & topstr
End If
Add = 0
End If
End If

Set oRange = oRange.GoToNext(wdGoToPage)
Next

System.Cursor = wdCursorNormal
Application.StatusBar = "Done!"
pagerange = Right(pagerange, Len(pagerange) - 1)

If Len(pagerange) <= 256 Then
With Dialogs(wdDialogFilePrint)
.Pages = pagerange
.Range = wdPrintRangeOfPages
.Show
End With
Else

Do While Len(pagerange) > 256
PagesToPrintChunk(i) = Left$(pagerange, 256)
Pos = InStrRev(PagesToPrintChunk(i), ",")
PagesToPrintChunk(i) = Left$(PagesToPrintChunk(i), Pos - 1)
pagerange = Mid$(pagerange, Pos + 1)
i = i + 1
Loop
PagesToPrintChunk(i) = pagerange

Do While j <= i
var = MsgBox(PagesToPrintChunk(j), vbInformation, "Set " & j
+ 1 & " of pages to print")
PagesForClipboard = PagesForClipboard & vbNewLine &
vbNewLine & PagesToPrintChunk(j)
j = j + 1
Loop


Set MyData = New DataObject
MyData.SetText (PagesForClipboard)

response = MsgBox("Copy required pages to clipboard?", vbYesNo)
If response = vbYes Then MyData.PutInClipboard

End If

Else
Select Case ActiveDocument.TrackRevisions
Case False
response = MsgBox("There are no recorded revisions in this " & _
"document. Track Changes is not enabled. Would " & _
"you like to turn Track Changes on?", vbYesNo)
If response = vbYes Then ActiveDocument.TrackRevisions = True
Case True
MsgBox "There are no tracked revisions in this document."
End Select
End If
End Sub

The one issue, if anyone wants to look into it, is that a footnote may span
more than one page, and there may be revisions on the second page of the
footnote, which would not be picked up by the above.
Thanks,
John


Graham Mayor said:
I spotted your query yesterday afternoon, just before I packed up for the
day and didn't have time to test my approach to the problem, and as Doug had
answered the question this morning I didn't bother to contribute; however I
think that my approach addresses all your concerns. The macro looks for any
revisions on the page or in the footnotes and prints just one copy of the
page in the order in which it appears in the document. Any page that has a
revision carried over from the previous page will also print.. It does not
matter whether there are sections in teh document as the macro processes the
current page.


Sub PrintRevisions()
Dim oRng As Range
Dim i, j As Long
Dim iPageCount As Long
Selection.EndKey wdStory
iPageCount = Selection.Information(wdActiveEndPageNumber)
For i = 1 To iPageCount
Selection.GoTo what:=wdGoToPage, name:=i
Set oRng = Selection.Bookmarks("\page").Range
For j = 1 To oRng.Footnotes.Count
If oRng.Footnotes(j).Range.Revisions.Count <> 0 Then
'MsgBox "Revisions in footnotes on page " & i
ActiveDocument.PrintOut Range:=wdPrintCurrentPage
GoTo NextPage
End If
Next j
If oRng.Revisions.Count > 0 Then
'MsgBox "Revisions on page " & i
ActiveDocument.PrintOut Range:=wdPrintCurrentPage
End If
NextPage:
Next i
End Sub

--
<>>< ><<> ><<> <>>< ><<> <>>< <>><<>
Graham Mayor - Word MVP


<>>< ><<> ><<> <>>< ><<> <>>< <>><<>


John said:
Doug,

This is incredible helpful, thank you. A few questions:

1) If I understand correctly, this will list all the pages with
changes in the main text, and then all the pages with changes in the
footnotes, so the pages will print out of order. This isn't ideal.

2) If a revision splits across more than one page (i.e., starts on
page 2, goes to page 3), I think this will only print page 3?

3) If a document has multiple sections (and pages that restart
numbering in each section), I think the code will not quite return
the pages that word needs to print - i.e., I guess it needs to return
something like s1p1,s3p1, unles theres a way of making word print
absolute page numbers?)

4) In a long document, there can easily be more than 100 pages with
changes, and if the string is more than 256 characters, word can't
print. I found something on the MVP site to handle this I think,
along the lines of:

If Len(revpages) <= 256 Then
With Dialogs(wdDialogFilePrint)
.Pages = revpages
.Range = wdPrintRangeOfPages
.Show
End With
Else

Do While Len(revpages) > 256
PagesToPrintChunk(k) = Left$(revpages, 256)
Pos = InStrRev(PagesToPrintChunk(k), ",")
PagesToPrintChunk(k) = Left$(PagesToPrintChunk(k), Pos
- 1) revpages = Mid$(revpages, Pos + 1)
k = k + 1
Loop
PagesToPrintChunk(k) = revpages

which makes an array of pages needing printing. I also came up with
some
code that builds the revpages array to include -s if multiple pages
next to each other need printing, which shorten it somewhat.

5) In a document that has 1000s of revisions, might it be better to
use my mehtod of going from page to page and seeing if there is 0 or
more than 0 revisioins, and deciding if to print that page? Then the
loop would be limited to the number of pages, not checking which page
each revision is on? That's why, if it's possible to somehow set the
range to be the footnotes of the page the rnage is on, if there are
any, I think it might be a little quicker.

Any advice on the above points wouild be much appreciated on the
above points.

Thanks!
John


Doug Robbins - Word MVP said:
The following code will print out the pages on which there are
revisions, whether they are in the main body of the document or the
footnotes:

Dim pnum As Long
Dim i As Long
Dim j As Long
Dim flag As Boolean
Dim arev As Revision
Dim revpages As String
Dim revarray As Variant
revpages = ""
pnum = 0
Dim astory As Range
For Each astory In ActiveDocument.StoryRanges
For Each arev In astory.Revisions
i = arev.Range.Information(wdActiveEndPageNumber)
If i <> pnum Then
pnum = i
If Not IsEmpty(revarray) Then
flag = False
For j = 0 To UBound(revarray)
If i = revarray(j) Then
flag = True
End If
Next j
If flag = False Then
revpages = revpages & "," & i
End If
Else
revpages = revpages & i
End If
revarray = Split(revpages, ",")
End If
Next arev
Next astory
ActiveDocument.PrintOut Range:=wdPrintRangeOfPages, Pages:=revpages


--
Hope this helps.

Please reply to the newsgroup unless you wish to avail yourself of my
services on a paid consulting basis.

Doug Robbins - Word MVP, originally posted via msnews.microsoft.com
Hello,

I am new to VBA programming - thank you for your help in advance.

I would like to set a Range to be the footnotes on a given page. For
example, in this loop:

For var = 1 To intPageCount
Set oRange = ActiveDocument.Range(0, 0)
Set oRange = oRange.GoTo(What:=wdGoToPage, Name:=var)
Set oRange = oRange.GoTo(What:=wdGoToBookmark,
Name:="\page") If oRange.Revisions.Count > 0 Then [print
page]


oRange cycles through each page. The purpose of this is that I can
then see
if there are any revisions on a given page, and if there are, print
the page
(hence the macro only prints pages with revisions on).

However, sometimes there are revisiosn in a footnote on a page, and
no revisions in the text on that page, and that page wouldn't be
printed. So effectively, I need to be able to set the range to be
the footnote text on a
given page, if there is any.

Any advise would be much appreciate
 
G

Graham Mayor

iPageCount does not reflect the page number that may be on the page but is
the actual page count so sections shouldn't make any difference however they
are numbered. The macro prints the current page so does not need to address
the page by section and page.

Check it for yourself

Dim iPageCount As Long
Selection.EndKey wdStory
iPageCount = Selection.Information(wdActiveEndPageNumber)
MsgBox iPageCount

Word is not a page layout application so there are no true pages as such -
merely a semblance of pages caused by text flow.

--
<>>< ><<> ><<> <>>< ><<> <>>< <>><<>
Graham Mayor - Word MVP


<>>< ><<> ><<> <>>< ><<> <>>< <>><<>


John said:
This is incredibly helpful. But I don't think it quite works with
multiple sections, because this code:

For i = 1 To iPageCount
Selection.GoTo what:=wdGoToPage, Name:=i
Set oRng = Selection.Bookmarks("\page").Range

doesn't cycle through all the pages in the document if thre are
multiple sections when the page numbering restart. So I guess there's
need to be a way to jump to an absolute page in a document, not a
numbered page?

Best,
John



Graham Mayor said:
I spotted your query yesterday afternoon, just before I packed up
for the day and didn't have time to test my approach to the problem,
and as Doug had answered the question this morning I didn't bother
to contribute; however I think that my approach addresses all your
concerns. The macro looks for any revisions on the page or in the
footnotes and prints just one copy of the page in the order in which
it appears in the document. Any page that has a revision carried
over from the previous page will also print.. It does not matter
whether there are sections in teh document as the macro processes
the current page.


Sub PrintRevisions()
Dim oRng As Range
Dim i, j As Long
Dim iPageCount As Long
Selection.EndKey wdStory
iPageCount = Selection.Information(wdActiveEndPageNumber)
For i = 1 To iPageCount
Selection.GoTo what:=wdGoToPage, name:=i
Set oRng = Selection.Bookmarks("\page").Range
For j = 1 To oRng.Footnotes.Count
If oRng.Footnotes(j).Range.Revisions.Count <> 0 Then
'MsgBox "Revisions in footnotes on page " & i
ActiveDocument.PrintOut Range:=wdPrintCurrentPage
GoTo NextPage
End If
Next j
If oRng.Revisions.Count > 0 Then
'MsgBox "Revisions on page " & i
ActiveDocument.PrintOut Range:=wdPrintCurrentPage
End If
NextPage:
Next i
End Sub

--
<>>< ><<> ><<> <>>< ><<> <>>< <>><<>
Graham Mayor - Word MVP


<>>< ><<> ><<> <>>< ><<> <>>< <>><<>


John said:
Doug,

This is incredible helpful, thank you. A few questions:

1) If I understand correctly, this will list all the pages with
changes in the main text, and then all the pages with changes in the
footnotes, so the pages will print out of order. This isn't ideal.

2) If a revision splits across more than one page (i.e., starts on
page 2, goes to page 3), I think this will only print page 3?

3) If a document has multiple sections (and pages that restart
numbering in each section), I think the code will not quite return
the pages that word needs to print - i.e., I guess it needs to
return something like s1p1,s3p1, unles theres a way of making word
print absolute page numbers?)

4) In a long document, there can easily be more than 100 pages with
changes, and if the string is more than 256 characters, word can't
print. I found something on the MVP site to handle this I think,
along the lines of:

If Len(revpages) <= 256 Then
With Dialogs(wdDialogFilePrint)
.Pages = revpages
.Range = wdPrintRangeOfPages
.Show
End With
Else

Do While Len(revpages) > 256
PagesToPrintChunk(k) = Left$(revpages, 256)
Pos = InStrRev(PagesToPrintChunk(k), ",")
PagesToPrintChunk(k) = Left$(PagesToPrintChunk(k),
Pos - 1) revpages = Mid$(revpages, Pos + 1)
k = k + 1
Loop
PagesToPrintChunk(k) = revpages

which makes an array of pages needing printing. I also came up with
some
code that builds the revpages array to include -s if multiple pages
next to each other need printing, which shorten it somewhat.

5) In a document that has 1000s of revisions, might it be better to
use my mehtod of going from page to page and seeing if there is 0 or
more than 0 revisioins, and deciding if to print that page? Then the
loop would be limited to the number of pages, not checking which
page each revision is on? That's why, if it's possible to somehow
set the range to be the footnotes of the page the rnage is on, if
there are any, I think it might be a little quicker.

Any advice on the above points wouild be much appreciated on the
above points.

Thanks!
John


:

The following code will print out the pages on which there are
revisions, whether they are in the main body of the document or the
footnotes:

Dim pnum As Long
Dim i As Long
Dim j As Long
Dim flag As Boolean
Dim arev As Revision
Dim revpages As String
Dim revarray As Variant
revpages = ""
pnum = 0
Dim astory As Range
For Each astory In ActiveDocument.StoryRanges
For Each arev In astory.Revisions
i = arev.Range.Information(wdActiveEndPageNumber)
If i <> pnum Then
pnum = i
If Not IsEmpty(revarray) Then
flag = False
For j = 0 To UBound(revarray)
If i = revarray(j) Then
flag = True
End If
Next j
If flag = False Then
revpages = revpages & "," & i
End If
Else
revpages = revpages & i
End If
revarray = Split(revpages, ",")
End If
Next arev
Next astory
ActiveDocument.PrintOut Range:=wdPrintRangeOfPages, Pages:=revpages


--
Hope this helps.

Please reply to the newsgroup unless you wish to avail yourself of
my services on a paid consulting basis.

Doug Robbins - Word MVP, originally posted via msnews.microsoft.com
Hello,

I am new to VBA programming - thank you for your help in advance.

I would like to set a Range to be the footnotes on a given page.
For example, in this loop:

For var = 1 To intPageCount
Set oRange = ActiveDocument.Range(0, 0)
Set oRange = oRange.GoTo(What:=wdGoToPage, Name:=var)
Set oRange = oRange.GoTo(What:=wdGoToBookmark,
Name:="\page") If oRange.Revisions.Count > 0 Then
[print page]


oRange cycles through each page. The purpose of this is that I can
then see
if there are any revisions on a given page, and if there are,
print the page
(hence the macro only prints pages with revisions on).

However, sometimes there are revisiosn in a footnote on a page,
and no revisions in the text on that page, and that page wouldn't
be printed. So effectively, I need to be able to set the range to
be the footnote text on a
given page, if there is any.

Any advise would be much appreciate
 
G

Graham Mayor

The main function of any vba application is to do the job in hand. It does
not really matter how ugly the code as long as it works ... unless you
expect someone else to try and debug it for you ;)

--
<>>< ><<> ><<> <>>< ><<> <>>< <>><<>
Graham Mayor - Word MVP


<>>< ><<> ><<> <>>< ><<> <>>< <>><<>


John said:
I think the following code may solve all of my problems (except one
tiny one). There does not seem to be an easy way in VBA to have Word
jump the cursor to a particular section and page number, or a
particular absolute page number. This works by simple going from page
to page.

This will always output the pages for printing in the p1s1 format,
even if it's not necessary. It seemed easier that way.

I've never programmed in VBA before Friday, and so this could be an
awful programme, though ti seems to work on pretty big documents for
me. Thank you for all the great resources, particularly of Word MVP
on the internet, I could never have done it without.

Sub ChangedPages()
'
' Print only Changed Pages Macro
'
'
Dim oRange As Word.Range
Dim intPageCount As Integer
Dim var As Integer
Dim response As Integer
Dim Add, bot, top, fnrevisions As Integer

Dim botstr As String, topstr As String
Dim pagerange As String
Dim Pos As Long, PagesToPrintChunk(10) As String,
PagesForClipboard As String
Dim i As Integer, j As Integer, k As Integer, fn As Integer,
FootNote As Integer

Dim MyData As DataObject

PagesForClipboard = "There are two many pages to be printed in one
go. Please print the following page ranges separately:"

i = 0 ' dummy variable
j = 0 ' dummy variable
Add = 0 'Variable used to determine if pages need to be added
top = -2 ' Variable used to define the top of a page range
bot = -2 ' Variable used to define the bottom of a page range

fnrevsision = 0 'Variable used to determine if any footnotes with
revisions in the document

Application.ScreenUpdating = False ' Prevents the screen from
flashing System.Cursor = wdCursorWait ' Switches the cursor to
egg-timer Selection.EndKey wdStory


If ActiveDocument.Footnotes.Count >= 1 Then fnrevisions =
ActiveDocument.StoryRanges(wdFootnotesStory).Revisions.Count

If ActiveDocument.Range.Revisions.Count + fnrevisions > 0 Then

intPageCount =
ActiveDocument.Range.Information(wdNumberOfPagesInDocument)

Set oRange = ActiveDocument.Range(0, 0)
Set oRange = oRange.GoTo(What:=wdGoToPage, Name:=1)

On Error Resume Next
For var = 1 To intPageCount
Application.StatusBar = "Checking page " & var & " of " &
intPageCount
Set oRange = oRange.GoTo(What:=wdGoToBookmark,
Name:="\page") ' Sets the range to be the page numbered var

For k = 1 To oRange.Footnotes.Count
If oRange.Footnotes(k).Range.Revisions.Count <> 0 Then
GoTo FootNote
End If
Next k

If oRange.Revisions.Count > 0 Then
FootNote:
Add = 1

If var = top + 1 Then
top = var
topstr = "p" &
oRange.Information(wdActiveEndAdjustedPageNumber) _
& "s" &
oRange.Information(wdActiveEndSectionNumber) Else
bot = var
top = var
botstr = "p" &
oRange.Information(wdActiveEndAdjustedPageNumber) _
& "s" &
oRange.Information(wdActiveEndSectionNumber) End If
If var = intPageCount Then
If bot = top Then
pagerange = pagerange & "," & botstr
Else
pagerange = pagerange & "," & botstr & "-" &
topstr End If
End If
Else
If Add = 1 Then
If bot = top Then
pagerange = pagerange & "," & botstr
Else
pagerange = pagerange & "," & botstr & "-" &
topstr End If
Add = 0
End If
End If

Set oRange = oRange.GoToNext(wdGoToPage)
Next

System.Cursor = wdCursorNormal
Application.StatusBar = "Done!"
pagerange = Right(pagerange, Len(pagerange) - 1)

If Len(pagerange) <= 256 Then
With Dialogs(wdDialogFilePrint)
.Pages = pagerange
.Range = wdPrintRangeOfPages
.Show
End With
Else

Do While Len(pagerange) > 256
PagesToPrintChunk(i) = Left$(pagerange, 256)
Pos = InStrRev(PagesToPrintChunk(i), ",")
PagesToPrintChunk(i) = Left$(PagesToPrintChunk(i), Pos
- 1) pagerange = Mid$(pagerange, Pos + 1)
i = i + 1
Loop
PagesToPrintChunk(i) = pagerange

Do While j <= i
var = MsgBox(PagesToPrintChunk(j), vbInformation, "Set
" & j + 1 & " of pages to print")
PagesForClipboard = PagesForClipboard & vbNewLine &
vbNewLine & PagesToPrintChunk(j)
j = j + 1
Loop


Set MyData = New DataObject
MyData.SetText (PagesForClipboard)

response = MsgBox("Copy required pages to clipboard?",
vbYesNo) If response = vbYes Then MyData.PutInClipboard

End If

Else
Select Case ActiveDocument.TrackRevisions
Case False
response = MsgBox("There are no recorded revisions in this
" & _ "document. Track Changes is not enabled. Would " &
_ "you like to turn Track Changes on?", vbYesNo)
If response = vbYes Then ActiveDocument.TrackRevisions =
True Case True
MsgBox "There are no tracked revisions in this document."
End Select
End If
End Sub

The one issue, if anyone wants to look into it, is that a footnote
may span more than one page, and there may be revisions on the second
page of the footnote, which would not be picked up by the above.
Thanks,
John


Graham Mayor said:
I spotted your query yesterday afternoon, just before I packed up
for the day and didn't have time to test my approach to the problem,
and as Doug had answered the question this morning I didn't bother
to contribute; however I think that my approach addresses all your
concerns. The macro looks for any revisions on the page or in the
footnotes and prints just one copy of the page in the order in which
it appears in the document. Any page that has a revision carried
over from the previous page will also print.. It does not matter
whether there are sections in teh document as the macro processes
the current page.


Sub PrintRevisions()
Dim oRng As Range
Dim i, j As Long
Dim iPageCount As Long
Selection.EndKey wdStory
iPageCount = Selection.Information(wdActiveEndPageNumber)
For i = 1 To iPageCount
Selection.GoTo what:=wdGoToPage, name:=i
Set oRng = Selection.Bookmarks("\page").Range
For j = 1 To oRng.Footnotes.Count
If oRng.Footnotes(j).Range.Revisions.Count <> 0 Then
'MsgBox "Revisions in footnotes on page " & i
ActiveDocument.PrintOut Range:=wdPrintCurrentPage
GoTo NextPage
End If
Next j
If oRng.Revisions.Count > 0 Then
'MsgBox "Revisions on page " & i
ActiveDocument.PrintOut Range:=wdPrintCurrentPage
End If
NextPage:
Next i
End Sub

--
<>>< ><<> ><<> <>>< ><<> <>>< <>><<>
Graham Mayor - Word MVP


<>>< ><<> ><<> <>>< ><<> <>>< <>><<>


John said:
Doug,

This is incredible helpful, thank you. A few questions:

1) If I understand correctly, this will list all the pages with
changes in the main text, and then all the pages with changes in the
footnotes, so the pages will print out of order. This isn't ideal.

2) If a revision splits across more than one page (i.e., starts on
page 2, goes to page 3), I think this will only print page 3?

3) If a document has multiple sections (and pages that restart
numbering in each section), I think the code will not quite return
the pages that word needs to print - i.e., I guess it needs to
return something like s1p1,s3p1, unles theres a way of making word
print absolute page numbers?)

4) In a long document, there can easily be more than 100 pages with
changes, and if the string is more than 256 characters, word can't
print. I found something on the MVP site to handle this I think,
along the lines of:

If Len(revpages) <= 256 Then
With Dialogs(wdDialogFilePrint)
.Pages = revpages
.Range = wdPrintRangeOfPages
.Show
End With
Else

Do While Len(revpages) > 256
PagesToPrintChunk(k) = Left$(revpages, 256)
Pos = InStrRev(PagesToPrintChunk(k), ",")
PagesToPrintChunk(k) = Left$(PagesToPrintChunk(k),
Pos - 1) revpages = Mid$(revpages, Pos + 1)
k = k + 1
Loop
PagesToPrintChunk(k) = revpages

which makes an array of pages needing printing. I also came up with
some
code that builds the revpages array to include -s if multiple pages
next to each other need printing, which shorten it somewhat.

5) In a document that has 1000s of revisions, might it be better to
use my mehtod of going from page to page and seeing if there is 0 or
more than 0 revisioins, and deciding if to print that page? Then the
loop would be limited to the number of pages, not checking which
page each revision is on? That's why, if it's possible to somehow
set the range to be the footnotes of the page the rnage is on, if
there are any, I think it might be a little quicker.

Any advice on the above points wouild be much appreciated on the
above points.

Thanks!
John


:

The following code will print out the pages on which there are
revisions, whether they are in the main body of the document or the
footnotes:

Dim pnum As Long
Dim i As Long
Dim j As Long
Dim flag As Boolean
Dim arev As Revision
Dim revpages As String
Dim revarray As Variant
revpages = ""
pnum = 0
Dim astory As Range
For Each astory In ActiveDocument.StoryRanges
For Each arev In astory.Revisions
i = arev.Range.Information(wdActiveEndPageNumber)
If i <> pnum Then
pnum = i
If Not IsEmpty(revarray) Then
flag = False
For j = 0 To UBound(revarray)
If i = revarray(j) Then
flag = True
End If
Next j
If flag = False Then
revpages = revpages & "," & i
End If
Else
revpages = revpages & i
End If
revarray = Split(revpages, ",")
End If
Next arev
Next astory
ActiveDocument.PrintOut Range:=wdPrintRangeOfPages, Pages:=revpages


--
Hope this helps.

Please reply to the newsgroup unless you wish to avail yourself of
my services on a paid consulting basis.

Doug Robbins - Word MVP, originally posted via msnews.microsoft.com
Hello,

I am new to VBA programming - thank you for your help in advance.

I would like to set a Range to be the footnotes on a given page.
For example, in this loop:

For var = 1 To intPageCount
Set oRange = ActiveDocument.Range(0, 0)
Set oRange = oRange.GoTo(What:=wdGoToPage, Name:=var)
Set oRange = oRange.GoTo(What:=wdGoToBookmark,
Name:="\page") If oRange.Revisions.Count > 0 Then
[print page]


oRange cycles through each page. The purpose of this is that I can
then see
if there are any revisions on a given page, and if there are,
print the page
(hence the macro only prints pages with revisions on).

However, sometimes there are revisiosn in a footnote on a page,
and no revisions in the text on that page, and that page wouldn't
be printed. So effectively, I need to be able to set the range to
be the footnote text on a
given page, if there is any.

Any advise would be much appreciate
 

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