Visio Guy

Visio Discussions => Programming & Code => Topic started by: maclarkson on September 02, 2019, 10:20:28 PM

Title: Simple VBA question
Post by: maclarkson on September 02, 2019, 10:20:28 PM
Hi all,

I am a bit of a newb to programming.

I have a data field that is populated from an excelsheet called prop.objectname in the shapes sheet. Is there a way to update the shapes text with this value when the object is either linked to its data or the linked data is refreshed.

Many thanks in advanced
Title: Re: Simple VBA question
Post by: dpetrov on September 03, 2019, 06:41:47 AM
Hi mate,

if get this right, you want to populate diagram changes with information provided by excel (e.g. changing hostnames of device). If this is the case - you don't even need programming. One way of doing it is to use Shape data for device naming. So when you're to name a device, use the [field] (from Insert -> Field) and then use the hostname property from the shape data. This way as soon as you import the new table the shape name will change (you'll still have to have some unique indexes such as ShapeKey, etc).

Hope this makes sense and answers your question.
Title: Re: Simple VBA question
Post by: maclarkson on September 04, 2019, 10:22:18 AM
I know about inserting fields, but this is not what I need to do. I want to specifically change the shape text.
Title: Re: Simple VBA question
Post by: vojo on September 04, 2019, 11:58:31 AM
To show it...got to insert it
Title: Re: Simple VBA question
Post by: Nikolay on September 04, 2019, 12:20:59 PM
There is an option in my old BackSync extension (http://unmanagedvisio.com/products/visio-back-sync/) to set shape text form shape data (also ShapeSheet formulas, if needed, like "PinX" or "Fill")
You could try if it still works :D

(https://i.paste.pics/6LRY7.png)
Title: Re: Simple VBA question
Post by: maclarkson on September 04, 2019, 01:19:56 PM
hay Nicolay,

I installed your addin a while ago and ts an excellent little adding. I would love to have a go at building something like that. would you be interested in starting up an open source project with me?

I am an Enterprise architect and I have using visio, Aris, Orbus, Mega and a whole heap of other tools. They are extremely expensive.

I have been working on a project to sync a database with visio in a similar fashion to Orbus and I would like to do something similar. The way these tools work is they are extremely simple. There are two tables. An object table and a relationships\connectors table. the connectors table just records all of the relationships between objects using a unique ID.

Here is the scenario for MVP:
1) I start a new diagram I can A) create objects from linked data (this can currently be achieved using the visio pro data connection functionality, if we create something different to do this potentially we can solve peoples problem of having to get a pro version of visio) or B) create new objects and these would be added to the database (this i currently cannot do)
2) I would then connect up the objects, and the connections would automatically be synchronised to the database.

Stretch goals:
1) ability to search the database for an object before adding it to a diagram
2) if the user created a connection in the database between two objects it would be good if i could take the two connected objects, throw them on to a page and then autoapply the connectors.
3) if a user tried to connect two objects up which had already been connected before the user would be prompted with a message
4) if a user tried to create an object that already was already existing it would prompt the user with a message

Would this be hard to do given your expertise?

Thanks

Mike

Title: Re: Simple VBA question
Post by: maclarkson on September 04, 2019, 01:24:57 PM
To my original question.

Can someone please please please just tell me whether it is possible to change the shape text to match up with the data from another Prop. field? and if so how?
Title: Re: Simple VBA question
Post by: maclarkson on September 04, 2019, 01:27:44 PM
Quote from: vojo on September 04, 2019, 11:58:31 AM
To show it...got to insert it

I actually want the text to be hidden as the text I will be simply holding a database unique id.
Title: Re: Simple VBA question
Post by: wapperdude on September 04, 2019, 01:28:25 PM
There's a bit of confusion here.  An example would work wonders.  What do you mean "match up"?

The interpretation is that the prop.field is the text being displayed.  Hence, the insert > field responses. 

But it sounds like what your saying is that if prop.A = value A, then show shapetext = prop.value1, if prop.A = value B, then show prop.value2.

Is that what you're after?
Title: Re: Simple VBA question
Post by: Nikolay on September 04, 2019, 03:10:28 PM
Quote from: maclarkson on September 04, 2019, 01:24:57 PM
Can someone please please please just tell me whether it is possible to change the shape text to match up with the data from another Prop. field? and if so how?

