You are on page 1of 16

Introduction to VBA Programming

In
MicroStation®

Copyright © 2013 Bentley Systems, Inc.

MicroStation’s API. A form has both graphical components and code components. The “Grid Maker” is a simple applet we should be able to complete during the course of the seminar. In a like manner we separate logical sections of a VBA project code into understandable sections. check boxes. subs and functions are structured in manner similar to these outlined below: Copyright © 2013 Bentley Systems. We will create a “Grid Maker” applet as a means of accomplishing this task. Class Module The visual basic reference defines a Class in this manner: “The formal definition of an object. The following is an overview of that structure: Module A module is a “container” for code. Its code component is like a standard module. various objects along with their methods and properties. the events. however it has no real use/existence until it is instantiated. Procedures (sub routines) Forms. Inc. modules and classes serve as containers that enable us to organize our code into logical bundles. The class acts as the template from which an instance of an object is created at run time. layers and models according to their purpose. What are forms and modules? In a MicroStation dgn file we group elements into cells. . Typically procedures. functions and procedures or subroutines. a form and a class module. In some sense forms.” A class appears very similar to a standard module. Controls are items such as command buttons. we will be exploring MicroStation’s Integrated Development Environment (IDE). it contains a ”standard” module. Modules. It makes use of fundamental structures and syntax.On the Grid… Our Seminar today is intended to quickly introduce you to a number of concepts in MicroStation VBA. In the GridMaker program. and Class Modules are divided into functions or sub routines (procedures). Form A form is an object such a window or dialog box. buttons and labels. Forms usually contain various controls which are referred to a child objects. The class defines the properties of the object and the methods used to control the object's behavior. As you build a form graphically by adding various controls such as progress bars. Along the way. text boxes and scroll bars. a class is used as a means for MicroStation to talk to the program as if it were a native MicroStation command. Yet while simple. methods and properties accompanying those controls (objects) become available for you as a programmer to utilize. and the VBA programming language. It contains lists of variables.

For example. These lines will display green text with a cyan highlight.  A colon (:) is used to separate statements on a line. These include:  The BE Communities . Private Sub DoSomething() Line of code… Line of code… Line of code… End Sub or Public Function FigureSomething(input_variable) Line of code… Line of code… Line of code… FigureSomething = n End Function The visual basic reference defines procedures in this manner: “A named sequence of statements executed as a unit. . Function.com/  Select Services . and Sub are types of procedures.http://selectservices. procedures are broken into lines of code. Syntax We will discuss syntax as the seminar progresses.  Lines that begin with an apostrophe (‘) are comments and are not executed. All executable code must be contained in a procedure. A few things to be aware of with lines as they appear in the VB editor:  Words that appear in color (magenta) are reserved words that have preset meaning. Getting Help In addition to the local help files.  Text in red is problematic code. Unfortunately we won’t have time to address all aspects of the VBA language. A procedure name is always defined at module level.com Copyright © 2013 Bentley Systems. Inc.com/en-US/  The Microsoft Developer Network – www.http://communities. both Microsoft’s VBA and the MicroStation object model are well documented in the help files that ship with MicroStation. however. You will find. Property.msdn. It acts like a new line.  A line ending in an underscore (_) is continued on the next line.” Code Lines Whereas modules can be broken down into procedures. Procedures can't be nested within other procedures.bentley.bentley. there are numerous online resources at your disposal.

Form Caption Close Button Text box: “TbRows” Labels Text box: “TbCols” Command Button: “CbPlaceGrid” Form: “GridMakerForm” Copyright © 2013 Bentley Systems. It marks the end of our procedure. It is not a part of a procedure and resides at the beginning of a module. Option Explicit is a compiler directive that forces explicit Startup Module declaration of variables. and is organized by module/form/class.Show FrmGridMaker. Code appears in the blue boxes and again at the end of this document in “print-out” form. The first text box is an object we have named TbRows . two labels and a command button. Option Explicit The Public Sub StartGridMaker procedure will be visible to Public Sub StartGridMaker() the”outside world” as an executable macro. We use this to start the entire program. FrmGridMaker. End Sub is just that. The applet code in its entirety is here.Show causes the FrmGridMaker form to End Sub appear.Explanation of GridMaker The following is an explanation of various elements and conventions found in the GridMaker applet. FrmGridMaker Form Object The FrmGridMaker form (pictured below) contains two text boxes. . Inc.

