VB6 and VB.NET are similar languages that differ for a myriad of major and minor details. Even keywords, methods, and controls that have the same name in both environments may have a completely different behavior, as we exhaustively show in our Resource section.

A tool that aims at preserving functional equivalence with the original VB6 code should account for all or at least the majority of these differences. All the VB6 conversion products on the market, including VB Migration Partner, fill this gap with a combination of these two elements:

  • code transformation techniques, to generate VB.NET code that behaves like the original VB6 code
  • support library that expose methods and controls that aren't found in the .NET Framework or in the Microsoft.VisualBasic namespace

Even the Upgrade Wizard included in Visual Studio, arguably the least sophisticated conversion tool around, relies on TWO support libraries - Microsoft.VisualBasic.Compatibility.dll and Microsoft.VisualBasic.Compatibility.Data.dll - to support VB6 features that have no direct correspondence in VB.NET, such as control arrays and the ADODC, DriveListBox, DirListBox, and FileListBox controls.

One of VB Migration Partner's strengths is its comprehensive support library. Its dozens of classes and hundreds of methods ensure that the generated VB.NET code always performs like the original VB6 app, an important factor in dramatically reducing the time and cost of the migration process. No other conversion tool comes with such a complete library and in fact no other conversion tool can compare to VB Migration Partner in its support for VB6 features.

Our competitors are aware of the many advantages of this approach, therefore some of them are adopting a twofold strategy: on one hand they are expanding *their* support library, on the other they publish strongly biased whitepapers where they claim that that extensive libraries compromise the maintainability of the generated VB.NET project.

Notice that VB Migration Partner is never explicitly mentioned in these documents, therefore authors don't feel compelled to back up their claims with any sort of evidence.

In this article I'll focus only on the supposed lack of readability and maintainability of converted VB.NET that use a support library. But unlike our competitors, I'll build my assertions on actual code snippets and compare the code that VB Migration Partner generates with the result from a “traditional” VB6 conversion tool that comes with a less powerful support library. Consider the following KeyPress handler written in VB6:

Private Sub Text1_KeyPress(KeyAscii As Integer)
   ' convert the pressed key to uppercase, but ignore spaces
   If KeyAscii = 32 Then KeyAscii = 0 : Exit Sub
   KeyAscii = Asc(Chr(KeyAscii))
End Sub

VB Migration Partner converts it as follows:

Private Sub Text1_KeyPress(ByRef KeyAscii As Short) Handles Text1.KeyPress
   ' convert the pressed key to uppercase, but ignore spaces
   If KeyAscii = 32 Then KeyAscii = 0 : Exit Sub
   KeyAscii = Asc(Chr(KeyAscii))
End Sub

The resulting VB.NET code is basically identical to the original code, and many VB6 developers understand how to read and maintain this code. Obviously there is no maintainability problem here.

Let’s see now the code produced by another conversion tool that doesn't rely on an extensive support library. The name the tool in question isn't really important, because the same concepts apply to any conversion tool that attempts to fill the gap between VB6 and VB.NET exclusively by means of code transformation techniques:

Private Sub Text1_KeyPress(ByVal eventSender As Object, _
      ByVal eventArgs As KeyPressEventArgs) Handles Text1.KeyPress
   Dim KeyAscii As Integer = Strings.Asc(eventArgs.KeyChar)
   ' convert the pressed key to uppercase, but ignore spaces
   If KeyAscii = 32 Then
      KeyAscii = 0
      If KeyAscii = 0 Then
         eventArgs.Handled = True
      End If
      Exit Sub
   End If

   KeyAscii = Strings.Asc(Strings.Chr(KeyAscii).ToString()(0))
   If KeyAscii = 0 Then
      eventArgs.Handled = True
   End If
   eventArgs.KeyChar = Convert.ToChar(KeyAscii)
End Sub

In the attempt to preserve functional equivalence of the original 3 statements inside the method, the tool generated as many as 13 (thirteen!!) statements. 

You might believe that the KeyPress event is a special and unique case, so let’s see another code snippet, a simple VB6 method that defines two optional parameters:

Public Sub TestOptional(Optional x As Variant, Optional y As Variant)
   If IsMissing(x) Then
      If IsMissing(y) Then
         x = 10
         y = 20
      End If
   End If
   MsgBox x * y
End Sub

This is how VB Migration Partner correctly translates it to VB.NET:

Public Sub TestOptional(ByRef Optional x As Object = MissingValue6, _
      ByRef Optional y As Object = MissingValue6)
   If IsMissing6(x) AndAlso IsMissing6(y) Then
      x = 10
      y = 20
   End If
   MsgBox6(x * y)
End Sub

Thanks to its support library, VB Migration Partner can generate code that is as readable and maintainable as the original VB6 method. Well, the generated code is actually more readable, because our software merged the two nested IFs, however this improvement is achieved by means of its sophisticated conversion engine and isn't a consequence of using a library.

Let’s now look at the code that our competitor's tool generates for the same method (for brevity's sake I removed 4 upgrade warnings):

Public Sub TestOptional(ByRef x_optional As Object, _
      ByRef y_optional As Object)
   Dim y As Object = Nothing
   If y_optional Is Nothing OrElse Not y_optional.Equals(Type.Missing) Then _
      y = TryCast(y_optional, Object)
   Dim x As Object = Nothing
   If x_optional Is Nothing OrElse Not x_optional.Equals(Type.Missing) Then _
      x = TryCast(x_optional, Object)

   Try
      If Not (x_optional Is Nothing) AndAlso _
         x_optional.Equals(Type.Missing) Then
         If Not (y_optional Is Nothing) AndAlso y_optional.Equals(Type.Missing) Then
            x = 10
            y = 20
         End If
      End If
      MessageBox.Show(CStr(CDbl(x) * CDbl(y)), Application.ProductName)
   Finally
      y_optional = y
      x_optional = x
   End Try
End Sub

Public Sub TestOptional(ByRef x_optional As Object)
   Dim tempRefParam As Object = Type.Missing
   TestOptional(x_optional, tempRefParam)
End Sub

Public Sub TestOptional()
   Dim tempRefParam2 As Object = Type.Missing
   Dim tempRefParam3 As Object = Type.Missing
   TestOptional(tempRefParam2, tempRefParam3)
End Sub

Now ask yourself: Which code would you like to maintain in the future? The concise adn readable 7-line method produced by VB Migration Partner or the 3 methods and 28 statements produced by the other tool?

Bottom line: never ever trust marketing literature that don't provide real-world examples and accurate comparisons.