使用 DXL 从 Enterprise Architect 检索 "Variant" 数据类型

Retrieve "Variant" data type from Enterprise Architect using DXL

如何使用 DXL OLE 机制从 Enterprise Architect 12 获取图表的修改时间?

详情:

我想从 EA 检索图表并将它们作为 OLE 对象集成到 IBM Rational DOORS 9.5 中。这已经在工作了。我打算在检索图表之前比较 EA 图和 DOORS 对象的修改日期,以确定是否真的需要此操作。

问题是,EA 提供了图表属性 EA.Diagram.ModifiedDate,其中 returns 图表的修改日期为数据类型 Variant。我如何在 DXL 中处理这个问题? oleGet() 的结果参数可以是 string|int|bool|char|OleAutoObj 类型之一。没有结构化类型(可能是 DxlObject)。 string 和 int 参数在调用后都不包含任何有用的数据——只是空值。

测试代码:

OleAutoObj  eaRepository, eaProject, eaDiagram
OleAutoObj  eaApp    = oleGetAutoObject("EA.App")
OleAutoArgs autoArgs = create
string      guid     = "{729F140F-9DA4-4ff6-A9B2-75622AD1C22D}"

// connect to an existing EA instance
oleGet (eaApp, "Repository", eaRepository)
oleMethod (eaRepository, "GetProjectInterface", autoArgs, eaProject)

// call EA to a diagram which has this GUID
put(autoArgs, guid)
oleMethod(eaRepository, "GetDiagramByGuid", autoArgs, eaDiagram)
delete autoArgs

// access diagram attributes
string eaModifiedDate // DXL accepts [string|int|bool|char|OleAutoObj] only
oleGet(eaDiagram, "ModifiedDate", eaModifiedDate)
print "ModifiedDate = '" eaModifiedDate"'\n"

IBM 的支持团队(商业版,可供付费客户使用)无法提供帮助,建议将此问题转发给服务团队 (额外的$s)。比较失望。

试试这个(只是猜测 :-)

OleAutoObj eaModifiedDate
oleGet(diagram, "ModifiedDate", eaModifiedDate)
if (null eaModifiedDate)
    print "no eaModifiedDate\n"
else {
    string diaDate
    oleGet(eaModifiedDate, "Value", diaDate)
    print "ModifiedDate = '" diaDate"'\n"
}

如果这不起作用,那么最终的解决方法是:

string err
string result

put(autoArgs, "SELECT ModifiedDate FROM t_diagram WHERE ea_guid = '"  guid  "'")
err = oleMethod (eaRepository, "SQLQuery", autoArgs, result)
if (!null err)
    print "ERROR: " err "\n"
delete autoArgs

print "result= '" result"'\n"

这将 return 一个 XML 格式的字符串 (!),其中包含您喜欢的格式的日期。

编辑 1:原来 EA 的 SQLQuery 有问题,return只是日期。因为 Perl 以类似的方式处理 OLE 变体,所以我找到了这个代码片段:

my $dia = $rep->getdiagrambyguid("{63EFF3FA-0D5C-4986-AC0A-C723D2F755E3}");
my $value = $dia->ModifiedDate->Value;
print $value->Date( 'yyyy/MM/dd' );
print $value->Time( 'hh:mm:ss' );

所以 ModifiedDate 是一个 ole-object 并且有一个 Date 和一个 Time 方法。 应该也适用于 DXL。

编辑 2:现在这是终极解决方案,甚至可以绕过 EA 漏洞海洋的悬崖:

my $dia = $rep->SQLQuery("SELECT Format (ModifiedDate, \"Short Time\") AS T FROM t_diagram");

这会将日期格式化为时间字符串。根据 this page 适用于 EAP(又名 Mickeysoft Access)。其他 RDBMS 可能具有类似的功能。

对我在评论中的陈述进行了一些更正的更新。

我错了。使用 OLE 自动化接口 确实 可以接收结构化数据类型。正如 Thomas 提到的,OleAutoObject 是正确的 DXL return 类型,oleGet() 是正确的函数。要访问 returned 对象的属性,需要了解 "real" 数据类型并查看 SDK documentation 以了解哪些 class 属性可用,因为 DXL 不知道数据类型。

但是,在 DXL 中,检索结构化数据类型的属性有点麻烦。示例(旨在附加到初始 post 的代码):

OleAutoObj  diaLinksCollection
int         count    = -1
string      buffer   = ""

// access simple diagram attributes
err = oleGet(eaDiagram, "Version", buffer)      
if (!null err) print "ERROR in Diagram.Version: " err "\n"
print "diagram version = " buffer "\n"

// access structured diagram attribute
err = oleGet(eaDiagram, "DiagramLinks", diaLinksCollection)
if (!null err) print "ERROR in Diagram.DiagramLinks: " err "\n"

err = oleGet(diaLinksCollection, "Count", count)
if (!null err) print "ERROR in Collection.Count: " err "\n"

print "count = " count "\n"

因此,确实可以执行 SQL 查询,即使存储库驻留在纯 *.eap 文件中,请参阅 Thomas 的解决方法。

如前所述,无法使用 oleGet() 检索 Variant 数据类型,因为这种方法 return 是 NULL 结果。