1
Automation Interface, Add-Ins and Tools / Re: Repository.GetCurrentDiagram() returning wrong diagram
« on: March 31, 2026, 08:26:03 pm »
Current diagram looks at which diagram is open in the main window.
Geert
Geert
This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.
!INC Local Scripts.EAConstants-VBScript
!INC Wrappers.Include
'
' Script Name: Format BOPF diagram
' Author: Geert Bellekens
' Purpose: Format a diagram containing BOPF elemnets
' Date: 2021-03-05
'
const width = 100
const verticalPadding = 10
const horizontalPadding = 200
dim lsDirectMode, lsAutoRouteMode, lsCustomMode, lsTreeVerticalTree, lsTreeHorizontalTree, _
lsLateralHorizontalTree, lsLateralVerticalTree, lsOrthogonalSquareTree, lsOrthogonalRoundedTree
lsDirectMode = "1"
lsAutoRouteMode = "2"
lsCustomMode = "3"
lsTreeVerticalTree = "V"
lsTreeHorizontalTree = "H"
lsLateralHorizontalTree = "LH"
lsLateralVerticalTree = "LC"
lsOrthogonalSquareTree = "OS"
lsOrthogonalRoundedTree = "OR"
dim defaultStyle
' set here the default style to be used
defaultStyle = lsOrthogonalSquareTree
function formatBOPFDiagram(diagram)
'inform user
Repository.WriteOutput outPutName, now() & " Starting formatting diagram '" & diagram.Name & "'" , 0
'auto layout diagram to get correct sizes
'auto layout diagram
dim diagramGUIDXml
'The project interface needs GUID's in XML format, so we need to convert first.
diagramGUIDXml = Repository.GetProjectInterface().GUIDtoXML(diagram.DiagramGUID)
'Then call the layout operation
Repository.GetProjectInterface().LayoutDiagramEx diagramGUIDXml, lsDiagramDefault, 4, 20 , 20, false
diagram.Update
'reload the diagram to make sure it works in all cases
set diagram = Repository.GetDiagramByID(diagram.DiagramID)
dim diagramObjects
set diagramObjects = getDiagramObjectsDictionary(diagram)
'get the diagramObject for the owner of the diagram
dim diagramObjectOwner as EA.DiagramObject
if diagramObjects.exists(diagram.ParentID) then
set diagramObjectOwner = diagramObjects.Item(diagram.ParentID)
'get diagram object object
dim diagramOwner as EA.Element
set diagramOwner = Repository.GetElementByID(diagram.ParentID)
dim x
dim y
'determine start position based on the owner's stereotype
if diagramOwner.Stereotype = "BOPF_businessObject" then
x = 10 'start top left for business object
else
x = 600 'start in the middle for node
end if
y = -10
dim height
height = abs(diagramObjectOwner.bottom) - abs(diagramObjectOwner.Top)
'set first position
diagramObjectOwner.left = x
diagramObjectOwner.right = x + width
diagramObjectOwner.top = y
diagramObjectOwner.bottom = y - height
diagramObjectOwner.Update
'process sub elements
formatSubElements diagramOwner, diagramObjectOwner, diagram, diagramObjects
'process combined datatype
if diagramOwner.Stereotype = "BOPF_node" then
formatDatatype diagramOwner, diagram, diagramObjects
end if
' Process authorizations. Usually there is only one authorization object per node. For now layout on each other
formatAuthorizationObjects diagram, diagramObjects
end if
'format links
formatLinks diagram
'reload diagram
diagram.Update
Repository.ReloadDiagram diagram.diagramID
'inform user
Repository.WriteOutput outPutName, now() & " Finished formatting diagram '" & diagram.Name & "'" , 0
end function
function formatLinks(diagram)
dim test as EA.DiagramLink
dim diagramLink as EA.DiagramLink
for each diagramLink in diagram.DiagramLinks
'get the connector
dim connector as EA.Connector
set connector = Repository.GetConnectorByID(diagramLink.ConnectorID)
setConnectorStyle diagramLink, connector
if connector.Stereotype = "SAP_association" then
formatAssociationLink(diagramLink)
end if
next
end function
function formatAssociationLink(diagramLink)
'get the order of the diagram link
dim sqlGetOrder
sqlGetOrder = "select con.seq from " & vbNewLine & _
" ( " & vbNewLine & _
" select c2.Connector_ID, ROW_NUMBER() over (order by c2.Name, c2.Connector_ID) as seq " & vbNewLine & _
" from t_connector c " & vbNewLine & _
" inner join t_connector c2 on c2.Start_Object_ID = c.Start_Object_ID " & vbNewLine & _
" and c2.End_Object_ID = c.End_Object_ID " & vbNewLine & _
" and c2.Stereotype = c.Stereotype " & vbNewLine & _
" inner join t_diagramlinks dl on dl.ConnectorID = c2.Connector_ID " & vbNewLine & _
" and dl.DiagramID = " & diagramLink.DiagramID & " " & vbNewLine & _
" where c.Connector_ID = '" & diagramLink.ConnectorID & "' " & vbNewLine & _
" ) con " & vbNewLine & _
" where con.Connector_ID = '" & diagramLink.ConnectorID & "' "
dim results
set results = getArrayListFromQuery(sqlGetOrder)
dim order
order = results(0)(0)
if order <> "1" then
'get key value pairs for geometry
dim geometryKeyValues
set geometryKeyValues = getKeyValuePairs(diagramLink.Geometry)
'move ey and ex
dim ey
ey = cInt(geometryKeyValues("EY"))
ey = ey - cint(order) * 20 'move end down
geometryKeyValues("EY") = ey
dim ex
ex = cInt(geometryKeyValues("EX"))
ex = ex - cint(order) * 20 'move end left
geometryKeyValues("EX") = ey
'then join again
diagramLink.Geometry = joinKeyValuePairs(geometryKeyValues)
'and update
diagramLink.Update
end if
end function
'actually sets the connector style
function setConnectorStyle(diagramLink, connector)
if diagramLink is nothing then
exit function
end if
'split the style into its parts
dim styleparts
dim styleString
' Throw away the last ; so that an empty cell at the end is not created when its Split
if len(diagramLink.Style) > 0 then
styleString = Left(diagramLink.Style, Len(diagramLink.Style)-1)
else
styleString = ""
end if
styleparts = Split(styleString,";")
dim mode
dim tree
dim linestyle
mode = ""
tree = ""
linestyle = determineLineStyle(connector)
'get out if no linestyle found
if len(linestyle) = 0 then
setConnectorStyle = false
exit function
end if
'these connectorstyles use mode=3 and the tree
if linestyle = lsTreeVerticalTree or _
linestyle = lsTreeHorizontalTree or _
linestyle = lsLateralHorizontalTree or _
linestyle = lsLateralVerticalTree or _
linestyle = lsOrthogonalSquareTree or _
linestyle = lsOrthogonalRoundedTree then
mode = "3"
tree = linestyle
else
mode = linestyle
end if
'set the mode value
setStylePart styleparts, "Mode", mode
'set the tree value
setStylePart styleparts, "TREE", tree
' setStylePart styleparts, "Color", determineColor(connector)
' setStylePart styleparts, "LWidth", determineLineWidth(connector)
' update style (add in trailing ; that is needed)
diagramLink.Style = join(styleparts, ";") & ";"
'clear path and geometry
diagramLink.Geometry = ""
diagramLink.Path = ""
'save diagramLink
diagramLink.update
'return true for dirty
setConnectorStyle = true
end function
function determineLineStyle(connector)
determineLineStyle = "" 'default none
'only do non stereotyped relations
if connector.Stereotype = "SAP_composition" then
determineLineStyle = lsLateralHorizontalTree
elseif connector.Stereotype = "BOPF_authorizationCheck" then
determineLineStyle = lsOrthogonalSquareTree
else
determineLineStyle = lsDirectMode
end if
end function
' Set the style to the specified value
function setStylePart(styleparts, style, value)
dim i
dim stylePart
dim index
index = -1
for i = 0 to Ubound(styleparts)
stylePart = styleparts(i)
if Instr(stylepart, style & "=") > 0 then
index = i
end if
next
If Len(value) > 0 then
' Adding to style
if index = -1 then
' extend the array when style is not already in array
redim preserve styleparts(Ubound(styleparts) + 1)
index = Ubound(styleparts)
end if
styleparts(index) = style & "=" & value
else
' Removing style from styleparts
if index >= 0 then
' copy the last value over the top of index, and then shrink the array
styleparts(index) = styleparts(Ubound(styleparts))
redim preserve styleparts(Ubound(styleparts) - 1)
end if
' if the index was -1 it already did not exist in the styleparts
end if
end function
function formatSubElements(diagramOwner, diagramObject, diagram, diagramObjects)
dim symmetric
if diagramOwner.Stereotype = "BOPF_node" then
symmetric = true
else
symmetric = false
end if
'get list of ID's that are owned by this diagramObject, and that are part of the diagram
dim diagramElementIDs
diagramElementIDs = Join(diagramObjects.Keys, ",")
dim sqlGetData
sqlGetData = "select o.Object_ID " & vbNewLine & _
" from (select o.Object_ID, o.Name, o.stereotype, " & vbNewLine & _
" case when o.stereotype = 'BOPF_determination' then 1 " & vbNewLine & _
" when o.stereotype = 'BOPF_validation' then 2 " & vbNewLine & _
" when o.stereotype = 'BOPF_action' then 3 " & vbNewLine & _
" else 99 end as seqOrder " & vbNewLine & _
" from t_object o " & vbNewLine & _
" where o.ParentID = " & diagramObject.ElementID & " " & vbNewLine & _
" and o.Object_ID in (" & diagramElementIDs & ") " & vbNewLine & _
" ) o " & vbNewLine & _
" order by o.seqOrder, o.stereotype, o.name "
dim subElementIDs
set subElementIDs = getVerticalArrayListFromQuery(sqlGetData)
dim subElementID
dim x
dim y
y = diagramObject.bottom
dim height
if subElementIDs.Count > 0 then
dim subDiagramObject as EA.DiagramObject
'determine max width
dim maxWidth
maxWidth = 0
for each subElementID in subElementIDs(0)
set subDiagramObject = diagramObjects(CLng(subElementID))
dim elementWidth
elementWidth = subDiagramObject.right - subDiagramObject.left
if elementWidth > maxWidth then
maxWidth = elementWidth
end if
next
if symmetric then
'format elements
dim position
position = 0 '0 = left, 1 = right, 2 = far left, 3 = far right
dim xValues
set xValues = CreateObject("System.Collections.ArrayList")
dim center
center = (diagramObject.left + diagramObject.right) /2
dim minBottom
minBottom = diagramObject.Bottom - (verticalPadding * 3)
'format elements
xValues.Add(center - horizontalPadding) '0
xValues.Add(center + horizontalPadding) '1
xValues.Add(center - (horizontalPadding * 2))'2
xValues.Add(center + (horizontalPadding * 2))'3
y = diagramObject.bottom - verticalPadding
for each subElementID in subElementIDs(0)
'go down on the first and and 3th position
if position = 0 or position = 2 then
y = minBottom - verticalPadding
end if
x = xValues(position)
set subDiagramObject = diagramObjects(CLng(subElementID))
height = abs(subDiagramObject.bottom) - abs(subDiagramObject.Top)
if position = 0 or position = 2 then
subDiagramObject.left = x
subDiagramObject.right = x + maxWidth
else
subDiagramObject.right = x
subDiagramObject.left = x - maxWidth
end if
subDiagramObject.top = y
subDiagramObject.bottom = y - height
subDiagramObject.update
if subDiagramObject.bottom < minBottom then
minBottom = subDiagramObject.bottom
end if
'reset position after 3
if position = 3 then
position = 0
else
position = position + 1
end if
next
else
'format elements
x = diagramObject.right + (horizontalPadding /2)
for each subElementID in subElementIDs(0)
set subDiagramObject = diagramObjects(CLng(subElementID))
height = abs(subDiagramObject.bottom) - abs(subDiagramObject.Top)
y = y - verticalPadding 'go down
subDiagramObject.left = x
subDiagramObject.right = x + maxWidth
subDiagramObject.top = y
subDiagramObject.bottom = y - height
subDiagramObject.update
y = subDiagramObject.bottom
'go one level deeper
y = formatSubElements(diagramOwner, subDiagramObject, diagram, diagramObjects)
next
end if
end if
'return Y
formatSubElements = y
end function
function formatDatatype(diagramOwner,diagram, diagramObjects)
'get list of ID's that are owned by this diagramObject, and that are part of the diagram
dim diagramElementIDs
diagramElementIDs = Join(diagramObjects.Keys, ",")
dim sqlGetData
sqlGetData = "select o.Object_ID " & vbNewLine & _
" from t_object o " & vbNewLine & _
" where o.Object_Type = 'Datatype' " & vbNewLine & _
" and o.Object_ID in (" & diagramElementIDs & ") "
dim datatypeIDs
set datatypeIDs = getVerticalArrayListFromQuery(sqlGetData)
dim datatypeID
dim x
x = 1200
dim y
y = -20
if datatypeIDs.Count > 0 then
for each datatypeID in datatypeIDs(0)
dim diagramObject as EA.DiagramObject
set diagramObject = diagramObjects(CLng(datatypeID))
dim height
height = abs(diagramObject.bottom) - abs(diagramObject.Top)
dim width
width = diagramObject.right - diagramObject.left
diagramObject.left = x
diagramObject.right = x + width
diagramObject.top = y
diagramObject.bottom = y - height
diagramObject.Update
next
end if
end function
''debug
'sub test
' dim diagram as EA.Diagram
' set diagram = Repository.GetDiagramByGuid("{50315683-1BB7-4557-B6A3-06FAFB9A6E23}")
' formatBOPFDiagram(diagram)
'end sub
'test
'formatAuthorizationObjects
function formatAuthorizationObjects (diagram, diagramObjects)
'1. Find all authorisation objects on the diagrams
'get list of ID's that are owned by this diagramObject, and that are part of the diagram
dim diagramElementIDs
diagramElementIDs = Join(diagramObjects.Keys, ",")
dim sqlGetData
sqlGetData= "select o.Object_ID " & vbNewLine & _
" from t_object o " & vbNewLine & _
" where o.Stereotype = 'SAP_authorizationObject' " & vbNewLine & _
" and o.Object_ID in (" & diagramElementIDs & ") "
dim authorizationObjectIDs
set authorizationObjectIDs = getVerticalArrayListFromQuery(sqlGetData)
'2. Find the BO node connected to the authorization object
dim authorizationObjectID
if authorizationObjectIDs.Count > 0 then
for each authorizationObjectID in authorizationObjectIDs(0)
dim diagramObject as EA.DiagramObject
set diagramObject = diagramObjects(CLng(authorizationObjectID))
'Find BO node
'Find BO node id
sqlGetData= "select o.Object_ID " & vbNewLine & _
" from t_object o " & vbNewLine & _
" inner join t_connector c " & vbNewLine & _
" on c.Start_Object_ID = o.Object_ID " & vbNewLine & _
" where o.Stereotype = 'BOPF_node' " & vbNewLine & _
" and o.Object_ID in (" & diagramElementIDs & ") " & vbNewLine & _
" and c.End_Object_ID = "& authorizationObjectID
dim BONodeIDs
set BONodeIDs = getVerticalArrayListFromQuery(sqlGetData)
if BONodeIDs.Count > 0 then
dim BONodeID
for each BONodeID in BONodeIDs(0)
dim diagramObjectBONode as EA.DiagramObject
set diagramObjectBONode = diagramObjects(CLng(BONodeID))
dim height
height = abs(diagramObject.bottom) - abs(diagramObject.Top)
dim width
width = diagramObject.right - diagramObject.left
dim x
x = diagramObjectBONode.right + 300
dim y
y = diagramObjectBONode.top
'3. Set the top coordinate of the authorization object equal to the ones of the bo node but more to the right.
diagramObject.left = x
diagramObject.right = x + width
diagramObject.top = y
diagramObject.bottom = y - height
diagramObject.Update
exit for
next
end if
next
end if
end functionThanks! I would like to avoid duplicating the query, if possible.
If it is stored internally in EA, where would I find that, please?
Thanks...I was afraid of that.Repository.Execute uses the connection EA makes to the database.
Unfortunately, I do not have update rights in the actual DB itself, so don't think I could run an update SQL statement, I believe.
Thanks for the quick answers.
Eric
Hi,If you create an element with a stereotype using the client API, the tagged values are created automatically.
EA Interop API provides a method to synchronize the MDG's stereotypes i.e. matching what one can do in EA via a right click on a stereotype in the toolbox > Synchronize Stereotype
Example: Repository.CustomCommand("Repository", "SynchProfile", "Profile=myProfile;Stereotype=test;");
As I create stereotyped elements matching a profile (custom MDG) via the PCS OSLC API, is there a way to run this Synchronize command so that all tagged values matching the profile definition are created ?
Thanks
Hello,
I tried to import a large XEA file with a GUID reset to a new EA repository (shared on Postgres, available via the PCS 6.1.166) and I eventually get an Application Error.
Opening the DBError file, I have the following:
Enterprise Architect (Build: 1628 - 64 bit)
Sparx Systems Database API [0x00001086]
Native Update FAILED with error:
23503 ERROR: insert or update on table "t_connector" violates foreign key constraint "fkam9fr64t66r6dgjgo3mfoji2a"
DETAIL: Key (end_object_id)=(0) is not present in table "t_object".
Context:
What could be the issue ?
Updates:
- I upgraded the PCS to the latest build but it didn't resolve the issue
- I ran a project integrity check
- The workaround I found involved importing the XEA file to a blank EA project and re-exporting it with the Strip GUID enabled. I wonder if this is related with conflicts on external dependencies that are removed down by going through a blank EA project. The size of the new file is a bit smaller that the original one
That was yesterday. I even got a timeout from Cloudflare trying to post.Over the last couple of days I have found the pages on the forum very slow to load / reload.Yes, and it seems to be getting worse. I think it took about 15 minutes before the post pox appeared.
Has anyone else noticed this?
Phil
Geert
Over the last couple of days I have found the pages on the forum very slow to load / reload.Yes, and it seems to be getting worse. I think it took about 15 minutes before the post pox appeared.
Has anyone else noticed this?
Phil
thank you for your reply!You should first figure out what the actual metaclass is.
I understand that I should extend the same metaclass as SysML1.4::FlowProperty (not Class). However, in EA 16.1 MDG Technology modeling I do not see Property available in the “Extend Metaclass” dialog.
Could you please clarify how I can extend the same metaclass as SysML1.4::FlowProperty in an MDG model?