Everyone:
It’s taken me a while to find the time to follow up on all your suggestions, then wrestle with them to reach a solution that fits my goals. It’s been a very fruitful exercise, and I now have what I need and more. However, I did run into what appears to be an insurmountable problem in one scenario.
My goal was to be able to deploy not only the initial masters and associated macros, but to keep them up to date without user intervention. Until I had encountered this thread, I had never considered using the stencil as the code repository—didn’t even know it was possible! But once I began thinking of the stencil as central, a whole bunch of possibilities opened up. Thanks for pointing me in the right direction.
Rather than defining sinks, classes, imports, and templates, I started instead with the existing Document Opened event in the stencil itself, and built outward from there. Here’s an outline of how it works:
1. All actions are based on the existence of TheDoc!User.Flag in the active document.
2. When opening the stencil, check to see if the Flag exists.
2a. If the Flag does NOT exist, then this document is not one that already utilizes the stencil’s functionality, so throw out a message box asking if the user wants to utilize it.
2.a.1. If they DON’T want to, create the Flag and set it to zero.
2.a.2. If they DO want to, create the Flag and set it to the stencil’s version number, then go about the various first-time initializations the stencil’s functionality requires.
2b. If the Flag DOES exist, and if it’s set to zero, the user has previously declined to use the stencil’s functionality, so turn everything off such that the stencil’s existence becomes transparent to the user.
2c. If the Flag DOES exist and it’s set to the current version number, the user has previously agreed and everything is up-to-date. Just turn on the stencil’s functionality and leave it at that.
2d. If the Flag DOES exist and it’s NOT the current version number, perform whatever upgrade tasks are necessary to bring the user document up to speed, then set the Flag to the new version number.
3. Each shape has CALLTHIS in its EventDrop formula that invokes the necessary functionality in the stencil, and upgrades the shape if necessary. Of course if the stencil hasn’t been opened, CALLTHIS calls nothing, so the stencil shapes can be used freely anywhere, only without the stencil’s functionality.
What I like about this approach is that I can just send out the new stencil and ask the users to simply open it; everything else is automatic. Each master and shape is similarly flagged with version numbers such that I can tell what upgrades are needed to existing shapes, if any. Using a template would require users to migrate existing drawings to the new template (and we all know how well trained users are when it comes to things like that!), but the auto-upgrade facility allows them to continue using their existing .vsd files. It also allows advanced users to create and maintain their own macros without worrying about the stencil getting in the way.
All well and good, BUT… there is one problem. For the first-time user, I thought it would be easiest if they just double clicked on the stencil.vss and have it initialize a new, blank document complete with all stencil functionality enabled. No such luck.
The stencil’s Document Opened event fires as expected, but that’s where all expectations went out the window. In no particular order, here’s how things went sour:
1. While it’s easy to dock a stencil to an existing document, I could not figure out how to dock a new document to an existing stencil. If you do this from the stencil…
Set TheDocument = Application.Documents.AddEx("", , visAddDocked)
…it does not dock.
2. If you subsequently open a copy of the stencil as follows…
Set TheStencil = Application.Documents.OpenEx(CurDir & "\" & Doc.Name, visOpenRW + visOpenDocked + visOpenCopy + visAddStencil)
…it DOES dock to the new document, and even asks if you want to enable macros. But no matter what I did, I could not get the stencil copy to execute any macro at all, not even its own Document Opened event.
3. I forgot to mention that the stencil initially opens up in a small window. If you maximize it using the user32 function ShowWindow, it maximizes to a window larger than the monitor and smothers the command bar at the bottom. Adding insult to injury, alt-tab does not select the next application’s window; Visio is always on top. Worse yet, Visio’s maximize box at the top right is grayed out, so you can’t manually maximize it, nor can you X out of the document. All you can do is minimize or close the entire Visio window, which is a handy necessity because the stencil window sits on top of everything, thereby precluding access to all other open applications. I could not devise a way to overcome any of these problems.
In the end I threw in the towel and added a test to see if the stencil is the only open document. If it is, I put up a message box saying you have to have a document open first, THEN open the stencil. Sheesh. How unprofessional. But at least it is a workaround.
Any ideas where I might have gone wrong? I’m running 32-bit Visio professional 2010 under Windows 8. A test stencil is attached. There’s a Stop in the Document Opened event because sometimes if you just let it run, Visio crashes. What a mess!
Thanks,
- Ken