Poppler:PDFの添付ファイルを保存(抽出)するVBA関数

TOP > Poppler ツール > *


Village Girl

概要

PDFの添付ファイルを指定フォルダに保存するVBA関数です。同時に添付ファイルの数とファイル名も取得できます。

Acrobat OLE を使わずに Poppler の pdfdetach.exe を使用します。

  1. 事前に各種エラーチェック
  2. 「-list」オプションでPDFの添付ファイル数を確認する。
    ゼロ件の時は以降の処理をスキップする。
  3. 添付ファイルのファイル名も抽出する。
  4. 添付ファイルのファイル名が全て半角ならば「-saveall」で一括保存する。
  5. 添付ファイルのファイル名に全角が含まれているならば、1つずつ「-save」で保存する。これはファイル名の文字化けを防ぐためです。

Poppler とは

フリーソフト Poppler を知らない人は先にコチラを御覧ください。

形式

001 Public Sub popSaveEembeddedFiles( _ 002 ByVal popPara_InPdfPath As String, _ 003 ByVal popPara_InPdfPassword As String, _ 004 ByVal popPara_OutFolder As String, _ 005 ByRef popPara_OutFileName() As String, _ 006 ByRef popPara_FileCount As Long, _ 007 ByRef strCmdMsg() As String, _ 008 ByRef strErr As String)


 Highlight:プログラミング言語のソースコードを構文で色分け (GUI編)
 

引数

  1. 第1引数 : popPara_InPdfPath As String  (In)
    入力のPDFファイルのフルパス
  2. 第2引数 : popPara_InPdfPassword As String  (In)
    入力のPDFファイルのユーザーパスワード。無ければ""。
  3. 第3引数 : popPara_OutFolder As String  (In)
    添付ファイルの出力先フォルダ名(フルパス)
  4. 第4引数 : popPara_OutFileName() As String (Out)
    添付ファイルのファイル名
  5. 第5引数 : popPara_FileCount As Long  (Out)
    添付ファイルのファイル数
    第4引数の配列の添字にもなる
  6. 第6引数 : strCmdMsg() As String  (Out)
    コマンドラインで表示された内容

     

    • strCmdMsg(0) : 標準出力
    • strCmdMsg(1) : 標準エラー出力
  7. 第7引数 : strErr As String  (Out)
    プログラム内のエラーメッセージ。エラー無しは ""。

戻り値

無し。

関数 / サンプル

事前設定

  1. コチラを参考にPoppler のダウンロードとインストールを行う。
  2. pdfdetach.exe のフルパスをCON_POPPLER_PATHにセット。
  3. gDebugMode = True のデバッグモードをFalseにセット。

サンプル

  • A-de-007.pdf から添付ファイルを保存します。
  • A-de-007.pdf のユーザーパスワードは「def」です。
  • 保存先フォルダは「D:¥Tools¥PDF¥File¥」です。

DownloadcLine-popSaveEembeddedFiles.xls

