Posted on 2011-11-01
Last Modified: 2012-05-12
I have one large PDF file containing invoices.  
Where knowing 1 or more page numbers,  how to extract these 1 or more pages in VB6 or some script or commandline option
to a separate PDF file , or print them out
Question by:BIAPRO
    LVL 4

    Expert Comment

    by:Ariful Ambia
    There is no effective way to do this. you may find some PDF cutter type software in the web through which you can try to separate the invoices.
    LVL 37

    Expert Comment

    Oh yes you can!!

    Have a look here, its simple but NOT cheap.
    LVL 44

    Expert Comment

    I'm going to use PDFSAM with a VB project for one of my clients.

    Author Comment

    when downloading the source, my Nod32 antivirus
    breaks off the download , stating that it contains
    a type off:   win32/installcore.c  thread.
    LVL 44

    Expert Comment

    You may want to get a second AV opinion.

    It is possible that they have recently acquired an infection.  Look around to see if there are some other sites, like CNet or SourceForge, that might have a PDFSAM download.
    LVL 11

    Accepted Solution

    I use the free utility PDFTK.

    pdftk.exe InputFile.pdf cat 2-5 output NewFile.pdf

    Open in new window

    LVL 11

    Expert Comment

    I realized later I left out the info to run this from VB6.

    You could use a Shell or Shell Execute command to directly run this statement, but VB6 will continue processing and if it expects the extracted pages to exist, they likely won't by the time your VB6 app tries to use it, simply because PDFTK (or any tool) will take longer to extract the page(s).  Shell and ShellExecute don't wait for the command to finish.  So I use ShellAndWait (code below) that I found online.  This will cause VB6 to wait for completion of execution and still allow for a maximum amount of time for the external process to complete to avoid an infinite loop.  I execute the command like this:

    Dim strInputFile as string     'Assume full path
    Dim strOutputFile as string    'Assume full path
    Dim strPDFTK as string     'Assume full path to PDFTK
    Dim strQ as string            'Holds double quotes to enclose full paths potentially with spaces
    Dim strPageRange as string
    dim intDelayInSeconds as integer
    strQ = """"
    strInputFile = strQ & "C:\You Path\Your File.pdf" & strQ
    strOutputFile = strQ & "C:\You Path\Your Results.pdf" & strQ
    strPDFTK = strQ & "C:\Program Files\PDFTK\pdftk.exe" & strQ
    strPageRange = "2-5"
    intMaxDelayInSeconds = 2
    ShellAndWait strPDFTK & " " & strInputFile & " cat " & strPageRange  & " output " & strOutputFile, _
                             vbNormalFocus, _

    Open in new window

    and the ShellAndWait routine:

    '(Alt Source with more error handling and details:
    'Execute Shell command and wait for result, but allow other processes to continue in app via DoEvents.
    'Private Sub Form_Load()
    '  Me.Show
    '  ShellAndWait "Notepad.exe", , 3
    '  Me.Caption = "done"
    'End Sub
    Option Explicit
    Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess _
        As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
    Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle _
        As Long, ByVal dwMilliseconds As Long) As Long
    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    Public Sub ShellAndWait(ByVal program_name As String, _
                             Optional ByVal window_style As VbAppWinStyle = vbNormalFocus, _
                             Optional ByVal max_wait_seconds As Long = 0)
        Dim lngProcessId As Long
        Dim lngProcessHandle As Long
        Dim datStartTime As Date
        Dim lngCursor As Long
        Const WAIT_TIMEOUT = &H102
        Const SYNCHRONIZE As Long = &H100000
        Const INFINITE As Long = &HFFFFFFFF
        lngCursor = Screen.MousePointer
        Screen.MousePointer = vbHourglass
        ' Start the program.
        On Error GoTo ShellError
        lngProcessId = Shell(program_name, window_style)
        On Error GoTo 0
        ' Wait for the program to finish.
        ' Get the process handle.
        lngProcessHandle = OpenProcess(SYNCHRONIZE, 0, lngProcessId)
        If lngProcessHandle <> 0 Then
            datStartTime = Now
              If WaitForSingleObject(lngProcessHandle, 250) <> WAIT_TIMEOUT Then
                Exit Do
              End If
              If max_wait_seconds > 0 Then
                If DateDiff("s", datStartTime, Now) > max_wait_seconds Then Exit Do
              End If
            CloseHandle lngProcessHandle
        End If
        Screen.MousePointer = lngCursor
        Exit Sub
    End Sub

    Open in new window


    Author Comment

    works great !! just for euro 24.00  good deal  thanks

    Author Closing Comment

    perfect solution!
    LVL 11

    Expert Comment

    Glad it works for you. Regarding your reference to €24.00, do you mean for the book?  After I found this utility and discovered how useful it is, I ordered the book myself just to support the author.  It's awesome that he put that utility online for free!

    Author Comment

    well i got a click for version to use with more then one location, so i did my tribute to him
    programmers need to drink too, right ?

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    Why You Should Analyze Threat Actor TTPs

    After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

    You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
    Entering time in Microsoft Access can be difficult. An input mask often bothers users more than helping them and won't catch all typing errors. This article shows how to create a textbox for 24-hour time input with full validation politely catching …
    The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
    The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

    779 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    20 Experts available now in Live!

    Get 1:1 Help Now