For the final installment in this series we will look at VBA (Visual Basic for Applications). The Pro and Platinum versions of BricsCAD for Windows include one of Microsoft’s programming languages, VBA. This is a version of Visual Basic designed to work inside software programs. BricsCAD runs VBA programs from menus and toolbars and at the command prompt.

VBA is completely different from LISP, just as LISP is completely different from Diesel and macros. If you learned the BASIC programming language, then that knowledge will be of no help, unfortunately, because Visual Basic has nothing in common with BASIC except for the name.

This chapter introduces you to the concepts of VBA programming and show you how to use it in

BricsCAD. (The Classic, MacOS, Linux, and demo versions of BricsCAD do not include VBA.)

For a full overview of VBA for BricsCAD, you can view the official, BricsCAD VBA Developer Guide.


The following topics are covered in this post:


Introduction to VBA

VBA is the second most-important programming language in BricsCAD. While LISP is the easier of the two to learn and use, it becomes cumbersome and slow for large programs and large sets of data. Furthermore, to create dialog boxes, LISP requires that you employ the difficult-to-understand DCL system.

At the other end of the programming spectrum is DRX or BRX, the DWG or BricsCAD runtime extensions. These programming interfaces are the fastest of all, because they are intimately tied into BricsCAD. You use D/BRX application programming interfaces with programs written in C or one of its offshoots. They are not simple to learn, and they present a drawback:  you must pay for a compiler that works with D/BRX. In contrast, LISP is free with all versions of BricsCAD, and VBA is free with BricsCAD Pro. DRX is not covered by this book. Note that as of BricsCAD V8, B/DRX replaces SDS, the Softdesk Development System. Also as of V8, BricsCAD switched the format of its VBA source files from IntelliCAD’s VBI to AutoCAD’s DVB format.

In contrast, VBA is fast and is designed with today’s user interfaces in mind. An advantage to learning VBA is that you can use the same programming language in many other Windows programs; learn once, program in many. Perhaps the toughest part of learning VBA is getting to know its jargon. Let’s begin!

ACCESSING VBA PROGRAMS

You write VBA code in a separate programming environment called the “VB Editor.” The editor provides assistance in writing the code, as well as constructing the user interface, which usually consists of dialog boxes.

You can run VBA programs at the BricsCAD command line or through its Add In Manager dialog box. Programs can also be launched from menu and toolbar macros, as well as from VisualLISP functions, topics not covered by this ebook.

The code can be embedded in a BricsCAD drawing or kept outside of BricsCAD for access by all drawings:

  • To run embedded macros, use the VbaRun
  • To run the macros stored in a .dvb project file, first load them through the VbaMan dialog box or the VbaLoad command prompt. Once loaded, the macros can be run with the either the VbaRun or VbaMan commands

Sending Commands

VBA has a command that works just like the LISP (command) function: SendCommand executes any BricsCAD command, such as Line, Erase, and Zoom. The function also handles command options, such as “1,1” and “All.”

Let’s take a look at it. Here is the VBA code for drawing a line between several pairs of x,y coordinates.

Sub Using_the_SendCommand()

ThisDrawing.SendCommand “line 1,1 1,8 11,8 11,1 c “

End Sub

TIP This VBA code isn’t too different from the equivalent code in LISP, which looks like this:

(defun using_the_sendcommand ()

(command “line 1,1 2,2 c “)

)

The words used in the snippet of VBA code have the following meaning:

Sub starts a new subroutine (or function).

Using_the_SendCommand() names the subroutine. The parentheses () indicates that no variables are used. Unlike LISP, VBA needs to know the names of variables and their type ahead of time. I’ll cover variables and types later in this chapter, but for now it’s enough to know that type refers to the type of data the variable holds, such as text (strings), whole numbers (integers), decimal numbers (reals), and other kinds of data.

ThisDrawing.SendCommand operates in the current drawing, identified generically by “ThisDrawing.” You do not specify the drawing’s name, you just need to use “ThisDrawing,” and VBA knows what you’re talking about.

“line 1,1 1,8 11,8 11,1 c “ executes the Line command, drawing four lines that make up rectangle between 1,1 to 11,8. The command and its prompts are read as a string, and then sent to BricsCAD’s command processor — just as if you had typed this at the command prompt.

TIP To end the command correctly, ensure that the string has a space at the end, just before the closing quotation mark. In the code above, you can see the space between the c and the “.

End Sub signals the end of the subroutine.


EMBEDDED OR EXTERNAL

BricsCAD stores VBA macros in drawings (embedded) or in .dvb files (external). There are pros and cons to each method, as listed by the following table:

Embedded External 
Storage in drawings in  .dvb files
Loading loaded with drawings loaded with VbaLoad command
Distribution with the  .dwg file with the .dvb file
Reactors yes no

