はじめに
前回の記事、「VBAでDocuWorksAPIを利用して複数のDocuWorks文書を合成して名前をつけて保存する」では、ファイル単位の合成はできますが、実際の業務では複数の様式が混在したファイルを作成したり、整理する必要があります。
DocuWorksDeskではページ操作に関連する機能が利用可能ですが、ページ順を指定しての並び替え、合成を自動化することはできません。
今回は「XDW_GetPage_」と「_XDW_MergeXdwFiles」を組み合わせることで、これを実現します。
目的
単一または複数のDocuWorks文書のページを指定順で合成したい。
処理フロー
1 合成用パス・ページ配列と保存用パスを取得
2 __XDW_GetPage__により合成用Docuworks文書の指定ページを複製し、合成用一時ファイルとして保存する
3 合成用一時ファイルを__XDW_MergeXdwFiles__により合成する
4 合成用一時ファイルを削除する
**サンプルコード**
Option Explicit
'XDW_GetPage DocuWorksファイルの指定のページをコピーして、別の1つのDocuWorks文書にする。
Private Declare PtrSafe Function XDW_GetPage _
Lib "xdwapi.dll" ( _
ByVal handle As LongPtr, _
ByVal nPage As Long, _
ByVal lpszOutputPath As String, _
Optional ByVal reserved As String = vbNullString) As Long
'XDW_OpenDocumentHandle DocuWorksファイルにアクセスするためのハンドルを得る。pHandleはAPIにより変更されるため、ByRefで定義
Private Declare PtrSafe Function XDW_OpenDocumentHandle _
Lib "xdwapi.dll" ( _
ByVal lpszFilePath As String, _
ByRef pHandle As LongPtr, _
ByRef pMode As XDW_OPEN_MODE) As Long
'XDW_CloseDocumentHandle DocuWorksファイルにアクセスするためのハンドルを解放する。
Private Declare PtrSafe Function XDW_CloseDocumentHandle _
Lib "xdwapi.dll" ( _
ByVal handle As LongPtr, _
Optional ByVal reserved As String = vbNullString) As Long
'XDW_MergeXdwFiles 複数のDocuWorks文書を合成して1つのDocuWorks文書を生成する。
Private Declare PtrSafe Function XDW_MergeXdwFiles _
Lib "xdwapi.dll" ( _
ByRef lpszInputPaths As LongPtr, _
ByVal nFiles As Long, _
ByVal lpszOutputPath As String, _
Optional ByVal reserved As String = vbNullString) As Long
Private Type XDW_OPEN_MODE
nSize As Long
nOption As Long
End Type
'******************************************************************************************************
'機能 単一または複数のDocuWorks文書の指定ページ順に合成してDocuWorks文書を生成する。
'引数 inputDwPaths 束ねるDW文書のファイルパス配列 /inputDwPages 束ねるDW文書のページ配列 /outputDwPath 出力パス
'戻値 XDWAPIエラーコード(Long型,16進数)
'備考 合成パス配列の要素数≦ページ番号配列の要素数であること
'******************************************************************************************************
Public Function MergeDwFilesFromPage( _
ByVal inputDwPaths As Variant, _
ByVal inputDwPages As Variant, _
ByVal OutputPath As String) As Long
'合成用DocuWorks文書を作成元Docuworks文書の指定ページから作成
Dim inputL As Long: inputL = LBound(inputDwPaths)
Dim inputU As Long: inputU = UBound(inputDwPaths)
Dim OutputFolderPath As String: OutputFolderPath = Mid$(OutputPath, 1, InStrRev(OutputPath, "\"))
Dim TempDwPaths() As String: ReDim TempDwPaths(inputL To inputU)
Dim TempDwSJISPaths() As String: ReDim TempDwSJISPaths(inputL To inputU)
Dim TempDwPtrs() As LongPtr: ReDim TempDwPtrs(inputL To inputU)
'DW_OPEN_READONLY=0/DW_OPEN_UPDATE=1
Dim OpenMode As XDW_OPEN_MODE
OpenMode.nOption = 0&
OpenMode.nSize = LenB(OpenMode)
Dim pHandle As LongPtr
Dim i As Long
For i = inputL To inputU
TempDwPaths(i) = OutputFolderPath & "dwMergeTemp" & i & ".xdw"
'XDW_MergeXdwFilesのための文字コード変換とポインタ取得
TempDwSJISPaths(i) = StrConv(TempDwPaths(i), vbFromUnicode)
TempDwPtrs(i) = StrPtr(TempDwSJISPaths(i))
'DocuWorksAPI:XDW_GetPageで合成用一時ファイル作成
XDW_OpenDocumentHandle inputDwPaths(i), pHandle, OpenMode
XDW_GetPage pHandle, inputDwPages(i), TempDwPaths(i)
XDW_CloseDocumentHandle pHandle
Next
'DocuWorksAPI:XDW_MergeXdwFilesの呼び出し
Dim fileNum As Long: fileNum = inputU - inputL + 1
MergeDwFilesFromPage = XDW_MergeXdwFiles(TempDwPtrs(inputL), fileNum, OutputPath)
'合成用一時ファイルの削除
For i = inputL To inputU
Kill TempDwPaths(i)
Next
End Function
解説
__XDW_GetPage__を利用するには、__XDW_OpenDocumentHandle__によりDocuWorksのハンドルを取得、XDW_GetPageを呼び出したあと、__XDW_CloseDocumentHandle__によりハンドルを解放する必要があります。
この際、__XDW_OpenDocumentHandle__の引数___pHandle___はAPIにより変更されるため、ByRefで定義しています。
補足
DocuWorksAPIには他に「XDW_InsertDocument」というDocuWorks文書に他のDocuWorks文書を挿入する関数が用意されていますが、APIの処理時間により、一時ファイルの削除を行うKillステートメントでエラーとなる場合があるため、XDW_MergeXdwFilesを利用するほうがコードの量も動作も安定します。
最後に
今回のサンプルは、実際の業務でDocuWorksAPIを活用していく上でかなり汎用性の高い処理になります。
・ワード等からの差し込み文書を束ね直して印刷原稿を作成
・フォーム用DwCtrlコントロールのPrintNoDialog/PrintWithDialogメソッドによる印刷処理用の一時ファイル作成
・ランダム順スキャン文書の分類
など、利用の幅がかなり広くなります。