Developing Microsoft Office Solutions Using C#

 

Paul Cornell
Microsoft Corporation

February 7, 2002

C# (pronounced "C sharp") is a new programming language, developed by Microsoft, which was developed from the ground up to work with the Microsoft .NET platform. Although you do not need to learn C# to develop .NET solutions, by the end of this month's column, you will see that C# code is not that difficult to read or program, and your awareness of C# will give you additional options as you develop Microsoft Office solutions.

Why Should I Use C#?

For years, there has been a somewhat heated discussion between the C/C++ and Microsoft Visual Basic® developer communities about which programming language to use. The C/C++ developers have commented that Visual Basic is a "toy" programming language that lacks the power and flexibility of C/C++, while Visual Basic developers complain that C/C++ is too hard to learn and takes too long to develop straightforward business applications.

Because Microsoft Visual Basic .NET and C# both conform to the .NET Common Language Specification (CLS) and the common language runtime, there is very little you can do in C# that you cannot do now in Visual Basic .NET. I feel the main thing to consider when evaluating whether to use C# is your previous experience with languages such as C, C++, or Microsoft JScript®. If you are more comfortable with these languages than Visual Basic for Applications (VBA), Microsoft Visual Basic, or Microsoft Visual Basic Scripting Edition (VBScript), you may want to consider using C#.

Additionally, we are already beginning to see more code samples using C# syntax presented in programming-oriented Web sites and books. We should also begin to see more developers creating solutions using C# that integrate into Microsoft Office. The time you invest in learning C# now will pay dividends later if you need to read, interpret, or interoperate with C# code.

Exploring a PowerPoint Macro in Office VBA, Visual Basic .NET, and C#

To demonstrate the similarities and differences among coding in Office VBA, Visual Basic .NET, and C#, I created a simple macro in Microsoft PowerPoint® 2002.

Here is the macro presented in the Office VBA version:

' Office VBA macro.
' Created in Microsoft PowerPoint 2002.

' References:

' Office VBA references by default:
'   Visual Basic for Applications (VBE6.DLL)
'   Microsoft PowerPoint 10.0 Object Library (msppt.olb)
'   OLE Automation (stdole2.tlb)
'   Microsoft Office 10.0 Object Library (mso.dll)

Public Sub CreateAnimatedPresentation()

    ' Purpose: Creates a PowerPoint presentation,
    ' adds a slide and two shapes to the slide,
    ' animates the shapes, and runs the slide show.
    
    Dim ppApp As PowerPoint.Application
    Dim objPres As PowerPoint.Presentation
    Dim objSlide As PowerPoint.Slide
    Dim objSquareShape As PowerPoint.Shape
    Dim objTriangleShape As PowerPoint.Shape
    Dim objSequence As PowerPoint.Sequence
    
    Set ppApp = New PowerPoint.Application
    
    ' Create a new PowerPoint presentation.
    Set objPres = ppApp.Presentations.Add
            
    ' Add a slide to the presentation.
    Set objSlide = objPres.Slides.Add(Index:=1, _
        Layout:=ppLayoutBlank)
    
    ' Place two shapes on the slide.
    Set objSquareShape = objSlide.Shapes.AddShape _
        (Type:=msoShapeRectangle, Left:=0, Top:=0, _
        Width:=100, Height:=100)
    Set objTriangleShape = objSlide.Shapes.AddShape _
        (Type:=msoShapeRightTriangle, Left:=0, Top:=150, _
        Width:=100, Height:=100)
    
    ' Add text to the shapes. 
    objSquareShape.TextFrame.TextRange.Text = "Click Me!"
    objTriangleShape.TextFrame.TextRange.Text = "Me Too!"
    
    ' Animate the two shapes.
    Set objSequence = objSlide.TimeLine.InteractiveSequences.Add _
        (Index:=1)
        
    With objSequence
        .AddEffect Shape:=objSquareShape, _
            effectID:=msoAnimEffectPathStairsDown, _
            trigger:=msoAnimTriggerOnShapeClick
        .AddEffect Shape:=objTriangleShape, _
            effectID:=msoAnimEffectPathHorizontalFigure8, _
            trigger:=msoAnimTriggerOnShapeClick
    End With
    
    ' Save the presentation and run the slide show.
    objPres.SaveAs FileName:="C:\Dancing Shapes.ppt"
    objPres.SlideShowSettings.Run
    
End Sub

To explain what is happening in this macro:

  • By default, when this macro is created, the Visual Basic Editor makes references to Visual Basic for Applications (VBE6.dll), the Microsoft PowerPoint 10.0 Object Library (msppt.olb), OLE Automation (stdole2.tlb), and the Microsoft Office 10.0 Object Library (mso.dll).
  • Several objects are declared, representing the PowerPoint application, a PowerPoint presentation, a PowerPoint slide that will be added to the presentation, two shapes that will be added to the slide, and an animation sequence used to animate the shapes.
  • The Presentations collection's Add method is called to create a new presentation.
  • The Slides collection's Add method is called to add a slide to the presentation.
  • The Shapes collection's AddShape method is called twice to add two shapes to the slide.
  • Each shape has a TextFrame property that returns a TextFrame object representing the alignment and anchoring properties for the shape.
  • Each TextFrame object has a TextRange property that returns a TextRange object representing the text properties in each shape.
  • Each TextRange object has a Text property that accesses the actual text in each shape.
  • The slide has a TimeLine property returns a TimeLine object representing the slide's animation timeline.
  • The TimeLine object has an InteractiveSequences property that returns a Sequences collection representing the collection of animations that are triggered by clicking on a shape.
  • The Sequences collection's Add method adds an interactive animation sequence to the animation timeline, returning a Sequence object.
  • The Sequence object's AddEffect method is called twice to add an interactive animation to each shape.
  • The Presentation object's Save method is called to save the presentation.
  • The Presentation object has a SlideShowSettings property that returns a SlideShowSettings object representing the collection of presentation properties.
  • The SlideShowSettings object's Run method runs the presentation.

Here is the equivalent code presented in a Visual Basic .NET console application:

' Visual Basic .NET console application.
' Created in Visual Studio .NET Beta 2.

' References:

' Visual Basic .NET references by default:
'   System (System.dll) 
'   System.Data (System.Data.dll) 
'   System.XML (System.XML.dll) 

' Microsoft PowerPoint 10.0 Object Library 
'   Visual Basic .NET creates and references:   
'       PowerPoint (Interop.PowerPoint_X_X.dll)
'       Office (Interop.Office_X_X.dll)
'       stdole (Interop.stdole_X_X.dll)
'       VBIDE (Interop.VBIDE._X_X.dll)

Imports PowerPoint.PpSlideLayout                ' Used for slide
                                                ' layout.
Imports Microsoft.Office.Core.MsoAutoShapeType  ' Used for shape types.
Imports PowerPoint.MsoAnimEffect                ' Used for animation
                                                ' effect types.
Imports PowerPoint.MsoAnimTriggerType           ' Used for trigger
                                                ' types.

Module AnimatedPresentation

    Sub Main()

        ' Purpose: Creates a PowerPoint presentation,
        ' adds a slide and two shapes to the slide,
        ' animates the shapes, and runs the slide show.

        Dim ppApp As New PowerPoint.Application()

        ' Create a new PowerPoint presentation.
        Dim objPres As PowerPoint.Presentation = _
            ppApp.Presentations.Add

        ' Add a slide to the presentation.
        Dim objSlide As PowerPoint.Slide = objPres.Slides.Add _
            (Index:=1, Layout:=ppLayoutBlank)

        ' Place two shapes on the slide.
        Dim objSquareShape As PowerPoint.Shape = _
            objSlide.Shapes.AddShape _
                (Type:=msoShapeRectangle, Left:=0, Top:=0, _
                Width:=100, Height:=100)
        Dim objTriangleShape As PowerPoint.Shape = _
            objSlide.Shapes.AddShape _
                (Type:=msoShapeRightTriangle, Left:=0, Top:=150, _
                Width:=100, Height:=100)

        ' Add an animation sequence. 
        Dim objSequence As PowerPoint.Sequence = _
            objSlide.TimeLine.InteractiveSequences.Add(Index:=1)

        ' Add text to the shapes. 
        objSquareShape.TextFrame.TextRange.Text = "Click Me!"
        objTriangleShape.TextFrame.TextRange.Text = "Me Too!"

        ' Animate the two shapes.
        With objSequence
            .AddEffect(Shape:=objSquareShape, _
                effectId:=msoAnimEffectPathStairsDown, _
                trigger:=msoAnimTriggerOnShapeClick)
            .AddEffect(Shape:=objTriangleShape, _
            effectID:=msoAnimEffectPathHorizontalFigure8, _
            trigger:=msoAnimTriggerOnShapeClick)
        End With

        ' Save the presentation and run the slide show.
        objPres.SaveAs(FileName:="C:\Dancing Shapes.ppt")
        objPres.SlideShowSettings.Run()

    End Sub

End Module

