Code for looping through subshapes and identifying the Data Graphics

Started by Visisthebest, November 15, 2023, 06:59:50 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Visisthebest

What is the best way to identify in code which subshapes in a group are Data Graphics?

What is the most logical thing to check to make sure a subshape is a data graphic, or not?
Visio 2021 Professional

Visisthebest

I realize checking for shapes on the Data Graphics layer would normally work, but in this case I need to move them to the layer the group shape is on, so checking for the layer doesn't solve the problem unfortunately.
Visio 2021 Professional

Nikolay

There is "shape.DataGraphic.Shapes" property. Maybe this one could help?

Visisthebest

Thank you Nikolay I did not know this existed, actually Microsoft does not list anything about the shapes property on the shape.datagraphic:
https://learn.microsoft.com/en-us/office/vba/api/visio.shape.datagraphic

so didn't know I could get the data graphic subshapes from a shape this way thank you!
Visio 2021 Professional

Visisthebest

Nikolay the documentation says:

Gets or sets the data graphic master (Master of type visTypeDataGraphic) that is associated with the shape. Read/write.

Doesn't sound like I can retrieve the Data Graphics shapes in a group shape from this.
Visio 2021 Professional

wapperdude

This link has fairly comprehensive discussion of datagraphics:  https://learn.microsoft.com/en-us/office/vba/visio/Concepts/about-displaying-data-graphically-visio

Here's a snippet, that might have immediate use:
You can also determine master names and IDs by iterating through the Masters collection in the current document, as shown in the following code.

    For intCounter = 1 To ActiveDocument.Masters.Count
        If ActiveDocument.Masters(intCounter).Type = visTypeDataGraphic Then
            Debug.Print ActiveDocument.Masters(intCounter).Name, ActiveDocument.Masters(intCounter).ID
        End If
    Next


Edit: Tried this out, and it does work.  Finds the DataGraphic masters in the document.  My guess, this might be too general as it is not limited on a per shape basis.  But, with some code modification, doing a recursive search, then it ought to be possible to find shapes that have a master which is of type DataGraphic.
Visio 2019 Pro

Nikolay

Yes, you are right... these are not the shapes you want, sorry for confusion :(

Visisthebest

Thank you Wapperdude!

It is fine Nikolay, I was hoping for a .IsDataGraphic boolean property or something, like .OneD, but probably I need to look in the User Cells there are some cell names unique to Data graphics as far as I can see.
Visio 2021 Professional

wapperdude

Well, you just have to search for the right keywords.  Here's recursive code that searches for datagraphic shapes.  Tried and tested on simple case.

Sub Main()
' Main calling code for recursive searching
' Original code provided by Surrogate
    ShapesList ActivePage.Shapes
End Sub

Sub ShapesList(ByVal shps As Shapes)
    Dim sh As Shape
    Dim vChars As Visio.Characters
   
    For Each sh In shps
'        If sh.CellExists("User.msvCalloutType", 0) Then
'            Debug.Print sh.Name, sh.Type; sh.Index
'        End If

        If sh.IsDataGraphicCallout Then
            Debug.Print sh.Name, sh.ID, sh.Index
        End If

'Recursive drill down call:
        ShapesList sh.Shapes
    Next sh
End Sub
Visio 2019 Pro

wapperdude

Here's code version that isn't recursive.  There may be cases where this does not work.  Technically, the parent shape of the datagraphics is NOT a group.  But, it could be grouped with other shapes.  In such a scenario, this code version won't work.  The above presented recursive code does work for both normally formed datagraphics and grouped instantiations.


Sub dgShapes()
    Dim sh As Visio.Shape
    Dim dgShp As Visio.Shape
   
    For Each sh In ActivePage.Shapes
        If Not sh.DataGraphic Is Nothing Then
            Debug.Print sh.Name    'Containing shape
            For Each dgShp In sh.Shapes
                If dgShp.IsDataGraphicCallout Then
                    Debug.Print dgShp.Name, dgShp.ID, dgShp.Index
                End If
            Next
        End If
    Next
End Sub
Visio 2019 Pro

Visisthebest

Thank you Wapperdude! I especially like your second solution, checking if a shape has a DataGraphic object (the datagraphic master) because obviously if it has this object it is a data graphic.

Clever solution!
Visio 2021 Professional