001 Option Explicit 002 003 Declare Function WaitForSingleObject Lib "kernel32" _ 004 (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long 005 Declare Function CloseHandle Lib "kernel32" _ 006 (ByVal hObject As Long) As Long 007 Declare Function GetExitCodeProcess Lib "kernel32" _ 008 (ByVal hProcess As Long, lpExitCode As Long) As Long 009 Declare Function OpenProcess Lib "kernel32" _ 010 (ByVal dwDesiredAccess As Long, _ 011 ByVal bInheritHandle As Long, _ 012 ByVal dwProcessID As Long) As Long 013 Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) 014 015 Const SYNCHRONIZE = 1048576 016 Const PROCESS_QUERY_INFORMATION = &H400 017 018 'Poppler-0.45 pdfdetach.exe 019 Const CON_POPPLER_PATH = "D:¥Poppler-0.45¥bin¥pdfdetach.exe" 020 ' Teme File No 021 Private gFileCnt As Long 022 ' Debug Mode [ True=On | False=Off ] 023 Private gDebugMode As Boolean 024 Private Const CON_FOLDER_KUGIRI = "¥" 025 026 ' テスト用呼び出し 027 Sub Main_Demo() 028 gDebugMode = True '実運用ではFalse 029 030 Dim popPara_InPdfPath As String 031 Dim popPara_InPdfPassword As String 032 Dim popPara_OutFolder As String 033 Dim popPara_OutFileName() As String 034 Dim popPara_FileCount As Long 035 036 'pdfdetach.exe コマンドラインからの出力内容 037 Dim strCmdMsg(1) As String 038 'プログラム内の実行エラーでのメッセージ 039 Dim strErr As String 040 Dim i As Long 041 042 '初期化 043 For i = 0 To UBound(strCmdMsg) 044 strCmdMsg(i) = "" 045 Next i 046 047 If gDebugMode Then Debug.Print "Start:" & Now 048 ' Dim j As Long 049 ' For j = 0 To **** 050 051 '入力PDFのフルパス 052 popPara_InPdfPath = Application.ActiveWorkbook.Path & _ 053 CON_FOLDER_KUGIRI & "A-de-007.pdf" '"in1.pdf" ' 054 '入力PDFの(文書を開く時の)ユーザーパスワード 055 popPara_InPdfPassword = "def" 056 '出力先フォルダ(必須:フルパスのみとする) 057 popPara_OutFolder = "D:¥Tools¥PDF¥File¥" 058 059 '関数の呼び出し 060 strErr = "" 061 Call popSaveEembeddedFiles( _ 062 popPara_InPdfPath, popPara_InPdfPassword, _ 063 popPara_OutFolder, popPara_OutFileName(), _ 064 popPara_FileCount, strCmdMsg(), strErr) 065 066 '関数の結果を確認 067 If InStr(strCmdMsg(0), "0 embedded files") > 0 Then 068 '「-list」オプションで添付ファイル数でゼロ件が返された時 069 MsgBox popPara_InPdfPath & vbCrLf & vbCrLf & _ 070 "添付ファイルが存在しませんでした。" & _ 071 vbCrLf & strCmdMsg(0), vbInformation, "お知らせ" 072 Exit Sub 073 ElseIf strErr <> "" Then 074 '関数内のプラグラムでエラーが発生した時 075 MsgBox strErr & vbCrLf & vbCrLf & _ 076 strCmdMsg(0) & vbCrLf & strCmdMsg(1), _ 077 vbCritical, "プログラム内の実行エラー" 078 Exit Sub 079 ElseIf strCmdMsg(1) <> "" Then 080 'コマンドラインの実行時にエラーを返された時 081 MsgBox strCmdMsg(1), _ 082 vbCritical, "コマンドラインの実行エラー" 083 Exit Sub 084 End If 085 086 '添付ファイルが保存できた。正常終了 087 Dim sWkMsg As String 088 sWkMsg = "保存した添付ファイルの数=" & popPara_FileCount 089 For i = 0 To UBound(popPara_OutFileName) 090 sWkMsg = sWkMsg & vbCrLf & _ 091 (i + 1) & "=" & popPara_OutFileName(i) 092 Next i 093 094 '※正常ならばローカルに保存した添付ファイルを別フォルダに移動する。 095 'name 096 'FileCopy 097 'FileSystemObject 等を使う 098 099 ' Next j 100 If gDebugMode Then Debug.Print "End :" & Now 101 102 MsgBox sWkMsg, vbInformation, "終了" 103 'MsgBox "strCmdMsg(0)=" & strCmdMsg(0) & vbCrLf & _ 104 "strCmdMsg(1)=" & strCmdMsg(1) & vbCrLf & _ 105 "strErr=" & strErr, vbInformation, "正常終了" 106 End Sub 107 108 '************************************************** 109 ' 110 ' Save all of the embedded files from the PDF file. 111 ' 112 ' 機能 : Poppler pdfdetach.exeを使って添付ファイルを保存する。 113 ' Create : 2016/07/01 114 ' Update : 2016/07/01 115 ' Vertion : 1.0.0 116 ' 117 ' 第1引数:popPara_InPdfPath As String (In) 118 ' 入力のPDFファイルのフルパス 119 ' 第2引数:popPara_InPdfPassword As String (In) 120 ' 入力のPDFファイルのユーザーパスワード。無ければ""。 121 ' 第3引数:popPara_OutFolder As String (In) 122 ' 添付ファイルの出力先フォルダ名(フルパス) 123 ' 第4引数:popPara_OutFileName() As String (Out) 124 ' 添付ファイルのファイル名 125 ' 第5引数:popPara_FileCount As Long (Out) 126 ' 添付ファイルのファイル数 127 ' 第4引数の配列の添字にもなる 128 ' 第6引数:strCmdMsg() As String (Out) 129 ' コマンドラインで表示された内容 130 ' strCmdMsg(0):標準出力 131 ' strCmdMsg(1):標準エラー出力 132 ' 第7引数:strErr As String (Out) 133 ' プログラム内のエラーメッセージ。エラー無しは ""。 134 ' 戻り値 : 無し 135 ' 136 ' 備考 : strErr<>""の時はエラー扱いとする。 137 ' URL : http://pdf-file.nnn2.com?p=874 138 ' その他 : 著作権等は主張しません。 139 ' 上記URLにコメントを頂けると嬉しいです。 140 ' 141 '************************************************** 142 143 Public Sub popSaveEembeddedFiles( _ 144 ByVal popPara_InPdfPath As String, _ 145 ByVal popPara_InPdfPassword As String, _ 146 ByVal popPara_OutFolder As String, _ 147 ByRef popPara_OutFileName() As String, _ 148 ByRef popPara_FileCount As Long, _ 149 ByRef strCmdMsg() As String, _ 150 ByRef strErr As String) 151 152 On Error GoTo Err_popSaveEembeddedFiles: 153 154 Dim strFilePath As String 155 Dim strTempFilePath(1) As String 156 Dim strCmd As String 157 Dim objFileSystem As Object 158 Dim i As Long 159 160 Const CON_OPTION_LIST = " -list " 161 Const CON_OPTION_SAVE = " -save %1 -o %2 " 162 Const CON_OPTION_SAVEALL = " -saveall " 163 164 '初期化 165 Set objFileSystem = CreateObject("Scripting.FileSystemObject") 166 strErr = "" 167 popPara_FileCount = 0 168 169 'エラーチェック 170 If objFileSystem.FileExists(popPara_InPdfPath) = False Then 171 strErr = popPara_InPdfPath & vbCrLf & _ 172 "[E01]このファイルは存在しません。" 173 Exit Sub 174 End If 175 If popPara_OutFolder = "" Then 176 strErr = "[E02]保存先フォルダがセットされてません。" 177 Exit Sub 178 End If 179 If Dir(popPara_OutFolder, vbDirectory) = "" Then 180 'フォルダが存在しないので作成します 181 If CreateFolder(popPara_OutFolder) = False Then 182 strErr = popPara_OutFolder & vbCrLf & _ 183 "[E03]保存先フォルダが作成出来ませんでした。" 184 Exit Sub 185 End If 186 End If 187 If objFileSystem.FileExists(CON_POPPLER_PATH) = False Then 188 strErr = CON_POPPLER_PATH & vbCrLf & _ 189 "[E04]このファイルは存在しません" 190 Exit Sub 191 End If 192 193 '▼コマンドラインの編集(-list) 194 strCmd = CON_POPPLER_PATH & CON_OPTION_LIST 195 If popPara_InPdfPassword <> "" Then 196 'ユーザーパスワードをセット ★★ 197 strCmd = strCmd & "-upw " & _ 198 popPara_InPdfPassword & " " 199 End If 200 201 '一時ファイル 202 gFileCnt = gFileCnt + 1 203 strFilePath = _ 204 Application.ActiveWorkbook.Path & CON_FOLDER_KUGIRI & _ 205 Format(Now(), "yyyymmdd-hhmmss-") & gFileCnt 206 ' 標準出力用 207 strTempFilePath(0) = strFilePath & ".txt" 208 ' 標準エラー出力用 209 strTempFilePath(1) = strFilePath & "-err.txt" 210 211 '注意:ファイルパスの前後にダブルクォーテーション 212 strCmd = strCmd & _ 213 """" & popPara_InPdfPath & _ 214 """ > """ & strTempFilePath(0) & _ 215 """ 2> """ & strTempFilePath(1) & """" 216 217 'コマンドラインの実行 218 strCmd = "cmd /c " & strCmd 219 Call RunCommandLine(strCmd, strErr) 220 If gDebugMode Then Debug.Print strCmd 221 ' If strErr <> "" Then 222 ' 'コマンドラインでエラー有り 223 ' GoTo popSaveEembeddedFiles_Skip: 224 ' End If 225 226 On Error GoTo popSaveEembeddedFiles_Skip: 227 228 '標準出力のテキストを読み込む 229 Call InputTempFile(strTempFilePath(), strCmdMsg(), strErr) 230 If strCmdMsg(1) <> "" Or strErr <> "" Then 231 'コマンドラインでエラー有り 232 GoTo popSaveEembeddedFiles_Skip: 233 End If 234 235 'コマンドラインでエラー無し 236 237 '▼添付ファイルのファイル名を取得 238 Dim strWk1 239 Dim strWk2 240 Dim bWk() As Byte 241 242 strWk1 = Split(strCmdMsg(0), vbCrLf) 243 '添付ファイルの数を取得 1行目:"x embedded files" 244 strWk2 = Split(strWk1(0), " ") 245 popPara_FileCount = strWk2(0) 246 If popPara_FileCount = 0 Or strWk2(1) <> "embedded" Then 247 '添付ファイル=ゼロ件、又はエラーはスキップ 248 GoTo popSaveEembeddedFiles_Skip: 249 End If 250 251 'ファイル名の抽出 252 ReDim popPara_OutFileName(popPara_FileCount - 1) As String 253 Dim strANSI As String 254 Dim bHenkan() As Boolean 255 ReDim bHenkan(popPara_FileCount - 1) As Boolean 256 Dim lHenkanCnt As Long 257 258 lHenkanCnt = 0 259 For i = 0 To popPara_FileCount - 1 260 strWk2 = Split(strWk1(i + 1), " ") 261 popPara_OutFileName(i) = strWk2(1) 262 'ファイル名に2バイト文字が存在するかをチェック 263 strANSI = StrConv(popPara_OutFileName(i), vbFromUnicode) 264 If Len(popPara_OutFileName(i)) <> LenB(strANSI) Then 265 '全角文字(2バイト文字)が混ざっている 266 bHenkan(i) = True 267 lHenkanCnt = lHenkanCnt + 1 268 Else 269 '半角文字のみ 270 bHenkan(i) = False 271 End If 272 Next i 273 274 '▽コマンドラインの編集 275 '注意:保存先にファイルが存在しても上書きされる。 276 Dim strCmd2 As String 277 278 If lHenkanCnt = 0 Then 279 '添付ファイル名に全角文字は無いので saveall で保存する 280 '▼(-saveall) 281 strCmd = Replace(strCmd, CON_OPTION_LIST, _ 282 CON_OPTION_SAVEALL & "-o " & popPara_OutFolder & " ") 283 'コマンドラインの実行 284 Call RunCommandLine(strCmd, strErr) 285 If strErr <> "" Then 286 'コマンドラインでエラー有り 287 GoTo popSaveEembeddedFiles_Skip: 288 End If 289 If gDebugMode Then Debug.Print strCmd 290 '標準出力のテキストを読み込む 291 Call InputTempFile(strTempFilePath(), strCmdMsg(), strErr) 292 Else 293 294 '添付ファイル名に全角文字が有るので -save で1つずつ保存する。 295 '保存時に文字化けを起こさないようにファイル名を指定する。 296 '▼(-save x ) 297 strCmd2 = Replace(strCmd, CON_OPTION_LIST, CON_OPTION_SAVE) 298 For i = 0 To popPara_FileCount - 1 299 '保存する添付ファイルの番号をセット 300 strCmd = Replace(strCmd2, "%1", i + 1) 301 '保存時のフルパス名をセット 302 strCmd = Replace(strCmd, "%2", _ 303 popPara_OutFolder & CON_FOLDER_KUGIRI & _ 304 popPara_OutFileName(i)) 305 'コマンドラインの実行 306 Call RunCommandLine(strCmd, strErr) 307 If strErr <> "" Then 308 'コマンドラインでエラー有り 309 GoTo popSaveEembeddedFiles_Skip: 310 End If 311 If gDebugMode Then Debug.Print strCmd 312 313 '標準出力のテキストを読み込む 314 Call InputTempFile(strTempFilePath(), strCmdMsg(), strErr) 315 'エラーが有れば、ループを抜ける 316 If strErr <> "" Then Exit For 317 If strCmdMsg(1) <> "" Then Exit For 318 Next i 319 End If 320 321 popSaveEembeddedFiles_Skip: 322 Set objFileSystem = Nothing 323 Exit Sub 324 Err_popSaveEembeddedFiles: 325 strErr = "(popSaveEembeddedFiles) Runtime Error :" & _ 326 Err.Number & vbCrLf & Err.Description & vbCrLf & _ 327 vbCrLf & "PDF File=" & popPara_InPdfPath 328 End Sub 329 330 ' 「添付ファイルの保存先」フォルダを作成する 331 332 Function CreateFolder(ByVal strPath As String) As Boolean 333 Dim objFSO As Object 334 Dim strRet As String 335 Set objFSO = CreateObject("Scripting.FileSystemObject") 336 On Error Resume Next 337 strRet = objFSO.CreateFolder(strPath) 338 If Err.Number = 0 Then 339 'エラー無し 340 CreateFolder = True 341 Else 342 'エラー有り 343 CreateFolder = False 344 If gDebugMode Then Debug.Print "CreateFolder:Error" & _ 345 vbCrLf & Err.Number & ":" & Err.Description & _ 346 vbCrLf & strPath 347 End If 348 Set objFSO = Nothing 349 End Function 350 351 ' コマンドラインの標準出力と標準エラー出力のファイルを 352 ' 読み込む。 353 354 Sub InputTempFile( _ 355 ByRef strTempFilePath() As String, _ 356 ByRef strCmdMsg() As String, _ 357 ByRef strErr As String) 358 On Error GoTo Err_InputTempFile: 359 360 Dim strInput As String 361 Dim lFileNo As Long 362 Dim i As Long 363 364 Dim strBuff As String 365 Dim objStream As Object 366 367 For i = 0 To UBound(strTempFilePath) 368 'UTF-8のファイルを読み込む 369 Set objStream = CreateObject("ADODB.Stream") 370 With objStream 371 .Charset = "UTF-8" 372 .Type = 2 '(1:バイナリ 2:テキスト) 373 .Open 374 .LoadFromFile strTempFilePath(i) 375 strBuff = .ReadText 376 .Close 377 End With 378 Set objStream = Nothing 379 380 strCmdMsg(i) = strBuff 381 Next i 382 383 '一時ファイルの削除 384 If strErr = "" Then 385 For i = 0 To UBound(strTempFilePath) 386 Kill strTempFilePath(i) 387 Next i 388 End If 389 Exit Sub 390 Err_InputTempFile: 391 strErr = "(InputTempFile) Runtime Error :" & _ 392 Err.Number & vbCrLf & Err.Description 393 End Sub 394 395 ' shell 関数の終了を待つ 396 397 Sub RunCommandLine(ByVal strCmd As String, _ 398 ByRef strErr As String) 399 On Error GoTo Err_RunCommandLine: 400 401 Dim hProcess As Long 402 Dim lpdwExitCode As Long 403 Dim dwProcessID As Long 404 Dim lRet As Long 405 Dim lCnt As Long 406 Const CON_SLEEP = 20 407 Const CON_LOOP_CNT = 250 408 lCnt = 0 409 dwProcessID = Shell(strCmd, vbHide) 410 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, _ 411 True, dwProcessID) 412 Do 413 Sleep CON_SLEEP 414 DoEvents 415 lRet = GetExitCodeProcess(hProcess, lpdwExitCode) 416 lCnt = lCnt + 1 417 If lCnt > CON_LOOP_CNT Then 418 If gDebugMode Then Debug.Print vbCrLf & strCmd 419 strErr = "[RunCommandLine]Shell Error : Time Orver " & _ 420 CON_SLEEP * CON_LOOP_CNT & "ms" 421 Exit Sub 422 End If 423 Loop While lpdwExitCode <> 0 424 Exit Sub 425 Err_RunCommandLine: 426 strErr = "(RunCommandLine) Runtime Error :" & _ 427 Err.Number & vbCrLf & Err.Description & vbCrLf & _ 428 vbCrLf & "Command=" & strCmd 429 End Sub


 Highlight:プログラミング言語のソースコードを構文で色分け (GUI編)
 

