VBAでアノテーションを操作してみよう
いくつかあるアノテーションの中でも、もっとも単純なテキストアノテーションを操作してみます。
基礎資料
動作確認環境
WindowsXP
Excel 2002 SP3
Fuji Xerox DocuWorks Desk 6.2.4
Fuji Xerox DocuWorks API DLL xdwapi.dll 6.2.0.35
参考資料
DocuWorksTM Development Tool Kit 6.2.5 リリースノート
(http://www.fujixerox.co.jp/download/soft/docuworks/pop/dwsdk625/Readme.html)
DocuWorks 6以前のSDKは(http://www.fujixerox.co.jp/download/soft/docuworks/download.html)からダウンロード。
DocuWorks 7のSDKは(http://www.fujixerox.co.jp/product/software/docuworks/download.html)からダウンロード。
実際にXDWAPIを利用する際には、DocuWorks API (XDWAPI)仕様書(XDWAPI.XDW)で、詳細を確認してください。
各種定数やエラーコードなどは、XDWAPIを利用するためのヘッダファイル(xdw_api.h xdwapian.h)に記載されています。
サンプルスクリプト
作成するアノテーション
サンプルスクリプトでは、ドキュワークスファイルD:\test001.xdwの1ページ目にテキストアノテーションを貼り付けます。
設定するテキストアノテーションの属性は以下のとおり。
- 表示文字 : 漢字ひらがなabc
- 位置 : 上端から10cm,左端から10cm
- フォント : MS P明朝
- フォントサイズ : 20pt
- フォントカラー : 赤
- フォントスタイル : 太字
- 背景色 : なし
いつものことですが、xdwapi.dllファイルの場所は、それぞれの環境に合わせて変更して下さい。
では、サンプルスクリプトどうぞ
Option Explicit '動作環境 WindowsXP Excel2002 DocuWorks6.2.4 '2.34 XDW_GetDocumentInformation DocuWorksファイル全体に関わる情報を得る。 Private Declare Function XDW_GetDocumentInformation Lib "D:¥dwsdk625¥XDWAPI¥DLL¥xdwapi.dll" (ByVal handle As Long, ByRef pDocumentInfo As XDW_DOCUMENT_INFO) As Long Private 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ファイルにアクセスするためのハンドルを解放する。 Private Declare Function XDW_CloseDocumentHandle Lib "D:¥dwsdk625¥XDWAPI¥DLL¥xdwapi.dll" (ByVal handle As Long, ByVal reserved As String) As Long '2.64 XDW_OpenDocumentHandle DocuWorksファイルにアクセスするためのハンドルを得る。この場合だけ、pHandleはByRefで定義 Private Declare Function XDW_OpenDocumentHandle Lib "D:¥dwsdk625¥XDWAPI¥DLL¥xdwapi.dll" (ByVal lpszFilePath As String, ByRef pHandle As Long, ByRef pMode As XDW_OPEN_MODE) As Long Private Type XDW_OPEN_MODE nSize As Long nOption As Long End Type '2.73 XDW_SaveDocument 変更を DocuWorks ファイルに反映させる。 Private Declare Function XDW_SaveDocument Lib "D:¥dwsdk625¥XDWAPI¥DLL¥xdwapi.dll" (ByVal handle As Long, ByVal reserved As String) As Long '2.1 XDW_AddAnnotation アノテーションを貼り付ける Private Declare Function XDW_AddAnnotation Lib "D:¥dwsdk625¥XDWAPI¥DLL¥xdwapi.dll" _ (ByVal handle As Long, ByVal nAnnotationType As Long, ByVal nPage As Long, ByVal nHorPos As Long, ByVal nVerPos As Long, ByVal pInitialData As String, ByRef phNewAnnotation As Long, ByVal reserved As String) As Long '2.74 XDW_SetAnnotationAttribute 指定したアノテーションの属性を設定する。 '文字列型設定用 Private Declare Function XDW_S_SetAnnotationAttribute Lib "D:¥dwsdk625¥XDWAPI¥DLL¥xdwapi.dll" Alias "XDW_SetAnnotationAttribute" _ (ByVal handle As Long, ByVal hAnnotation As Long, ByVal lpszAttributeName As String, ByVal nAttributeType As Long, ByVal pAttributeValue As String, ByVal nReserved As Long, ByVal pReserved As String) As Long '長整数型設定用 Private Declare Function XDW_L_SetAnnotationAttribute Lib "D:¥dwsdk625¥XDWAPI¥DLL¥xdwapi.dll" Alias "XDW_SetAnnotationAttribute" _ (ByVal handle As Long, ByVal hAnnotation As Long, ByVal lpszAttributeName As String, ByVal nAttributeType As Long, ByRef pAttributeValue As Long, ByVal nReserved As Long, ByVal pReserved As String) As Long Private Enum XDW_AID 'アノテーションの種類 XDW_AID_TEXT = 32785 XDW_AID_FUSEN = 32794 XDW_AID_STRAIGHTLINE = 32828 XDW_AID_RECTANGLE = 32829 XDW_AID_ARC = 32830 XDW_AID_LINK = 49199 XDW_AID_BITMAP = 32831 XDW_AID_STAMP = 32819 XDW_AID_MARKER = 32795 XDW_AID_POLYGON = 32834 End Enum Private Enum XDW_Color 'カラーの種類(16進数を10進数に変換) XDW_COLOR_NONE = CLng("&H" & "010101") XDW_COLOR_BLACK = CLng("&H" & "000000") XDW_COLOR_MAROON = CLng("&H" & "000080") XDW_COLOR_GREEN = CLng("&H" & "008000") XDW_COLOR_OLIVE = CLng("&H" & "008080") XDW_COLOR_NAVY = CLng("&H" & "800000") XDW_COLOR_PURPLE = CLng("&H" & "800080") XDW_COLOR_TEAL = CLng("&H" & "808000") XDW_COLOR_GRAY = CLng("&H" & "808080") XDW_COLOR_SILVER = CLng("&H" & "C0C0C0") XDW_COLOR_RED = CLng("&H" & "0000FF") XDW_COLOR_LIME = CLng("&H" & "00FF00") XDW_COLOR_YELLOW = CLng("&H" & "00FFFF") XDW_COLOR_BLUE = CLng("&H" & "FF0000") XDW_COLOR_FUCHIA = CLng("&H" & "FF00FF") XDW_COLOR_WHITE = CLng("&H" & "FFFFFF") XDW_COLOR_FUSEN_RED = CLng("&H" & "FFC2FF") XDW_COLOR_FUSEN_BLUE = CLng("&H" & "FFBF9D") XDW_COLOR_FUSEN_YELLOW = CLng("&H" & "64FFFF") XDW_COLOR_FUSEN_LIME = CLng("&H" & "C2FF9D") End Enum Private Const XDW_ATN_Text = "%Text" Private Const XDW_ATN_FontName = "%FontName" Private Const XDW_ATN_FontSize = "%FontSize" Private Const XDW_ATN_FontStyle = "%FontStyle" Private Const XDW_ATN_FontPitchAndFamily = "%FontPitchAndFamily" Private Const XDW_ATN_ForeColor = "%ForeColor" Private Const XDW_ATN_BackColor = "%BackColor" Sub AddAnnotation_Text() Dim strFileName1 As String 'ファイル名 'Docworksを使うための前処理(ここから) Dim lngHandle, lngHandleAnnotation As Long Dim myMode As XDW_OPEN_MODE Dim myInfo As XDW_DOCUMENT_INFO 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 'Docworksを使うための前処理(ここまで) strFileName1 = "D:¥test001.xdw" 'DocuWorksファイルにアクセスするためのハンドルを得る。関数が正常に終了したら0を返す。異常終了したときは、エラーコードを返す。 XDW_OpenDocumentHandle strFileName1, lngHandle, myMode 'DocuWorksファイル全体に関わる情報を得る。 XDW_GetDocumentInformation lngHandle, myInfo 'アノテーションを貼り付ける。 Dim myXDW_AID As XDW_AID '貼り付けるアノテーションの種類 Dim myXDW_ATN As String 'アノテーションの属性名 Dim lngPage, lngHorPos, lngVerPos As Long 'アノテーションを貼るページ、アノテーションのx座標、y座標(単位は1/100mm) myXDW_AID = XDW_AID_TEXT '貼り付けるアノテーションの種類を指定。 lngPage = 1 '1ページ目に貼り付ける lngHorPos = 1000 '10cm lngVerPos = 1000 '10cm XDW_AddAnnotation lngHandle, myXDW_AID, lngPage, lngHorPos, lngVerPos, vbNullString, lngHandleAnnotation, vbNullString '貼り付けたアノテーションの属性を設定する。 Dim myXDW_ATN_Color As XDW_Color Dim strTxt, strAttributeName As String Dim lngFValue As Long myXDW_ATN = XDW_ATN_Text strTxt = "漢字ひらがなabc" '内容文字列の設定 XDW_S_SetAnnotationAttribute lngHandle, lngHandleAnnotation, myXDW_ATN, 1, strTxt, 0, vbNullString myXDW_ATN = XDW_ATN_FontSize 'フォントサイズを設定 lngFValue = 200 '20pt XDW_L_SetAnnotationAttribute lngHandle, lngHandleAnnotation, myXDW_ATN, 0, lngFValue, 0, vbNullString myXDW_ATN = XDW_ATN_ForeColor 'フォントカラーを設定 lngFValue = 255 'red XDW_L_SetAnnotationAttribute lngHandle, lngHandleAnnotation, myXDW_ATN, 0, lngFValue, 0, vbNullString myXDW_ATN = XDW_ATN_FontStyle 'フォントスタイルを設定 lngFValue = 2 'XDW_FS_BOLD_FLAG XDW_L_SetAnnotationAttribute lngHandle, lngHandleAnnotation, myXDW_ATN, 0, lngFValue, 0, vbNullString myXDW_ATN = XDW_ATN_FontName 'フォントフェイス名を設定 strTxt = "MS P明朝" XDW_S_SetAnnotationAttribute lngHandle, lngHandleAnnotation, myXDW_ATN, 1, strTxt, 0, vbNullString myXDW_ATN = XDW_ATN_BackColor '背景色を設定 myXDW_ATN_Color = XDW_COLOR_NONE XDW_L_SetAnnotationAttribute lngHandle, lngHandleAnnotation, myXDW_ATN, 0, myXDW_ATN_Color, 0, vbNullString '変更を DocuWorks ファイルに反映させる。関数が正常に終了したら0を返す。異常終了したときは、エラーコードを返す。 XDW_SaveDocument lngHandle, vbNullString 'DocuWorksファイルにアクセスするためのハンドルを解放する。関数が正常に終了したら0を返す。異常終了したときは、エラーコードを返す。 XDW_CloseDocumentHandle lngHandle, vbNullString End Sub
使用する関数
使用した関数のなかで主要なものは、XDW_AddAnnotationとXDW_SetAnnotationAttribute。
XDW_AddAnnotationについて
アノテーションを貼り付けるために使うXDW_AddAnnotationの形式は以下のとおりです。
形式
int XDW_AddAnnotation(
XDW_DOCUMENT_HANDLE handle, int nAnnotationType, int nPage, int nHorPos, int nVerPos,
XDW_AA_INITIAL_DATA* pInitialData, XDW_ANNOTATION_HANDLE* phNewAnnotation,
void* reserved);
パラメータ
- handle DocuWorks ファイルのハンドル。
- nAnnotationType アノテーションの種類。
- nPage アノテーションを貼るページを指定する。1から始まる。
- nHorPos アノテーションのx座標。単位は1/100mm。
- nVerPos アノテーションのy座標。単位は1/100mm。
- pInitialData 初期値情報。
- phNewAnnotation 貼り付けられたアノテーションへのハンドルが返される。
- reserved 予約引数。NULLでなければならない。
XDW_SetAnnotationAttributeについて
アノテーションの属性を設定するために使うXDW_SetAnnotationAttributeの形式は以下のとおり。
形式
int XDW_SetAnnotationAttribute(
XDW_DOCUMENT_HANDLE handle, XDW_ANNOTATION_HANDLE hAnnotation,
const char* lpszAttributeName, int nAttributeType, char* pAttributeValue, int nReserved,
void* pReserved);
バラメータ
- handle DocuWorks ファイルのハンドル。
- hAnnotation アノテーションのハンドル。
- lpszAttributeName 属性名を指定する。
- nAttributeType 属性値の型情報。
- pAttributeValue 設定する属性値へのポインタ。
- nReserved 予約引数。0でなければならない。
- pReserved 予約引数。NULLでなければならない。
注意点
XDW_SetAnnotationAttribute関数は、第5引数pAttributeValueに、文字列型と長整数型をとります。
サンプルスクリプトの例によると、表示する文字列とフォントフェイス名を設定するときは、文字列型。フォントサイズやフォントカラーなどを設定するときは、長整数形をとります。
ホントは AS Any で定義できるとスマートなのですが、うまくいかなかったので、それぞれ別名で関数を定義することにしました。
XDW_S_SetAnnotationAttributeが文字列型の設定用、XDW_L_SetAnnotationAttributeが整数型の設定用です。
NULLターミネート文字列のポインタ渡し
DLLに文字列を渡すときは常に参照渡しになる
XDW_SetAnnotationAttributeで、第5引数pAttributeValueに、文字列型の値のポインタを渡すのに、苦労した。
SDKによると、「アノテーションに文字列型の属性を設定するときは、nAttributeTypeにXDW_ATYPE_STRINGをpAttributeValueにNULLターミネート文字列へのポインタを指定する。」とある。
ポインタ渡しなら、参照渡しでByRefでしょう!とやってみたものの、エラー。StrPtrで取得したアドレスを ByVal や ByRef で渡したり、As Any にしてもだめ。
で、たどり着いたドキュメントが、これ。
DLL へ引数を渡す方法(http://support.microsoft.com/kb/402464/ja)
ちょっと古い記述のようです。
文字列型
C 言語で扱う文字列は ASCIIZ 文字列 (Null 文字で終了している文字列) です。引数として ASCIIZ 文字列を渡すときは ByVal キーワードを使用する必要があります。
ByVal variable name As String
文字列は常に「参照渡し」になります。ByVal キーワードは「値渡し」という意味ではなく、ASCIIZ 文字列 (C 言語などで使用される 0 で終了する文字列) に変換して渡すという意味なので注意が必要です。また、引数で示した文字列変数に文字列を返す DLL プロシージャの場合、渡した文字列よりも長い文字列を DLL プロシージャが返した場合には、他の領域を破壊しますので注意が必要です。
ASCIIZ?
聞いたことない。
よくお世話になっている@ITの解説(http://www.atmarkit.co.jp/icd/root/17/5785517.html)によると以下のとおり。
終端記号としてNULL(ゼロ)が割り当てられている文字列。
「アスキージー」とか「アスキーゼット」とか読むらしい。
ということは、「NULLターミネート文字列」= ASCIIZ 文字列ということか。
知らなかった。
DLLに文字列型の値をポインタ渡しするときは、ByValキーワードを使う。
文字列は常に「参照渡し」される。ByValでも参照渡し(ポインタ渡し)になって、さらに(ご丁寧に)ASCIIZ 文字列 (NULLターミネート文字列) に変換して渡してくれる。
ひとつ利口になりました。
DLLにnullポインタを渡すときは、String型で宣言してvbNullStringを使う
おせっかいですが、DLL へ引数を渡す方法(http://support.microsoft.com/kb/402464/ja)で、
Null ポインタを渡す必要があるときは、その引数を As Any として宣言し、ByVal 0& を渡します。
とありますが、これは古い記述で、今はvbNullstringが使えます
Office VBA と Windows API (http://msdn.microsoft.com/ja-jp/library/dd296887.aspx)
一部の DLL 関数には、文字列または文字列への null ポインタのいずれかを受け取れる引数を持つものがあります。文字列への null ポインタは、指定した引数を無視することを Windows に指示する特殊なポインタです。長さが 0 の文字列 (“”) とは異なります。このような関数を宣言する場合、以前のバージョンの VBA では、引数を型 Any で宣言するか、2 つのバージョンの DLL 関数を宣言する必要がありました。2 つのバージョンの引数を宣言する場合、1 つは型 String として引数を定義し、もう 1 つは型 Long として定義します。しかし、VBA に文字列への null ポインタを表す vbNullString 定数が含まれるようになったので、null ポインタを渡す必要がある場合には、引数を型 String として宣言し、vbNullString 定数を渡すことができます。
最近のコメント