Resources

VB6 vs VB.NET language - VB Keywords


This section includes a description of all the VB6 keywords and commands that aren't available or that behave differently under VB.NET.


Unless otherwise stated, VB Migration Partner fully supports all the Visual Basic 6 features and keywords mentioned in this page. For more information, please read the manual and the knowledge base section.




A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z




VB Keywords

#Const

Both VB6 and VB.NET support this language directive; however, VB6 supports and correctly evaluates the following functions: Abs, Sgn, Len, and LenB. VB.NET doesn’t support these functions in compile-time expressions. (In this case VB Migration Partner issues a warning.)

#If, #ElseIf, #Else, #End If

These compiler directives are supported under VB.NET; however, both the Upgrade Wizard and VB Migration Partner convert only the code inside the #If, #ElseIf, or #Else section whose condition is evaluated as “true”; VB6 code in other sections isn’t converted.

The two languages evaluate #If and #ElseIf conditions for two minor details. First, the VB6 test expression can contain the following functions: Abs, Sgn, Len, and LenB, whereas VB.NET doesn’t support these functions in compile-time expressions. (In this case VB Migration Partner issues a warning.). Second, all string comparisons are carried out in case-insensitive mode under VB6 and in case-sensitive mode under VB.NET.

Abs

The Abs keyword isn’t implemented in Microsoft.VisualBasic.dll assembly. You must replace it with a reference to the Math.Abs method (in System namespace)
        result = Math.Abs(value)

AddressOf

VB.NET supports the AddressOf keyword, but only when the application defines a delegate class that can point to the target method. To understand what this means, say that you have the following VB6 code:
        Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" ( _
            ByVal hWnd As Long, ByVal ndx As Long, ByVal newValue As Long) As Long
            
        Sub StartSubclassing(ByVal hWnd As Long)
            oldProcAddr = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WndProc)
        End Sub
        
        Function WndProc(ByVal hWnd As Long, ByVal uMsg As Long, _
            ByVal wParam As Long, ByVal lParam As Long) As Long
            ' …
        End Function
To have this code to compile correctly, you must define a delegate class that can point to the WndProc method and use this delegate in the definition of the SetWindowLong API method:
        Public Delegate Function SetWindowLong_CBK(ByVal hWnd As Integer, _
            ByVal uMsg As Integer, ByVal wParam As Integer, _
            ByVal lParam As Integer) As Integer
            
        Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
            (ByVal hWnd As Integer, ByVal ndx As Integer, _
            ByVal newValue As SetWindowLong_CBK) 
        
        Public Sub StartSubclassing(ByVal hWnd As Integer)
            oldProcAddr = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WndProc)
        End Sub
Notice that this mechanism works only because VB.NET allows you to omit the name of the delegate in the AddressOf expression. In fact, the complete – and arguably, more readable – version of the code inside the StartSubclassing method is as follows:
        oldProcAddr = SetWindowLong(hWnd, GWL_WNDPROC, _
            New SetWindowLong_CBK(AddressOf WndProc))
VB Migration Partner correctly generates the delegate definition and creates the overload for the Windows API method that takes the function pointer as an argument.

AppActivate

The VB6 version of the AppActivate method takes a second (optional) wait argument; if this argument is True than the method waits until the external application receives the input focus. The VB.NET version of this method takes only one argument.

VB Migration Partner provides a special AppActivate6 method that takes two arguments and behave like the VB6 method.

Array

VB.NET lacks the Array method, which VB6 developers can use to create a Variant array on the fly.

VB Migration Partner defines a replacement method named Array6, whose source code follows:
        Public Function Array6(ByVal ParamArray args() As Object) As Object
            Return args
        End Function

AscB

VB.NET doesn’t support “byte-oriented” string methods.

VB Migration Partner provides the AscB6 replacement method, which approximates the original VB6 method’s behavior but isn’t guaranteed to work well in all circumstances. This replacement method is marked as obsolete and methods invocations are flagged with a migration warning.

Atn

The Atn keyword isn’t implemented in Microsoft.VisualBasic.dll assembly. You must replace it with a reference to the Math.ATan method (in System namespace)
        result = Math.ATan(value)

Calendar

VB.NET doesn’t support the Calendar property.

VB Migration Partner defines a dummy replacement method named Calendar6 method that always returns zero and throws if a nonzero value is assigned.

CDate, IsDate

VB.NET version of CDate and IsDate methods is less forgiving than the corresponding VB6 method. Under VB6 these methods attempt to reverse the day-month numbers if they don’t make up a valid date. For example, under VB6 both statements assign the #11/23/2008# date constant to the target variable:
        dat = CDate("11/23/2008")   ' dd/mm/yyyy format is assumed
        dat = CDate("23/11/2008")   ' mm/dd/yyyy format is assumed
