Luke207 used Ask the Experts™
I am very new to Vb and i really need help from vb geeks here.. :p

anyway, i made a form and what i want to do is how to print it. By the way, i'll be using a ready made form as my paper source. What i want to print is the values inputted on the textbox and eventually position it on the form. How will i start? what shall i do? anyone has a sample code? :p
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
In simple terms you use the Printer Object like this:

Const Imperial = 1440 ' inches
Const Metric = 567 ' metric

Dim Twips as single
Twips = Imperial ' or Metric for centimeters
Printer.CurrentX = 1.5 * Twips ' 1.5 inches from left
Printer.CurrentY = 2 * Twips ' 2 inches from top
Printer.Print Text1; ' print some text

' tab over to next column
' use Format to handle numerics and dates, booleans, etc.
Printer.CurrentX = 3 * Twips ' 3 inches from left
Printer.Print Format(NumericValue,"0.00");

Printer.NewPage ' makes a new page
Printer.EndDoc  ' the document is complete

Here is a usage summary of how to handle the printer:

It is not hard to use VB's printer object. Here are some more samples using the VB Printer object or
a picture box for print preview.

When you realy get some subroutines together it is quicker to create your report in VB than either Access
or Data  reports.

After each ============== is a handy code section showing an example.

You can print anywhere you like on your page within the following positions:

l = Printer.ScaleLeft ' you must print to the right of here
t = Printer.ScaleTop ' below here
h = Printer.ScaleHeight ' above here
w = Printer.ScaleWidth ' left of here

' output to picture box or printer
If preview Then
  Set outp = picMyPictureControl
  outp.Height = Printer.Height
  outp.Width = Printer.Width
  Set outp = Printer
End If

' Change font
outp.Font.Name = "Arial"
outp.Font.Size = 8

' set line height to height of fields + a littlebit more
lineheight = outp.TextHeight("X") * 1.01

' set a factor so that you can think in either inches or centimeters
twips = 1440 ' or 567 for centimeters

'set margins
leftmargin = twips * 0.5 ' Set .5 inches from left

' set topmargin
topmargin = twips * 2 ' Set 2 inches from top
if Not Preview then
  if topmargin < t then
    topmargin = t
  end if
end if
' set bottom point
bottompoint = outp.ScaleHeight - lineheight - twips * 1

' set mid pint
centerpoint = (outp.ScaleWidth - outp.ScaleLeft) * 0.5 + outp.ScaleLeft

' set rightmargin
rightmargin = outp.ScaleWidth - twips * 0.5

' Now do some printing
' move to printing position
outp.CurrentX = leftmargin
outp.CurrentY = topmargin

outp.Print "Print some text";

' print next field
outp.CurrentX = leftmargin + 2 * twips ' tab over 2 inches
outp.Print "Print some more";

' right justify to right side
outp.CurrentX = outp.ScaleWidth - outp.TextWidth(YourText$)
outp.Print YourText$;

' center justify
outp.CurrentX = centerpoint - outp.TextWidth(YourText$) * 0.5
outp.Print YourText$;

' tab to  2 inches from the left
Printer.CurrentX = 2 * twips

outp.Print "Print some more";

' Advance to next line
outp.CurrentY = outp.CurrentY + lineheight

' draw a line across
outp.line (leftmargin,outp.currenty)-(rightmargin-outp.currenty),0,bf

' draw a box arround an area
' you can also handle shading here as well rgb(250,250,250)but you
' need to use a windows API call to print on top of shading
' due to bug in windows
outp.line (leftmargin,topmargin)-(rightmargin-bottompoint),rgb(0,0,0),B

' Have we reached end of page or is this the top of the first page

Gosub CheckPage

If Page=0 or outp.CurrentY > bottompoint Then

  Page = Page + 1
  if page>1 Then ' if first page don't to end of page  
      ' print bottom of page stuff here
      outp.CurrentY = bottompoint - twips * 0.5
      outp.CurrentX = centerpoint
      outp.Print "Page " + CStr(Page);
      If preview Then
          ok = MsgBox("Continue Y/N", vbYesNo + _ vbQuestion, "End of Page")
          If ok <> vbYes Then
               ' unload your preview form
               Exit Sub
          end if
          outp.CurrentY = topmargin
      End If
  End If
  ' handle page headings in a gosub or Subroutine here
  gosub PrintHeadings