結果

001 Start:2016/07/01 19:54:16 002 cmd /c ・・・長いので省略・・・ -list  ・・・長いので省略・・・・ 003 cmd /c ・・・長いので省略・・・ -save 1 -o ・・・長いので省略・・・・ 004 cmd /c ・・・長いので省略・・・ -save 2 -o ・・・長いので省略・・・・ 005 cmd /c ・・・長いので省略・・・ -save 3 -o ・・・長いので省略・・・・ 006 End :2016/07/01 19:54:18


 Highlight:プログラミング言語のソースコードを構文で色分け (GUI編)
 

▽正常終了の時

Poppler:PDFの添付ファイルを保存するVBA関数

上記は関数内で編集したメッセージです。

▽ユーザーパスワードが間違っている時

Poppler:PDFの添付ファイルを保存するVBA関数

上記の1段目はプログラム内からのエラーメッセージ。2段目はコマンドラインからのエラーメッセージです。

▽添付ファイルがゼロ件の時

Poppler:PDFの添付ファイルを保存するVBA関数

上記は1段目と2段目はプラグラム内で編集したメッセージです。3段目がコマンドラインからのメッセージです。

結果の判断方法

popSaveEembeddedFiles 関数の戻り値で判断します。以下は優先順位を含めて解説します。

  1. 添付ファイル数でゼロ件が返された時:
    InStr(strCmdMsg(0), "0 embedded files") > 0 の時です。
    strCmdMsg(0)には改行コードも入っているので
    strCmdMsg(0) = "0 embedded files" の判定は出来ない。
  2. 関数内のプラグラムでエラーが発生した時: 
    strErr <> "" の時です。
  3. コマンドラインの実行時にエラーを返された時:
    strCmdMsg(1) <> "" の時です。