Under VB.NET one of the two assignments fails. (Which assignment fails depends on locale settings.)

VB Migration Partner’s library contains two methods, named CDate6 and IsDate6, that mimics VB6 behavior and ensures that converted applications behave like the original ones.

ChrB

VB.NET doesn’t support “byte-oriented” string methods.
VB Migration Partner provides the ChrB6 replacement method, which approximates the original VB6 method’s behavior but isn’t guaranteed to work well in all circumstances. This replacement method is marked as obsolete and methods invocations are flagged with a migration warning.

Close#

The Close# keyword maps to the FileClose method in Microsoft.VisualBasic.dll. File number can’t be preceded by the # symbol.

Const

VB6 supports implicit conversion between string and numeric values, VB.NET doesn’t. For example, the following code is legal in VB6 but not in VB.NET:
        Const ONE As String = "1"
        Const TWO As Integer = ONE * 2  ' this is equal to 2 (numeric)
Current version of VB Migration Partner doesn’t automatically fix this problem.

CreateObject

The CreateObject method defined in Microsoft.VisualBasic.dll fails to recognize classes that have been converted to VB.NET. To understand why this detail can impact on migrated applications, let’s suppose that you have an ActiveX EXE project named TestProject and that exposes a public class named Widget. Being a public COM class, the application can instantiate the class by means of either the New operator or the CreateObject method. (CreateObject is often used when the class name is parameterized or when you want the new object to run in a different thread.) After the migration to VB.NET, the class isn’t a COM class any longer and the canonic CreateObject function won’t work.

VB Migration Partner fixes this issue by defining a special CreateObject6 method that can instantiate both classes converted from VB6 and standard COM classes.

CStr, Str

Str and CStr methods support date arguments under VB6, but not under VB.NET.

CVar

VB.NET doesn’t support the Variant data type, consequently the CVar function isn’t supported and should be rendered as CObj.

CVErr

VB.NET doesn’t support the CVErr method. The simplest way to transport information about an error is to return an Exception object.

Date, Date$

VB6 overloads the Date keyword, in that it is both the name of the Date type and the name of the function that returns today’s date. In VB.NET the value of today’s date should be obtained by invoking the Today property. Instead, references to the Date$ function should be translated as DateString.

Debug.Print

The Debug.Print method must be converted to either Debug.Write or Debug.WriteLine, depending on whether the original VB6 statement has a trailing semicolon.

Declare

VB.NET fully supports the Declare keyword, except the ability to define “As Any” parameters. When converting a VB6 application you should replace such parameters with a definite data type; if callers pass different data types to the Declare – for example, a Long and a String – you should provide different overloads of the Declare statement, so that no “As Any” parameters are necessary.

Another problem with Declare statements is that VB.NET doesn’t support 32-bit integers used as callback addresses, as it happens with a few Windows API methods such as EnumFonts or EnumWindows. In this case you must declare a Delegate class with opportune syntax and change the parameter type so that it uses the delegate.

Finally, a minor problem you might face is that VB6 allows Declare statements containing two or more parameters with same name, but they are illegal under VB.NET.

VB Migration Partner handles these problems automatically: it generates all the necessary overloads for the Declare, defines one delegate class for each callback parameters, and adjusts parameter names if any duplicate exists.

DefBool, DefByte, DefCur, DefDate, DefDbl, DefInt, DefLng, DefObj, DefSng, DefStr, DefVar

These compiler directives aren’t supported by VB.NET; both VB Upgrade Wizard and VB Migration Partner assign the correct data type to all variables that aren’t declared or don’t have an explicit As clause.

Dim

VB6 allows you to define a variable without the As clause, in which case the type of the variable is affected by the DefXxx directive whose range corresponds to the first character of the variable’s name. (If no DefXxx directive is present, the Variant type is used by default.) VB.NET allows Dim keywords without the As clause only if Option Strict Off is used; the type of the variable is always Object. A different rule applies if the variable is part of a list, as in this statement:
        Dim x, y, z As Double
In VB6 the z variable is of type Double, whereas x and y are affected by the current DefXxx directive (or are Variants if no directive is found). Conversely, in VB.NET all three variables are of type Double.

Another difference between VB6 and VB.NET is that, if the Dim keyword appears inside an If, For, For Each, Do, While, or Select block, then the latter limits the scope of the variable to the block itself whereas VB6 makes the variable visible to the entire method:
        Do While x > 0
            ' in VB.NET the k variable can’t be accessed outside the Do…Loop block
            Dim k As Integer
            ...
        Loop
