VBA
Discuss AutoCAD ActiveX and VBA (Visual Basic for Applications) questions here.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to make a TextSSet inorder

4 REPLIES 4
Reply
Message 1 of 5
cxhair
358 Views, 4 Replies

How to make a TextSSet inorder

Hi , every one!

I just want to make a Text selectionset,then make it inoder by their Y coordinate,at last ,print their textstring on the command line,unfortunately ,failed !

code as blow :

Private Sub Demo()
    Dim SSet As AcadSelectionSet
    Dim Ent As AcadText
    Dim fType(0) As Integer: Dim fData(0) As Variant
    fType(0) = 0: fData(0) = "TEXT"
    Set SSet = CreatSSet("X-SSet")
    SSet.SelectOnScreen fType, fData
    Call OrderSSet(SSet)
    For i = 0 To SSet.Count - 1
        Set Ent = SSet.Item(i)
        ThisDrawing.Utility.Prompt vbCrLf & Ent.TextString
    Next
End Sub

'----------------------bubble sort -----------------------------
Private Function OrderSSet(ByRef SSet As AcadSelectionSet)
    Dim i As Integer: Dim j As Integer
    Dim Ent1 As AcadText: Dim Ent2 As AcadText
    For i = 1 To SSet.Count - 1
        For j = i - 1 To SSet.Count - 1
            Set Ent1 = SSet.Item(j)
            Set Ent2 = SSet.Item(j + 1)
            If Ent1.InsertionPoint(1) < Ent2.InsertionPoint(1) Then
                Set SSet.Item(j) = Ent2
                Set SSet.Item(j + 1) = Ent1
            End If
        Next
    Next
End Function

 The code is failed when it comes to the bubble sort "Set Ent1 = SSet.Count -1",then system give me a warning "Object doesn't support this property or method",i  don't know what is going wrong !

Any reply will be  appreciate!

4 REPLIES 4
Message 2 of 5
RICVBA
in reply to: cxhair

you can't change SelectionSet's item sequence

you can walk around this by means of some different techniques, all sharing the same process format which is:

1) build your selection set (as you already do with the SSet.SelectOnScreen method)

2) iterate through it and store in an array both index position and data of interest for your sorting purpouses (in this case, Y-coordinates) of every item

3) sort the array by the data of interest

4) build a new SelectionSet using iterating through the sorted array index values and retrieving consequent original selection set items

 

by the way, look out for your sorting algorithm inner j-loop where you can have j = SSet.Count - 1 and therefore j + 1 = SSet.Count thus resulting in an error when trying to access Sset.Item(j + 1)

Message 3 of 5
cxhair
in reply to: RICVBA

Thanks a million my friend, now i did.

I will appreciate if you can give some more suggestions.

Private Sub Inc()
    Dim SSet1 As AcadSelectionSet
    Dim SSet2 As AcadSelectionSet
    Dim ArrY() As AcadText
    Dim ArrN() As Integer
    Dim Temp As AcadText
    Dim i As Integer: Dim j As Integer
    Dim fType(1) As Integer
    Dim fData(1) As Variant
    
    
    Set SSet1 = Csset("SSet1_1x")
    fType(0) = 0: fData(0) = "TEXT"
    fType(1) = 1: fData(1) = "*"
    SSet1.SelectOnScreen fType, fData
    
    
    ReDim ArrY(SSet1.Count - 1)
    ReDim ArrN(SSet1.Count - 1)
    fData(1) = ""
    For i = 0 To UBound(ArrY)
        Set ArrY(i) = SSet1.Item(i)
        fData(1) = fData(1) & SSet1.Item(i).TextString & ","
    Next
    
    OrderY ArrY
    
    '-----------------------
    Set SSet2 = Csset("SSet2_2x")
    SSet2.SelectOnScreen fType, fData
    For i = 0 To SSet2.Count - 1
        Set Temp = SSet2.Item(i)
        For j = 0 To UBound(ArrY)
            If StrComp(Temp.TextString, ArrY(j).TextString, vbTextCompare) = 0 Then
                ArrN(j) = ArrN(j) + 1
                Exit For
            End If
        Next
    Next
    
    
    '-----------------------
    For i = 0 To UBound(ArrY)
        ThisDrawing.Utility.Prompt vbCrLf & "No.[  " & ArrY(i).TextString & "  ] " & " the Quatity is --------" & ArrN(i)
    Next
    ThisDrawing.Utility.Prompt vbCrLf

End Sub

Private Function Csset(Str As String)
    Dim i As Integer
    For i = 0 To ThisDrawing.SelectionSets.Count - 1
        If StrComp(Str, ThisDrawing.SelectionSets.Item(i).Name, vbTextCompare) = 0 Then
            ThisDrawing.SelectionSets.Item(i).Delete
            Exit For
        End If
    Next
    Set Csset = ThisDrawing.SelectionSets.Add(Str)