詳細はサンプル内の「Sub Main_Demo 」のpopSaveEembeddedFiles 関数使用後の処理コードを参照してください。

001 '関数の呼び出し 002 strErr = "" 003 Call popSaveEembeddedFiles( _ 004 popPara_InPdfPath, popPara_InPdfPassword, _ 005 popPara_OutFolder, popPara_OutFileName(), _ 006 popPara_FileCount, strCmdMsg(), strErr) 007 008 '関数の結果を確認 009 If InStr(strCmdMsg(0), "0 embedded files") > 0 Then 010 '「-list」オプションで添付ファイル数でゼロ件が返された時 011 MsgBox popPara_InPdfPath & vbCrLf & vbCrLf & _ 012 "添付ファイルが存在しませんでした。" & _ 013 vbCrLf & strCmdMsg(0), vbInformation, "お知らせ" 014 Exit Sub 015 ElseIf strErr <> "" Then 016 '関数内のプラグラムでエラーが発生した時 017 MsgBox strErr & vbCrLf & vbCrLf & _ 018 strCmdMsg(0) & vbCrLf & strCmdMsg(1), _ 019 vbCritical, "プログラム内の実行エラー" 020 Exit Sub 021 ElseIf strCmdMsg(1) <> "" Then 022 'コマンドラインの実行時にエラーを返された時 023 MsgBox strCmdMsg(1), _ 024 vbCritical, "コマンドラインの実行エラー" 025 Exit Sub 026 End If 027 028 '添付ファイルが保存できた。正常終了


 Highlight:プログラミング言語のソースコードを構文で色分け (GUI編)
 