An embedded macro cannot be used by other drawings, unless you specifically embed it into other drawing files.

Use the VbaMan command’s Embed button to convert projects to embedded projects. A serious problem with embedded macros is that they can contain viruses. Hence, BricsCAD displays a warning dialog box that gives you the option of disabling or enabling macros, or preventing them from loading at all.


WRITING AND RUNNING VBA ROUTINES

Whereas Notepad or other text editor can be used to write LISP routines, a programming environment included with BricsCAD must be used for VBA. You use this environment to write and run all code. To access the VBA editor, follow these steps:

  1. The first step is to ensure that BricsCAD can run VBA macros. Because VBA is a source of viruses, the ability to run VBA programs is normally turned off. Here is now to enable VBA macros:
    1. From the BricsCAD Tools menu, choose Security. Notice the Security dialog box.introduction toe visual basics
    2. If necessary, choose the Security Level tab.
      TIP This dialog box is necessary because of a poor decision by Microsoft programmers. When they created VBA: they allowed documents to store VBA code. This convenient feature turned into a major security problem, because it made it easy for hackers to distribute benign-looking Word and Excel files that contained malicious VBA code.
      After too many people and companies suffered from having precious files erased from their computers, Microsoft finally added this dialog box to overcome the VBA exploit. Today, Windows-based documents cannot run VBA code by default (security level = high), and so you must lower the security level for VBA to work.
    3. If the security level is set to High, change it to Medium or Low. The differences between the settings are listed by the table below:
      VBA Setting Meaning
      High All VBA routines are prevented from operating; default.
      Medium BricsCAD asks if you wish to run each VBA routine.
      Low All VBA routines are run, without question
    4. After you change the security level in this dialog box, you must restart BricsCAD with the Quit command or by using File | Exit.
  2. With VBA enabled, you can now open its programming environment. From the Tools menu, choose VBA, and 436 Customizing BricsCAD V20 then choose Visual Basic for Applications. Notice the VBA programming environment.visual basics workspace
  3. Code is written in modules — a form that is initially blank, into which you type in the code. To start a new module, from the Insert menu, choose Module. Notice that a blank window appears, as shown below.visdual basics application coding
  4. Enter the following code into the module. (This is the same line drawing code you saw earlier.)

    Sub Using_the_SendCommand()

    ThisDrawing.SendCommand “line 1,1 2,2 1,2 c “

    End Subcoding

  5. You now have enough code to execute a program. Click the Run button, which you find on the toolbar.visdual basics application coding introductionSuccess! Notice that BricsCAD draws a triangle. If the routine fails to run, check for these problems:
    • Is security is set to High or Medium?
    • Does the code contain spelling errors?

You can use SendCommand to draw and edit entities, and to change viewpoints with commands like Zoom and Pan. You can use it to insert blocks, change properties, and plot drawings. Just be careful that you enter the options of commands correctly; coordinates and the names of options are particularly fussy.

DISPLAYING MESSAGES

Displaying messages in dialog boxes is as easy as using this code with the MsgBox function:

MsgBox “The drawing border is complete.”

  1. Add the line to the code in the VBA editor:editing the code
  2. And then click the Run button again. You should see a dialog box in BricsCAD that looks like this:

Now that is much, much easier than coding a dialog box in LISP with DCL!

Constructing Dialog Boxes

Speaking of dialog boxes, VBA includes an interactive dialog box construction kit called the “user form.” Let’s take a look at how it works.

To start a new user form, follow these steps:

  1. In the Project palette, right-click Module1.
  2. From the shortcut menu, choose Insert, and then choose Userform.
    Notice the gray window filled with a grid of dots. This is where you design dialog boxes.
    Adjacent to the form is the Toolbox. It contains the elements that make up dialog boxes — known as “controls” in the correct VBA jargon. You will probably recognize many of the controls, such as text entry box, checkbox, and radio button.
  3. To place a control, choose one from the Toolbox, and then position it in the user form. For example, to add a checkbox, follow these steps:
    1. In the Toolbox, click the checkbox item
    2. In Userform1, click anywhere. Notice that the check box is placed with generic text that reads “Checkbox1.”
    3. To edit the text or any other property of the check box, glance over at the Properties palette. (If it is not visible, choose Properties Window from the View menu; if necessary, click the Categorized tab.) Notice the name of the control, plus a ton of other properties — the choices can become quite overwhelming.
    4. You have written some code and you have drawn a simple dialog box. To connect the check box with the VBA code, choose the Select Objects tool from the Toolbox, and then double-click the check box control.check box visual coding
      Notice that another module window opens, into which you can enter code — something I won’t detail at this point.adding elements Bricscad

We will look at the code-dialog box link in greater detail later in this chapter. First, though, an
introduction to how VBA really works.

BricsCAD V20 Automation Object Model

 how VBA really works

