Hvorfor
07-14-2011, 04:34 AM
Hello guys,
This week i started to make a template that is going to be used to make various documentation. This template will be used by several diffrent people. So because people have diffrerent habits when it comes to typing in word (some use to much enter/page breaks and dont care about stuff like blank pages etc) I thought I would make a macro that go's trough the document and removes empty pages (ie. Pages with only Return, space tab, page break and other "empty" formating on it).
So far using the all mighty google, and my very limited programming skills have been enugh to make it work OK. However, I have run inn to one problem. The macro considers hidden text (in this case RD fields) as empty formating.
So why is this a problem?
Well, I have decided that every chapter shuld be saved in its own document, so the files wont be to long and for easier reuse of chapters. So i use RD fileds in the "main" doc so the TOC can be updated and the correct page numbers set.
My problem is this:
If i have to many RD fields or the TOC ends at the end of the page the RD fields will end up on an "empty" page, and get deleted by my macro. This in turn will make the macro useless.
So here is the code that i have "Written"/modified from examples i found on google. Im sure there is a better way of doing this, and Im very open for suggestions. The code does more than searching for blank pages, it also checks if the doc has even number of pages, if not it inserts a blank page. It also sets pagenumbers (for all docs) and updates the TOC.
Macro:
Sub TOC_Macro_Test()
Dim oField As Field
Dim strCode As String
Dim iLastPage As Long
Dim oDoc As Document
ChDir ActiveDocument.Path
With ActiveDocument.ActiveWindow.View
.ShowAll = False
.ShowHiddenText = False
.ShowFieldCodes = False
.Type = wdPrintView
End With
Remove_Blank_Pages_Macro
checkForEvenPageNumbers
ActiveDocument.Repaginate
Selection.Move Unit:=wdStory, Count:=1
iLastPage = Selection.Information(wdActiveEndAdjustedPageNumber)
For Each oField In ActiveDocument.Fields
If oField.Type = wdFieldRefDoc Then
strCode = Trim$(oField.Code)
strCode = Trim$(Mid$(strCode, InStr(strCode, " ")))
If LCase$(Left$(strCode, 2)) = "\f" Then
strCode = Trim$(Mid$(strCode, 3))
End If
If LCase$(Right$(strCode, 2)) = "\f" Then
strCode = Trim$(Left$(strCode, Len(strCode) - 2))
End If
If Asc(strCode) = 34 Then
strCode = Trim$(Mid$(strCode, 2, Len(strCode) - 2))
End If
ChDir ActiveDocument.Path
Set oDoc = Documents.Open(FileName:=strCode)
oDoc.Activate
With oDoc.ActiveWindow.View
.ShowAll = False
.ShowHiddenText = False
.ShowFieldCodes = False
.Type = wdPrintView
End With
Remove_Blank_Pages_Macro
checkForEvenPageNumbers
oDoc.Sections(1).Headers(wdHeaderFooterPrimary). _
PageNumbers.RestartNumberingAtSection = True
oDoc.Sections(1).Headers(wdHeaderFooterPrimary). _
PageNumbers.StartingNumber = iLastPage + 1
oDoc.Repaginate
Selection.Move Unit:=wdStory, Count:=1
iLastPage = Selection.Information(wdActiveEndAdjustedPageNumber)
oDoc.Close SaveChanges:=wdSaveChanges
End If
Next oField
ChDir ActiveDocument.Path
ActiveDocument.Fields.Update
End Sub
Function that removes blank pages:
Public Function Remove_Blank_Pages_Macro()
Dim NumberOfPages As Long
Dim CurrentPage As Long
CurrentPage = 1
NumberOfPages = Selection.Information(wdNumberOfPagesInDocument)
Selection.GoTo What:=wdGoToSection, Which:=wdGoToFirst
Selection.ExtendMode = True
Selection.GoTo What:=wdGoToPage, Which:=wdGoToNext, Count:=1
For CurrentPage = 1 To NumberOfPages
Selection.ExtendMode = False
If isBlankSelection Then
If CurrentPage = NumberOfPages Then
ActiveDocument.GoTo(wdGoToPage, wdGoToLast).Bookmarks("\Page").Range.Delete
Selection.ExtendMode = True
Selection.GoTo What:=wdGoToLine, Which:=wdGoToPrevious, Count:=1
If isBlankSelection Then
Selection.Delete
End If
Exit For
End If
Selection.Delete
Selection.ExtendMode = True
Selection.GoTo What:=wdGoToPage, Which:=wdGoToNext, Count:=1
Else
Selection.Collapse (wdCollapseEnd)
Selection.ExtendMode = True
Selection.GoTo What:=wdGoToPage, Which:=wdGoToNext, Count:=1
End If
Next CurrentPage
Selection.Collapse (wdCollapseEnd)
Selection.ExtendMode = False
End Function
Function that checks if the selection is blank:
Public Function isBlankSelection()
For Each c In Selection.Characters
If (c <> vbCr And c <> vbTab And c <> vbFormFeed And c <> " ") Then
isBlankSelection = False
Exit Function
End If
Next
isBlankSelection = True
End Function
Function that inserts a blank page at the end if the document has odd number of pages.
Public Function checkForEvenPageNumbers()
If ActiveDocument.BuiltInDocumentProperties("number of pages") Mod 2 <> 0 Then
Selection.EndKey Unit:=wdStory
Selection.InsertBreak Type:=wdPageBreak
End If
End Function
I hope I have provided enough information for you to help me with my problem.
PS: I'm also looking to write a macro / function that finds the RD fields in the TOC and puts them all on the same line so i dont get a line shift between every RD field.
Thank you,
Even
This week i started to make a template that is going to be used to make various documentation. This template will be used by several diffrent people. So because people have diffrerent habits when it comes to typing in word (some use to much enter/page breaks and dont care about stuff like blank pages etc) I thought I would make a macro that go's trough the document and removes empty pages (ie. Pages with only Return, space tab, page break and other "empty" formating on it).
So far using the all mighty google, and my very limited programming skills have been enugh to make it work OK. However, I have run inn to one problem. The macro considers hidden text (in this case RD fields) as empty formating.
So why is this a problem?
Well, I have decided that every chapter shuld be saved in its own document, so the files wont be to long and for easier reuse of chapters. So i use RD fileds in the "main" doc so the TOC can be updated and the correct page numbers set.
My problem is this:
If i have to many RD fields or the TOC ends at the end of the page the RD fields will end up on an "empty" page, and get deleted by my macro. This in turn will make the macro useless.
So here is the code that i have "Written"/modified from examples i found on google. Im sure there is a better way of doing this, and Im very open for suggestions. The code does more than searching for blank pages, it also checks if the doc has even number of pages, if not it inserts a blank page. It also sets pagenumbers (for all docs) and updates the TOC.
Macro:
Sub TOC_Macro_Test()
Dim oField As Field
Dim strCode As String
Dim iLastPage As Long
Dim oDoc As Document
ChDir ActiveDocument.Path
With ActiveDocument.ActiveWindow.View
.ShowAll = False
.ShowHiddenText = False
.ShowFieldCodes = False
.Type = wdPrintView
End With
Remove_Blank_Pages_Macro
checkForEvenPageNumbers
ActiveDocument.Repaginate
Selection.Move Unit:=wdStory, Count:=1
iLastPage = Selection.Information(wdActiveEndAdjustedPageNumber)
For Each oField In ActiveDocument.Fields
If oField.Type = wdFieldRefDoc Then
strCode = Trim$(oField.Code)
strCode = Trim$(Mid$(strCode, InStr(strCode, " ")))
If LCase$(Left$(strCode, 2)) = "\f" Then
strCode = Trim$(Mid$(strCode, 3))
End If
If LCase$(Right$(strCode, 2)) = "\f" Then
strCode = Trim$(Left$(strCode, Len(strCode) - 2))
End If
If Asc(strCode) = 34 Then
strCode = Trim$(Mid$(strCode, 2, Len(strCode) - 2))
End If
ChDir ActiveDocument.Path
Set oDoc = Documents.Open(FileName:=strCode)
oDoc.Activate
With oDoc.ActiveWindow.View
.ShowAll = False
.ShowHiddenText = False
.ShowFieldCodes = False
.Type = wdPrintView
End With
Remove_Blank_Pages_Macro
checkForEvenPageNumbers
oDoc.Sections(1).Headers(wdHeaderFooterPrimary). _
PageNumbers.RestartNumberingAtSection = True
oDoc.Sections(1).Headers(wdHeaderFooterPrimary). _
PageNumbers.StartingNumber = iLastPage + 1
oDoc.Repaginate
Selection.Move Unit:=wdStory, Count:=1
iLastPage = Selection.Information(wdActiveEndAdjustedPageNumber)
oDoc.Close SaveChanges:=wdSaveChanges
End If
Next oField
ChDir ActiveDocument.Path
ActiveDocument.Fields.Update
End Sub
Function that removes blank pages:
Public Function Remove_Blank_Pages_Macro()
Dim NumberOfPages As Long
Dim CurrentPage As Long
CurrentPage = 1
NumberOfPages = Selection.Information(wdNumberOfPagesInDocument)
Selection.GoTo What:=wdGoToSection, Which:=wdGoToFirst
Selection.ExtendMode = True
Selection.GoTo What:=wdGoToPage, Which:=wdGoToNext, Count:=1
For CurrentPage = 1 To NumberOfPages
Selection.ExtendMode = False
If isBlankSelection Then
If CurrentPage = NumberOfPages Then
ActiveDocument.GoTo(wdGoToPage, wdGoToLast).Bookmarks("\Page").Range.Delete
Selection.ExtendMode = True
Selection.GoTo What:=wdGoToLine, Which:=wdGoToPrevious, Count:=1
If isBlankSelection Then
Selection.Delete
End If
Exit For
End If
Selection.Delete
Selection.ExtendMode = True
Selection.GoTo What:=wdGoToPage, Which:=wdGoToNext, Count:=1
Else
Selection.Collapse (wdCollapseEnd)
Selection.ExtendMode = True
Selection.GoTo What:=wdGoToPage, Which:=wdGoToNext, Count:=1
End If
Next CurrentPage
Selection.Collapse (wdCollapseEnd)
Selection.ExtendMode = False
End Function
Function that checks if the selection is blank:
Public Function isBlankSelection()
For Each c In Selection.Characters
If (c <> vbCr And c <> vbTab And c <> vbFormFeed And c <> " ") Then
isBlankSelection = False
Exit Function
End If
Next
isBlankSelection = True
End Function
Function that inserts a blank page at the end if the document has odd number of pages.
Public Function checkForEvenPageNumbers()
If ActiveDocument.BuiltInDocumentProperties("number of pages") Mod 2 <> 0 Then
Selection.EndKey Unit:=wdStory
Selection.InsertBreak Type:=wdPageBreak
End If
End Function
I hope I have provided enough information for you to help me with my problem.
PS: I'm also looking to write a macro / function that finds the RD fields in the TOC and puts them all on the same line so i dont get a line shift between every RD field.
Thank you,
Even