Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

setting the "vbTab" width (or space)

Status
Not open for further replies.

OrthoDocSoft

Programmer
May 7, 2004
291
0
0
US
Folks,

I'm making progress with my printing format by using "vbtab" inserted into strings to space things correctly.

Problem is that the width of the data in the first column "widens" (because the words get longer) as the data prints down the page, and when it is wider than the set vbTab width, it kicks over another tab, even when I've already tabbed over plenty.

What I need to do is set the tab width a bit wider so this doesn't happen. Can it be done?

I need somthing like:

"Set vbTab.space = 8"

Thanks

Ortho


[lookaround] "you cain't fix 'stupid'...
 
Don't know if it applies directly for you but might help. I produce a complicated printout using a richtextbox control:

Code:
 With fPrinter.rtbPrint                                  'use the rich text box
    
        .SelText = vbCrLf: .SelText = vbCrLf                    'feed two lines
        .SelTabCount = 2                                        'set the tabs and tab positions for the header
        .SelTabs(0) = 40
        .SelTabs(1) = 70
        .SelBold = True                                                         'set bold font for the title
        .SelText = "DETAILED TEST RESULTS - " & frmBVID.lblTestType & " "       'print the title
        .SelText = frmBVID.lblTestSys & vbTab & vbTab & NewSeq & vbCrLf
        .SelBold = False                                                        'switch off bold
        .SelText = String(85, "_") & vbCrLf                                     'print a horizontal line
        .SelText = vbCrLf                                                       'complete the rest of the header
        .SelText = "DTp Number : " & frmBVID.txtValue(0) & vbTab & "GVTS : " & vts & vbCrLf
        
        .SelText = "Vehicle Make : " & pMake & vbTab & "Date : " & Date & vbTab & "Time : " & Time & vbCrLf
        
        Select Case UCase(testset.Tclass)
            
            Case Is = "HGV"
                .SelText = "Vehicle Type : " & pType & vbTab & "GVW (kg): " & Format(frmBVID.txtValue(14)) & vbTab & "GTW (kg): " & Format(frmBVID.txtValue(15)) & vbCrLf
            
            Case Is = "PSV"
                .SelText = "Vehicle Type : " & pType & vbCrLf
            
            Case Is = "TRAILER"
                .SelText = "Vehicle Type : " & pType & vbTab & "GVW (kg): " & Format(frmBVID.txtValue(2)) & vbTab & "TAW (kg): " & Format(frmBVID.txtValue(7)) & vbCrLf
            
            Case Is = "CLASS4"
                .SelText = "Vehicle Type : " & pType & vbTab & "TW (kg): " & Format(frmBVID.txtValue(5)) & vbCrLf
            
            Case Is = "CLASS5"
                If Not frmBVID.txtValue(5) = "-" Then
                    .SelText = "Vehicle Type : " & pType & vbTab & "GVW (kg): " & Format(frmBVID.txtValue(5)) & vbCrLf
                Else
                    .SelText = "Vehicle Type : " & pType & vbTab & "GVW (kg): " & Format(frmBVID.txtValue(6)) & vbCrLf
                End If
            
            Case Is = "CLASS7"
                .SelText = "Vehicle Type : " & pType & vbTab & "GVW (kg): " & Format(frmBVID.txtValue(5)) & vbCrLf
            
        End Select
        
        If Not storereg = 0 Then            'if the customer info may have been stored, print it
        
            .SelText = "Vehicle ID : " & testset.Reg & vbTab & "Customer : " & testset.Customer & vbCrLf
        
        Else
            
            .SelText = vbCrLf               'otherwise feed a line
        
        End If
        
        .SelText = vbCrLf                   'another blank line
    
    End With
 
Likewise, here's some code I use to print RTF (if it helps), I think I got it from MSDN.