Object-Oriented Programming

In programming, is more efficient to work with objects. No, not geometric objects, but programming objects. To keep clear the distinction, I refer to geometric objects as entities.

You had a hint of the object-oriented nature of VBA with the ThisDrawing.SendCommand piece of code: the SendCommand function is instructed to operate on the ThisDrawing object, which is the current drawing. You can add objects to ThisDrawing, such as ModelSpace to ensure the commands are executed in model space instead of paper space:

ThisDrawing.ModelSpace.SendCommand()

Notice the dots ( . ) that connects them, much like the dot in the dotted pairs used by LISP to access entity data. VBA is premised upon object orientation, where everything in BricsCAD is organized as objects and according to a strict hierarchy. Technically, this is known as “exposing the BricsCAD database” through Microsoft’s Common Object Model (COM).

COMMON OBJECT MODEL

On the facing page is a very important figure: it is a diagram of the object model in BricsCAD. (It changes from release to release as new objects are introduced.) The chart shows how entities relate to objects:

  • Entities are in found model or paper space, or in blocks
  • Model/paper space and blocks are found in documents
  • Documents (drawings) are found in the application (BricsCAD)

As an alternative to the diagram, you can use the Object Browser found in BricsCAD’s VBA programming environment, described next.

OBJECT BROWSER

The object browser lists all of the objects that VBA can access in BricsCAD. To use the object browser, follow these steps:

  1. From the View menu, choose Object Browser. Notice the Object Browser palette.custom element with vba
  2. In the All Libraries droplist, choose BricsadDb. (Db is short for database.)dropdown selection box
  3. Scroll down to AcadLine. This is the BricsCAD line entity, but it is named acadline to maintain compatibility with VBA applications programmed in AutoCAD.
  4. On the right, notice all the properties, methods, and events that are available for line entities. I’ve detailed them in the following section.
  5. At the bottom is helpful info. As the cursor rests on a member, a brief description is provided, along with a link to the parent.
    The figure below shows the information provided for Length:
  • Length is a property that specifies the length of the current line.
  • It is a double variable (double accuracy floating point).
  • Is is read-only, which means programmers and users cannot edit the value.
  • It is a member of BricsCADDb.AcadLine.

By now, you might realize that the Property palette reports the values stored by BricsCADDb for all entities in the drawing. Let’s take a closer look at all that a line object entails.

TIPS Rename the buttons and text boxes so that the names describe what they do. For instance, rename the OK button as btnOK; rename the Last Point text box as txtLastPoint, and so on.

If the font size and style in the Code window are too small, you can change them. From the Tools menu, choose Options. Select Editor Format, and then choose a different font size and/or font name.

The VBA code editor uses color to highlight different types of code:

Green text Comments
Black text Normal code
Blue text VBA keywords
Red text Errors in the syntax
Yellow highlight Execution points
Brown highlight Breakpoints

LINE ENTITY

The line entity is created with the AcadLine method in model or paper space, and in a block:

  • ModelSpace.AddLine adds a line to model space.
  • PaperSpace.AddLine adds a line to the current layout tab.
  • Block.AddLine adds a line to the specified block, dynamic block, or xref block.

Lines have properties, methods, and events:

  • Properties affect the geometry and look of the line.
  • Method refers to the ways in which lines can be edited.
  • Events refers to the manner in which entities report that they’ve been changed

Below, I’ve listed all properties, methods, and events for line entities. The list gives you an idea
of the richness (or, complexity) of the access you have to the internals of BricsCAD, the richness
provided by the object model through VBA.

Properties

Lines can have the following properties. Some of these will be familiar to you; others will be new.

Properties Meaning
Geometric Properties
Angle Angle in radians from the x-axis measured counterclockwise
Delta Delta-x, -y, and -z values, from one endpoint to the other
Length Length of the line
Normal Normal to the line
EndPoint X,y,z-coordinate of the line’s end point
StartPoint X,y,z-coordinate of the start point
Entity Properties
Hyperlinks Embedded hyperlink
Layer Layer name
Linetype Linetype name
LinetypeScale Linetype scale
Lineweight Lineweight width
Material Material name (used for rendering)
PlotStyleName Plot style name, if enabled
Thickness Thickness, in the z-direction
TrueColor Color
Visible Visibility, independent of layer setting
Other Properties
Application Specifies the BricsCAD application
Document Specifies the drawing
Handle Specifies the entity identification number
HasExtensionDictionary Reports whether the line has an extension dictionary
ObjectID Alternative method of obtaining the entity id number
OwnerID Reports the ObjectID of the parent object

Methods

The line can be edited with the following methods:

