Sparx Systems Forum
Enterprise Architect => Automation Interface, Add-Ins and Tools => Topic started by: bomber on March 16, 2017, 03:13:57 am
-
I have a VBA script and macro that pastes the selected EA diagram into Word. The script worked in EA7 but I recently upgraded to EA13. The GetCurrentDiagram always returns null even if a diagram is open in a single instance of EA running behind Word.
[tt]Sub InsertSelectedEADiagram()
Dim App As EA.App
Dim dDiagram As EA.Diagram
Dim sFilename As String
Dim sShape As InlineShape
Dim rep As New EA.Repository
Set App = GetObject("", "EA.App")
Set dDiagram = App.Repository.GetCurrentDiagram
' If dDiagram = Null Then
' MsgBox "No diagram selected"
' Exit Sub
' End If
sFilename = "d:\" & Str(dDiagram.DiagramID) & ".emf "
App.Project.PutDiagramImageToFile dDiagram.DiagramGUID, sFilename, 0
Set sShape = Application.Selection.InlineShapes.AddPicture(Filename:=sFilename, LinkToFile:=False, SaveWithDocument:=True)
sShape.AlternativeText = dDiagram.DiagramID
sShape.Width = sShape.Width * 0.7
sShape.Height = sShape.Height * 0.7
Set sShape = Nothing
Set dDiagram = Nothing
Set App = Nothing
End Sub[/tt]
-
I don't see any code that opens a diagram, so unless you have a default diagram setup it seems logical that it would return empty for current diagram.
Geert
-
The way this works is as follows:
I have EA open and I edit a diagram
Then I switch (Alt-Tab) to Word and run this macro script from a toolbar button. Then this macro takes the currently open diagram in EA, saves it to a file and inserts it into the document at that point. I could have used the clipboard, but at the time when I used EA 7, the clipboard rendering was bad.
This worked in EA 7 and my current EA 13 when referencing an old EA COM object, but after reinstalling my system after a HDD crash 2 days ago, these scripts did not work anymore. Now it references the latest EA Object Model 2.1.
Any suggestions?
EDIT: just to clarify, this script runs in Word VBA
-
Ok, I see, the Set App = GetObject("", "EA.App") connects to the running instance of EA.
Check if you by any chance have two ea.exe processes running. This GetObject operation only connects to the first ea.exe process started on the pc, so if you have any ghost processes running on the background it could be connecting to that process instead of the instance you are working on.
Geert
-
Hmm strange, this now works. Without me having to do anything. I did reboot so, this may have fixed it. Tx for the help..
-
Hmm this is still a problem. When I start off from new, I open Word and EA. In Task Manager there is 1 EA process running. Then when the Set App = GetObject("", "EA.App") runs, another instance of EA process appears. This is probably to be expected, but I am not sure. Then the script fails again as per the OP.
When I close EA, the new (2nd) process still runs and it has to be killed manually.
-
The example in my book uses
Set EAapp = GetObject(, "EA.App")
, so with no instead of an empty-string parameter. No idea whether that makes a difference.
q.
-
The example in my book uses Set EAapp = GetObject(, "EA.App")
, so with no instead of an empty-string parameter. No idea whether that makes a difference.
q.
Same here, this is the code I use in my excel importer to connect to the current repository. And ASAIK this has been working on all versions of EA;
'-------------------------------------------------------------
' Author: Geert Bellekens
' Date: 17/12/2007
' Description: Return the currently opened EA Model
'-------------------------------------------------------------
Public Function getCurrentRepository() As EA.Repository
Dim EAapp As EA.App
Dim EArepository As EA.Repository
Set EAapp = GetObject(, "EA.App")
'Warning when EA not open
If EAapp Is Nothing Then
MsgBox "Please Open Enterprise Architect"
'try again
Set getCurrentRepository = Me.getCurrentRepository
End If
'Warning when no repository is opened.
Set EArepository = EAapp.Repository
If EArepository Is Nothing Then
MsgBox "Please open a Model in Enterprise Architect"
'try again
Set getCurrentRepository = Me.getCurrentRepository
End If
'return the found repository
Set getCurrentRepository = EAapp.Repository
End Function
-
As the others have said, make the first parameter null. If that still fails to work, uninstall EA and see if the VBA code still compiles. If so, then you have a referencing problem in your VBA project. If it fails to compile, then your references are OK - reinstall and it should work.
Lastly, we've found that if the EA.exe link is setup as "Run as Administrator", the Set EAapp = GetObject(, "EA.App") will fail (anybody else seen this?).
HTH,
Paolo
-
Lastly, we've found that if the EA.exe link is setup as "Run as Administrator", the Set EAapp = GetObject(, "EA.App") will fail (anybody else seen this?).
I would expect that behavior unless running the script as administrator too. Windows won't let the script see processes owned by another user if not administrator. I don't know how the reverse would behave.
-
Lastly, we've found that if the EA.exe link is setup as "Run as Administrator", the Set EAapp = GetObject(, "EA.App") will fail (anybody else seen this?).
I would expect that behavior unless running the script as administrator too. Windows won't let the script see processes owned by another user if not administrator. I don't know how the reverse would behave.
Thanks, Simon,
When I get a chance - sometime this century, I hope - I'll check it out and confirm.
Paolo
-
Lastly, we've found that if the EA.exe link is setup as "Run as Administrator", the Set EAapp = GetObject(, "EA.App") will fail (anybody else seen this?).
I would expect that behavior unless running the script as administrator too. Windows won't let the script see processes owned by another user if not administrator. I don't know how the reverse would behave.
Not to mention completely different registry hives are loaded in that context. You maybe able to copy the relevant keys across to the security identifier that starts with S-1-5-21. But I wouldn't. You'd be better to create a proper user log in and run EA and then use the powershell stat-process cmdlet to run EA as that user.
-
Lastly, we've found that if the EA.exe link is setup as "Run as Administrator", the Set EAapp = GetObject(, "EA.App") will fail (anybody else seen this?).
I would expect that behavior unless running the script as administrator too. Windows won't let the script see processes owned by another user if not administrator. I don't know how the reverse would behave.
Not to mention completely different registry hives are loaded in that context. You maybe able to copy the relevant keys across to the security identifier that starts with S-1-5-21. But I wouldn't. You'd be better to create a proper user log in and run EA and then use the powershell stat-process cmdlet to run EA as that user.
I may not have been clear enough. It's the same user. If I start an EA instance (via shortcut) with [X] Run as Administrator set, the GetObject Fails. If the setting is unset, then it works.
Paolo
-
Lastly, we've found that if the EA.exe link is setup as "Run as Administrator", the Set EAapp = GetObject(, "EA.App") will fail (anybody else seen this?).
I would expect that behavior unless running the script as administrator too. Windows won't let the script see processes owned by another user if not administrator. I don't know how the reverse would behave.
Yes, noticed that too, and the explanation of Simon was exactly how I interpreted it. And it makes sense from a security standpoint.
And yes, if you are running your script/program as admin, and you want it to connect to the running instance of EA then you have to start EA as Admin as well, or it won't find the process.
That is not the fact when you want to debug your add-in and attach to the ea.exe process. In that case you can run your IDE as admin, and EA as regular user.
Geert
-
I may not have been clear enough. It's the same user. If I start an EA instance (via shortcut) with [X] Run as Administrator set, the GetObject Fails. If the setting is unset, then it works.
Actually I may be wrong about the security identifier changing, it may just be the token. Unfortunately I can't test it from my work machine. But in many ways it isn't the same user. There's quite a few moving parts to the security context in which a user starts a process.
-
Just to be clear, we have already started EA (it may or may not have been in [X] Run as Administrator). Then we decide to do something that requires our "Helper" in Excel. By default, this does NOT start in [X] Run as Administrator mode so if EA is in Administrator, it cannot find the EA instance. We don't start EA from the Helper.
Paolo
-
Just to be clear, we have already started EA (it may or may not have been in [X] Run as Administrator). Then we decide to do something that requires our "Helper" in Excel. By default, this does NOT start in [X] Run as Administrator mode so if EA is in Administrator, it cannot find the EA instance. We don't start EA from the Helper.
Install sysinternals process monitor (it's free) and see what actually is happening. From what you're saying it sounds like you're trying to be malware and hijack another process, but I may not be understanding you clearly. Process monitor should show you what is actually happening, and may even show you if you've ended up with two completely separate security contexts.
-
I have very similar issue, but when running script from EA Scripting.
I have opened diagram in EA. It is even selected in Project Browser.
While running script listed bellow I got the error "diagram is null"
!INC Local Scripts.EAConstants-JScript
function main()
{
var diagram as EA.Diagram;
diagram = Repository.GetCurrentDiagram();
Repository.ReloadDiagram(diagram.DiagramID); /* throws error: diagram is NULL */
}
main();
I can reference diagram using GUID and GetDiagramByGuid() method. Then it works.
What am I doing wrong?
-
The diagram must be visible. Just selecting it in the browser won't work.
q.
-
Didn't I write it's already opened? OK, I wasn't precize enough. It was opened and visible. No other diagrams were opened.
-
Was just making sure... Anyhow, this rather looks like an issue with the J(ava)Script itself. Unfortunately I can't help with that.
q.
-
OK. I'll try VB and let know.
I like more C-like syntax, that's why I used JavaScript.
-
Ah. Stupid me. When I ran the snippet, the script editor was in the focus :-( Running from the scripting tree it showed no issue.
q.
-
Nice find.
So it seems to be a bug.
-
Nice find.
So it seems to be a bug.
No, if you have a script in the main window then there is no Current Diagram.
Geert
-
Could you elaborate more?
From my understanding, once I open a diagram and let it shown, there is (have to be) current diagram.
What do you mean by 'script in the main window'? Do you mean, once I have opened script, then no diagram can be simultaneously visible?
I can do that by having scripting window floating (usually on second monitor). Then I can see an opened diagram being current.
Side-question: how to debug a script which uses GetCurrentDiagram method? ;)
-
I guess you can't debug that from inside EA. I'm using scripts that run outside EA where it's easily possible to do that.
q.
-
Could you elaborate more?
From my understanding, once I open a diagram and let it shown, there is (have to be) current diagram.
What do you mean by 'script in the main window'? Do you mean, once I have opened script, then no diagram can be simultaneously visible?
I can do that by having scripting window floating (usually on second monitor). Then I can see an opened diagram being current.
Side-question: how to debug a script which uses GetCurrentDiagram method? ;)
What if you have two floating diagram windows? Which one should EA then consider to be the current?
AFAIK GetCurrentDiagram only returns the visible diagram in the main window.
For debugging purposes you can float the script window instead of the diagram window and debug it like that.
Geert
-
Geert, I have written already: I have script window floating which causes described issue.
The diagram is docked to main window.
I have to check running scripts from outside, but I'm not sure it is possible to use JS language in this case.
-
Geert, I have written already: I have script window floating which causes described issue.
The diagram is docked to main window.
Sorry I must have missed that.
Anyway, what I usually do to debug my scripts is to comment out the call to the main function and create a "test" function.
In this test function, instead of getting the current diagram, I test my functionality with a specific diagram which I get based on it's GUID.
That allows me to test 99% of my script code. The only thing that I'm not able to test this way is the GetCurrentDiagram call itself, but I'm sure that works just fine.
Geert
-
There's always one of those diagram windows in FOCUS and that's what counts. If the scripting window is open and you start debugging from there it will be the "diagram" in question which for GetCurrentDiagram is no valid (so a Null) diagram.
q.
-
Yes, I understand how it works right now (or rather how it doesn't work, though).
IMO it should be considered as glitch, since GetCurrentDiagram() suggests nothing about focus nor working with other window which contain something else but diagram.
I'm going to report the issue.
Thank you for confirming the issue as well as pointing to workarounds.
-
AFAIK GetCurrentDiagram only returns the visible diagram in the main window.
Unfortunately, it's smarter/more annoying than that. A simple description would be that it is the last main window you have interacted with. That means that if you start a script using either the debug or run buttons on the script editor you will never have a current diagram, because that script editor will be the current view.