Visio Guy

Visio Discussions => Programming & Code => Topic started by: ExcelMVP on January 02, 2013, 12:30:52 PM

Title: Add new shape at certain position in visio page
Post by: ExcelMVP on January 02, 2013, 12:30:52 PM
Hey , Thanks for looking into my query

just wondering what will be a VBA code to add new shape(say rectangle) on Visio page at certain position of the Visio page. I actually want to create a dynamic legend based on the color of the shapes, so would want to add the shape somewhere at the bottom of the sheet.

Many thanks.

Title: Re: Add new shape at certain position in visio page
Post by: Paul Herber on January 02, 2013, 12:49:39 PM
The drop method
http://msdn.microsoft.com/en-us/library/office/ms195970(v=office.12).aspx
has parameters for the X and Y location.
Title: Re: Add new shape at certain position in visio page
Post by: ExcelMVP on January 02, 2013, 01:22:41 PM
Thanks Paul, It was really helpful

cheers.
Title: Re: Add new shape at certain position in visio page
Post by: Michelle on January 03, 2013, 03:49:39 PM
I was wondering something very similar...
Just out of curiosity, can I control the location of a shape placed via VBA in relation to another shape just placed on the page?  I have a shape that uses a Macro to place another shape once it is placed.  I'd love to be able to have VBA place that "automatic" shape in close proximity to the original shape just placed.  (rather than the predetermined spot which is the same each time I place that original shape resulting in several of these "second" shapes right on top of each other in that location)

If there is a solution for this, please (for me) "dumb down" your answer, as I am easily confused, LOL  ;)

Michelle
Title: Re: Add new shape at certain position in visio page
Post by: Jumpy on January 04, 2013, 07:17:06 AM
As stated in the other thread: Use CALLTHIS instead of RUNMACRO.

A macro that you start with CALLTHIS has to be sligthly different than one started with RUNMACRO, because with CALLTHIS you automatically get a referece to the calling shape in the code:

Sub MyMacro(shp as Visio.Shape)
' Do sth.
End Sub

For your example/problem with the placing of a new shape relative to the old/calling shape:

Sub MyMacro(shp as Visio.Shape)
  Dim newshp as Shape
  Const xoffset=10
  Const yoffset=0
  'Do something that results in the newshape droped somewhere on the page
  'Now you can place the new shape relative to the old shape:

  newshp.Cells("PinX").Result("mm") = shp.Cells("PinX").Result("mm") + xoffset
  newshp.Cells("PinY").Result("mm") = shp.Cells("PinY").Result("mm") + yoffset
End Sub

Title: Re: Add new shape at certain position in visio page
Post by: contact_ankit86 on January 09, 2013, 05:32:10 AM
Hi,

I had a very similar problem. I want to drop a shape on the chart and connect it with another shape. I am able to copy a shape, do some modifications and paste the shape on a chart. it also gets connected the way i want to. the only problem is that the new sahpe gets pasted on any other shape. In other words it gets overlapped with other shape. Chart is all dynamic so will not be knowing the PINX and PINY where the new shape needs to be placed. even if i add some constant value to existing shapes PINX and PINY, i will not be knowing if thers already a shape at that position.

Is there any way by which i can find the empty/ vacant place on the chart so that the new shape gets pasted there and connected to another shape.

Title: Re: Add new shape at certain position in visio page
Post by: Jumpy on January 09, 2013, 07:17:42 AM
When the shape is posted, you can see if it's overlapping another shape and reposition at again.
There are functions ot the shape object in Visio like DistanceFrom or SpatialNeighbours that you could use for that.
Title: Re: Add new shape at certain position in visio page
Post by: contact_ankit86 on January 09, 2013, 11:38:38 AM
Thanks Jumpy.. It helped..!! SpatialNeighbours did not work but got an idea from this function..!!

Cheers  ;)
Title: Re: Add new shape at certain position in visio page
Post by: vojo on January 09, 2013, 05:38:08 PM
I did something like this a few years back....as I recall, the functions I found in visio did not seem work
(very poor precision...based on my experience, visio must use some other hidden functions support autoroute et al tasks and such).
I ended up creating my own distancefrom / spatial neighbor functions
Title: Re: Add new shape at certain position in visio page
Post by: Michelle on January 16, 2013, 09:54:50 PM
Hey Jumpy,

I wanted to refer back to your reply to me... I wasn't able to try it out then, but now the issue has come up again, so I need to try it now.

The first Code sample you show... is that what I need to add to the beginning of my macro to make it work with the CALLTHIS function?  Or can I just use CALLTHIS instead of RUNMACRO leaving everything else the same? 