Method Meaning
Entity Editing
ArrayPolar Creates a polar array of the line
ArrayRectangular Creates a rectangular array
Copy Copies the line
Delete Erases the line
Mirror Mirrors the line
Mirror3D Mirrors the line in 3D
Move Moves the line
Offset Creates an offset copy of the line
Rotate Rotates the line
Rotate3D Rotates the line in 3D
ScaleEntity Resizes the line
TransformBy Moves, scales, and/or rotates the line
Other Method:
GetBoundingBox Reports the coordinates of the rectangle that encompasses the line
GetExtensionDictionary Returns the line’s extension dictionary
GetXData Returns the line’s extended entity data
SetXData Stores extended entity data in the line
IntersectWith Returns coordinates where line intersects other objects
Highlight Highlights the line
Update Regenerates the line

Events

When entities are changed, they trigger events. For lines, there is just one event. The Modified event is triggered whenever a property is set, even when the new value equals the current one.

Events are prevented from triggering while modal dialog boxes are open. (A modal dialog box is one that must be dismissed before you can continue working in BricsCAD; ie, most dialog boxes.)

Dialog Box with Code

In earlier posts, I showed you how to construct a dialog box using DCL, and then add the LISP code to make it work. The dialog box looked like this:

The dialog box displays the current value of three system variables:

  • Last point reports the current value of the LastPoint system variable.
  • Last angle reports the value of LastAngle (read-only).
  • Last prompt reports the value of LastPrompt (read-only).

Let’s repeat the tutorial, this time using VBA to do both jobs done separately by DCL and LISP before – designing the dialog box and writing-running the code.

DESIGNING THE DIALOG BOX

Dialog boxes are designed with the VBA programming environment, as follows:

  1. Start BricsCAD, and then use the Tools | VBA | Visual Basic for Applications command to open the VBA programming environment.
  2. Start a new Userform. (From the Insert menu, choose UserFrom.) Notice that VBA creates a generic dialog box named UserForm1.
  3. Change the name on the title bar by following these steps:
    1. Open the Properties palette. (From the View menu, choose Properties Window.)
    2. Scroll down to Caption, and then change “UserForm1” to Last Input. As you type, notice that the title bar of the dialog box updates at the same time.creating custom elements for bricscad with VBC
  4. The bulk of our new dialog box consists of three text input boxes. The first one is constructed like this:
    1. In the Toolbox, choose the TextBox control.
    2. Click anywhere in the center of the form. Notice the text entry box appears, but it lacks a text prompt for the user, such as “Last Angle:” You add the text a little later on.anatomy of a box
  5. In BricsCAD, the LastAngle system variable is read-only. This means that users can view the value but not change it. Text boxes that cannot be edited by users are traditionally colored gray. Here is how to make the text box read-only and gray:
    1. Ensure the text box is selected (has grips, as illustrated above).
    2. In the Properties palette, change the value of BackColor (found in the Appearance section) to Inactive Title Bar.

    “Inactive Title Bar” is an enum, a preset value in VBA, kind of like pi in LISP. (Enum is short for “enumerated.”) Should the user change the colors of Windows’ user interface, the background color of this text box will also change.

  6. To add the prompt, use the Label tool, as follows:
    1. Choose the Label tool from the Toolbox.
    2. Click and drag a rectangle in front of the text box. If necessary, drag the label into position.
    3. Backspace over the generic “Label1” text, replacing it with Last Angle:
    4. To right justify the text, change the value of TextAlign property to 3 (fmTextAlignRight).
      TIP You can drag dialog box elements with the cursor, but it tends to jump to the grid dot spacing. To fine tune the location of an element, use the Position section of the Properties palette.
      Change the value of Top to move the element up and down, Left to move horizontally. The values represent the number of pixels from the upper left corner of the dialog box.
  7. You can create the other two text input boxes through copy and paste:
    1. Use the cursor to select both elements. Here are two ways to do it:
      • You can drag a rectangle around both of them.
      • Alternatively, you can choose one, hold down the Ctrl key, and then choose the other.
    2. Press Ctrl+C to make a copy (stored in the Clipboard).
    3. Press Ctrl+V to paste the copy in the dialog box. The copies are pasted right on top of the originals, unfortunately. This means you need to move one of them, following the pasting.
    4. Separate the overlapping elements by dragging the copies above the originals.
  8. Change the properties of the new pair of text input elements:
    • Change text label to Last Point.
    • Change BackColor of the text box Window Background (white), because the value of the LastPoint system variable can be changed by the user.
  9. Edit the wording for the Last Prompt field. Keep the background color of the Last Prompt text box gray, because the LastPrompt system variable cannot be edited by users.
  10. It is quite likely that the elements don’t line up perfectly. VBA can align them for you, as follows:
    1. Select the three text elements, and then right-click.
    2. From the shortcut menu, choose Rights. Notice that they now line up perfectly.
    3. Repeat for the three input boxes.
  11. The final elements are the OK and Cancel buttons. From the Toolbox, drag the Command Button element onto the user form.
    Left: Selecting the CommandButton tool, and then… Right: …dragging it onto the form.
  12. Change its Caption property to OK.
  13. Repeat to add the Cancel button.