PDFの添付ファイル

  1. Poppler:PDFの添付ファイル一覧を取得するVBA関数
  2. PDF の3つのパスワード  ※添付ファイルのパスワードの話

備考

  1. 関数の以下の引数は配列数を宣言してないことに注意。
    関数内でReDim で再宣言するからです。

     

    • Dim popPara_OutFileName()   As String
  2. コマンドラインの標準出力のテキストがUTF-8の為に日本語文字が化けてしまいます。その為のやや複雑な処理が入っています。
  3. この pdfdetach.exe は日本語の扱いが現在は出来ません。VBA関数で操作すると日本語の問題をカバーできるので、かえってこちらのVBA関数の方が便利だと思います。

< Poppler へ戻る


技術メモ

これ以降は当関数に関する作成者の技術メモです。見なくても結構です。後のメンテナンスの時に見ます。

基本

  1. Poppler も Xpdf も pdfdetach.exe の技術仕様は基本的に同じのはずです。
  2. 日本語名の添付ファイルを pdfdetach.exe で保存するとファイル名は文字化けを起こします。Xpdf では日本語の言語ファイルが有るので「-enc Shif-JIS」オプションで日本語は扱えますがファイル名は全て「全角文字」になってしまいます。Poppler であろうと Xpdf であろうと日本語を意識するとファイル名の扱いにどうしようもなく対応に困る問題が出ます。しかし、当関数はその問題を全て解決する様に処理を行っています。半角文字は半角で、全角文字は全角でファイル名を処理しています。
  3. 当VBA関数では添付ファイルを保存する前に添付ファイルのファイル名の一覧を「-list」オプションで取得している。添付ファイルの数とファイル名に日本語が存在するかどうかをチェックする為です。数がゼロならば保存処理は行わない。ファイル名に2バイト文字がある時は「-saveall」オプションでは無く、「-save 」でファイル名を指定して保存するようにしています。
  4. 日本語のファイル名が有る時に「-save」オプションを使う理由は文字化けを防ぐためです。「-saveall 」だとファイル名が文字化けしてしまうからです。それを防ぐために別名で保存する形で正しいファイル名を指定しての保存処理を行います。

