Excel VBA Just PDF4 または Adobe.Acrobatで複数のPDFファイルを結合させる

#複数のファイルを結合させるときの手順
自動的にPDFファイルを結合させたいという要望のために検索しても前提や手順が思いっているのと違えば参考にならない。
コードの前に、どういう手順で結合しているのかを示す。
この記事では、PDFファイルか、PDFファイルにしたいファイルを一つのフォルダに入れて、Excelでリストを作って、最後にバッチファイルで結合させる。という手順で結合させることを目指す。

##1．一つのフォルダに、結合させたいファイルを集める

 - Win10 + Excel Ver16 以降で確認
 - Just PDF 4または、Adobe Acrobatで結合することを前提
 - 結合するファイルを奥フォルダを、仮に `C:\hoge\pdf結合ファイル\`とする
 - サブフォルダは無視する
 - PDFが入っても容量が足りなくならないほどディスクサイズは大きいとする
 - 20ファイル程度を想定している
 - 画像が入っているファイルを想定している。
 - Accessは通常は印刷しないので、Excelに出力してから以下の手順でPDF化することを想定している。そうでない場合はレポートから出力する。

###NOTE:ファイルの種類はWord、Excel PDFに限定
 - Word
 - Excel
 - PDF

に限定している。

###ほかの形式のファイルは予めPDFに
Publisher, Powerpoint, Textファイル,JPGが考えられるが、これらはPDFに予め変換して上記のフォルダに入れる。

###NOTE:Pageは消しておくことを推奨
Word、Excelでページを付けていることが往々にしてある。
しかし結合時にはじゃまになる。
Pageは最後にAcrobat等でつけるほうが簡単だと思われる。フッター等のページは必要か確認する。
もちろんPDF化を見越してつけている場合はそのままでも良いが、通常は消し忘れているだけというのが多い。

###できれば名前でソートできるように頭に半角数字二桁で順番をつける
予めファイル名が数字順にソートできれば、のちの結合も簡単になる。

##3.PDFを結合させるためのExcelファイルを作成する
これはあとでVBAを提示する。combinePDF.xlsmなどとして、結合ファイルとは別のフォルダに保存するほうが望ましい。

##4.Excelで一覧表を作り、ファイルを並べる

 1. マクロが動くようにオプションを設定し、開発タブを表示させておくこと。またオプションのPDF/Aに準拠のチェックを外すこと。
 2. Excelを起動しで新規ワークブックをつくる。
 3. ALT+F11 ->　ALT+I -> ALT+ M でVBEを開きモジュールを作る。
 4. ALT+T -> ALT+R で参照設定 Word, Microsoft Scripting Rutime, Windows Script Object Model, VBSCript Regular Expression 5.5, Microsoft ActiveX Data Objects Model 6.1 Library, WIAを指定。正規表現とWIAは今回は使っていないが。
 5. 以下のソースをコピーする。
 6. `SheetSetting'を実行する
 7. A1に`C:\hoge\pdf結合ファイル`と入力する
 8. DropDownFileListを実行する
 9. 一旦名前をつけて保存で、結合ファイルをおいているフォルダ以外の場所に、Excelファイルを保存する。

####Picture::参照設定のイメージ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/6fd70f45-3344-9b99-7f2c-f28bcefb20d2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/d270cf7b-6fda-38c4-f4fc-9bbf6f8ef559.png)

