Link to home
Start Free TrialLog in
Avatar of peispud
peispudFlag for Canada

asked on

Shellexecute argument to print multiple copies

Hi

I am using ShellExecute  to open  Brother label printer file.  The code works perfectly!

Often, I need 2 or more identical labels.    In such cases, I would like to direct the printer job to print multiple copies per Shell Execute command (see code).
The reason for this is that  label printer produces waste at the beginning of each print job (by design).    If I print multiple copies then waste is reduced.

I appreciate any help.
Thank you.



Option Compare Database
Option Explicit

Const Dir As String = "C:\!!Tools\Microsoft Access\Labels"
Const TheFile As String = "P- 12MM OLT - Cable - CSP.lbx"
Const SW_SHOW = 5
  
Private Declare Function ShellExecute Lib "shell32.dll" _
Alias "ShellExecuteA" (ByVal hwnd As Long, _
ByVal lpOperation As String, ByVal lpFile As String, _
ByVal lpParameters As String, _
ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long

Private Sub btnPrint_Click()
    ShellExecute Me.hwnd, "print", Dir & "\" & TheFile, vbNullString, vbNullString, SW_SHOW
End Sub

Open in new window

Avatar of Duncan Roe
Duncan Roe
Flag of Australia image

print doesn't appear to have a copies option, but it can print multiple files
C:\Users\Duncan>print/?
Prints a text file.

PRINT [/D:device] [[drive:][path]filename[...]]

   /D:device   Specifies a print device.

Open in new window

You could enhance your program to have a "number of copies" entry and repeat the file name in the 3rd argument to ShellExecute (perhaps construct this argument using a StringBuilder ) according to the number of copies selected.
Before going to that trouble, I would suggest trying it from a CMD window to make sure you do actually save paper (you may not). E.g. to print 3 copies from a CMD window
print "C:\!!Tools\Microsoft Access\Labels\P- 12MM OLT - Cable - CSP.lbx" "C:\!!Tools\Microsoft Access\Labels\P- 12MM OLT - Cable - CSP.lbx" "C:\!!Tools\Microsoft Access\Labels\P- 12MM OLT - Cable - CSP.lbx"

Open in new window

From reading through the definition of the shell execute function, it appears there is no method to do so in the function itself.

Instead, the method is meant to be called multiple times in a loop to print multiple separate copies.

 In either case, since tpur issue is due to the printer itself wasting space between each print job you will encounter that wasted space whether using a loop or if the function itself allowed you to send multiple jobs in a single go.

In order to actually achieve your goal, create a copy of your print function, rename it slightly to allow you to call it from the original copy, and othwrwise make no changes.

In the original function:

1) leave the name unchanged
2) ammend the parameters to take an optional quantity parameter
3) have the function copy the file to be printed to a temp file in the temp path.
4) if QTY param is provided and specifies a number >1 concatinate the original file content onto the temp file n number of times where n = QTY-1

5)  Specify that temp file as the file to br printed by thenoriginal renamed function.

 Something like this pseuedo code:

Option Compare Database
Option Explicit

Const Dir As String = "C:\!!Tools\Microsoft Access\Labels"
Const TheFile As String = "P- 12MM OLT - Cable - CSP.lbx"
Const SW_SHOW = 5
Const _TempDir As String = "C:\Temp\LablePrint"
Const _QTYFeild = 2


Private Declare Function ShellExecute Lib "shell32.dll" _
Alias "ShellExecuteA" (ByVal hwnd As Long, _
ByVal lpOperation As String, ByVal lpFile As String, _
ByVal lpParameters As String, _
ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long

Private Sub btnPrint_Click()
  
    Call Print_Job Dir&"\"&TheFile, _QTYFeild

End Sub

Private Sub Submit_Print_Job ( _JobFile ByVal as String)

    ShellExecute Me.hwnd, "print", _JobFile, vbNullString, vbNullString, SW_SHOW

End Sub

Private Sub Print_Job ( _PFile ByVal as String, Optional ByVal _QTY As Int = 1)

Dim _TFile as string

If _QTY <= 1
   _TPFile =_PFile
 Else

Dim _dt As DateTime
Dim _ISODT as String = dt.ToUniversalTime().ToString("yyyy-M-d_HH.mm.ss.ffff", CultureInfo.InvariantCulture)

DIM _TPFile As String = _TempDir & "\TempPrint_" & _ISODT & ".tmp"

        Using outputStream As New FileStream(_TPFile, FileMode.Create)
            Using writer As New BinaryWriter(outputStream)
    For J = 1 To _QTY Step 1
                    Using inputStream As New FileStream(_PFile, FileMode.Open)
                        Using reader As New BinaryReader(inputStream)
                            writer.Write(reader.ReadBytes(inputStream.Length))
                        End Using

            End Using

         Next J

    End Using
                    
 End Sub

Call Submit_Print_Job _TPFile

Open in new window

Avatar of peispud

ASKER

HI..
I am using Microsoft Access VBA.

Duncan Roe's solution solution...    The print jobs are delimited by a space character in the example.  I may need another delimiter.
Ben Personick solution...                   I will have to work at the code to make it VBA friendly.

I will happily work with these two solutions.  But I will be otherwise busy on my other job responsibilities, so time is a precious commodity.
If a VBA solution show up, that would be even better.
Mine is VB, but done on my phone on the way to work, so might need a little tweaking.
You should be all right with a space delimiter because the print jobs are quoted
Avatar of peispud

ASKER

If you can do this on the phone,  I will definitely find time to tweak it. :)
Avatar of peispud

ASKER

I am trouble getting this right.  Do I need a Reference, Import etc?

Using outputStream As New FileStream(_TPFile, FileMode.Create)
Using writer As New BinaryWriter(outputStream)

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Ben Personick (Previously QCubed)
Ben Personick (Previously QCubed)
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of peispud

ASKER

Thank you for your help.
Hey @peispud, glad to help :)