The design of the dialog box is complete. The next stage adds code that makes the dialog box operate.

If you wish, you can fine tune the look of the dialog box by making the OK button narrower, adding a frame around the text input boxes, changing colors of elements, and so on. I find it interesting that I prefer working with DCL, because BricsCAD takes care of lining up dialog box elements so that it looks good — without all the manual tweaking required by VBA.

ADDING THE CODE

With the dialog box design in place, let’s start working on the code. In LISP, a single routine handles everything that happens in the dialog box; in contrast, VBA uses many snippets of code. One snippet handles the Cancel button, another the OK button, another handles the value displayed by the Last Point text box, and so on.

You don’t need to worry about linking code snippets to dialog box elements. VBA does that for you. When the user clicks on a text box or the OK button, VBA runs the correct snippet of code automatically.

Clicking Cancel

To link the Cancel button to a VBA code snipped, follow these steps:

  1. Double-click the Cancel button. Notice that a module-like form appears, and that it is partially filled out.
  2. Add the command for closing the dialog box:
    End
  3. You’re done!
  4. Well, that’s not quite all. You still need to test that Cancel button actually works. Here’s how:
    1. On the VBA toolbar, click the Run button. Notice that the dialog box appears in BricsCAD.
    2. Try clicking an element other than the Cancel button, such as the OK button. Nothing happens, because there is no code tied to it.
    3. Click Cancel. The dialog box should disappear. Yay, it works!

QUICK SUMMARY OF VBA DATA TYPES

Data Type Comment Range From To
Byte 0 255
Boolean True False
Integer -32,768 32,767
Long Long integer -2,147,483,648 2,147,483,647
Single Single-precision floating-point -3.402823E38 -1.401298E-45 (negative Values)
1.401298E-45 3.402823E38 (positive values)
Double Double-precision floating-point -1.79769313486231E308 -4.94065645841247E-324 (negative values)
4.94065645841247E-324 1.79769313486232E308 (positive values)
Decimal +/-79,228,162,514,264,337,593,543,950,335 (no decimal point)
+/-7.9228162514264337593543950335 (28 decimal places)
+/-0.0000000000000000000000000001 (smallest nonzero number)
Date January 1, 100 December 31, 9999
Currency Scaled integer -922,337,203,685,477.5808 922,337,203,685,477.5807
String Variable-length 0 approximately 2 billion characters
Fixed-length 1 approximately 65,400 characters
Variant Numbers Any numeric value up to a double
Characters Same as variable-length string
Object Any object reference
User-defined Same range as its data type.

QUICK SUMMARY OF VBA DATA TYPE RETURN VALUES

Constant Value Discription
vbEmpty 0 Empty or uninitialized
vbNull 1 Null or no valid data
vbInteger 2 Integer
vbLong 3 Long integer
vbSingle 4 Single-precision floating-point number
vbDouble 5 Double-precision floating-point number
vbCurrency 6 Currency value
vbDate 7 Date value
vbString 8 String
vbObject 9 Object
vbError 10 Error value
vbBoolean 11 Boolean value
vbVariant 12 Variant (array)
vbDataObject 13 Data access object
vbDecimal 14 Decimal value
vbByte 17 Byte value
vbUserDefinedType 36 Variant (user-defined types)
vbArray 8192 Array

QUICK SUMMARY OF VBA STRING MANIPULATION

Keyword, Operator Comment
Asc, Chr Accesses ASCII and ANSI values
Format, Lcase, Ucase Converts to lower- or uppercase
Format Formats strings
InStr, Left, LTrim, Mid, Len Finds lengths of strings
LSet, Rset Justifies string left or right
Option Compare Sets string comparison rules
Right, RTrim, Trim Manipulates strings
Space, String Creates strings of repeating characters
StrComp Compares two strings
StrConv Converts strings
& Concatenates strings

QUICK SUMMARY OF VBA PROGRAM COMPONENTS

Projects store macros. (LISP calls these “programs.”)

Macros refer to chunks of VBA programming code. (LISP calls these “functions.”) VBA macros can be embedded (stored in drawings) or saved to .dvb files on disk.

Reactors are pieces of macro code that react to events in the drawing, such as the drawing being saved, an object added to the drawing, or the user clicking a mouse button.

Forms refer to the location where VBA code is constructed. Often, forms look like dialog boxes.

Controls refer elements in forms, such as check boxes and droplists.

Classes are definitions of objects. For example, AcadLine is the class that defines the line entity.

Objects refer to classes put into forms. The objects can have the following attributes:

  • Properties that describe the object, such as its color, height, and width.
  • Methods that modify objects, such as copying and rotating them.
  • Events that report when objects are modified.

