Master Formula Chain

Started by LostTime77, January 22, 2022, 03:01:10 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

LostTime77

I have been banging my head against the wall for awhile now. Searching various things does not seem to come up with a result. Maybe this is a dumb question and the answer is already available.

What I am trying to do:

I am trying to create multiple masters using shared global data. For example, setting the global shared data in the user cells of the document shapesheet or elsewhere. Then within the masters, using those cells. I then can have a ton of shapes that are based on several masters, but there is common data being used for formatting, such as geometry distances, line widths, etc.. When I want to make a change to the global data, the intention is to change the value and then have all the masters and shapes based on the masters updated all at once automatically.

The issue(s) I am having:

  • Placing the global data within the document shapesheet feels wrong, but whatever. There doesn't seem to be a better way.
  • Within a master's shape sheet, I am using a bunch of formulas based on the global data cells. After I save the master and drag a new shape onto the page, I then try and change a global data value and the shape on the page does NOT update based on the new value. I then go and view the inherited shape sheet formulas within the said shape and find that they are in fact correct, referencing the correct cells. Visio seems to not want to update a formula chain based on the global cell data with a length more than 1. It seems that if I put a global cell reference directly into a cell creating a dependency chain of 1 formula, things update correctly when the global data changes. If I click on one of the inherited problem cells (black), then press enter to force a local update of the formula, the correct value pops into the cell and changes to the global data work as expected. Its almost as if the inherited values need to be "seeded" first by forcing a local update.

Examples:

  • User.test defined in the document shapesheet
  • master object just containing a rectangle. Call this rect

Example 1:

  • rect.Width = TheDoc!User.test
  • Update User.test in document shapesheet

Works - A shape is created from the master and the width changes in the shapesheet AND on the page drawing window

Example 2:

  • User.t defined in rect
  • rect.User.t = TheDoc!User.test
  • rect.Width = User.t
  • Update User.test in document shapesheet

Does not work - A shape is created from the master. The width does not change in the shapesheet OR the page drawing window. Here's the kicker. rect.User.t still contains the correct formula AND so does rect.Width. Both cells are black. Changing the document level value User.test updates rect.User.T and the update IS seen in the shapesheet window. However, rect.Width does not update. Clicking on either rect.Width OR rect.User.t and pressing enter to force them to become local seems to cause both cells to now update together properly.

What exactly am I missing here? I am illustrating the issue with the simplest example. Obviously, I need to make some more complex shapes, but I want the global data to update correctly. Also, I did try using the document level globals with every combination of using either shape data or User cells in addition to trying those combinations on the master. I then tried it instead using page level globals in the document and changing the syntax to globally reference the page. All combinations lead to the behavior in example 2.

Croc

A similar situation is discussed in the article https://visioport.ru/blog/index.php/34-thedocref
The article is in Russian, but it can be read via translate.google.com
At the end there are conclusions:
1. When developing stencils, you should be very careful when using inheritance chains (several consecutive links in formulas), they may not work.
2. For long chains, it is desirable to provide for the translation of inherited formulas into local ones. This can be built into the design of shapes, for example using SETF in the EventDrop event, or using programmatic methods.

LostTime77

Humbug. I did actually happen upon the Russian thread you are referencing, but my example / use case was slightly different. I only skimmed that thread.

Guess it's back to making an addin. From what I have found, the issue does not seem to be present when using local data that is all present in the master. For example, if I define a constant in the master (say 5in) then use that cell in a chain within the same master, things seem to work fine. If I update the original constant in the master, everything propagates through the chain all the way to the shapes in the document. Take note though that I don't think I have a need for long chains. I have only tested with chains of about 3 or 4 in length. Realistically my chains will be a maximum of 2 or 3. Now, for some reason when the original constant is within another page or the doc shape sheet, used as the first cell in the chain, the chain stops the update after the first cell. It seems maybe there is a bug with non local data.

Alas, my intention is to be able to build master shapes that use global constants. When I update those constants, all the masters and shapes based on those masters will update. I had a few ideas to get by the limitations such as macros or an addin. I really hate VBA with a passion. Not so much the language though! The fact MS has been dragging along this old editor and not supporting a modernization effort for 2 decades. Then citing "We will be keeping VBA for a long time yet, because lots of people use it and everybody knows it." Guys, you are contradicting yourselves.

