Since I also happen to have need for this functionality and have been putting it off I went ahead and fleshed this out a little more. I wrote a function PDFtkMerge that accepts an array of filenames and an output file name and merges them. Again, this requires PDFtk to be installed in the user's computer (or more specifically PDFtk Server, the command line tool). Make sure the executable path at the top of the module is correct. I've collected all the code necessary to make this work in a single module file for you. At the very bottom of the file you'll find a test sub that demonstrates the usage of the merge function:
Code:
Option Compare Database
Option Explicit
'https://www.pdflabs.com/docs/pdftk-man-page/
Const PDFtkPath As String = "C:\Program Files (x86)\PDFtk\bin\pdftk.exe"
Function FileExists(ByVal strFile As String, Optional bFindFolders As Boolean) As Boolean
'Purpose: Return True if the file exists, even if it is hidden.
'Arguments: strFile: File name to look for. Current directory searched if no path included.
' bFindFolders. If strFile is a folder, FileExists() returns False unless this argument is True.
'Note: Does not look inside subdirectories for the file.
'Author: Allen Browne. http://allenbrowne.com June, 2006.
Dim lngAttributes As Long
'Include read-only files, hidden files, system files.
lngAttributes = (vbReadOnly Or vbHidden Or vbSystem)
If bFindFolders Then
lngAttributes = (lngAttributes Or vbDirectory) 'Include folders as well.
Else
'Strip any trailing slash, so Dir does not look inside the folder.
Do While Right$(strFile, 1) = "\"
strFile = Left$(strFile, Len(strFile) - 1)
Loop
End If
'If Dir() returns something, the file exists.
On Error Resume Next
FileExists = (Len(Dir(strFile, lngAttributes)) > 0)
End Function
Function FolderExists(strPath As String) As Boolean
On Error Resume Next
FolderExists = ((GetAttr(strPath) And vbDirectory) = vbDirectory)
End Function
Function TrailingSlash(varIn As Variant) As String
If Len(varIn) > 0 Then
If Right(varIn, 1) = "\" Then
TrailingSlash = varIn
Else
TrailingSlash = varIn & "\"
End If
End If
End Function
'this sub will execute a shell command and wait for execution to finish
Public Sub RunCmd(cmd As String)
On Error GoTo ErrHandler_RunCmd
'https://stackoverflow.com/questions/15951837/wait-for-shell-command-to-complete
Dim wsh As Object
Set wsh = VBA.CreateObject("WScript.Shell")
Dim waitOnReturn As Boolean: waitOnReturn = True
Dim windowStyle As Integer: windowStyle = 1
'Debug.Print cmd
wsh.Run cmd, windowStyle, waitOnReturn
ExitHandler_RunCmd:
Set wsh = Nothing
Exit Sub
ErrHandler_RunCmd:
Resume ExitHandler_RunCmd
End Sub
'base function to call pdftk from the command line
Public Sub PDFtk(args As String)
Dim cmd As String
cmd = """" & PDFtkPath & """ " & args
RunCmd cmd
End Sub
'PDFtkMerge will combine an array of pdf files into a single output file
' it will fail of any of the input files are not found or of the output
' filename already exists.
' returns True of a new output file is created, otherwise returns false
Public Function PDFtkMerge(files() As Variant, output As String) As Boolean
On Error GoTo ErrHandler_PDFtkMerge
Dim filename As Variant
Dim rslt As Boolean
Dim args As String
rslt = False
'loop through the files and make surey the exist
For Each filename In files
If Not FileExists(filename) Then Err.Raise 1001, , "Input file not found" & vbCrLf & vbCrLf & filename
args = args & """" & filename & """ "
Next filename
'check the output filename
If FileExists(output) Then Err.Raise 1002, , "Output file already exists" & vbCrLf & vbCrLf & output
args = args & "output """ & output & """"
'run the command
'Debug.Print args
PDFtk args
'see if it worked
If FileExists(output) Then rslt = True
ExitHandler_PDFtkMerge:
PDFtkMerge = rslt
Exit Function
ErrHandler_PDFtkMerge:
MsgBox Err.Description, , "PDFtkMerge Error #" & Err.Number
Resume ExitHandler_PDFtkMerge
End Function
Public Sub MERGE_TEST()
Dim input_files() As Variant
Dim output_file As String
input_files = Array("D:\S1.10.pdf", _
"D:\S2.20.pdf", _
"D:\S2.30.pdf", _
"D:\S3.10.pdf")
output_file = "D:\s_combined.pdf"
Debug.Print PDFtkMerge(input_files, output_file)
End Sub
*I said free but double check the licensing terms for your situation.
** also, the docs appear to show it might be able to handle your files with passwords. We'll need to modify the code above for that...