Absolute and relative sizes in Visio

G

geejay

Hi

(Visio SDK, .NET Framework 3.5)

I am trying to figure out how to get absolute pin values for all the objects
I programmatically create within a Visio page.

Because I want to use groups, I have some objects that are relatively
positioned within the group. However I am struggling trying to get meaningful
pin values from these objects.

Here is the method I am trying to use:

I check to see whether the containing shape is the page or another object.

If the containing shape is the page, then I am safe, and can use the value
retrieved from Visio.VisCellIndices.visXFormPinX in the shapesheet.

If the shape is part of a group, then I try using the XYToPage method on the
shape to get the absolute page pin values. This almost works, but is always
above by about 1 cm.

I should also mention that I am using "cm" by default. However, changing the
page units doesn't seem to have much affect.

Wondering if anyone has had success with the XYToPage method?

Cheers

Greg
 
G

geejay

Ok, it would be good to use the API directly though. Surely these XYToPage
functions actually work given a certain environment.

Do you have any code that executes sheet functions?

Thanks
 
J

JuneTheSecond

Hi,

XYtoPage returns values in inches.
But, Yes Visio, seems, has bags.

Shapesheet functions and XYtoPage soetimes return the same wrong values.
Especially when the child shape rotates.
I think there is no medicine other than pure mathematical calculations.

Next are my test macros.
Option Explicit

For ShapeSheetFunctions, the page need to have user-defined cells,
User.pin, User.x and User.y , and
User.x = PNTX(User.pin)
and User.y = PNTY(User.pin)

Sub ShapeSheetFunctions()
Dim shp As Visio.Shape
Dim I As Long, N As Long
N = 1000
For I = 1 To N
Set shp = ShapeFromID(I)
If Not shp Is Nothing Then
If shp.Parent.Type = visTypeGroup Then
ActivePage.PageSheet.Cells("User.pin").Formula = _
"PAR(PNT(Sheet." & I & "!PinX,Sheet." & I & "!PinY))"
ElseIf shp.Parent.Type = visTypePage Then
ActivePage.PageSheet.Cells("User.pin").Formula = _
"PNT(Sheet." & I & "!PinX,Sheet." & I & "!PinY)"
End If
Debug.Print I,
ActivePage.PageSheet.Cells("User.x").Result("mm"), _
ActivePage.PageSheet.Cells("User.y").Result("mm")
End If
Next
End Sub

Sub VBAXYToPage()
Dim shp As Visio.Shape
Dim I As Long, N As Long
Dim x As Double, y As Double
On Error GoTo ERRMSG
N = 1000
For I = 1 To N
Set shp = ShapeFromID(I)
If Not shp Is Nothing Then
If shp.Parent.Type = visTypeGroup Then
shp.XYToPage shp.Cells("PinX"), shp.Cells("PinY"), x, y
Debug.Print I, shp.NameU, x * 25.4, y * 25.4
ElseIf shp.Parent.Type = visTypePage Then
Debug.Print I, shp.NameU, shp.Cells("PinX").Result("mm"),
shp.Cells("PinY").Result("mm")
End If
End If
Next
Exit Sub
ERRMSG:
MsgBox Err.Description
End Sub

Function ShapeFromID(ID As Long) As Visio.Shape
On Error GoTo ERRHND
Set ShapeFromID = ActivePage.Shapes.ItemFromID(ID)
Exit Function
ERRHND:
Set ShapeFromID = Nothing
End Function

--
Best Regards.

JuneTheSecond
Now, visual calculation is more visual.
http://www.geocities.jp/visualcalculation/english/index.html
 
G

geejay

Ok thanks. It's good to know that it's not just me.

The way I solved this situation was to actually use the grouping
functionality within Visio. Doing this I can move the group around which
automatically moves all the objects inside around. This suits for 90% of my
requirements. The other 10% I use absolute positioning and ungroup all the
group objects.

I guess you could come up with your own implementation of this function by
recursively looking through each shape within a shape within a shape. Then
calculating the co-ords all the way up the shape tree. This is what I thought
was implemented by XYToPage but obviously not.

Thanks for all your help.

Greg
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top