Category Archives: API

Information relating to the EA API model and its use

Automatic testing of EA AddIns

This post was inspired by a post on the Sparx forum a couple of weeks ago which was asking about automated testing for AddIns. This got me thinking about what can and can’t be done in EA using scripts and/or code, and what else may needed to perform the task.

The problem with testing is often that you need to emulate the actions of the user through a windows UI, and this is the case that was highlighted.  Without interaction through the EA UI AddIn Broadcasts events are not fired, and hence our AddIn would be outside of the processing  loop.

If we look at an example.  Say we have an AddIn which adds an attribute to every new class that is created.  To test this functionality we need to manually add our new class element through the EA UI.

So any solution we develop requires us to be able to replicate the manual interaction with the EA UI, perform the required sequence of tests, and then check the results to verify that our AddIn worked correctly.

Fortunately there are test tools that will emulate user inputs for windows application. So keen to validate my proposed solution I set to work:

  1. Create a small test AddIn – that simply added an attribute to each new class added (probably not a real use case but at least it’s easy to do an very visible}
  2. Use a test tool to emulate the manual process of adding  a new class element (and hopefully ensure our AddIn received the required events!)
  3. Run a script that could verify our new class element had its attribute added. I was planning on using EA scripts to do this, but as I’ll detail below I ended up using an external script to access the automation API to access the model and perform the checks.

So now for the detail and results of my experiment.

1. Create an AddIn

To check the process I needed a test AddIn – which I called TestingChecker, that responds to the OnPostNewElement event, which is fired by EA when a user adds a new element. Here is the code stripped of all error handling code

 
Function EA_OnPostNewElement(Repository As EA.Repository, Info As EA.EventProperties) As Boolean
Dim myElementID As Long = Info.Get(0).Value
Dim myElement As EA.Element = Repository.GetElementByID(myElementID)
    myElementID = Info.Get(0).Value
    myElement = Repository.GetElementByID(myElementID)
    If myElement.Type = "Class" Then
       Dim et As String = myElement.Type
       ' add an attribute
        Dim a As EA.Attribute = Nothing
        a = myElement.Attributes.AddNew("NewAttribute", "")
        a.Update()
        a.Name = "New Attribute"
        a.Update()
     End If
   Return True
    End Function
End Class

Nothing special here, so I assume you are happy with this and it’s operation so no further comment.

2. Testing the UI

I hadn’t used windows test tools for decades so had to reacquaint myself with what tools were available.  A quick trawl around the Internet and there were plenty to chose from, but which? Many required the writing of scripts, whilst others promised more features including the power of recording a users input which could be replayed.

So with the aim of minimising my effort, I downloaded a trial copy of one of the more powerful products and set about “recording”  my inputs to EA.  However, I found it very frustrating with the tools ability to select the correct UI items.  When the recorded scripts were replayed I found that they weren’t as good as I had hoped, and failed to select items correctly.  Hence the tool failed to perform the required tasks. I suspect the recording process relies on mouse location rather than correctly identifying controls, or the challenge with identifying the EA controls..  So rather than spend more time trying to work around these issues I decided to jump in and write the scripts myself.

Based on that decision I downloaded AutoIt (a freeware toolset).  The information on this tool stated it could perform the required control selection and provide the required user inputs.

Tools needed:

A few notes relating to the AutoIt tools.

The AutoIt Full Installation download includes all the tools required although it only contains a lite version of SciTE and I read it is recommended that you download the full version of SciTE.

You use SciTE that you use to create your scripts with AutoIt Window Info tool to get information that you need from your application under test e.g. control details. You can compile, build, run you scripts from the SciTE tools options, and if you needed can access the Koda GUI Form designer from the same menu.

In the SciTE help file, amongst other useful information, is a simple Notepad automation tutorial which was sufficient to get me started – I would suggest you work through the tutorials to gain familiarity with the tools.  Also for those interested there are several more tutorials.

Following the inevitable trials and errors I was able to write scripts that could select controls and perform the required actions.

To make it easier for testing I set up EA to use a default model (so didn’t need to specify when running EA) whose initial content was:

Initial Model Content

Initial contents of test EA model

Using the AutoIt script I produced a simple function that will:

  • run EA – opening default model
  • add a single class element
  • close the EA file
  • close EA
Func AddStuff2EA()
$PID = Run("C:\Program Files (x86)\Sparx Systems\EA\EA.exe")
WinWaitActive("WinTextCheck - Enterprise Architect")
; get focus on EA
$Res = ControlFocus("WinTextCheck - Enterprise Architect","",2)
;Send("^M") - want to send cntrl+M but there seems to be an issues - the following code found on wbe
; http://www.autoitscript.com/forum/topic/125359-solved-send-ctrlm-leaves-ctrl-pressed-in-some-way/
Send("{LCTRL down}")
Send("{m down}")
Sleep(500)
Send("{m up}")
Send("{LCTRL up}")
WinWaitActive("New Element","") ; wait for dialog to present
Send("Class 1") ; enter name of new class
Sleep(500)
ControlClick("New Element","Save",1) ; save the class dialog
; close EA
$Closed= ProcessClose($PID)
EndFunc