End Function
Private Function OrderY(ByRef Arr As Variant)
    Dim i As Integer
    Dim j As Integer
    Dim Temp As AcadText
    Dim Text1 As AcadText
    Dim Text2 As AcadText
    
    For i = 0 To UBound(Arr)
        For j = 0 To UBound(Arr) - (i + 1)
            Set Text1 = Arr(j)
            Set Text2 = Arr(j + 1)
            If Text1.InsertionPoint(1) < Text2.InsertionPoint(1) Then
                Set Temp = Arr(j)
                Set Arr(j) = Text2
                Set Arr(j + 1) = Temp
            End If
        Next
    Next
    
End Function

 

Message 4 of 5
RICVBA
in reply to: cxhair

as to me you did a very cool work!

 

what follows are suggestions of no effect for small elaborations (i.e. with a few items to work with). you may take them into account for general purpose. or not at all!

 

' cool "cxhair" routines with some "RICVBA" minor modifications
Option Explicit

'use "Public" instead of "Private" if you want this Sub to be called via "tools/Macro/Macro" menu commands
Public Sub Inc2()
    Dim SSet1 As AcadSelectionSet, SSet2 As AcadSelectionSet ' the lesser the codelines the better the code readability. moreover I'd group variables together when of the same type and/or for the same purposes
    Dim ArrY() As AcadText
    Dim ArrN() As Integer
    Dim i As Integer, j As Integer ' see what above
    Dim fType(1) As Integer
    Dim fData(1) As Variant
    
    Set SSet1 = Csset("SSet1_1x")
    fType(0) = 0: fData(0) = "TEXT"
    fType(1) = 1: fData(1) = "*"
    SSet1.SelectOnScreen fType, fData ' you could enclose this statament in a do-while loop until the user makes a valid selection (for instance with a select items number > 0)
    ' or you could place here a control to catch a selection with no items and exit sub (and may be throwing a warning message, too)
      
    ReDim ArrY(SSet1.Count - 1)
    ReDim ArrN(SSet1.Count - 1)
    fData(1) = ""
    For i = 0 To UBound(ArrY)
        Set ArrY(i) = SSet1.Item(i)
        fData(1) = fData(1) & SSet1.Item(i).TextString & ","
    Next
    SSet1.Delete 'unless you need it for further elaborations
    
    OrderY ArrY()
    
    '-----------------------
    Set SSet2 = Csset("SSet2_2x")
    SSet2.SelectOnScreen fType, fData ' same pieces of advice as above for SSet1
    
    For i = 0 To SSet2.Count - 1
        With SSet2.Item(i)
            For j = 0 To UBound(ArrY)
                If StrComp(.TextString, ArrY(j).TextString, vbTextCompare) = 0 Then
                    ArrN(j) = ArrN(j) + 1
                    Exit For
                End If
            Next
        End With
    Next
    SSet2.Delete 'unless you need it for further elaborations
    
    
    '-----------------------
    For i = 0 To UBound(ArrY)
        ThisDrawing.Utility.Prompt vbCrLf & "No.[  " & ArrY(i).TextString & "  ] " & " the Quantity is --------" & ArrN(i)
    Next
    ThisDrawing.Utility.Prompt vbCrLf

End Sub

Private Function Csset(Str As String) As AcadSelectionSet
    
    ' sometimes errors can be useful! managing them is a useful technique that avoids you a lot of work
    
    On Error Resume Next
    ThisDrawing.SelectionSets.Item(Str).Delete ' delete a SelectionSet with the given name (Str), if already there
    On Error GoTo 0
    
    Set Csset = ThisDrawing.SelectionSets.Add(Str) ' now you can safely add a SelectionSet with the given name
       
End Function

' you don't use "OrderY" as a true Function (there's no "OrderY =..." or "set OrderY =..." statements inside)
' so let's call it by its name: a Sub!

' You can write faster procedures if you use specific data types (AcadText, in this case) instead of Variant
' moreover, using Variant would be a false generalization in this case (if that was your aim) since not all objects have "InsertionPoint" property as AcadText has.
' if you look at "AutoCAD ActiveX and VBA Reference" guide you'll see that it's common to Attribute, AttributeReference, BlockRef, ExternalReference, MInsertBlock, MText, Shape, Table, Text, and Tolerance Symbol objects only
Private Sub OrderY(ByRef Arr() As AcadText) '
    Dim i As Integer
    Dim j As Integer
    Dim Temp As AcadText
    
    For i = 0 To UBound(Arr) - 1 ' the iteration for i = Ubound(arr) is not useful since every item is already in its right position. furthermore the following j loop wouldn't start since UBound(Arr) - (i + 1) would result in a negative number
        For j = 0 To UBound(Arr) - (i + 1)
            If Arr(j).InsertionPoint(1) < Arr(j + 1).InsertionPoint(1) Then
                Set Temp = Arr(j)
                Set Arr(j) = Arr(j + 1)
                Set Arr(j + 1) = Temp
            End If
        Next
    Next
    
End Sub

 

 

 

Message 5 of 5
cxhair
in reply to: RICVBA

I'm a VBA begin-learner ,Your suggestions are so useful ,thanks for your patient guidance , Thank you so much !

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

”Boost