Both Upgrade Wizard and VB Migration Partner solve the problem by moving the Dim at the top of the block where it is defined.

Dim (arrays)

VB.NET doesn’t support arrays whose lower index is nonzero. Also, VB.NET requires that the rank – that is, the number of dimensions of the array - be specified if the array is declared but not initialized:
        Dim arr(,) As Integer   ' a two-dimensional array of integers

Dir

The version of the Dir method found in Microsoft.VisualBasic.dll assembly differs from the VB6 version in an important detail: when the latter enumerates all the directories in a subfolder, it can return two spurious entries:  “.” (single dot) and “..” (double dot), which represent current directory and parent directory. The VB.NET version doesn’t return these items. If the VB6 code being migrated assumes that these elements are always present, the converted VB.NET applications will behave errantly.

VB Migration Partner mimics the VB6 behavior, so that the migrated VB.NET works correctly even if the original VB6 application discards the first two results from Dir without checking whether they contain the “.” and “..” entries.

DoEvents

Under VB6 the DoEvents method ensures that all pending Windows messages are processed, then it returns the number of open forms. VB.NET’s version of this method is Application.DoEvents: it ensures that pending messages are processed but it returns no value to the caller.

VB Migration Partner provides a DoEvents6 method that behaves like the VB6 counterpart.

End

VB.NET supports the End keyword, but it is recommended that you invoke the Application.Exit method instead of (or before) executing the End keyword. This is the VB.NET code that VB Migration Partner produces:
        Application.Exit(): End

EndIf

VB6 supports the obsolete spelling “EndIf” (no embedded space); the VB6 code editor automatically expands this word into “End If”, but the obsolete keyword might be encountered in applications whose source code is automatically generated. VB.NET doesn’t support the “EndIf” spelling.

EOF#

The EOF# keyword maps to the EOF method in Microsoft.VisualBasic.dll. File number can’t be preceded by the # symbol.

Eqv

The Eqv operator isn’t supported under VB.NET. This is the equivalent expression to be used instead:
        result = (CBool(op1) = CBool(op2))

Erase

Under VB6 an array can be either static or dynamic: static arrays are declared and created in the Dim statement (e.g. Dim arr(10) As String), whereas dynamic arrays are first declared using a Dim statement (with no indexes) and later instantiated by means of a ReDim statement. The two array types use different memory allocation mechanisms – memory for static arrays are allocated at compile time, whereas dynamic arrays are always allocated at runtime – but from the developer’s perspective the main difference is in the behavior of the Erase keyword.

When the Erase keyword is applied to a static array, the memory allocated to the array is cleared: all the array elements are reset to their default value (zero, null string, or Nothing) but the array bounds aren’t modified. Conversely, when a dynamic array is erased, then the memory allocated to the array is released and any attempt to reference any element causes a runtime exception.

Under .NET all arrays are dynamic and the Erase keyword behave as with all VB6 dynamic arrays. This minor differences can cause a problem when migrating a piece of VB6  code that erases a static array and is then followed by a reference to one of its elements:

        ' this code works under VB6 but fails after migrating to VB.NET
        Dim arr(10) As Double    ' a static array
        ' …
        Erase arr 
        arr(0) = 123             ' exception under VB.NET

To work around this issue, VB Migration Partner converts the Erase statement into either Erase6 or the ClearArray6 method, for dynamic or static arrays respectively.

Error

VB.NET doesn’t support the Error statement; it should be replaced by a call to the Err.Raise method.

FileAttr

VB6 supports a version of FileAttr with two arguments. If the second argument is 1 or omitted the function returns the mode used to open the file; if the second argument is 2, then the function raises an Error 5 under VB6 (it used to return the operating system file handle under 16-bit version of Visual Basic.) The VB.NET version of this method supports only one argument.

FileDateTime

The VB6 version of the FileDateTime method works with both files and directories, whereas the VB.NET version works only with directories.

VB Migration Partner provides a special FileDateTime6 method that behaves like the VB6 one.

Format

The VB.NET version of the Format method differs from the VB6 version in many ways. First, it doesn’t accept named formats – namely, General Number, Currency, Fixed, Standard, Percent, Yes/No, True/False, On/Off. Second, it doesn’t support formatting of string values with the @, &, <, and > placeholders. Third, it doesn’t support a few date/time formats. Fourth, it doesn’t support the FirstDayOfWeek and FirstWeekOfYear optional arguments. There are other, minor differences too.

VB Migration Partner works around all these differences by exposing the special Format6 method, which behaves more closely like the VB6 method.

Get#

