1
votes

I'm writing script to automate Visio documents using Python. I'm using win32com module and so far, I'm doing good. I learned how to play with shapes , masters and stencil etc.; however, I stuck on the connecting shapes. I searched many forums and discussions but I couldn't get any clear explanation myself.

I decided to create an 2 object to connect them from their connection points that I added. Here, I added big picture so that, connection points on the edges can be seen clearly.

Shape with connection points on the edges

Then, I tried to connect them. What I learned from documentation is, first I need to create an connect object. Then I need to create 2 cells from this 1D object, which are begin("BeginX") and end("EndX") points. Then, I need to glue this endpoints to the objects.

Here is my Python code which is taken from VBA documentation(I converted it to Python). However, it's really hard to understand what is "Geometry1.X1" etc.

import win32com.client
app = win32com.client.Dispatch("Visio.Application")
app.Visible = True
doc = app.Documents.Open("d:\\X.vsd")
page = app.ActivePage

...

added_new_shape1 = page.Drop(master_shape_ex, 5, 5)
added_new_shape2 = page.Drop(master_shape_ex, 10, 5)

myConnector = page.Drop(app.ConnectorToolDataObject, 4, 10)
myConnectorBegin = myConnector.Cells("BeginX")
myConnectorEnd = myConnector.Cells("EndX")

vsoCellGlueToObject = added_new_shape1.Cells("Geometry1.X1")
vsoCellGlueToObject2 = added_new_shape2.Cells("Geometry1.X1")

myConnectorBegin.GlueTo(vsoCellGlueToObject)
myConnectorEnd.GlueTo(vsoCellGlueToObject2)

If I run my code, 2 shapes are connected from the corners.

enter image description here

Then I play with X1, I see connection end points are changing but I'm so confused here.

Many questions are coming to mind but if I have the answer of these 2, I believe that I will understand the logic.

  1. How can I connect shapes by specifying the points on shapes?
  2. How can I connect shapes using connection points? (In this example, I created shape and added connection points myself. Does it matter to add connection points using script? )

I would be very happy if you could give me advice beyond these two questions.

1

1 Answers

0
votes

Consider this code:

Python:

import win32com.client

app = win32com.client.Dispatch("Visio.Application")
app.Visible = True
#open Visio document and assign it to variable doc
doc = app.Documents.Open(r"c:\Users\Alex20\Documents\Connect.vsdm")
page = app.ActivePage

# drop shape to the page from doc stencil by name "Master.4" at x,y coord.
added_new_shape1 = page.Drop(doc.Masters("Master.4"), 2, 2)
added_new_shape2 = page.Drop(doc.Masters("Master.4"), 4, 4)

# create connection point for added_new_shape1
# by adding row to 7 section (stores an object's connection points), after last exists row, unnamed rows
conPt1 = added_new_shape1.AddRow(7, -2, 153) # .AddRow(visSectionConnectionPts, visRowLast, visTagCnnctPt)
conRow1 = added_new_shape1.Section(7).Row(conPt1) #get the created row
# set coordinates of the connection point (0) - x, (1) - y
conRow1.Cell(0).FormulaU = "Width*1"
conRow1.Cell(1).FormulaU = "Height*0.5"

# create connection point for added_new_shape2
conPt2 = added_new_shape2.AddRow(7, -2, 153)
conRow1 = added_new_shape2.Section(7).Row(conPt2)
conRow1.Cell(0).FormulaU = "Width*0.5"
conRow1.Cell(1).FormulaU = "Height*1"

# drop the connector onto page
myConnector = page.Drop(app.ConnectorToolDataObject, 4, 10)
myConnectorBegin = myConnector.Cells("BeginX") #get start point of the connector
myConnectorEnd = myConnector.Cells("EndX") #get end point of the connector

vsoCellGlueToObject = added_new_shape1.Cells("Connections.X1") # get early created connection point of the first shape
vsoCellGlueToObject2 = added_new_shape2.Cells("Connections.X1") # get early created connection point of the second shape

myConnectorBegin.GlueTo(vsoCellGlueToObject) # connect start point of the connector to shape's connection point
myConnectorEnd.GlueTo(vsoCellGlueToObject2)

The same (VBA):

Sub Macro2()
    Set pg = Application.ActiveWindow.Page
    
    Set s1 = pg.Drop(ActiveDocument.Masters("Master.4"), 2, 2)
    Set s2 = pg.Drop(ActiveDocument.Masters("Master.4"), 4, 4)

    intRowIndex1 = s1.AddRow(visSectionConnectionPts, visRowLast, visTagCnnctPt)
    Set vsoRow1 = s1.Section(visSectionConnectionPts).Row(intRowIndex1)
    vsoRow1.Cell(visCnnctX).FormulaU = "Width*1"
    vsoRow1.Cell(visCnnctY).FormulaU = "Height*0.5"

    intRowIndex3 = s2.AddRow(visSectionConnectionPts, visRowLast, visTagCnnctPt)
    Set vsoRow2 = s2.Section(visSectionConnectionPts).Row(intRowIndex3)
    vsoRow2.Cell(visCnnctX).FormulaU = "Width*0.5"
    vsoRow2.Cell(visCnnctY).FormulaU = "Height*1"

    Set conn = pg.Drop(Application.ConnectorToolDataObject, 0#, 0#)
    
    Set vsoCell1 = conn.CellsU("BeginX")
    Set vsoCell2 = s1.Cells("Connections.X1")
    vsoCell1.GlueTo vsoCell2
    
    Set vsoCell1 = conn.CellsU("EndX")
    Set vsoCell2 = s2.Cells("Connections.X1")
    vsoCell1.GlueTo vsoCell2
End Sub

See Cells (Visio ShapeSheet Reference) at https://docs.microsoft.com/en-us/office/client-developer/visio/cells-visio-shapesheet-reference

enter image description here