End If


' Graphics
' picG is the image you wish to print
' Both picG.Image and picG.Pictue can be used as a source

' S=Source of picture

' so you can crop the source picure like
sx =  cropleft ' Source x position
sy =  croptop
sw =  picG.ScaleWidth - cropright
sh = picG.ScaleHeight - cropbottom

' D=Destination pos X,Y and H & W is height and width
' e.g. DX=destination x postion

DX = t
DY = l
DW = r-l

' keep same aspect ratio of pircure width/height relationship

ARatio=picG.scaleheight/picg.scalewidth ' aspect ratio of source picture

' because  dh / dw = sh / sw = ARatio
' you can find the correct dh from dw
DH = DW * ARatio

' the raster op allows pictures to be merged, or just plain copied type "RasterOpConstants." to see
list of options

RasterOp = RasterOpConstants.vbSrcCopy

' now print the graphic
outp.PaintPicture picG.Picture, DX, DY, DW, DH, SX, SY, SW, SH, RasterOp

' you can create effects like upside down and mirror using -DH and -DW

' Autoshrink

Before you print your graphic you can test to see if it fits on the page, if it is too large then shrink
it a little so it fits.

Imagine you want to print at height position hp and left poisition lp you graphic is in picture box

' set position where graphic is to be printed.
DX = lp ' set desintation x
DY = hp ' set desintation y
DW = picG.Width
DH = picG.Height

' now here is the cute bit to stop graphic going over page.

If DH + DY > h Then ' where h = printer.scaleheight
  DH = h - DY ' set the height to the remaining height
  DW = DW * (DH / picG.Height) ' reduce width by same propotion
End If

Printer.PaintPicture picG.Picture, DX, DY, DW, DH

' Finishing up

Page = Page + 1

' print bottom of page stuff here
' best done in another subroutine
outp.CurrentY = bottompoint - twips * 0.5
outp.CurrentX = centerpoint
outp.Print "Page " + CStr(Page)

If preview Then
  ok = MsgBox("Complete", vbExclamation, "End of Document")
End If

' to abandon printing
If Not preview Then
End If

' Shading and transparent fonts

' First print a box
outp.Line (LeftM, startplace)-(RightM, endplace), RGB(247, 247, 247), BF
outp.FillStyle = 1 ' this should work in NT but not in 95
outp.FontTransparent = True
If Not preview Then ' fix windows 95 bug
  iBKMode = SetBkMode(outp.hdc, TRANSPARENT)
end if

' You need this in a code module
Public Declare Function SetBkMode Lib "gdi32" _
    (ByVal hdc As Long, ByVal nBkMode As Long) As Long

Public iBKMode As Long
Public Const TRANSPARENT = 1
Public Const OPAQUE = 2

' Zooming

Set a zoom factor and multiply all coordinates by the zoom factor. Examples:

ZF = 1 ' 1.5=150%, 2=200% etc.

outp.CurrentX = MyXPos * ZF
outp.CurrentY = MyYPos * ZF
outp.Font.Size = 8 * ZF

outp.Line (X1 * ZF, Y1 * ZF)-(X2 * ZF, Y2 * ZF),RGB(0,0,0),B

If preview Then
  Set outp = picMyPictureControl
  outp.Height = Printer.Height * ZF
  outp.Width = Printer.Width * ZF

Ryan ChongSoftware Team Lead


Form1.PrintForm ? or you need better solution?
If you want to print a form as it looks on the screen then you need the zCaptureWindow class from this question:

Dim CW as new zCaptureWindow