The second Code example... Is this a macro I create and then call in the EventDrop cell of the shape that is brought in automatically vis the macro?  The code confuses me, how does it know which shape to place it near?  I don't need this to be precise, I just need the shapes to reliably place near each other no matter where on the drawing page I place the first one....

Any help is greatly appreciated!
Michelle
Title: Re: Add new shape at certain position in visio page
Post by: Jumpy on January 17, 2013, 08:30:02 AM
Quote from: Michelle on January 16, 2013, 09:54:50 PM
The first Code sample you show... is that what I need to add to the beginning of my macro to make it work with the CALLTHIS function?  Or can I just use CALLTHIS instead of RUNMACRO leaving everything else the same? 
Yes. A macro that is called with Callthis, has to have the (shp as Visio.Shape) part. A variable for a Shape object.
The name u use doesn't matter, so you could for example write (myShape as Visio.Shape), too.
Inside the macro that variable shp represents the shape that started this macro, so if for example you place Callthis in EventDrop cell, shp represents the Shape that you just droped on the page.

Quote
The second Code example... Is this a macro I create and then call in the EventDrop cell of the shape that is brought in automatically vis the macro?  The code confuses me, how does it know which shape to place it near?  I don't need this to be precise, I just need the shapes to reliably place near each other no matter where on the drawing page I place the first one....

shp is a shape you just placed on the shape (was it in your case photo device or sth.?).
With shp.cells("PinX").Result("mm") and shp.Cells("PinY").Result("mm") you know the position of your shape in mm.
Know the macro drops the new shape, that you wan't to place near the old shape. How to select a mastershape and drop a shape is explained somewhere in this forum, I'd bet.
The only thing that remains is to place the new shape near the old shape, in my example above via:

newshp.Cells("PinX").Result("mm") = shp.Cells("PinX").Result("mm") + xoffset
newshp.Cells("PinY").Result("mm") = shp.Cells("PinY").Result("mm") + yoffset

where xoffset and yoffset are constants that define where to position the newshape in relation to the oldshape.


In Essence: I react to the first shape droped (the foto devide) and that code drops and places the second shape (the lens device).

---------
I don't want to confuse you but the best way to do this (without using a smart shape) would be to use the code above, but additionally add an information of the newshape (for example the ID) somewhere in the shapesheet of the oldshape.
If you know change the property in the oldshape, that defined what a shape has to be near the old shape, you can call a macro again wiht Callthis and DEPENSON that first deletes the former newshape (find it with the ID stored somewhere in the old shape) and know drops another differnet newshape near your oldshape and stores it's ID in the oldshape again.


Title: Re: Add new shape at certain position in visio page
Post by: Michelle on January 17, 2013, 02:25:17 PM
OK, I am going to try what you are telling me, but I am very intrigued by your last paragraph...

QuoteI don't want to confuse you but the best way to do this (without using a smart shape) would be to use the code above, but additionally add an information of the newshape (for example the ID) somewhere in the shapesheet of the oldshape.
If you know change the property in the oldshape, that defined what a shape has to be near the old shape, you can call a macro again wiht Callthis and DEPENSON that first deletes the former newshape (find it with the ID stored somewhere in the old shape) and know drops another differnet newshape near your oldshape and stores it's ID in the oldshape again.

Too late now to worry about confusing me!   :P  j/k.  I am very comfortable with smart shapes.  I have been working within the shape sheet for a few years now.  It is the code stuff that throws me for a real loop.  I am interested in how you mention that I can add information in the old shape about the ID of the new shape?  I thought that was always my problem of doing this within the shape sheet, that when the shapes are placed on the drawing area they get assigned new ID.  I need this to run whether I place the shape first, or 51st.  And also if I use the shape one time or 17 times.  Can I refer to the shape to be brought in, even though it is actually a copy of a shape from another page?  The ID is different once it is a copy, correct?
Title: Re: Add new shape at certain position in visio page
Post by: Michelle on January 17, 2013, 03:22:10 PM
I thought I'd try to be smart and midify my module code to work in my situation.  So much for that Ha Ha!  Here's what I am trying.  (Mind you I have tried several versions of this...)

Sub MyMacro4(shp As Visio.Shape)

    'Enable diagram services
    Dim DiagramServices As Integer
    DiagramServices = ActiveDocument.DiagramServicesEnabled
    ActiveDocument.DiagramServicesEnabled = visServiceVersion140

    Application.ActiveWindow.Page = Application.ActiveDocument.Pages.ItemU("Page-3")

    ActiveWindow.DeselectAll
    ActiveWindow.Select Application.ActiveWindow.Page.Shapes.ItemFromID(14), visSelect
    Application.ActiveWindow.Selection.Copy

    Application.ActiveWindow.Page = Application.ActiveDocument.Pages.ItemU("Site Layout")
    Dim newshp As Shape
   

    Application.ActiveWindow.Page.PasteToLocation shp.Cells("PinX").Result("#") + 10#, shp.Cells("PinY").Result("#") + 0, 0