This code could be improved and clearly if you were in production mode, where you needed to add lots of elements and other stuff, you would restructure with a proper design!

Running this script and inspecting the model we can see that the class element has been added together with the attribute added by my AddIn.

Model Contents after adding New Class

Model Contents after adding New Class

3. Checking the results

Now I want to have a means to check the results automatically, checking that the model has the required contents.

My initial approach was to use EA scripts which could be initiated by through the UI, however a combination of issues meant that I changed my approach. The issues were:

  1. Accessing the relevant scripts within the EA UI – one of the issues I did find using AutoIt was the ability to access a specific script; I guess that is more I need to explore in the the tool to do this accurately.
  2. Ensure that the scripts were present in the test model
  3. Wanting any checking to be independent of the creation scripts.
  4. AutoIt scripts could interact with COM and hence allow me to access the automation API

So with that decision made I created a simple script that would interact with EA, using the normal automation API, to open the test EA model and check that both the new element and its attribute had been added to our model. The code for this function below:

  • Opens an instance of EA
  • Looks for the element I have added
  • Checks that the AddIn has created the attribute for this element
Func CheckCreated()
$EARep = ObjCreate("EA.Repository")
$F = $EARep.OpenFile("C:\Users\adrian\Documents13 EA Related\WinTestChecks\WinTextCheck.eap")
Local $Models = $EARep.Models ; we only have one model
Local $Model = $EARep.Models.GetAt(0)
Local $Packages = $Model.Packages
$NumPackages = $Packages.Count
; now do the check for package "Package1" with "Class 1"
For $i = 0 to $NumPackages-1
	$P = $Packages($i)
	$N = $P.Name
	if $N = "Package1" Then
 		$Elements = $P.Elements
		 $NumElements = $Elements.Count
		 for $j = 0 to $NumElements -1
			   $Element = $Elements($j)
			   $ElementName = $Element.Name
			  if $ElementName = "Class 1" Then
 				   $Attributes = $Element.Attributes
				    $NumAttributes = $Attributes.Count
				    For $k = 0 to $NumAttributes - 1
					     $Attribute = $Attributes($K)
					     $AttributeName = $Attribute.Name
					     if $AttributeName = "New Attribute"  Then
						       ConsoleWrite("Attribute found" & @CRLF)
						       ConsoleWrite("Closing EA" & @CRLF)
						       $EARep.Close()
						       ConsoleWrite("====== Checks complete ======" & @CRLF)
						       return true
					     endif
			 	   Next
			   EndIf
		  Next
	 EndIf
Next
ConsoleWrite("Closing EA" & @CRLF)
$EARep.Close()
$EARep = 0
$EARep = ""
ConsoleWrite("====== Checks complete ======" & @CRLF)
return False
EndFunc

This did the trick (once again a piece of test code so for the real world would expect to see something a little more refined!)

Final script

Having got the separate parts working I created a script that calls these functions plus including some code to output results to a log file as illustrated below:

