Selecting sub shape with right-click menu

Started by snuuba, December 06, 2016, 07:58:59 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

snuuba

Hi,

I have a master shape used for documenting networking switches. This master shape contains multiple sub shapes, one them is used for documenting switch port assignments. Port assignment data is within the shape data for the sub shape and can be manipulated in "Shape Data" window. My problem is that, sometimes it is hard to select sub shape manually and have data visible in "Shape Data" window.

I would like to add right-click menu action to master / top level shape, which would select the port assignment sub shape, so I can edit data in "Shape Data" window more easily

I already know how to add actions into right-click menu, but I am looking for action that would select a sub shape by name and display shape data for given shape in "Shape Data" window. Since the shapes are grouped together, I can always assign the same name for sub shape, so what I am really after is action something like: selectshape("Shapename").

I've already found examples in VBA, but I don't have any experience with VBA, so I am wondering if this could be achieved with one-liner without VBA?

Yacine

There's no possibility to do what you want with simple shapesheet functions, but you may consider other possibilities.

1) Make it easier to select the sub-shape.
a) Either make the sub-shapes to be selected first. To be set in the behaviour of the group. Or in the shapesheet: Section Group properties; Select mode = 2.
b) If the difficulties to select the subshapes come from to tiny shapes, the make sure to give them proper filled backgrounds.

2) Put the shape data of the subshape in the group shape and switch their visibility by means of an action row. (Main data / Special data)

3) Other options only with VBA, but with the disadvantage of having to carry the code with the shapes (in the doc or the stencil)
Yacine

snuuba

Quote from: Yacine on December 06, 2016, 12:21:08 PM
There's no possibility to do what you want with simple shapesheet functions, but you may consider other possibilities.

a) Either make the sub-shapes to be selected first. To be set in the behaviour of the group. Or in the shapesheet: Section Group properties; Select mode = 2.


Thanks, this made selection slightly easier.

It seems that I have to get familiar with VBA in order to get the exact behaviour I am looking for. I have written bunch of shell scripts, so I have don't problems with coding in general, but the object nature of VBA is bit difficult for me.

I did have a look at examples in : https://msdn.microsoft.com/en-us/library/office/ff767900.aspx

In the examples shapes are first created and array variable is populated with shapes. Then in different examples shapes are selected one by one in "For" loops. Do I have to use "For" loops to go trough all the sub shapes and then use "if" clause to match shape name and perform actions on that shape. Or can I somehow pass the shape name (SwitchPortAssignmentBoxDual24Port) or shape ID (1903) directly to "ActiveWindow.Selection.Select"?

Something like this: 
Public Sub Select_Example()

    Dim vsoShapes As Visio.Shape


    'Cancel the selection of all the shapes on the page.
    ActiveWindow.DeselectAll

     'Create a Selection object.
    Dim vsoSelection As Visio.Selection
    Set vsoSelection = ActiveWindow.Selection

    vsoSelection.Select "SwitchPortAssignmentBoxDual24Port", 2
   
End Sub

Thomas Winkel

Hi,

the following code does the job:

Sub selectSubShape(shp As Visio.Shape)
    Dim subShp As Visio.Shape
   
    For Each subShp In shp.Shapes
        If subShp.Name = "Data" Then
            ActiveWindow.Select subShp, visSubSelect
        End If
    Next subShp
End Sub


The attached document has three examples:
1. Your "right click" solution
2. Data in group, similar as suggest by Yacine in 2)
3. Direct selection of sub shape as suggested by Yacine 1a)

snuuba

Thomas,

Wow, thanks a million, exactly what I was looking for :).

It seems that sub shape has to be a direct sub shape for the shape that calls the VBA code. My original shape was nested with multiple groups and in this case VBA did not find sub-sub shape. But no problem, I can collapse the shapes into one group, so that the port assignment box is direct sub shape to group "parent" shape with right-click menu. Or maybe add another "for" loop

Also it seems VBA code does not "follow" if I just copy the shape to another document or even by adding VBA code directly to stencil containing the shape. I am using templates with my drawings anyway and can include the VBA code in the template, which seems to work.

Many new ideas pop into my mind, I see many sleepless nights a head of me :)

Thanks again, this site rocks!!

Snuuba

Thomas Winkel

No problem with subsubsubsub...shapes, you can do it recursive:

Sub selectSubShape(shp As Visio.Shape, typeID As String)
    Dim subShp As Visio.Shape
   
    For Each subShp In shp.Shapes
        If VShape.typeID(subShp) = typeID Then
            ActiveWindow.Select subShp, visSubSelect
            Exit Sub
        End If
        selectSubShape subShp, typeID
    Next subShp
End Sub

You should never have code in your documents or templates, only in the stencil.
With =CALLTHIS you can call code from any open VBA project.
Also it is not a good idea to identify a shape by its name.
Better create a user attribute and check its value.
All this is implemented in the attached stencil
The shape is protected from sub-shape selection, they can only accessed by context menu.