BackColor = vbRed While the forgoing sample is something we might do when a program is running. method or property. . This dialog is usually docked to the left side of the Microsoft Visual Basic window BackColor Property in properties dialog Copyright © 2013 Bentley Systems. The dot notation is how we show the “complete path” of an object.To refer to the text box “TbRows” from a module programmatically we would key in: FrmGridMaker. Inc. For instance if we wanted to programmatically set the background color of the aforementioned text box to red we would key in: mGridMaker.TbRows. we could also change the background color at design time through the properties dialog box in the IDE.TbRows Notice the dot (period) between the form name (container object) and the text box name.

” statements refer to the object in which they appear—in this case the FrmGridMaker form. The Int function then TbRows = Int(Val(TbRows)) removes the decimal portion of the number (if it exists).” is helpful in locating objects that are the text box to a string quotes are required e. It marks the end of our procedure.” MeTbRows = ”ABC” produces a list of the form’s methods. children of the form. child objects. If Val(TbCols) < 1 Then TbCols = 1 The Int function returns the integer portion of a number and End Sub the Val function returns a number from a string. The exit event occurs when the text box loses Private Sub TbCols_Exit(ByVal Cancel As MSForms. Copyright © 2013 Bentley Systems. If Val(TbRows) < 1 Then TbRows = 1 This statement ensures a End Sub number of 1 or greater exists in the text box. typing “Me. When setting necessary “Me. These two nearly identical procedures respond to text box exit events.TbRows = 4 show method in the procedure Startup.ReturnBoolean) the focus (e.g. the user clicks a different control). a numeric value is Private Sub TbRows_Exit(ByVal Cancel As MSForms. In this case. While not MeTbRows = 4 sets the value/text to 4.ReturnBoolean) derived from the characters in the text box through the Val function. ' pre-populate text fields with default values The Private Sub UserForm_Initialize() procedure is automatically executed as a result of calling the form’s Me.TbCols = 4 fields. It is not a part of a procedure Private Sub UserForm_Initialize() and resides at the beginning of a module. . More to the point. Inc. Note the procedure is Private. properties and End Sub is just that.g. Note these functions are nested. TbCols = Int(Val(TbCols)) The logic in these procedures ensures useable data is entered. The “Me. We will use this procedure to pre-populate the text Me. This means it will End Sub not be assessable from outside the form.StartGridMaker. Any text that appears after an apostrophe (‘) is considered a comment and is not compiled into executable code.FrmGridMaker Form Code Option Explicit is a compiler directive that forces explicit Option Explicit declaration of variables.

g. Inc. Dim points(0 To 1) As Point3d The complete list of procedures for Dim ClickNumber As Integer IPrimitiveCommandEvents is as follows: Dim DM As MsdDrawingMode 1.StartPrimitive New ClsDrawGrid statement “tells” MicroStation a new “primitive” CommandState. IprimitiveCommandEvents_Start() Since these Dim statements appear outside a procedure. IprimitiveCommandEvents_Dynamics() 4. MicroStation begins to send user input to the command class and program flow moves to the class (See ClsDrawGrid). End Sub An instance of the command class (ClsDrawGrid) is created and attached to MicroStation. Technically this procedure responds to the click event for the CbPlaceGrid command button. the variables are visible to the entire module.StartPrimitive New ClsDrawGrid command is starting and what the command is. IprimitiveCommandEvents_Reset() Dim statements are used to establish variables of various types. IprimitiveCommandEvents_Cleanup() 2. Never-the- less. This procedure is launched when the “Place Grid” button is pressed. IprimitiveCommandEvents_Keyin() 5. Private Sub IPrimitiveCommandEvents_Start() This procedure is called at beginning of the command. ClsDrawGrid Class Module Option Explicit The Implements IPrimitiveCommandEvents provides the necessary “connection points” MicroStation requires to interact with a command—In this case a command that is used to create geometry. . Private Sub CbPlaceGrid_Click() The CommandState. It might be used to set variables or adjust settings. 6. Dim ClickNumber as Integer creates a variable of the type integer called “ClickNumber”. Dim points(0 to 1) as Point3d creates a (short) array of variables which may be reference by the name “points” and a number in parenthesis e. its presence is required. The connection points Implements IPrimitiveCommandEvents are expressed as procedures that must be present-- even if they don’t do anything. points(1) This procedure is not used in this case. End Sub Copyright © 2013 Bentley Systems. IprimitiveCommandEvents_DataPoint() 3.

