Sparx Systems Forum
Enterprise Architect => Automation Interface, Add-Ins and Tools => Topic started by: David Rains (bioform) on January 11, 2011, 02:02:27 pm
-
I am working on a set of shape scripts to support SBVs (structured business vocabularies). I am trying to, via scripts, to locate the source class for an associated class (e.g., have Class1 and Class2, drag association class connector between the two and Class3 is created).
The issue I am having is how to locate the object ID of the source class( Class1) from the Class3 element in a script? If I remember right an associated classes' ID is stored in the connector's PDATA1 field...
Previously I did this by SQL calls to a hosted EA model (find the instance of the stereotyped Class3 object ID in the connector table under PDATA1, then use the StartObjectID and EndObjectIDs to find their tagged values I am interested in....
SBV Example: Class1 (term) is named "Dog", Class2 (term) is named "Hand", created associated class using connector and it will be named "DOG bites Hand" (a fact type), the verb "bites" would be displayed as the name label of the association, etc.
thanks for the help in advance... (aka Bioform)
David
-
David,
Do you use an assocationClass or just a regular association?
For a regular association you should look into Connector.ClientID and Connector.SupplierID.
I wouldn't know how to figure this out for AssociationClasses, but what I would do is to create an empty model with only Client, Target and Association class.
Then open the database and look how these three things are connected.
If something is stored in the PDATA fields you can get them in a script with Element.MiscData
Geert
-
Yes, it is an association class that I stereotyped as a "Wording". The other is relatively simple. But EA creates a connector entry for the A-B association, and then stores the Object ID of C (the assocated class - in this case my stereotyped FactType class) in the connector's PDATA1 as a string value.
Since I am rather new to the use of scripting in EA (today is my first day in fact) I am unsure of HOW to:
Identify the connector ID when all I know is the object ID of the associated class (C)... I was assuming I could look at a collection of connectors, then examine the PDATA field for the Object ID value of C.
I noticed from reading earlier posts that the connectors are not treated like a regualr collection? I tried to just run through a collection of connectors, but kept getting a message about method not being available... even though auto-sense shows it....
I will post a snippet of my script to show where I am having the problem and error message.
BTW it sure is fun to be back working with EA... :) Still on version 7.5 but am planning on updating in the next week or so.... waiting for new job to start... :)
Regards,
david
-
I would assume as well that you would need C.Connectors to gain access to the association.
Do post a snippet, I'm curious to what exactly is going wrong.
I can relate to your feelings. I had to work with MEGA for a year, and I sure was glad to be allowed to work with EA again.
Geert
PS. Version 9 is just around the corner, and it promises a whole bunch of improvements. Should be a matter of a few months before it is released.
-
Thanks for your help BTW :)
Okay, I decided to take a different more direct tack...
- Manually select the association-class connector in the diagram
- load the connector data
==============
dim theDiagram as EA.Diagram
set theDiagram = Repository.GetCurrentDiagram
dim theConnector as EA.Connector
set theConnector = theDiagram.SelectedConnector
==============
Everything working at this point... can see values for SupplierID and ClientID .... saved them to variables supplerID and clientID
Next load the supplier element's data
=========================
dim theSourceElement as EA.Element
set theSourceElement = Repository.GetElementByID(supplierID)
msgbox "Source: " & theSourceElement.ElementID, vbOkayOnly
=========================
Nothing? I re-read the snippet about GetElementByID and this seems to refer NOT to the EA assigned object ID, but to a local value of a collection?
Is there NOT a simple way to reference a element directly if you know it's EA objectID?
I seem to be finding myself in need of some basic code snippets to understand locating objects (elements, connectors, packages, etc.). I have checked the local scripts but they mostly depend on the element being already selected on the project tree (Repository.GetTreeSelected... )
BTW when are you starting that book Geert? :)
-
No, AFAIK Repository.GetElementByID works as you think it does.
I've used that quite a lot in my addins, and I never had any problems with it.
What you could do is check if the supplierID you provide is in fact an Object_ID in the table t_object.
If I find the time I'll have a go at it on my system. Just curious, which version of EA are you using?
Geert
PS. about the book.. I don't know, the problem is that something like that would demand a huge investment (time-wise) and at the moment I can't afford to do much unpaid (or later-paid) work.
If I were to find a sponsor on the other hand ;D
-
I just tested this on my machine (v 8.0.862) with following C# code:
public static void test()
{
ACVModel model = new UMLToolConnector().getCurrentModel();
EA.Repository repo = ((EAModel)model.getUMLModel()).getWrappedModel();
EA.Connector connector = repo.GetConnectorByID(1);
EA.Element supplier = repo.GetElementByID(connector.SupplierID);
EA.Element client = repo.GetElementByID(connector.ClientID);
EA.Element associationClass = repo.GetElementByID(int.Parse(connector.MiscData[0]));
string associationClassName = associationClass.Name;
}
and it works perfectly. I have both the supplier, client and associationClass elements.
Geert
-
Well, I have done the rewrite and I am still getting the original error mesage when I try to GetElementByID.... Here is the code snippet
=================
45 - dim supplierID
46 - supplierID = theConnector.SupplierID
47 -
48 - dim supplierElement as EA.Element
49 - supplierElement = Repository.GetElementByID(supplierID)
=================
The error message is.... Object doesnt support this property or method. Line49.
I check the value with a msgbox and it displays "supplierID: 80" which is correct when I check the t_object table
-
try "dim supplierID as Integer"
It might be that by passing a variant to the getElementByID you get the error.
Geert
-
I have been trying this using VBScript which supports only a variant type. I tried to force the issue by making this change
=================
supplierElement = Repository.GetElementByID(int(supplierID))
=================
But I still get the same error....
Now you might ask why don't I use VS2008 pro that I have installed on my laptop... good question. I tried to run the conversion for the VS2003 C# add-in example and the conversion was unsuccessful.
What I would LOVE to see posted is a add-in framework template in VB or C# for 2008... Hint Hint EA Admins :) - I can hack some pretty complex code using VBA but getting my 2008 environement set up to run the examples using outdated info been very fustrating on my end...
<whine whine whine...> :)
David
-
Just tried using Clng to force the subtype to long... but still getting that same error?!
thank god I'm going bald, because I don't have to go the hair pulling route to vent :)
David "Quicker in the Shower" Rains
-
David,
Take a look at my EA navigator addin (http://community.sparxsystems.com/resources/scripts/navigator-addin-navigate-operations-sequence-diagrams-and-vice-versa) on the community site.
That includes the source code in C# and it should give you a good start for writing C# addins.
Geert
-
May your hair continue to grow and your feet never hurt! :)
Now to go hide, read, and learn! :)
Thanks again, and yes it is 3:30 AM and I should be in bed over here!
David
-
Have fun.
To give you some more stuff to read: this page (http://themodelfactory.org/Pattern:Modelling_Tooling_Framework) describes the pattern I used to design the framework for my addin.
Geert
-
Perfect timing! I had the source open and was browsing the TMF wiki!!
WOW that is some resource!
Just make sure you and Palo never pass on to the next what ever okay? ;)
-
For completness here is the full code for the VBScript
=======================================
option explicit
'Process the newly created wording connector
'Assumptions:
' - a valid sbvrWording connector (conWording) is selected in the current diagram
' - the connector stores the associated class ID in PDATA1 (access via .MiscData(#-1)
' - the connector has the necessary tag values (e.g., verb_phrase_forward/reverse)
' - the connector associations a new class with 1 or 2 <sbvrTerm> classes (unary or binary)
' - the newassociation class has NOT been stereotyped yet
' - the associated term(s) have been previously named
' - user will supply a forward and reverse verb phrase when prompted
'Example Data:
' - Term Names = A, B
' - verb phrase forward = precedes, reverse = follows
'Success Outcome:
' - associated clase name will be derived and assigned (e.g., A precedes B)
' - associated class will be assigned the correct stereotype (e.g., sbvrFactType)
' - wording connector will display 'precedes' in the .... label
'
'TO DO LIST
' - add error checking
sub sbvrProcessWordingConnector()
' Get the currently selected connector in the diagram to work on
dim theDiagram as EA.Diagram
set theDiagram = Repository.GetCurrentDiagram
dim theConnector as EA.Connector
set theConnector = theDiagram.SelectedConnector
on error resume next
if theConnector is nothing or theConnector.Stereotype <> "sbvrWording" or theConnector.MiscData(0) = "" then 'PDATA# is (#-1)
' No item selected in thediagram, or the item selected was not expected
MsgBox( "This script requires a sbvrWording connector be selected in the current diagram." & chr(10) & _
"Please try again." )
on error goto 0 'Turn Error checking back on
else
on error goto 0 'Turn Error checking back on
'Msgbox( "Success")
dim supplierElement as EA.Element
supplierElement = Repository.GetElementByID(theConnector.SupplierID) 'ERROR OCCURS HERE!!
dim clientElement as EA.Element
clientElement =Repository.GetElementByID(theConnector.ClientID)
msgbox("Supplier and Client IDs: " & supplierID & " <" & supplierElement.Name & ">, " & clientID & " <" & clientElement.Name & ">")
end if
set theConnector = nothing
set theDiagram = nothing
end sub
sbvrProcessWordingConnector
=======================================
-
Okay I just could not let go of this and just scrapped the whoile thing and started from scratch... oif course things worked fine now?!!
anyway here is the working solution.... and this thread can be closed!
====================
option explicit
sub main()
dim currentDiagram as EA.Diagram
set currentDiagram = Repository.GetCurrentDiagram
dim currentConnector as EA.Connector
set currentConnector = currentDiagram.SelectedConnector
on error resume next
if currentConnector is nothing or currentConnector.Stereotype <> "sbvrWording" or currentConnector.MiscData(0) = "" then 'PDATA# is (#-1)
' No item selected in thediagram, or the item selected was not expected
MsgBox( "This script requires a sbvrWording connector be selected in the current diagram." & chr(10) & _
"Please try again." )
on error goto 0 'Turn Error checking back on
else
on error goto 0 'Turn Error checking back on
msgbox "Connector Name, ID, and GUID: " & currentConnector.Name & ", " & currentConnector.ConnectorID & ", " & currentConnector.ConnectorGUID ,vbOKOnly
dim sourceElement as EA.Element
set sourceElement = Repository.GetElementByID(currentConnector.SupplierID)
'set elementSelected = Repository.GetTreeSelectedObject
msgbox "Source Element Name, ID, and GUID: " & sourceElement.Name & ", " & sourceElement.ElementID & ", " & sourceElement.ElementGUID ,vbOKOnly
dim clientElement as EA.Element
set clientElement = Repository.GetElementByID(currentConnector.ClientID)
'set elementSelected = Repository.GetTreeSelectedObject
msgbox "Client Element Name, ID, and GUID: " & clientElement.Name & ", " & clientElement.ElementID & ", " & clientElement.ElementGUID ,vbOKOnly
dim assocc_classElement as EA.Element
set assocc_classElement = Repository.GetElementByID(currentConnector.MiscData(0))
'set elementSelected = Repository.GetTreeSelectedObject
msgbox "Assoc. Class Element Name, ID, and GUID: " & assocc_classElement.Name & ", " & assocc_classElement.ElementID & ", " & assocc_classElement.ElementGUID ,vbOKOnly
set sourceElement = nothing
set clientElement = nothing
set assocc_classElement = nothing
end if
set currentConnector = nothing
set currentDiagram = nothing
end sub
main
====================
-
Glad to hear you got everthing working. There will be improved support for Association Classes through the automation interface in version 9.
I re-read the snippet about GetElementByID and this seems to refer NOT to the EA assigned object ID, but to a local value of a collection?
I'm not sure if I'm reading into this wrong (having not seen the source of your quote), but I don't think that statement is accurate.
An object ID is unique within the context of a repository, but not globally - which is why objects both have IDs (repository unique identifier) and GUIDs (globally unique identifier).
If you import/export between repositories you will notice that the IDs change but the GUIDs do not. As a result, I would not expect GetElementByID to fail if the element ID you are using comes from the current repository.