Printing PDF file as per the counts specified in Excel sheet

nitkot

New Member
Joined
May 2, 2023
Messages
21
Office Version
  1. 2019
Platform
  1. Windows
  2. Mobile
  3. Web
We are non-profit organization, which is sending the question papers of religious exam to various schools based on their enrollment of levels.

We need one code, which can print/export to combined PDF based on the parameters given in the excel sheet.

Please check the attached excel sheet for parameters. At break of every school change, system can print one banner page with school name.
 

Attachments

  • Screenshot_6.png
    Screenshot_6.png
    24.5 KB · Views: 12
Replace the entire GetNumPages function with this, which uses FileSystemObject to read dump_data.txt instead of VBA file I/O statements.
VBA Code:
Private Function GetNumPages(PDFfullName As String) As Long

    Dim Wsh As Object 'WshShell
    Dim FSO As Object 'Scripting.FileSystemObject
    Dim ts As Object 'Scripting.TextStream
    Dim dataFile As String
    Dim command As String
    Dim allText As String
  
    'Run PDFtk dump_data command to get number of pages in this PDF
  
    dataFile = Left(PDFfullName, InStrRev(PDFfullName, "\")) & "dump_data.txt"
  
    command = "PDFtk " & Q & PDFfullName & Q & " dump_data output " & Q & dataFile & Q
    Debug.Print command
    Set Wsh = CreateObject("WScript.Shell")  'New WshShell
    Wsh.Run "cmd /c " & command, 0, True
  
    Set FSO = CreateObject("Scripting.FileSystemObject") 'New Scripting.FileSystemObject
    Set ts = FSO.OpenTextFile(dataFile, 1)
    allText = ts.ReadAll
    ts.Close
    FSO.DeleteFile dataFile
 
    GetNumPages = Split(Split(allText, "NumberOfPages: ")(1), vbCrLf)(0)
 
End Function
 
Upvote 0
Solution

Excel Facts

Does the VLOOKUP table have to be sorted?
No! when you are using an exact match, the VLOOKUP table can be in any order. Best-selling items at the top is actually the best.
Replace the entire GetNumPages function with this, which uses FileSystemObject to read dump_data.txt instead of VBA file I/O statements.
VBA Code:
Private Function GetNumPages(PDFfullName As String) As Long

    Dim Wsh As Object 'WshShell
    Dim FSO As Object 'Scripting.FileSystemObject
    Dim ts As Object 'Scripting.TextStream
    Dim dataFile As String
    Dim command As String
    Dim allText As String
 
    'Run PDFtk dump_data command to get number of pages in this PDF
 
    dataFile = Left(PDFfullName, InStrRev(PDFfullName, "\")) & "dump_data.txt"
 
    command = "PDFtk " & Q & PDFfullName & Q & " dump_data output " & Q & dataFile & Q
    Debug.Print command
    Set Wsh = CreateObject("WScript.Shell")  'New WshShell
    Wsh.Run "cmd /c " & command, 0, True
 
    Set FSO = CreateObject("Scripting.FileSystemObject") 'New Scripting.FileSystemObject
    Set ts = FSO.OpenTextFile(dataFile, 1)
    allText = ts.ReadAll
    ts.Close
    FSO.DeleteFile dataFile
 
    GetNumPages = Split(Split(allText, "NumberOfPages: ")(1), vbCrLf)(0)
 
End Function

Apology for delay in response and testing this, it seems now, it is working properly. I have tested it.

Thanks a lot for your kind help, I will get back to you should any help is required.
 
Upvote 0
it seems now, it is working properly. I have tested it.
The marked solution has been changed accordingly. In your future questions, please mark the post as the solution that actually answered your question, instead of your feedback message as it will help future readers. No further action is required for this thread.
 
Upvote 0
We are non-profit organization, which is sending the question papers of religious exam to various schools based on their enrollment of levels.

We need one code, which can print/export to combined PDF based on the parameters given in the excel sheet.

Please check the attached excel sheet for parameters. At break of every school change, system can print one banner page with school name.
Hi John,
Thanks for your response and revised code. There was minor correction which I have to do as below. Hope this is correct syntax.

Public Sub Print_PDFs2) --> Public Sub Print_PDF()

While running, Unfortunately, code is sending three PDF(s) of the school name heading only, it does not extend the header PDF file with the mentioned files that many times as defined in the excel sheet.

Also, when you do that, I need output as single PDF file only with Total number of pages = No. of copies for each file + No. of header page printed. In our sample case, it will be 59 pages + 3 school header page (which is getting printed correctly as of now but in separate files) = Total 62 pages.

Hope I am clear to define the problems. Highly appreciate your effort. If you can share me your email id, I can send the sample PDF and Excel sheet also.

Thanks in advance.
Nitin
Hi John,

Giving you reference of our earlier communication in this blog, When I tried on my real data with around 400 rows of file names within school, I am getting this message at end. Check the attached image of error.

On reducing the number of rows to 100, I am getting message "Merged file is created" - but in the folder, file is not existed!

Is there a limit in number of rows?

I have to submit the report in 2 days and will require your urgent assistance.

Thanks
Nitin
 

Attachments

  • Screenshot_5.png
    Screenshot_5.png
    10.6 KB · Views: 2
  • Screenshot_6.png
    Screenshot_6.png
    27.7 KB · Views: 2
Upvote 0
When I tried on my real data with around 400 rows of file names within school, I am getting this message at end. Check the attached image of error.

On reducing the number of rows to 100, I am getting message "Merged file is created" - but in the folder, file is not existed!

Is there a limit in number of rows?

In a way, there is a limit to the number of rows, but only because there is a limit to the length of the Windows command line. The PDFtk merge is done by a single command string containing all the input PDFs, so the more rows, the longer this string is. If the string exceeds the maximum command line length then the WshShell Run function would fail.

The message at the end should tell you the full name of the final merged PDF.

Here is a better approach which merges the input PDFs row by row to intermediate output PDFs (MERGE_1.pdf, MERGE_2.pdf, etc.) and at the end copies the last intermediate output PDF to the final merged PDF. With this method you shouldn't exceed the maximum command line length, unless the number of copies (3rd column in the table) is a high number.

VBA Code:
Option Explicit

Const Q As String = """"

Public Sub Merge_All_School_PDFs()

    Dim PDFsTable As ListObject
    Dim headerSheet As Worksheet
    Dim PDFsFolder As String, inputPDFs As String, FinalMergedPDF As String
    Dim MergeNumber As Long, MergedPDF As String
    Dim i As Long, n As Long
    Dim school As String
    Dim numPages As Long
    Dim command As String
    Dim Wsh As Object 'WshShell
    
    Set Wsh = CreateObject("WScript.Shell")  'New WshShell
    
    Set PDFsTable = ActiveSheet.ListObjects(1)
    
    'Add temporary sheet which will be exported to PDF for each school's 2-page header
    
    Set headerSheet = ThisWorkbook.Worksheets.Add(Before:=ThisWorkbook.Worksheets(1))
    
    With PDFsTable
    
        PDFsFolder = Left(.DataBodyRange(1, 2).Value, InStrRev(.DataBodyRange(1, 2).Value, "\"))
        FinalMergedPDF = PDFsFolder & "All Schools Merged.pdf"
        
        If Dir(FinalMergedPDF) <> vbNullString Then Kill FinalMergedPDF
        
        'Create BLANK.pdf which is added to list of PDFs to be merged for input PDFs which have an odd number of pages
        
        headerSheet.Range("A1").ExportAsFixedFormat Type:=xlTypePDF, Filename:=PDFsFolder & "BLANK.pdf", _
                        Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=False
            
        school = ""
        MergeNumber = 0
        inputPDFs = ""
        
        For i = 1 To .DataBodyRange.Rows.Count
            
            'Assign the next intermediate merged output PDF
            
            MergeNumber = MergeNumber + 1
            MergedPDF = "MERGE_" & MergeNumber & ".pdf"
            
            Debug.Print .DataBodyRange(i, 1).Value, .DataBodyRange(i, 2).Value, .DataBodyRange(i, 3).Value
            If .DataBodyRange(i, 1).Value <> school Then
                'School has changed - update header sheet and export it as PDF with 2 pages
                school = .DataBodyRange(i, 1).Value
                With headerSheet.Range("C25")
                    .Clear
                    .Value = school
                    .Font.Name = "Calibri"
                    .Font.Size = 72
                    .Font.Bold = True
                End With
                headerSheet.Range("A1:I60").ExportAsFixedFormat Type:=xlTypePDF, Filename:=PDFsFolder & school & " HEADER.pdf", _
                    Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=False
                'Add school header PDF to list of PDFs to be merged
                inputPDFs = inputPDFs & Q & school & " HEADER.pdf" & Q & " "
            End If
            
            'Get number of pages in this PDF
            numPages = GetNumPages2(.DataBodyRange(i, 2).Value)
           
            'Add PDF file in column 2 the number of times specified in column 3 to list of PDFs to be merged
            For n = 1 To .DataBodyRange(i, 3).Value
                inputPDFs = inputPDFs & Q & Mid(.DataBodyRange(i, 2).Value, InStrRev(.DataBodyRange(i, 2).Value, "\") + 1) & Q & " "
                If numPages Mod 2 <> 0 Then
                    'This PDF file has an odd number of pages so add BLANK.pdf to list of PDFs to be merged
                    inputPDFs = inputPDFs & Q & "BLANK.pdf" & Q & " "
                End If
            Next
        
            'Using PDFtk cat command, merge this set of input PDFs to the current intermediate merged output PDF
            
            command = "CD /D " & Q & PDFsFolder & Q & " & PDFtk " & inputPDFs & "cat output " & Q & MergedPDF & Q
            'Debug.Print command
            Wsh.Run "cmd /c " & command, 0, True
            
            'The current intermediate merged output PDF becomes the first input PDF in the next set of PDFs to be merged
            
            inputPDFs = Q & MergedPDF & Q & " "
            
        Next
        
    End With
    
    'Copy the last intermediate merged output PDF to the final merged PDF
    
    FileCopy PDFsFolder & MergedPDF, FinalMergedPDF
   
    Application.DisplayAlerts = False
    headerSheet.Delete
    Application.DisplayAlerts = True
    
    'Delete all the intermediate output PDFs, school header PDFs and BLANK.pdf
    
    Wsh.Run "cmd /c DEL " & Q & PDFsFolder & "MERGE_*.pdf" & Q, 0, True
    Wsh.Run "cmd /c DEL " & Q & PDFsFolder & "* HEADER.pdf" & Q, 0, True
    Wsh.Run "cmd /c DEL " & Q & PDFsFolder & "BLANK.pdf" & Q, 0, True
    
    MsgBox "Created " & FinalMergedPDF, vbInformation
    
End Sub

'Using FileSystemObject to read dump_data.txt file
Private Function GetNumPages2(PDFfullName As String) As Long

    Dim Wsh As Object 'WshShell
    Dim FSO As Object 'Scripting.FileSystemObject
    Dim ts As Object 'Scripting.TextStream
    Dim dataFile As String
    Dim command As String
    Dim allText As String
    
    'Run PDFtk dump_data command to get number of pages in this PDF
    
    dataFile = Left(PDFfullName, InStrRev(PDFfullName, "\")) & "dump_data.txt"
    
    command = "PDFtk " & Q & PDFfullName & Q & " dump_data output " & Q & dataFile & Q
    'Debug.Print command
    Set Wsh = CreateObject("WScript.Shell")  'New WshShell
    Wsh.Run "cmd /c " & command, 0, True
    
    Set FSO = CreateObject("Scripting.FileSystemObject") 'New Scripting.FileSystemObject
    Set ts = FSO.OpenTextFile(dataFile, 1)
    allText = ts.ReadAll
    ts.Close
    FSO.DeleteFile dataFile
       
    GetNumPages2 = Split(Split(allText, "NumberOfPages: ")(1), vbCrLf)(0)
    'Debug.Print GetNumPages2 & " pages"
    
End Function
 
Upvote 0
In a way, there is a limit to the number of rows, but only because there is a limit to the length of the Windows command line. The PDFtk merge is done by a single command string containing all the input PDFs, so the more rows, the longer this string is. If the string exceeds the maximum command line length then the WshShell Run function would fail.

The message at the end should tell you the full name of the final merged PDF.

Here is a better approach which merges the input PDFs row by row to intermediate output PDFs (MERGE_1.pdf, MERGE_2.pdf, etc.) and at the end copies the last intermediate output PDF to the final merged PDF. With this method you shouldn't exceed the maximum command line length, unless the number of copies (3rd column in the table) is a high number.

VBA Code:
Option Explicit

Const Q As String = """"

Public Sub Merge_All_School_PDFs()

    Dim PDFsTable As ListObject
    Dim headerSheet As Worksheet
    Dim PDFsFolder As String, inputPDFs As String, FinalMergedPDF As String
    Dim MergeNumber As Long, MergedPDF As String
    Dim i As Long, n As Long
    Dim school As String
    Dim numPages As Long
    Dim command As String
    Dim Wsh As Object 'WshShell
   
    Set Wsh = CreateObject("WScript.Shell")  'New WshShell
   
    Set PDFsTable = ActiveSheet.ListObjects(1)
   
    'Add temporary sheet which will be exported to PDF for each school's 2-page header
   
    Set headerSheet = ThisWorkbook.Worksheets.Add(Before:=ThisWorkbook.Worksheets(1))
   
    With PDFsTable
   
        PDFsFolder = Left(.DataBodyRange(1, 2).Value, InStrRev(.DataBodyRange(1, 2).Value, "\"))
        FinalMergedPDF = PDFsFolder & "All Schools Merged.pdf"
       
        If Dir(FinalMergedPDF) <> vbNullString Then Kill FinalMergedPDF
       
        'Create BLANK.pdf which is added to list of PDFs to be merged for input PDFs which have an odd number of pages
       
        headerSheet.Range("A1").ExportAsFixedFormat Type:=xlTypePDF, Filename:=PDFsFolder & "BLANK.pdf", _
                        Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=False
           
        school = ""
        MergeNumber = 0
        inputPDFs = ""
       
        For i = 1 To .DataBodyRange.Rows.Count
           
            'Assign the next intermediate merged output PDF
           
            MergeNumber = MergeNumber + 1
            MergedPDF = "MERGE_" & MergeNumber & ".pdf"
           
            Debug.Print .DataBodyRange(i, 1).Value, .DataBodyRange(i, 2).Value, .DataBodyRange(i, 3).Value
            If .DataBodyRange(i, 1).Value <> school Then
                'School has changed - update header sheet and export it as PDF with 2 pages
                school = .DataBodyRange(i, 1).Value
                With headerSheet.Range("C25")
                    .Clear
                    .Value = school
                    .Font.Name = "Calibri"
                    .Font.Size = 72
                    .Font.Bold = True
                End With
                headerSheet.Range("A1:I60").ExportAsFixedFormat Type:=xlTypePDF, Filename:=PDFsFolder & school & " HEADER.pdf", _
                    Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=False
                'Add school header PDF to list of PDFs to be merged
                inputPDFs = inputPDFs & Q & school & " HEADER.pdf" & Q & " "
            End If
           
            'Get number of pages in this PDF
            numPages = GetNumPages2(.DataBodyRange(i, 2).Value)
          
            'Add PDF file in column 2 the number of times specified in column 3 to list of PDFs to be merged
            For n = 1 To .DataBodyRange(i, 3).Value
                inputPDFs = inputPDFs & Q & Mid(.DataBodyRange(i, 2).Value, InStrRev(.DataBodyRange(i, 2).Value, "\") + 1) & Q & " "
                If numPages Mod 2 <> 0 Then
                    'This PDF file has an odd number of pages so add BLANK.pdf to list of PDFs to be merged
                    inputPDFs = inputPDFs & Q & "BLANK.pdf" & Q & " "
                End If
            Next
       
            'Using PDFtk cat command, merge this set of input PDFs to the current intermediate merged output PDF
           
            command = "CD /D " & Q & PDFsFolder & Q & " & PDFtk " & inputPDFs & "cat output " & Q & MergedPDF & Q
            'Debug.Print command
            Wsh.Run "cmd /c " & command, 0, True
           
            'The current intermediate merged output PDF becomes the first input PDF in the next set of PDFs to be merged
           
            inputPDFs = Q & MergedPDF & Q & " "
           
        Next
       
    End With
   
    'Copy the last intermediate merged output PDF to the final merged PDF
   
    FileCopy PDFsFolder & MergedPDF, FinalMergedPDF
  
    Application.DisplayAlerts = False
    headerSheet.Delete
    Application.DisplayAlerts = True
   
    'Delete all the intermediate output PDFs, school header PDFs and BLANK.pdf
   
    Wsh.Run "cmd /c DEL " & Q & PDFsFolder & "MERGE_*.pdf" & Q, 0, True
    Wsh.Run "cmd /c DEL " & Q & PDFsFolder & "* HEADER.pdf" & Q, 0, True
    Wsh.Run "cmd /c DEL " & Q & PDFsFolder & "BLANK.pdf" & Q, 0, True
   
    MsgBox "Created " & FinalMergedPDF, vbInformation
   
End Sub

'Using FileSystemObject to read dump_data.txt file
Private Function GetNumPages2(PDFfullName As String) As Long

    Dim Wsh As Object 'WshShell
    Dim FSO As Object 'Scripting.FileSystemObject
    Dim ts As Object 'Scripting.TextStream
    Dim dataFile As String
    Dim command As String
    Dim allText As String
   
    'Run PDFtk dump_data command to get number of pages in this PDF
   
    dataFile = Left(PDFfullName, InStrRev(PDFfullName, "\")) & "dump_data.txt"
   
    command = "PDFtk " & Q & PDFfullName & Q & " dump_data output " & Q & dataFile & Q
    'Debug.Print command
    Set Wsh = CreateObject("WScript.Shell")  'New WshShell
    Wsh.Run "cmd /c " & command, 0, True
   
    Set FSO = CreateObject("Scripting.FileSystemObject") 'New Scripting.FileSystemObject
    Set ts = FSO.OpenTextFile(dataFile, 1)
    allText = ts.ReadAll
    ts.Close
    FSO.DeleteFile dataFile
      
    GetNumPages2 = Split(Split(allText, "NumberOfPages: ")(1), vbCrLf)(0)
    'Debug.Print GetNumPages2 & " pages"
   
End Function
Thanks a lot for your your quick response, I will try this soon and will get back to you.
 
Upvote 0
Hi John,

Apology for delay in response, I was travelling. I have tested the latest macro, it is now working fine. Since files are created in merged cumulative manner, it is taking huge time to combine the last two file. After processing around 150 rows in excel, macro is running ahead of file system merging time, and it is unable to find the file with number ahead and breaking over there. Probably, once last two files are merged successfully, macro should move ahead with further processing. Is that is possible?

Thanks
Nitin
 
Upvote 0
Since files are created in merged cumulative manner, it is taking huge time to combine the last two file. After processing around 150 rows in excel, macro is running ahead of file system merging time, and it is unable to find the file with number ahead and breaking over there. Probably, once last two files are merged successfully, macro should move ahead with further processing. Is that is possible?
The latest (second) macro merges row by row for the number of copies of each PDF, plus the school header PDF and BLANK.pdf, if needed, to intermediate files MERGE_1.pdf, MERGE_2.pdf etc. These intermediate PDFs get bigger and bigger; in my tests the last one is 95 Mb. The error you describe sounds like PDKtk hadn't created the current MERGE_n.pdf, due to an error with the cat command. These PDKtk errors are 'hidden' from the macro because I've used the WshShell Run method and this doesn't allow command errors to be read. The alternative is the WshShell Exec method, which does allow command errors to be read.

In one test, the current MERGE_n.pdf was only 10 Mb and it should have been about 70 Mb. This and your error suggests we are seeing the limitations of the PDFtk tool. Maybe in some situations it can't merge a very large PDF (80 Mb+?) with a few smaller PDFs (the PDFs for a single row). Maybe there is an internal memory or data limitation with the PDFtk.exe process.

I'm not sure if using WshShell Exec to run each merge command, checking if an error has occurred and repeating the merge until there isn't an error will solve the problem because the error is likely to keep repeating because VBA is running all the commands in the same Excel.exe same process.

Here's a third macro which uses a combination of the techniques used by the first and second macros. I previously mentioned the maximum Windows command line length, which you probably exceeded with the first macro. The maximum is 8191 characters.

The first macro used a single command to merge all the many 'small' PDFs, hence the possibility of exceeding the maximum length.

The second macro used multiple commands to merge a single intermediate 'very large' PDF, which got bigger and bigger, and a few 'small' PDFs.

This third macro creates multiple merge commands, up to a maximum length of 3000 characters, to merge a single intermediate 'large' PDF and many 'small' PDFs (as many as will fit into 3000 characters). Therefore each 'large' intermediate PDF will be smaller than the 'very large' intermediate PDFs created by the second macro because many more of the 'small' PDFs are being merged with it in each command. (I hope that makes sense).

If the macro fails, please experiment with different values for Const MAX_COMMAND_LENGTH = 3000.

VBA Code:
Option Explicit

Public Sub Merge_All_School_PDFs3()

    Dim PDFsTable As ListObject
    Dim headerSheet As Worksheet
    Dim PDFsFolder As String, inputPDFs As String, FinalMergedPDF As String
    Dim i As Long, n As Long
    Dim school As String
    Dim numPages As Long
    Dim command As String
    Dim MergeNumber As Long, MergedPDF As String
    Dim PDFsColl As Collection, PDFfile As Variant
    Dim Wsh As Object 'WshShell
  
    Const MAX_COMMAND_LENGTH = 3000
  
    Set Wsh = CreateObject("WScript.Shell")  'New WshShell
      
    Set PDFsTable = ActiveSheet.ListObjects(1)
  
    'Add temporary sheet which will be exported to PDF for each school's 2-page header
  
    Set headerSheet = ThisWorkbook.Worksheets.Add(Before:=ThisWorkbook.Worksheets(1))
  
    With PDFsTable
  
        PDFsFolder = Left(.DataBodyRange(1, 2).Value, InStrRev(.DataBodyRange(1, 2).Value, "\"))
        FinalMergedPDF = PDFsFolder & "All Schools Merged.pdf"
      
        'Delete all the intermediate output PDFs and final merged PDF
  
        Wsh.Run "cmd /c DEL " & Q2(PDFsFolder & "MERGE_*.pdf"), 0, True
        If Dir(FinalMergedPDF) <> vbNullString Then Kill FinalMergedPDF
              
        'Create BLANK.pdf which is added to list of PDFs to be merged for input PDFs which have an odd number of pages
      
        headerSheet.Range("A1").ExportAsFixedFormat Type:=xlTypePDF, Filename:=PDFsFolder & "BLANK.pdf", _
                        Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=False
                 
        'Create collection of PDFs to be merged
      
        Set PDFsColl = New Collection
      
        school = ""
      
        For i = 1 To .DataBodyRange.Rows.Count
      
            Debug.Print .DataBodyRange(i, 1).Value, .DataBodyRange(i, 2).Value, .DataBodyRange(i, 3).Value
            If .DataBodyRange(i, 1).Value <> school Then
                'School has changed - update header sheet and export it as PDF with 2 pages
                school = .DataBodyRange(i, 1).Value
                With headerSheet.Range("C25")
                    .Clear
                    .Value = school
                    .Font.Name = "Calibri"
                    .Font.Size = 72
                    .Font.Bold = True
                End With
                headerSheet.Range("A1:I60").ExportAsFixedFormat Type:=xlTypePDF, Filename:=PDFsFolder & school & " HEADER.pdf", _
                    Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=False
              
                'Add school header PDF to collection of PDFs to be merged
              
                PDFsColl.Add school & " HEADER.pdf"
            End If
          
            'Get number of pages in this PDF
            numPages = GetNumPages2(.DataBodyRange(i, 2).Value)
         
            'Add PDF file in column 2 the number of times specified in column 3 to collection of PDFs to be merged
            For n = 1 To .DataBodyRange(i, 3).Value
                PDFsColl.Add Mid(.DataBodyRange(i, 2).Value, InStrRev(.DataBodyRange(i, 2).Value, "\") + 1)
                If numPages Mod 2 <> 0 Then
                    'This PDF file has an odd number of pages so add BLANK.pdf to collection of PDFs to be merged
                    PDFsColl.Add "BLANK.pdf"
                End If
            Next
                  
        Next
      
    End With
  
    'Loop through collection of PDFs, merging multiple PDFs up to the specified maximum command line length
  
    MergeNumber = 1
    MergedPDF = "MERGE_" & MergeNumber & ".pdf"
    inputPDFs = ""
  
    For Each PDFfile In PDFsColl
        'Would adding this PDF fit maximum command length?
        If Len("CD /D " & Q2(PDFsFolder) & " & PDFtk " & inputPDFs & Q2(PDFfile) & " " & "cat output " & Q2(MergedPDF)) < MAX_COMMAND_LENGTH Then
            'Yes, so add it to list of input PDFs to be merged
            inputPDFs = inputPDFs & Q2(PDFfile) & " "
        Else
            'No, so merge input PDFs to the current intermediate merged output PDF
            command = "CD /D " & Q2(PDFsFolder) & " & PDFtk " & inputPDFs & "cat output " & Q2(MergedPDF)
            Debug.Print command
            Wsh.Run "cmd /c " & command, 0, True
          
            'Add the current intermediate merged output PDF and this PDF to the next set of PDFs to be merged
            inputPDFs = Q2(MergedPDF) & " " & Q2(PDFfile) & " "
            MergeNumber = MergeNumber + 1
            MergedPDF = "MERGE_" & MergeNumber & ".pdf"
        End If
    Next
  
    'Merge remaining input PDFs to the current intermediate merged output PDF
  
    If inputPDFs <> "" Then
        command = "CD /D " & Q2(PDFsFolder) & " & PDFtk " & inputPDFs & "cat output " & Q2(MergedPDF)
        Debug.Print command
        Wsh.Run "cmd /c " & command, 0, True
    End If
  
    'Copy the last intermediate merged output PDF to the final merged PDF
  
    FileCopy PDFsFolder & MergedPDF, FinalMergedPDF
 
    Application.DisplayAlerts = False
    headerSheet.Delete
    Application.DisplayAlerts = True
  
    'Delete all the intermediate output PDFs, school header PDFs and BLANK.pdf
  
    Wsh.Run "cmd /c DEL " & Q2(PDFsFolder & "MERGE_*.pdf"), 0, True
    Wsh.Run "cmd /c DEL " & Q2(PDFsFolder & "* HEADER.pdf"), 0, True
    Wsh.Run "cmd /c DEL " & Q2(PDFsFolder & "BLANK.pdf"), 0, True
  
    MsgBox "Created " & FinalMergedPDF, vbInformation
  
End Sub

Private Function Q2(text As Variant) As String
    Q2 = Chr(34) & text & Chr(34)
End Function


'Using FileSystemObject to read dump_data.txt file
Private Function GetNumPages2(PDFfullName As String) As Long

    Dim Wsh As Object 'WshShell
    Dim FSO As Object 'Scripting.FileSystemObject
    Dim ts As Object 'Scripting.TextStream
    Dim dataFile As String
    Dim command As String
    Dim allText As String
  
    'Run PDFtk dump_data command to get number of pages in this PDF
  
    dataFile = Left(PDFfullName, InStrRev(PDFfullName, "\")) & "dump_data.txt"
  
    command = "PDFtk " & Q2(PDFfullName) & " dump_data output " & Q2(dataFile)
    Debug.Print command
    Set Wsh = CreateObject("WScript.Shell")  'New WshShell
    Wsh.Run "cmd /c " & command, 0, True
  
    Set FSO = CreateObject("Scripting.FileSystemObject") 'New Scripting.FileSystemObject
    Set ts = FSO.OpenTextFile(dataFile, 1)
    allText = ts.ReadAll
    ts.Close
    FSO.DeleteFile dataFile
     
    GetNumPages2 = Split(Split(allText, "NumberOfPages: ")(1), vbCrLf)(0)
    Debug.Print GetNumPages2 & " pages"
  
End Function
 
Last edited:
Upvote 0

Forum statistics

Threads
1,214,991
Messages
6,122,628
Members
449,095
Latest member
bsb1122

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top