QUICK SUMMARY OF VBA COMMANDS IN BRICSCAD

The VBA-related command names are shown below in boldface, while equivalent menu names are shown in parentheses.

You access the menu items from the Tools | VBA menu.

Vba (Visual Basic for Applications) opens the VB Editor for writing and debugging macros.

VbaRun (Macros) loads and runs VBA macros; displays the Macros dialog box and lists the names of VBA macros stored in the current drawing.

VbaNew (New Project) specifies the name of a new VBA project file.

VbaLoad  (Load Project) loads .dvb VBA project files; displays the Open dialog box.

-VbaLoad command load .dvb project files at the command prompt.

VbaMan (Project Manager) displays the VBA Manager dialog box.

AddInMan (Add-in Manager) lists programs that can be loaded into BricsCAD, and controls how they are loaded; displays the Add-In Manager dialog box.

(VbaStmt is not supported by BricsCAD; its purpose in other programs is to load and run macros at the command prompt.)

LastInput.Dvb

With the introduction to VBA programming behind you, let’s carry on and examine a fully coded program. Below is the Last Input dialog box, and on the facing page is the VBA code
for LastInput.Dvb. In the following pages, I comment on parts of the code.

The main part of the project is shown in color; other modules are like subroutines that support the main module. I’ve added lines to visually separate modules, and I have color coded
module names so that you can cross-reference them.

The following VBA code was developed by Ferdinand Janssens, programmer at Bricsys.

Conversion Routines

VBA was not designed with CAD in mind, and so it does not easily handle concepts unique to vector drawings, such as the processing of 2D and 3D points. Just as in LISP, VBA must separate coordinate triplets, and then recombine them as strings.

Two of the conversion routines in Mr Janssens’s program are useful for any VBA programming with BricsCAD. These are as follows:

  • PointToString coverts 3D points (x, y, z coordinates) to strings, such as 3,2,1 to “3”,”2″,”1″.
  • StringToPoint coverts strings back to 1D, 2D, or 3D coordinate points, such as “3”,”2″,”1″ to 3,2,1.

Frankly, I am surprised at the amount of code VBA needs for adding and removing quotation marks from the single, most common, type of CAD data. The good news is that once you write these two routines, you can use them over again in your other VBA programs.

Here are descriptions of how they work.

POINTTOSTRING CONVERSION FUNCTION

The PointToString routine adds quotations marks to each coordinate to convert them from real numbers to strings. For example, 3.4,2,0 becomes “3.4”,”2″,”1″. It looks like this:

Private Function PointToString(vIn As Variant) As String

Dim sPt As String:    sPt = vbNullString     Dim

iPrecision As Integer

iPrecision = ThisDrawing.GetVariable(“LUPREC”)

If VarType(vIn) > vbArray Then

sPt = StringFromValueFixedDecimal(vIn(0), iPrecision) & “, “

sPt = sPt & StringFromValueFixedDecimal(vIn(1), iPrecision) & “, “

sPt = sPt & StringFromValueFixedDecimal(vIn(2), iPrecision)

End If

PointToString = sPt

End Function

(VBA keywords are shown in boldface.)

Let’s examine how this code works, line by line.

Private Function PointToString(vIn As Variant) As String

Private means that the function can be accessed only within this module. This is roughly analogous to the practice in LISP where variables names are placed after the slash character to make them local, such as (defun function (/ vaname)).

Function specifies the name, arguments, and code. It is like the defun function in LISP.

PointToString is the name of the function.

vIn is the name of the argument’s variable (vIn is short for “variant input”). The purpose of  this variable is to receive the argument passed to this function when it is processed.

As declares the data type of the argument.

Variant is the data type, meaning the function is completely flexible when it comes to   data types, working with numbers, text, and arrays.

As String means that the output of the function is a variable length string.

In summary, this line of code defines a local function named “PointToString” that expects numbers or text as input, and then returns text.


QUICK SUMMARY OF VBA PREDEFINED CONSTANTS

Constant Value Comments
vbCrLf Chr(13) + Chr(10) Carriage-return, linefeed
vbCr Chr(13) Carriage-return
vbLf Chr(10) Linefeed
vbNewLine Chr(13) + Chr(10) New line character (\n)
vbNullChar Chr(0) Character with value 0
vbNullString 0 String with value 0; used for external procedures
vbObjectError -2147221504 Values greater are user-defined error numbers
vbTab Chr(9) Tab (\t)
vbBack Chr(8) Backspace

Dim sPt As String:    sPt = vbNullString

Dim is the most common way of declaring variable names. Unlike LISP, VBA needs to know ahead of time the names of variables and their data types. While to experienced LISP programmers declarations seems like unnecessary extra work, this ahead-of-time declaration is one of the ways that VBA routines run faster than ones written in LISP.

