Count Shapes by Master-Shape

Started by Karl, July 13, 2015, 09:15:56 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Karl

Hi,

i want to count how many shapes of one type i have on my sheet and save it to a label. Is it possible? Im new to VBA and Visio...  :-[


Thanks in advance.

charlykuntz

Hello Karl,

this is possible. My suggestion is to go through all shapes on a page and use the Shape.Master property (https://msdn.microsoft.com/en-us/library/office/ff766776.aspx) of each shape to count the masters.

aledlund

That is exactly what the legend shape does, although it requires that the shapes have a specific user field initialized. I'd start by putting a legend on the page and then dragging one of the shapes onto it that you want to keep track of.
Al

Karl

Thanks for your help. git that almost working :)

Sub Counter()

    Dim shp As Visio.Shape
    Dim i As Integer
   
    For Each shp In ActivePage.Shapes
        If shp.Master.Name Like "DV-ED.*" Then
           i = i + 1
            End If
            ActivePage.Shapes("SheetED").Characters.Text = CStr(i)
    Next shp
End Sub


1. how can i edit "SheetED" if it is on another page?
2. i get a Run Time Error '91' : Object Variable or With Block not Set

charlykuntz

Did you try Al's solution? It's a nice approach without programming. (Thanks Al, I haven't known this legend shape so far).

Regarding your questions:

1. Try the Document.Pages property.
2. I am not familiar with VBA but I suppose that your "shp" variable is not initialized in the for each loop. There is no need to declare the shp variable when using the for each loop. Just remove Dim shp As Visio.Shape and try again.

Karl

for question 1 this works for me:
ActiveDocument.Pages(5).Shapes("SheetED").Characters.Text = CStr(i)

for question 2:
i have no idea what to do...  :-[

charlykuntz

Have you already removed this line of code?
Dim shp As Visio.Shape

Does the error still occur?

JohnGoldsmith

Hi,

An alternative method would be to create a selection based on master type.  For example:


Sub CheckMasterInstances()
Dim mstNameU As String
mstNameU = "Process"

Dim targetDoc As Visio.Document
Set targetDoc = ThisDocument 'Change as required

Dim targetMst As Visio.Master
Set targetMst = GetMasterByName(targetDoc, mstNameU, True)

Dim shpCount As Integer
If Not targetMst Is Nothing Then
    Dim vPag As Visio.Page
    For Each vPag In targetDoc.Pages
        shpCount = shpCount + PageInstanceCount(vPag, targetMst)
    Next
End If

Debug.Print targetDoc.Name & " contains " & shpCount & " instances of '" & mstNameU & "' master"

End Sub


Private Function PageInstanceCount(ByRef vPag As Visio.Page, ByRef vMst As Visio.Master) As Integer
If Not vPag Is Nothing Then
    Dim vSel As Visio.Selection
    Set vSel = vPag.CreateSelection(visSelTypeByMaster, visSelModeSkipSuper, vMst)
    PageInstanceCount = vSel.Count
End If
End Function


Private Function GetMasterByName(ByRef vDoc As Visio.Document, targetName As String, isNameU As Boolean) As Visio.Master
If Not vDoc Is Nothing Then
    Dim mstNames() As String
    Dim idx As Long
    If isNameU Then
        vDoc.Masters.GetNamesU mstNames
    Else
        vDoc.Masters.GetNames mstNames
    End If
    For idx = LBound(mstNames) To UBound(mstNames)
        If mstNames(idx) = targetName Then
            Set GetMasterByName = vDoc.Masters(idx + 1)
            Exit Function
        End If
    Next idx
End If
End Function


Modifications might include changing the page loop if you only want to count foreground pages or maybe changing the PageInstanceCount function to output a report showing page name and instance count.

Also notice, just in case you weren't aware, that the above code uses the universal master names and not the local ones (although you could change it to that if you wanted to).

Anyway, hope that helps.

Best regards

John
John Goldsmith - Visio MVP
http://visualsignals.typepad.co.uk/