質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

1回答

3824閲覧

VBAでPDFを結合させる場合において、失敗するケース理由がわかりません

pegy

総合スコア243

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

1クリップ

投稿2020/09/23 07:19

こちらのサイトを参考にして特定のフォルダでpdfファイルを結合させるコードを作成しております。

PDF環境
Adobe Acrobat 2017
※サイト内でproが必要となっていますが、参照設定でacrobatが選択できており、問題はないと判断しています。

さて、以下のコードの通り、ループをさせて実行させるとCells(6,4)とCells(7,4)のパスにある_combined.pdfだけ4kbのファイルができて、クリックすると「この文書を開くときにエラーが発生しました。このファイルにはページがないため開けません」というメッセージボックスが出現し、結果としてうまくPDFが結合できていないことがわかりました。反対にCells(4,4)とCells(5,4)はうまく結合できております。それぞれpdfファイルが2つずつ入っており、特に権限等にも差がないように思われます。特に失敗しているpdfファイルだけが重いという特徴もございません、

試したこと

①前半がうまくいっていることから、以下のコードのように、waitで処理時間を待機させてみたのですが、特に効果はありませんでした。

②ループではなく直接Cells(7,4)だけを実行してみたのですが、結果は結合に失敗しました。

八方ふさがりな状況で、何か考えられる原因がわかる方、何卒、アドバイスを願えますでしょうか。
宜しくお願い申し上げます。

vba

1/* 2Cells(4,4) → C:\Users\re\Desktop\2.A会社\#2131_202009AA 3Cells(5,4) → C:\Users\re\Desktop\2.B会社\#2141_202009BB 4Cells(6,4) → C:\Users\re\Desktop\2.C会社\#2153_202009CC 5Cells(7,4) → C:\Users\re\Desktop\2.D会社\#2163_202009DD 6 7*/ 8Option Explicit 9Declare Function StrCmpLogicalW Lib "SHLWAPI.DLL" (ByVal lpStr1 As String, ByVal lpStr2 As String) As Long 10 11 12Sub combine() 13 Dim i As Integer 14 Dim cl As String 15 Dim fn As String 16 17 Dim startTime As Double 18 Dim endTime As Double 19 Dim processTime As Double 20 21 startTime = Timer 22 i = 4 23 Do 24 cl = Cells(i, 4).Value 25 fn = Mid(cl, InStr(cl, "_") + 1) 26 27 If cl = "" Then 28 Exit Do 29 End If 30 31 32 Debug.Print (cl) 33 Call Combine_All_PDF(cl, fn) 34 35 Application.Wait Now + TimeValue("00:00:05") 36 i = i + 1 37 38 Loop 39 endTime = Timer 40 processTime = endTime - startTime 41 MsgBox "処理が完了しました、経過時間は" & processTime & "です。" 42End Sub 43 44 45Sub Combine_All_PDF(filepath As String, filename As String) 46 47 Dim i As Long 48 Dim fs As FileSystemObject 49 Dim basefolder As Scripting.Folder 50 Dim savepath As String 51 Dim st() As String 52 Dim mysubfiles As Scripting.Files 53 Dim mysubfile As Scripting.File 54 55 Set fs = New Scripting.FileSystemObject 56 57 58 59 Set basefolder = fs.GetFolder(filepath) 60 Set mysubfiles = basefolder.Files 61 62 i = 0 63 64 For Each mysubfile In mysubfiles 65 66 If fs.GetExtensionName(Path:=mysubfile) = "pdf" Then 67 ReDim Preserve st(i) 68 st(i) = mysubfile.Path 69 Debug.Print st(i) 70 i = i + 1 71 End If 72 73 Next 74 75'---コード3|抽出したPDFファイルを配列を利用して、名前順に並び替える 76 Dim j As Long 77 Dim tmp As String 78 79 For i = 0 To UBound(st) 80 For j = i To UBound(st) 81 Debug.Print st(i), st(j) 82 If StrCmpLogicalW(StrConv(st(i), vbUnicode), StrConv(st(j), vbUnicode)) > 0 Then 83 tmp = st(i) 84 st(i) = st(j) 85 st(j) = tmp 86 Debug.Print tmp 87 Debug.Print st(i) 88 Debug.Print st(j) 89 End If 90 Next 91 Next 92 93 94'---コード4|名前順にPDFファイルを結合していく 95 Dim AcroPDDocNew As New Acrobat.AcroPDDoc 96 Dim AcroPDDocAdd As New Acrobat.AcroPDDoc 97 Dim acroid As Long 98 Dim acroGetPages As Long 99 Dim acroPages As Long 100 101 acroPages = 0 102 acroid = AcroPDDocNew.Create() 103 104 Dim f As Variant 105 106 For Each f In st 107 acroid = AcroPDDocAdd.Open(f) 108 acroGetPages = AcroPDDocAdd.GetNumPages() 109 acroid = AcroPDDocNew.InsertPages(acroPages - 1, AcroPDDocAdd, 0, acroGetPages, True) 110 acroid = AcroPDDocAdd.Close() 111 acroPages = acroPages + acroGetPages 112 Next 113 114 savepath = filepath & "\" & filename & "_combined.pdf" 115 116 '結合したPDFファイルを最後に保存する 117 118 acroid = AcroPDDocNew.Save(1, savepath) 119 acroid = AcroPDDocNew.Close() 120 121 'オブジェクトを強制開放する 122 123 Set AcroPDDocAdd = Nothing 124 Set AcroPDDocNew = Nothing 125 126End Sub 127

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

