VB Printing (I think it SHOULD be easy)

This is REALLY bothering me.  Several months ago I successfully created an App that queried a database and printed out information, one record per page to the PRINTER.  I'm 99% certain I didn't use the PrintForm Method and I can remember or easily figure out how I did it and now I need to do it again.

For example:

Query DB for 10 records of people.  I then format each line (font size, center or not, use some vbtab's to align things, etc, etc and then it AUTOMATICALLY prints out to my printer with the click of a button.  Suggestions anyone?

On a related note:
The PrintForm method sends an image of the specified form to the printer. To print information from your application with PrintForm, you must first display that information on a form and then print that form with the PrintForm method. The syntax is as follows:


If you omit the form name, Visual Basic prints the current form. PrintForm prints the entire form, even if part of the form is not visible on the screen. If a form contains graphics, however, the graphics print only if the form’s AutoRedraw property is set to True. When printing is complete, PrintForm calls the EndDoc method to clear the printer.

For example, you could send text to a printer by printing it on a form and then calling PrintForm with the following statements:

Print "Here is some text."

The PrintForm method is by far the easiest way to print from your application. Because it may send information to the printer at the resolution of the user’s screen (typically 96 dots per inch), results can be disappointing on printers with much higher resolutions (typically 300 dots per inch for laser printers). The results may vary depending on objects on your form.
I have tried the following, specifically:
Print "Here is some text."

And all I get is a blank form.  NOTHING on it.  And when printed, I get a BLANK page.  What am I missing?  Why doesn't
Print "Here is some text."
actually show the text?  I get no errors, it just doesn't show.

I consider this urgent so mucho points to the first person to answer correctly both questions - or I'll split them if you get the answer for one and not the other.


LVL 97
Lee W, MVPTechnology and Business Process AdvisorAsked:
Who is Participating?
gary_jConnect With a Mentor Commented:
Why not use the printer object?

printer.font.name = "Courier"
printer.font.size = 10
printer.orientation = 1 'portrait, 2 for landscape
printer.currentx = 500
printer.currenty = 500
printer.print "Test"

will send one page to the default printer with the word "test" positioned at 500,500

One method I use regularly is to format the printout in a listbox, using a font like courier or terminal
then go through the list box

for i = 0 to listbox.listcount - 1
    <-------------------------------- test for page breaks, increment lines, etc. here
    printer.print listbox.list(i)
next 'i


i'll using something like this:

sub prHead (intPage as page)
     if intpage = 1 then
            set up the printer object

     'print the heading
      call prLine(500,500,"First header line")
      call prline(500,750,"Second header line")
      printer.line (500,1000) - (10500,1000)
end sub

sub prLine (lngX as long, lngY as long, strPrint as string)
          printer.currentx = lngX
          printer.currenty = lngY
          printer.print strPrint
end sub

I hope this helps
rdwillettConnect With a Mentor Commented:
If you really want to print and are not using a datareport  use a richtextbox.

'Things to remember ( all margins must be defined in twips -- 1" = 1440 twips)
'You can also select printer using the commondialog control i.e.:
      'Printer.TrackDefault = True
'You can also use vbTab and vbcrLf and all the richtextbox features to format data. Font, ForeColor, etc
'You can also size the richtextbox to match the paper size (8.5X11 or other) and then use scroll bars on the form to view
'You can prevent user from editting richtextbox by setting locked propery = True

Call the following function from the module below from your form with something like this:
Private Sub Command1_Click()
    PrintRTF Me.RichTextBox1, 1440, 1440, 1440, 720    'sets margin to 1", 1", 1", 0.5"
End Sub

Add this code to a module:

Private Declare Function SendMessage Lib "user32" Alias _
"SendMessageA" (ByVal hWnd As Long, ByVal msg As Long, _
ByVal wp As Long, lp As Any) As Long

Private Declare Function GetDeviceCaps Lib "gdi32" _
  (ByVal hdc As Long, ByVal nIndex As Long) As Long

Private Const WM_USER = &H400
Private Const EM_FORMATRANGE As Long = WM_USER + 57

Private Const PHYSICALOFFSETX As Long = 112
Private Const PHYSICALOFFSETY As Long = 113

Private Type RECT
   Left           As Long
   Top            As Long
   Right          As Long
   Bottom         As Long
End Type

Private Type CharRange
   cpMin          As Long
   cpMax          As Long
End Type

Private Type FormatRange
   hdc            As Long
   hdcTarget      As Long
   rc             As RECT
   rcPage         As RECT
   chrg           As CharRange
End Type

Public Function PrintRTF(rtf As RichTextBox, nnLeftMarginWidth _
 As Long, nnTopMarginHeight As Long, nnRightMarginWidth As _
 Long, nnBottomMarginHeight As Long) As Boolean

    On Error GoTo ErrorHandler
    Dim nLeftOffset      As Long
    Dim nTopOffset       As Long
    Dim nLeftMargin      As Long
    Dim nTopMargin       As Long
    Dim nRightMargin     As Long
    Dim nBottomMargin    As Long
    Dim fr               As FormatRange
    Dim rcDrawTo         As RECT
    Dim rcPage           As RECT
    Dim nTextLength      As Long
    Dim nNextCharPos     As Long
    Dim nRet             As Long

    Printer.Print Space(1)
    Printer.ScaleMode = vbTwips
    nLeftOffset = Printer.ScaleX(GetDeviceCaps(Printer.hdc, _
    PHYSICALOFFSETX), vbPixels, vbTwips)
    nTopOffset = Printer.ScaleY(GetDeviceCaps(Printer.hdc, _
    PHYSICALOFFSETY), vbPixels, vbTwips)
    nLeftMargin = nnLeftMarginWidth - nLeftOffset
    nTopMargin = nnTopMarginHeight - nTopOffset
    nRightMargin = (Printer.Width - nnRightMarginWidth) _
    - nLeftOffset
    nBottomMargin = (Printer.Height - nnBottomMarginHeight) _
   - nTopOffset
    rcPage.Left = 0
    rcPage.Top = 0
    rcPage.Right = Printer.ScaleWidth
    rcPage.Bottom = Printer.ScaleHeight
    rcDrawTo.Left = nLeftMargin
    rcDrawTo.Top = nTopMargin
    rcDrawTo.Right = nRightMargin
    rcDrawTo.Bottom = nBottomMargin
    fr.hdc = Printer.hdc
    fr.hdcTarget = Printer.hdc
    fr.rc = rcDrawTo
    fr.rcPage = rcPage
    fr.chrg.cpMin = 0
    fr.chrg.cpMax = -1
    nTextLength = Len(rtf.Text)

        fr.hdc = Printer.hdc
        fr.hdcTarget = Printer.hdc
        nNextCharPos = SendMessage(rtf.hWnd, EM_FORMATRANGE, _
        True, fr)
        If nNextCharPos >= nTextLength Then Exit Do
        fr.chrg.cpMin = nNextCharPos
        Printer.Print Space(1)

    nRet = SendMessage(rtf.hWnd, EM_FORMATRANGE, _
    False, ByVal CLng(0))

    PrintRTF = True

    Exit Function
    PrintRTF = False
End Function

By the way you can print muliple pages by adding a next and previous button show user can view each page.  When printing pages just shuffle through recordset for each page
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

PaulHewsConnect With a Mentor Commented:
>What am I missing?  Why doesn't
Print "Here is some text."

Set the AutoRedraw = True on the form properties.  This will cause the form to retain any thing drawn or printed on it after repainting.

Private Sub Form_Load()
    Me.AutoRedraw = True
    Me.Print "Here is some text"
End Sub

But I would use the printer object as per gary_j's suggestion above to print the information...
Lee W, MVPTechnology and Business Process AdvisorAuthor Commented:
Since this was a two part question, part 2 was clearly answered by PaulHews, Part two, rdwillett provided a method that, quite frankly, I wasn't prepared to try and also wasn't the method I knew I had used a couple years back.  However, he did allude to a few things with the Printer.xyz lines and that did ring a bell, hence I awarded a small amount of points for this.  gary_j's answer I believe WAS the method I had used a couple years back and since he posted the comment I've been looking up more and more information on manipulating printout using the Printer object, and it's definitely working for me.

Thanks All!
Lee W, MVPTechnology and Business Process AdvisorAuthor Commented:
oops, this:
...answered by PaulHews, Part two, rdwillett provided...

should read:
...answered by PaulHews, Part one, rdwillett provided...
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.