#include "AddStuff2EA.au3"
; Script Start - Add your code below here
ConsoleWrite("Starting EA test" & @CRLF)
;---------------
AddStuff2EA(")) ; we add a class to EA
;---------------
ConsoleWrite("Checking EA model" & @CRLF)
 ; log file
	$myfilename = 	"C:\Users\adrian\Documents\testingChecking.txt"
	$FSO = objCreate("Scripting.FileSystemObject")
	If $FSO.FileExists($myFileName) Then
  ; we want to open with append
		  $FileObject= $FSO.OpenTextFile ($myFileName, 8, True)
	Else
  		$FileObject = $FSO.CreateTextFile ($myFileName)
	EndIf
   ;Create new file (or replace an existing file)
   $FileObject.WriteLine("New log entry.. " & _NowTime())
;---------------
$CheckIt = CheckCreated() ; call function to check that the class we added PLUS the work done by the AddIn has been completed successfully
If $CheckIt  Then
	  ConsoleWrite("Item found" & @CRLF)
	  $FileObject.WriteLine("Item found")
Else
	  ConsoleWrite("Item NOT found" & @CRLF)
	  $FileObject.WriteLine("Item NOT found")
EndIf
;---------------
$FileObject.Close()
ConsoleWrite("xxxxx All done xxxxxx" & @CRLF)
Exit

If we now run this script we can see the output in the Console window.

Running test script within script editor

Running test script within script editor

We can see the outcome was successful but not that friendly.

What next?

This code was written as proof of concept to check capability rather than for production use. Furthermore, the scripts would need to be modified to:

  • Create (or copy a clean copy of) the initial EA model to ensure the same base
  • Handle the EA model names – and not rely on setting the model as default
  • Add other tests for the specific target AddIn

One useful feature of AutoIt is its capability to create a GUI interface, and thus for the execution of regression tests we could produce an application that was a little more friendly.

A useful tutorial “learning to script with AutoIt” includes a brief introduction to using the GUI functions.  In addition,and included with the AutoIt download, is a GUI Builder tool (Koda) which can help produce the GUI scripts.

Also AutoIt can be used compile the scripts into an executable, which can eliminate complexity that may be associated with running the tests for those without knowledge of AutoIt.

So to test this, and using Koda to help design to UI, I created a GUI application with my existing test scripts providing most of the functionality.  This simple GUI application is illustrated below.

AutoIt based GUI Tester presents a friendly test tool

AutoIt based GUI Tester presents a friendly test tool

Nothing fancy but straightforward to use.  A much more sophisticated application could be developed if required.  The plus is that the user simply starts a simple windows executable.

Conclusions

In this post I have explored the ability to automatic test EA AddIn.  Using AutoIt scripts to emulate the user input as well as interact with the EA automation API I have demonstrated that this is possible.

I found AutoIt straightforward to use and was impressed by its features.  Also it is a plus that it is freeware.

I hope that this post is of interest to those working with AddIns (as well as other areas) and would welcome your comments or feedback.

Adrian

Advertisements

More exploring scripts – looking at application interoperability

In my last post on scripting  I was looking at using scripts as part of customising EA.    When I finished the last post I was part way through my exploration of “Application Interoperability”. So let me continue, but I must warn you that in this post I won’t be covering too much that is unique to scripting, however it is nevertheless useful stuff that provides some groundwork for subsequent experiments into scripting.

Last time I looked at how a script can gain access to an application such as Excel which can operate as a COM server.  My next set of experiments looked into if and how scripts could interact with code that I’d developed outside of EA, for example, a windows application or from one of my own class libraries (DLL).

To provide a sense of what I was thinking about let me use a diagram to illustrate theses and other options I am exploring.  In the diagram I show EA and its repository together with several other components that may be treated within the current context as being “internal” to EA’s operating environment plus several components that clearly site “outside of the box”.   I have treated everything that EA knows about including any registered AddIns as being inside,  the others, which EA doesn’t know about, are outside.

To guide us through the experiments I have numbered the connections to represent each specific test; remember we are in the world of experimenting, so I am just illustrating capability, whether or not it is of any value is another story.

Overview of scripting scenarios to explore

Overview of scripting scenarios to explore

Overview of interoperability scenarios to explore

1. Calling my Class Library (DLL) from an EA script

This is a relatively straight forward case since it is just another example where we use our script to create an application object,  but in this case the object (DLL class) is one I created.  Of course, there are some rules, for example when we create our class library we must:

  • provide suitably accessible public methods
  • our library needs to be registered as a COM object so that Windows is aware of the class when our script wants to use it.

So here is the code for my class library – very simple.

 Public Class MyEACalledClass
 Public Sub New()
    MsgBox("Hello from my DLL")
 End Sub
 End Class

This class is compiled as a library and then registered for COM interop using regasm, this is the same way that we register an  EA AddIn – see my post One of our Addins is missing for more information.

And then within our EA model we can create a script that calls this class as illustrated in  the screen shot.  When the script runs we get the message box that we have in the class constructor.

Calling my own class library

Calling my own class library

So we have address case 1 – now into case 2.

(2) my DLL can access EA repository

We can extend the functionality of the class library (DLL) as we wish.  For example, we may want our library to perform some functions that involve interacting with the current EA repository.  To do this we simply need to:

  • Write the relevant EA code in our class library (linking with Interop.EA.dll)
  • At run time, we need the script to pass the current EA repository object to our class library

Below is a trivial example.  The setEAModel receives the current EA repository object which is stored locally and then the getEAModelInfo method interacts with EA and returns a value to the calling process, in our case as shown below a simple script.

Private myRepository As EA.Repository = Nothing
Public Sub setEAModel(pRepository As EA.Repository)
  myRepository = pRepository
End Sub
 Public Function getEAModelInfo() As String
 If myRepository IsNot Nothing Then
 Dim myInfoString As String = myRepository.ConnectionString
 Return myInfoString
 End If
 Return "No report"
 End Function

Here is an example script calling our class library and getting information back relating to the current repository.

Calling EA from our DLL

Calling EA from our DLL

Clearly we wouldn’t create a library to perform such a trivial task which can be done locally. However, there may be situations where you want other functions such as interacting with another application / service that cannot be done within a script, but doesn’t warrant the need to create an EA addin, and hence this could be an option.

 (3) / (4) Windows application using our class library and interacting with EA repository

The next 2 examples look at using a windows application as a EA client, firstly just accessing the EA repository and then accessing and running a script.

The first test case (3) of access our own DLL is purely windows and an everyday task for windows application developers, so no more on that.

As with any other windows application you need to ensure that you include the relevant library(s) that supports interoperating with EA ( Interop.EA.dll) which exists in the EA installation directory.  Then to connect to EA:

  1. Create a new EA.Repository object (e.g. myEARepository)
  2. Open your file( or EA server) using myRepository.OpenFile(filenamestring)
  3. Perform required functions as required.

If you are new to working with the EA API I would suggest getting a copy of Scripting Enterprise Architect by Thomas Kilian – it goes through most stuff that you may want to do when working with EA.  And if that isn’t sufficient then check out Sparx Systems Automation Forum

So why would we produce a windows application as an EA client? The simple reason is that you want to provide a client that performs specific functions that do not require the use of the EA UI, for example:

  • to reduce complexity for the user – I have developed clients that make it easy to work with an EA model, as illustrated below a very simple interface with an application that can be provided to new users or more specifically in my case to those resistant to starting to use EA
Example of an EA client

Example of an EA client

  • to provide interaction with a 3rd party application
  • to run automatically to perform some house keeping tasks on the repository – this allows the application to be scheduled with windows Task Scheduler.

BTW: In relation to working with EA I have found it really useful at time to produce a small windows application accessing EA as an external application.  I have developed a small template application which provides the basic infrastructure for interacting with EA, selecting and opening a repository and providing basic element functions that I continually reuse when testing stuff.

(5) Accessing and running EA script’s from the outside

For the final experiment today, I was looking at a means for an external windows application to make a call to EA, and for EA to run a requested script for us. For example, there can be scenarios when you want to run a script on an automatic basis.

As far as I can see EA doesn’t provide a means to open EA from a command line, run a script and close.  The nearest I can see is the Project Shortcut – which nearly fulfils the requirements except that it doesn’t appear to provide a means to run a suitable script of my choice.  Is there a mechanism?

Well in the meantime it looks like I will have to create an application that will open my repository and execute the scripts.  So how can this be done – well as I started I see it’s not a short answer so I’m going to dedicate my next post to that task, as well as look at possible interactions between EA Addins and EA scripts. I’m already writing it so won’t be long.

In the meantime I hope this was of interest.

Any queries about this or other scripting issues let me know as I could add them to my expanding list of scripting experiments.

All the best

Adrian

Customising EA – a 2nd look at scripting

Following on from my last post in which I provided an overview of the ways that you can customise EA, I have spent some time exploring more of the capabilities of EA scripting. Although I’ve used VBA extensively I’ve rarely used scripting either within EA or in a windows environment so I was keen to see how much you could really do.

I start by assuming that most of the stuff I do when accessing an EA project model with an EA AddIn can be done with scripting, however I needed to check this out as well as look at some other areas which are needed to support potential EA related applications.  Hence, look at scripting and how to interact with the user, system and other applications.

The mindmap below illustrates my target list and I warn you I don’t get to the end in this post. But let’s start and look at what I found during my exploring so far:

Explore the capabilities of scripting for each of these areas?

Explore the capabilities of scripting for each of these areas?

Well, let’s start and look at what I’ve found so far  – basically items 1 .. 7  – where my aim for each is as follows:

  • User Interface – what can I do in providing the user with information and getting results back
  • Library access – what existing code exists that I can use and what capabilities does it offer

External access – can EA scripts interact with stuff outside of EA for example:

  • File access – can I read / write files?
  • Network access – what communication capabilities exist?
  • System access – what services exist?
  • Application interoperability- can I interact with other applications e.g. Office

I’ll now outline what I found and in a future posts look at the missing items as well as resolve some of my outstanding issues.

In each of the areas I’ve been testing using VBScript, and assume but not tested, that the functionality I outline is available with the other scripting engines; that may be a very bold statement!  Also you need to remember in writing the code it’s important to note that VBScript is not VB,  as I found out and I often needed to check the syntax.

1. EA model access

This is the area I expected all to work but wanted to check access to packages, elements, diagrams etc and that information can be exchanged between the script and EA projec. To do these tests I used the code samples provided in the EA manual and, with making relevant syntax changes, all seemed to work fine.  No surprises and none expected so that was a good start.

Key to the operation is access to the currently open repository through a predefined object “Repository”.  Methods are selectable using Intelli-sense with access to the help file for access to the EA Object Model reference material. All fine so far.

2. User Interface

For me the user interface is a key component,  so I was keen to understand what capabilities are available.  I half expected it to be a basic command line text interface but as you will see there is potential for much more.

To start with it is worth a moment looking at how a user will access scripts.  There are 2 basic mechanisms that I would expect to be used.

The scripting window access from Tools | Scripting which presents a list of the available scripts.  And either using the run button in the tool bar or context menu the user can run the script.

Running a script from the content menu

Running a script from the scripting list window

or from the context menu – in which case those scripts created for the relevant script group will be available i.e. if you create a script with a Diagram group then that script will only be available when working within a diagram.

Running a diagram script within the context of a diagram

Running a diagram script within the context of a diagram

So having got the script started in most cases there is a need to interact with the user whether asking questions, capturing data or presenting results.

To support this requirement EA provides a Session object which supports input, output and prompt methods which provide a basic capability e.g.

Session.Output “Some information for the user”

The prompt method can capture a result from user input.

Also provided with EA is a library of helper functions (EAScriptLib).  This is supplied as an MDG so if not present in your list of scripts then check your Settings | MDG Technologies to ensure that it has been enabled.

Enable the EAScriptLib

Enable the EAScriptLib

You then have a set of scripts functions available in several scripts in the EAScriptLib group.  You will need to look at the script source to see the available functions and usage information.

EA Script Library

EA Script Library

If you want to use any of the functions within these library files you will need to include the relevant library in your script e.g. !INC EAScriptLib.VBScript-Dialog before you can use it.

For example, a simple input box could be accessed as illustrated below.

EAScriptLib Input box

EAScriptLib Input box

When looking into other options I soon discovered there were more options.

For example, VBScript provides some standard functions such as

MsgBox(prompt[, buttons][, title][, helpfile, context])

I also found other functionality via the windows shell application object.  For example, using the BrowserForFolder to select a filename, and get its path.

Function BrowseForFile()
Dim shell : Set shell = CreateObject("Shell.Application")
Dim file : Set file = shell.BrowseForFolder(0, "Choose a file:", &H4000)
if (not file is nothing) then
BrowseForFile = file.self.Path
else
BrowseForFile = "No file selected"
end if
End Function

It soon became clear that it was possible to create quite sophisticated dialogs, although I found nothing as powerful as a custom form; perhaps I have missed something.

3. Libraries

As with most programming languages there are libraries of functions available for scripting, as you will have read I have already discovered a few. But when I started with VBScript I was unaware of the range of functions that were available and just a quick search on the Internet found many more.  For example, there are scripts covering most things that I needed including:

  • Hardware information
  • Messaging
  • Networking
  • Operating systems information
  • Security

Already we have seen that EA has its own Sparx provided EAScriptLib which provides some helper functions – see above for details.  Then there is the standard VBScript library ( see VBScript language reference at MSDN)  plus access there is access to a range of other application objects such as:

And with that I think I can do most of the tasks I need so onto a few tests.  A quick search provides examples for most of these.

4. File access

With the ability to interact with users and libraries available, accessing files should be straightforward.  And this was indeed the case. The function below worked fine –

Sub MakeHelloWorldFile (FileName)
'Create a new file in C: drive or overwrite existing file
Set FSO = CreateObject("Scripting.FileSystemObject")
If FSO.FileExists(FileName) Then
Answer = MsgBox("File " & FileName & " exists ... OK to overwrite?", vbOKCancel)
'If button selected is not OK, then quit now
If Answer <> vbOK Then Exit Sub
Else
'Confirm OK to create
Answer = MsgBox("File " & FileName & " ... OK to create?", vbOKCancel)
If Answer <> vbOK Then Exit Sub
End If
'Create new file (or replace an existing file)
Set FileObject = FSO.CreateTextFile (FileName)
' and put some content into the file
FileObject.WriteLine "Time ... " & Now()
FileObject.WriteLine "Hello, World"
FileObject.Close()
MsgBox "File " & FileName & " ... updated."
End Sub

With that I was happy that basic file functionality is available using the File System Object so left it there.

5. Network access

Next on the list was communication.  Perhaps a simple test to retrieve information from a web server, so try accessing a web page. Once again network access was straightforward using the HTTP request. For example, the few lines below were able to read a web page and output as text string.

Set o = CreateObject("MSXML2.XMLHTTP")
o.open "GET", "http://eaforms.exploringea.co.uk", False
o.send
' o.responseText now holds the response as a string.
Session.Output(o.responseText)

Looking at script examples I found there is clearly I much more functionality readily available whether it be parsing the content, sending emails,..

6. System access

Next I looked at system access, and this was probably the biggest surprise to me. How much could I do from scripts in terms of accessing and manipulating system information? Well it turns out that you can do a lot, although I suspect that windows security will prevent normal users doing anything catastrophic (I hope so!).

My findings were that EA can happily run the scripts that access all types of system tasks using WScript or get information using the winmgmts objects.

For example, using the File system object you can create a batch file and then using the shell object run the batch file. e.g.

Set objShell = CreateObject("Wscript.Shell")
objShell.run("%comspec% /c C:\Users\adrian\Documents\mybatchfile.cmd")

This was clearly an area with plenty of functionality that would go far beyond the normal day to day needs of the EA user.  For those interested there is plenty to explore – I stopped myself as I suspect I could have spend hours or even days as I have only scratched the surface.

7. Application interoperability

So to the area of greatest interest to me – applications working together.

Having used VBA more than a decade ago to transfer information from Excel to EA my first task was to discover what could be done the other way round, then look further at the general capabilities for interacting with external applications.

With the knowledge that it was possible to create an application object with VBScript, and my experience of writing several EA AddIns for MS Office products applications, I was confident that I should be able to connect.  And this was the case .

For an external application that is available as a COM server you can create a reference to the server, and use that to interact with the relevant files. In the case of Excel this is done as follows:

Set objExcel = CreateObject(“Excel.Application”)

And the following lines illustrate how to create a workbook, adding some dummy data into the worksheet and setting some cell formatting.

dim strFileName
dim objExcel
dim objWorkbook
dim objRange
strFileName = "C:\Users\adrian\Documents\c1.xls"
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = True
Set objWorkbook = objExcel.Workbooks.Add()
' now makes visible and then puts some data into the sheet
objExcel.Visible = True
objExcel.Workbooks.Add
objExcel.Cells(1, 1).Value = "Name"
objExcel.Cells(1, 1).Font.Bold = TRUE
objExcel.Cells(1, 1).Interior.ColorIndex = 30
objExcel.Cells(1, 1).Font.ColorIndex = 2
objExcel.Cells(2, 1).Value = "Test value 1"
objExcel.Cells(3, 1).Value = "Test value 2"
objExcel.Cells(4, 1).Value = "Test value 3"
objExcel.Cells(5, 1).Value = "Test value 4"
Set objRange = objExcel.Range("A1","A5")
objRange.Font.Size = 14
Set objRange = objExcel.Range("A2","A5")
objRange.Interior.ColorIndex = 36
Set objRange = objExcel.ActiveCell.EntireColumn
objRange.AutoFit()
objWorkbook.Saveas(strFileName)
objExcel.Quit

For other MS Office applications (Word, Project, Powerpoint, Outlook) the approach should be very similar, although I have not tested all.  But what other applications?  Using Create object I assume that a script could connect to any application that provide a COM interface.  So I started Visual Studio and looked at the COM references are available.  There are 100’s on my system, however I suspect that not all are available and/or useful.  I did test with a few application objects and soon realised that I have a lot more exploring to do in this area.  Although, I suspect, purely for general interest as I’m not sure many of these applications will be useful with EA. I’ll find out.

Roundup

Although there are still some areas, as listed on my mindmap, left to explore and I will get onto these in due course. However, as usual I’ve discovered some interesting stuff along the way which I want to explore further, and find some answers before moving onto the next  topic.  So I’ll leave it here for today, with some questions in my mind regarding application interoperability, and the promise that I’ll check out some more of the EA Scripting capabilities.

If you have experiences of scripting or questions feel free to add a comment.

Have fun EXploringEA

Adrian

 

Customising EA

In my last post I started to look at how we can access tools from within EA by customising the tools menu.  My plan was to continue looking  at accessing tools however in starting to pull together ideas for this post, I realised that I was going to be talking about stuff which may be new to some.  So I thought that I should step back and, rather than continue with detail, provide an overview of the range options that exist for customising or enhancing EA.  With that in place, it should make it easier to delve into the detail for each area in turn. I can then use this as a reference for my exploring (and posts).

An EA programming model

To help with the descriptions I’ll start by presenting a version of my EA programming model.   I always like a picture to help me understand the components and relationships.

Below is a diagram that provides my view of EA and the interfaces that it provides within the our current area of interest.

An EA Programming Model

My “EA Programming Model”

So let me describe each component in turn.

The Enterprise Architect world box within the green boundary contains those components that are within and managed by EA.  The boxes outside (green and brown) represent components that are outside of EA.  The EA Database is placed on the boundary as, by default, EA provides its own database engine to work with EAP files or could be configured to use a server based database, which would be completely outside of EA (please don’t complain about the detail of this point!)

So starting with the Enterprise Architect world box:

  • EA – represents the EA code, UI and all the bits I’m not going to discuss any further.
  • EA Database – already covered above, so no further discussion at present

Then possibly the 2 most important components for anybody enhancing EA:

  • The EA Object Model  presents an API through which other components can access information within the EA Model and perform a wide range of tasks.  It is through this interface that changes to the EA model (and underlying database are made).
  • The EA AddIn Framework supports the use of external code (DLL) to enhance the functionality of EA.  The ability to produce your own code that can be recognised and integrated with EA is a brilliant step in making EA the powerful and flexible tool it is. More on this later.

There is one more component in the box:

  • The Scripting engines.  EA provides several scripting engines that are accessed within the EA UI, and hence always within the context of the current EA model.  These scripts can make use of other libraries which are provided as well as access external services. NOTE: Scripting is not available in the Desktop or Professional editions, and not all libraries are provided in the Corporate edition.

So now let’s look outside of the green box:

  • The External Client Application represents a windows application that can connect to the EA Object Model API.  The function of these applications could be varied and really only limited to the imaginative of the developer.
  • My AddIn DLL represents the most powerful and flexible type of enhancement implemented between EA and 3rd party code. Using the EA Addin Framework the AddIn will be known to EA and becomes an integral part of the running process whose functionality defined by the developer.

From this brief outline we can now look at the capabilities of the key programmable components in some more detail.
Scripting

I’ll start with Scripting, which is probably the easiest means for enhancing EA, not least as the capability to write and run scripts is provided within EA.  The user can write scripts within EA using a either VBScript, JScript or JavaScript.

Here are the basic steps to getting going with scripting. You access the scripts and script editing use “Tools | scripting”.

There are different types of scripts within EA, used for different purposes.  A quick look at the group menu items lists the groups that are provided – illustrated below.

EA Script Types for different purposes

EA Script Types for different purposes

If you look at the scripts tab you will see scripts in these different groups.  You can select an existing group or create a new group and then create a new script – as below.  Note:  Some groups may be read-only.

Create a new script

Create a new script

If you double click or use the context menu you can now open the editor and start writing – illustrated below.

Example of newly created script

Example of newly created script

‘m not going to go into more detail at present, the point is just to illustrate how easy it is to start scripting.  You can look at the learning centre with EA to follow through the steps and create/debug your own scripts.

In addition to having the development tools to hand within EA, scripts have access to the current EA object model (referred to as EA within a script) as well as use of other supplied libraries (System and with the correct EA edition MathLib). In addition, Sparx provides, via an MDG its EAScriptLib, a set of helper functions in the libraries; list of help scripts provided illustrated below.

EAScripLib listing of libraries provided

EAScripLib listing of libraries provided

Scripting is very powerful and in my opinion great when you:

  • Have a well defined limited functionality (scripts do not provide a rich UI)
  • Want to do something quickly
  • What to test ideas or have a one-off task
  • Will need to make code changes regularly

Scripting can be applied to all aspects of the EA model. There are different script types to support different areas of EA which provides the necessary hooks to access these different types at the appropriate places

My use of scripting within EA has been limited so I’m keen to explore further. For example, with:

  • Searches – having used simple selections or SQL – what else if anything does the script offer?
  • Workflow – I did have a look at this when developing AddIns for MS Project, but decided at the time it wasn’t able to help with that work so kept all my code in the AddIn
  • UI Interface modelling Sparx provides some helper scripts for Win32 – so what do they do?
  • External access – I’ve written VBA (more later) in MS Office tools to access EA. I assume it will work the other way – does it? What else can I do?
  • Script UI capabilities – what can be done?

External Client application

EA presents its object model as a COM service, hence any client application that can act as a COM client could access EA. Applications could be written in wide range of languages such as VB.NET, C, C++, C#, Java… A standalone client can be tailored to meet your requirements with a UI and functionality to reflect the task in hand. For example, an application could be used to support data entry from users who don’t want to or need to use EA directly, or to transfer information between an EA model and a 3rd party application.

Also we mustn’t forget the power of some of our standard tools such as MS Office. These can act as client applications by using their own scripting capabilities to interact with the EA model. For example, I’ve used VBA scripts in Excel extensively to transfer information between the two tools.  The biggest challenge for me was the practical task of configuration management -tracking scripts.  To help with this issue you could employ an Excel  (Word …) AddIns, which does require more coding, but does help.  My own experience has been with an AddIn for MS-Project which provides project managers with access to information within the EA model whilst operating in their familiar environment.

But what else would I want to be do with a client application?

External App 2

In my programming model, I included a second external application which accesses the EA database directly.  This is possible and dependent on the requirement may be useful, HOWEVER – yes a big HOWEVER – in bypassing the EA Object Model API you open yourselves up to a set of risks which could result in corruption your model.  You should note that:

  • You need to ensure that any changes are complete, you may need to make changes to multiple tables, so ensure that you modify the relevant table entries correctly.
  • Sparx may make changes to the database which will require updates to you code to work correctly.  I’m not sure how one would monitor when these changes are made since it is internal to EA’s workings.

So if you ever consider working with the database directly you need to be careful. My only use of accessing the database directly has been to perform bulk name changes – it worked and the model survived (of course I did have a back up before so I could do a model comparison after the changes – good practice!)

EA AddIn’s

So now onto the EA AddIn which is potentially the most powerful enhancement and is at the top of the list in terms of integration with EA.  The EA Framework provides the means to:

  • Add your own menu items (EA extensions menu – available in the main menu, diagram context menu and project browser)
  • Add you own UI –  with your own windows/ dialogs or using EA’s Custom Views as either an EA AddIn window or an EA Tab.
  • Respond to EA events.  These normally happen as a consequence of user initiated actions (note unlike scripting the user is not explicitly calling the code directly). These events cover a range of situations such as:
    • Add-In Events – which primarily relate to the connection  between EA and the AddIn as well as calls relating to menus that the AddIn may provide
    • Broadcast Events – which primarily relate to changes initiated through user action in the EA UI such as creating, modifying, deleting items or MDG loading or activation or validating a model
    • MDG Events – associated with the operation of MDG’s the AddIn may support

The fact that the AddIn exists within the current context means that, like EA scripts, it has direct access to the current EA model.

An EA AddIn is developed as a DLL (Class library) that EA, if registered within windows and enabled within EA, will load at start-up ready for use.  The EA AddIn Framework defines the interface which the AddIn code can implement and if specific methods are provided by your class library then EA will make calls at the appropriate time for your code to perform its task. Not only can your code work with the EA Object Model to access the current EA model it can initiate and work with other running process e.g. Excel.

So if you need any of this capability you have no other choice. Although, on the downside, writing a simple AddIn may be a few hours work in my experience developing production tested products is much longer – I know since writing AddIns’s is my bread and butter!

Where next?

As I stated at the start of this post my aim has been to provide an overview of the capabilities EA has for customising EA and set out a road map for my explorations.  Below is a mindmap summarising the areas covered with a guide to some of the areas I need to look at.

Customising EA - items to explore

Customising EA – items to explore

If you have any related questions or topics for customising EA do let me know and, although I cannot guarantee I’ll find the answers, at least I can take a look see whilst EXploringEA.

Adrian

Just another little frustration but who am I to point fingers

Not sure if you have ever experienced it but this week I spent a few hours wondering how the EA API really does work.

I was trying to:

  • create a diagram
  • add an element and related diagram object to it
  • add a child element to the initial element and place a related diagram object within the initial object – important to note that I wanted the object to be contained and on top of the 1st object.

Straightforward  I thought.  I’ve created masses of diagrams so didn’t think much about it.  To my surprise didn’t quite go as expected. Debugging the code and looking at data all was working fine until I did an update to the diagram object for the 2nd object, whereupon both position data was modified and the sequence (z-order) was set to match the owing element.

Well I don’t think I missed anything in the documentation so clearly there are some assumptions that are being made by EA – which are not presented – but hey we all do that with code.

Its documentation again.  In one of my latest projects I’ve been thinking about how to improve the documentation, not for others but just for myself.  Yes I have all the code – however this doesn’t always help during the development, especially as the produce evolves to cope with moving goalposts.  I try to use EA, starting with a “nice” model and syncing code as I progress.  This can work fine with small developments however as they grow and the specification and design changes, it can become a bit of a mess, and to be honest I can give up on trying to maintain the integrity of the code/mode. Perhaps I’m just lazy or too impatient keen to produce the deliverables.

But the need to understand the assumptions and constraints is vital in ensuring that I as the user of the API do the right thing and that the product (e.g. EA) fulfills its part to the “contract”.

Is this a matter for the QA authority to pick up on?

Many decades ago as a young developer I was working on a project where I was instructed that as part of the process we had to present all our code, when we thought it was completed, to the QA manager.  So following a peer review off I went for my first meeting with Dave (who turned out to be a very experienced developer). His role as the QA manager role was to review my code and documentation and ensue that not only he could understand it but anybody else who may have to work on the project could.  So it soon became clear on my 1st visit that my work was not done!

Sort of seems right  – but I know from subsequent projects in different companies its rare to have formal peer reviews let alone in-depth reviews by a QA authority (even if you could find  them!)

I’ve seen posts which highlight the need to review between different versions of code at the design level.  Yes we can do a code “diff” but translating this back to the UML is an interesting task.  Perhaps an ideal topic for a research student – or one of those project I’ll put on the list for when I retire.

Well back to my initial problem – I did find a solution by creating the elements and diagram objects within the package and only after the creation of the diagram object change their parents to become children of the desired object.  For those interested I’ve put a short note with code example here – “EXploringEA_EAHowTo_CreateDiagramObjectsForChildElements

Of course, the fact that product companies don’t provide all the documentation required for developers has led to a massive market in “How to books”.

For those working with the EA API  you can get a good introduction to its innards from the  books by Thomas Kilan (Inside EA and Scripting EA)  – they don’t have all the answers (but who does), however they cover the key stuff and provide a great background.

Well with that little diversion I’ve got to get back on track to my current project.

Adrian