.StartDynamics causes MicroStation to ClickNumber = ClickNumber + 1 continuously. execute the IPrimitivecommandEvents_Dynamics procedure. The variable ClickNumber is incremented. ByVal View As View) points(ClickNumber) = Point CommandState. With the second click the grid is drawn and a reset is programmatically executed. The effect is a grid the dynamically resizes. points(1): PrimitiveCommandEvents_Reset The IprimitiveCommandEvents_DataPoint procedure is executed each time a data point is sent to MicroStation while our custom command is active. The DrawMode variable determines if the element is being erased or redrawn. Point End Sub The IprimitiveCommandEvents_Dynamics procedure is executed whenever the MicroStation cursor is moved. In our example here the DrawGrid procedure is being called with the first data point and the current location of the cursor. We use this procedure to “undraw” and redraw elements to the screen dynamically. Beginning after the first click. Here is what’s happening: 1.Private Sub IPrimitiveCommandEvents_DataPoint(Point As Point3d. 3. Inc. 2. 4. An element of the “points” array is assigned the latest data point coordinates. Copyright © 2013 Bentley Systems. If ClickNumber = 1 Then CommandState. with each change in mouse position. The coordinates of the data point as well as what view it was selected from are sent by MicroStation to this procedure.StartDynamics If ClickNumber = 2 Then DrawGrid points(0). dynamics are turned on. DM = DrawMode DrawGrid points(0).

This procedure is called at end of the command. its Private Sub IPrimitiveCommandEvents_Cleanup() presence is required. Never-the-less. its presence is required. Never-the-less.StopDynamics CommandState. The IprimitiveCommandEvents_Reset procedure is executed when the user enters a reset (usually a right Private Sub IPrimitiveCommandEvents_Reset() mouse click). CommandState. ClickNumber = 0 End Sub This procedure is not used in this case. Private Sub IPrimitiveCommandEvents_Keyin(ByVal Keyin As String) End Sub This procedure is not used in this case. Inc. Copyright © 2013 Bentley Systems. It is used to End Sub take care of “housekeeping” matters.Stopdynamics halts the calling of IprimitivecommandEvents_Dynamics procedure. .

DrawGrid contains the logic for determining the locations of the grid lines.Y / FrmGridMaker.Y DrawLine Startpt.X = LL. UR As Point3d) MicroStation model—that is handled by the Dim Startpt As Point3d DrawLine procedure. The Point3DSubtract function subtracts the Dif = Point3dSubtract(UR.Y = LL. Endpt. LL) coordinates of two vectors or points. Dim Endpt As Point3d DrawGrid requires two points be passed to it by a calling statement.Y + (Spacing * c) Endpt. Endpt Next End Sub Copyright © 2013 Bentley Systems. Dim Spacing As Double Variable declarations. Inc.TcCols text box.X = LL.Y For – Next Loop The contents of this loop is repeated until the value ‘c’ is equal to the value in the For c = 0 To FrmGridMaker. Endpt. Endpt.TbCols FrmGridMaker.X For c = 0 To FrmGridMaker.X = UR. 'column lines Comments are preceded by an apostrophe(‘).TbRows This section of code is nearly identical to the Startpt.Y = Startpt.Y found on the form “FrmGridMaker”.TbRows Startpt. The starting value of c is 0 and it is incremented each time Startpt.Y = LL.Y = UR. Endpt Next 'row lines Spacing = Dif. The points have been Dim Dif As Point3d named LL (Lower Left) and UR (Upper Right). Note: It is not critical the points be entered by Dim c As Integer the user in that order.X DrawLine Startpt. It does not actually draw the elements to the screen or to the Sub DrawGrid(LL As Point3d. Spacing = Dif.X = Startpt.TbCols In this line we take the x ordinate of the point “Dif” and divide it by the value TbCols text box Startpt.X / FrmGridMaker. .X preceding section that calculated the column lines.X + (Spacing * c) the loop is executed.

Endpt As Point3d) this procedure must pass it two points. Startpt. If ClickNumber = 2 Then The block If-then-else statement ActiveModelReference. Statements that call Sub DrawLine(Startpt As Point3d. Creation and display of lines happens here in the DrawLine procedure. Copyright © 2013 Bentley Systems. . The variable DM controls the draw mode and is set by the End Sub IPrimitivecommandEvents_ Dynamics procedure. If it is 2 the line (part of the grid) is Else added to the current MicroStation model. If the value oLine. Dim oLine As LineElement Declare oLine as a Line element object Object elements need to be Set Set oLine = CreateLineElement2(Nothing. Inc.Redraw DM 'Used with dynamics is not 2 then the element is End If earthier drawn or undrawn to the screen. Here we use CreateLineElement2 to instantiate oLine. Endpt) before that can be used.AddElement oLine checks the ClickNumber.

type. A MicroStation session may access many models.Terms The following is a list of terms used in this case study. Module-level declarations and definitions in a standard module are Public by default. Control An object you can place on a form that has its own set of recognized properties. – Visual Basic Reference Method A procedure that acts on an object. A Visual Basic program has to access a model to be able to save or retrieve graphical elements. Some controls are interactive (responsive to user actions). The same model may be referenced different ways. It is in no way exhaustive. – Visual Basic Reference Module (standard module) A module containing only procedure. – Visual Basic Reference Standard controls are readily available from the toolbox in the VBA editor. Events can occur as a result of a user action or program code. – Visual Basic Reference Event An event is an action recognized by an object. or they can be triggered by the system. You use controls to receive user input. such as clicking the mouse or pressing a key. including its property and method definitions. . There may also be Copyright © 2013 Bentley Systems. Class Module A module that contains the definition of a class. and events. display output. Forms are containers for controls. You can manipulate most controls using methods. Other controls may be added from the Tools pull-down menu. A standard module is referred to as a code module in earlier versions of Visual Basic. For example. methods. Inc. A multiple-document interface (MDI) form can also act as a container for child forms and some controls. Most of this information is available in the “Standard” Visual Basic Reference help or the MicroStation-specific VBA reference which will display when searching for help on a particular member in the object browser. and data declarations and definitions. and for which you can write code to respond. while others are static (accessible only through code). and trigger event procedures. – Visual Basic Reference Form A window or dialog box. The models may be in different design files. a model may be in use as the active model. – Visual Basic Reference Model Reference All graphical elements in MicroStation are in models.

and Sub are types of procedures. The MicroStation object model treats each of these references as a ModelReference object. Inc. Variables declared in a procedure are visible only within the procedure and lose their value between calls unless they are declared Static. Property. A Sub procedure begins with a Sub statement and ends with an End Sub statement. When we need to work with text we use strings Sub procedure A procedure that performs a specific task within a program. When Option Private Module is in effect. the module itself is private and therefore not visible to referencing projects. . but returns no explicit value. procedure. VBA Visual Basic for Applications Copyright © 2013 Bentley Systems. MVBA File extension for a MicroStation Visual Basic Project (filename. or object. a variable declared as Public is visible to all procedures in all modules in a directly referencing project unless Option Private Module is in effect. – Visual Basic Reference. String A variable that contains a series of letters. A procedure name is always defined at module level. different views of the model mapped into the same view. sentences paragraphs or entire documents. Function. For example.mvba) Procedure A named sequence of statements executed as a unit. All executable code must be contained in a procedure. Procedures can't be nested within other procedures. For example. – Visual Basic Reference. – Visual Basic Reference. Scope Defines the visibility of a variable.

When using MicroStation’s command browser. use one of the following: VBA RUN [project name]module_name. MS_VBANEWPROJECTDIRECTORY "Directory for new projects" Directory that is used when a new project is created. Custom tool or other method that implements Key-ins. Each configuration variable expects a valid value.Launching a MicroStation VBA Macro Macros may be launched from MicroStation by selecting the Utilities>Macros>Project Manager menu item. You do not need to close and restart in order for the configuration variable change to take effect. Visual Basic for Applications Configuration Variables The following table lists the configuration variables that affect Visual Basic for Applications. "Directories to search for Directories that are searched when opening an existing VBA MS_VBASEARCHDIRECTORIES VBA projects" project.subprocedure already been loaded. loading the project (if necessary) and selecting the “Macros” button. . Variable "Short name" Description "Automatically save VBA If set to 1. automatically saves modified VBA projects every MS_VBASAVEONRUN project" time it starts running a VBA program. "Names of standard Names of the projects that are opened when the VBA dialog is MS_VBAAUTOLOADPROJECTS projects" opened. Inc. An invalid value will not override a setting. Copyright © 2013 Bentley Systems.subprocedure Loads and Runs a Macro VBA execute subprocedure Runs a visible sub Or procedure that has VBA execute module_name.

StartPrimitive New ClsDrawGrid End Sub ClsDrawGrid Class Module Code Option Explicit Implements IPrimitiveCommandEvents Dim points(0 To 1) As Point3d Dim ClickNumber As Integer Dim DM As MsdDrawingMode Private Sub IPrimitiveCommandEvents_Start() End Sub Private Sub IPrimitiveCommandEvents_DataPoint(Point As Point3d. points(1): IPrimitiveCommandEvents_Reset Copyright © 2013 Bentley Systems.ReturnBoolean) TbRows = Int(Val(TbRows)) If Val(TbRows) < 1 Then TbRows = 1 End Sub Private Sub CbPlaceGrid_Click() CommandState. ByVal View As View) points(ClickNumber) = Point ClickNumber = ClickNumber + 1 If ClickNumber = 1 Then CommandState.ReturnBoolean) Command Button: “CbPlaceGrid” TbCols = Int(Val(TbCols)) If Val(TbCols) < 1 Then TbCols = 1 End Sub Private Sub TbRows_Exit(ByVal Cancel As MSForms. Inc.StartDynamics If ClickNumber = 2 Then DrawGrid points(0).Startup Module Code Option Explicit Dim Test As String Public Sub StartGridMaker() FrmGridMaker.TbCols = 4 Text box: “TbRows” End Sub Text box: “TbCols” Private Sub TbCols_Exit(ByVal Cancel As MSForms.Show End Sub FrmGridMaker Form Code Option Explicit Private Sub UserForm_Initialize() ' pre-populate text fields with default values Me.TbRows = 4 Me. .

Point End Sub Private Sub IPrimitiveCommandEvents_Reset() CommandState.X = LL. UR As Point3d) Dim Startpt As Point3d Dim Endpt As Point3d Dim Dif As Point3d Dim c As Integer Dim Spacing As Double Dif = Point3dSubtract(UR. Startpt.Y / FrmGridMaker.AddElement oLine Else oLine.TbRows Startpt.Y = Startpt. Endpt Next 'row lines Spacing = Dif. Inc.Y = UR.TbRows Startpt.Y Endpt. Endpt) If ClickNumber = 2 Then ActiveModelReference. ByVal DrawMode As MsdDrawingMode) DM = DrawMode DrawGrid points(0). LL) 'column lines Spacing = Dif. Endpt As Point3d) Dim oLine As LineElement Set oLine = CreateLineElement2(Nothing.X Endpt. Endpt Next End Sub Sub DrawLine(Startpt As Point3d.Redraw DM 'Used with dynamics End If End Sub Copyright © 2013 Bentley Systems. ByVal View As View.TbCols Startpt.TbCols Startpt.X For c = 0 To FrmGridMaker.X / FrmGridMaker. .X + (Spacing * c) Endpt.X = Startpt.End Sub Private Sub IPrimitiveCommandEvents_Dynamics(Point As Point3d.Y DrawLine Startpt.X = LL.X DrawLine Startpt.Y = LL.StopDynamics ClickNumber = 0 End Sub Private Sub IPrimitiveCommandEvents_Keyin(ByVal Keyin As String) End Sub Private Sub IPrimitiveCommandEvents_Cleanup() End Sub Sub DrawGrid(LL As Point3d.Y For c = 0 To FrmGridMaker.X = UR.Y = LL.Y + (Spacing * c) Endpt.