Code:
Public Sub PrintRTF(RTF As Object, PrinterDriver As String, LeftMarginWidth As Long, TopMarginHeight As Long, RightMarginWidth As Long, BottomMarginHeight As Long, OrigPageWidth As Long, OrigPageHeight As Long)
  
  Dim LeftOffset As Long
  Dim TopOffset As Long
  Dim LeftMargin As Long
  Dim TopMargin As Long
  Dim RightMargin As Long
  Dim BottomMargin As Long
  Dim fr As FormatRange
  Dim rcDrawTo As RECT
  Dim rcPage As RECT
  Dim TextLength As Long
  Dim NextCharPosition As Long
  Dim OldNextCharPosition As Long
  Dim r As Long
  Dim Prx As Printer
  
  ' Select the printer...
  For Each Prx In Printers
    If (Prx.DeviceName = PrinterDriver) Then
      Set Printer = Prx
      Exit For
    End If
  Next Prx
  DoEvents
  
  ' Start a print job to get a valid Printer.hDC
  Printer.Print Space(1)
  Printer.ScaleMode = vbTwips
  
  ' Get the offset to the printable area on the page in twips
  LeftOffset = Printer.ScaleX(GetDeviceCaps(Printer.hdc, PhysicalOffsetX), vbPixels, vbTwips)
  TopOffset = Printer.ScaleY(GetDeviceCaps(Printer.hdc, PhysicalOffsetY), vbPixels, vbTwips)
  
  ' Check margins...
  If (LeftMarginWidth = -1) Then LeftMarginWidth = 500
  If (RightMarginWidth = -1) Then RightMarginWidth = 500
  If (TopMarginHeight = -1) Then TopMarginHeight = 500
  If (BottomMarginHeight = -1) Then BottomMarginHeight = 500
  If (OrigPageWidth = -1) Then OrigPageWidth = 0
  If (OrigPageHeight = -1) Then OrigPageHeight = 0
  
  ' Account for the original page dimensions...
  XFactor! = IIf(OrigPageWidth = 0, 1, Printer.Width / (OrigPageWidth + 1))
  YFactor! = IIf(OrigPageHeight = 0, 1, Printer.Height / (OrigPageHeight + 1))
  
  ' Calculate the Left, Top, Right, and Bottom margins
  LeftMargin = LeftMarginWidth - LeftOffset
  TopMargin = TopMarginHeight - TopOffset
  RightMargin = (Printer.Width - (RightMarginWidth / XFactor!)) - LeftOffset
  BottomMargin = (Printer.Height - (BottomMarginHeight / YFactor!)) - TopOffset
  
  LeftMargin = LeftMargin / XFactor!
  RightMargin = RightMargin / XFactor!
  TopMargin = TopMargin / YFactor!
  BottomMargin = BottomMargin / YFactor!
  
  ' Set printable area rect
  rcPage.Left = 0
  rcPage.Top = 0
  rcPage.Right = Printer.ScaleWidth
  rcPage.Bottom = Printer.ScaleHeight
  
  ' Set rect in which to print (relative to printable area)
  rcDrawTo.Left = LeftMargin
  rcDrawTo.Top = TopMargin
  rcDrawTo.Right = RightMargin
  rcDrawTo.Bottom = BottomMargin
  
  ' Set up the print instructions
  fr.hdc = Printer.hdc        ' Use the same DC for measuring and rendering
  fr.hdcTarget = Printer.hdc  ' Point at printer hDC
  fr.rc = rcDrawTo            ' Indicate the area on page to draw to
  fr.rcPage = rcPage          ' Indicate entire size of page
  fr.chrg.cpMin = 0           ' Indicate start of text through
  fr.chrg.cpMax = -1          ' end of the text
  
  ' Get length of text in RTF
  TextLength = Len(RTF.Text)
  
  ' Loop printing each page until done
  On Error Resume Next
  Do
    ' Print the page by sending EM_FORMATRANGE message
    OldNextCharPosition = NextCharPosition
    NextCharPosition = SendAnyMessage(RTF.hwnd, EM_FormatRange, True, fr)
    If (NextCharPosition >= TextLength) Or (NextCharPosition = OldNextCharPosition) Then Exit Do
    fr.chrg.cpMin = NextCharPosition ' Starting position for next page
    Printer.NewPage                  ' Move on to next page
    Printer.Print Space(1)           ' Re-initialize hDC
    fr.hdc = Printer.hdc
    fr.hdcTarget = Printer.hdc
  Loop      ' Commit the print job
  
  Printer.EndDoc      ' Allow the RTF to free up memory
  
  r = SendMessage(RTF.hwnd, EM_FormatRange, False, ByVal CLng(0))
  
End Sub

- Andy
___________________________________________________________________
If you think nobody cares you're alive, try missing a couple of mortgage payments
 
Something like this perhaps;

Private Sub Command1_Click()

Dim MyData(1 To 10, 1 To 4) As String
Dim ColumnOffsets As Variant

Printer.ScaleMode = vbCentimeters
ColumnOffsets = Array(0, 2, 5, 8, 10) 'element 0 is not used below

For j = 1 To 10 'get your data into an array
For i = 1 To 4
MyData(j, i) = "Column " & i & "Row " & j
Next
Next
For j = 1 To 10 'print the array
For i = 1 To 4
Printer.CurrentX = ColumnOffsets(i)
Printer.Print MyData(j, i);
Next
Printer.Print vbCrLf
Next
Printer.EndDoc

End Sub
 
Andy, that's just a bastardised version of the MSDN link I already gave to Ortho in thread222-1571225 (the full version has the advantage that what is displayed on the screen matches what is printed)
 
What they're trying to say, is "no" you can't change the size of a tab character.
What you can do instead, is not use vbTab, but use your own variable set to a fixed length containing spaces.
And use a fixed-length font, such as Courier New, in the textbox to ensure spacing is consistent.

Const BigTab as String = " "
 
>What they're trying to say, is "no" you can't change the size of a tab character


No, we're not. You can change the size of a tab. But you have to resort to the API to output your text (unless you are displaying in a multiline edit control or a richtextbox - then you can use the API to set the tab size, and use normal VB text routines).

However the OP is actually trying to develop a report printing routine, and some of us are suggesting an alternative approach ...

 
With the richtextbox control you have good control over tabs using the seltabs and tabcount properties - no need for the api? (Provided the rtb is the only control with tabstop=true on the form)

 
You might also consider using the VB6 DataReport capability as an alternative if you haven't looked at it yet. This can export as text or HTML as well as print the output, and it can be previewed before printing too. You also have a "designer" for creating the layout in the IDE. It does not require the used of a database at all, just create a DataSource control that returns an ADO Recordset. Example here.

Another option is to use a DHTMLEdit control for reporting. This also offers the ability to preview, print, and save as HTML. A small example of this can be found here. The example works off a template in HTML, so you can easily use any HTML development tool to play with your report layout.
 
>With the richtextbox control you have good control

You do not have the ability to set the default tab size, which you do with the API. Of course, this may not be a particualrly onerous issue.
 
In terms of performance, and time to develop, what's the benefit of using API calls to alter tab size, as opposed to just defining your own constants or structs to insert line space?
 
One problem is that adding spaces only works reliably with fixed pitch fonts (as you yourself noted).

 
I guess I was getting at bbuk's point--you don't need to alter the tab size, you merely need to set fixed tab stops within the richtextbox. However, even those aren't always reliable with variable-width fonts, so I would still suggest fixed-width any time exact visual spacing or alignment is a requirement.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top