[SOLVED] Sorting shapes by property value and storing in array

Started by jwebber89, March 05, 2018, 06:11:36 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

jwebber89

Hi All,

Long time lurker.
I'm attempting to pro-grammatically clean up visio diagrams (placement, sizing, auto-space). One aspect that is hanging me up at the moment is the ability to sort shapes by a specific shape property and then store them in an array. As I understand there are very few tools for sorting arrays so I assume have to build my own sorting method?

Not entirely sure where to start or go about this efficiently.

The function/macro will only have to handle a few dozen shapes at a time.
What I'd like to do is store all the shape objects from a selection and loop over them looking for a 'specific type' (property). From here repeat the loop to do a compare and store these  in asc order in my final array to do my auto-spacing.


Here is what I have so far?




Public Sub SortTest()


Dim iShp As Integer
Dim cShapes As Collection
Dim vItm As Variant
Dim i As Long, j As Long
Dim vTemp As Variant
Dim oShp As Visio.Shape
Dim objShp As Object


Set cShapes = New Collection
    For iShp = 1 To Visio.ActiveWindow.Selection.Count
        Set oShp = Visio.ActiveWindow.Selection.Item(iShp)
        If oShp.Cells("Prop.Type") = 4000 Or oShp.Cells("Prop.Type") = 4001 Then
            cShapes.Add (oShp)
        End If
    Next iShp
       
    For i = 1 To cShapes.Count - 1
      For j = i + 1 To cShapes.Count
          If cShapes(i) > cShapes(j) Then
              'store the lesser item
              vTemp = cShapes(j)
              'remove the lesser item
              cShapes.Remove j
              're-add the lesser item before the
              'greater Item
              cShapes.Add vTemp, vTemp, i
          End If
      Next j
    Next i


    'Test it
    For Each vItm In cShapes
        MsgBox vItm
    Next vItm
human

I Know my issue at this point is not understanding how my objects are stored in my collection. I assumed it would save the object and not the literal string name of the object (a shape in this case). Therefore I can't do any comparisons on it's properties in the cShapes loop.


Such as


cShapes(i).Cells("PinX") >  [font=Verdana][size=2px]cShapes(j).Cells("PinX")[/font][/size]

jwebber89

#1
I found my mistake


specifically this line is wrong:

cShapes.Add (oShp)

The above writes the string literal of the reference and not the reference itself

the correct syntax for the object reference is:

cShapes.Add oShp

Full code snipp



Dim iShp As Integer
Dim cShapes As Collection
Dim oShp As Visio.Shape


Dim vItm As Variant
Dim i As Long, j As Long
Dim vTemp As Variant
Dim objShp1 As Variant
Dim objShp2 As Variant




Set cShapes = New Collection
    For iShp = 1 To Visio.ActiveWindow.Selection.Count
        Set oShp = Visio.ActiveWindow.Selection.Item(iShp)
       
        If oShp.Cells("Prop.Type") = 4000 Or oShp.Cells("Prop.Type") = 4001 Then
            cShapes.Add (oShp)
        End If
    Next iShp

   
    For i = 1 To cShapes.Count - 1
      For j = i + 1 To cShapes.Count
      objShp1 = cShapes(i).Cells("PinX")
      objShp2 = cShapes(j).Cells("PinX")
          If cShapes(i).Cells("PinX") > cShapes(j).Cells("PinX") Then
              'store the lesser item
              vTemp = cShapes(j)
              'remove the lesser item
              cShapes.Remove j
              're-add the lesser item before the
              'greater Item
              cShapes.Add vTemp, vTemp, i
          End If
      Next j
    Next i

    'Test it
    For Each vItm In cShapes
        MsgBox vItm
    Next vItm




The function takes a the active selection and grabs all shapes that meet the first If condition and stores them in a collection.

the collection is then sorted by the second/third  for loop which removes the lesser item and adds it before the greater one, it does this recursively thus giving u a sorted collection of shapes.

Purpose was to take a collection of sorted shapes and align them appropriately.



President of the United States: Donald J. _____ (the "J" stands for "Joke"):    :o  (slow claps......)

wapperdude

@ jwebber89:  please refrain from political comments.

Thanks.
Wapperdude
Visio 2019 Pro