Ten Code Conversions for VBA, Visual Basic .NET, and C#

This content is no longer actively maintained. It is provided as is, for anyone who may still be using these technologies, with no warranties or claims of accuracy with regard to the most recent product version or service release.

 

Paul Cornell
Microsoft Corporation

January 2003

Applies to:
     Microsoft® Office XP
     Microsoft Visual Basic® .NET
     Microsoft Visual C#™.NET

Summary: Learn equivalent syntax for Microsoft Office Visual Basic for Applications (VBA), Microsoft Visual Basic .NET, and Microsoft C# code samples. (21 printed pages)

Contents

Comments
Setting References
Declaring and Initializing Variables
Arrays
Collections
Do
If
Select Case
File Input and Output
Error Handling

The purpose of this article is to introduce Microsoft Office Visual Basic for Applications (VBA) developers to Microsoft Visual Basic .NET and Microsoft C# through the use of side-by-side code syntax comparisons. For additional code syntax examples, see:

Comments

VBA and Visual Basic .NET use the single apostrophe (') for comments.

C# uses a double slash (//) to denote comments to the end of the current line. You can also use a slash followed by an asterisk (/*) to begin a multi-line comment and use the asterisk followed by a slash (*/) to end a multi-line comment.

' VBA and Visual Basic .NET
' Any characters on this line are comments.
Dim strAge As String ' Any characters here are comments.
' This is a 
' multiline comment.

// C#
// Any characters on this line are comments.
string strAge; // Any characters here are comments.
/* This is a 
multiline comment. */

Setting References

In VBA, Visual Basic .NET, and C#, you set references in similar ways. As you know for VBA, in the Office Visual Basic Editor, on the Tools menu, you click References, and then select each reference to an external code component. In Visual Studio .NET, on the Project menu, you click Add Reference, and select each reference to an external code component.

To minimize object and collection name conflicts in VBA, you can optionally preface each object or collection declaration with the corresponding library's display name. You must preface object or collection declarations if there are conflicting types in multiple referenced external libraries (such as DAO.Recordset and ADO.Recordset if both Data Access Objects [DAO] and ActiveX Data Objects [ADO] are referenced in the project).

In Visual Basic .NET and C#, you must preface every class declaration with the class's corresponding namespace. You can shorten namespace references by using the Imports (Visual Basic .NET) or using (C#) statements. You can also alias namespace references.

' VBA
' Assume the Word 10.0 Object Library is referenced.
...
Dim wdApp As Word.Application ' Prefacing the library's display name.
Dim docMain As Document       ' Omitting the library's display name.
...

' Visual Basic .NET
' Assume the Word 2002 PIA is referenced.
...
Dim wdApp As Microsoft.Office.Interop.Word.Application
...

' You can shorten the previous line of code as follows:
Imports Microsoft.Office.Interop.Word
...
Dim wdApp As Application
...

' You can also use a namespace alias.
Imports Word = Microsoft.Office.Interop.Word
...
Dim wdApp As Word.Application
...

// C#
// Assume the Word 2002 PIA is referenced.
...
Microsoft.Office.Interop.Word.Application wdApp;
...

// You can also use a namespace alias.
using Word = Microsoft.Office.Interop.Word;
...
Word.Application wdApp;
...

If you refer to two or more classes in your code with the same name across two or more assemblies in .NET, you must qualify those classes with their complete namespaces or use namespace aliases. For example, if you reference the Microsoft.Office.Interop.Excel and Microsoft.Office.Interop.Word namespaces and then try to write the following code in Visual Basic .NET:

Imports Microsoft.Office.Interop.Word
Imports Microsoft.Office.Interop.Excel
...
Dim wdApp As Application
Dim xlApp as Application

You will receive the error 'Application' is ambiguous, imported from the namespaces or types 'Microsoft.Office.Interop.Excel, Microsoft.Office.Interop.Word'.

To resolve this error, you use a fully-qualified reference or a namespace alias, for example:

Dim wdApp As Microsoft.Office.Interop.Word.Application
Dim xlApp as Microsoft.Office.Interop.Excel.Application 

Or:

Imports Word = Microsoft.Office.Interop.Word
Imports Excel = Microsoft.Office.Interop.Excel
...
Dim wdApp As Word.Application
Dim xlApp As Excel.Application

Declaring and Initializing Variables

Declaring variables in Visual Basic .NET is the same as VBA. However, Visual Basic .NET and C# allow you to initialize variables on the same lines that you declare them. In C# variable declaration, you provide the data type (for example, the C# int data type is equivalent to the Visual Basic Integer data type), followed by the variable name, and you don't use the Dim or As statements.

Also, the Set statement no longer exists in Visual Basic .NET. Finally, notice that you must use a set of parentheses after code such as Word.Application(). In Visual Basic .NET and C#, you can immediately customize a class instance on initialization, which you cannot do in COM-based languages such as VBA. To signify that the Word.Application object takes no initialization arguments, you leave the parentheses empty.

' VBA
...
Dim wdApp As Word.Application
Dim docMain As Document
Dim intDocuments As Integer

Set wdApp = New Word.Application
Set docMain = wdApp.ActiveDocument

intDocuments = 0
...

' Visual Basic .NET
Imports Word = Microsoft.Office.Interop.Word
...
Dim wdApp As New Word.Application()
Dim docMain As Word.Document = wdApp.ActiveDocument
Dim intDocuments As Integer = 0
...

// C#
using Word = Microsoft.Office.Interop.Word;
...
Word.Application wdApp = new Word.Application();
Word.Document docMain = wdApp.ActiveDocument;
int intDocuments = 0;
...

Arrays

Array syntax is similar for VBA and Visual Basic .NET. However, in Visual Basic .NET you can initialize an array's values on the same line as the array's declaration. Also, notice that in VBA you use the Debug.Print method, while in Visual Basic .NET you use the Debug.WriteLine method, and you use the Console.WriteLine method in C#. Additionally, all argument lists must be surrounded by parenthesis in Visual Basic .NET and C# (in VBA, you can omit the parenthesis in simple statements). In VBA and Visual Basic .NET, you use space-underscore characters ( _) to specify line continuations and carriage returns for the ends of code statements and code blocks. In C#, there is no line-continuation character, semicolons specify the ends of code statements, and curly braces define code blocks. Also, notice the for loop in C#; you don't use the word Next, and the for loop conditions syntax is more compact. Finally, notice that you use ampersand symbols (&) to concatenate strings in Visual Basic and you use plus symbols (+) to concatenate strings in C#.

' VBA
...
Dim intAge(4) As Integer
Dim intPerson As Integer

intAge(1) = 35
intAge(2) = 34
intAge(3) = 29
intAge(4) = 30

For intPerson = 1 To UBound(intAge)

    Debug.Print "Person #" & intPerson & " is " & _
        intAge(intPerson) & " years old."

Next intPerson
...

' Visual Basic .NET
...
Dim intAge() As Integer = {35, 34, 29, 30}
Dim intPerson As Integer

For intPerson = 0 To UBound(intAge)

    Debug.WriteLine(value:="Person #" & intPerson + 1 & " is " & _
        intAge(intPerson) & " years old.")

Next intPerson
...

// C#
...
int[] intAges = {35, 34, 29, 30};
int intPerson;

for(intPerson = 0; intPerson < intAges.Length; intPerson++)
{
    Console.WriteLine("Person #" + (intPerson + 1) + " is " + 
        intAges[intPerson] + " years old.");
}
...

Collections

VBA and Visual Basic .NET both use the same Collection collection. There is no equivalent in C#; for example, you can use the System.Collections.ArrayList class to create a group of objects that behave similar to the Visual Basic Collection collection.

' VBA
...
Dim colNames As Collection
Dim intName As Integer

Set colNames = New Collection

With colNames

    .Add Item:="Paul"
    .Add Item:="Frank"
    .Add Item:="Lisa"
    .Add Item:="Dave"

    For intName = 1 To .Count

        ' Use Debug.WriteLine for Visual Basic .NET.
        Debug.Print "Item #" & intName & " = " & _
            .Item(intName)

    Next intName

End With
...

' Visual Basic .NET
Imports Microsoft.VisualBasic
...
Dim colNames As New Collection()
Dim intName As Integer

With colNames

    .Add(Item:="Paul")
    .Add(Item:="Frank")
    .Add(Item:="Lisa")
    .Add(Item:="Dave")

    For intName = 1 To .Count

        Debug.WriteLine(message:="Item #" & intName & " = " & _
            .Item(intName))

    Next intName

End With
...

// C#
using System.Collections;
...
ArrayList colNames = new ArrayList();

colNames.Add("Paul");
colNames.Add("Frank");
colNames.Add("Lisa");
colNames.Add("Dave");

for(int intName = 0; intName < colNames.Count; intName++)
{
    Console.WriteLine("Item #" + (intName + 1) + " = " + 
        colNames[intName]);
}
...

You can use the For Each…Next statement to iterate the objects in a VBA Collection collection because the Collection collection supports a hidden _NewEnum method.

You can use the For Each…Next statement to iterate the objects in a Microsoft.VisualBasic.Collection class instance because the Collection class implements the System.Collection.IEnumerable interface.

Finally, you can use the foreach statement in C# to iterate the objects in a System.Collections.ArrayList class instance because the ArrayList class implements the System.Collections.IEnumerable interface.

Here's how VBA, Visual Basic .NET, and C# support iterating through collections that support the _NewEnum method (COM) and class instances that implement the IEnumerable interface (.NET).

' VBA
...
Dim colNames As Collection
Dim vntName As Variant

Set colNames = New Collection

With colNames

    .Add Item:="Paul"
    .Add Item:="Frank"
    .Add Item:="Lisa"
    .Add Item:="Dave"

    For Each vntName In colNames

        Debug.Print vntName

    Next vntName

End With
...

' Visual Basic .NET
...
Dim colNames As New Collection()
Dim objName As Object

With colNames

    .Add(Item:="Paul")
    .Add(Item:="Frank")
    .Add(Item:="Lisa")
    .Add(Item:="Dave")

    For Each objName In colNames

        Debug.WriteLine(objName)

    Next objName

End With
...

// C#
...
ArrayList colNames = new ArrayList();

colNames.Add("Paul");
colNames.Add("Frank");
colNames.Add("Lisa");
colNames.Add("Dave");

foreach(object objName in colNames)
{
    Console.WriteLine(objName);
}
...

Do

Do…Loop behaves the same in VBA and Visual Basic .NET; C# uses a while block instead. Also notice in the Visual Basic .NET code sample below that the VBA code intCounter = intCounter + 1 is shortened to the equivalent intCounter += 1. In C# you write intCounter++;.

' VBA
...
Dim intNumber As Integer, intCounter As Integer

intNumber = 10
intCounter = 1

Do While intCounter <= intNumber

    Debug.Print intCounter
    intCounter = intCounter + 1

Loop
...

' Visual Basic .NET
Dim intNumber As Integer = 10, intCounter As Integer = 1

Do While intCounter <= intNumber

    Debug.WriteLine(value:=intCounter)
        intCounter += 1

Loop
...

// C#
...
int intNumber = 10, intCounter = 1;

while(intCounter <= intNumber)
{
    Console.WriteLine(intCounter);
    intCounter++;
}
...

If

If. ElseIf, and Else statements behave the same way in both VBA and Visual Basic .NET. In C#, the Visual Basic statement If changes to if, ElseIf changes to else if, and there is no Then statement in C#.

' VBA
...
Dim strTarget As String, strTry1 As String, strTry2 As String

strTarget = "Paul"
strTry1 = "Frank"
strTry2 = "Lisa"

If strTry1 = strTarget Then

    MsgBox strTry1 & " matches " & strTarget & "."

ElseIf strTry2 = strTarget Then

    MsgBox strTry2 & " matches " & strTarget & "."

Else

    MsgBox Prompt:="Neither " & strTry1 & " nor " & _
        strTry2 & " matches " & strTarget & "."

End If
...

' Visual Basic .NET
...
Dim strTarget As String = "Paul", strTry1 As String = "Frank", _
    strTry2 As String = "Lisa"

    If strTry1 = strTarget Then


        MsgBox(Prompt:=strTry1 & " matches " & strTarget & ".")

    ElseIf strTry2 = strTarget Then

        MsgBox(Prompt:=strTry2 & " matches " & strTarget & ".")

    Else

        MsgBox(Prompt:="Neither " & strTry1 & " nor " & _
            strTry2 & " matches " & strTarget & ".")

    End If
...

// C#
using System.Windows.Forms;
...
string strTarget = "Frank", strTry1 = "Paul", strTry2 = "Lisa";

if(strTry1==strTarget)
{
    MessageBox.Show(strTry1 + " matches " + strTarget + ".");
}
else if(strTry2==strTarget)
{
    MessageBox.Show(strTry2 + " matches " + strTarget + ".");
}
else
{
    MessageBox.Show("Neither " + strTry1 + " nor " + 
        strTry2 + " matches " + strTarget + ".");
}
...

Select Case

Select Case statements work the same way in both VBA and Visual Basic .NET. In C#, you use switch…case statements. After each case statement, you must use the break keyword. Case Else in Visual Basic translates to the default statement in C#.

' VBA
...
Dim strGrade As String

strGrade = "A"

Select Case strGrade

    Case "A"

        MsgBox Prompt:="Superior"

    Case "B"

        MsgBox Prompt:="Great"

    Case "C"

        MsgBox Prompt:="Good"

    Case "D"

        MsgBox Prompt:="Needs Improvement"

    Case "F"

        MsgBox Prompt:="Failing"

    Case Else

        MsgBox Prompt:="Which grading system " & _
            "are you using?"

    End Select

' Visual Basic .NET
Dim strGrade As String = "A"

Select Case strGrade

    Case "A"

        MsgBox(Prompt:="Superior")

    Case "B"

        MsgBox(Prompt:="Great")

    Case "C"

        MsgBox(Prompt:="Good")

    Case "D"

        MsgBox(Prompt:="Needs Improvement")

    Case "F"

        MsgBox(Prompt:="Failing")

    Case Else

        MsgBox(Prompt:="Which grading system " & _
            "are you using?")

End Select

// C#
using System.Windows.Forms;
...
string strGrade = "A";

switch(strGrade)
{
    case "A":
        MessageBox.Show("Superior");
        break;
    case "B":
        MessageBox.Show("Great");
        break;
    case "C":
        MessageBox.Show("Good");
        break;
    case "D":
        MessageBox.Show("Needs Improvement");
        break;
    case "F":
        MessageBox.Show("Failing");
        break;
    default:
        MessageBox.Show("Which grading system " + 
            "are you using?");
        break;
}
...

File Input and Output

The Visual Basic core language allows the Close, Input, Open, Print, and Write statements for file input and output. The VBA FileSystem module provides additional functions to navigate a file system and work with files such as ChDir, CurDir, FileCopy, SetAttr, and so on. The Microsoft Scripting Runtime (scrrun.dll) provides even more functions for file input and output such as CreateTextFile, OpenTextFile, ReadLine, and WriteLine. In Visual Basic .NET and Visual C# .NET you use the classes and members of the System.IO namespace.

' VBA
' Using the Open, Write, and Close statements.
...
Dim objFile As Variant
Dim strText As String

objFile = "C:\temp\Test.txt"
strText = "This text was written on " & Now & "."

Open objFile For Output As #1
Write #1, strText
Close #1
...

' Using the Microsoft Scripting Runtime.
...
Dim objFSO As Scripting.FileSystemObject
Dim objTS As Scripting.TextStream

Set objFSO = New Scripting.FileSystemObject
Set objTS = objFSO.CreateTextFile("C:\temp\Test.txt")

objTS.WriteLine "This text was written on " & Now & "."
objTS.Close
...

' Visual Basic .NET
Imports System.IO
...
Dim objSR As StreamWriter

objSR = File.CreateText("C:\temp\Test.txt")
objSR.WriteLine("This text was written on " & Now & ".")
objSR.Close()
...

// C#
using IO = System.IO;
...
IO.StreamWriter objSR;

objSR = IO.File.CreateText("C:\\temp\\Test.txt");
objSR.WriteLine("This text was written on " +
    System.DateTime.Now + ".");
objSR.Close();
...

Error Handling

VBA uses error-handling statements such as On Error GoTo Line, On Error GoTo 0, and On Error Resume Next. You can still use these in Visual Basic .NET, but you can also handle errors by using the Try/Catch/Finally statements (try/catch/finally in C#), which also reduces the amount of code you need to write, as follows:

' VBA
Private Sub DivideByZero()

    On Error GoTo DivideByZero_Err
    
    Dim intNumber As Integer
    
    intNumber = 1
    MsgBox "Here's a common error: " & intNumber / 0
    
DivideByZero_End:
    
    Exit Sub
    
DivideByZero_Err:
    
    Select Case Err.Number
    
        Case 11 ' Division by zero.
            MsgBox "You can't divide " & intNumber & " by 0."
            
        Case Else ' Unanticipated error.
            MsgBox "Error " & Err.Number & " in procedure DivideByZero: " & _
                Err.Description & "."
                
    End Select
    
    Resume Next
    
End Sub

' Visual Basic .NET
Private Sub DivideByZero()

    Dim intNumber As Integer = 1

    Try

        intNumber /= 0
        MsgBox("Here's a common error: " & intNumber)

    Catch e As System.OverflowException

        MsgBox("You can't divide " & intNumber & " by 0.")

    Catch e As System.Exception ' Unanticipated error.

        MsgBox("Error in " & e.Source & ": " & e.Message)

    Finally

        ' Recovery code goes here.

    End Try

End Sub

// C#
private void DivideByZero()
{

    int intNumber = 1;

    try
    {
        intNumber /= 0;
        MessageBox.Show("Here's a common error: " + intNumber);
    }

    catch(System.OverflowException e)
    {
        MessageBox.Show("You can't divide " + intNumber + " by 0.");
    }

    catch(System.Exception e)    // Unanticipated error.
    {
        MessageBox.Show("Error in " + e.Source + ": " + e.Message);
    }

    finally
    {
        // Recovery code goes here.
    }

}