radames1000

2020/09/23 08:09

・Cells(6,4)とCells(7,4)のPDFファイル各二つは手動で問題なく開きますか?  ⇒そもそもPDFファイルに問題がないか ・例えばうまくいったCells(4,4)の中のPDFファイルをCells(6,4)に持ってきたらうまく結合されますか? ・逆に、失敗したCells(6,4)の中のPDFファイルをCells(4,4)に持ってきたらうまく結合されますか?  ⇒フォルダに問題がないか
pegy

2020/09/23 08:39

コメントありがとうございます。 ・手動で問題なく開くファイルです ・逆にした場合もそれぞれ開くためフォルダには問題がないようです。 一点、少し特殊な点がわかりました。それぞれのフォルダに入っているPDFが2つ入っているのですが、そのうちの一つは必ず.msgがファイル(アウトルックのメール.msgをhtml化→PDF化したもの)がオリジナルです。 こちらは前回の質問の結果で動作させることができました。 https://teratail.com/questions/292690 ここで、Cells(6,4)とCells(7,4)の.msgファイルをPDF化したものを見ると、後半の1ページないしは2ページに空白のページがPDF上見て取れます。 これはCells(4,4)、Cells(4,5)にの中にある同様の.msgをオリジナルとするファイルには存在しない現象です。 単純に空白のページでも結合されるはずとも思ったのですが、現時点で判明した現象として申し添えます。
pegy

2020/09/23 08:41

もちろん、オリジナルのメールファイル.msgには空白のページは存在しません。今並行して調べているのですが、そもそも.msg → html → pdfの過程でなぜ空白のページができてしまうのかが解明できてはいません。
guest

回答1

0

PDFの構造について簡単に説明します。
(今回に関係する所だけ)
「PDFの中にはn番目からlの長さだけXXXの情報が入っています」という情報一覧があります。
その一覧の情報から本当の情報を抜き出してきます。
これの順番と位置との関係が重要で
PDFを生成するソフトによって変わってきたりします。


Aソフト
・文字列だけ左上から順番に設定。
・次に画像だけ左上から順番に設定。

Bソフト
・文字列画像関係なく左上から順番に設定。

Cソフト
・文字列は先に指定した文字列エリアに設定
・画像は先に指定した画像エリアに設定

これはあくまで「PDFを生成するソフト」が「PDFの仕様をどう解釈したか?」の問題で
良し悪しではありません。

Aソフト、Bソフト、Cソフトで作成したPDFを読み取る際は
各ソフトで決めたPDFのルールに基づき読み取るので問題発生は少ないです。
(初期の頃はPDF読み込みエラーなどによくなりました)

ただ今回の様にPDFをAソフトとCソフトで作った形式を結合しようとすると
問題が発生しやすくなります。
大体が「先に指定したPDFの形式にのっとったPDFの結合方法」を行おうとします。
そうすると「後に指定したPDFの形式と齟齬が発生」する場合があります。
それでも「先に指定したPDFの形式」に強引に合わせようとしますので
結果エラーPDFが出来上がるのです。

できればPDFを生成するソフトを統一するのが一番好ましいのですが
できない場合空のPDFを用意して結合のはじめに指定し残り2ファイルを結合指定してみて下さい。
(空.pdf + A.pdf + B.pdf)
場合にもよりますが、エラーにならない場合があります。

投稿2020/09/23 20:38

kuma_kuma_

総合スコア2506

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pegy

2020/09/24 01:42

コメントを頂き有難うございます。 同じ形式での出力にそろえることができないかと調べてしました。 まず、2つのファイルのうち一つ目は複合機から直接PDFで取得(OCRを挟みますが)するもので、もう一つが上記の追加修正にも記載した「https://teratail.com/questions/292690」に基づき、HTMLを経由してVBAのライブラリを用いて出力したものになります。 前者はハードウェア側の問題もあるので変更は難しいですが、後者について合わせることができないかと検討しております。 今プロパティ等で仰って頂いたような例えばABCのような形式がどれに該当するのかを調べようと思っていたのですが、調べていても見つけることができず、判別することは可能でしょうか? 宜しくお願い申し上げます。
pegy

2020/09/24 03:10

決定的な点が分かりました、msg由来ではなく複合機から取得しているPDFの一部に保護がかかっていることがわかりました。いま、Googleで確認しているのですが、VBAから保護を解除する方法は流石にないですよね?もしご存じであればご教示を頂けると幸いです。 宜しくお願い申し上げます。
kuma_kuma_

2020/09/25 16:21

> VBAから保護を解除する方法 保護を解除する方法はないですね(保護の意味がなくなるので) PDFに対して変更しないようにするのが「保護」ですから今回の結合(A,BファイルからCファイル) の場合影響無いかと思うんですが... > 例えばABCのような形式がどれに該当するのか ソフトは無いですね... 私の場合PDF初期に頃エラーが多かったせいで構造解析してた頃があって知っていたからで
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問