The Get# keyword maps to the FileGet method defined in the Microsoft.VisualBasic.dll assembly. However, the FileGet and FilePut methods don’t work in exactly the same manner with nonscalar values, therefore you can’t exchange data files between VB6 and VB.NET if the file contains dynamic arrays, variant values, or structures.

VB Migration Partner maps the Get# keyword to the FileGet6 method, which offers better compatibility with the original VB6 method.

GoSub

VB.NET doesn’t support the GoSub keyword. You should move the code in the GoSub block to a distinct method, defining and passing as arguments the local variables that the GoSub block uses.

VB Migration Partner manages to convert this keyword but delivers code that can’t be easily maintained, therefore it’s recommended that you get rid of GoSubs before migrating the project.

ImeStatus

VB.NET doesn’t support the ImeStatus method.

VB Migration Partner defines a dummy replacement method named ImeStatus6 method that always returns zero.

Imp

The Imp operator isn’t supported under VB.NET. This is the equivalent expression to be used instead:
        result = Not op1 Or op2

Implements

VB.NET supports the Implements keyword, but its argument must be and Interface type, not a class as in VB6. Also, the Implements keyword is also used to qualify methods and properties that implement a member of the interface:
        Private Sub IAddin_Connect(ByVal root As Object) Implements IAddin.Connect
            ' ...
        End Sub

Input#

The Input# keyword maps to the Input method in Microsoft.VisualBasic.dll. File number can’t be preceded by the # symbol.

InputB

VB.NET doesn’t support “byte-oriented” string methods.

VB Migration Partner provides the InputB6 replacement method, which approximates the original VB6 method’s behavior but isn’t guaranteed to work well in all circumstances. This replacement method is marked as obsolete and methods invocations are flagged with a migration warning.

InputBox

The VB.NET version of the InputBox method works exactly like the VB6 version, except for two details. First, the VB6 version accepts individual CR characters (ASCII 13) as line separators in the message text, whereas the VB.NET version requires a CR-LF pair (ASCII 13 + ASCII 10). Second, the VB6 version takes an optional pair of coordinates and interprets them as twips, whereas the VB.NET version interprets them as pixels. Third, the VB.NET version causes a Deactivated event in the current form, and then an Activated event when the input box is closed and the focus regains the input focus.

To avoid these minor problems, VB Migration Partner defines an InputBox6 method that works exactly like the VB6 method.

InstrB

VB.NET doesn’t support “byte-oriented” string methods.

VB Migration Partner provides the InstrB6 replacement method, which approximates the original VB6 method’s behavior but isn’t guaranteed to work well in all circumstances. This replacement method is marked as obsolete and methods invocations are flagged with a migration warning.

IsEmpty

VB.NET doesn’t support the Empty value, therefore the IsEmpty function isn’t supported. In most cases, the Empty value is converted to Nothing, therefore the IsEmpty function can map to the IsNothing method.

IsMissing

VB.NET doesn’t support missing optional parameters, therefore the IsMissing function isn’t supported. For example, the following VB6 code:
        Sub Execute(Optional ByVal shipDate As Variant)
            If IsMissing(shipDate) Then shipDate = Now
                …
        End Sub
