Creating and Using UniqueIDs in Shapes

Started by Scott Morrison, June 07, 2013, 09:50:34 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Scott Morrison

Hello all,
I'm not new to Visio nor to programming but I am new to developing in Visio.
I'm using 2007 and am creating my own custom shapes with Shape Data.
I want to create a UniqueID for all my shapes in the context of the drawing.
I have created a Shape data element called 'Shape UniqueID'. (ShapeSheet  Prop.Shape_Unique_ID)
I tried to generate a unique ID (Shape.UniqueID property), using the formula syntax below, in the ShapeSheet 'Value' cell for the property : 
    =UniqueID(visGetOrMakeGUID)   and =UniqueID(1)
But Visio does not recognize this as a valid Formula..

I also tried to use DATA1():
    =Guard(Data1())
That gives me a unique value BUT it does not update if you copy the shape.

I've dowloaded the 2007 SDK and can't find a Shapesheet function to read the properties.

I have also seen that you can set the page so UniqueIDs are always on shapes used but I can't figure out how to turn it on.

My "preference" is to use a Shape Data element and set it BUT......

Any Ideas would be appreciated?
Thanks ... Scott

JohnGoldsmith

Hello Scott,

UniqueIDs are only accessible in code, ie, there's no ShapeSheet function that'll return a unique ID (GUID) - is that what you're trying to do already?

By default a shape starts off without a UniqueID so you have to assign it in code.  Some shapes such as the off page connector shape store the unique IDs in the ShapeSheet so that they can track which shape is connected to which, but this is managed by an addon.

I'll jot down some sample code, but can you give a little more detail on what you're trying to achieve?

Best regards

John

Sub UniqueIDsDemo()

Dim vPag As Page
Set vPag = ActivePage

Dim vShp As Shape
Set vShp = vPag.DrawRectangle(1, 1, 1, 1)
Debug.Print vShp.NameID & " UniqueID = '" & vShp.UniqueID(visGetGUID) & "'"

Dim sGUID As String
sGUID = vShp.UniqueID(visGetOrMakeGUID)

Debug.Print vShp.NameID & " UniqueID = '" & vShp.UniqueID(visGetGUID) & "'"

vShp.AddSection visSectionUser
Dim rowIdx As Integer
Dim cellName As String
cellName = "UniqueID"
rowIdx = vShp.AddNamedRow(visSectionUser, cellName, visTagDefault)
vShp.CellsSRC(visSectionUser, rowIdx, visUserValue).FormulaU = sGUID

Debug.Print vShp.NameID & "!User." & cellName & " = '" & vShp.CellsU("User." & cellName).ResultStrU("") & "'"

End Sub

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

Scott Morrison

John,
Thanks for the help.
Actually I thought that was the case but I was hoping.
I'll give the code you sent a try.
Thanks again.
Scott ;)

Scott Morrison

John,
Thanks for the guidance.
The attached code shows what I did.
I created shape properties in (on) the Master:
    1) 'User.UniqueID'  ( set it with the code on add ) [vsoShape.UniqueID(visGetGUID)]
    2) 'Prop.Shape_Unique_ID' with a Value '=  GUARD(User.UniqueID)'

Situation
The process issue I'm experiencing now is that when I added the shape before the above code was implemented ' Private on Sub Document_ShapeAdded(ByVal Shape As IVShape) ' the  value on the Child Shape was changed from 'GUARD(User.UniqueID)' to the actual value of User.UniqueID'

So I had some 174 shapes that had a 'Prop.Shape_Unique_ID = 12846745gtrehu77654' instead of a Guarded reference to User.UniqueID ['GUARD(User.UniqueID)'].

So I wrote code to make the change on all Child shapes with the Master "CAP Process Step".
After running the code the 'User.UniqueID' is now referenced by
     'Prop.Shape_Unique_ID'
      So in the Shape sheet you see
               'Prop.Shape_Unique_ID =  GUARD(User.UniqueID)'
        instead of
               'Prop.Shape_Unique_ID =  12846745gtrehu77654'

Problem:
After running the code, chages to the Master are nolonger inherited by the children that were modified by the code.
I have confirmed with the attached code that the process shapes are still seen as associated to the the Master "CAP Process Step".

Any Ideas on what was triggered to stop the inheritance?
Thanks
Scott

===================================================================

I have included PNG's of the ShapeSheets and the shapes in a 7z zip file for both Shapes:
Shape Added from stencil, Shape Modified by Code.

Note: On the shapesheet there are two properties that used the GAURD function:
          "Shape Unique ID"
          "Assigned Page"

The value for "Assigned Page"  'GUARD(PAGENAME())' has always inherited form the master    correctly as expected

The value "Shape Unique ID" GUARD(User.UniqueID)'  did not


vojo

I may be off base...but I believe unique ID is document centric not world wide.   I think there is another type of ID that is WW unique if you want
to use that.

Of course, you create your own IDs thru various approaches.   Visio would leave them alone and they could probably be more readable
especially if you have VBA involved anyway.  Maybe some user friendly name || timestamp on drop.

JohnGoldsmith

Hello Scott,

From looking at your code, it looks like you're setting your Prop.Shape_Unique_ID cell for each instance shape, but this should be an inherited value that you can set once in the master.  The instances all have local values (because you've set them in code) and so those cells are no longer inheriting from the master.  You need to make sure you have the correct formula in your master that references the User cell, (ie Prop.Shape_Unique_ID GUARD(User.UniqueID)), and then only change the User.Unique cell values in the instance shapes.

If you need to reset inheritance in your instance shapes, just loop through them and set the formula to "=".

Let me know how you get on.

Best regards

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

JohnGoldsmith

@vojo - UniqueID is a GUID that, although theoretically not necessarily unique, can be regarded as unique.  This article has a good explanation on the uniqueness of GUIDs http://blogs.msdn.com/b/oldnewthing/archive/2008/06/27/8659071.aspx

I agree with the thrust of what you're saying though, GUIDs aren't always the best way to go for identifying shapes.

Best regards

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

Scott Morrison

Good Morning: John, Vojo,
The ID's I'm creating are only expected to be unique for a drawing Context.
They are being generated so that I can manage the Drawing and all its page in Excel.

So I also agree that the ID should not be used as a Glodal id.
And thanks for the Article reference it was good.

John,
I will try re-setting the formulas as you suggest.
But as you saw in the snapshots I sent what should I investigate if
the formula  'GUARD(User.UniqueID)' is not inherited correctly from the Master?


{ 'Prop.Shape_Unique_ID =  GUARD(User.UniqueID)' }


   

JohnGoldsmith

Hi Scott,

If a particular cell in your instance shape is not inheriting from the master then you can reset it by setting its formula to "=".

I'm not clear which is your instance shape image though.  Is 'ShapeSheet_ModifiedByCode.png' the problem one?  In that image it looks like the whole section has become local and I would want to investigate why that's happened.  Has a row been added to the instance shape (which would have the effect of making the entire section local)?  Either way setting the cell formula to "=" should work and you can do this in code or manually in the ShapeSheet.

Does that work for you?

Best regards

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

vojo

perhaps I am confusing NAME / NAMEU with this context....apologies

JohnGoldsmith

@vojo well you're quite right, there are lots of ways to identify shapes and Scott, if you don't have to use GUIDs and you're able to identify the document then storing the page ID along with the shape ID should get you to the same place.
John Goldsmith - Visio MVP
http://visualsignals.typepad.co.uk/