VB Printing (I think it SHOULD be easy)

Posted on 2005-04-13
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
    LVL 4

    Assisted Solution

    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

    LVL 4

    Expert Comment

    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
    LVL 5

    Accepted Solution

    Why not use the printer object? = "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
    LVL 38

    Assisted Solution

    >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 95

    Author Comment

    by:Lee W, MVP
    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 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 95

    Author Comment

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

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

    Featured Post

    Do You Know the 4 Main Threat Actor Types?

    Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

    Join & Write a Comment

    I’ve seen a number of people looking for examples of how to access web services from VB6.  I’ve been using a test harness I built in VB6 (using many resources I found online) that I use for small projects to work out how to communicate with web serv…
    When designing a form there are several BorderStyles to choose from, all of which can be classified as either 'Fixed' or 'Sizable' and I'd guess that 'Fixed Single' or one of the other fixed types is the most popular choice. I assume it's the most p…
    Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
    This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

    734 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

    Need Help in Real-Time?

    Connect with top rated Experts

    23 Experts available now in Live!

    Get 1:1 Help Now