[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now


VB Printing (I think it SHOULD be easy)

Posted on 2005-04-13
Medium Priority
Last Modified: 2012-06-27
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.


Question by:Lee W, MVP

Assisted Solution

rdwillett earned 200 total points
ID: 13778950
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


Expert Comment

ID: 13778961
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

Accepted Solution

gary_j earned 800 total points
ID: 13784459
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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

LVL 38

Assisted Solution

PaulHews earned 1000 total points
ID: 13784547
>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...
LVL 97

Author Comment

by:Lee W, MVP
ID: 13807190
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!
LVL 97

Author Comment

by:Lee W, MVP
ID: 13807202
oops, this:
...answered by PaulHews, Part two, rdwillett provided...

should read:
...answered by PaulHews, Part one, rdwillett provided...

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

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

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

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…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
Suggested Courses

834 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