End Sub


But pretty much everyting I try places the copied shape in the same exact spot as where my original macro had it.  I changed the "mm" to # because I am working with inches, and my original macro had code that said:

Application.ActiveWindow.Page.PasteToLocation 664#, 248#, 0

I was thinking I could change out the reference to the original shape right in there, but Either I can't or I'm doing something wrong! 

Any help would be appreciated!

Michelle
Title: Re: Add new shape at certain position in visio page
Post by: vojo on January 17, 2013, 05:51:32 PM
last line is using shp....not newshp

If I understand this macro...it basically is placing the current shape where it already is

Title: Re: Add new shape at certain position in visio page
Post by: Michelle on January 17, 2013, 06:38:35 PM
I have tried what seems like every combination of shp & newshp, and nothing gets that second shape placed anywhere new.  I don't know if it is not doing anything, or like you said... just placing it where it already is.  I need it to place at a certain location offset from the shape that originally called it. 

Where should I place the "CALLTHIS" to make that happen?  In the EventDrop of the calling shape?  In the EVentDrop of the "new" called shape?  In a scratch section of one of those two like I did for the original module that calls the shape ion the first place? 

I feel like I'm close, but can't get it.... and I NEED this! 
Thanks for any help!
Michelle
Title: Re: Add new shape at certain position in visio page
Post by: Michelle on January 17, 2013, 07:02:54 PM
Oops. got interrupted and lost my train of thought.  What I meant to add to my previous post was that when I run this macro:
Sub PlaceClose(shp As Visio.Shape)

Dim newshp As Shape

  Const xoffset = 100
  Const yoffset = 0
  'Do something that results in the newshape droped somewhere on the page
  'Now you can place the new shape relative to the old shape:

  newshp.Cells("PinX").Result("") = shp.Cells("PinX").Result("") + xoffset
  newshp.Cells("PinY").Result("") = shp.Cells("PinY").Result("") + yoffset
End Sub


I get an error: "Object Variable or With Block Variable not set"  And if I hit debug, the arrow points to this line:  newshp.Cells("PinX").Result("") = shp.Cells("PinX").Result("") + xoffset
and it's highlighted.
Unfortunatly, I have no idea what that means!

Michelle
Title: Re: Add new shape at certain position in visio page
Post by: Paul Herber on January 17, 2013, 07:10:21 PM
Change line:
Application.ActiveWindow.Page.PasteToLocation shp.Cells("PinX").Result("#") + 10#, shp.Cells("PinY").Result("#") + 0, 0
to
newshp = Application.ActiveWindow.Page.PasteToLocation shp.Cells("PinX").Result("#") + 10#, shp.Cells("PinY").Result("#") + 0, 0


[My code here is incorrect - ignore]
Title: Re: Add new shape at certain position in visio page
Post by: Michelle on January 17, 2013, 08:17:39 PM
Thanks for taking a look, Paul.  I did as you suggested.  Now the second shape does not place, and I get an error:  "Compile Error - Invalid use of property." 

The debugger shows this line: 
shp.Cells("PinX").Result ("#") + 10#, shp.Cells("PinY").Result("#") + 0, 0

with  .Result  highlighted in blue. 
Can you help? 

Michelle
Title: Re: Add new shape at certain position in visio page
Post by: Jumpy on January 18, 2013, 07:40:28 AM
I still only have Visio 2007 so I didn't know PasteToLocation:

http://msdn.microsoft.com/en-us/library/ff768423%28v=office.14%29.aspx

I looked it up and saw that this procedure has no return value, so it doesn't give back a reference to the new shape. That is sad and not good thinking on part of the Visio developers. Because PasteToLocation can only be used with shapes it shouldn't have made a problem to create the function in a way that returns the pasted shape.

Nevertheless, it is as it is (as the people in my area used to say), and Pauls code won't work:
newshp = Application.ActiveWindow.Page.PasteToLocation ...

So if you create a new shape with copy and paste your code can't know the new shape.
So you should not use Copy and Paste. Instead lookup the name of the mastershape of the old shape and drop a new instance of that mastershape from the stencil to the page with good old page.Drop method:

http://msdn.microsoft.com/en-us/library/office/ms195970%28v=office.12%29.aspx

hth Jumpy