sPt is the name of the variable (sPt is short for “string point”).

As is the keyword for declaring data types.

String is the data type.

: (colon) indicates the end of a line label. sPt is given its initial value:

vbNullString is one of VBA’s predefined constants — just like pi is predefined as 3.1431… in  LISP. The value of vbNullString is 0 (not the same as a zero-length string, “”). This is done so  that the dialog box initially displays 0 when the LastPoint contains nothing.

In summary, this line of code defines a variable named “sPt” and assigns it the value of 0.

Dim iPrecision As Integer

iPrecision is the name of another variable (short for “integer precision”). Its purpose is to specify the number of decimal places used by this function.

As Integer defines its data type as an integer, because an integer is large enough to hold the  value of decimal places, which in BricsCAD ranges from 0 to 8.

In summary, this line of code defines a variable named “iPrecision.”

iPrecision = ThisDrawing.GetVariable(“LUPREC”)

ThisDrawing is VBA’s way of accessing data from the current drawing — without needing to know its name.

GetVariable gets the value of system variables, and it gets the value of the current drawing.

This is like using the (getvar) function in LISP.

  LuPrec” is the name of the system variable that stores the value of the current linear   units precision (as set by the Setting dialog box). LuPrec is a BricsCAD name and has   nothing to do with VBA; this means that you can use the same line of code to access the   value of any system variable, including those unique to BricsCAD.

In summary, this line of code gets the value of system variable LuPrec, and then stores it in iPrecision.

If VarType(vIn) > vbArray Then

If starts the usual if-then decision-making construct found in all programming languages. (If they have no “if-then” construct, then they are not programming languages.) In this case, if checks the value of vIn.

VarType is the function that determines the data type of variables. It returns an integer that  reports the data type. Once you know the data type, you can perform other work on it. In this  case, it checks the data type of vIn.

> is the greater than function.

vbArray is another VBA constant; this one carries the value of 8192. However,    array types always return a value larger than 8192 in order to report the type of    the array. An array can consist of numbers, text, Booleans, and so on. In our    program, the array is the coordinate triplet, such as 1,2,3.

In summary, this line of code checks to see if the data type of vIn is an array. More specifically, it asks, “Is the value of vIn greater than 8192? If so, then it is an array, and processing can continue.”

sPt = StringFromValueFixedDecimal(vIn(0), iPrecision) & “, “

StringFromValueFixedDecimal is a user-defined function that converts a decimal into a string, and then simulates the number of decimal points. (It is listed a little later in the LastPoint.Dvb program.) It expects two arguments: a decimal number and the precision (ie, the number of decimal points to display).

vIn(0) extracts the first value of array vIn. Yup, VBA considers 0 as #1, just as in LISP. If vIn is 3.2,2,0, then 3.2 is extracted.

iPrecision specifies the number of decimal points. For example, is vIn(0) is 3.2, then this
function changes it to “3.2000” (when iPrecision is 4) or to “3”, when iPrecision is 0.

& is VBA’s function for concatenating (linking together) strings — same as the
StrCat function in LISP.

“, “ is concatenated to the string, resulting in sPt holding the value of
“3.2000, “.

In summary, this line of code converts the first element of the coordinate array into a string with a fixed number of decimal points, and then adds a comma and space.

sPt = sPt & StringFromValueFixedDecimal(vIn(1), iPrecision) & “, “

This line of code is identical to the one above, but with two differences:

sPt = sPt & concatenates the existing value of sPt (“3.2000, “) with the second value extracted from the array.