snuuba

Thanks again,

Yes, I agree that using names to identify shapes is not very elegant solution. My stencils would look whole lot different, if had known all that I know now :) I've used shape names directly quite a lot and changing it to id-based identification might take a while.

Using shape name based identification works reasonably well as long as you ungroup one group at a time. Shapes will break if you happen to ungroup two shapes of same type at the same time, as you cannot easily regroup shapes without breaking them.

However this solves another problem that I have. I've been looking for a way to hide cables in drawings. I experimented with layers, but that only works in Visio format. If I export drawing into PDF-format layer visibility information gets lost and cabling is visible regardless of layer visibility setting. If I use same ID string per cable type, I can toggle visibility by setting cable shape transparency to 100% and automate this by running similar piece of VBA code as used for selection.

Having VBA code within stencil is probably the right way to go. Code follows the shape and does not require specific template to be used. Downside in my use case is that I could share the code if it is in template. I have multiple stencils and updating code might take more time, if same piece of code is in different stencils.

Thomas Winkel

Hi,

layers are a good way to hide shapes.
In order to hide them in Visio as well as in PDF exports and on print-outs you also have to set layer print attribute accordingly.
Here a code snippet from my project.

If a.active Then
    pge.Layers(a.name).CellsC(visLayerVisible).Formula = "1"
    pge.Layers(a.name).CellsC(visLayerPrint).FormulaU = "1"
    pge.Layers(a.name).CellsC(visLayerLock).FormulaU = "0"
Else
    pge.Layers(a.name).CellsC(visLayerVisible).Formula = "0"
    pge.Layers(a.name).CellsC(visLayerPrint).FormulaU = "0"
    pge.Layers(a.name).CellsC(visLayerLock).FormulaU = "1"
End If

See all the possible layer attributes in the "Layer Properties" window.

The code does not have to be in the same stencil as a calling shape was dropped from.
We habe like 10 stencils, but only one with code.
The stencils are distributed to our users via SVN.
With "SVN-Notifier" they are always up to date.
Code in the template is a problem because then you have a complete copy with each document.
This end up in chaos.

vojo

FWIW (and that might not be very much), I did hide/show a couple of different ways

Basically, you can:
  1)  play with width/height of shape....something like  guard(if(<trigger>, width=0, width = <nominal value>))
  2)  On any geometry, you can set the show/hide cell

So at a group level, you can have action cells that can enable either show hide behavior

actionX  = setf(getref(action.checked), if(action.checked, 0,1))

trigger = if (actionX.checked, true, false)

Use trigger as above

I if I remember, the first way (dimension = 0) worked better in 2003....
I think there was some sort of artifact with second way of doing it
(it might be that the "shape ghost" aka the selection box was still in play....which still made selections tough)

At any rate, while perhaps not as slick as other ways, it worked well for me.

snuuba

Quote from: Thomas Winkel on December 07, 2016, 10:05:38 AM
Hi,
layers are a good way to hide shapes.
In order to hide them in Visio as well as in PDF exports and on print-outs you also have to set layer print attribute accordingly.

I stand corrected :) In my experiment with layers I toggled only "Visible" setting for the layer, not "Print" setting. By deselecting "Print" setting the layer was not visible in PDF-files.

I think that I will still explore hiding items with "transparency" setting. This will give more fine-grained control over visibility. I can select one shape and hide type of cables in that shape, while keeping the same type of cables visible in other shapes which are on the same Visio page. With layers the scope seems to be page, if I hide a layer which contains certain type of cables, all shapes using this layer on the same page will be hidden. Or can I toggle layer visibility per shape?

Show/hide cell works if the object is a visio geometry / shape, but not with imported bitmap images. In my stencils I have shape which contains company logos as bitmap images, based on which company is chosen, only logo for that company is shown ( transparency setting = 0%), while the other logos/images are hidden by setting image transparency to 100%.

Thomas Winkel

#10
No, a layer is unique for the page.
You could have many layers or change the layer membership of a shape with code.
The big advantage with shapesheet settings over layers is, that this can be done without code, only with formulas.

Have a look at this article:
http://www.visguy.com/2006/09/05/the-hidden-world-of-visio-shapes/

Edit:
Also layer membership and layer settings can be done in ShapeSheet.
Section "Layer Membership" in ShapeSheet and Section "Layers" in page ShapeSeet.
Cool, didn't know that...

vojo

in visio 2013, transparency has a bug that makes it difficult to use

Select a group, try transparency....it first set all shapes to default color then transparency
Transparency defaults to everything ...so need to reformat either line or fill as needed

Only work around I found is to go in and transparent each shape fill and border

Just another in the list of reasons why visio 2003 is better than visio 2013  ;-)  (up to 8 so far)

vojo

show/hide pictures ==> play with width/height settings (see above).

If you want the user to also be able to resize....look at setatref commands