23 Replies Latest reply on Sep 22, 2017 11:23 AM by Matt Bieringer

    GetNext but with a direction

    Matt Bieringer

      Hello all,

      Is it possible to use the .GetNext command but have it look in a direction instead of the next note or view that was added? Basically I am making a macro that will replace annotation text but I need it to search for the next annotation to the right, which might not have been the last annotation added. I attached an image of the order of progression that I need the macro to go in.

      Thank you,

      Matt

       

      Below is my sub

      Public Sub okclick()
      Dim y As Long
      Dim i As Long
          If IsNumeric(StartForm.TextBox1.Value) Then
              ID = StartForm.TextBox1.Value
              
              MsgBox "Start Number: " & ID
              
              Set swApp = Application.SldWorks
              Set swModel = swApp.ActiveDoc
              Set swDraw = swModel
              Set swView = swDraw.GetFirstView
              
              While Not swView Is Nothing
                  Set swNote = swView.GetFirstNote
                  While Not swNote Is Nothing
                      If swNote.GetText Like "~~" Then
                          If swNote.GetText Like "~~" Then swNote.SetText ID
                          ID = ID + 1
                          Set swNote = swNote.GetNext()
                      Else
                          Set swNote = swNote.GetNext
                      End If
                  Wend
                  Set swView = swView.GetNextView
              Wend
              
          Else
              ClearForm
          End If
          Unload StartForm
      End Sub
      
        • Re: GetNext but with a direction
          Nilesh Patel

          Hi Matt,

           

          Not sure of any direct method but have a look at the following approach.

           

          1. Get note array using IView.GetNotes for the current view.

          2. Run a loop for this note array and obtain IAnnotation object using INote.GetAnnotation.

          3. Get the position of this annotation using IAnnotation.GetPosition.

          4. By comparing position of each annotations, you may be able determine the direction of selection you want.

           

          I have not tried this, so not sure whether it will work or not. But it will definitely require some time and effort.

           

          Hope this helps.

           

          Regards,

            • Re: GetNext but with a direction
              Amen Allah Jlili

              I agree with Nilesh Patel . You will need to traverse the annotations first then put them a list and then sort them by the position of their X.
              This can easily be done with VSTA macros. With VBA, you'll need to algorithm to sort a collection. Use the bubble sort algorithm:

               

              Sub BubbleSort(list()) 
              '   Sorts an array using bubble sort algorithm
                  Dim First As Integer, Last As Long
                  Dim i As Long, j As Long
                  Dim Temp As Long
                 
                  First = LBound(list)
                  Last = UBound(list)
                  For i = First To Last - 1
                      For j = i + 1 To Last
                          If list(i) > list(j) Then
                              Temp = list(j)
                              list(j) = list(i)
                              list(i) = Temp
                          End If
                      Next j
                  Next i
              End Sub
                • Re: GetNext but with a direction
                  Matt Bieringer

                  Thank you guys. I am starting to think I am in over my head with this one. I can honestly say I have no idea how to properly use the algorithm. I tried to write up a small macro that will just display the location of the annotation so I can see what it is I am working with, but that just seems to crash every time I try it. That being said, could you explain how I can use the sort?

                   

                  This is my location macro

                  Dim swApp                           As SldWorks.SldWorks
                  Dim swModel                         As SldWorks.ModelDoc
                  Dim swDraw                          As SldWorks.DrawingDoc
                  Dim swView                          As SldWorks.View
                  Dim swNote                          As SldWorks.Note
                  Dim swAnno                          As SldWorks.Annotation
                  Dim i                               As Long
                  Dim bl                              As Long
                  Dim start                           As String
                  Dim num                             As Long
                  Dim loc                             As Object
                  Sub main()
                  Set swApp = Application.SldWorks
                  Set swModel = swApp.ActiveDoc
                  Set swDraw = swModel
                  Set swView = swDraw.GetFirstView
                  start = 1
                  num = 0
                  While Not swView Is Nothing
                      Set swNote = swView.GetFirstNote
                      While Not swNote Is Nothing
                          If swNote.GetText Like "~~" Then
                              If swNote.GetText Like "~~" Then swNote.SetText start
                                  num = start
                                  Set swAnno = swNote.GetAnnotation
                                      loc = swAnno.GetPosition
                                  MsgBox "Number: " & num & "Position" & loc
                                  start = start + 1
                              Set swNote = swNote.GetNext
                          End If
                      Wend
                      Set swView = swView.GetNextView
                  Wend
                  End Sub
                  
                    • Re: GetNext but with a direction
                      Matt Bieringer

                      Ok I was able to get my location macro to work, but I am still unsure of how I can make the algorithm work with the macro.

                       

                      Dim swApp                           As SldWorks.SldWorks
                      Dim swModel                         As SldWorks.ModelDoc
                      Dim swDraw                          As SldWorks.DrawingDoc
                      Dim swView                          As SldWorks.view
                      Dim swNote                          As SldWorks.Note
                      Dim swAnno                          As SldWorks.Annotation
                      Dim loc                             As Variant
                      Dim nam                             As String
                      Dim num                             As String
                      Dim view                            As String
                      Sub main()
                      Set swApp = Application.SldWorks
                      Set swModel = swApp.ActiveDoc
                      Set swDraw = swModel
                      Set swView = swDraw.GetFirstView
                      num = 1
                      While Not swView Is Nothing
                          Set swNote = swView.GetFirstNote
                          view = swView.GetName2
                          While Not swNote Is Nothing
                              If swNote.GetText Like "~~" Then
                                  If swNote.GetText Like "~~" Then swNote.SetText num
                                  Set swAnno = swNote.GetAnnotation
                                  'Debug.Print "Hello"
                                      loc = swAnno.GetPosition
                                      nam = swAnno.GetName
                                      If Not IsNull(loc) Then
                                          'swAnno
                                          'MsgBox "Name: " & nam & " Location x: " & loc(0) * 39.3701 & "y: " & loc(1) * 39.3701
                                          Debug.Print "      Name of view = (" & view & ")"
                                          Debug.Print "      Number of annotation = (" & num & ")"
                                          Debug.Print "      Name of annotation = (" & nam & ")"
                                          Debug.Print "      Origin of annotation = (" & loc(0) * 39.3701 & ", " & loc(1) * 39.3701 & ") in"
                                          Debug.Print ""
                                      End If
                                  num = num + 1
                                  Set swNote = swNote.GetNext
                              Else
                                  Set swNote = swNote.GetNext
                              End If
                          Wend
                          Set swView = swView.GetNextView
                      Wend
                      End Sub
                      
                    • Re: GetNext but with a direction
                      Ivana Kolin

                      sort by X is not enough, then you will get this order 6, 1, 4, 5, 2, 3

                      This should be sorted by angel. Find two notes with max Y. This will give you point 1 and 2.  Create vector and compare angel between this vector and vector from  note 1  and all other notes.

                        • Re: GetNext but with a direction
                          Matt Bieringer

                          But wouldn't that assume that the first note that it comes across is the starting note? This might not always be the case, as not everyone at my company likes to start their balloons in the same location.

                          • Re: GetNext but with a direction
                            John Alexander

                            Would it be better to compute the angles of the rays beginning at some center point rather than the first note?

                             

                            In the example, if 6 and 5 happened to have their x positions swapped (I think that is a reasonable possibility), the relative angle with respect to note 1 would not be in order anymore. If the angle was computed with respect to some center point, I think it would be more robust.

                              • Re: GetNext but with a direction
                                Ivana Kolin

                                it would be better, but it is not really easy to compute with vectors and 360°

                                  • Re: GetNext but with a direction
                                    Matt Bieringer

                                    Thank you guys for the ideas, do you know of an example where I can see how I could go about this?

                                      • Re: GetNext but with a direction
                                        John Alexander

                                        This just adds the step of computing the angle of a vector from the first note to all of the rest of the notes. It is kind of sloppy, the functions at the bottom just compute the angle of the vectors between any notes or (optionally) points.

                                         

                                        The next step would be to sort by this value.

                                         

                                        Sub main()
                                            Dim swApp          As SldWorks.SldWorks
                                            Dim swModel        As SldWorks.ModelDoc
                                            Dim swDraw          As SldWorks.DrawingDoc
                                            Dim swView          As SldWorks.view
                                            Dim swNote          As SldWorks.Note
                                            Dim swFirstNote    As SldWorks.Note
                                            Dim swAnno          As SldWorks.Annotation
                                            Dim loc            As Variant
                                            Dim nam            As String
                                            Dim num            As String
                                            Dim view            As String
                                          
                                          
                                            Dim notes() As SldWorks.Note
                                          
                                          
                                            Set swApp = Application.SldWorks
                                            Set swModel = swApp.ActiveDoc
                                            Set swDraw = swModel
                                            Set swView = swDraw.GetFirstView
                                          
                                            num = 1
                                            While Not swView Is Nothing
                                                Set swFirstNote = swView.GetFirstNote
                                                Set swNote = swView.GetFirstNote
                                                view = swView.GetName2
                                                Debug.Print view
                                                While Not swNote Is Nothing
                                                    If swNote.GetText Like "~~" Then
                                                        If swNote.GetText Like "~~" Then swNote.SetText num
                                                        Set swAnno = swNote.GetAnnotation
                                                        'Debug.Print "Hello"
                                                            loc = swAnno.GetPosition
                                                            nam = swAnno.GetName
                                                            If Not IsNull(loc) Then
                                                                'swAnno
                                                                'MsgBox "Name: " & nam & " Location x: " & loc(0) * 39.3701 & "y: " & loc(1) * 39.3701
                                                                'Debug.Print "      Name of view = (" & view & ")"
                                                                'Debug.Print "      Number of annotation = (" & num & ")"
                                                                'Debug.Print "      Name of annotation = (" & nam & ")"
                                                                'Debug.Print "      Origin of annotation = (" & loc(0) * 39.3701 & ", " & loc(1) * 39.3701 & ") in"
                                                                'Debug.Print ""
                                                            End If
                                                        num = num + 1
                                                      
                                                        Debug.Print (computeAngleBetweenNotes(swFirstNote, swNote))
                                                        Set swNote = swNote.GetNext
                                                    Else
                                                        Set swNote = swNote.GetNext
                                                    End If
                                                Wend
                                                Set swView = swView.GetNextView
                                            Wend
                                        End Sub
                                        
                                        Function computeAngleBetweenNotes(swNote1 As SldWorks.Note, swNote2 As SldWorks.Note) As Double
                                            Dim swAnno1    As SldWorks.Annotation
                                            Dim swAnno2    As SldWorks.Annotation
                                           
                                            Set swAnno1 = swNote1.GetAnnotation
                                            Set swAnno2 = swNote2.GetAnnotation
                                           
                                            computeAngleBetweenNotes = computeAngleBetweenPoints(swAnno1.GetPosition, swAnno2.GetPosition)
                                        End Function
                                        
                                        Function computeAngleBetweenPoints(loc1 As Variant, loc2 As Variant) As Double    'points as variant arrays (x,y)
                                            computeAngleBetweenPoints = ArcTan2(loc2(0) - loc1(0), loc2(1) - loc1(1))
                                        End Function
                                        
                                        Function ArcTan2(X As Double, Y As Double) As Double
                                            'borrowed from: https://stackoverflow.com/questions/5117265/does-vba-have-an-atan2-function?
                                            Const PI As Double = 3.14159265358979
                                            Const PI_2 As Double = 1.5707963267949
                                            Select Case X
                                                Case Is > 0
                                                    ArcTan2 = Atn(Y / X)
                                                Case Is < 0
                                                    ArcTan2 = Atn(Y / X) + PI * Sgn(Y)
                                                    If Y = 0 Then ArcTan2 = ArcTan2 + PI
                                                Case Is = 0
                                                    ArcTan2 = PI_2 * Sgn(Y)
                                            End Select
                                        End Function
                                        
                                          • Re: GetNext but with a direction
                                            Matt Bieringer

                                            John that works very well, the only issue I can see with that is the arctan from balloon 1 to balloon 2 is 0 because they are on the same x plane.

                                              • Re: GetNext but with a direction
                                                John Alexander

                                                Is that incorrect? The angles will be with respect to horizontal/x axis. If you sort the angles in increasing order, the notes would be progressing in a CCW fashion and vice versa.

                                                  • Re: GetNext but with a direction
                                                    Matt Bieringer

                                                    That will work as long as there is not a balloon that is in between 1 and 2 that is slightly above. Then I return a positive number which if I sort them will make the last balloon to number. That being said I can use that to sort along with the x and y positions, that is if I can figure out the sort.

                                                      • Re: GetNext but with a direction
                                                        John Alexander

                                                        This is why I think it would be best to compute these angles for vectors starting at the center point of all the notes.

                                                         

                                                        Imagine you've computed your angles with respect to the center point. When you select a starting annotation, that annotation will (probably) have a non-zero angle, call it theta_start. You can subtract theta_start from all of the rest and you'll have a guarantee that increasing values are moving CCW about the center_point (and vice versa). This would essentially "clock" the values so that they are starting at 0 and, with one additional step, guarantee that they not exceed (0,2pi]. In this way, you don't have to do any thinking about whether or not a note is higher than the starting note. You can start with any note that you want and it will order the notes to increase/decrease along CW or CCW.

                                                         

                                                        Assuming you've built your array of angles measured with respect to the center point and named it "theta_array" and also selected a starting annotation and computed its angle:

                                                        for i in 0 to ubound(theta_array)

                                                             theta(i) = theta(i) - theta_start 'offset

                                                             'There is a clever (but inefficient) way of wrapping unbounded angles back on (0, 2pi] without using modular arithmetic.

                                                             theta(i) = ArcTan2(cos(theta(i)), sin(theta(i)))

                                                             'traditionally atan2 takes (y,x) but the function provided earlier takes (x,y)

                                                        next i

                                                        This step would be a precursor to the actual sorting.

                                                         

                                                         

                                                        EDIT: I wrote this post before realizing that Ivana already got it done.

                                                  • Re: GetNext but with a direction
                                                    Ivana Kolin

                                                    sorted and using centerpoint

                                                     

                                                    Option Explicit
                                                     
                                                    Private Function ArcTan2(x As Double, Y As Double) As Double
                                                        'borrowed from: https://stackoverflow.com/questions/5117265/does-vba-have-an-atan2-function?
                                                        Const PI As Double = 3.14159265358979
                                                        Const PI_2 As Double = 1.5707963267949
                                                        Select Case x
                                                            Case Is > 0
                                                                ArcTan2 = Atn(Y / x)
                                                            Case Is < 0
                                                                ArcTan2 = Atn(Y / x) + PI * Sgn(Y)
                                                                If Y = 0 Then ArcTan2 = ArcTan2 + PI
                                                            Case Is = 0
                                                                ArcTan2 = PI_2 * Sgn(Y)
                                                        End Select
                                                    End Function
                                                    Sub BubbleSort(list() As Note)
                                                        '   Sorts an array using bubble sort algorithm
                                                        Dim i As Long, j As Long
                                                        Dim Temp As Note
                                                        Dim last As Long
                                                        last = UBound(list)
                                                        For i = 0 To last - 1
                                                            For j = i + 1 To last
                                                                If Val(list(i).TagName) < Val(list(j).TagName) Then
                                                                    Set Temp = list(j)
                                                                    Set list(j) = list(i)
                                                                    Set list(i) = Temp
                                                                End If
                                                            Next j
                                                        Next i
                                                    End Sub
                                                    Sub main()
                                                        Dim swApp As SldWorks.SldWorks
                                                        Dim swModel As SldWorks.ModelDoc
                                                        Dim swDraw As SldWorks.DrawingDoc
                                                        Dim swView As SldWorks.view
                                                        Dim swNote As SldWorks.Note
                                                        Dim swFirstNote As SldWorks.Note
                                                        Dim swAnno As SldWorks.Annotation
                                                        Dim loc As Variant
                                                        Dim xMin As Double
                                                        Dim xMax As Double
                                                        Dim yMin As Double
                                                        Dim yMax As Double
                                                     
                                                        Dim cpX As Double
                                                        Dim cpY As Double
                                                        Dim notes() As SldWorks.Note
                                                     
                                                        Dim i As Integer
                                                     
                                                     
                                                        Set swApp = Application.SldWorks
                                                        Set swModel = swApp.ActiveDoc
                                                        Set swDraw = swModel
                                                        Set swView = swDraw.GetFirstView
                                                     
                                                      
                                                        xMax = -99999999
                                                        yMax = -99999999
                                                        xMin = 99999999
                                                        yMin = 99999999
                                                        While Not swView Is Nothing
                                                            Set swFirstNote = swView.GetFirstNote
                                                            Set swNote = swView.GetFirstNote
                                                            While Not swNote Is Nothing
                                                                If swNote.GetText Like "~~*" Then
                                                                    i = i + 1
                                                                    Set swAnno = swNote.GetAnnotation
                                                                    loc = swAnno.GetPosition
                                                                    If loc(0) < xMin Then xMin = loc(0)
                                                                    If loc(0) > xMax Then xMax = loc(0)
                                                                    If loc(1) < yMin Then yMin = loc(1)
                                                                    If loc(1) > yMax Then yMax = loc(1)
                                                                End If
                                                                Set swNote = swNote.GetNext
                                                            Wend
                                                            Set swView = swView.GetNextView
                                                        Wend
                                                        If i = 0 Then Exit Sub
                                                        cpX = (xMax + xMin) / 2
                                                        cpY = (yMax + yMin) / 2
                                                     
                                                        ReDim notes(i - 1)
                                                        i = 0
                                                        Set swView = swDraw.GetFirstView
                                                     
                                                        While Not swView Is Nothing
                                                            Set swFirstNote = swView.GetFirstNote
                                                            Set swNote = swView.GetFirstNote
                                                     
                                                            While Not swNote Is Nothing
                                                     
                                                                If swNote.GetText Like "~~*" Then
                                                                    Set notes(i) = swNote
                                                                    i = i + 1
                                                                    Set swAnno = swNote.GetAnnotation
                                                     
                                                                    loc = swAnno.GetPosition
                                                                   
                                                                    swNote.TagName = ArcTan2(cpX - loc(0), cpY - loc(1))
                                                                End If
                                                                Set swNote = swNote.GetNext
                                                     
                                                            Wend
                                                            Set swView = swView.GetNextView
                                                        Wend
                                                     
                                                        BubbleSort notes
                                                     
                                                        For i = 0 To UBound(notes)
                                                            notes(i).SetText i
                                                        Next
                                                    End Sub
                                                    
                                                      • Re: GetNext but with a direction
                                                        Matt Bieringer

                                                        Ivana thank you so much again. One issue I have is that this starts at the bottom right corner and I need it to start at the top left. What should I change in order to sort this in the correct direction?

                                                          • Re: GetNext but with a direction
                                                            Ivana Kolin

                                                            always upper left or  selected = 1 and then clockwise the rest?

                                                             

                                                            Option Explicit
                                                             
                                                            Public Function ArcTan2(x As Double, y As Double) As Double
                                                                'borrowed from: https://stackoverflow.com/questions/5117265/does-vba-have-an-atan2-function?
                                                                Const PI As Double = 3.14159265358979
                                                                Const PI_2 As Double = 1.5707963267949
                                                                Select Case x
                                                                    Case Is > 0
                                                                        ArcTan2 = Atn(y / x)
                                                                    Case Is < 0
                                                                        ArcTan2 = Atn(y / x) + PI * Sgn(y)
                                                                        If y = 0 Then ArcTan2 = ArcTan2 + PI
                                                                    Case Is = 0
                                                                        ArcTan2 = PI_2 * Sgn(y)
                                                                End Select
                                                            End Function
                                                            Sub BubbleSort(list() As Note)
                                                                '   Sorts an array using bubble sort algorithm
                                                                Dim i As Long, j As Long
                                                                Dim Temp As Note
                                                                Dim last As Long
                                                                last = UBound(list)
                                                                For i = 0 To last - 1
                                                                    For j = i + 1 To last
                                                                        If Val(list(i).TagName) < Val(list(j).TagName) Then
                                                                            Set Temp = list(j)
                                                                            Set list(j) = list(i)
                                                                            Set list(i) = Temp
                                                                        End If
                                                                    Next j
                                                                Next i
                                                            End Sub
                                                            Sub main()
                                                                Dim swApp As SldWorks.SldWorks
                                                                Dim swModel As SldWorks.ModelDoc
                                                                Dim swDraw As SldWorks.DrawingDoc
                                                                Dim swView As SldWorks.view
                                                                Dim swNote As SldWorks.Note
                                                                Dim swFirstNote As SldWorks.Note
                                                                Dim swAnno As SldWorks.Annotation
                                                                Dim loc As Variant
                                                                Dim xMin As Double
                                                                Dim xMax As Double
                                                                Dim yMin As Double
                                                                Dim yMax As Double
                                                             
                                                                Dim cpX As Double
                                                                Dim cpY As Double
                                                                Dim notes() As SldWorks.Note
                                                             
                                                                Dim i As Integer
                                                             
                                                             
                                                                Set swApp = Application.SldWorks
                                                                Set swModel = swApp.ActiveDoc
                                                                Set swDraw = swModel
                                                                Set swView = swDraw.GetFirstView
                                                             
                                                              
                                                                xMax = -99999999
                                                                yMax = -99999999
                                                                xMin = 99999999
                                                                yMin = 99999999
                                                                While Not swView Is Nothing
                                                                    Set swFirstNote = swView.GetFirstNote
                                                                    Set swNote = swView.GetFirstNote
                                                                    While Not swNote Is Nothing
                                                                        If swNote.GetText Like "~~*" Then
                                                                            i = i + 1
                                                                            Set swAnno = swNote.GetAnnotation
                                                                            loc = swAnno.GetPosition
                                                                            If loc(0) < xMin Then xMin = loc(0)
                                                                            If loc(0) > xMax Then xMax = loc(0)
                                                                            If loc(1) < yMin Then yMin = loc(1)
                                                                            If loc(1) > yMax Then yMax = loc(1)
                                                                        End If
                                                                        Set swNote = swNote.GetNext
                                                                    Wend
                                                                    Set swView = swView.GetNextView
                                                                Wend
                                                                If i = 0 Then Exit Sub
                                                                cpX = (xMax + xMin) / 2
                                                                cpY = (yMax + yMin) / 2
                                                             
                                                                ReDim notes(i - 1)
                                                                i = 0
                                                                Set swView = swDraw.GetFirstView
                                                             
                                                                While Not swView Is Nothing
                                                                    Set swFirstNote = swView.GetFirstNote
                                                                    Set swNote = swView.GetFirstNote
                                                             
                                                                    While Not swNote Is Nothing
                                                             
                                                                        If swNote.GetText Like "~~*" Then
                                                                            Set notes(i) = swNote
                                                                            i = i + 1
                                                                            Set swAnno = swNote.GetAnnotation
                                                             
                                                                            loc = swAnno.GetPosition
                                                                            Dim t As Double
                                                                            t = ArcTan2(cpX - loc(0), cpY - loc(1))
                                                                           
                                                                            swNote.TagName = t
                                                                        End If
                                                                        Set swNote = swNote.GetNext
                                                             
                                                                    Wend
                                                                    Set swView = swView.GetNextView
                                                                Wend
                                                             
                                                                BubbleSort notes
                                                                rotate notes
                                                                For i = 0 To UBound(notes)
                                                                   
                                                                    notes(i).SetText i
                                                                Next
                                                            End Sub
                                                            Sub rotate(list() As Note)
                                                                '   Sorts an array using bubble sort algorithm
                                                                Dim i As Long, j As Long, k As Long
                                                                Dim Temp As Note
                                                                Dim last As Long
                                                                Dim tempList() As Note
                                                                Const PI_4 As Double = -0.785398163397448
                                                                ReDim tempList(UBound(list))
                                                                last = UBound(list)
                                                                For i = 0 To last
                                                                    Debug.Print Val(list(i).TagName)
                                                                    If Val(list(i).TagName) < PI_4 Then
                                                                        If i = 0 Then Exit Sub
                                                                        k = 0
                                                                        For j = i To last
                                                                            Set tempList(k) = list(j)
                                                                            k = k + 1
                                                                        Next
                                                                        Exit For
                                                                    End If
                                                                Next i
                                                                For j = 0 To i - 1
                                                                    Set tempList(k) = list(j)
                                                                    k = k + 1
                                                                Next
                                                                list = tempList
                                                                
                                                            End Sub
                                                            
                                                            
                                                            
                                                              • Re: GetNext but with a direction
                                                                Matt Bieringer

                                                                That almost worked I just needed to change PI_4 from -0.785398163397448 to -0.39269908175. That being said is there a way for me to sort and set the text before going to the next view while still maintaining the total balloon numbers? I initially tried to move the sort notes and set text lines above the last .getnextview but I get a '91 error in regards to the If Val(list(i).TagName) < Val(list(j).TagName) Then line in the bubblesort sub.

                                                                  • Re: GetNext but with a direction
                                                                    Ivana Kolin

                                                                    I didn't test it!

                                                                    Option Explicit
                                                                    
                                                                    
                                                                       
                                                                    Public Function ArcTan2(x As Double, y As Double) As Double
                                                                        'borrowed from: https://stackoverflow.com/questions/5117265/does-vba-have-an-atan2-function?
                                                                        Const PI As Double = 3.14159265358979
                                                                        Const PI_2 As Double = 1.5707963267949
                                                                        Select Case x
                                                                            Case Is > 0
                                                                                ArcTan2 = Atn(y / x)
                                                                            Case Is < 0
                                                                                ArcTan2 = Atn(y / x) + PI * Sgn(y)
                                                                                If y = 0 Then ArcTan2 = ArcTan2 + PI
                                                                            Case Is = 0
                                                                                ArcTan2 = PI_2 * Sgn(y)
                                                                        End Select
                                                                    End Function
                                                                    
                                                                    
                                                                    Sub BubbleSort(list() As Note)
                                                                        '   Sorts an array using bubble sort algorithm
                                                                        Dim i As Long, j As Long
                                                                        Dim Temp As Note
                                                                        Dim last As Long
                                                                        last = UBound(list)
                                                                        
                                                                        For i = 0 To last - 1
                                                                            For j = i + 1 To last
                                                                                If Val(list(i).TagName) < Val(list(j).TagName) Then
                                                                                    Set Temp = list(j)
                                                                                    Set list(j) = list(i)
                                                                                    Set list(i) = Temp
                                                                                End If
                                                                            Next j
                                                                        Next i
                                                                    End Sub
                                                                    
                                                                    
                                                                    Sub main()
                                                                        Dim swApp As SldWorks.SldWorks
                                                                        Dim swModel As SldWorks.ModelDoc
                                                                        Dim swDraw As SldWorks.DrawingDoc
                                                                        Dim swView As SldWorks.View
                                                                        Dim swNote As SldWorks.Note
                                                                        Dim swFirstNote As SldWorks.Note
                                                                        Dim swAnno As SldWorks.Annotation
                                                                        Dim loc As Variant
                                                                        Dim xMin As Double
                                                                        Dim xMax As Double
                                                                        Dim yMin As Double
                                                                        Dim yMax As Double
                                                                        Dim notesText As Integer
                                                                        Dim notesTotalCounter As Integer
                                                                        Dim cpX As Double
                                                                        Dim cpY As Double
                                                                        Dim notes() As SldWorks.Note
                                                                       
                                                                        Dim i As Integer
                                                                       
                                                                       
                                                                        Set swApp = Application.SldWorks
                                                                        Set swModel = swApp.ActiveDoc
                                                                        Set swDraw = swModel
                                                                        Set swView = swDraw.GetFirstView
                                                                       
                                                                        
                                                                        xMax = -99999999
                                                                        yMax = -99999999
                                                                        xMin = 99999999
                                                                        yMin = 99999999
                                                                        While Not swView Is Nothing
                                                                            Set swFirstNote = swView.GetFirstNote
                                                                            Set swNote = swView.GetFirstNote
                                                                            While Not swNote Is Nothing
                                                                                If swNote.GetText Like "~~*" Then
                                                                                    i = i + 1
                                                                                    Set swAnno = swNote.GetAnnotation
                                                                                    loc = swAnno.GetPosition
                                                                                    If loc(0) < xMin Then xMin = loc(0)
                                                                                    If loc(0) > xMax Then xMax = loc(0)
                                                                                    If loc(1) < yMin Then yMin = loc(1)
                                                                                    If loc(1) > yMax Then yMax = loc(1)
                                                                                End If
                                                                                Set swNote = swNote.GetNext
                                                                            Wend
                                                                            Set swView = swView.GetNextView
                                                                        Wend
                                                                        If i = 0 Then Exit Sub
                                                                        cpX = (xMax + xMin) / 2
                                                                        cpY = (yMax + yMin) / 2
                                                                        notesTotalCounter = i - 1
                                                                       
                                                                        
                                                                        Set swView = swDraw.GetFirstView
                                                                        notesText = 1
                                                                        While Not swView Is Nothing
                                                                            Set swFirstNote = swView.GetFirstNote
                                                                            Set swNote = swView.GetFirstNote
                                                                            ReDim notes(notesTotalCounter)
                                                                            i = 0
                                                                            While Not swNote Is Nothing
                                                                               
                                                                                If swNote.GetText Like "~~*" Then
                                                                                    Set notes(i) = swNote
                                                                                    i = i + 1
                                                                                    Set swAnno = swNote.GetAnnotation
                                                                       
                                                                                    loc = swAnno.GetPosition
                                                                                    Dim t As Double
                                                                                    t = ArcTan2(cpX - loc(0), cpY - loc(1))
                                                                                     
                                                                                    swNote.TagName = t
                                                                                End If
                                                                                Set swNote = swNote.GetNext
                                                                       
                                                                            Wend
                                                                            If i > 0 Then
                                                                                ReDim Preserve notes(i - 1)
                                                                                BubbleSort notes
                                                                                rotate notes
                                                                                For i = 0 To UBound(notes)
                                                                                    notes(i).SetText notesText
                                                                                    notesText = notesText + 1
                                                                                Next
                                                                            End If
                                                                            Set swView = swView.GetNextView
                                                                        Wend
                                                                    End Sub
                                                                    
                                                                    
                                                                    Sub rotate(list() As Note)
                                                                        '   Sorts an array using bubble sort algorithm
                                                                        Dim i As Long, j As Long, k As Long
                                                                        Dim Temp As Note
                                                                        Dim last As Long
                                                                        Dim tempList() As Note
                                                                        Const PI_4 As Double = -0.39269908175
                                                                        ReDim tempList(UBound(list))
                                                                        last = UBound(list)
                                                                        For i = 0 To last
                                                                            Debug.Print Val(list(i).TagName)
                                                                            If Val(list(i).TagName) < PI_4 Then
                                                                                If i = 0 Then Exit Sub
                                                                                k = 0
                                                                                For j = i To last
                                                                                    Set tempList(k) = list(j)
                                                                                    k = k + 1
                                                                                Next
                                                                                Exit For
                                                                            End If
                                                                        Next i
                                                                        For j = 0 To i - 1
                                                                            Set tempList(k) = list(j)
                                                                            k = k + 1
                                                                        Next
                                                                        list = tempList
                                                                          
                                                                    End Sub
                                                                    
                                              • Re: GetNext but with a direction
                                                Matt Bieringer

                                                Ok so I think I have figured out what the best way to control all my locations by using a multidimensional array. That being said I need to sort it now. This is how the array is created.

                                                vloc(0,i)=x

                                                vloc(1,i)=y

                                                vloc(2,i)=ArcTan

                                                 

                                                I need to sort all instances of the array by the first column, then once they are all together, i.e. vloc(0,2), vloc(0,1), vloc(1,1), vloc(1,2), vloc(2,2), vloc(2,1). Then sort by the second column while maintaining the original sort, i.e. vloc(0,1), vloc(0,2), vloc(1,1), vloc(1,2), vloc(2,1), vloc(2,2). I have tried some iterations of quicksort but I am having some difficulty that doesn't involve excel functionality.