How to Print Files in VBA Without APIs

As I continue to delve into PowerShell I have been successfully eliminating the need for several APIs in my code base to eliminate things like

  • APIs
  • Enums
  • Conditional Compilation Directives
  • Versioning issues/Missing References

In the past I have always printed documents by simply using the ExecuteFile function found in my article VBA – Opening Files and URLs.

PowerShell Printing a Single File

Once again, PowerShell makes it extremely easy to print a file and performs this action with a single line of code, as shown below:

Start-Process -FilePath 'C:\Users\Dev\Documents\PowerShell.docx' -Verb Print

Thus, we can build a simple VBA wrapper like:

Public Sub PS_PrintFile(ByVal sFile As String)
    Dim sCmd                  As String

    sCmd = "Start-Process -FilePath '" & sFile & "' -Verb Print"
    Call PS_Execute(sCmd)
End Sub

and you would then simply call it by doing:

Call PS_PrintFile("C:\Users\Dev\Documents\PowerShell.docx")

So with a single PowerShell command and the PS_Execute sub from VBA – Run PowerShell Command we can now print any files without the need of any APIs.

PowerShell Printing All The Files In A Directory

So what can we do if we need to print all the files within a directory?

Yes, we could use Dir() or the File System Object (FSO) to iterate over a folder and call the above function over and over, but we don’t need to. Once again, we can do this directly in PowerShell using a single line of code, such as:

Get-ChildItem "C:\Users\Dev\Documents\" | ForEach-Object {Start-Process $_.FullName –Verb Print}

With this in mind, we once again create a simple wrapper function like:

Public Sub PS_PrintDirectoryFiles(ByVal sFolder As String)
    Dim sCmd                  As String

    sCmd = "Get-ChildItem '" & sFolder & "' | ForEach-Object {Start-Process $_.FullName –Verb Print}"
    Call PS_Execute(sCmd)
End Sub

This will work as long as the file type has a default application associated to it.

You can use this function by simply doing:

PS_PrintDirectoryFiles("C:\Users\Dev\Documents\")

What’s even more interesting with this approach is you can use filters to restrict the files to be printing. For instance, say we wanted to print all the Word documents in the folder. We could simply do:

PS_PrintDirectoryFiles("C:\Users\Dev\Documents\*.doc*")

Opening File(s)

This approach is built upon the usee of the ‘Print’ verb. It should be noted that the Start-Process cmdlet offers other verbs such as ‘Open’, ‘Edit’, … depending on the type of file. So you could use the exact same approach to open a single, or entire directory of files in one call. Or perhaps, add a Verb argument to the function to make it more versatile. Perhaps something like:

Public Sub PS_StartFiles(ByVal sItem As String, sVerb As String)
    Dim sCmd                  As String

    sCmd = "Get-ChildItem '" & sItem & "' | ForEach-Object {Start-Process $_.FullName –Verb " & sVerb & "}"
    Call PS_Execute(sCmd)
End Sub

Below are a few examples of how it can then be used.

Call PS_StartFiles("C:\Users\Dev\Documents\PowerShell.docx", "Open")
Call PS_StartFiles("C:\Users\Dev\Documents\PowerShell.docx", "Print")
Call PS_StartFiles("C:\Users\Dev\Documents\*.docx", "Open")
Call PS_StartFiles("C:\Users\Dev\Documents\*.docx", "Print")
Call PS_StartFiles("C:\Users\Dev\Documents\*", "Open")
Call PS_StartFiles("C:\Users\Dev\Documents\*", "Print")

A Few Resources on the Subject

2 responses on “How to Print Files in VBA Without APIs

  1. Mark Burns

    This is AWESOME.
    Could I encourage you to write an eBook on the general topic of interfacing Access/VBA with Powershell?
    …even if the eBook was only a somewhat enhanced compilation of your existing articles on the subject?