It is possible only programmatically (shape.Text = "FOO"). For ShapeSheet formulas, shape text is available as read-only.
The mentioned extension does just that - populates the shape.Text propery from a given Prop. column (if this is enabled in the settings).

The extension is very basic; it relies on Visio data infrastructure.
It does not assume any automatic diagram generation from data actually, and I don't see any possibility for this in the scope of the extension.
Title: Re: Simple VBA question
Post by: maclarkson on September 04, 2019, 08:54:00 PM
The field name is Prop.objectid

The value of this id comes from the data that is supplied from an excel sheet. I basically want

shape.text=Prop.objectid

I then want the shape.text to be hidden and guarded from being changed.
Title: Re: Simple VBA question
Post by: wapperdude on September 04, 2019, 10:06:00 PM
Requires 3 steps.
1) as per Vojo, Insert>Field>Shape Data and pick your entry
2) to hide, open shapesheet, scroll to Misc Section, and set Hide Text = 1
3) to protect scroll to Protection section, set LockTextEdit = 1
4) to protect, scroll to Text Fields section, put guard wrapper around formula in Value cell.  Note, this section only appears after field insert of step1 was done.

That's it

Wapperdude
Title: Re: Simple VBA question
Post by: maclarkson on September 05, 2019, 11:12:05 AM
I have written this piece of code which I use to record against the connector the objects connect from and to. At the moment it will give me the text name it came from and the text name it goes to. ShpFrom.text and shpTo.text, but I don't want the text I want the objectID (prop.objectID). Either i change the text on the object or I could directly access the ObjectID. How do I rewrite the code to do this?

Sub GetFlowchartConnections()
' Gets text from shapes connected at each end of every line on page
' Stores text in two shape data fields on each line

    Dim pg As Visio.Page
    Dim shp As Visio.shape
    Dim cnxEndPoints As Visio.Connects
    Dim EP As Visio.Connect
    Dim shpFrom As Visio.shape
    Dim shpTo As Visio.shape
   
    For Each pg In ActiveDocument.Pages
        For Each shp In pg.Shapes
            Call InitFromTo(shp)
           
            ' BeginX only exists if shape is a line
            If shp.CellExists("BeginX", False) Then
                'Get connects collection for current shape
                Set cnxEndPoints = shp.Connects
               
                If cnxEndPoints.Count > 0 Then
                    For i = 1 To cnxEndPoints.Count
                        Set EP = cnxEndPoints(i)
                        If EP.FromPart = visBegin Then
                            ' Get shape this end is attached to
                            Set shpFrom = EP.ToSheet
                            ' Store attached shape's text
                            shp.CellsU("Prop.From").FormulaU = Chr(34) & shpFrom.Text & Chr(34)
                        Else
                            ' Get shape this end is attached to
                            Set shpTo = EP.ToSheet
                            ' Store attached shape's text
                            shp.CellsU("Prop.To").FormulaU = Chr(34) & shpTo.Text & Chr(34)
                        End If
                    Next
                End If
            End If
        Next
    Next

End Sub
Title: Re: Simple VBA question
Post by: maclarkson on September 05, 2019, 11:19:07 AM
Actually this code came from one of these forums. I just altered it but I need to alter it a bit more.
Title: Re: Simple VBA question
Post by: wapperdude on September 05, 2019, 01:11:41 PM
Should be able to change shpFrom.Text to shpFrom.ID.  Same with the other variable.
Title: Re: Simple VBA question
Post by: maclarkson on September 06, 2019, 09:43:59 PM
I tried that but the ID is the ID from the shape. The shape ID is only unique to sheet. I want the prop.objectID from the shape which is the one from the database. This one is unique
Title: Re: Simple VBA question
Post by: wapperdude on September 06, 2019, 10:42:17 PM
This is all very confusing.  A simple example would help clarify things.  Do the shpFrom and shpTo have the prop.objectID?

If so, you can assign the shapetext as explained before, to have this ID.  But, why do that?  You hide the text anyway.  If this is for a connectivity report, isn't the info in the Excel file already?  You can make a custom report, if that's the goal, just by accessing the prop.objectID value directly from the shape, and not mess around with all this shapetext stuff.

So, a picture or Visio file showing what you want, at this point, will (ought to ) clarify what you your trying to accomplish.