should be modified – before or after the migration – so that the shipDate parameter has a well defined value if omitted. For example, you can use a value that is surely invalid for the application as the “missing” value:
        Sub Execute(Optional ByVal shipDate As Date = #1/1/1900#)
            If shipDate = #1/1/1900# Then shipDate = Now
                …
        End Sub
VB Migration Partner uses the special IsMissing6 method to handle missing optional arguments.

IsNull

VB.NET doesn’t support the Null value, therefore the IsNull function isn’t supported. In most cases, the Null value is converted to either Nothing or DBNull.Value, therefore the IsNull function can map to the following test:
        If value Is Nothing OrElse TypeOf value is DBNull Then …

Left

VB.NET supports Left and Right string functions. However, if the code runs inside a form or a user control, VB.NET interprets these names as references to the Left and Right properties of the Form and UserControl object itself, which causes a compilation error. You can avoid this error in two ways. First, you can explicitly reference the Microsoft.VisualBasic namespace, possibly with an Imports alias at the top of the file (this is the approach that VB Migration Partner uses):
        Imports VB = Microsoft.VisualBasic
        …
        Function GetFirstLastChar(ByVal arg As String) As String
            Return VB.Left(arg, 1) & VB.Right(arg, 1)
        End Function
Alternatively, you can use methods exposes by the System.String class, for example:
        Function GetFirstLastChar(ByVal arg As String) As String
            Return arg.SubString(0, 1) & arg.SubString(arg.Length – 1)
        End Function

LeftB

VB.NET doesn’t support “byte-oriented” string methods.

VB Migration Partner provides the LeftB6 replacement method, which approximates the original VB6 method’s behavior but isn’t guaranteed to work well in all circumstances. This replacement method is marked as obsolete and methods invocations are flagged with a migration warning.

Len

VB6’s Len method works with strings and Type…End Type blocks; in the latter case it returns the number of bytes taken when the block is written to disk or passed to a Windows API method. The VB.NET’s Len method only works with strings; you should use the Marshal.SizeOf method when working with structures, even though you aren’t guaranteed that you get the same value you’d receive in VB6.

VB Migration Partner’s library defines a Len6 method that behaves like the VB6 function.

LenB

VB.NET doesn’t support “byte-oriented” string methods.

VB Migration Partner provides the LenB6 replacement method, which approximates the original VB6 method’s behavior but isn’t guaranteed to work well in all circumstances. This replacement method is marked as obsolete and methods invocations are flagged with a migration warning.

Let, Set

VB.NET doesn’t support neither the Let nor the Set keyword. Object assignments don’t require the Set keyword because the lack of support for parameterless default members ensures that no ambiguity exists for the following statement:
        Dim tb As TextBox, txt As String
        tb = TextBox1           ' assign an object reference
        txt = TextBox1.Text     ' (explicitly) assign the default member

Line Input#

The Line Input# keyword maps to the LineInput function in Microsoft.VisualBasic.dll. File number can’t be preceded by the # symbol. Notice that, instead of taking the variable as an argument, the LineInput method returns the value read from file.
        result = LineInput(1)

Load

You can’t load a form in VB.NET. Creating a form instance has more or less the same effect.

LoadPicture

VB.NET doesn’t support the LoadPicture method; it can be rendered by means of the Image.FromFile method. There are a few differences, though, because the Image.FromFile method doesn’t support the size, colorDepth, x, and y (optional) arguments. Also, when an empty string is passed in the first argument, the LoadPicture VB6 method returns a null image.

To account for all these differences, VB Migration Partner defines a special method named LoadPicture6 that behaves like the VB6 method.

LoadResBitmap, LoadResData, LoadResString

VB.NET doesn’t support LoadResString, LoadResBitmap, and LoadResData methods.

VB Migration Partner converts VB6 resource files to.NET files and attempts to convert these methods into references to My.Resources.Xxxx items. (This conversion is possible only if the resource ID is a literal constant value.) In addition, automatic conversion of LoadResBitmap and LoadResData methods is tricky, because these methods take a second argument that defines the kind of resource (icon, bitmap, cursor); if this argument isn’t a literal or an enumerated constant, VB Migration Partner falls back to LoadResBitmap6 or LoadResData6 methods in the support library.

LOC#

The LOC# keyword maps to the Loc method in Microsoft.VisualBasic.dll. File number can’t be preceded by the # symbol.

Lock#

The Lock# keyword maps to the Lock method in Microsoft.VisualBasic.dll. File number can’t be preceded by the # symbol and the To keyword isn’t allowed.

LOF#

The LOF# keyword maps to the LOF method in Microsoft.VisualBasic.dll. File number can’t be preceded by the # symbol.

LSet

VB.NET doesn’t support the LSet keyword. You can use the String.PadRight method as a replacement in string assignments:
        s1 = s2.PadRight(s1.Length, " "c)    ' this replaces LSet s1 = s2
VB.NET has no equivalent for the LSet keyword used to copy elements of different Type…End Type blocks (Structure blocks in VB.NET).

MidB

VB.NET doesn’t support “byte-oriented” string methods.

VB Migration Partner provides the MidB6 replacement method, which approximates the original VB6 method’s behavior but isn’t guaranteed to work well in all circumstances. This replacement method is marked as obsolete and methods invocations are flagged with a migration warning.

Mod

VB6’s Mod operator converts its operands to integers and then returns the (integer) remainder of the division. By contrast, VB.NET’s Mod operator doesn’t perform any conversion: if the operands are floating-point numbers, the result is the remainder of the floating-point division. If the operands of the Mod operator are Single, Double, or Currency values, you should explicitly convert them to 32-bit integers before using the Mod operator under VB.NET:
        result = CInt(op1) Mod CInt(op2)
VB Migration Partner performs this fix automatically, if necessary.

MsgBox

The VB.NET version of the MsgBox method works exactly like the VB6 version, except that the VB6 version accepts individual CR characters (ASCII 13) as line separators in the message text, whereas the VB.NET version requires a CR-LF pair (ASCII 13 + ASCII 10). Also, the VB.NET MsgBox method causes a Deactivated event to be fired in the form that loses the input focus, and an Activated event when the message box is closed and the form regains the input focus.

To avoid these minor problems, VB Migration Partner defines a MsgBox6 method that works exactly like the VB6 method.

Name

VB.NET doesn’t support the Name method; you should use the Rename method, defined in the Microsoft.VisualBasic.dll assembly.

Next

Under VB6, a single Next keyword can terminate two or more For loops, as in this example:
        For i = 0 To 10
            For j = 0 To 20
                …
            Next j, i
VB.NET doesn’t support this syntax and requires that each For loop be terminated by a distinct Next keyword.

ObjPtr

VB6 language includes three undocumented functions: VarPtr, StrPtr, and ObjPtr. These methods have no equivalent under VB.NET and can’t be translated.

VB Migration Partner issues a warning when one of these methods is encountered.

On … GoSub

VB.NET doesn’t support calculated On…GoSub statements. You should move the code in GoSubs block to distinct methods, defining and passing as arguments the local variables that each GoSub block uses.

VB Migration Partner converts this keyword but delivers code that can’t be easily maintained, therefore it’s recommended that you get rid of On…GoSub statements before migrating the project.

On … Goto

VB.NET doesn’t support calculated On…GoTo statements. You can replace it with a Select Case whose Case blocks contain a GoTo statement, which increases the number of GoTos in the application and makes control flow hard to follow. It is recommended that original VB6 code be revised to get rid of On…GoTo statements before migrating the project.

Open#

The Open# keyword maps to the FileOpen method defined in the Microsoft.VisualBasic.dll assembly, which has a standard object-oriented syntax; keywords normally used inside an Open# statement – such as Input, Output, Random, Binary, Access, Shared, Read, Write, Lock – aren’t supported.

Option Base

VB.NET doesn’t support Option Base, because all arrays must have a zero lower index.

VB Migration Partner accounts for this directive and allows you to control the actual lower index by means of the ArrayBounds pragma.

Option Explicit

VB.NET supports this directive, but it requires an explicit On (or Off) argument:
        Option Explicit On

Option Private

This directive is used only in Access VBA and has no effect in VB6. VB.NET doesn’t support this directive and VB Migration Partner can safely ignore it.

Print, Print#

VB.NET doesn’t support the Print method – that outputs to a form, a user control, or a PictureBox’s surface – and partially supports the Print# method that outputs to file. The latter method maps to the Write or WriteLine method defined in Microsoft.VisualBasic.dll assembly, but the bytes actually emitted aren’t necessarily the same as in the original VB6 code, therefore the converted VB.NET application might not be able to exchange data with existing VB6 applications.

VB Migration Partner works around this issue by defining the FilePrint6 and FilePrintLint6 methods, which behave like the original VB6 methods.

Property Get, Property Let, Property Set

VB.NET uses a different syntax for properties. The Property Get method maps to the Get block in VB.NET; the Property Let or Property Set methods map to the Set block:
        Public Property Name() As String
            Get
                Return m_Name
            End Get
            Set(ByVal value As String)
                m_Name = value
            End Set
        End Property
Also, VB6 supports ByRef parameters for the Property Let and Property Set blocks, but VB.NET doesn’t.

Put#

The Put# keyword maps to the FilePut method defined in the Microsoft.VisualBasic.dll assembly. However, the FileGet and FilePut methods don’t work in exactly the same manner with nonscalar values, therefore you can’t exchange data files between VB6 and VB.NET if the file contains dynamic arrays, variant values, or structures.

VB Migration Partner maps the Put# keyword to the FilePut6 method, which offers better compatibility with the VB6 method.

ReDim

In VB6 the ReDim keyword can both declare an array and create its elements; in VB.NET you need two separate statements: the Dim keyword declares the array (and optionally creates its elements), but the ReDim keyword can only create (or recreate) array elements. In other words, the following VB6 statement:
        ReDim arr(10) As Integer    ' defines and creates an array
must be converted to the following VB.NET sequence:
        Dim arr() As Integer        ' defines an array
        …
        ReDim arr(10)               ' creates the array and its elements
VB.NET doesn’t support the “As” clause in ReDim keywords: the type of array elements is defined in the Dim statement. Like the Dim keyword, the ReDim keyword doesn’t support lower indices other than zero.

Rem

VB6 supports multiline remarks, as in this example:
        ' first line _
        second line _
        third line
VB.NET doesn’t support this syntax, therefore you must add an apostrophe at the beginning of the line:
        ' first line 
        ' second line
        ' third line

Return

VB.NET doesn’t support the GoSub keyword, therefore it doesn’t need to support the Return keyword. However, VB.NET uses the Return keyword to return a value from a Function or from the Get block of a Property block.

VB Migration Partner correctly translates both the Gosub and Return keywords, but delivers code that can’t be easily maintained, therefore it’s recommended that you get rid of GoSub statements before migrating the project.

Right

VB.NET supports Left and Right string functions. However, if the code runs inside a form or a user control, VB.NET interprets these names as references to the Left and Right properties of the Form and UserControl object itself, which causes a compilation error. You can avoid this error in two ways. First, you can explicitly reference the Microsoft.VisualBasic namespace, possibly with an Imports alias at the top of the file (this is the approach that VB Migration Partner uses):
        Imports VB = Microsoft.VisualBasic
        …
        Function GetFirstLastChar(ByVal arg As String) As String
            Return VB.Left(arg, 1) & VB.Right(arg, 1)
        End Function
Alternatively, you can use methods exposes by the System.String class, for example:
        Function GetFirstLastChar(ByVal arg As String) As String
            Return arg.SubString(0, 1) & arg.SubString(arg.Length – 1)
        End Function

RightB

VB.NET doesn’t support “byte-oriented” string methods.

VB Migration Partner provides the RightB6 replacement method, which approximates the original VB6 method’s behavior but isn’t guaranteed to work well in all circumstances. This replacement method is marked as obsolete and methods invocations are flagged with a migration warning.

RSet

VB.NET doesn’t support the RSet keyword. You can use the String.PadLeft method to replace the RSet in string assignments:
        s1 = s2.PadLeft(s1.Length, " "c)    ' this replaces RSet s1 = s2

SavePicture

VB.NET doesn’t support the SavePicture method, which can be rendered by means of the Image.Save method.

Seek#

Both the Seek# command and the Seek function map to the Seek method in Microsoft.VisualBasic.dll. (The version with one argument is the function, the version with two argument is the command.) File number can’t be preceded by the # symbol.

Spc

The SPC keyword, used to insert spaces in a Print, Print#, and Debug.Print method, is supported by VB.NET only inside converted Print# statements (which map to Write and WriteLine statements).

Split

When its first argument is an empty string, the VB6 version of Split returns an “empty” string array, that is an array that has no items. (Such an array has LBound=0 and UBound=-1.) Conversely, the VB.NET version of the Split method returns an array with one element (with zero index) set equal to the null string.

VB Migration Partner accounts for this difference and translates Split into the Split6 helper method, which behaves exactly like the VB6 method.

Sqr

The Sqr keyword isn’t implemented in Microsoft.VisualBasic.dll assembly. You must replace it with a reference to the Math.Sqrt method (in System namespace)
        result = Math.Sqrt(value)

Static

VB6 supports the Static keyword both at the variable-declaration level (in which case that variable is declared as static and preserves its value between calls to the method) and at the method-declaration level, in which case all the variables inside the method are treated as static variables. VB.NET supports the Static keyword only at the variable-declaration level. For example, the following VB6 code:
        Static Sub Test()
            Dim x As Integer, y As Long
            …
        End Sub
must be converted to VB.NET as follows:
        Sub Test()
            Static x As Short
            Static y As Integer
            …
        End Sub

Stop

VB.NET supports the Stop keyword, but it is good programming habit to replace it with a call to the Debugger.Break method. The reason: if a Stop keyword remains in product code, it crashes the application. Instead, the Debugger.Break method is ignored if the project is compiled in Release mode.

StrConv

The VB6 version of the StrConv method takes both strings and Byte array in its first argument, and can convert from ASCII to Unicode and back. The StrConv method defines in Microsoft.VisualBasic.dll assembly works only with strings and can’t convert to/from Unicode.

VB Migration Partner provides the StrConv6 method, which matches the VB6 behavior perfectly.

String, String$

VB6 overloads the String keyword, in that it is both the name of the String type and the name of a library method. In VB.NET the String and String$ methods should be rendered as the StrDup function.

StrPtr

VB6 language includes three undocumented functions: VarPtr, StrPtr, and ObjPtr. These methods have no equivalent under VB.NET and can’t be translated.

VB Migration Partner issues a warning when one of these methods is encountered.

TAB

The TAB keyword, used to insert spaces in a Print, Print#, and Debug.Print method, is supported by VB.NET only inside converted Print# statements (which map to Write and WriteLine statements).

Time, Time$

The Time function should be translated as a reference to the TimeOfDay property. Instead, references to the Time$ function should be translated as TimeString.

Timer

VB6’s version of the Timer functions returns a Single value; the Timer function defined in the Microsoft.VisualBasic.dll assembly returns a Double value.

To

The To keyword is supported inside Dim and ReDim statements; however, the lower indices of the array can only be zero under VB.NET, therefore in practice this keyword can be always removed. The Upgrade Wizard leaves the Dim or ReDim statement unchanged, therefore any nonzero lower index causes a compilation error.

VB Migration Partner is able to solve this problem if an opportune ArrayBounds pragma is used.

Type … End Type

Type…End Type blocks must be converted to VB.NET Structure blocks. However, if the Type contains initialized arrays, fixed-length strings, or auto-instancing (As New) object variables, the Structure requires to be initialized:
        Structure
            Public ID As Integer
            Public Name As String       ' this was String * 30
            Public Notes() As String    ' this was Notes(10)
            Public Address As Location  ' this was Address As New Location
            
            Public Sub Initialize()
                Name = Space(30)
                ReDim Notes(10)
                Address = New Location()
            End Sub
        End Structure
In addition to converting the Type block into a Structure, VB Migration Partner automatically initializes it. VB Migration Partner generates also the correct System.Runtime.InteropServices.MarshalAs attributes to ensure that string and array elements are marshaled correctly when the structure is passed as an argument to a Declare method.

TypeName

The VB.NET Typename function works like the original VB6 method, however you must pay attention to an important detail. The following VB6 code tests whether a value is a 16-bit integer
        If TypeName(value) = "Integer" Then
The problem in migrating this code to VB6 is that value is now a Short variable, therefore the code should be migrated as:
        If TypeName(value) = "Short" Then
A similar problem occurs with other data types that have been renamed in VB.NET, such as Long and Currency.

To avoid this problem, VB Migration Partner defines a special TypeName6 method that returns the same string that would return under VB6.

TypeOf

VB6 TypeOf keyword doesn’t perfectly corresponds to VB.NET keyword in many cases. For example, the following test always succeeds in VB.NET, because all data types inherit from System.Object:
        If TypeOf value Is Object Then …
Instead, if the test for Object is meant to check that a value isn’t scalar you must use this code:
        If Not TypeOf value Is String AndAlso Not value.GetType().IsValueType Then …
Under VB.NET you can’t use TypeOf with value types, therefore you need a different approach when testing the type of a Structure (e.g. a converted Type…End Type block):
        If value.GetType() Is GetType(myudt) Then …

Unload

You can’t unload a form in VB.NET. Invoking the form’s Close method has more or less the same effect.

Unlock#

The Unlock# keyword maps to the Unlock method in Microsoft.VisualBasic.dll. File number can’t be preceded by the # symbol and the To keyword isn’t allowed.

UserControl

Under VB6 you can use the UserControl keyword inside a user control class to reference the current user control, as in:
        UserControl.BackColor = vbRed
VB.NET doesn’t recognize this keyword, thus you must replace it with a reference to the “Me” object:
        Me.BackColor = Color.Red

VarPtr

VB6 language includes three undocumented functions: VarPtr, StrPtr, and ObjPtr. These methods have no equivalent under VB.NET and can’t be translated.

VB Migration Partner issues a warning when one of these methods is encountered.

Wend

VB6 supports While…Wend loops, whereas VB.NET supports While…End While loops; therefore the Wend keyword must be translated as End While.

Width#

The Width# keyword maps to the FileWidth method defined in Microsoft.VisualBasic.dll assembly.

Write#

VB.NET partially supports the Write# method that outputs to file, which maps to the Write or WriteLine method defined in Microsoft.VisualBasic.dll assembly. However, the bytes actually emitted aren’t necessarily the same as in the original VB6 code, therefore the converted VB.NET application might not be able to exchange data with existing VB6 applications.

VB Migration Partner translates this method to FileWrite6 and FileWriteLine6 methods, which behave like the original VB6 method.






Follow Francesco Balena on VB6 migration’s group on

LinkedIn





Read Microsoft Corp’s official case study of a VB6 conversion using VB Migration Partner.




Code Architects and its partners offers remote and onsite migration services.

More details




Subscribe to our free newsletter for useful VB6 migration tips and techniques.

newsletter



To learn more about your VB6 applications, run VB6 Analyzer on your source code and send us the generated text file. You will receive a detailed report about your VB6 applications and how VB Migration Partner can help you to quickly and effectively migrate it to .NET.

Get free advice



A fully-working, time-limited Trial Edition of VB Migration Partner allows you to test it against your actual code

Get the Trial




The price of VB Migration Partner depends on the size of the VB6 application, the type of license, and other factors

Request a quote




Migrating a VB6 application in 10 easy steps

Comparing VB Migration Partner with Upgrade Wizard

Migration tools: Feature Comparison Table

All whitepapers