第5回 1ページ目を削除する
前回
新規文書作成後にできる余分なセクション区切りの削除まで進みました。
今回は、コマンドボタンを置くためにのみ存在していた1ページ目の削除を行います。
目次
〝ページを削除する〟とは?
Wordにおいて、文書の部分を削除するには、その部分を表すRange
オブジェクトを削除するという方法を用います。
セクションを削除したければ、まずSection
オブジェクトを取得し、そのRange
プロパティを叩いてそのセクションの範囲を表すRange
オブジェクトを取得してからDelete
メソッドで削除します。
' アクティブドキュメントの2つ目のセクションを削除
Dim doc As Document
Set doc = ActiveDocument
Dim sect As Section
Set sect = doc.Sections.Item(2)
Call sect.Range.Delete
段落を削除したければ、まずParagraph
オブジェクトを取得し、そのRange
プロパティを叩いてその段落の範囲を表すRange
オブジェクトを取得してからDelete
メソッドで削除します。
' アクティブドキュメントの3つ目の段落を削除
Dim doc As Document
Set doc = ActiveDocument
Dim para As Paragraph
Set para = doc.Paragraphs.Item(3)
Call para.Range.Delete
したがって、文書の1ページ目を削除したければ、
文書の1ページ目を表すRange
オブジェクトを取得して、そのDelete
メソッドを使えば良い
ということになります。
ところがここで難問に出くわします……。
Wordには〝ページ〟を表すオブジェクトがない
という問題です。
〝ページ〟を表すオブジェクトがない
これは、かなり我々の実感に反する実装です。
文書に〝ページ〟という単位があるのは当たり前のように感ずるからです。
ただ、落ち着いてよく考えると、〝ページ〟という単位は実に不安定な単位であることがわかります。
文書の中で、個々の〝ページ〟には確たる境目というものがありません。
この点がセクションや段落、文字とは異なります。
セクションなら、あるセクションと別のセクションの境目には必ずセクション区切りがあります。
段落なら、ある段落と別の段落の境目には必ず改段落マークがあります。
一方、ページの場合、ページと別のページの間にページ区切りが必ずしも存在するわけではありません。
任意の位置にページ区切りを入れることもできますが、基本的に、あるページと別のページの境目は、ページ設定の都合でたまたまそうなっているだけに過ぎないのです。
このような事情で、Wordには〝ページを表すオブジェクト〟が存在しないのでしょう。やはり、理にかなった設計であると思います。
とはいえ、〝特定のページ全体(を表すRange
オブジェクト)を取得したい〟という場面はそれなりにあることでしょう。
このような場合には、Wordの組み込みブックマークという機能を用います。
〝1ページ目〟のRangeオブジェクト取得・削除
〝定義済みのブックマーク〟とは?
まず、「ブックマーク」とは、文書の任意の範囲に名前を付ける機能だと思えば良いでしょう。
これは、ちょうど、Excelの「名前」機能に似ています。
Excelで、任意のセル範囲に名前を付けて参照することができるように、Wordでも「ブックマーク」という機能によって、文書内の任意の範囲に名前を付け、その名前によって当該範囲を参照することができます。
このように、「ブックマーク」は基本的にはユーザが好きなように設定するものですが、始めから定義されているブックマークがあります。それが今回使用する定義済みのブックマーク(Predefined Bookmarks)です。
「定義済みのブックマーク」はけっこうたくさんありますので、コチラでご確認ください。(日本語版のページだと、自動翻訳のせいで翻訳してはいけないところまで日本語になってしまってイマイチなので、英語版のURLをご案内します。慣れたらむしろ日本語版より読みやすいかも……。)
数ある「定義済みのブックマーク」の中で、今回使用するのは\Page
です。
Current page, including the break at the end of the page, if any. The current page contains the insertion point. If the current selection contains more than one page, the "\Page" bookmark is the first page of the selection. Note that if the insertion point or selection is in the last page of the document, the "\Page" bookmark does not include the final paragraph mark.
この説明にあるように、\Page
というブックマークは、
- カーソル(insertion point)のあるページの範囲で、
- 末尾にページ区切りがあるときはページ区切りを含み、
- 選択範囲が複数ページにわたる場合は選択範囲内の先頭のページの範囲で、
- カーソル(insertion point)が文書の最終ページにあるときは、末尾の改段落マークを含まない
という範囲のRange
オブジェクトを表すわけです。
……ということは、文書の1ページ目を取得するには、
文書の先頭にカーソル(insertion point)を置いて、「定義済みのブックマーク」/Page
を取得すれば良い
ということです。
文書の1ページ目を取得する
では、「定義済みのブックマーク」のしくみを用いて文書の1ページ目を表すRange
オブジェクトを取得します。手順は次のとおりです。
- 文書の1ページ目を表す
Bookmark
オブジェクトを取得する Bookmark
オブジェクトのRange
プロパティを叩いて文書の1ページ目を表すRane
オブジェクトを取得する
これだけです。
リスト1
ソースコードを
Private Sub ExportMailMergeDocuments()
Dim doc As Document
Set doc = ThisDocument
Dim mm As MailMerge
Set mm = doc.MailMerge
mm.Destination = wdSendToNewDocument
mm.SuppressBlankLines = True
Dim mds As MailMergeDataSource
Set mds = mm.DataSource
mds.ActiveRecord = 1
mds.FirstRecord = 1
mds.LastRecord = 1
Call mm.Execute( _
Pause:=True _
)
Dim newDoc As Document
Set newDoc = Application.ActiveDocument
Dim lastSect As Section
Set lastSect = newDoc.Sections(newDoc.Sections.Count)
If lastSect.Range.Start = newDoc.Content.End - 1 Then
Call lastSect.Range.Previous(Unit:=wdCharacter, Count:=1).Delete
End If
' 念のためカーソルを文書の先頭に置く
Call newDoc.Range(0, 0).Select
' 先頭ページを表す`Range`オブジェクトを取得する
Dim firstPageRng As Range
Set firstPageRng = newDoc.Bookmarks.Item("\Page").Range
End Sub
新規文書作成直後、カーソル(insertion point)は文書の先頭にあるはずですが、念のため
Call newDoc.Range(0, 0).Select
によって明示的に(explicit)カーソル(insertion point)を文書先頭位置に置いています。
Document
オブジェクトのRange
メソッドの引数は、[Document].Range(start, end)
となっています。
引数start
、end
は、ともに文書内の絶対位置を表す数値で、
newDoc.Range(0, 0)
ならば、文書の0文字目から0文字目の位置、すなわち文書の先頭の位置を表すRange
オブジェクトが返ることになります。
文書の先頭位置を表すRange
オブジェクトのSelect
メソッドを実行することによって、文書の先頭にカーソル(insertion point)を置いているわけです。
さて、文書の先頭位置にカーソル(insertion point)がある状態で「定義済みのブックマーク」\Page
を取得すれば、そのブックマークは1ページ目全体を指し示すはずなので、
newDoc.Bookmarks.Item("\Page")
で1ページ目全体Bookmark
オブジェクトを取得し、
newDoc.Bookmarks.Item("\Page").Range
Range
プロパティを叩いて返されるRange
オブジェクトを変数firstPageRng
に突っ込んでいます。
1ページ目全体を表すRangeオブジェクトを削除する
こうなると、あとは取得したRange
オブジェクトのDelete
メソッドを実行して削除するだけです。
リスト2
ソースコードを
Private Sub ExportMailMergeDocuments()
Dim doc As Document
Set doc = ThisDocument
Dim mm As MailMerge
Set mm = doc.MailMerge
mm.Destination = wdSendToNewDocument
mm.SuppressBlankLines = True
Dim mds As MailMergeDataSource
Set mds = mm.DataSource
mds.ActiveRecord = 1
mds.FirstRecord = 1
mds.LastRecord = 1
Call mm.Execute( _
Pause:=True _
)
Dim newDoc As Document
Set newDoc = Application.ActiveDocument
Dim lastSect As Section
Set lastSect = newDoc.Sections(newDoc.Sections.Count)
If lastSect.Range.Start = newDoc.Content.End - 1 Then
Call lastSect.Range.Previous(Unit:=wdCharacter, Count:=1).Delete
End If
' 念のためカーソルを文書の先頭に置く
Call newDoc.Range(0, 0).Select
' 先頭ページを表す`Range`オブジェクトを取得する
Dim firstPageRng As Range
Set firstPageRng = newDoc.Bookmarks.Item("\Page").Range
' `Range`オブジェクトを削除する
Call firstPageRng.Delete
End Sub
Call firstPageRng.Delete
で1ページ目を削除します。
画像では実にわかりづらいのですが、1ページ目がめでたく削除されています。
おわりに
これで、〝データ(笑)を差し込んだ新規文書〟が完成しました。
次回は、この整形済み新規文書に名前を付けて保存する処理を解説します。