Printer.PaintPicture CW.CaptureClient(ME), DX,DY
(Dx, DY are the coordiantes of where to print.
Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

How to select a printer:

What you do is create a setup program that saves the device name for the required printer.
Say you need 2 prinets one for documents and one for reports. You need as setup program
so operator can choose which one is needed.

Your setup from will have 2 combo boxes

so in the form load you need:

dim pr as printer
dim documents$
dim reports$



for each pr in printers
  comboDocuments.Additem pr.DeviceName
  comboReports.Additem Pr.Devicename

combodocuemnts=documents ' set the current name in the combo box
comboreports=reports ' set the current name in the combo box


In the save button on the form:
SaveSetting "MyProg", "Printers", "Reports", comboReports
SaveSetting "MyProg", "Printers", "Documents", comboDocuments

When you want to select a printer in your code you say:

' save the current printer name
Ok=SelectPrinterTypeOK("Reports") ' or "Documents"
if not ok then
  frmSelectPrinters.Show ' they need to choose a printer
  exit sub
end if

Just start printing

Printer.Print "ABCD"


And now the bits that do the work:

Function SelectPrinterTypeOK(PrinterType as String) as Boolean

' find the device name for the required printer
' then select that printer

Dim PName$
PName$ = getsetting("MyProg","Printers",PrinterType,"")
if len(Pname$)=0 then
  Exit Function
end if

End Functon

Function SelectPrinterNameOK(PrinterName as String) as Boolean

' select a printer by device name

Dim Pr as Printer

' search for the required printer
For each Pr in Printers
   If Ucase(Pr.DeviceName)=Ucase(PrinterName) Then
       Set Printer = Pr
       SelectPrinterNameOK = True
       Exit Function
   End If

End Function

If you want your app to be linkes to the current Windows printer.
In your App startup you need to set:

Printer.TrackDefault = True


what i need to do is to position the inputted values on the form to the paper source(ready form) when printed. I have now my form and the problem is to position the inputed values when printed to the ready form.... :(


what i need to do is to position the inputted values on the form to the paper source(ready form) when printed. I have now my form and the problem is to position the inputed values when printed to the ready form.... :(

 So what you do is you mesaure each box on the form, say in CM.

You get a position from the top and a position from the left for each box on your paper.
Measure exactly to the box edge, in the code there is hGap which sets the amount of gap to leave inthe box.
Also measure the width of each box.

You now create a text file formspec.csv here is a sample but you can use any format you like (the csv file can be created/edited by Excel):

Source, Index, Format, Jusify, Top, Left, Width, FontSizeAdjust,Options,Comments


In excel, when you edit the file, you need to put a singe quote infront of formts like 0.00

The font adjust allows to to increase or negative will decreas the size of font.
You can create a form frmPreview with a pixture box to handle print preview option.

The source is the textbox/checkbox, etc.
If you are using control arrays specify the index of the array element,
otherwise leave blank.

Put a check box chkPreview on your form.

The details will be loaded into an array.

Option Base 0
Private Type FormDataDef
    Source As Control
    Format As String ' like 0.00 or dd-mmm-yy, etc.
    Justify As String ' L,R,C left,right,centre
    Top As Single
    Left As Single
    FontAdjust As Single
    Attributes As String
    Width As Long
End Type

Dim Fields() As FormDataDef

Private Sub cmdPrint_Click()

' print fields onto a form

Dim fc As Long
Dim TextValue As String
Dim pr As Object

Const Metric = 567
Const Imperial = 1440

Dim Twips As Single

Dim FontSize As Single
Dim Fontname As String

Dim HGap As Single ' horrizontal gap
Dim bBold As Boolean

Twips = Metric ' set for centimeters

' setup font details
FontSize = 10
Fontname = "Arial"

' a gap between the box edge and where to start printing
HGap = Twips * 0.1

Dim PreView As Boolean

' have the clicked for a print preview
If chkPreview.Value = 1 Then
    PreView = True
    Load frmPreview
    Set pr = frmPreview.picTest
    Set pr = Printer
End If

pr.Font.Name = Fontname

For fc = 0 To UBound(Fields)
    If Len(Fields(fc).Format) > 0 Then
        TextValue = Format(Fields(fc).Source, Fields(fc).Format)
        TextValue = Format(Fields(fc).Source, Fields(fc).Format)
    End If
    ' get justified position
    pr.CurrentX = getJPos(TextValue, fc, pr, HGap)
    ' set vert. pos
    pr.CurrentY = Fields(fc).Top
    ' adjust font size up or down
    pr.Font.Size = FontSize + Fields(fc).FontAdjust
    ' apply specials
    If InStr(Fields(fc).Attributes, "/B") > 0 Then
        bBold = True
        bBold = False
    End If
    pr.Font.Bold = bBold
    ' at last print data
    pr.Print TextValue;
Next fc

If PreView Then
   ' do nothing
End If

End Sub

Private Sub Form_Load()

Const Metric = 567
Const Imperial = 1440

Dim Twips As Single
Twips = Metric ' set for centimeters

ReDim Fields(10) As FormDataDef
ReDim specs(0) As String
ReDim fdef(0) As String ' field definition

Dim lc As Long
Dim fc As Long

Dim FileData$

' Read your data
FileData$ = ReadFile(App.Path + "\FormSpec.CSV")

' Create an array element for each line
specs = Split(FileData, vbCrLf)

' Load The data into your fields
' ignore first line
For lc = 1 To UBound(specs)
    If Len(specs(lc)) = 0 Then Exit For
    fdef = Split(specs(lc), ",")
    ReDim Preserve fdef(8)
    If fc > UBound(Fields) Then
        ReDim Preserve Fields(fc)
    End If
    'Source , Index, Format, Jusify, Top, Left, Comments
    Fields(fc).Format = Trim(fdef(2))
    Fields(fc).Justify = UCase(Trim(fdef(3)))
    Fields(fc).Top = CSng(fdef(4)) * Twips
    Fields(fc).Left = CSng(fdef(5)) * Twips
    If Len(Trim(fdef(1))) > 0 Then
        Set Fields(fc).Source = Me.Controls(fdef(0))(CLng(fdef(1)))
        Set Fields(fc).Source = Me.Controls(fdef(0))
    End If
    Fields(fc).Width = CSng(fdef(6)) * Twips
    Fields(fc).FontAdjust = CSng(fdef(7))
    Fields(fc).Attributes = UCase(Trim(fdef(8)))
    fc = fc + 1
Next lc

ReDim Preserve Fields(fc - 1)

End Sub

Function getJPos(ThingToPrint, ColumnNo, OutputDevice As Object, HorrizontalGap As Single)

' returns a justified position

Dim TW As Single
Dim LeftPos As Single

Select Case UCase(Fields(ColumnNo).Justify)
    Case Is = "R"
        ' right justify
        TW = OutputDevice.TextWidth(ThingToPrint)
        LeftPos = Fields(ColumnNo).Left + Fields(ColumnNo).Width - TW - (HGap * 0.5)
    Case Is = "C"
        ' center justify
        TW = Me.TextWidth(ThingToPrint) * 0.5
        LeftPos = Fields(ColumnNo).Left + (Fields(ColumnNo).Width * 0.5) - TW
    Case Else
        LeftPos = Fields(ColumnNo).Left + (HGap * 0.5)
End Select

getJPos = LeftPos

End Function
Public Function ReadFile(FileName As String) As String

' Reads a whole file into a string
' string contains ERROR if file not found or error

Dim wlfn As Long

wlfn = FreeFile
On Error Resume Next

If Len(Dir(FileName)) > 0 Then
    If Err.Number Then
        ReadFile = "Invalid resource file path: " + FileName
        Exit Function
    End If
    Open FileName For Input Shared As #wlfn
    ReadFile = Input(LOF(wlfn), wlfn)
    Close wlfn
    ReadFile = "ERROR"
End If

End Function
Now you can adjust your form when then printer changes the layout, no need for coding changes!


You didn't need to get the forms printed as VB can print anything.


thanks for the advices vb geeks..i all of your answers would be my solution.. :p


thanks for the advices vb geeks..i all of your answers would be my solution.. :p
Author of the Year 2009

Hi Luke207,
It appears that you have forgotten this question. I will ask Community Support to close it unless you finalize it within 7 days. I will ask a Community Support Moderator to:

    Accept inthedark's comment(s) as an answer.

Luke207, if you think your question was not answered at all or if you need help, just post a new comment here; Community Support will help you.  DO NOT accept THIS comment as an answer.

EXPERTS: If you disagree with that recommendation, please post an explanatory comment.
DanRollins -- EE database cleanup volunteer

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial