IBM Support

Alternatives for Migrating IBM Rational Rhapsody VBA macros

Question & Answer


Question

What are the options to migrate macros in Rational Rhapsody that use Visual Basic for Applications (VBA)?

Answer

Abstract:

The IBM Rational Rhapsody Visual Basic for Applications (VBA) Interface is no longer available for new purchases. Maintenance renewals are possible only for existing customers with Rational Rhapsody VBA Add On. See Rational Rhapsody 7.5.x Packaging Changes for more information. Existing users are strongly encouraged to migrate and re-use existing macros with other technologies as future Rational Rhapsody releases may not include VBA.

Much of the functionality of the VBA scripts can be converted to other technologies to continue to leverage the behavior. This document gives a short overview about the possible alternatives and proposes a workflow for converting the scripts.

This document provides overall guidance but does not cover all aspects of converting VBA projects.

In order to perform the following steps, a Rational Rhapsody 7.5.1 or earlier is needed with VBA installed to access the existing VBA scripts. .


VBA Project characteristics:


Storage:

VBA stored with Rhapsody Projects may contain forms, modules and class modules.

  • Forms - are user designed UI including forms’ code.
  • Modules - are global functions, containing the "macro" commands that can be called directly from Rhapsody.
  • Class Modules - are classes with their methods and members.

The VBA project is stored in the file <project name>.vba besides the <project name>.rpy.

The VBA project is stored in a binary format. In order to read it, it should be exported to readable files. It should be opened using Rational Rhapsody 7.5.1 or lower.

One disadvantage of VBA for projects is that any user with VBA can open up the source code and modify it potentially causing maintenance issues with delivered macros. Migration away from VBA helps to mitigate this problem.


The Application Object:

When running a VBA script embedded into an Application, the top-level object of the script is the Application object and the script is implicitly aware of the methods of the Application. For a Rhapsody VBA script the top-level object is defined by the interface: RPApplication.

When using VBA with Rhapsody a user can call any method of RPApplication directly. When running this script from outside the Application, the Application needs to be accessed explicitly.

Example:

VBA from within Rhapsody:

openProject "L:\project.rpy"

From an external program explicit access is required:

Dim rhap As RPApplication

Set rhap = GetObject(,"Application.Rhapsody")

rhap.openProject "L:\project.rpy"


VBA Syntax

VBA syntax is based on Visual Basic 6 but the currently available VB.NET has many differences.

Note: "VB.NET" includes the versions Visual Basic 2003, Visual Basic 2005-Visual Basic 2008.

References:



Migration

Migrating to VB.NET

Unfortunately, there is no automatic import/conversion from VBA to Visual Basic (both VB6 and VB.NET). Since VBA is based on Visual Basic 6, if you have access to legacy Visual Basic 6 then it is possible to translate the code to Visual Basic 6 by copying and then resolving any ambiguous references. The code can then be run from Rhapsody as an external helper.

Since Visual Basic 6 is not available currently, migration to VB .NET is the more common requirement. Following references to Microsoft documentation at http://msdn.microsoft.com/en-us/library/aa192490%28office.11%29.aspx

The general process to follow is:

1. Re-create the UI (if exists) in VB environment;

2. Copy the VBA code and correct the syntax;

3. Add reference to Rhapsody COM interface;

4. Run the program externally, or create helper to be invoked from inside rhapsody.

The following example demonstrates the process.


Migration to VB.NET Example

In this example below, a VBA macro sample is migrated from VBA to VB.NET using Microsoft® Visual Studio 2008 to show the general migration process. The code below can be cut and pasted if you wish to follow the steps on your own.

The "RhapsodyVBHelper" is the sample which runs from within Rational Rhapsody allowing some operations to be performed on classes.

The sample contains:

  • A Module: Containing the logic and macros that invokes a form.
  • A Form: UI for activating some operations.
  • In Rhapsody, we define a helper (from the Tools->Customize menu) that invokes this macro that is applicable to a class. This allows user to invoke the helper from the context menu of the class.

The RhapsodyVBHelper example review

The VBA Module:



    Public context As RPClass

    Public counter As Integer

    Sub ShowForm()

    Dim frm As New UserForm1

    If (Not (getSelectedElement Is Nothing)) And (getSelectedElement.metaclass = "Class") Then

        Set context = getSelectedElement

        frm.Label1.Caption = context.name

        frm.PopulateListBox

        frm.Show

    Else

        MsgBox ("Please select class")

    End If

       

    End Sub

    Sub PrintOverriddenProerties(element As RPModelElement)

    Dim col As RPCollection

    Set col = element.getOverriddenProperties(0)

    Dim allProps As String

    For Each prop In col

        allProps = allProps & prop + vbLf

    Next

    If Not allProps = "" Then

        MsgBox (allProps)

        Else

        MsgBox ("No Overridden Properties")

    End If

    End Sub

    Sub addToClass(theClass As RPClass, metaType As String)

    Select Case metaType

        Case "Port"

            Call theClass.addNewAggr(metaType, "Port" & counter)

            counter = counter + 1

        Case "Activity"

            Set ad = theClass.addActivityDiagram

           

        Case "StateChart"

            Set sc = theClass.addStatechart

     

        End Select

    End Sub


The VBA form:

The Form contains

Name
Type
UserForm1UserForm
BtnPrintOverriddenPropsCommandButton
btnAdd2ClassCommandButton
ListBox1ListBox
Label1Label

The "Caption" property of the buttons is as shown on the form:

  • btnPrintOverriddenProps : "Print Overridden Properties"
  • btnAdd2Class : "Add to Class"

The code behind the form:



    Sub PopulateListBox()

        Dim MyArray As Variant

        Dim Ctr As Integer

        MyArray = Array("Port", "StateChart", "Activity")

       

        For Ctr = LBound(MyArray) To UBound(MyArray)

            Me.ListBox1.addItem MyArray(Ctr)

        Next

    End Sub

    Private Sub btnAdd2Class_Click()

    If (ListBox1.ListIndex = -1) Then

        MsgBox ("Please select value form list")

    Else

        Call addToClass(context, ListBox1.value)

    End If

           

    End Sub

    Private Sub BtnPrintOverriddenProps_Click()

        Call PrintOverriddenProerties(context)

    End Sub


Creating VB.NET project

Open Microsoft® Visual Studio 2008.

Create new VB Project: File->New->Project…

Select new Visual Basic Console Application:

Adding reference to Rhapsody

Add Rhapsody from Project->Add References…

Choose the COM tab and locate rhapsody:

Choose OK.

Adding the Form

Right click the project on the Solution Explorer and choose Add->Windows Form. The following dialog will appear. Change the name to UserForm1, in order to be the same as the old VBA project and press Add.

Adding the code to the module

Copy & Paste the code from the VBA module1 inside the module definition:



    Module Module1

        Public context As RPClass

        Public counter As Integer

        Sub ShowForm()

            Dim frm As New UserForm1

            If (Not (getSelectedElement Is Nothing)) And (getSelectedElement.metaclass = "Class") Then

                context = getSelectedElement

                frm.Label1.Caption = context.name

                frm.PopulateListBox()

                frm.Show()

            Else

                MsgBox("Please select class")

            End If

        End Sub

        Sub PrintOverriddenProerties(ByVal element As RPModelElement)

            Dim col As RPCollection

            col = element.getOverriddenProperties(0)

            Dim allProps As String

            For Each prop In col

                allProps = allProps & prop + vbLf

            Next

            If Not allProps = "" Then

                MsgBox(allProps)

            Else

                MsgBox("No Overridden Properties")

            End If

        End Sub

        Sub addToClass(ByVal theClass As RPClass, ByVal metaType As String)

            Select Case metaType

                Case "Port"

                    Call theClass.addNewAggr(metaType, "Port" & counter)

                    counter = counter + 1

                Case "Activity"

                    ad = theClass.addActivityDiagram

                Case "StateChart"

                    sc = theClass.addStatechart

            End Select

        End Sub

    End Module


  1. Add "Imports rhapsody" before the first line.
  2. Add the Rhapsody Application Object as member of the module:
    "Public rhap As RPApplication"
  3. Initialize the Rhapsody Application object:
    Add at the beginning of the "ShowForm" Subroutine:
    rhap = GetObject(, "Rhapsody.Application")
  4. For each method of RPApplication add the prefix: "rhap."
    example: "getSelectedElement" -> "rhap.getSelectedElement"
  5. Change "Caption" property of Label to "Text"
  6. Add declaration for undeclared objects.
  7. Change the Subroutine "ShowForm" to "Main"

