Manipulating Selection Set with VBA1 May, 1998 By: Bill Kramer
This month, we continue our journey into Visual Basic for Applications (VBA) and explore how to use it with AutoCAD R14.01 for Windows by developing a global text editor. Our example program can be used to change all or selected groups of text and multiline text objects in the current drawing. If you want to use the program on your PC and have AutoCAD R14.01, then please download TXTSR.DVB. By the way, a tip of the hat to John Gibbs, who supplied the idea for this article while we were discussing VBA learning hazards.
Selection sets can present a stumbling block when youre first working with VBA in AutoCAD. Selection sets are collections of entities obtained from a drawing. An AutoCAD-based applications program can create a selection set in three ways:
- adding entity objects one at a time;
- selecting objects on the screen;
- or selecting the objects based on some programmatic feature.
In VBA, selection set objects are defined in the AutoCAD objects extension library. The Object browser and help system in the VBA editor can be used to find all of the selection set object properties and methods (methods is the VBA term for subroutines and functions associated with objects). We are only going to focus on a few as we develop a simple applicationthey should point you in the direction for more advanced VBA-based solutions.
To utilize the input data form for the application, the operator inputs two strings, one to find and the other to replace the found string within the source string. Two toggles are available for selecting what kind of text objectseither regular TEXT or multiline text (MTEXT)to locate. Three command buttons are at the bottom of the dialog box. The first button will cause the program to select all text objects (based on the selection of TEXT and MTEXT) in the current drawing and perform a search and replace. The second button will allow the user to select TEXT or MTEXT objects using the normal selection methods inside AutoCAD. The third button cancels the macro and returns control to AutoCAD.
You can run this macro by using the VBALOAD command to load the TXTSR VBA project. Only one macro is available in this project, so simply select it and run. The dialog box, as shown in Figure 1, should then appear. Type the text to search, then type the text to replace and press the selection button of your choice. When you are finished, the popup dialog box shows the number of replacements made. The toggles are preset to allow for MTEXT and TEXT selections, so most of the time they can be ignored. Other than the load and start-up process (which can be put in a menu), this utility is pretty easy to run.
Now for the best part. We really only need to program the reactions to the command buttons because the remainder of the input fields take care of themselves. The text and toggle fields are VBA objects that can be accessed when the command buttons are selected, which means that the input data is accessible at any time inside the program. All you have to do is specify the name of the object followed by the property of interest. In the case of the text and toggle fields, we want the Value property. In my experience as a programmer, Ive found this feature to be one of the more powerful aspects of the Visual programming environment inside VBA. It is not unusual to find, that for many input systems designed in this fashion (where text input is processed into drawing information), only a few of the controls actually require programming. The majority are left up to the operator after setting some reasonable default values in the Value property.
Now, lets take a look at the code required to service the command buttons. Listing 1 contains the call-back function that is run when command Button1 is selected. This button automatically selects all the text objects in the current drawing. The name of a button or control object is found in the VBA Editor Properties dialog box when viewing the input form. The code in Listing 1 is short, as two subroutines that do most of the work have been employed. The subroutines are found in Listings 3 and 4, but first, lets take a look at the call-back function to learn a little about handling selection sets inside VBA.
Selection sets are collections in VBA and are defined as the AutoCAD object AcadSelectionSet. The first step when using a selection set in VBA is to define a variable with the type AcadSelectionSet and then link that variable to a named selection set in the drawing.
A selection set name can be anything you want and can also be re-used. I favor the name TEST. The selection set name is assigned by using the Add method of the Selection Sets object inside the current drawing (ThisDrawing) object. This step is required, as the selection set object must be bound to the open drawing to work properly. Since we are establishing the value of the object S1, the SET statement is used.
If you are new to VBA, note how the Add subroutine is called in the program code. The format for addressing an object in VBA is to define the path to the object separated by dots and then define either the subroutine, function or property desired. The path to an object may be through other objects, as seen in the example code. To add a selection set, we first had to define the drawing. Object programming is not hard to use, and VBA even helps you out as you are typing in the program.
After the selection set has been defined and linked to a named selection set in the current drawing, you can use the Select method in the selection set object. This method (or function) has five parameters, not all of which are required. Select is used to populate a selection set through a programmatic approach. The options for Select include: getting all objects in the drawing; selecting a window area with supplied points; or retrieving the last selection set. All of the options are for program-controlled selection where additional parameters are supplied as needed.
In the case of a Select All option, such as the one we are using in Listing 1, no further parameters are required, unless you want to supply a filter for the selection. Filters allow the program to specify that only a specific type of object can be selected or that objects sharing a particular property are desired. In this program, we only want TEXT and MTEXT objects from the drawing. To create a filter, you must supply a pair of point lists as dummy arguments, as they are in this example. P1 and P2 are defined as variants but have no values in this program. If needed by the selection option, they can contain points or arrays of points. The group codes and data values that make up the filter list follow the two point lists. These variants were created in the Build_Filter function found in Listing 3 and described below.
Looking at Listing 1 one last time, youll note that there is a test where the S1.Count property is tested. Count is a property, and since S1 has been set to a selection set object, this statement tells us how many objects are in the collection. The syntax is the same when calling a function as it is in the S1.Select statement just above the conditional test. Methods and properties are accessed in the same manner. When youre learning VBA, the most daunting task can be learning all the names, properties and methods you can use. But using the Visual editor and exploring a little, you can find what is needed.
When it asks the user to select objects, the SelectOnScreen method is used. In order to allow you to make the selection, the VBA program must pass control to AutoCAD. To accomplish this, two steps are required. The first is to hide the current dialog box using the Hide method. The dialog box is named TXTSR, and the statement TXTSR.Hide will cause the dialog box to be hidden. Dialog boxes are objects in the VBA environment, as are programs. The second step is to check to see if AutoCAD is visible. The object ThisDrawing is associated with an application that is AutoCAD itself. The property Visible tells you if the application is currently visible in the Windows environment. Visible is either true or false (on or off).
At the end of the CommandButton2 call-back function, the Txtsr dialog box is put back on the screen using the Show method. If it isnt, then the program has no more input running in front of the user, and the computer will appear stupid.
Both the Select and SelectOnScreen methods used filters. Listing 3 is an example of how to build a filter set in VBA. Filter sets are provided as variants to the selection methods. The variants are constructed as two arrays; the first contains all integer codes, and the second contains associated variable values. The integer code array contains the DXF group codes and specialty codes of filters. For example, if you want a filter that only gets Circle objects with a radius of 1.5, the group codes would be 0 for the object type and 40 for the radius value. The variable data array would then contain the string CIRCLE and the real number 1.5 for the associated parameters.
The Build_Filter function first determines how many entries will be in the arrays. The value properties of the toggle objects are checked, and if true, a counter is incremented. If the counter is greater than one, then we are looking for either TEXT or MTEXT objects. If it is equal to one, then we are only looking for MTEXT or TEXT, not both. The next step is to dimension the arrays to the sizes needed to house the filter data. The arrays GRP and DAT are defined using the REDIM command in VBA, which allows our programs to redefine the size of arrays dynamically.
In this program, we have the option of testing for either one or more entity object types. When testing for both, the filter list needs to contain an OR test. The group code -4 is placed in the integer array GRP, and the string <OR in the DAT variant array. This string starts the OR condition for the next items, allowing our program to test more than one possibility.
The value of the text toggle is tested again, and if true, the string TEXT is added to the variant list and the group code 0 added to GRP. The MTEXT toggle is tested in the same manner, and MTEXT added to the filter list is called for.
Finally, if both TEXT and MTEXT were used and the variable GCT has a value greater than one, the -4 group code is used again to close the OR condition. String OR> is added to the variant list DAT. Then, before returning, the function sets the values of the arrays into the variant arguments GrpCode and DatVals for subsequent passing into the selection methods.
The value of the Build_Filter function is an integer, and it is either one if a filter was built or zero if one was not built. The command button functions in Listings 1 and 2 use this return value to decide if they are to go ahead and build the selection set.
After building the selection set, the function Change_The_Text is called. This function is shown in Listing 4. After defining some variables of different types, the function starts by obtaining the strings from the edit box objects in the dialog box. Then a For Next loop is started that iterates through the selection set collection. In the For Next loop, each entity is taken from the selection set and placed in the variant Ent for use inside the loop. Ent is an entity object, and it is either TEXT or MTEXT. The value of the string is found in the property TextString for this object.
Now, our routine has the string to search for and an entity string. The Instr function of VBA can be used to find the location of the one string inside the other. This function returns an integer that is zero if the string was not found at all or is a number greater than zero. When the number is greater than zero, it is the location of where the search string was found. In that case, you can use string concatenation to rebuild the string from the components of the older string. The Mid function in VBA returns partial strings when it is given a source string, the starting position and number of characters requested.
After rebuilding the string, the TextString property of the text object is updated with the new value and the object updated on the screen. A counter is updated that keeps track of how many objects were changed. This value is reported in a message box at the end of the routine.
As you can see, working with entity objects is very easy. After isolating the entity object, the properties can be adjusted by supplying the new values directly. Unlike AutoLISP and ADS, which require the programmer to dig through an entity data list and make substitutions, the object-oriented approach seen in VBA is easy to understand and not that hard to learn. The most difficult part is finding the names of all the properties; this you can overcome by invoking the help system and object browsing tools provided with the package.
Object-oriented programming inside AutoCAD is the trend for the next few years. Already, ActiveX, ObjectARX and VBA environments support the use of objects within the AutoCAD system, and more programming tools will be available soon that also support objects. If youre new to object-oriented programming, dont be too concerned. It is not that difficult to comprehend and is intended to make the job of programming easier and more fun. As this simple example shows, dialog boxes are a snap and complex manipulations of the database can be accomplished in just a few lines of code.
If you want to use these program modules, please download them from the Web at The code Archivethe listings provided in this article are not complete. Several small routines are not present that are required to run the program properly and can be added by students as an exercise. These routines include the call-back function for the Cancel button and the macro start-up function. Until next time, keep on programming!<
Autodesk Technical Evangelist Lynn Allen guides you through a different AutoCAD feature in every edition of her popular "Circles and Lines" tutorial series. For even more AutoCAD how-to, check out Lynn's quick tips in the Cadalyst Video Gallery. Subscribe to Cadalyst's free Tips & Tools Weekly e-newsletter and we'll notify you every time a new video tip is published. All exclusively from Cadalyst!