Thomas Alva Edison's light bulb VBInfoZine Home
   An ordinary VB developer shares his own successes and failures
   FREE to registered subscribers.  

The dark side of the VB6 Format function

How the weird VB6 Format's function behavior caused a hard-to-find bug in an ASP WebClass application.

Quick question: What would the following VB6 code display in the immediate window:
Dim S As String
S = Format$(String$(300, "x"))
Debug.Print Len(S)
You guessed 300?

Wrong!

It displays 255. The Format$ function truncates its output to 255 characters.

I've found it out the hard way - by a user complaining about my application.

The application in question is a simple, web-based task manager. It has a VB6 webclass front-end that calls a VB6 COM+ business object. Pretty standard stuff a couple of years ago, when the application was developed ;-).

The weird thing is that the application has been in production for over three years without any problems. Well, until yesterday, when I've got a complaint that the task manager application sometimes truncates task descriptions entered by the user.

Here is how it happened:

The VB6 webclass uses a generic routine to read a value from an ADO Recordset and format it as a String to be displayed on a web page:

Public Sub GetFieldValueHtml( _
  ByVal dbRS As ADODB.Recordset, _
  ByVal sFieldName As String, _
  ByRef sTagContents As String)

  sTagContents = vbNullString
  If dbRS Is Nothing Then Exit Sub

  ' The field name can have embedded format string
  ' (after a colon character).
  Dim vValFmt
  vValFmt = VBA.Split(sFieldName, "|")

  Dim dbFld As ADODB.Field
  Set dbFld = dbRS.Fields(vValFmt(0))

  If UBound(vValFmt) < 1 Then
    ' No format string, just the field's name.
      sTagContents = VBA.Format$(dbFld.Value)
  Else
    ' Field name followed by a format string
    sTagContents = VBA.Format$(dbFld.Value, vValFmt(1))
  End If
End Sub
When the user wants to view a task, the business object retrieves the task's record from database and passes it as an ADO Recordset to the webclass. The webclass' template contains generic <WC@FIELD> tags containing the field names with optional formatting information, for example:
<tr>
  <td class="label">Priority:</td>
  <td class="control"><input type="text"
    value="<WC@FIELD>PriorityName</WC@FIELD>"
    name="PriorityName">
  </td>
  <td class="label">Deadline:</td>
  <td class="control"><input type="text"
    value="<WC@FIELD>Deadline|d.m.yyyy</WC@FIELD>"
    name="Deadline">
</td>
In the webclass' ProcessTag method, the tag's content is passed to the GetFieldValueHtml function, along with the task's recordset. If any string field in the recordset has more than 255 characters, the Format$ function truncates the string and the web page displays just the first 255 characters. (And the users complain about truncated task descriptions.)

Fortunately, the users didn't lose their long task descriptions, because the code reading values from HTML form fields and writing them back to the Recordset doesn't use the Format$ function. So when I fixed the GetFieldValueHtml function, the user saw her long task description in its entirety.

Here is the fix:

Public Sub GetFieldValueHtml( _
  ByVal dbRS As ADODB.Recordset, _
  ByVal sFieldName As String, _
  ByRef sTagContents As String)

  sTagContents = vbNullString
  If dbRS Is Nothing Then Exit Sub

  ' The field nam can have embedded format string
  ' (after a colon character).
  Dim vValFmt
  vValFmt = VBA.Split(sFieldName, "|")

  Dim dbFld As ADODB.Field
  Set dbFld = dbRS.Fields(vValFmt(0))

  If UBound(vValFmt) < 1 Then
    ' No format string, just the field's name.
    ' @@@ Don't use Format on values bigger than 255 chars,
    ' because Format truncates its output to 255 chars.
    If dbFld.ActualSize > 255 Then
      sTagContents = dbFld.Value
    Else
      sTagContents = VBA.Format$(dbFld.Value)
    End If
  Else
    sTagContents = VBA.Format$(dbFld.Value, vValFmt(1))
  End If
End Sub
Funny, isn't it?

Well, not much, really. It meant about three hours of debugging, fixing and testing old VB6 code.

Mind that Format!

© Palo Mraz, Wednesday, August 06, 2003

PS: What about VB.NET? It's OK; VB.NET's Format doesn't truncate its output.

 ©2003-2007 Palo Mraz. All Rights Reserved.   See my 'new browser window' policy