カーソルを任意の場所に置くFunctionの改良(Word)
カーソルを任意の場所に置くFunctionの改良(Word)
似たような書類を、宛先別に大量生産するような場合に、差込印刷機能を使う場面は多いと思う。
で、差込印刷の差込レコードごとにWordドキュメントが生成されると便利(というか後々扱いやすい)なので、
こんな感じでWordドキュメントを大量生産することが多い。
摩訶不思議な不具合
差し込むデータは、相手先の名前だったり、日付だったりするのだが、場合によっては、字幅を揃えたいことがある。
そんなときに、差し込みフィールドの部分に均等割付を施す。
しかし、たまに困ったことが起こる。
データが差し込まれた瞬間とか、出来上がったWordドキュメントを開き直したときに、均等割付がめちゃくちゃになってしまうのである。
これは、職場のPCでしか今のところ起こらないので、そのものずばりをお見せできないのだけれど、擬似的に再現すると、
こんなふうにキッチリ揃えたはずなのに、
ドキュメントを開き直したら、こんなふうにガタガタになる、というイメージ。
で、これまたお見せできないのだけれど、それぞれの均等割付がなされている部分をクリックしてやると、だいたい元に戻る。なのに、その状態で上書き保存しても、開き直すとまたガタガタ……。
職場のPCでしか起きないので、Word2010のバグか何かだと思っていたのだけれど、職場のPCが2016になってからも引き続き起こる。家の2013ではまるで再現できないのに。
これの何が困るって、
自動印刷ができない
こと。
せっかく書類の量産を自動化しても、印刷したり、PDF化したりする作業が全部手作業だというのでは、非効率もはなはだしい。
そういうわけで、作ったのが
このFunctionなのであった。
Functionの改良
Excelからでも使えるように改良してみた。
リスト1 標準モジュール
Public Function setCursor(ByVal targetDoc As Document, _ ByVal targetPage As Long, _ ByVal targetLine As Long, _ ByVal targetCharacter As Long, _ Optional ByVal isToClick As Boolean = True) As Boolean setCursor = False On Error GoTo Finalizer Dim wordApp As Word.Application Set wordApp = targetDoc.Parent Call wordApp.Selection.GoTo(What:=wdGoToPage, _ Which:=wdGoToAbsolute, _ Count:=targetPage) If targetLine = 1 Then 'targetLineが「1」のときは移動しない。' Else Call wordApp.Selection.GoTo(What:=wdGoToLine, _ Which:=wdGoToRelative, _ Count:=targetLine - 1) End If Call wordApp.Selection.MoveRight(Unit:=wdCharacter, _ Count:=targetCharacter, _ Extend:=wdMove) If isToClick Then Selection.Select '……(*)' setCursor = True Finalizer: Set wordApp = Nothing End Function
Selection
オブジェクトは、Word.Application
の配下にあるので、Excelなど他アプリから操作するときは、Word.Application
オブジェクトから指定しないと使えない。
Officeデベロッパー センターの記述によると、
ドキュメント ウィンドウ枠ごとに Selection オブジェクトは 1 つだけであり、アプリケーション全体で 1 つの Selection オブジェクトのみをアクティブにできます。 https://docs.microsoft.com/ja-jp/office/vba/api/word.selection
とのことなので、Word.Application
オブジェクトは、対象のDocumentオブジェクトのParent
プロパティから取得するのが良いと思った。
ちなみに、(*)の
If isToClick Then Selection.Select
は、カーソル位置を移動した後、その部分をクリックする動作を再現したつもり。
これでいいのかどうか、こんなのが必要なのかどうか、は不明。
使ってみる
次のコードで実験。
リスト2 標準モジュール
Public Sub test02() Dim wordApp As New Word.Application wordApp.Visible = True Dim targetDoc As Word.Document Set targetDoc = wordApp.Documents.Open(ThisWorkbook.Path & "\ち~んw.docx") Dim i As Long For i = 1 To 5 Call setCursor(targetDoc, 1, i, 2, True) Call WindowsAPI.waitFor(500) Next Call targetDoc.Close(SaveChanges:=False) Call wordApp.Quit Set wordApp = Nothing End Sub
Excelから、同じフォルダ内にある「ち~んw.docx」というドキュメントを開いて、そのドキュメントの1ページ目にある1行目~5行目までの文字列の2文字目のところをそれぞれクリック(っていうか選択)する、というもの。
一瞬で終わってしまうと何をやっているのかわからないので、1行ごとに0.5秒ウェイトするようにしている。
WindowsAPI
クラスについては、
コチラをどうぞ。
ちょいわかりにくいけど、こんな動作。
おわりに
こちらの情報によると、均等割付を字数単位で指定しているのが原因なのかも知れない。
一度、職場のPCでmm単位で指定して実験してみようと思う。