ドキュメントを量産するときに文字列を差し込む(Word)

ドキュメントを量産するときに文字列を差し込む(Word)

ドキュメントにデータを差し込むといえば、差し込み印刷機能を思い浮かべる人が多いと思うが、簡単なものならブックマーク機能を使ったら十分いける。

準備

前回

akashi-keirin.hatenablog.com

と同じドキュメント(笑)を使う。

その上で、次のようにブックマークを設定する。

f:id:akashi_keirin:20210912073352p:plain

f:id:akashi_keirin:20210912073354p:plain

f:id:akashi_keirin:20210912073357p:plain

これだけ。

ブックマーク部分に文字列を書き込むマクロ

前回記事のリスト1に手を加える。

リスト1
Private Sub test00()
  Const SRC_FOLDER As String = "\SrcDocument\" '"
  Const SRC_FILE_NAME As String = "SrcDocument.docx"
  Const SAVE_FOLDER As String = "\Products\" '"
  
  'テンプレート用ファイルのフルパス組み立て'
  Dim srcPath As String
  srcPath = ThisDocument.Path & SRC_FOLDER & SRC_FILE_NAME
  '保存先フォルダパス'
  Dim saveDir As String
  saveDir = ThisDocument.Path & SAVE_FOLDER
  
  'ファイル名の部品を取得’ '""
  Dim psnNum As String
  psnNum = Format(2, "0#")
  Dim sectName As String
  sectName = "明訓"
  Dim psnName As String
  psnName = "山田 太郎"
  'ファイル名組み立て'
  Dim flName As String
  flName = psnNum & psnName & "@" & sectName & ".docx"
  
  'テンプレート用ファイルを開く'
  Dim templateDoc As Word.Document
  Set templateDoc = Word.Documents.Open(srcPath)
  '名前を付けて保存'
  Call templateDoc.SaveAs2(saveDir & flName)
'=========================================================='
  'ブックマーク箇所に文字列を書き込む'
  With templateDoc
    .Bookmarks("PersonNumber").Range.Text = psnNum
    .Bookmarks("SectionName").Range.Text = sectName
    .Bookmarks("PersonName").Range.Text = psnName
  End With
'=========================================================='
  '上書き保存して閉じる'
  Call templateDoc.Close(SaveChanges:=True)  '……(*)
End Sub

===」で挟んだ部分を追加し、(*)の部分を変えた。

[Bookmarks]("index").Rangeで、ブックマークした部分のRangeオブジェクトが取得できるので、そのTextプロパティに値をセットしてやればよい。

これで、あたかもブックマーク部分に文字列を差し込んだかのような効果が得られるのである!

使ってみる

f:id:akashi_keirin:20210912073400p:plain

f:id:akashi_keirin:20210912073402p:plain

f:id:akashi_keirin:20210912073405p:plain

f:id:akashi_keirin:20210912073410g:plain

万全。

おわりに

[Bookmark]RangeオブジェクトのTextプロパティを直接書き換えると、ブックマークは消失します。

新しくできたドキュメントを汚さないという意味では便利なのかも知れませんが、これがありがたいことなのかどうか、よくわかりません。

あと、やっとWordのRangeオブジェクトがちょっとわかってきたような気もします。気のせいでしょうけど。