Title: Re: Simple VBA question
Post by: maclarkson on September 07, 2019, 09:53:42 AM
I have attached an example.
If you click the report icon you will see it creates an excel report that tells you which app is connected to the other. If you copy and connect up to another object you will notice it creates a new row for each connector. It uses the shpfrom.text to grab the app text. Change this to shpfrom.id and it will use the ID. I do not want either of these. Now connect up the attached register. I want the ID that is in the Attached register to be the from and to ID's not the ID from the shape. I was then going to connect up the connectors with the sheet two so that I now have a record in the excel sheet of what is being connected to what.
Title: Re: Simple VBA question
Post by: wapperdude on September 07, 2019, 02:07:03 PM
I see a major problem... the shapes, e.g., App1, do not have any shape data, certainly not Prop.ObjectID.  Why do you mention this?  It doesn't exist?

So, you have two options for your project...
A)  When the code finds a connected shape, either a From or To, then, use that shape's text to search the Excel file for matching AppName, and then grab the corresponding ObjectID.  Two more choices
      I.) take the ObjectID and stuff it directly into your new report, or
     II.) take the ObjectID and stuff it into the appropriate Prop.To or Prop.From value cell of the connector.

B) When the "App(whatever)" is added to the shape, create a Prop.ObjectID and add the correct value.  Then, when the connector finds an attached shape, check to see if Prop.ObjectID exists.  IF so, grab it's value and place into the appropriate connector value cell.  If the Prop.ObjectID doesn't exist, ignore. 

Note, once the Prop.ObjectID has been added, I believe the built-in Reports function can be configured to yield the desired info without resorting to custom code.


Title: Re: Simple VBA question
Post by: maclarkson on September 07, 2019, 09:05:03 PM
Sorry I attached the wrong document

Check now you will see that I have connected up the data and it has a prop.objectID
Title: Re: Simple VBA question
Post by: wapperdude on September 07, 2019, 11:41:32 PM
You need to change the two shpText lines to be as follows:
   shp.CellsU("Prop.From").FormulaU = shpFrom.CellsU("Prop.ObjectID").ResultStr(visNone)
   shp.CellsU("Prop.To").FormulaU = shpTo.CellsU("Prop.ObjectID").ResultStr(visNone)

This will put the desired values in the connector From/To value cells. 

It doesnot address changing the "App1" or "App 2" labels if desired.  See this post  http://visguy.com/vgforum/index.php?topic=7638.0 (http://visguy.com/vgforum/index.php?topic=7638.0)

Title: Re: Simple VBA question
Post by: maclarkson on September 08, 2019, 09:08:52 PM
Hay that's awesome and it worked a treat so I tried to apply it an extra row of data

shp.CellsU("Prop.FromName").FormulaU = shpFrom.CellsU("Prop._VisDM_AppName").ResultStr(visNone)
shp.CellsU("Prop.ToName").FormulaU = shpTo.CellsU("Prop._VisDM_AppName").ResultStr(visNone)

But now I get a debug error.
Title: Re: Simple VBA question
Post by: wapperdude on September 08, 2019, 09:54:25 PM
When you use the CellsU method couple of things...
1) obviously, the cell has to already exist.
2) what's inside the quotes is taken literally.  That applies to Upper/Lower case and spelling.  It literally has to be the exact name as shown in the shapesheet.
Title: Re: Simple VBA question
Post by: maclarkson on September 09, 2019, 12:28:04 AM
I checked the case and the spelling and for the life of me could still not find the problem.

I will remove the report function eventually and I will just want to run the code to update the cell contents. Is there line of code I can add in to trigger the update each time I change something.

Title: Re: Simple VBA question
Post by: wapperdude on September 09, 2019, 04:25:51 PM
I can confirm and reproduce the error.  So, you're not going crazy.  But, for now, I have no explanation.
Title: Re: Simple VBA question
Post by: wapperdude on September 09, 2019, 10:42:21 PM
This syntax works: shp.CellsU("Prop.FromName").Formula = Chr(34) & shpFrom.CellsU("Prop._VisDM_AppName").ResultStr(visNone) & Chr(34)

Title: Re: Simple VBA question
Post by: maclarkson on September 10, 2019, 10:49:24 AM
Awesome! By the way? what does the chr(34) do?
Title: Re: Simple VBA question
Post by: wapperdude on September 10, 2019, 12:59:25 PM
Chr(34) is the dbl quote.  But, avoids having to use many, multiple dbl quotes in a row.

I believe Visio Guy had an article about it on his website.