###ファイルの順番等を確認
基本的に結合したいファイルに付番していればソートも簡単になるが、以下を確認する

 - 順番が正しく揃っているか（上から下へ並んで結合される）
 - Excelファイルは全シートに印刷範囲が設定されていること。なお、拡大縮小の場合は、「次のページ数に合わせて印刷」で設定しておくほうが、確実に印刷される。％で指定していると、ページが分割される場合がある。[1 ページに収める](https://support.microsoft.com/ja-jp/office/1-%E3%83%9A%E3%83%BC%E3%82%B8%E3%81%AB%E5%8F%8E%E3%82%81%E3%82%8B-f3015be3-e007-4762-90a7-19ebc8052511)
 - VBS、Batファイルは除外すること。
 - 結合しないファイルがリストに存在しないこと。
 - Publisher、PowerPointで、作成し予めPDF化したファイルについては、そのPDFファイルがA列に存在すること
 - 注意：既存のExportASで出力したPDFファイルは削除されるので、必要な場合は別のフォルダに保存すること

##5.マクロを実行
### コードの手直し、再出力時のオプションの変更の確認
いよいよPDFと結合するためのバッチファイルを作成する
Acrobatの場合は、その前に、combine.vbsファイルの位置を決めて、必要であればコードを変更する。（手順6にも影響）
また、画質が落ちる場合にはオプションを変更する。もしくはあとで再出力する。（手順7.と関連）

###このファイル以外のExcelファイル、及び、Wordファイル、PDFファイルを終了する
特に今から作るPDFファイルを開いているとエラーになるので、必ず終了させる。

###マクロの実行
以上のような準備を行って、
UTFBATCombine
を実行する。
そうすると`C:\hoge\pdf結合ファイル\`に

 - Combine.bat
 - CombineAdobePDF.bat
 - CombineAdobePDFU8.bat

が作成される。

##6.ADDB PDFで結合させる場合上記の結合ファイルのフォルダに、Combine.vbsを作成して入れる（例外あり）
[Acrobatを使ってPDFファイルを結合するVBScript](https://www.ka-net.org/blog/?p=10764)
ソースはきぬあさ氏。これを`combine.vbs`として保存。
###Note:最近のメモ帳(notepad.exe)は保存するときにANSIを強制しないと起動オプションが効かないらしい
このVBSciptはANSIで作成すること。ほかがUTF-8なのでうっかり作りがちなので要注意。
<b>現在のWindows10では、Win+R `Notepad.exe /a`で起動しても今はANSIにならないようだ。</b>
ここについて確認したところ、ファイル名を指定しなければオプションが効かなくなっている。
なので、上記のフォルダを前提にすると

```bat
notepad /a "C:\hoge\pdf結合ファイル\combine.vbs"
```

のようにファイル名を指定し、オプションを前置する。
上記のコードは、「ファイル名を指定して実行」でも cmd.exeを起動しても、自動的にメモ帳が起動し、ANSIファイルが作成される。

きぬあさ氏のソースをコピーして上書き保存する。
上記のコードを使わずにメモ帳を起動した場合は、
ソースをコピーして、
ファイル 名前を付けて保存でANSIに変更、すべてのファイルにする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/a7d76669-53fd-49a1-db88-4d75f351b6f9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/bdab8668-c038-cf6b-5c53-cc58dcb53daf.png)

combine.vbsで保存する。

###注意:Combine.vbsはサーバーの場合はCドライブに置くこと
Acrobatの場合、今回はローカルで作成しているので作動するが、コマンドプロンプトの特性を考えるとサーバーでは動かないことも考えられる。
##7.ファイルの出来上がりを確認し、バッチファイルで結合
<b>JustPDF4の場合</b> `Combine.bat`を実行 出来上がるファイルは combined.pdfに固定。多分Just PDF 4の設定によると思うが、batの場合、重複ファイルがあると枝番がつく。
<b>Acrobatの場合</b>  `CombineADOBEPDF.bat`を実行。こちらは別の`Combine.vbs`を呼び出すことで、ドラッグアンドドロップと同じ効果を出す。combine.vbsの場所があっていないと失敗する。また、環境依存文字がある場合等は `CombineAdobePDFU8.bat`を実行する。こちらのファイル名はタイムスタンプで決定する。

##8.出来上がり具合を確認
基本的にサイズを小さくしているので、少し画質は落ちる。これがだめな場合は、標準で出力するようにVBAのオプションを変える。

- 縦、横は違う方向に回転していないか
- ページの大きさは適切か。
- 結合されず入っていないページがないか。
- 画像は荒れすぎていないか
- 印刷が切れていないか
- フッター、ヘッダー等が余計についていないか
- プロパティの情報を消すべきか

などを確認すること。
すでにバッチファイルが出来上がっているので、手直しがあるファイルだけ、PDFを再出力する。
こうすることで、何度でもPDFを結合し直すことができる。

##9.ページ番号つけなど
この辺はアクションスクリプト等で自動化しておく。
ある程度マニュアル化し、ページ番号に使うフォントの種類、サイズ、位置を決めておくこと。
ファイルを結合し直すことがよくあるため、ここは自動化で処理できるように細かい設定をしないこと。
（例、縦横があっても、下につけるなど。）

# Excelのコード

```vb
Option Explicit

Sub SheetSetting()
' For Microsoft Excel
' PDFを作るためのファイル一覧表を作成する
' 参照設定については本コードのソースhttps://qiita.com/Q11Q/items/ea51244937291a7689edのページを参照
' 2021/12/10 UPTDATE
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet: Set ws = ActiveSheet
Dim ws1 As Worksheet
Cells.Select
Selection.Clear
    Range("B1").Value = "<-ここにフルパス（最後は円記号なし）"
    Range("A2") = "ファイル名"
    Range("G2") = "combined.pdf"
    Range("H2").Value = "<-完成するファイル名。これと同じファイル名は使用しないこと。違う場合はフルパスで入力。"
    Range("F2") = "PDFファイル"
    Range("A2").Select
    Columns("A:A").ColumnWidth = 15.13
    Cells.Select
    Selection.RowHeight = 27

    With Selection.Font
        .Name = "MS UI Gothic"
        .Size = 9
        .Strikethrough = False
        .Superscript = False
        .Subscript = False
        .Underline = xlUnderlineStyleNone
        .TintAndShade = 0
        .ThemeFont = xlThemeFontNone
    End With
ws.Activate
On Error Resume Next
   Range("B1").ClearComments
   Range("B1").AddComment
   Range("B1").Comment.Visible = False
   Range("B1").Comment.Text Text:="このA1に入ったパスのフォルダのファイルだけ操作する。サブフォルダは操作しない。"
   Range("A2").Select
   Range("A2").ClearComments
   Range("A2").AddComment
   Range("A2").Comment.Visible = False
   Range("A2").Comment.Text Text:="フルパスのファイル名のうち、フォルダ名を除いた分" & Chr(10) & "C:\hoge\test.txtなら" & Chr(10) & "test.txtのみ入る"
' シート名 の決定
If ws.Name <> "BuildPDF" Then
  For Each ws1 In wb.Worksheets
    If ws.Name <> ws1.Name And ws1.Name = "BuildPDF" Then
       Exit Sub ' 他に同名(BuildPDF)のシートがあれば終了
    End If
  Next
End If
ws.Select
If ws.Name <> "BuildPDF" Then ws.Name = "BuildPDF"
End Sub

Sub DropDownFileList()
' A1に入っているフォルダのファイルを展開する
' UPDATE 20121/12/08
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet: Set ws = ActiveSheet
Dim Rng As Range
Dim iRow As Long, iCol As Long, LastRow As Long, LastCol As Long
Dim WSH As New IWshRuntimeLibrary.WshShell
Dim FSO As New Scripting.FileSystemObject
Dim strPath As String
Dim oFolder As Scripting.Folder
Dim oFile As Scripting.File
Dim sExt As String
LastRow = ws.Range("A1:A" & Rows.Count).End(xlUp).Row
If LastRow > 3 Then Range("A3:AA" & LastRow).Clear
iRow = 3
If FSO.FolderExists(Range("A1")) Then
  WSH.CurrentDirectory = Range("A1")
  strPath = Dir(CurDir)
  Set oFolder = FSO.GetFolder(CurDir)
  'If ofolder.Files > 100 Then Exit Sub ' 100以上は一応カット
  For Each oFile In oFolder.Files
    If oFile.Name <> "combined.pdf" Then
      ' 2021/12/07 拡張子フィルタ実装
      sExt = LCase(FSO.GetExtensionName(oFile.Path))
      If sExt = "pdf" Or sExt Like "xls*" Or sExt Like "doc*" Then
       If wb.FullName <> oFile.Path Then
        Cells(iRow, 1) = oFile.Name
        iRow = iRow + 1
       End If
      End If
    End If
  Next
End If
End Sub

Sub UTFBATCombine()
' For Excel VBA
' 参照設定 Word WScript.Shell FileSystemObject RegExp
' UPDATE 20121/12/10
Dim wb As Workbook, wb1 As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet: Set ws = wb.Worksheets("BuildPDF")
Dim Rng As Range
Dim iRow As Long, iCol As Long, LastRow As Long, LastCol As Long
Dim wApp As New Word.Application, wDoc As Word.Document
Dim sr As New ADODB.Stream
Dim WSH As New IWshRuntimeLibrary.WshShell
Dim FSO As New Scripting.FileSystemObject ' Scripting.FileSystemObject 関連
Dim oFolder As Scripting.Folder, oFile As Scripting.File, strPath As String, strExt As String, strFile As String, strPDF As String
Dim TS As TextStream, BufScript As String ' Acrobat 専用
Dim Reg As New RegExp, iMatch As Long, subM As SubMatches, MC As MatchCollection, M As Match ' 正規表現用
strPath = ws.Range("A1")
If FSO.FolderExists(strPath) = False Then
Exit Sub
Else
WSH.CurrentDirectory = strPath
LastRow = ws.Range("A" & Rows.Count).End(xlUp).Row
End If
' Just PDF 4用の処理 Block 1
sr.Charset = "UTF-8"
sr.LineSeparator = adCRLF
sr.Mode = adModeReadWrite
sr.Type = adTypeText
sr.Open
sr.WriteText "@Echo OFF" & vbCrLf & "ChCp 65001" & vbCrLf & "CD /C C:" & vbCrLf & "CD %programfiles(x86)%", adWriteLine
strPDF = FSO.BuildPath(strPath, "combined.PDF") ' 出力するファイル名
If strPDF <> Range("G2") Then
If LCase(FSO.GetExtensionName(Range("G2"))) = "pdf" Then
strPDF = Range("G2")
End If
End If
sr.WriteText "IF EXIST" & Chr(32) & """" & strPDF & """" & Chr(32) & "DEL" & Chr(32) & """" & strPDF & """"
sr.WriteText "CD JustSystems", adWriteLine
sr.WriteText "CD JustPdf4 && CD Creator", adWriteLine
sr.WriteText "JustPdf4CmdCreator.exe /combine", adWriteChar
' --<end>---- Just PDF 4用の処理　 Block 1
For iRow = 3 To LastRow
strFile = FSO.BuildPath(strPath, Cells(iRow, 1))
strExt = FSO.GetExtensionName(strFile)
Select Case True
' Excel 97-2003
Case LCase(strExt) = "xls"
On Error Resume Next
Set wb1 = Excel.Application.Workbooks.Open(strFile, False, True, , , , True, , , , False, , False): DoEvents
  If Err.Number <> 0 Then
    Debug.Print strFile & " not open. ", Err.Number, Err.Description
    Err.Clear
  Else
  strPDF = FSO.BuildPath(strPath, FSO.GetBaseName(strFile) & ".PDF")
  If Dir(strPDF) <> "" Then Kill strPDF
    wb1.Activate
    ActiveWorkbook.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
        strPDF, Quality:= _
        xlQualityMinimum, IncludeDocProperties:=False, IgnorePrintAreas:=False, _
        OpenAfterPublish:=False: DoEvents
    wb1.Close False: DoEvents
    Set wb1 = Nothing
    Cells(iRow, 6) = FSO.GetBaseName(strPDF) & ".PDF"
  End If
' Excel 2007 Later
Case LCase(strExt) Like "xls*"
On Error Resume Next
Set wb1 = Excel.Application.Workbooks.Open(strFile, False, True, , "", "", True, , , False, False, , False): DoEvents
  If Err.Number <> 0 Then
    Debug.Print strFile & " not open. ", Err.Number, Err.Description
    Err.Clear
  Else
    strPDF = FSO.BuildPath(strPath, FSO.GetBaseName(strFile) & ".PDF")
     If Dir(strPDF) <> "" Then Kill strPDF
    wb1.Activate
    ActiveWorkbook.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
      strPDF, Quality:= _
      xlQualityMinimum, IncludeDocProperties:=False, IgnorePrintAreas:=False, _
      OpenAfterPublish:=False: DoEvents
    wb1.Close False: DoEvents
    Set wb1 = Nothing
    Cells(iRow, 6) = FSO.GetBaseName(strPDF) & ".PDF"
  End If
' Word doc 97 - 2003
Case LCase(strExt) = "doc"
On Error Resume Next
Set wDoc = wApp.Documents.Open(strFile, False, True, False, "", "", False, "", "", wdOpenFormatDocument97)
  If Err.Number <> 0 Then
    Debug.Print Err.Number, Err.Description
    Err.Clear
   Set wDoc = wApp.Documents.Open(strFile, False, True, False, "", "", False, "", "", wdOpenFormatAuto): DoEvents
  End If
  On Error GoTo 0
  strPDF = FSO.BuildPath(strPath, FSO.GetBaseName(strFile) & ".PDF")
  If Dir(strPDF) <> "" Then Kill strPDF
  'wDoc.ExportAsFixedFormat2 strPDF, wdExportFormatPDF, False, wdExportOptimizeForOnScreen, wdExportAllDocument, , , wdExportDocumentContent, True, False, wdExportCreateNoBookmarks, True, True, False, True: DoEvents
  wDoc.ExportAsFixedFormat strPDF, wdExportFormatPDF, False, wdExportOptimizeForPrint, wdExportAllDocument, , , wdExportDocumentContent, False, False, wdExportCreateNoBookmarks, False, True, False: DoEvents
  wDoc.Close False
  Cells(iRow, 6) = FSO.GetBaseName(strPDF) & ".PDF"
' Word 2007docx,docm
Case LCase(strExt) Like "doc?"
  strPDF = FSO.BuildPath(strPath, FSO.GetBaseName(strFile) & ".PDF")
  If Dir(strPDF) <> "" Then Kill strPDF
  Set wDoc = wApp.Documents.Open(strFile, False, True, False, "", "", False, "", "", wdOpenFormatAuto): DoEvents
  'wDoc.ExportAsFixedFormat2 strPDF, wdExportFormatPDF, False, wdExportOptimizeForOnScreen, wdExportAllDocument, , , wdExportDocumentContent, True, False, wdExportCreateHeadingBookmarks, True, True, False, True: DoEvents
  wDoc.ExportAsFixedFormat strPDF, wdExportFormatPDF, False, wdExportOptimizeForPrint, wdExportAllDocument, , , wdExportDocumentContent, False, False, wdExportCreateNoBookmarks, False, True, False: DoEvents
  wDoc.Close False: DoEvents
  Cells(iRow, 6) = FSO.GetBaseName(strPDF) & ".PDF"
' PDF
Case LCase(strExt) Like "pdf"
  Cells(iRow, 6) = Cells(iRow, 1)
  strPDF = FSO.BuildPath(strPath, Cells(iRow, 1))
' Publisher Powerpointはとりあえずやらない独自でPDFで出力してから結合すること
' Word Excel PDF以外は無視する
Case Else
  Cells(iRow, 6) = ""
End Select
'　成功したら列挙する
If Cells(iRow, 6) <> "" Then
'　sr.WriteText Chr(32) & """" & FSO.BuildPath(strPath, strPDF) & """", adWriteChar ' Just PDF 4
sr.WriteText Chr(32) & """" & strPDF & """", adWriteChar ' Just PDF 4
BufScript = BufScript & Chr(32) & """" & strPDF & """" ' Acrobat
End If
Next
' Just PDF 4用の処理 Block 2
strFile = FSO.BuildPath(strPath, "combine.bat")
strPDF = FSO.BuildPath(strPath, "combined.PDF") ' 出力するファイル名
If strPDF <> Range("G2") Then strPDF = Range("G2")
If Dir(strFile) <> "" Then Kill strFile
sr.WriteText Chr(32) & "/out" & Chr(32) & """" & strPDF & """", adWriteLine
sr.WriteText "ChCp 932", adWriteLine
sr.WriteText "@Echo ON", adWriteLine
sr.SaveToFile strFile, adSaveCreateNotExist
sr.Close
' --<end>---- Just PDF 4用の処理　 Block 2

' Adobe PDF の場合( Just PDF4 を使う場合は　以下、39行は不要なので、コメントアウトするか削除する 上記のAdober pdf用の変数の宣言、ステートメント等も削除してよい）
' combine.vbs自体はきぬあさ氏のところからコードを借りる
' strFile = FSO.BuildPath(strPath, "CombineAdobePDFANSi.bat")
' If Dir(strFile) <> "" Then Kill strFile
' Set TS = FSO.OpenTextFile(strFile, ForWriting, True, TristateUseDefault)
strFile = FSO.BuildPath(strPath, "Combine.vbs") ' 他のファイルと同じフォルダにあるときはこちら
'strFile = "%USERPROFILE%\OneDrive\ドキュメント\Combine.vbs" ' サーバーの場合は、ローカルに設定するこちらを使う（きぬあさ氏のところからコードを借りる）
strFile = FSO.BuildPath(strPath, "CombineAdobePDF.bat")
If Dir(strFile) <> "" Then Kill strFile
Set TS = FSO.OpenTextFile(strFile, ForWriting, True, TristateUseDefault) ' TristateTrue = -1 UTF-16LE TristateUseDefault = -2 ANSI
strFile = FSO.BuildPath(strPath, "Combine.vbs")
'strFile = "%USERPROFILE%\OneDrive\ドキュメント\Combine.vbs" ' サーバーの場合は、ローカルに設定するためこちらを使う
On Error Resume Next
TS.WriteLine "@Echo Off" & vbCrLf & "ChCp 932" ' 日本語を想定 言語が違う場合はここは異なる
BufScript = """%windir%\system32\CScript.exe""" & Chr(32) & """" & strFile & """" & Chr(32) & "//Nologo" & BufScript
TS.WriteLine BufScript
On Error GoTo 0
If Err.Number <> 0 Then
TS.Close
Err.Clear
Else
TS.WriteLine "@Echo ON" & vbCrLf & "ChCp 932" '日本語の場合標準が932
TS.Close
End If
' 文字化けする場合、UTF-8バッチファイルも同時に作るのでCombineAdobePDFU8.batを使うこと
strFile = FSO.BuildPath(strPath, "CombineAdobePDFU8.bat")
If Dir(strFile) <> "" Then Kill strFile
sr.Charset = "UTF-8"
sr.LineSeparator = adCRLF
sr.Mode = adModeReadWrite
sr.Type = adTypeText
sr.Open
sr.WriteText "@Echo Off" & vbCrLf & "ChCp 65001", adWriteLine
' Replaceでバッチファイルの名前だけ変える
BufScript = Replace(BufScript, "CombineAdobePDF.bat", "CombineAdobePDFU8.bat", 1, 1, vbTextCompare)
sr.WriteText BufScript, adWriteLine
sr.WriteText "chcp 932", adWriteLine ' 日本語を想定 言語が違う場合はここは異なる
sr.WriteText "@echo on", adWriteLine
sr.SaveToFile strFile
sr.Close
'　--<End>----　 Adobe PDFで結合させる Jst PDF4の場合はここまでの行を削除する
' Wordが起動しているときは強制終了
On Error Resume Next
wApp.Quit
End Sub
```

#Point
##PDFファイルを小さくする大雑把な方法
個別にPDF化し、バッチファイルで結合するため、差し替えるファイルだけバッチファイルで何度も結合をやり直せる。
そこで、ファイルサイズを小さくする方法は、絶対とは言えないが、

 -　Office系は、ExportASの設定で、予め小さくPDFにして、結合させたほうが、全体の容量が小さくなる可能性が高い。
 -　Excelのページ設定は%ではなく、横1ページ 縦1ページの設定にする。まれに勝手にページが分割される。
 -　また、結合させたあとから圧縮するよりきれいにできる。
 -　つまり、画像がある場合は、標準ではなくスクリーン用で出力し、結合させたほうがファイルサイズが膨張しない。
 -　Word等の構造化タグ、情報等を削除すると僅かに落ちる。結合したときの作用が不明。
 -　Officeは1.4で出力しているらしいので、PDFのバージョンを上げる。
 -　それでもだめなときは画質を落とす。
 -　Page付を自動化しておくと、手直しだけに集中できる。

という順序でサイズを小さくする。この辺は深入りすると本当に深いので、省略。


##Officeの各ExportAsFixedFormatの違い
###Word
https://docs.microsoft.com/ja-jp/office/vba/api/word.document.exportasfixedformat
https://docs.microsoft.com/ja-jp/office/vba/api/word.document.exportasfixedformat2

ExportAsFixedFormat (OutputFileName, ExportFormat, ***OpenAfterExport***, ***OptimizeFor***, Range, From, To, Item, IncludeDocProps, KeepIRM, CreateBookmarks, DocStructureTags, BitmapMissingFonts, UseISO19005_1, FixedFormatExtClassPtr)

ExportAsFixedFormat2 (OutputFileName, ExportFormat, OpenAfterExport, OptimizeFor, Range, From, To, Item, IncludeDocProps, KeepIRM, CreateBookmarks, DocStructureTags, BitmapMissingFonts, UseISO19005_1, <font color="Red">OptimizeForImageQuality</Font>, FixedFormatExtClassPtr)

#### 2との違い
OptimizeForImageQualityだけが違う。通常は使わないのでどちらでも良い。
しかし、画像がある場合には重要となる。
画像がある場合の最適化で出現する

とりあえず画像を1枚貼って実験した結果。
構造化タグはTrueだとそれだけで40kB消費する。また、小さい画像では構造化タグがあると、画像の最適化オプションがTrueでもFalseでも同じサイズになった。
True Falseで比較すると、1のほうが容量が小さい。
2における画像の最適化は、最小（スクリーン用）では全く無効であり、印刷用になって初めて効いてきた。
また、2のほうが出力が遅い。
#### どちらを使うか
マクロの記録だと1が使われる。
また、2でコードを組んで実行すると原因不明のエラーが起きる。これは出力が遅いことに起因しているのかもしれない。
容量のことを考えても1が安定してマクロが挙動する。
2を使うのは印刷用でかつ、画像をを最適化しない、つまり、印刷所へ納入するときなどであると思われる。
####重要な設定と微妙な設定
#####重要
Optimizefor 画面用の方にする。[wdexportoptimizefor](https://docs.microsoft.com/ja-jp/office/vba/api/word.wdexportoptimizefor)
OpenAfterExport　必ずFalse そうしないとPDFが開いて大変なことになる
Range 全部出力が通常と考えられる [wdExportAllDocument](https://docs.microsoft.com/ja-jp/office/vba/api/word.wdexportrange)
Item [wdExportDocumentContent](https://docs.microsoft.com/ja-jp/office/vba/api/word.wdexportitem)変更履歴は通常含めない。そしてこのときの定数が wdExportDocumentContent = 0  逆に含めるときは wdExportDocumentWithMarkup ＝ 7(2021/12/07追加)
KeepIRM xps形式で出力しないので、通常False
BitmapMissingFonts True必須 フォントのライセンスでPDFへフォントの埋め込みを許可しない場合は、この引数をtrue。省略してもTrue。ただし画面では「フォントの埋め込みが不可能な場合はテキストをビットマップに変換する」という表記になっており、若干意味合いが違う。
[フォントの埋め込みが不可能な場合はテキストをビットマップに変換する 2015.08.30 Sunday](http://selfishjelly.marine-moon.com/?eid=100)
> 印刷屋さんのマニュアルを見ているときに、「フォントの埋め込みが不可能な場合はテキストをビットマップに変換する」をチェックしている印刷屋さんと「ISO 19005-1に準拠（PDF/A）」にチェックしている印刷屋さんといろいろあります。

#####微妙
UseISO19005_1 これはPDF/Aを設定する。この設定はデフォルトのFalseにしたほうが透過画像に影響しない。しかしPDF/Aが標準なので悩ましい。
IncludeDocProps 基本は不要と思われる
CreateBookmarks　ここも結合時の挙動が不明。削除(wdExportCreateNoBookmarks)が0なので、本来は削除が正しいかもしれない。このため、挙動が不安定な97-2003ファイル形式は wdExportCreateNoBookmarks としている。2007以降ではwdExportCreateHeadingBookmarks をつけている。また、この機能を使い、PDFのブックマーク（しおり）にするにはアウトラインレベルを決定する必要がる。
DocStructureTags  一応 True これも結合時の挙動が不明。
OptimizeForImageQuality　上で画面用を選んでいる場合には圧縮しなくてよいと思われるが、標準のFalseでよいと思われる。
### Excel
[Workbook.ExportAsFixedFormat](https://docs.microsoft.com/ja-jp/office/vba/api/excel.workbook.exportasfixedformat)

####Excelは手動でしかPDF/Aの設定が変えられない
https://excel-ubara.com/excelvba1/EXCELVBA439.html
WordのIO19005_1がオプションのPDF/Aに準拠に相当するのだが、ExcelはVBAで設定できない。手動でしか設定を変更できない。
このチェックを外さないと、透過画像が真っ黒になってしまう。

####Excelにはフォントをビットマップにするオプションがない
ExcelはWordや他のOfficeアプリケーションと比較すると、BitmapMissingFontsオプションがない。
Excelの場合、JustPDF4はアドインとして追加できる。この場合はBitmap化オプションがある。
なぜExcelだけないのかがわからない。

### 97-2003形式をPDF化するときの挙動
Wordの場合は、オプションを簡略化しないとうまく動かない
Excelは、wb1．Activateで明示的にActiveにしないとPDFにならない。現在のVersion 16 は97-2003系を開くと、もとのファイルにActiveWindowが勝手に移動する。Excelの場合、自動記録で取得すると、PDF化するのはActiveWordkBookではなくAcitiveWindowらしい。
このため、勝手にフォーカスが移動すると、PDF化に失敗する。このため、Activateが必要。
このへんの理由は現在不明

### PowerPoint Publisher
https://docs.microsoft.com/ja-jp/office/vba/api/powerpoint.presentation.exportasfixedformat
ExportAsFixedFormat ( Path , FixedFormatType, Intent , FrameSlides, HandoutOrder, OutputType, PrintHiddenSlides, PrintRange , RangeType, SlideShowName, IncludeDocProperties, KeepIRMSettings, DocStructureTags, BitmapMissingFonts, UseISO19005 _ 1, ExternalExporter)
https://docs.microsoft.com/ja-jp/office/vba/api/powerpoint.presentation.exportasfixedformat2
ExportAsFixedFormat2 ( Path , FixedFormatType, Intent, FrameSlides, HandoutOrder, OutputType , PrintHiddenSlides, PrintRange, RangeType , SlideShowName , IncludeDocProperties, KeepIRMSettings, DocStructureTags, BitmapMissingFonts, UseISO19005_1, IncludeMarkup, ExternalExporter)

https://docs.microsoft.com/ja-jp/office/vba/api/publisher.document.exportasfixedformat
ExportAsFixedFormat ( Format , FileName, Intent , IncludeDocumentProperties , ColorDownsampleTarget, ColorDownsampleThreshold, OneBitDownsampleTarget, OneBitDownsampleThreshold, From, , Copies , Collate, PrintStyle, DocStructureTags, BitmapStructureTags , BitmapMissingFonts, UseISO19005_1, ExternalExporter)

いずれもWordを理解していると、差異だけ理解すれば良い。
Powerpointはスライドの設定が細かい。やはり2があるがIncludeMarkupが違っている。
PublisherはPDFなど印刷に特化しているだけあって、画像圧縮のしきい値が存在する。WordのExportAsFixesdFormatの
OptimizeForImageQualityもこれを簡略化してオプションにしていると考えられる。

### UTF-8のBatファイル
[バッチファイルを UTF-8 で書く](https://itpc.blog.fc2.com/blog-entry-193.html)
[UTF-8のバッチファイルが文字化けする時の対処3選](https://nayutari.com/batch-utf8)
UTF-8形式で作成したバッチファイルは通常は動かない。
しかしChcp 65001を最初にかませると動く。
これによって機種依存文字を使ったバッチファイルが可能となった。
また、Acrobatの場合、VBSはANSIしかない。このため、ファイル名に機種依存文字があれば通常は文字化けして動かない。しかし、同様にバッチファイルをUTF-8にして機種依存文字があるファイルを列挙し、そこからVBSを起動すると、問題がないらしい。
何れにせよバッチファイルがUTF-8で書けるようになったことがわかったのは今回とても大きい。
また、意外なことにAcrobat本家は結合がコマンドラインでできる前提になっていない。きぬあさ氏のコードも本当によくできている。
非常に癖があるが、Just PDFシリーズのほうがコマンドラインで結合が可能であるというのも驚く。

###以前はUTF-8では作成できなかった
しかし、たしかに

[【Windows 10対応】Windowsのバッチファイルの基本的な使い方](https://atmarkit.itmedia.co.jp/ait/articles/1506/26/news026.html)
2018年03月08日 05時00分 公開のITメディアでは、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/2e02b551-6566-9bc1-4311-64a4e531721b.png)
>　Windows OSのバッチファイルは単なるテキストファイルである。そのため、メモ帳などを使って実行したいコマンド列を列挙し、文字コードを「ANSI」あるいは「Shift-JIS」形式にして保存すればよい（「Unicode」や「UTF-8」形式は不可）。ファイルの拡張子は「.bat」か「.cmd」のいずれかにしておく。どちらでも違いはないが、今なら.cmdでよいだろう。

と記載されている。以下の記事も2018年なので、何らかの変更があったのだろう。メモ帳の標準がUTF-8に変更したのだから必要な変更である。

### UTF-16LEは無理のようだ
[コマンドプロンプトでUnicode(UTF-8,UTF-16)を扱う2013-12-19 19:16:31](https://diarywind.com/blog/e/cmd-unicode.html)
>UTF-8はコードページ65001、UTF-16LEはコードページ850で扱うことができます。コマンドプロンプトでコードページを変更するにはchcp 65001やchcp 850を実行します。ただし注意点が2つあります。（略）

ならば、UTF-16LEならどうかというと、これはbatファイルを読み込むときにエラーを起こしてしまう。このため、ChCpで切り替わらない。UTF-8は読み込まれる。
なおchcp 850は

[Windows 文字コードページ一覧 (Windows Tips)](https://www.ipentec.com/document/windows-codepage-list)
> 850	ibm850	Western European (DOS)	西ヨーロッパ語 (DOS)

と解説されている。
https://docs.microsoft.com/ja-jp/windows/win32/intl/code-page-identifiers
も同様。なのでUTF-16LEはどうも無理なようだ。

# 参考文献

[Excel（エクセル）のファイルをPDFに変換、保存する方法｜範囲選択やパスワードの設定に関して プラウ](https://prau-pc.jp/excel/create-a-pdf2/)
パスワードの設定はできないが、オプションについての解説
[アクセシビリティの高い PDF ファイルを作成する](https://support.microsoft.com/ja-jp/topic/%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B7%E3%83%93%E3%83%AA%E3%83%86%E3%82%A3%E3%81%AE%E9%AB%98%E3%81%84-pdf-%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B-064625e0-56ea-4e16-ad71-3aa33bb4b7ed)
 > PDF ファイルにアクセシビリティ タグを追加すると、スクリーン リーダーやその他の支援技術による、目次、ハイパーリンク、ブックマーク、代替テキストなどを含む文書の読み上げや移動が簡単になります。 また、アクセシビリティ タグを追加すると、大型ディスプレイ、携帯情報端末 (PDA)、携帯電話などのさまざまなデバイスの情報を読み上げられるようになります。 Windows、Office for Mac、Office for Web では、PDF 形式でファイルを保存するときに自動的にタグを追加できます。

[ExcelをPDF化するとずれる！【理想通りに】変換する方法](https://chieryoku.com/excel-pdf-change/)
こちらでは縮小率で解決している。

[旧バージョンの印刷プレビュー（全画面表示）を使うには 初心者のためのOffice講座](https://hamachan.info/win7/excel/qinsatu.html)
>クイックアクセスツールバーの［印刷プレビューと印刷］
［印刷プレビュー(全画面表示)］をクイックアクセスツールバーに追加

非常に重要なテクニックなので、必ず追加が望ましい。