StringFromValueFixedDecimal(vIn(1) extracts the second element from the array.

In summary, this line of code converts the second element of the coordinate array into a string, and then concatenates it to the first element. sPt now holds “3.2000, 2.0000, “. You can start to see how the numerical array is being converted, piece by piece, to a string array.

sPt = sPt & StringFromValueFixedDecimal(vIn(2), iPrecision)

The process repeats, with sPt now holding the string “3.2000, 2.0000, 0.000”.

End If

End indicates the end of a section.

If indicates the end of the if-then statement. If vIn hadn’t been an array, then the routine  would have skipped the previous three lines of code, and jumped to here. Can you guess the  value sPt would hold in this case?

PointToString = sPt

The value of sPt is assigned to PointToString, where it can be accessed by any other line of code. (If vIn had not been an array, the value of sPt would be 0.)

End Function

End specifies the end of the module.

 Function indicates that the function has come to an end. Because this is a subroutine, the  value of PointToString is now returned to the main part of the code, where it is used by this  statement:

Me.txtLastPoint.Text = PointToString(vLastpoint)

STRINGTOPOINT CONVERSION FUNCTION

The StringToPoint routine removes quotations marks from each string to convert it to a real number. For example, “3.4, 2, 0” becomes 3.42,0. Some of the code will be familiar to you from above.

Private Function StringToPoint(sIn As String) As Variant

Dim sCoords() As String:    sCoords = Strings.Split(sIn, “,”)

Dim tmpPt(0 To 2) As Double

If UBound(sCoords) = 0 Then

tmpPt(0) = Val(sCoords(0))

ElseIf UBound(sCoords) = 1 Then

tmpPt(0) = Val(sCoords(0))

tmpPt(1) = Val(sCoords(1))

ElseIf UBound(sCoords) = 2 Then

tmpPt(0) = Val(sCoords(0))

tmpPt(1) = Val(sCoords(1))

tmpPt(2) = Val(sCoords(2))

End If     StringToPoint = tmpPt

End Function

Let’s examine what some of this code does:

Dim sCoords() As String: sCoords = Strings.Split(sIn, “,”)

Dim sCoords() As String defines variable sCoords (sort for “string coordinates), and assigns a data type of String.

Split splits the string into a one-dimensional array with the specified number of substrings.

“,” specifies the delimiter, which tells Split where to make the split. In this case, a string like  “3.4, 2, 0” becomes “3.4”, “2”, and “0”.

If UBound(sCoords) = 0 Then

UBound reports the size of an array. It is useful in determining whether the function is dealing with 2D coordinates (a 2-element array) or 3D, a three-element array.

tmpPt(0) = Val(sCoords(0))

Val converts numbers in strings as a numeric value. In short, the “3.4” becomes 3.4.

This subroutine is used by the txtLastPoint_BeforeUpdate function.

LOADING AND RUNNING LASTINPUT.DVB

You can download the LastInput.Dvb file from my Dropbox account.

Follow these steps to load the program:

  1. Start BricsCAD.
  2. From the Tools menu, select VBA, and then choose Load Project.
  3. In the Open dialog box, choose “LastPoint.Dvb”, and then click Open. The program is now loaded into BricsCAD.
    (If the Security dialog box appears, choose Low, and then click OK.)

To run the program, follow these steps:

  1. From the Tools menu, select VBA, and then choose Macros.
  2. In the Run BricsCAD VBA Macro dialog box, choose “Module1.main”.
  3. Click Run.
    Notice that the Last Input dialog box appears. If the drawing is brand-new (no objects drawing), then the fields report 0.
  4. To see the dialog box at work, start the Line command, and then draw a few lines. (This dialog box is nonmodel, meaning it can stay open even as you execute other commands in BricsCAD.)
  5. Click Update to see the dialog box report the values of the last point, angle, and prompt.
  6. To change the value of Last Point, highlight the coordinates, and then enter different values for x, y, and z.
  7. When done, click OK. The dialog box disappears.
  8. Press Esc to cancel the Line command.
TIP To include a VBA project in a toolbar or menu macro, use the -VbaRun command, and then provide the macro name as the argument.

QUICK SUMMARY OF VBA VARIABLE DECLARATIONS

Declaration Comments
Dim Default method of declaring variables:
When Dim appears within the procedure, the variable is available
only within the procedure
When Dim appears in the declarations section of the module, the variable is available to all procedures within the module but not to
other modules in the project
Public Makes variables available to all procedures in all modules in the project
Private Restricts variables for use only by procedures in the same module
Static Variables retain their values between calls
Option Explicit All variables must be explicitly declared within the module

QUICK SUMMARY OF VBA SHORTCUT REFERENCES

Term Comments
This Refers to the current or active BricsCAD document
Me Makes variables available to every procedure in a class module. Used when a class has more than one instance, because Me refers to the instance of the class in the code currently being executed

Download BricsCAD free for 30-days

Start Using BricsCAD Today

Permanent or subscription licenses that work in all languages, in all regions.


  1. Introduction
  2. 55 Tips for BricsCAD Users
  3. Settings
  4. Changing the Environment
  5. Custom User Interface
  6. Introduction to the Customize Dialog Box
  7. Customize the Menu Bar & Context Menus
  8. Toolbars and Button Icons
  9. Writing Macros and Diesel Code
  10. Ribbon Tabs and Panels
  11. Keystroke Shortcuts, Aliases & Shell Commands
  12. Mouse, Double-click & Tablet Buttons
  13. Absolutely Everything You Need to Know About The Quad
  14. Rollover Properties
  15. Workspaces and the User Interface
  16. Designing Tool & Structure Panels
  17. Creating Simple & Complex Linetypes
  18. Patterning Hatches
  19. Decoding Shapes & Fonts
  20. Coding with Field Text
  21. Writing Scripts
  22. Programming with LISP (Introduction)
  23. LISP Functions
  24. Writing a Simple LISP Program
  25. 7 Tips for LISP Programming
  26. Designing Dialog Boxes with DCL