1.g. AutoCAD VBA Lecture 3
1.g. AutoCAD VBA Lecture 3
1.g. AutoCAD VBA Lecture 3
Lecture 3
Prof. Mounir Mabsout Elsa Sulukdjian Walid El Asmar
For iterating through a selection set, the For-EachNext loop structure may not be best at all times. Example: when selectively removing objects from the selection set. The For-Each-Next loop starts at the beginning of the list till the end of it and the removal of an item from the list inside the loop will cause the loop to skip one.
Selection set filter 1: Array containing object references to items to be removed from selection set:
Sub My_Filter1(SS As AcadSelectionSet, ET As Object) Dim Ents() As Object Dim Ent As Object i = 0 For Each Ent In SS If Ent.EntityType <> ET.EntityType Then ReDim Preserve Ents(0 To i) Set Ents(i) = Ent i = i + 1 End If Next Ent If i > 0 Then SS.RemoveItems (Ents) End If End Sub Note: Preserve maintains the values in the array as it is expanded while ReDim by itself will destroy the current contents of the array.
For selection of specific entity objects in an application, working with subsets, I.e. Selection Sets, makes it easier. To build a selection set of certain types of objects or objects that share specific property traits, you can use a filter. A filter is a set of properties that the entity objects need to match in order to be included in the selection set (properties can be specific object types as well as ranges of values ex: all circles with radii 1 and 2 drawing units). In VBA, a filter is constructed as 2 arrays of variants containing information that consists of group codes and data values.
The Filter
The 1st array of the filter contains group codes only. Group Codes: are integer values that indicate the type of data being referenced. The data itself resides in the 2nd array. The index value links the 2 arrays (the 1st value in the group codes array correspond with the 1st value in the data array). The 2nd array contains the data elements associated with the group codes. Data Elements: will be of different data types that correspond to the integer codes (ex: group code 2 will have a string, group code 10 will have a point). The 2 arrays MUST then be assigned to variant variables that are passed to the selection set function. The reason for using variants is to ease the transfer of information from BASIC to other environments.
0 1 2 8 10 11 40 62 67 -4
Object type string LINE, ARC, or CIRCLE String value in Text, Mtext Object name string used for Blocks & Tables Layer name string Primary point Secondary points for text alignments, line endpoints, Arc and circle radius Color number (integer) Model/Paper space integer flag (value of 1 indicates the object is in paper space) Grouping operator string or relational test (<=)
Building a selection set from the entire drawing that will contain only CIRCLE entity objects with a radius of 5 drawing units:
Dim Ftyp(1) As Integer Dim Fvar(1) As Variant Dim Filter1, Filter2 As Variant Ftyp(0) = 0: Fvar(0) = "CIRCLE" Ftyp(1) = 40: Fvar(1) = 5# Dim S1 As AcadSelectionSet Set S1 = ThisDrawing.SelectionSets.Add("S1") Filter1 = Ftyp 'Filter 1 is the FilterType Filter2 = Fvar 'Filter 2 is the FilterData S1.Select acSelectionSetAll, , , Filter1, Filter2
Arrays must be dimensioned to the proper size for the filters, I.e. if you re using only 2 filter items, the array length should be exactly 2.
Selection set containing all circles with a radius value less than or equal to 5 drawing units:
Dim Ftyp1(2) As Integer Dim Fvar1(2) As Variant Dim Filter1, Filter2 As Variant Dim S1 As AcadSelectionSet Ftyp1(0) = 0: Fvar1(0) = "CIRCLE" Ftyp1(1) = -4: Fvar1(1) = "<=" Ftyp1(2) = 40: Fvar1(2) = 5# Set S1 = ThisDrawing.SelectionSets.Add("S1") Filter1 = Ftyp1 'Filter 1 is the FilterType Filter2 = Fvar1 'Filter 2 is the FilterData S1.Select acSelectionSetAll, , , Filter1, Filter2
The filter uses the (-4) group code. The comparison test is applied to the values that follow (here the radius value).
These tests are typically applied against real numbers found in entity object properties and they can also be applied for points: = Equal to < Less than > Greater than <= Less than or equal >= Greater than or equal != or /= Not equal to * Always-true returns true very time
Testing for objects that are located in the 1st quadrant, I.e. having X and Y values >= 0:
Dim Pnt(0 To 2) As Double Dim Ftyp(1) As Integer: Dim Fvar(1) As Variant Dim Filter1, Filter2 As Variant Dim S1 As AcadSelectionSet Pnt(0) = 0#: Pnt(1) = 0#: Pnt(2) = 0# Ftyp(0) = -4: Fvar(0) = ">=,>=,*" Ftyp(1) = 10: Fval(1) = Pnt Filter1 = Ftyp 'Filter 1 is the FilterType Filter2 = Fval 'Filter 2 is the FilterData Set S1 = ThisDrawing.SelectionSets.Add("S1") S1.Select acSelectionSetAll, , , Filter1, Filter2
Whats Next