艱難辛苦の末、DocuWorks API(XDWAPI)のxdwapi.dllを使って、ドキュワークスファイルをJPEGやPDFファイルに変換するスクリプトができました。
このスクリプトで設定値を変えれば、解像度、カラー、圧縮形式を指定してファイル変換できます。
動作確認環境はWindowsXP、Excel2002、DocuWorks6.2です。
このスクリプトを動作させるには、FUJI XEROX社のDocuWorksがインストールされている必要があります。
また、DocuWorks APIを使うためは、DocuWorksのバージョンにあったDLLファイルが必要です。今回使ったxdwapi.dllはDocuWorks Development Tool Kit 6.2.5 日本語版(dwsdk625.exe)に含まれているものを使い、(http://www.fujixerox.co.jp/download/soft/docuworks/download301.html)からダウンロードしました。
※ここから先の記述について、素人の記載ですので、参考程度にしてくださいね。また、誤りがありましたら、ご指摘いただけるとうれしいです。
今回、ドキュワークスファイルをJPEGやPDFファイルに変換するために使った関数「XDW_ConvertPageToImageFile」は次の引数をとります。
XDW_ConvertPageToImageFile(XDW_DOCUMENT_HANDLE handle, int nPage, const char* lpszOutputPath, XDW_IMAGE_OPTION* pImageOption)
4個の引数のうち、最後のpImageOptionには、構造体XDW_IMAGE_OPTION_EXのポインタを指定します。
構造体XDW_IMAGE_OPTION_EXの内容は次のとおり。
int nSize
int nDpi
int nColor
int nImageType
void* pDetailOption
ドキュワークスファイルをPDFファイルに変換する場合、void*型のpDetailOptionに構造体XDW_IMAGE_OPTION_PDFのポインタを指定します。
ちなみに構造体XDW_IMAGE_OPTION_PDFの内容は次のとおり。
int nSize
int nCompress
int nConvertMethod
int nEndOfMultiPages
図示すると、こんな関係になっています。
pImageOption
↑
構造体XDW_IMAGE_OPTION_EX
——————
| int nSize |
| int nDpi |
| int nColor |
| int nImageType |
| void* pDetailOption —– 構造体XDW_IMAGE_OPTION_PDF
———————–
| int nSize |
| int nCompress |
| int nConvertMethod |
| int nEndOfMultiPages |
———————–
さて、VBAで構造体を扱うときは、ユーザー定義の変数を使うということは分かっているので、2つの構造体「XDW_IMAGE_OPTION_EX」と「XDW_IMAGE_OPTION_PDF」に対応したユーザー定義変数を作成します。
今回のポイントは、「構造体XDW_IMAGE_OPTION_EXのpDetailOptionに、構造体XDW_IMAGE_OPTION_PDFのポインタを指定する」ところ。
ユーザー定義変数は値型です。
なので、今回のスクリプトの定義を流用して表現すると、
myImageOptionEx.pDetailOption = myImageOptionPDF ——-(1)
としてみたのですが、うまくいきません。値型をそのまま入れているけど、XDW_ConvertPageToImageFile関数へは参照渡しにしてるからいいかな?と思ったのですが、だめです。ここは仕様のとおりvoid*型であるpDetailOptionへはmyImageOptionPDFのポインタを渡さなければならないらしい。
そこで、VBAの隠し関数「VarPtr」を使いました。この関数は、変数のメモリアドレスを返します。マイクロソフトのサポート(http://support.microsoft.com/kb/199824/ja)によると、Visual Basicには、メモリアドレスを取得するため、次の5つの関数が提供されているようです。
VarPtr – は、変数のアドレスを返します。
VarPtrArray – 配列のアドレスを返します。
StrPtr – UNICODE 文字列バッファーのアドレスを返します。
VarPtrStringArray – 文字列の配列のアドレスを返します。
ObjPtr – オブジェクト変数によって参照されるインターフェイスへのポインターを返します。
VBAにはVarPtr、StrPtr、ObjPtrしか見当たりません。残りの2つはVBAにないのかな?
で、(1)は次のようになりました。
myImageOptionEx.pDetailOption = VarPtr(myImageOptionPDF) ——-(1′)
これで、pDetailOptionに、構造体XDW_IMAGE_OPTION_PDFのポインタを渡せました。
余談ですが、これらの構造体をクラス化することもチャレンジしたのですが、なかなかうまくいきません。
さて、それではサンプルスクリプトです。
宣言部と、サブプロシージャGetImageFromXDW_EX1とGetImageFromXDW_EX2があります。
GetImageFromXDW_EX1はD:\test001.xdwをD:\test001.pdfに変換する単純なスクリプトです。スクリプトの構成はこちらのほうが分かりやすいと思います。
GetImageFromXDW_EX2は、inputboxを使った簡単なユーザー対話型のスクリプトになっています。順番に入力をしていくとビットマップ、TIFF、JPEG、PDFファイルが作れます。手っ取り早く使ってみたい方は、こちらをどうぞ。
あ、以前にも書きましたが、宣言部のxdwapi.dllの配置場所は、各自で修正してください。
‘=======================スクリプトここから======================= ‘———————–宣言部 ここから———————– ’2.34 XDW_GetDocumentInformation DocuWorksファイル全体に関わる情報を得る。 Public Declare Function XDW_GetDocumentInformation Lib "D:\XDW\dwsdk625\XDWAPI\DLL\xdwapi.dll" (ByVal handle As Long, ByRef pDocumentInfo As XDW_DOCUMENT_INFO) As Long Public Type XDW_DOCUMENT_INFO nSize As Long ‘構造体XDW_DOCUMENT_INFOのバイト数を設定する。 nPages As Long ’総ページ数。 nVersion As Long ‘DocuWorksファイルのファイルフォーマットのバージョン。 nOriginalData As Long ‘オリジナルデータの数。 nDocType As Long ‘ファイルの種類。 nPermission As Long ‘認可情報。 nShowAnnotations As Long ‘アノテーションの表示状態。 nDocuments As Long ‘nDocTypeがバインダーである場合はバインダーの内部DocuWorks文書数を示す。 nBinderColor As Long ’nDocTypeがバインダーである場合はバインダーの色を示す。 nBinderSize As Long ‘nDocTypeがバインダーである場合はバインダーのサイズを示す。 End Type ’2.6 XDW_CloseDocumentHandle DocuWorksファイルにアクセスするためのハンドルを解放する。 Public Declare Function XDW_CloseDocumentHandle Lib "D:\XDW\dwsdk625\XDWAPI\DLL\xdwapi.dll" (ByVal handle As Long, ByVal reserved As String) As Long ’2.64 XDW_OpenDocumentHandle DocuWorksファイルにアクセスするためのハンドルを得る。この場合だけ、pHandleはByRefで定義 Public Declare Function XDW_OpenDocumentHandle Lib "D:\XDW\dwsdk625\XDWAPI\DLL\xdwapi.dll" (ByVal lpszFilePath As String, ByRef pHandle As Long, ByRef pMode As XDW_OPEN_MODE) As Long Public Type XDW_OPEN_MODE nSize As Long nOption As Long End Type ’2.8 XDW_ConvertPageToImageFile DocuWorksファイルのページからイメージファイルを生成する。 Public Declare Function XDW_ConvertPageToImageFile Lib "D:\XDW\dwsdk625\XDWAPI\DLL\xdwapi.dll" (ByVal handle As Long, ByVal nPage As Long, ByVal lpszOutputPath As String, ByRef pImageOption As XDW_IMAGE_OPTION_EX) As Long Public Type XDW_IMAGE_OPTION_TIFF nSize As Long ‘構造体XDW_IMAGE_OPTION_TIFFのバイト数を設定する。 nCompress As Long ‘圧縮形式を指定する。 nEndOfMultiPages As Long ‘マルチページで出力したいときに指定する。 End Type Public Type XDW_IMAGE_OPTION_JPEG nSize As Long ‘構造体XDW_IMAGE_OPTION_JPEGのバイト数を設定する。 nCompress As Long ‘圧縮形式を指定する。 End Type Public Type XDW_IMAGE_OPTION_PDF nSize As Long ‘構造体XDW_IMAGE_OPTION_PDFのバイト数を設定する。 nCompress As Long ‘圧縮形式を指定する。 nConvertMethod As Long ‘MRC圧縮するときに変換方法を指定する。 nEndOfMultiPages As Long ‘マルチページで出力したいときに指定する。nPageからここで指定したページまでを単一のPDFファイルとして出力する。 End Type Public Type XDW_IMAGE_OPTION_EX nSize As Long ’構造体XDW_IMAGE_OPTION_EXのバイト数を設定する。 nDpi As Long ‘解像度。10~600dpiの範囲の整数値。 nColor As Long ‘XDW_IMAGE_MONOのときは白黒、XDW_IMAGE_MONO_HIGHQUALITYのときは白黒 (高画質)、 XDW_IMAGE_COLORのときはカラーを示す。 nImageType As Long ‘イメージの種類を指定する。 pDetailOption As Long ‘variant,XDW_IMAGE_OPTION_PDF以外ならok、それ以外は-2147024809エラー End Type ‘———————–宣言部 ここまで———————– ‘———プロシージャ「GetImageFromXDW_EX1」 ここから——— ‘D:\test001.xdwをD:\test001.pdfに変換。 Sub GetImageFromXDW_EX1() Dim strFileName1, strFileName2 As String ‘Docworksを使うための前処理(ここから) Dim lngHandle As Long Dim myMode As XDW_OPEN_MODE Dim myInfo As XDW_DOCUMENT_INFO Dim myImageOptionEx As XDW_IMAGE_OPTION_EX Dim myImageOptionJPEG As XDW_IMAGE_OPTION_JPEG Dim myImageOptionPDF As XDW_IMAGE_OPTION_PDF With myMode ’XDW_OpenDocumentHandleを実行する際のmyModeに値を設定 .nOption = 1 ‘ #define XDW_OPEN_READONLY 0 ‘ #define XDW_OPEN_UPDATE 1 .nSize = LenB(myMode) End With With myInfo ’XDW_GetDocumentInformationを実行する際のmyInfoに値を設定 .nSize = LenB(myInfo) End With With myImageOptionJPEG .nCompress = 0 ’XDW_COMPRESS_NORMAL 0 劣化有 標準(JPEG) (default) ‘XDW_COMPRESS_HIGHQUALITY 2 劣化有 高画質(JPEG) ‘XDW_COMPRESS_HIGHCOMPRESS 3 劣化有 高圧縮(JPEG) .nSize = LenB(myImageOptionJPEG) End With With myImageOptionPDF .nCompress = 8 ‘#define XDW_COMPRESS_MRC_NORMAL 8 ‘#define XDW_COMPRESS_MRC_HIGHQUALITY 9 ‘#define XDW_COMPRESS_MRC_HIGHCOMPRESS 10 ‘#define XDW_COMPRESS_NORMAL 0 ‘#define XDW_COMPRESS_HIGHQUALITY 2 ‘#define XDW_COMPRESS_HIGHCOMPRESS 3 .nConvertMethod = 0 ‘#define XDW_CONVERT_MRC_ORIGINAL 0 ‘#define XDW_CONVERT_MRC_OS 1 .nEndOfMultiPages = 0 ‘マルチページで出力したいときに指定する。 ‘ nPageからここで指定したページまでを単一のPDFファイル ‘ として出力する。0またはnPageと同じ場合はシングルページ ‘ となる (default)。負の値や、正でnPageより小さい場合は ‘ エラーとなる。文書の総ページ数より大きかった場合は、 ‘ nPageから総ページ数までをマルチページで出力する。 .nSize = LenB(myImageOptionPDF) End With With myImageOptionEx .nDpi = 300 .nColor = 1 ’#define XDW_IMAGE_MONO 0 ‘#define XDW_IMAGE_COLOR 1 ‘#define XDW_IMAGE_MONO_HIGHQUALITY 2 .nImageType = 3 ‘#define XDW_IMAGE_DIB 0 ‘#define XDW_IMAGE_TIFF 1 ‘#define XDW_IMAGE_JPEG 2 ‘#define XDW_IMAGE_PDF 3 .pDetailOption = VarPtr(myImageOptionPDF) .nSize = LenB(myImageOptionEx) End With ‘Docworksを使うための前処理(ここまで) strFileName1 = "D:\test001.xdw" str FileName2 = "D:\test001.pdf" ‘DocuWorksファイルにアクセスするためのハンドルを得る。関数が正常に終了したら0を返す。異常終了したときは、エラーコードを返す。 XDW_OpenDocumentHandle strFileName1, lngHandle, myMode ‘DocuWorksファイル全体に関わる情報を得る。 XDW_GetDocumentInformation lngHandle, myInfo ‘DocuWorksファイルのページからイメージファイルを生成する。 MsgBox XDW_ConvertPageToImageFile(lngHandle, 1, strFileName2, myImageOptionEx) ‘DocuWorksファイルにアクセスするためのハンドルを解放する。関数が正常に終了したら0を返す。異常終了したときは、エラーコードを返す。 XDW_CloseDocumentHandle lngHandle, vbNullString End Sub ‘———プロシージャ「GetImageFromXDW_EX1」 ここまで——— ‘———プロシージャ「GetImageFromXDW_EX2」 ここから——— ‘ユーザー対話型で、ファイル変換。 Sub GetImageFromXDW_EX2() Dim strFileName1, strFileName2 As String ‘変換対象ファイル名と出力ファイル名 strFileName1 = "D:\test001.xdw" ‘変換対象ファイルのパス strFileName2 = "D:\test001." ‘出力ファイルのフルパスのデフォルト値 Dim lngPageNo_first, lngPageNo_end As Long ’変換開始ページ、変換終了ページ Dim lngnImageType As Long ‘ユーザーが選択したイメージタイプ Dim lngConvertPageToImageFile_Err As Long ‘XDW_ConvertPageToImageFileのエラーコード ‘変換対象ファイル名の確認 strFileName1 = InputBox("変換対象のドキュワークスファイルのフルパスを指定してください。", , strFileName1) Dim lngHandle As Long Dim myMode As XDW_OPEN_MODE Dim myInfo As XDW_DOCUMENT_INFO Dim myImageOptionEx As XDW_IMAGE_OPTION_EX With myMode ’XDW_OpenDocumentHandleを実行する際のmyModeに値を設定 .nOption = 1 ‘ #define XDW_OPEN_READONLY 0 ‘ #define XDW_OPEN_UPDATE 1 .nSize = LenB(myMode) End With ‘DocuWorksファイルにアクセスするためのハンドルを得る。関数が正常に終了したら0を返す。異常終了したときは、エラーコードを返す。 XDW_OpenDocumentHandle strFileName1, lngHandle, myMode With myInfo ’XDW_GetDocumentInformationを実行する際のmyInfoに値を設定 .nSize = LenB(myInfo) End With ‘DocuWorksファイル全体に関わる情報を得る。 XDW_GetDocumentInformation lngHandle, myInfo ‘出力ファイルのイメージタイプ、変換開始ページ、変換終了ページを指定。 lngnImageType = InputBox("ビットマップ→0" & Chr(13) & Chr(10) & _ "TIFF→1" & Chr(13) & Chr(10) & _ "JPEG→2" & Chr(13) & Chr(10) & _ "PDF→3" & Chr(13) & Chr(10) _ , "変換後のイメージタイプを指定", 3) lngPageNo_first = InputBox("ドキュワークス文書の総ページ数は" & myInfo.nPages & "ページです。" _ & Chr(13) & Chr(10) & "変換開始ページを入力してください。", "変換開始ページを指定", 1) If lngnImageType = 1 Or lngnImageType = 3 Then lngPageNo_end = InputBox("ドキュワークス文書の総ページ数は" & myInfo.nPages & "ページです。" _ & Chr(13) & Chr(10) & "変換終了ページを入力してください。", "変換終了ページを指定", myInfo.nPages) End If ‘指定した出力ファイルのイメージタイプ別にXDW_IMAGE_OPTION_EX構造体を定義。 Select Case lngnImageType Case 0 ‘lngnImageType=0、すなわちXDW_IMAGE_DIB:ビットマップに変換する場合。 With myImageOptionEx .nImageType = lngnImageType End With strFileName2 = strFileName2 & "bmp" ‘出力ファイル名に拡張子を付加 Case 1 ‘lngnImageType=1、すなわちXDW_IMAGE_TIFF:TIFFに変換する場合。 Dim myImageOptionTIFF As XDW_IMAGE_OPTION_TIFF With myImageOptionTIFF .nCompress = 4 ’XDW_COMPRESS_NOCOMPRESS 4 圧縮なし (default) ’XDW_COMPRESS_PACKBITS 6 Packbits圧縮 ’XDW_COMPRESS_JPEG 5 JPEG圧縮 (画質は「標準」固定) ’XDW_COMPRESS_G4 7 G4(MMR)圧縮 .nEndOfMultiPages = lngPageNo_end .nSize = LenB(myImag eOptionTIFF) End With With myImageOptionEx .nImageType = lngnImageType .pDetailOption = VarPtr(myImageOptionTIFF) End With strFileName2 = strFileName2 & "tiff" ‘出力ファイル名に拡張子を付加 Case 2 ‘lngnImageType=2、すなわちXDW_IMAGE_JPEG:JPEGに変換する場合。 Dim myImageOptionJPEG As XDW_IMAGE_OPTION_JPEG With myImageOptionJPEG .nCompress = 0 ’XDW_COMPRESS_NORMAL 0 劣化有 標準(JPEG) (default) ’XDW_COMPRESS_HIGHQUALITY 2 劣化有 高画質(JPEG) ’XDW_COMPRESS_HIGHCOMPRESS 3 劣化有 高圧縮(JPEG) .nSize = LenB(myImageOptionJPEG) End With With myImageOptionEx .nImageType = lngnImageType .pDetailOption = VarPtr(myImageOptionJPEG) End With strFileName2 = strFileName2 & "jpeg" ‘出力ファイル名に拡張子を付加 Case 3 ‘lngnImageType=3、すなわちXDW_IMAGE_PDF:PDFに変換する場合。 Dim myImageOptionPDF As XDW_IMAGE_OPTION_PDF With myImageOptionPDF .nCompress = 8 ‘#define XDW_COMPRESS_MRC_NORMAL 8 ‘#define XDW_COMPRESS_MRC_HIGHQUALITY 9 ‘#define XDW_COMPRESS_MRC_HIGHCOMPRESS 10 ‘#define XDW_COMPRESS_NORMAL 0 ‘#define XDW_COMPRESS_HIGHQUALITY 2 ‘#define XDW_COMPRESS_HIGHCOMPRESS 3 .nConvertMethod = 0 ‘#define XDW_CONVERT_MRC_ORIGINAL 0 ‘#define XDW_CONVERT_MRC_OS 1 .nEndOfMultiPages = 6 ‘マルチページで出力したいときに指定する。 ‘ nPageからここで指定したページまでを単一のPDFファイル ‘ として出力する。0またはnPageと同じ場合はシングルページ ‘ となる (default)。負の値や、正でnPageより小さい場合は ‘ エラーとなる。文書の総ページ数より大きかった場合は、 ‘ nPageから総ページ数までをマルチページで出力する。 .nSize = LenB(myImageOptionPDF) End With With myImageOptionEx .nImageType = lngnImageType .pDetailOption = VarPtr(myImageOptionPDF) End With strFileName2 = strFileName2 & "pdf" ‘出力ファイル名に拡張子を付加 End Select With myImageOptionEx .nDpi = 300 .nColor = 1 ’#define XDW_IMAGE_MONO 0 ‘#define XDW_IMAGE_COLOR 1 ‘#define XDW_IMAGE_MONO_HIGHQUALITY 2 ‘「nImageTypeとpDetailOptionは上記のSelect文中で設定してあるのでスキップ」 ‘ .nImageType = lngnImageType ‘#define XDW_IMAGE_DIB 0 ‘ ‘#define XDW_IMAGE_TIFF 1 ‘ ‘#define XDW_IMAGE_JPEG 2 ‘ ‘#define XDW_IMAGE_PDF 3 ‘ .pDetailOption = VarPtr(myImageOptionPDF) .nSize = LenB(myImageOptionEx) End With ‘出力ファイル名の確認 strFileName2 = InputBox("出力ファイル名を指定してください。", , strFileName2) ‘DocuWorksファイルのページからイメージファイルを生成する。 lngConvertPageToImageFile_Err = XDW_ConvertPageToImageFile(lngHandle, lngPageNo_first, strFileName2, myImageOptionEx) Select Case lngConvertPageToImageFile_Err Case 0 MsgBox "ファイルの作成が成功しました", vbInformation Case Else MsgBox "ファイルは作成できませんでした。" & Chr(13) & Chr(10) & _ "エラーメッセージ(10進数):" & lngConvertPageToImageFile_Err & Chr(13) & Chr(10) & _ "エラーメッセージ(16進数):" & Hex(lngConvertPageToImageFile_Err) _ , vbExclamation End Select ‘DocuWorksファイルにアクセスするためのハンドルを解放する。関数が正常に終了したら0を返す。異常終了したときは、エラーコードを返す。 XDW_CloseDocumentHandle lngHandle, vbNullString End Sub ‘———プロシージャ「GetImageFromXDW_EX2」 ここまで——— ‘=======================スクリプトここまで=======================
今回のまとめ。
APIで提供されている関数で、構造体のポインタを引数にとる場合。
1.構造体をユーザー定義型の変数で作成し、ByRefすなわち参照渡しにすれば、そのユーザー定義型の変数のアドレスが渡せる。
2.その構造体の内容に、さらに構造体が含まれていて、構造体の要素(void*型)に構造体のポインタを渡さなければならないとき、ユーザー定義型変数をそのまま渡すとエラーになるので、VarPtr関数を使い、ユーザー定義型変数のメモリ上のアドレスを渡す。
更新ありがとうございます。
かなり勉強になりましたし、大変助かりました。
こちらの情報をおかげでかなりの効率化が可能となり
大変助かりました。
本当にありがとうございます!
kishiさん、どういたしまして。
役に立ててよかったです。日常の作業が楽になると嬉しいですよね。
こちらも、とても勉強になりました。
機会があったら、またお越しください(^О^ノ~
はじめまして、こちらの書き込みを見させてもらい、処理が上手くいきました。
大変有難うございました。
一つご質問があり、書き込みいたしました。
xdwファイルに入っている複数ページをばらすコーディングをしたいのですが、インタネット上で探しても中々見つかりません。
お知恵を貸していただければ助かります。
宜しく御願いいたします。
TOSHIさん、こんにちは。
記事の内容がお役に立てたようで、うれしいです。
さて、「xdwファイルに入っている複数ページをばらすコーディング」とのことですが、何かスクリプトをかいてみようと思います。
気長に待っていてくださいね (^ー゚)ノ