P.S.:
Perhaps you can make a screenshot or explain a little more, what you really wan't to do. What is your scenario, what do you do and what should happened automatically when you did what you did. Which shapes from which stencils (propably your own) are you working with or should work with your macro.
Title: Re: Add new shape at certain position in visio page
Post by: Paul Herber on January 18, 2013, 09:18:19 AM
Quote from: Jumpy on January 18, 2013, 07:40:28 AM

... and Pauls code won't work ...


Dang. You are right.
Got an idea though, after the shape has been dropped it will be the only shape in a selection, so
undo the change I suggested and insert afterwards:

newshp =  Application.ActiveWindow.Selection(1)

I think ...
Title: Re: Add new shape at certain position in visio page
Post by: Michelle on January 18, 2013, 06:07:11 PM
Who debugged the VBA code and got the shape working as desired?  *This Chick*
LOL

I felt it was close, so I just started trying things...  I have it working just as I want... SO Happy!

In case you are curious:
Sub MyMacro4(shp As Visio.Shape)

    'Enable diagram services
    Dim DiagramServices As Integer
    DiagramServices = ActiveDocument.DiagramServicesEnabled
    ActiveDocument.DiagramServicesEnabled = visServiceVersion140

    Application.ActiveWindow.Page = Application.ActiveDocument.Pages.ItemU("Page-3")

    ActiveWindow.DeselectAll
    ActiveWindow.Select Application.ActiveWindow.Page.Shapes.ItemFromID(14), visSelect
    Application.ActiveWindow.Selection.Copy

    Application.ActiveWindow.Page = Application.ActiveDocument.Pages.ItemU("Site Layout")
 
    Application.ActiveWindow.Page.PasteToLocation shp.Cells("PinX") + 150, shp.Cells("PinY") + 10, 0

   
End Sub


Thanks for your patience with me!  I am in a funny place right now, I don't really feel like I know a thing about code, yet somehow I can sometimes make things happen.   ;)
Michelle
Title: Re: Add new shape at certain position in visio page
Post by: contact_ankit86 on January 24, 2013, 09:44:27 AM
Hi,

I am facing a very strange problem. I am trying to copy paste a shape programmtically and then setting the PINX and PINY of that new shape using below code :

newshp.Cells("PINX") = oldshp.Cells("PINX")
newshp.Cells("PINY") = oldshp.Cells("PINY")

The problem is it places the new shape at correct location on one system but same code on a different system places at a wrong position. i am not sure what exactly the problem is. I have tried it on two desktops (shows same behaviour) and 2 laptops(shows different behaviour). Is there any setting on Desktop / laptops that is making Visio to behave different..?

Any thoughts..???


Title: Re: Add new shape at certain position in visio page
Post by: aledlund on January 24, 2013, 01:09:51 PM
I'd start with the Page Setup => Layout and Routing => and check to see if move shapes is checked.
al
Title: Re: Add new shape at certain position in visio page
Post by: Jumpy on January 24, 2013, 03:03:34 PM
And maybe the Default Property is in Inches and you have metric units in one of the sytems?

newshp.Cells("PINX").Result("mm") = oldshp.Cells("PINX").Result("mm")

or another unit instead of mm
Title: Re: Add new shape at certain position in visio page
Post by: Archangelos on October 19, 2016, 02:01:05 PM
I have a question. Let's say that a macro command added a shape in the page. How can we get the name of that shape?

For example, take a look at the picture. It has three rectangles that have been inserted manually.

1. Is it possible to change the name, to rename it from Rectangle.1 to something else?
2. If I add a shape via code can I define the name? If not, how can I get it in a variable?
Title: Re: Add new shape at certain position in visio page
Post by: metuemre on October 19, 2016, 02:12:05 PM
I don't know how you add a shape to a page via macro but let me give a simple example. Below code adds a rectangle to the activepage and rename it to "Sample"

Public Sub SampleRename()

Dim vsoShape As Visio.Shape
Set vsoShape = ActivePage.DrawRectangle(1, 1, 2, 2)
vsoShape.name = "Sample"

End Sub
Title: Re: Add new shape at certain position in visio page
Post by: vojo on October 20, 2016, 03:24:34 AM
set pinx and piny cells to designated location of shape or group origin.
(don't use locpinx or locpiny...that is shape location in relation to the designated origin)
Title: Re: Add new shape at certain position in visio page
Post by: Archangelos on November 08, 2016, 10:01:18 PM
Quote from: metuemre on October 19, 2016, 02:12:05 PM
I don't know how you add a shape to a page via macro but let me give a simple example. Below code adds a rectangle to the activepage and rename it to "Sample"

Public Sub SampleRename()

Dim vsoShape As Visio.Shape
Set vsoShape = ActivePage.DrawRectangle(1, 1, 2, 2)
vsoShape.name = "Sample"

End Sub

Interesting, thanks buddy.