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.
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 (https://msdn.microsoft.com/en-us/library/office/ff766776.aspx)) of each shape to count the masters.
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
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
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.
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... :-[
Have you already removed this line of code?
Dim shp As Visio.Shape
Does the error still occur?
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 (https://msdn.microsoft.com/en-us/library/bb902804(v=office.12).aspx) and not the local ones (although you could change it to that if you wanted to).
Anyway, hope that helps.
Best regards
John