The code should be like the following:



    Imports rhapsody 'VB.NET addition

    Module Module1

        Public rhap As RPApplication 'VB.NET addition

        Public context As RPClass

        Public counter As Integer

        Sub main()

            rhap = GetObject(, "Rhapsody.Application") 'VB.NET addition

            Dim frm As New UserForm1

            If (Not (rhap.getSelectedElement Is Nothing)) And (rhap.getSelectedElement.metaClass = "Class") Then

                context = rhap.getSelectedElement

                'frm.Label1.Caption = context.name ***VBA code***

                frm.Label1.Text = context.name 'VB.NET changed

                frm.PopulateListBox()

                frm.ShowDialog()

            Else

                MsgBox("Please select class")

            End If

        End Sub

        Sub PrintOverriddenProerties(ByVal element As RPModelElement)

            Dim col As RPCollection

            col = element.getOverriddenProperties(0)

            'Dim allProps As String ***VBA code***

            Dim allProps As String = "" 'VB.NET changed

            For Each prop In col

                allProps = allProps & prop + vbLf

            Next

            If Not allProps = "" Then

                MsgBox(allProps)

            Else

                MsgBox("No Overridden Properties")

            End If

        End Sub

        Sub addToClass(ByVal theClass As RPClass, ByVal metaType As String)

            Select Case metaType

                Case "Port"

                    Call theClass.addNewAggr(metaType, "Port" & counter)

                    counter = counter + 1

                Case "Activity"

                    'ad = theClass.addActivityDiagram ***VBA code***

                    Dim ad As RPFlowchart = theClass.addActivityDiagram 'VB.NET changed

                Case "StateChart"

                    'sc = theClass.addStatechart ***VBA code***

                    Dim sc As RPStatechart = theClass.addStatechart 'VB.NET changed

            End Select

        End Sub


Creating the Form

The new project will be opened with an empty form

Using the toolbox add to the form controls like the VBA form.

Name
Type
UserForm1System.Windows.Forms.Form
BtnPrintOverriddenPropsButton (instead of CommandButton)
btnAdd2ClassButton (instead of CommandButton)
ListBox1ListBox
Label1Label

To set the Text visible on the Buttons change the "Text" property. (VBA eq. “Caption”)

Creating the code behind the form

Right click on the Form and choose "View Code" to show the code behind.

You can see that the code already contains:

Public Class UserForm1

End Class

In order to create the methods " BtnPrintOverriddenProps_Click() "and" btnAdd2Class_Click()" double click the buttons from the form.

The code will be modified as follows:



    Public Class UserForm1

        Private Sub btnPrintOverriddenProps_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrintOverriddenProps.Click

        End Sub

        Private Sub btnAdd2Class_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd2Class.Click

        End Sub

    End Class

    Now you can copy the code from the original VBA, including the subroutine "PopulateListBox", and change it slightly to fit VB.NET controls as follows:

    Public Class UserForm1

        Private Sub btnPrintOverriddenProps_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrintOverriddenProps.Click

            Call PrintOverriddenProerties(context)

        End Sub

        Private Sub btnAdd2Class_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd2Class.Click

            ' If (ListBox1.ListIndex = -1) Then ***VBA code***

            If (ListBox1.SelectedIndex = -1) Then 'VB.NET changed

                MsgBox("Please select value form list")

            Else

                'Call addToClass(context, ListBox1.value) ***VBA code***

                Call addToClass(context, ListBox1.SelectedItem) 'VB.NET changed

            End If

        End Sub

        Sub PopulateListBox()

            'Dim MyArray As Object  ***VBA code***

            Dim MyArray As ArrayList 'VB.NET changed

            Dim Ctr As Integer

            'MyArray = Array("Port", "StateChart", "Activity")  ***VBA code***

            MyArray = New ArrayList() 'VB.NET changed

            MyArray.Add("Port") 'VB.NET changed

            MyArray.Add("StateChart")  'VB.NET changed

            MyArray.Add("Activity") 'VB.NET changed

            'For Ctr = LBound(MyArray) To UBound(MyArray) ***VBA code***

            'Me.ListBox1.addItem(MyArray(Ctr))  ***VBA code***

            For Ctr = 0 To MyArray.Count - 1

                ListBox1.Items.Add(MyArray.Item(Ctr))  'VB.NET changed

            Next

        End Sub

    End Class


Testing the application

You can already test and debug the application. In this case open Rational Rhapsody and select a class. Then run the application and see the form loads and operates similar to the old VBA scripts.

You can now add this helper to Rational Rhapsody.

Adding the helper to Rational Rhapsody

Open Rhapsody and choose from the menu: Tools->Customize…

Create new helper:

  1. Click on the "new" icon and give it a name
  2. Chooses the executable created by Visual Studio (e.g. C:\RhapsodyVBHelper\bin\Debug\RhapsodyVBHelper.exe )
  3. Set Applicable to Class
  4. Notice that the type is "External program" and not "VBA macro"

Now you will be able to run it by right clicking the class:


[{"Product":{"code":"SSB2MU","label":"IBM Engineering Systems Design Rhapsody"},"Business Unit":{"code":"BU059","label":"IBM Software w\/o TPS"},"Component":"General Information","Platform":[{"code":"PF033","label":"Windows"}],"Version":"7.5.2","Edition":"All Editions","Line of Business":{"code":"LOB59","label":"Sustainability Software"}}]

Product Synonym

Rational Rhapsody

Document Information

Modified date:
27 May 2022

UID

swg21428105