How do I space out multiple [sub]containers within containers?

Started by Chesticles, December 05, 2022, 02:28:08 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Chesticles

I have written a Visio macro that reads data from an Excel file. The Excel file data is a transaction log of a user's clicks(actions) as they're navigating through their software and other computer applications. My end goal is to automatically create a Spaghetti Diagram.

For each step in the Excel file, I have the application, page, sub-section 1, sub-section 2, sub-section 3(SS3), and then the action name.... all in separate columns. I have also added Unique Identifiers for each row by concatenating each of the columns into one cell value. I use these unique IDs for container/step shape naming in the macro so they can be identified easier later on. For the application through SS3 columns, I am inserting those into Visio as containers. For the container, i have created a stencil object that's being dropped on to the page each time. The action name is dropping a rectangle shape on the page. This shape is also a stencil that's being called during the page.drop command.

Some steps(actions) happen within the app only, page only, or each sub-section only so the macro is mostly a bunch of nested for loops.

The general approach how I have the macro written is to:
1. Insert app containers
2. Insert page containers for each app container that needs it
3. Insert ss1 containers for each page container
... and so on for all levels
5. Insert step shapes and nest within appropriate container level
6. Add connectors between each shape

The main problem I have is cleanly spacing out the containers as they're being dropped.

Every time a new container shape is dropped, I
1. Assign it a name from the respective uniqueID column in the Excel sheet
2. Label it
3. Unlock the container by using .LockMembership = False
4. Add it to the container one level above by .AddMember containeronelevelabove, visMemberAddUseResizeSetting
5. Lock the container by using .LockMembership = True
6. Resize container level above by .ResizeAsNeeded = visContainerAutoResizeExpandContract

This resizing and contracting statement works fine for the new container and the container one level above, but won't work for any container levels above that. Additionally, when there are multiple subcontainers within one container, sometimes they overlap or get spaced too far apart.... completely random. Ex: 2 SS1 containers within the same Page container.

All of this to say, how do I space multiple containers within the same level apart evenly?

Here is a snippet of the macro where I add the Application containers and then the page containers for each of the appcontainers.

    Const xoffset = 5
    Const yoffset = 0

    'Add Containers for Applications
    For I = 2 To lastrow
        appname = datasheet.Range("E" & I).Text 'App name is unique ID since there's no parent container
        appcount = objExcel.WorksheetFunction.CountIf(datasheet.Range("E2:E" & I), appname)
       
        'Only write unique values
        If appcount = 1 Then
            Application.ActiveWindow.Page.Drop Application.Documents.Item("PageContainer.vssx").Masters.ItemU("Container"), 1, 2
            Set appcontainer = ActiveWindow.Selection.PrimaryItem
            appcontainer.Name = appname & "_app.cont"
            appcontainer.Text = appname
            If I = 2 Then
                Set previouscontainer = appcontainer
            End If
            appcontainer.Cells("PinX").Result("in") = previouscontainer.Cells("PinX").Result("in") + xoffset
            appcontainer.Cells("PinY").Result("in") = previouscontainer.Cells("PinY").Result("in") + yoffset
            Set previouscontainer = appcontainer
        End If
    Next I
    '===============================================================================================================
   
    'Add Pages for each App Container
    For I = 2 To lastrow
        appname = datasheet.Range("E" & I).Text
        pagename = datasheet.Range("F" & I).Text
        pageuniqueID = datasheet.Range("R" & I).Text
        pagecount = objExcel.WorksheetFunction.CountIf(datasheet.Range("R2:R" & I), pageuniqueID)
       
        'Only write unique values
        If pagecount = 1 And pagename <> "" Then
            For Each appcontainer In ActivePage.Shapes
                If appcontainer.Name = appname & "_app.cont" Then                                                                               'locate correct Application Container
                    Application.ActiveWindow.Page.Drop Application.Documents.Item("PageContainer.vssx").Masters.ItemU("Container"), I, 5        'Add new container
                    Set pagecontainer = ActiveWindow.Selection.PrimaryItem
                    pagecontainer.Name = pageuniqueID & "_page.cont"
                    pagecontainer.Text = pagename
                    appcontainer.ContainerProperties.LockMembership = False
                    appcontainer.ContainerProperties.AddMember pagecontainer, visMemberAddUseResizeSetting                                     'Add page container to respective Application Container
                    appcontainer.ContainerProperties.LockMembership = True
                    appcontainer.ContainerProperties.ResizeAsNeeded = visContainerAutoResizeExpandContract                                     'Align containers
                       Exit For
                End If
            Next appcontainer
        End If
    Next I

Any help is greatly appreciated!