This Visual Basic .NET code sample differs from the Office VBA macro as follows:

  • Similar to Microsoft Visual Basic 6.0, in Visual Basic .NET you must create code that runs separately from PowerPoint. For this code sample, I chose a console application because I did not need the overhead of a user interface to drive PowerPoint automation. By default, Microsoft Visual Studio® .NET creates references to the System namespace (System.dll), the System.Data namespace (System.Data.dll), and the System.XML namespace (System.XML.dll). This action is identical to setting references in VBA, except that .NET DLLs are being referenced instead of COM type libraries and COM dynamic-link libraries (DLLs).
  • Also similar to Visual Basic 6.0, because Visual Basic .NET does not integrate with the Office Visual Basic Editor, there is no way for Visual Basic .NET to know that you are creating code that automates PowerPoint. Therefore, you need to add a reference to the Microsoft PowerPoint 10.0 Object Library. When you add this reference, Visual Basic .NET infers from the PowerPoint object library that you also need references added to the Microsoft Office 10.0 Object Library (msppt.olb), OLE Automation (stdole2.tlb), and Microsoft Visual Basic for Applications Extensibility 5.3 (VBE6EXT.OLB).
  • Visual Basic .NET allows a single .vb file to contain multiple code modules and class modules. Therefore, the Module...End Module keywords must be used to designate the beginning and end of a single code module inside of a .vb file.
  • The Imports keyword is used in Visual Basic .NET to reduce repetitive keystrokes while coding. For example, in Office VBA, while I could code Dim objPres As PowerPoint.Presentation, I could leave out PowerPoint because I have already referenced the Microsoft PowerPoint 10.0 Object Library. In Visual Basic .NET, in addition to referencing libraries, you must also provide the complete namespace to library members in code. For example, in Visual Basic .NET, if I did not type the code Imports Microsoft.Office.Core.MsoAutoShapeType, I would need to retype this namespace in two places in my code as follows: ... objSlide.Shapes.AddShape(Type:=Microsoft.Office.Core.MsoAutoShapeType.msoShapeRectangle, ... and ... objSlide.Shapes.AddShape(Type:=Microsoft.Office.Core.MsoAutoShapeType.msoShapeRightTriangle, .... As long as no other referenced library contains the members msoShapeRectangle and msoShapeRightTriangle (which is virtually impossible unless a library developer uses these same names), then Visual Basic .NET will be able to use the Imports statement to resolve my use of the members msoShapeRectangle and msoShapeRightTriangle to the correct namespace and assembly.
  • In a Visual Basic .NET console application, program execution begins with the subroutine named Main.
  • Initializers in Visual Basic .NET allow variables to be declared and initialized in one line of code. The Set keyword is no longer used in Visual Basic .NET.
  • Otherwise, this code is almost identical to the Office VBA macro.

Here is the equivalent code presented in a C# console application:

/*  C# console application.
    Created in Visual Studio .NET Beta 2. */

/*  References:

    C# references by default:
        System (System.dll) 
        System.Data (System.Data.dll) 
        System.XML (System.XML.dll) 

        Microsoft PowerPoint 10.0 Object Library 
            Visual Basic .NET creates and references:   
                PowerPoint (Interop.PowerPoint_X_X.dll)
                Office (Interop.Office_X_X.dll)
                stdole (Interop.stdole_X_X.dll)
                VBIDE (Interop.VBIDE._X_X.dll)   */

using System;                 // C# default reference.
using Microsoft.Office.Core;  // Used for shape types.

namespace OfficeTalk.CSharpAnimatedPresentation
{
    class AnimatedPresentation
        {
            static void Main(string[] args)
            {
                // Purpose: Creates a PowerPoint presentation,
                // adds a slide and two shapes to the slide,
                // animates the shapes, and runs the slide show.

                PowerPoint.Application ppApp = 
                    new PowerPoint.Application();

                // Create a new PowerPoint presentation.
                PowerPoint._Presentation objPres =
                    ppApp.Presentations.Add(MsoTriState.msoTrue);

                // Add a slide to the presentation.
                PowerPoint._Slide objSlide = objPres.Slides.Add
                    (1, PowerPoint.PpSlideLayout.ppLayoutBlank);

                // Place two shapes on the slide. 
                PowerPoint.Shape objSquareShape =
                    objSlide.Shapes.AddShape
                        (MsoAutoShapeType.msoShapeRectangle, 
                        0, 0, 100, 100);
                PowerPoint.Shape objTriangleShape =
                    objSlide.Shapes.AddShape
                        (MsoAutoShapeType.msoShapeRightTriangle, 
                        0, 150, 100, 100);

                // Add an animation sequence. 
                PowerPoint.Sequence objSequence = 
                    objSlide.TimeLine.InteractiveSequences.Add(1);

                // Add text to the shapes. 
                objSquareShape.TextFrame.TextRange.Text = "Click Me!";
                objTriangleShape.TextFrame.TextRange.Text = "Me Too!";

                // Animate the shapes. 
                objSequence.AddEffect(objSquareShape, 
                    PowerPoint.MsoAnimEffect.msoAnimEffectPathStairsDown,
                    PowerPoint.MsoAnimateByLevel.msoAnimateLevelNone, 
                    PowerPoint.MsoAnimTriggerType.msoAnimTriggerOnShapeClick,
                    1);
                objSequence.AddEffect(objTriangleShape, 
                    PowerPoint.MsoAnimEffect.msoAnimEffectPathHorizontalFigure8,  
                    PowerPoint.MsoAnimateByLevel.msoAnimateLevelNone,
                    PowerPoint.MsoAnimTriggerType.msoAnimTriggerOnShapeClick,
                    1);

                    // Save the presentation and run the slide show. 
                    objPres.SaveAs("C:\\Dancing Shapes.ppt",
                        PowerPoint.PpSaveAsFileType.ppSaveAsPresentation, 
                        MsoTriState.msoTrue);
                    objPres.SlideShowSettings.Run();

      }
   }
}

The C# code is compared and contrasted with the Visual Basic .NET code as follows:

  • Comments in Office VBA and Visual Basic .NET are represented by the apostrophe (') character; anything following the apostrophe character to the end of the line is treated as one comment. In C#, there are two main types of comments: double-slash (//) characters are identical to the apostrophe character; multiline comments start with the slash-asterisk (/*) characters and end with the asterisk-slash (*/) characters.
  • The using directive in C# is different from the Imports keyword in Visual Basic .NET. In Visual Basic .NET, the Imports keyword helps cut down on repetitive keystrokes. In C# there is no such construct. The using directive is used instead to reference namespaces only, not data types or enumerated types such as PowerPoint.PpSlideLayout.
  • In C#, you must declare namespaces that uniquely qualify the names of subroutines, methods, variables, and members in your code. In this code sample, I made up the namespace OfficeTalk.CSharpAnimatedPresentation (in Visual Basic .NET, the namespace can be set or read by right-clicking the project in the Project Explorer window, clicking Properties, clicking the Common Properties folder, clicking General, and referring to the Root Namespace box).
  • Subroutines, methods, variables, and members must reside in classes, similar to class modules in Office VBA and Visual Basic. In this code sample, the class's name is AnimatedPresentation. The concept of a code module does not exist in C#—only class modules are used. Similar to Visual Basic .NET, program execution in a C# console application starts with the method named Main.
  • In the signature of the Main method, the static modifier indicates that the Main method can be called directly without declaring and initializing an object of type AnimatedPresentation first. The return type void indicates that a value is not returned when this method is called. The Main method also accepts an array of strings (the bracket ([]) characters are used instead of the parentheses (()) characters in Visual Basic to denote arrays) named args. To summarize this by comparing to Visual Basic .NET, in Visual Basic the code Sub MySub (x As Integer, y As Integer) As Integer would be coded static int MySub (int x, int y) in C#.
  • Identical to C, C++, and JScript, a variable's data type is always declared before the variable's name, and the Visual Basic keywords Dim and As are not used. So, in Visual Basic we code Dim ppApp As PowerPoint.Application, but in C# we code PowerPoint.Application ppApp.
  • Also identical to C, C++, and JScript, the semicolon (;) character is used to indicate the end of a statement or code block (in Visual Basic, a carriage return serves the same purpose). Unlike Visual Basic, the underscore (_) character is not used in C# to indicate line continuations.
  • C# does not use named arguments, unlike Visual Basic, which can use named arguments.
  • Some characters in strings, such as the backslash (\) character, need to be escaped by prefacing the character with an additional backslash character. So in a C# string, the backslash character is represented as two backslash (\\) characters, a carriage return is represented as a backslash-n (\n) character, the Beep function in Visual Basic is represented by a backslash-a (\a) character, a double-quotation (") character is represented as a backslash-double-quotation character (\"), and so on.

Further Reading

 

Paul Cornell works for the MSDN Online Office Developer Center and the Office developer documentation team. Paul also writes the Office Power User Corner column for the Office Assistance Center. He spends his free time with his wife and daughter. They are expecting their next child in a few weeks.