Anyhow, what I will be doing is developing an addin. It will exist as a ribbon button. The only thing it does is when you click it, it brings up an input dialog. You input a shape sheet property you want to change and its new value. That's it. The addin then iterates through all the masters and sets that property to the new value. This way I can develop all the masters with local properties of the same name and update all the properties at once as if they were global constants. Since visio seems to like local data in the masters, this should work fine. I ran some initial tests doing it with a VBA macro and some hardcoded values to test it quickly, and everything works.

wapperdude

#3
Out of curiousity, I cobbled together the attached file.  It is by no means a complete nor exhaustive study wrt nesting grouped shapes and using variables defined at the Document level.  But, it does provide a base from which to explore.

Group construction:  there are two methods to create a group.  1) select a bunch of shapes and group them, and 2) select a shape, convert to group and then add shapes to the group.  For this file, the 2nd approach was chosen.  Once a basic group structure was created, it was then dupliccated.  Then, the 1st group was added to the 2nd group, and so on.  I stopped with 4 nestings giving an equivalent of 5 levels.  Within a group, User section was introduced to hold a variable.  Depending upon the desired dependency, the variable might look at the parent shape, and, typically, the parent shape might either look at the page or the document.  Entries are either true or false.  These displayed in the shapes.  In some cases, I made the fillcolor reflect the status of the User variable.  Just enough to demonstrate functionality.

The placements may be either copy/paste or drag and drop from either a Custom defined stencil or the Document stencil.  The only behavior anomaly shown was with the drag and drop method when Document based variables were referenced.  For copy and paste, the Document based behavior was properly functioning.  In all cases, if you open the Doc shapesheet, you can see the User variable value change, but the drag and drop shapes just don't update.  I did not pursue this any further.

Enjoy.
Visio 2019 Pro

wapperdude

#4
Ok.  bit of update.
Open the shapesheet for the group master shape.  Scroll to the FillForegnd entry.  As you double click the, uh, double click shape, the FillForegnd entry actually does toggle.  But, the shape itself doesnot update it's fill. As configured, the FillForegnd cell checks the User defined variable, and sets the color using an IF statement.  It appears, that if the IF statement is moved to the User entry, and then using SETF(GETREF()) construct to push a value into the FillForegnd cell DOES preserve the DOC variable functionality for Drag N Drop.

The User cell formula becomes:  =TheDoc!User.docVar+IF(TheDoc!User.docVar,SETF(GetRef(FillForegnd),4),SETF(GetRef(FillForegnd),2))

The 1st part of entry allows other cells to read, the 2nd part pushes value into the FillForegnd cell.
Visio 2019 Pro

wapperdude

#5
Attached is slightly different variation of previous file.  The top level parent of the nested groups may be double clicked to open the shape data window.  This allows entry of new values into the Document shapesheet, including text.  Note, manual/GUI text entry will clobber the functionality of this shape.

Drag N Drop still works.
Visio 2019 Pro

LostTime77

I highly appreciate you digging into this. I am always amazed by good people and how they either truly try to investigate or do a bunch of leg work for others.

However, I just spent a few hours making an addin using VS and C# that does exactly what I want. Basically on any master shape you can send a queue marker event which gets picked up by the addin. So drop a shape into the document from a master and you get an action menu. The event formula is such that it passes the page name and id of the currently selected shape. Then the plugin looks for all cells in the user property section with a g_ prefix. It then pulls those properties out into a list and a WPF window is created with a datagrid. You can then modify the values of those constants. Once you click "OK" on the window, the code iterates through every master in the document. It then finds the corresponding document shape within the master and updates all of the user cells from the datagrid with the new values.

This allows all the masters to use local user cells for their formulas and all the g_ prefixed properties will be updated at once by the addin. Tested and works very well.

wapperdude

I was aware  of your attention to develop code, but my curiosity took over.  I would agree with doing a code solution based upon the scope of your task.  That was pretty fast development.
Visio 2019 Pro

LostTime77

#8
Code is pretty simple. Here is the VS solution if anyone is interested. Code is literally provided as is. First time doing an add in. Make sure not to run the solution unless you want the plugin installed. If it installs you can remove it in the developer tab through the com add ins. Additionally in the startup routine there is a line that when commented out opens up a test document on my machine, so I didn't have to keep manually opening a doc every debug session. Change it to the proper path if you want it to open a doc on debug.

(Don't care if you know my first name. Can't be bothered to make it fancier to hide my name)

Latest stuff:

  • VS Community 2022
  • Visio 2021