標準出力と標準エラー出力について

  1. コマンドラインでの結果を標準出力と標準エラー出力の2つのテキストに出力できます。標準出力は正常の結果内容。標準エラー出力はエラー時のメッセージ内容。たまに逆に出力しているプログラムの有りますが、一応はこの形です。
  2. pdfdetach.exe は標準出力と標準エラー出力を出力しますが。「-save」又は「-saveall」オプションでは両方の出力が無い時が正常終了を意味しています。
  3. 先に「-list」オプションを実行してます。この時は標準出力が合って、標準出力エラーが無い時が正常終了を意味してます。
  4. 標準出力と標準エラー出力共にUTF-8のコードでテキストに出力します。よってVBAで読み込む時は変換して読み込む必要が有ります。つまりVBAの通常のテキスト入力ではダメです。

エラーメッセージの扱い

  1. 当VBA関数でのエラーの判定は優先順位:上が高、下が低。
    1. strErr : VBA関数内でのエラーの内容
    2. strCmdMsg( 1 ) : コマンドラインの標準エラー出力の内容
    3. strCmdMsg( 0 ) : コマンドラインの標準出力の内容
  2. 上記ではstrCmdMsg( 0 )の内容も見る必要があります。理由は添付ファイルを保存する前「-list」オプションを実行し、strCmdMsg( 0 )=「0 embedded files」でないかをチェックする必要があるからです。
  3. strErr も strCmdMsg( 1 ) もブランクの時は正常処理。
  4. 詳細はVBA関数のサンプル「Sub Main_demo」を参照。

< Poppler へ戻る

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


★ 文章での質問は難しいですよネ。でも、早く解決して、家に帰りたい。


SAMURAI Plugin

コメントをする時は出来れば以下もお願いします。

  • OS名 バージョン
  • Acrobat バージョン
  • ツール(Excel等) バージョン
コメントにサンプルコードを入れる時はコードを全て全角文字列にしてください。コチラで半角に戻します。それでもエラーが回避できない時はコメント下さい。個別に対処します。



お仕事で当サイトを見ている方へ
考え込んだら、ご質問下さい。
一緒に解決策を考えましょう。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください