 <?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.analytica.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jhuawen</id>
	<title>Analytica Docs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.analytica.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jhuawen"/>
	<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php/Special:Contributions/Jhuawen"/>
	<updated>2026-05-19T14:16:18Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.9</generator>
	<entry>
		<id>https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36717</id>
		<title>The ADE Tutorial/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36717"/>
		<updated>2015-11-08T19:46:49Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南 ]]&lt;br /&gt;
&lt;br /&gt;
此教程教你如何在一个Visual Basic程序中使用Analytica决策引擎（ADE）。&lt;br /&gt;
&lt;br /&gt;
==你的第一个ADE应用程序==&lt;br /&gt;
首先先从头开始写一个简单的ADE程序，只要确认一切设置正常。按照以下步骤操作：&lt;br /&gt;
&lt;br /&gt;
test&lt;br /&gt;
&lt;br /&gt;
第一个程序执行了以下操作：&lt;br /&gt;
*建立一个名称为ADE的[[CAEngine/zh|CAEngine]]自动化对象（通过使用&amp;lt;code&amp;gt;new [[CAEngine/zh|CAEngine]]&amp;lt;/code&amp;gt;).&lt;br /&gt;
*打开Analytica模型 (通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]] 方法。&lt;br /&gt;
*显示模型名称返回[[CAEngine::OpenModel/zh|OpenModel]]的值。&lt;br /&gt;
我们将在后面的章节详细了解这些信息。&lt;br /&gt;
&lt;br /&gt;
===接下来讲什么呢?===&lt;br /&gt;
我们不会尝试在此入门教程中解释ADE的特征。本指南后面几个章节会描述这些特征。 &lt;br /&gt;
&lt;br /&gt;
从现在开始，我们我们将使用名称为&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;的示例模型。打开 Analytica安装目录下 '''Example Models'''文件夹里面的'''Risk Analysis'''文件夹便可找到&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;文件。如果你找不到，或者你安装Analytica的时候未选择安装examples（示例）文件，在ADE安装目录下面的'''Examples\Tutorial.NET'''文件家中有一个副本。 &lt;br /&gt;
&lt;br /&gt;
Txc模型演示了减少污染物TXC排放的risk-benefit （风险-效益）分析。请用Analytica打开Txc查看它是如何工作的。 &lt;br /&gt;
&lt;br /&gt;
ADE '''Examples\Tutorial.NET''' 文件夹中名称为&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;的Visual Basic.NET程序示例显示了ADE很多方面。该程序建立了一个ADE自动化对象，打开包含该对象的&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，获取变量 &amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，计算变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;，通过获取每个表格的单独组件以表格的方式打印输出变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的结果，然后改变变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义。再次获取变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的值，看一下 变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;定义的改变对变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;有什么影响。如果设置正确的话,&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;将显示在“Text Txc window”中显示的窗口。 &lt;br /&gt;
&lt;br /&gt;
应用程序显示变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义（&amp;lt;tt&amp;gt;&amp;quot;Normal (30M, 3M)&amp;quot;&amp;lt;/tt&amp;gt;），以及与&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;关联的表格，这都基于&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义。你可以通过从主菜单选择'''File &amp;gt; Change Population Exposed'''改变&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，然后查看改变对&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;表格的影响。&lt;br /&gt;
&lt;br /&gt;
[[File:TextTxcWindow.png|400px/zh | 文件：TextTxcWindow.png|400px]]&lt;br /&gt;
&lt;br /&gt;
===区分title（名称） 和 identifier（标识符）===&lt;br /&gt;
无论什么时候，一个ADE函数都需要一个变量你必须传达变量的'''''[[Identifier|标识符]]''''' ，而不是它的'''''[[Title|名称]]'''''。这可能会引起混淆，因为在Analytica影响图中一般显示每一个变量的名称。默认情况下，在你最初建立每一个对象的时候，Analytica自动根据名称建立一个标识符。用（_）代替名称中的每一个空格或者其他非字母和数字字符。 &lt;br /&gt;
&lt;br /&gt;
你可以通过点击“Control+y”（或者从Object（对象）菜单选择'''Show by identifier''' ：显示标识符） 来以标识符显示变量。对于模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;，你可以看到名称为&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;变量的标识符为 &amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;。将变量传递给ADE函数时，使用标识符很重要。如果你传递&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;，ADE无法找到变量，并且将返回一个错误。&lt;br /&gt;
&lt;br /&gt;
===从Visual Basic中建立一个ADE 对象===&lt;br /&gt;
&lt;br /&gt;
如果你还没准备好，将名称为tt&amp;gt;Examples\Tutorial\TestTxc.sln&amp;lt;/tt&amp;gt;载入到Visual Basic.NET中，查看名称为&amp;lt;tt&amp;gt;TestTxc.vb&amp;lt;/tt&amp;gt;的文件的代码。其代码看起来像：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Imports ADEW &lt;br /&gt;
:. . . &lt;br /&gt;
:Public adeEngine As [[CAEngine/zh|CAEngine]]&lt;br /&gt;
&lt;br /&gt;
:Public Sub Main() &lt;br /&gt;
::Dim exeDirectory, theModel As String &lt;br /&gt;
::Dim theModelString As String &lt;br /&gt;
::exeDirectory = VB6.GetPath &lt;br /&gt;
::theModel = exeDirectory &amp;amp; &amp;quot;\..\&amp;quot; &amp;amp; &amp;quot;Txc.ana&amp;quot; &lt;br /&gt;
::adeEngine = New [[CAEngine/zh|CAEngine]]&lt;br /&gt;
::... &lt;br /&gt;
::theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
::... &lt;br /&gt;
::frmMain.DefInstance.Show() &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在每一个文件的顶部的代码将自动化对象 '''adeEngine''' 声明为一个[[CAEngine/zh|CAEngine]] 对象。使用此对象，我们能够访问[[CAEngine/zh|CAEngine]] 展示的所有公共函数（参考 [[ADE Server Class Reference/zh|ADE服务器类型参考]] ）&lt;br /&gt;
&lt;br /&gt;
变量&amp;lt;tt&amp;gt;adeEngine&amp;lt;/tt&amp;gt;包含我们的进程内对象[[CAEngine/zh|CAEngine]]。如果我们想使用ADE的本地（进程外）服务器版本，我们可以将一个项目参考添加到'''Analytica Decision Engine Server 4.6 COM''' 组件并将顶部行从&amp;lt;tt&amp;gt;Imports ADEW&amp;lt;/tt&amp;gt;改成&amp;lt;tt&amp;gt;Imports ADE&amp;lt;/tt&amp;gt;即可。 &lt;br /&gt;
&lt;br /&gt;
这里是另一种获得一个先[[CAEngine/zh|CAEngine]]对象的方法。此循序不需要给项目添加参考。&amp;lt;tt&amp;gt;&lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADEW4.6.CAEngine&amp;quot;) ’ in-process &lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADE4.6.CAEngine&amp;quot;) ’ out-of-process &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果想理解使用进程内和进程外（或本地）服务器的利与弊，以及哪一种自动化服务器用于不同的场景，参考[[Using_the_Analytica_Decision_Engine_Server#In-process_vs_Out-of-process/zh | In-process vs. out-of-process]]&lt;br /&gt;
&lt;br /&gt;
===COM和 Automation 接口比较===&lt;br /&gt;
在上面的例子当中，我们使用COM接口调用ADE。在一个COM 接口中，对象 在本例中为[[CAEngine/zh|CAEngine]] 被声明为[[CAEngine/zh|CAEngine]] ，编译器解决每一个成员函数，并且在编译时间内能探测几个明显的错误。另外，Visual Studio可以提供方法和参数类型列表当，在你编程的时候可以当做一个提示工具，在编写使用ADE程序是非常有用。COM调用比Automation调用要快一点，但是在ADE应用程序中速度差异通常不是很重要。对于ADE 4.6我们推荐使用COM结构，只要你的语言支持。&lt;br /&gt;
&lt;br /&gt;
在VB Automation中，你可以将一个对象简单声明为Object（对象），而不是像[[CAEngine/zh|CAEngine]]、[[CAObject/zh|CAObject]]等更加具体的类型。当使用Automation调用'''ADE'''方法时，在运行时间内确定方法。在编译时间内，编译器不知道你的 '''ADE''' 对象是否有一个名称为[[CAEngine::OpenModel/zh|OpenModel]]的函数。在VB中，调用COM方法或Automation 方法的语法是相通的——唯一的不同在于对象类型是否明确被声明。&lt;br /&gt;
&lt;br /&gt;
在VC++和C#中，调用COM的语法和调用Automatio的语法不同。在这些情况下，COM要方便的多，Automation能够获得相冗余。然而，同样的语言，包括VBScript和其他脚本语言，只支持Automation不支持COM。&lt;br /&gt;
&lt;br /&gt;
===监视Process（进程）===&lt;br /&gt;
当使用进程外ADE服务器时，你的代码必须在终止时释放[[CAEngine/zh|CAEngine]]COM对象。当最终[[CAEngine/zh|CAEngine]]使用被释放时，ADE.exe 进程自动终止。到目前为止所看到的代码，VB语言在达到程序末端时，自动处理释放对象。但是，当你调试你的代码是，你可以提前终止你的程序来修复bug，你的程序可能被Task Manager（任务管理器）终止，或者你自己的代码也可能奔溃，导致你的程序进程在它有机会释放对象之前终止。因为COM对象从来不会被释放，ADE.exe进程不知道它是否在使用中，你的ADE.exe 进程没有任何进展。 &lt;br /&gt;
&lt;br /&gt;
为了避免这种情况发生，一种好的习惯就是在调用[[CAEngine/zh|CAEngine]]实例后 立即调用[[CAEngine::MonitorProcess/zh|CAEngine::MonitorProcess]]。通过这种方式，ADE能够得知哪一个进程正在使用它，同时将设置一个程序去探测你的进程是否在ADE被完全释放前终止。如果你的程序进程没有终止，ADE进程会立即将它关闭，消除了ADE没有进展的应用。 &lt;br /&gt;
&lt;br /&gt;
要从一个.NET应用程序获得进程ID，使用System.Diagnostics.Process namespace中的'''GetCurrentProcess().Id''' 。在其他语言中，你可以使用Windows SDK 的'''GetProcessId( )'''函数。 &lt;br /&gt;
&lt;br /&gt;
'''[[CAEngine::MonitorProcess/zh|MonitorProcess]]()''' 只能用来监视运行ADE进程的同一台计算机的进程，一次当通过DCOM运行ADE时不能使用。当使用进程内ADEW服务器时没有必要使用。&lt;br /&gt;
&lt;br /&gt;
==使用ADE打开模型==&lt;br /&gt;
我们现在打开&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，显示我们的应用程序主窗口。使用以下调用：tt&amp;gt;&lt;br /&gt;
:theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
:frmMain.DefInstance.Show &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]]函数打开模型。如果成功的话，变量&amp;lt;tt&amp;gt;theModelString&amp;lt;/tt&amp;gt;将包含模型的名字。否则，将包含一个空的串。虽然由于为了简介的缘故，我们没有这样做，但是你应该检查从[[CAEngine::OpenModel/zh|OpenModel]]函数返回的是不是一个空的串。如果是，说明在你打开的模型中存在一个错误。你可以使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]]属性找出是哪种错误 （&amp;lt;tt&amp;gt;adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] 和adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]&amp;lt;/tt&amp;gt;）。&lt;br /&gt;
&lt;br /&gt;
==从Analytica模型中检索对象==&lt;br /&gt;
下一步就是从我们的模型中检索对象（变量、模块、函数等），以便我们能获取他们的属性（[[definition|定义]]、[[title|名称]]、[[class|类型]]等等 ）。我们的示例模型（&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;）操作&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;和&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;对象。尤其是，修改&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;可以查看这是如何影响&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt; 对象。&lt;br /&gt;
&lt;br /&gt;
我们的&amp;lt;tt&amp;gt;TxcTest.vbproj&amp;lt;/tt&amp;gt; （&amp;lt;tt&amp;gt;TxcText.sln&amp;lt;/tt&amp;gt;）项目中的&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;文件里的 '''PrintAttributes''' 函数演示了如何检索对象。该函数首先被&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''Form_Load''' 函数调用，当应用程序启动后，可以显示'''Cost'''表格。当然无论什么时候，只要我们想输出'''Cost'''表格的当前值，都可以调用。该函数如下所示：&lt;br /&gt;
:Public Sub PrintAttributes(ByRef inputIdentifier As String, ByRef  outputIdentifier As String) &lt;br /&gt;
::Dim inputObject, outputObject As [[CAObject/zh|CAObject]]&lt;br /&gt;
::Dim resultTable As [[CATable/zh|CATable]]&lt;br /&gt;
::Dim definitionAttrInput As String &lt;br /&gt;
::inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
::outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier) &lt;br /&gt;
::definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;definition&amp;quot;) &lt;br /&gt;
::resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]]&lt;br /&gt;
::Call PrintResultTable(resultTable, inputIdentifier, definitionAttrInput, outputIdentifier) &lt;br /&gt;
::ReleaseComObject(resultTable) &lt;br /&gt;
::ReleaseComObject(inputObject) &lt;br /&gt;
::ReleaseComObject(outputObject) &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''PrintAttributes'''和作为'''inputIdentifier'''参数的&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;变量标识符以及作为'''outputIdentifier'''参数的'''Cost'''变量一起使用。如下所示通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::GetObjectByName/zh|GetObjectByName]]函数提取相应对象：&amp;lt;tt&amp;gt;&lt;br /&gt;
:inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取成功，将返回一个[[CAObject/zh|CAObject]]类型对象。如果使用'''[[CAObject/zh|CAObject]]'''的函数，参考[[CAObject/zh|SendCommand(command)]]，可以获得一个[[CAObject/zh|CAObject]]的完整函数列表。如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取失败，返回值为&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;。代码应该检查以确保[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取的结果是有效的。如果找不到，可使用[[CAEngine/zh|CAEngine]]的 [[CAEngine::ErrorCode/zh|ErrorCode]]和 [[CAEngine::ErrorText/zh|ErrorText]]属性获取错误信息。例如：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Set inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:If inputObject Is Nothing Then &lt;br /&gt;
::MsgBox(“This error from GetObjectByName occurred: “&amp;amp; _ vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &amp;amp; “:” &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) &lt;br /&gt;
:Else &lt;br /&gt;
::'inputObject valid &lt;br /&gt;
:End If&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===获取对象属性===&lt;br /&gt;
每一个Analytica对象都有一组属性，例如[[identifier|标识符]]、[[title|名称]]、[[description| 描述]]和[[class|类型]]。你可以使用[[CAObject::GetAttribute/zh|GetAttribute]]函数来获去Analytica对象的属性。例如，如要获取'''inputObject'''的定义（当前为cost）：&amp;lt;tt&amp;gt;&lt;br /&gt;
:definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh|GetAttribute]](&amp;quot;[[Definition|定义]]&amp;quot;) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt; 中，&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;的定义为&amp;quot;&amp;lt;tt&amp;gt;[[Normal]](30M, 3M)&amp;lt;/tt&amp;gt;&amp;quot; ，我们将它储存在'''definitionAttrInput'''当中。.&lt;br /&gt;
&lt;br /&gt;
===计算对象和检索结果===&lt;br /&gt;
使用[[CAObject/zh|CAObject]]的[[CAObject::Result/zh|Result]]或[[CAObject::ResultTable/zh|ResultTable]]方法来获取变量的值。如果有必要的话，ADE先自动计算变量。如果你确定结果为基元（只有一个元素），使用[[CAObject::Result/zh|Result]]方法。否则使用[[CAObject::ResultTable/zh|ResultTable]]，检索结果为一个''数组''。基元结果当作一个特殊数组案例来处理，没有维度的数组。如果值为基元[[CATable::AtomicValue/zh|AtomicValue]]方法将返回一个数字或者字符串单一值。 &lt;br /&gt;
&lt;br /&gt;
默认情况下，[[CAObject::Result/zh|Result]]和[[CAObject::ResultTable/zh|ResultTable]]返回结果的中值，也就是说，ADE以确定性方式计算结果。对于一个概率值，将[[CAObject/zh|CAObject]]的[[CAObject::ResultType/zh|ResultType]]属性设置为想要的不确定性视图——Mean（平均值） Sample（样本）、PDF（概率密度函数）、CDF（累计分布函数）、Confidence bands（置信带）、或者Statistics（统计数据）详情请参考[[CAObject::ResultType/zh|ResultType]]。我们通过如下的方式获取outputObject 输出对象 的值：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]] &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
结果为一个[[CATable/zh|CATable]]对象，允许我们访问一个表格中的单个元素。 &lt;br /&gt;
&lt;br /&gt;
如果你通过调用[[CAObject::Result/zh|Result]]来获取一个数组（或者表格）的值，将返回数组为一个字符串，列出索引和元素，以逗号隔开。通常使用[[CAObject::ResultTable/zh|ResultTable]]更加简单，这样你没有必要从字符串中解析表格的元素。&lt;br /&gt;
&lt;br /&gt;
===获取表格索引元素===&lt;br /&gt;
一个Analytica表格包含0个或者多个索引。如果包含一个索引，那么该表格是1维表格；如果有2个索引，说他是2维表格，依此类推。0维度表格包含一个“单一基元”（或标量）值。你可以使用CATable的[[CATable::NumDims/zh|NumDims]]获取表格的维数（也就是索引数）。要想获取表格的单个索引，可使用[[CATable/zh|CATable]]的 [[CATable::IndexNames/zh|IndexNames]]和 [[CATable::GetIndexObject/zh|GetIndexObject]]函数。 &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''PrintResultTable'''函数说明了这两个函数的使用。从'''PrintAttributes'''中调用'''PrintResultTable'''，执行打印'''TestTxc'''中的表格的实际工作（为了简洁起见，我们只给出了关联ADE的该函数部分）。&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Public Sub PrintResultTable(ByRef resultTable As CATable, ByRef inputIdentifier As String, ByRef definitionAttrInput As String, ByRef outputIdentifier As String) &lt;br /&gt;
::Dim theIndexName, theTableName As String &lt;br /&gt;
::Dim theIndexElement As String &lt;br /&gt;
::Dim theTableElement &lt;br /&gt;
::Dim theIndexObj As [[CAIndex/zh|CAIndex]]&lt;br /&gt;
::Dim numEls As Integer &lt;br /&gt;
::Dim spaces, i As Integer &lt;br /&gt;
::Dim lenStr As Short &lt;br /&gt;
::Dim OutputStr As Short &lt;br /&gt;
::Dim spaceString, underlineString As String &lt;br /&gt;
::... &lt;br /&gt;
::theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1) &lt;br /&gt;
::theTableName = resultTable.[[CATable::Name/zh|Name]] &lt;br /&gt;
::theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName) &lt;br /&gt;
::numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
::... &lt;br /&gt;
::For i = 1 To numEls &lt;br /&gt;
:::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
:::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
:::... &lt;br /&gt;
::Next i &lt;br /&gt;
::InformationPane.Text = outputString &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
通过'''PrintResultTable'''获取一个表格的索引方法如下：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1)&lt;br /&gt;
:theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
我们通过使用[[CATable/zh|CATable]]的[[CATable::IndexNames/zh|IndexNames]]函数获取第一个索引的名字。我们将它传递给[[CATable/zh|CATable]]的[[CATable::GetIndexObject/zh|GetIndexObject]]函数以获取表示我们的索引的[[CAIndex/zh|CAIndex]]。该自动化对象返回其相应索引的相关信息。如果此函数调用失败，将返回&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;信息。在此情况下，使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]] 函数找出原因。&lt;br /&gt;
&lt;br /&gt;
==从CATable和CAIndex中获取信息==&lt;br /&gt;
[[PrintResultTable]]说明了如何从[[CATable/zh| CATable]]和[[CAIndex/zh|CAIndex]] 对象获取信息。该代码获取'''Cost'''表格的索引和表格元素：&lt;br /&gt;
: &amp;lt;tt&amp;gt;&lt;br /&gt;
:numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
:For i = 1 To numEls &lt;br /&gt;
::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
::... &lt;br /&gt;
:Next i &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[CAIndex/zh|CAIndex]]的[[CAIndex::IndexElements/zh|IndexElements]]属性返回第一个索引中的元素个数。[[CAIndex/zh|CAIndex]]的[[CAIndex::GetValueByNumber/zh|GetValueByNumber]]函数获取单个索引元素。 &lt;br /&gt;
&lt;br /&gt;
我们通过传递表格中元素的坐标，使用  [[CATable/zh|CATable]]的[[CATable::GetDataByElements/zh|GetDataByElements]]函数获取'''Cost'''表格对象的单个表格元素'''resultTable'''。 &lt;br /&gt;
&lt;br /&gt;
当我检索 [[CATable/zh|CATable]]对象中单个元素（'''resultTable'''）的时候，我们利用了该表格是一维的事实。因此，我们只需要传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个单一数（这个数代表表格中的位置）。但是，如果我们处理两个或者更多维度，我们必须传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个数组函数，并且指明我们要检索的表格元素的位置。因此，如果我们不想检索一个二维数组的position (4,3)位置的元素，我们可以这样写：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Dim W as Variant 'return element &lt;br /&gt;
:Dim IndexPtrs(1 To 2) As Variant 'position in table &lt;br /&gt;
::... &lt;br /&gt;
:IndexPtrs(1) = 4 &lt;br /&gt;
:IndexPtrs(2) = 3 &lt;br /&gt;
:W = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](IndexPtrs) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==控制基元值格式==&lt;br /&gt;
[[CATable/zh|CATable]]中的每个基元值可以是一个数、一个字符串，或者其它一些基本类型（''例如''：[[Null|空值]]、[[Undefined|未定义]]、[[Reference|参考]]，或 [[Handle|句柄]]。通过说明类型和值，它们作为''变体''被返回，这是一种Visual Basic能读懂的数据结构。[[CATable/zh|CATable]]的[[CATable::RenderingStyle|RenderingStyle]]属性控制Analytica基础值是如何映射到Visual Basic变体的。 &lt;br /&gt;
&lt;br /&gt;
例如：可以通过使用Analytica 模型的数字格式设置将一个数值返回成一个数字或者字符串。如果被指定格式，有一个选线控制是截断数字的位数，还是精确返回。 &lt;br /&gt;
&lt;br /&gt;
子程序[[PrintResultTable/zh|PrintResultTable]]在&amp;lt;tt&amp;gt;frmMain.vb&amp;lt;/tt&amp;gt;中载入,其渲染风格直接指明：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::NumberAsText/zh|NumberAsText]] = True &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::FullPrecision/zh|FullPrecision]] = False &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::StringQuotes/zh|StringQuotes]] = 2 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
第一行指明数值应该根据与结果对象有关的数字格式被格式化为文本。例如在其程序输出中，我们将看到&amp;lt;tt&amp;gt;30.103M&amp;lt;/tt&amp;gt;，而非&amp;lt;tt&amp;gt;30102995.6639812&amp;lt;/tt&amp;gt;，如果我们让Visual Basic将数值串联我们的结果字符串，将显示该结果。在此事件中，一个值为字符串的单元格出现在结果中，返回值将明确带双引号。对于[[CARenderingStyle/zh|CARenderingStyle]]对象中的所有可用属性，请参考[[CARenderingStyle/zh|CARenderingStyle]]。&lt;br /&gt;
&lt;br /&gt;
===其它访问表格的方式===&lt;br /&gt;
有几种访问多维表格[[CATable/zh|CATable]]中元素的方式。每一种都有可能在特定的场合使用起来比较方便。 &lt;br /&gt;
&lt;br /&gt;
第一种方式就是使用[[CATable/zh | CATable]]的 [[CATable::GetDataByElements/zh|GetDataByElements]]或[[CATable::GetDataByLabels/zh|GetDataByLabels]]方法，上面代码示例中有显示。在此情况下，利用你想获取的基元值的单元格位置。 &lt;br /&gt;
&lt;br /&gt;
第二种方式就是使用[[CATable/zh|CATable]][[CATable::Slice/zh|Slice]]或[[CATable::Subscript/zh | Subscript]]方法获取一个少一个维度的新[[CATable/zh|CATable]]对象。通过重复减少维度，最终将获得0维度，这时你将获得一个单一基元值。此时，[[CATable/zh|CATable]]的[[CATable::AtomicValue/zh|AtomicValue]]方法返回该值 。[[CATable::AtomicValue/zh|AtomicValue]]方法是唯一获取一个标值的方法（因为没有坐标位置）。如果你需要建立完整结果其中一个切片的图形图像，必须使用此方法。 &lt;br /&gt;
&lt;br /&gt;
第三种方式就是使用[[CATable/zh|CATable]]的[[CATable::GetSafeArray/zh|GetSafeArray]]方法，将多维数组转化成一个''安全数组''（或者一个.NET数组）。你可以在使用VB或者其它.NET语言直接处理多维数组。因为对于Analytica维度没有固定顺序，但是安全数组和.NET数组有一个明确的顺序，你必须先使用[[CATable/zh|CATable]]对象的[[CATable::SetIndexOrder/zh|SetIndexOrder]]方法在调用[[CATable::GetSafeArray/zh|GetSafeArray]]之前指明维度的顺序。注意如果你知道你的数组是一维的，那就没必要了。&lt;br /&gt;
&lt;br /&gt;
===修改对象===&lt;br /&gt;
一个自定义用户程序通常从一个用户或者其它外部源获取输入，以便转化成Analytica模型中的输入变量。你可以设定输入变量的定义或者通过使用定义表格来这样做。 &lt;br /&gt;
&lt;br /&gt;
'''TestTxc''' 说明了如何修改'''Pop_exp'''定义，此模型是一个影响结果变量Cost的模型输入。要想在该示例中设定该定义，从主菜单上选择'''File &amp;gt; Change Population'''。将出现一个对话框，如下图所示：&lt;br /&gt;
&lt;br /&gt;
[[File:RedefiningtheVariableDefinition.jpg|400px/zh|文件：RedefiningtheVariableDefinition.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
在信息栏中输入一个新定义并点击'''Ok'''确认。主窗口将显示一个新的Cost值。当点击该对话框中的'''Ok'''按钮时，调用了&amp;lt;tt&amp;gt;ChangeDef.frm&amp;lt;/tt&amp;gt;函数，然后调用[[PrintAttributes]]函数打印&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果。&lt;br /&gt;
&lt;br /&gt;
此函数类似于：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Private Sub OkButton_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles OkButton.Click &lt;br /&gt;
::Dim errorText As String&lt;br /&gt;
::Dim pop_exp_Object As [[CAObject/zh|CAObject]] &lt;br /&gt;
::Dim errorCode As Short &lt;br /&gt;
::Dim errorString As String &lt;br /&gt;
::newDefinition = PopExposedDef.Text &lt;br /&gt;
::pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
::pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]](&amp;quot;[[Definition]]&amp;quot;, newDefinition) &lt;br /&gt;
::errorCode = adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &lt;br /&gt;
::If errorCode &amp;lt;&amp;gt; 0 Then &lt;br /&gt;
:::MsgBox(&amp;quot;This error occurred while processing your definition: &amp;quot; &amp;amp; vbCrLf &amp;amp; vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) :::PopExposedDef.Focus()&lt;br /&gt;
::Else&lt;br /&gt;
:::Me.Close() &lt;br /&gt;
:::frmMain.DefInstance.PrintAttributes(&amp;quot;Pop_exp&amp;quot;, &amp;quot;Cost&amp;quot;) &lt;br /&gt;
::End If &lt;br /&gt;
::ReleaseComObject(pop_exp_Object) &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
该函数抓取了输入到'''New Definition''' 新定义给'''Population Exposed'''栏，并通过使用[[CAObject/zh|CAObject]]对象中的[[CAObject::SetAttribute/zh|SetAttribute]]函数将它设置给&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;对象。然后调用[[PrintAttributes/zh|PrintAttributes]]，以计算&amp;lt;tt&amp;gt;Cost object&amp;lt;/tt&amp;gt;，并打印新的结果。要想给变量&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;设定一个新定义，我们可以为&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;获取[[CAObject/zh|CAObject]]对象，然后将其定义设置成用户输入的定义。通过使用下面的代码来实现：&lt;br /&gt;
:pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
:pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]]( &amp;quot;[[Definition]]&amp;quot;, newDefinition )&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
无论什么时候调用[[CAObject::SetAttribute/zh|SetAttribute]]，都应该检查[[CAEngine/zh|CAEngine]]自动化对象（'''adeEngine'''）的[[CAEngine::ErrorCode/zh|ErrorCode]]，以免它的定义是非法的。尝试一下输入一个新定义，比如&amp;lt;code&amp;gt;[[Uniform]](25M,35M)&amp;lt;/code&amp;gt;，然后点击'''Ok'''。当&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;的定义被改变时， &amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果由ADE重新计算，此时'''ResultTable'''接下来调用给Cost变量（在应用程序窗口重新显示时）。&lt;br /&gt;
&lt;br /&gt;
使用ADE绘图&lt;br /&gt;
&lt;br /&gt;
通过Analytica 4.6使用相同的绘图引擎，你可以建立一个图表或者图形以显示一个数组值或者不确定值结果。在ADE4.6中，你可以使用 [[CATable/zh|CATable]]的[[CATable::GraphToFile/zh|GraphToFile]]和[[CATable::GraphToStream/zh|GraphToStream]]方法。图形可以以几种可能的图像格式返回，例如'''image/png'''、 '''image/bmp'''或者 '''image/jpeg'''。 &lt;br /&gt;
&lt;br /&gt;
从可用图形选项中选择的最简单方式就是使用Analytica打开你的模型。你可以实验设置各种默认设置或者替代选择的变量，看它们是如何工作的。但你选择了你想设置的选项，保存模型。当为每一个生成结果图形时，ADE将使用这些设置。 &lt;br /&gt;
&lt;br /&gt;
对于更高维度的结果，可能需要做一些必要工作，以便选择将绘制结果的切片和具体的轴（也就是相对于图例哪个维度作为X轴）。[[CATable/zh|CATable]]的[[CATable::Subscript/zh|Subscript]]或[[CATable::Slice/zh|Slice]]方法可以用来控制轴选择特殊的切片用来绘制，能够用来控制轴。详情请参考[[CATable/zh|CATable]]。在我们的&amp;lt;tt&amp;gt;Tutorial.NET&amp;lt;/tt&amp;gt;示例中，我们有一个一维结果（&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;），因此我们没有必要担心截取或者绕轴旋转。 &lt;br /&gt;
&lt;br /&gt;
[[CATable::GraphToStream/zh|GraphToStream]]方法被用来从ADE中直接转化图形图形到一个用户界面中。使用[[CATable::GraphToStream/zh|GraphToStream]]比起使用[[CATable::GraphToFile/zh|GraphToFile]]来要稍微复杂一点，因为[[CATable::GraphToFile/zh|GraphToFile]]除了需要文件名以外还需要其它一些信息，以便编写图形。要使用[[CATable::GraphToStream/zh|GraphToStream]]，我们必须在内存内设置一个流，允许ADE写入该留，然后从该留重建。因为.NET流和COM流不兼容，你必须使用ADE一同提供的[[StreamConnector]]类型.&amp;lt;tt&amp;gt;frmMain&amp;lt;/tt&amp;gt; 中的'''GraphResult_Click'''子程序演示了[[CATable::GraphToStream/zh|GraphToStream]]的使用。从主应用程序窗口选择 '''Graph Result'''菜单选项，结果将出现在一个如下所示的图形当中：&lt;br /&gt;
&lt;br /&gt;
[[File:resultgraph.jpg/zh|文件：resultgraph.jpg]]&lt;br /&gt;
&lt;br /&gt;
==结论==&lt;br /&gt;
&lt;br /&gt;
在此教程中，我们介绍了Analytica决策引擎的几个重要方面。我们看到了如何建立一个ADE服务器对象，使用ADE打开模型，获取模型中的单个对象、计算对象、获取表格中的元素，以及修改模型中的对象。但是ADE可以做的远不止这些。 &lt;br /&gt;
&lt;br /&gt;
我们希望你已经足够了解其基本特征，这样你现在才能独自开始探索更多新的高级特征。我们建议你现在开始阅读字教程的剩余部分以了解ADE能做什么。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
| [[Installation of ADE/zh|ADE 安装]] &amp;lt;- ||  [[The ADE Tutorial/zh|ADE 入门教程]] || -&amp;gt; [[Using the ADE Server/zh|使用ADE服务器]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36715</id>
		<title>The ADE Tutorial/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36715"/>
		<updated>2015-11-08T19:45:12Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南 ]]&lt;br /&gt;
&lt;br /&gt;
此教程教你如何在一个Visual Basic程序中使用Analytica决策引擎（ADE）。&lt;br /&gt;
&lt;br /&gt;
==你的第一个ADE应用程序==&lt;br /&gt;
首先先从头开始写一个简单的ADE程序，只要确认一切设置正常。按照以下步骤操作：&lt;br /&gt;
&lt;br /&gt;
test&lt;br /&gt;
&lt;br /&gt;
第一个程序执行了以下操作：&lt;br /&gt;
*建立一个名称为ADE的[[CAEngine/zh|CAEngine]]自动化对象（通过使用&amp;lt;code&amp;gt;new [[CAEngine/zh|CAEngine]]&amp;lt;/code&amp;gt;).&lt;br /&gt;
*打开Analytica模型 (通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]] 方法。&lt;br /&gt;
*显示模型名称返回[[CAEngine::OpenModel/zh|OpenModel]]的值。&lt;br /&gt;
我们将在后面的章节详细了解这些信息。&lt;br /&gt;
&lt;br /&gt;
===接下来讲什么呢?===&lt;br /&gt;
我们不会尝试在此入门教程中解释ADE的特征。本指南后面几个章节会描述这些特征。 &lt;br /&gt;
&lt;br /&gt;
从现在开始，我们我们将使用名称为&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;的示例模型。打开 Analytica安装目录下 '''Example Models'''文件夹里面的'''Risk Analysis'''文件夹便可找到&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;文件。如果你找不到，或者你安装Analytica的时候未选择安装examples（示例）文件，在ADE安装目录下面的'''Examples\Tutorial.NET'''文件家中有一个副本。 &lt;br /&gt;
&lt;br /&gt;
Txc模型演示了减少污染物TXC排放的risk-benefit （风险-效益）分析。请用Analytica打开Txc查看它是如何工作的。 &lt;br /&gt;
&lt;br /&gt;
ADE '''Examples\Tutorial.NET''' 文件夹中名称为&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;的Visual Basic.NET程序示例显示了ADE很多方面。该程序建立了一个ADE自动化对象，打开包含该对象的&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，获取变量 &amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，计算变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;，通过获取每个表格的单独组件以表格的方式打印输出变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的结果，然后改变变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义。再次获取变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的值，看一下 变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;定义的改变对变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;有什么影响。如果设置正确的话,&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;将显示在“Text Txc window”中显示的窗口。 &lt;br /&gt;
&lt;br /&gt;
应用程序显示变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义（&amp;lt;tt&amp;gt;&amp;quot;Normal (30M, 3M)&amp;quot;&amp;lt;/tt&amp;gt;），以及与&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;关联的表格，这都基于&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义。你可以通过从主菜单选择'''File &amp;gt; Change Population Exposed'''改变&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，然后查看改变对&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;表格的影响。&lt;br /&gt;
&lt;br /&gt;
[[File:TextTxcWindow.png|400px/zh | 文件：TextTxcWindow.png|400px]]&lt;br /&gt;
&lt;br /&gt;
===区分title（名称） 和 identifier（标识符）===&lt;br /&gt;
无论什么时候，一个ADE函数都需要一个变量你必须传达变量的'''''[[Identifier|标识符]]''''' ，而不是它的'''''[[Title|名称]]'''''。这可能会引起混淆，因为在Analytica影响图中一般显示每一个变量的名称。默认情况下，在你最初建立每一个对象的时候，Analytica自动根据名称建立一个标识符。用（_）代替名称中的每一个空格或者其他非字母和数字字符。 &lt;br /&gt;
&lt;br /&gt;
你可以通过点击“Control+y”（或者从Object（对象）菜单选择'''Show by identifier''' ：显示标识符） 来以标识符显示变量。对于模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;，你可以看到名称为&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;变量的标识符为 &amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;。将变量传递给ADE函数时，使用标识符很重要。如果你传递&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;，ADE无法找到变量，并且将返回一个错误。&lt;br /&gt;
&lt;br /&gt;
===从Visual Basic中建立一个ADE 对象===&lt;br /&gt;
&lt;br /&gt;
如果你还没准备好，将名称为tt&amp;gt;Examples\Tutorial\TestTxc.sln&amp;lt;/tt&amp;gt;载入到Visual Basic.NET中，查看名称为&amp;lt;tt&amp;gt;TestTxc.vb&amp;lt;/tt&amp;gt;的文件的代码。其代码看起来像：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Imports ADEW &lt;br /&gt;
:. . . &lt;br /&gt;
:Public adeEngine As [[CAEngine/zh|CAEngine]]&lt;br /&gt;
&lt;br /&gt;
:Public Sub Main() &lt;br /&gt;
::Dim exeDirectory, theModel As String &lt;br /&gt;
::Dim theModelString As String &lt;br /&gt;
::exeDirectory = VB6.GetPath &lt;br /&gt;
::theModel = exeDirectory &amp;amp; &amp;quot;\..\&amp;quot; &amp;amp; &amp;quot;Txc.ana&amp;quot; &lt;br /&gt;
::adeEngine = New [[CAEngine/zh|CAEngine]]&lt;br /&gt;
::... &lt;br /&gt;
::theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
::... &lt;br /&gt;
::frmMain.DefInstance.Show() &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在每一个文件的顶部的代码将自动化对象 '''adeEngine''' 声明为一个[[CAEngine/zh|CAEngine]] 对象。使用此对象，我们能够访问[[CAEngine/zh|CAEngine]] 展示的所有公共函数（参考 [[ADE Server Class Reference/zh|ADE服务器类型参考]] ）&lt;br /&gt;
&lt;br /&gt;
变量&amp;lt;tt&amp;gt;adeEngine&amp;lt;/tt&amp;gt;包含我们的进程内对象[[CAEngine/zh|CAEngine]]。如果我们想使用ADE的本地（进程外）服务器版本，我们可以将一个项目参考添加到'''Analytica Decision Engine Server 4.6 COM''' 组件并将顶部行从&amp;lt;tt&amp;gt;Imports ADEW&amp;lt;/tt&amp;gt;改成&amp;lt;tt&amp;gt;Imports ADE&amp;lt;/tt&amp;gt;即可。 &lt;br /&gt;
&lt;br /&gt;
这里是另一种获得一个先[[CAEngine/zh|CAEngine]]对象的方法。此循序不需要给项目添加参考。&amp;lt;tt&amp;gt;&lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADEW4.6.CAEngine&amp;quot;) ’ in-process &lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADE4.6.CAEngine&amp;quot;) ’ out-of-process &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果想理解使用进程内和进程外（或本地）服务器的利与弊，以及哪一种自动化服务器用于不同的场景，参考[[Using_the_Analytica_Decision_Engine_Server#In-process_vs_Out-of-process/zh | In-process vs. out-of-process]]&lt;br /&gt;
&lt;br /&gt;
===COM和 Automation 接口比较===&lt;br /&gt;
在上面的例子当中，我们使用COM接口调用ADE。在一个COM 接口中，对象 在本例中为[[CAEngine/zh|CAEngine]] 被声明为[[CAEngine/zh|CAEngine]] ，编译器解决每一个成员函数，并且在编译时间内能探测几个明显的错误。另外，Visual Studio可以提供方法和参数类型列表当，在你编程的时候可以当做一个提示工具，在编写使用ADE程序是非常有用。COM调用比Automation调用要快一点，但是在ADE应用程序中速度差异通常不是很重要。对于ADE 4.6我们推荐使用COM结构，只要你的语言支持。&lt;br /&gt;
&lt;br /&gt;
在VB Automation中，你可以将一个对象简单声明为Object（对象），而不是像[[CAEngine/zh|CAEngine]]、[[CAObject/zh|CAObject]]等更加具体的类型。当使用Automation调用'''ADE'''方法时，在运行时间内确定方法。在编译时间内，编译器不知道你的 '''ADE''' 对象是否有一个名称为[[CAEngine::OpenModel/zh|OpenModel]]的函数。在VB中，调用COM方法或Automation 方法的语法是相通的——唯一的不同在于对象类型是否明确被声明。&lt;br /&gt;
&lt;br /&gt;
在VC++和C#中，调用COM的语法和调用Automatio的语法不同。在这些情况下，COM要方便的多，Automation能够获得相冗余。然而，同样的语言，包括VBScript和其他脚本语言，只支持Automation不支持COM。&lt;br /&gt;
&lt;br /&gt;
===监视Process（进程）===&lt;br /&gt;
当使用进程外ADE服务器时，你的代码必须在终止时释放[[CAEngine/zh|CAEngine]]COM对象。当最终[[CAEngine/zh|CAEngine]]使用被释放时，ADE.exe 进程自动终止。到目前为止所看到的代码，VB语言在达到程序末端时，自动处理释放对象。但是，当你调试你的代码是，你可以提前终止你的程序来修复bug，你的程序可能被Task Manager（任务管理器）终止，或者你自己的代码也可能奔溃，导致你的程序进程在它有机会释放对象之前终止。因为COM对象从来不会被释放，ADE.exe进程不知道它是否在使用中，你的ADE.exe 进程没有任何进展。 &lt;br /&gt;
&lt;br /&gt;
为了避免这种情况发生，一种好的习惯就是在调用[[CAEngine/zh|CAEngine]]实例后 立即调用[[CAEngine::MonitorProcess/zh|CAEngine::MonitorProcess]]。通过这种方式，ADE能够得知哪一个进程正在使用它，同时将设置一个线程去探测你的进程是否在ADE被完全释放前终止。如果你的程序进程没有终止，ADE进程会立即将它关闭，消除了僵尸ADE进程的堆积。 &lt;br /&gt;
&lt;br /&gt;
要从一个.NET应用程序获得进程ID，使用System.Diagnostics.Process namespace中的'''GetCurrentProcess().Id''' 。在其他语言中，你可以使用Windows SDK 的'''GetProcessId( )'''函数。 &lt;br /&gt;
&lt;br /&gt;
'''[[CAEngine::MonitorProcess/zh|MonitorProcess]]()''' 只能用来监视运行ADE进程的同一台计算机的进程，一次当通过DCOM运行ADE时不能使用。当使用进程内ADEW服务器时没有必要使用。&lt;br /&gt;
&lt;br /&gt;
==使用ADE打开模型==&lt;br /&gt;
我们现在打开&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，显示我们的应用程序主窗口。使用以下调用：tt&amp;gt;&lt;br /&gt;
:theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
:frmMain.DefInstance.Show &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]]函数打开模型。如果成功的话，变量&amp;lt;tt&amp;gt;theModelString&amp;lt;/tt&amp;gt;将包含模型的名字。否则，将包含一个空的串。虽然由于为了简介的缘故，我们没有这样做，但是你应该检查从[[CAEngine::OpenModel/zh|OpenModel]]函数返回的是不是一个空的串。如果是，说明在你打开的模型中存在一个错误。你可以使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]]属性找出是哪种错误 （&amp;lt;tt&amp;gt;adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] 和adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]&amp;lt;/tt&amp;gt;）。&lt;br /&gt;
&lt;br /&gt;
==从Analytica模型中检索对象==&lt;br /&gt;
下一步就是从我们的模型中检索对象（变量、模块、函数等），以便我们能获取他们的属性（[[definition|定义]]、[[title|名称]]、[[class|类型]]等等 ）。我们的示例模型（&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;）操作&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;和&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;对象。尤其是，修改&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;可以查看这是如何影响&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt; 对象。&lt;br /&gt;
&lt;br /&gt;
我们的&amp;lt;tt&amp;gt;TxcTest.vbproj&amp;lt;/tt&amp;gt; （&amp;lt;tt&amp;gt;TxcText.sln&amp;lt;/tt&amp;gt;）项目中的&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;文件里的 '''PrintAttributes''' 函数演示了如何检索对象。该函数首先被&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''Form_Load''' 函数调用，当应用程序启动后，可以显示'''Cost'''表格。当然无论什么时候，只要我们想输出'''Cost'''表格的当前值，都可以调用。该函数如下所示：&lt;br /&gt;
:Public Sub PrintAttributes(ByRef inputIdentifier As String, ByRef  outputIdentifier As String) &lt;br /&gt;
::Dim inputObject, outputObject As [[CAObject/zh|CAObject]]&lt;br /&gt;
::Dim resultTable As [[CATable/zh|CATable]]&lt;br /&gt;
::Dim definitionAttrInput As String &lt;br /&gt;
::inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
::outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier) &lt;br /&gt;
::definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;definition&amp;quot;) &lt;br /&gt;
::resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]]&lt;br /&gt;
::Call PrintResultTable(resultTable, inputIdentifier, definitionAttrInput, outputIdentifier) &lt;br /&gt;
::ReleaseComObject(resultTable) &lt;br /&gt;
::ReleaseComObject(inputObject) &lt;br /&gt;
::ReleaseComObject(outputObject) &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''PrintAttributes'''和作为'''inputIdentifier'''参数的&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;变量标识符以及作为'''outputIdentifier'''参数的'''Cost'''变量一起使用。如下所示通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::GetObjectByName/zh|GetObjectByName]]函数提取相应对象：&amp;lt;tt&amp;gt;&lt;br /&gt;
:inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取成功，将返回一个[[CAObject/zh|CAObject]]类型对象。如果使用'''[[CAObject/zh|CAObject]]'''的函数，参考[[CAObject/zh|SendCommand(command)]]，可以获得一个[[CAObject/zh|CAObject]]的完整函数列表。如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取失败，返回值为&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;。代码应该检查以确保[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取的结果是有效的。如果找不到，可使用[[CAEngine/zh|CAEngine]]的 [[CAEngine::ErrorCode/zh|ErrorCode]]和 [[CAEngine::ErrorText/zh|ErrorText]]属性获取错误信息。例如：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Set inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:If inputObject Is Nothing Then &lt;br /&gt;
::MsgBox(“This error from GetObjectByName occurred: “&amp;amp; _ vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &amp;amp; “:” &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) &lt;br /&gt;
:Else &lt;br /&gt;
::'inputObject valid &lt;br /&gt;
:End If&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===获取对象属性===&lt;br /&gt;
每一个Analytica对象都有一组属性，例如[[identifier|标识符]]、[[title|名称]]、[[description| 描述]]和[[class|类型]]。你可以使用[[CAObject::GetAttribute/zh|GetAttribute]]函数来获去Analytica对象的属性。例如，如要获取'''inputObject'''的定义（当前为cost）：&amp;lt;tt&amp;gt;&lt;br /&gt;
:definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh|GetAttribute]](&amp;quot;[[Definition|定义]]&amp;quot;) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt; 中，&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;的定义为&amp;quot;&amp;lt;tt&amp;gt;[[Normal]](30M, 3M)&amp;lt;/tt&amp;gt;&amp;quot; ，我们将它储存在'''definitionAttrInput'''当中。.&lt;br /&gt;
&lt;br /&gt;
===计算对象和检索结果===&lt;br /&gt;
使用[[CAObject/zh|CAObject]]的[[CAObject::Result/zh|Result]]或[[CAObject::ResultTable/zh|ResultTable]]方法来获取变量的值。如果有必要的话，ADE先自动计算变量。如果你确定结果为基元（只有一个元素），使用[[CAObject::Result/zh|Result]]方法。否则使用[[CAObject::ResultTable/zh|ResultTable]]，检索结果为一个''数组''。基元结果当作一个特殊数组案例来处理，没有维度的数组。如果值为基元[[CATable::AtomicValue/zh|AtomicValue]]方法将返回一个数字或者字符串单一值。 &lt;br /&gt;
&lt;br /&gt;
默认情况下，[[CAObject::Result/zh|Result]]和[[CAObject::ResultTable/zh|ResultTable]]返回结果的中值，也就是说，ADE以确定性方式计算结果。对于一个概率值，将[[CAObject/zh|CAObject]]的[[CAObject::ResultType/zh|ResultType]]属性设置为想要的不确定性视图——Mean（平均值） Sample（样本）、PDF（概率密度函数）、CDF（累计分布函数）、Confidence bands（置信带）、或者Statistics（统计数据）详情请参考[[CAObject::ResultType/zh|ResultType]]。我们通过如下的方式获取outputObject 输出对象 的值：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]] &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
结果为一个[[CATable/zh|CATable]]对象，允许我们访问一个表格中的单个元素。 &lt;br /&gt;
&lt;br /&gt;
如果你通过调用[[CAObject::Result/zh|Result]]来获取一个数组（或者表格）的值，将返回数组为一个字符串，列出索引和元素，以逗号隔开。通常使用[[CAObject::ResultTable/zh|ResultTable]]更加简单，这样你没有必要从字符串中解析表格的元素。&lt;br /&gt;
&lt;br /&gt;
===获取表格索引元素===&lt;br /&gt;
一个Analytica表格包含0个或者多个索引。如果包含一个索引，那么该表格是1维表格；如果有2个索引，说他是2维表格，依此类推。0维度表格包含一个“单一基元”（或标量）值。你可以使用CATable的[[CATable::NumDims/zh|NumDims]]获取表格的维数（也就是索引数）。要想获取表格的单个索引，可使用[[CATable/zh|CATable]]的 [[CATable::IndexNames/zh|IndexNames]]和 [[CATable::GetIndexObject/zh|GetIndexObject]]函数。 &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''PrintResultTable'''函数说明了这两个函数的使用。从'''PrintAttributes'''中调用'''PrintResultTable'''，执行打印'''TestTxc'''中的表格的实际工作（为了简洁起见，我们只给出了关联ADE的该函数部分）。&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Public Sub PrintResultTable(ByRef resultTable As CATable, ByRef inputIdentifier As String, ByRef definitionAttrInput As String, ByRef outputIdentifier As String) &lt;br /&gt;
::Dim theIndexName, theTableName As String &lt;br /&gt;
::Dim theIndexElement As String &lt;br /&gt;
::Dim theTableElement &lt;br /&gt;
::Dim theIndexObj As [[CAIndex/zh|CAIndex]]&lt;br /&gt;
::Dim numEls As Integer &lt;br /&gt;
::Dim spaces, i As Integer &lt;br /&gt;
::Dim lenStr As Short &lt;br /&gt;
::Dim OutputStr As Short &lt;br /&gt;
::Dim spaceString, underlineString As String &lt;br /&gt;
::... &lt;br /&gt;
::theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1) &lt;br /&gt;
::theTableName = resultTable.[[CATable::Name/zh|Name]] &lt;br /&gt;
::theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName) &lt;br /&gt;
::numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
::... &lt;br /&gt;
::For i = 1 To numEls &lt;br /&gt;
:::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
:::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
:::... &lt;br /&gt;
::Next i &lt;br /&gt;
::InformationPane.Text = outputString &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
通过'''PrintResultTable'''获取一个表格的索引方法如下：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1)&lt;br /&gt;
:theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
我们通过使用[[CATable/zh|CATable]]的[[CATable::IndexNames/zh|IndexNames]]函数获取第一个索引的名字。我们将它传递给[[CATable/zh|CATable]]的[[CATable::GetIndexObject/zh|GetIndexObject]]函数以获取表示我们的索引的[[CAIndex/zh|CAIndex]]。该自动化对象返回其相应索引的相关信息。如果此函数调用失败，将返回&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;信息。在此情况下，使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]] 函数找出原因。&lt;br /&gt;
&lt;br /&gt;
==从CATable和CAIndex中获取信息==&lt;br /&gt;
[[PrintResultTable]]说明了如何从[[CATable/zh| CATable]]和[[CAIndex/zh|CAIndex]] 对象获取信息。该代码获取'''Cost'''表格的索引和表格元素：&lt;br /&gt;
: &amp;lt;tt&amp;gt;&lt;br /&gt;
:numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
:For i = 1 To numEls &lt;br /&gt;
::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
::... &lt;br /&gt;
:Next i &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[CAIndex/zh|CAIndex]]的[[CAIndex::IndexElements/zh|IndexElements]]属性返回第一个索引中的元素个数。[[CAIndex/zh|CAIndex]]的[[CAIndex::GetValueByNumber/zh|GetValueByNumber]]函数获取单个索引元素。 &lt;br /&gt;
&lt;br /&gt;
我们通过传递表格中元素的坐标，使用  [[CATable/zh|CATable]]的[[CATable::GetDataByElements/zh|GetDataByElements]]函数获取'''Cost'''表格对象的单个表格元素'''resultTable'''。 &lt;br /&gt;
&lt;br /&gt;
当我检索 [[CATable/zh|CATable]]对象中单个元素（'''resultTable'''）的时候，我们利用了该表格是一维的事实。因此，我们只需要传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个单一数（这个数代表表格中的位置）。但是，如果我们处理两个或者更多维度，我们必须传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个数组函数，并且指明我们要检索的表格元素的位置。因此，如果我们不想检索一个二维数组的position (4,3)位置的元素，我们可以这样写：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Dim W as Variant 'return element &lt;br /&gt;
:Dim IndexPtrs(1 To 2) As Variant 'position in table &lt;br /&gt;
::... &lt;br /&gt;
:IndexPtrs(1) = 4 &lt;br /&gt;
:IndexPtrs(2) = 3 &lt;br /&gt;
:W = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](IndexPtrs) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==控制基元值格式==&lt;br /&gt;
[[CATable/zh|CATable]]中的每个基元值可以是一个数、一个字符串，或者其它一些基本类型（''例如''：[[Null|空值]]、[[Undefined|未定义]]、[[Reference|参考]]，或 [[Handle|句柄]]。通过说明类型和值，它们作为''变体''被返回，这是一种Visual Basic能读懂的数据结构。[[CATable/zh|CATable]]的[[CATable::RenderingStyle|RenderingStyle]]属性控制Analytica基础值是如何映射到Visual Basic变体的。 &lt;br /&gt;
&lt;br /&gt;
例如：可以通过使用Analytica 模型的数字格式设置将一个数值返回成一个数字或者字符串。如果被指定格式，有一个选线控制是截断数字的位数，还是精确返回。 &lt;br /&gt;
&lt;br /&gt;
子程序[[PrintResultTable/zh|PrintResultTable]]在&amp;lt;tt&amp;gt;frmMain.vb&amp;lt;/tt&amp;gt;中载入,其渲染风格直接指明：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::NumberAsText/zh|NumberAsText]] = True &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::FullPrecision/zh|FullPrecision]] = False &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::StringQuotes/zh|StringQuotes]] = 2 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
第一行指明数值应该根据与结果对象有关的数字格式被格式化为文本。例如在其程序输出中，我们将看到&amp;lt;tt&amp;gt;30.103M&amp;lt;/tt&amp;gt;，而非&amp;lt;tt&amp;gt;30102995.6639812&amp;lt;/tt&amp;gt;，如果我们让Visual Basic将数值串联我们的结果字符串，将显示该结果。在此事件中，一个值为字符串的单元格出现在结果中，返回值将明确带双引号。对于[[CARenderingStyle/zh|CARenderingStyle]]对象中的所有可用属性，请参考[[CARenderingStyle/zh|CARenderingStyle]]。&lt;br /&gt;
&lt;br /&gt;
===其它访问表格的方式===&lt;br /&gt;
有几种访问多维表格[[CATable/zh|CATable]]中元素的方式。每一种都有可能在特定的场合使用起来比较方便。 &lt;br /&gt;
&lt;br /&gt;
第一种方式就是使用[[CATable/zh | CATable]]的 [[CATable::GetDataByElements/zh|GetDataByElements]]或[[CATable::GetDataByLabels/zh|GetDataByLabels]]方法，上面代码示例中有显示。在此情况下，利用你想获取的基元值的单元格位置。 &lt;br /&gt;
&lt;br /&gt;
第二种方式就是使用[[CATable/zh|CATable]][[CATable::Slice/zh|Slice]]或[[CATable::Subscript/zh | Subscript]]方法获取一个少一个维度的新[[CATable/zh|CATable]]对象。通过重复减少维度，最终将获得0维度，这时你将获得一个单一基元值。此时，[[CATable/zh|CATable]]的[[CATable::AtomicValue/zh|AtomicValue]]方法返回该值 。[[CATable::AtomicValue/zh|AtomicValue]]方法是唯一获取一个标值的方法（因为没有坐标位置）。如果你需要建立完整结果其中一个切片的图形图像，必须使用此方法。 &lt;br /&gt;
&lt;br /&gt;
第三种方式就是使用[[CATable/zh|CATable]]的[[CATable::GetSafeArray/zh|GetSafeArray]]方法，将多维数组转化成一个''安全数组''（或者一个.NET数组）。你可以在使用VB或者其它.NET语言直接处理多维数组。因为对于Analytica维度没有固定顺序，但是安全数组和.NET数组有一个明确的顺序，你必须先使用[[CATable/zh|CATable]]对象的[[CATable::SetIndexOrder/zh|SetIndexOrder]]方法在调用[[CATable::GetSafeArray/zh|GetSafeArray]]之前指明维度的顺序。注意如果你知道你的数组是一维的，那就没必要了。&lt;br /&gt;
&lt;br /&gt;
===修改对象===&lt;br /&gt;
一个自定义用户程序通常从一个用户或者其它外部源获取输入，以便转化成Analytica模型中的输入变量。你可以设定输入变量的定义或者通过使用定义表格来这样做。 &lt;br /&gt;
&lt;br /&gt;
'''TestTxc''' 说明了如何修改'''Pop_exp'''定义，此模型是一个影响结果变量Cost的模型输入。要想在该示例中设定该定义，从主菜单上选择'''File &amp;gt; Change Population'''。将出现一个对话框，如下图所示：&lt;br /&gt;
&lt;br /&gt;
[[File:RedefiningtheVariableDefinition.jpg|400px/zh|文件：RedefiningtheVariableDefinition.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
在信息栏中输入一个新定义并点击'''Ok'''确认。主窗口将显示一个新的Cost值。当点击该对话框中的'''Ok'''按钮时，调用了&amp;lt;tt&amp;gt;ChangeDef.frm&amp;lt;/tt&amp;gt;函数，然后调用[[PrintAttributes]]函数打印&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果。&lt;br /&gt;
&lt;br /&gt;
此函数类似于：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Private Sub OkButton_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles OkButton.Click &lt;br /&gt;
::Dim errorText As String&lt;br /&gt;
::Dim pop_exp_Object As [[CAObject/zh|CAObject]] &lt;br /&gt;
::Dim errorCode As Short &lt;br /&gt;
::Dim errorString As String &lt;br /&gt;
::newDefinition = PopExposedDef.Text &lt;br /&gt;
::pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
::pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]](&amp;quot;[[Definition]]&amp;quot;, newDefinition) &lt;br /&gt;
::errorCode = adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &lt;br /&gt;
::If errorCode &amp;lt;&amp;gt; 0 Then &lt;br /&gt;
:::MsgBox(&amp;quot;This error occurred while processing your definition: &amp;quot; &amp;amp; vbCrLf &amp;amp; vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) :::PopExposedDef.Focus()&lt;br /&gt;
::Else&lt;br /&gt;
:::Me.Close() &lt;br /&gt;
:::frmMain.DefInstance.PrintAttributes(&amp;quot;Pop_exp&amp;quot;, &amp;quot;Cost&amp;quot;) &lt;br /&gt;
::End If &lt;br /&gt;
::ReleaseComObject(pop_exp_Object) &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
该函数抓取了输入到'''New Definition''' 新定义给'''Population Exposed'''栏，并通过使用[[CAObject/zh|CAObject]]对象中的[[CAObject::SetAttribute/zh|SetAttribute]]函数将它设置给&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;对象。然后调用[[PrintAttributes/zh|PrintAttributes]]，以计算&amp;lt;tt&amp;gt;Cost object&amp;lt;/tt&amp;gt;，并打印新的结果。要想给变量&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;设定一个新定义，我们可以为&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;获取[[CAObject/zh|CAObject]]对象，然后将其定义设置成用户输入的定义。通过使用下面的代码来实现：&lt;br /&gt;
:pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
:pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]]( &amp;quot;[[Definition]]&amp;quot;, newDefinition )&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
无论什么时候调用[[CAObject::SetAttribute/zh|SetAttribute]]，都应该检查[[CAEngine/zh|CAEngine]]自动化对象（'''adeEngine'''）的[[CAEngine::ErrorCode/zh|ErrorCode]]，以免它的定义是非法的。尝试一下输入一个新定义，比如&amp;lt;code&amp;gt;[[Uniform]](25M,35M)&amp;lt;/code&amp;gt;，然后点击'''Ok'''。当&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;的定义被改变时， &amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果由ADE重新计算，此时'''ResultTable'''接下来调用给Cost变量（在应用程序窗口重新显示时）。&lt;br /&gt;
&lt;br /&gt;
使用ADE绘图&lt;br /&gt;
&lt;br /&gt;
通过Analytica 4.6使用相同的绘图引擎，你可以建立一个图表或者图形以显示一个数组值或者不确定值结果。在ADE4.6中，你可以使用 [[CATable/zh|CATable]]的[[CATable::GraphToFile/zh|GraphToFile]]和[[CATable::GraphToStream/zh|GraphToStream]]方法。图形可以以几种可能的图像格式返回，例如'''image/png'''、 '''image/bmp'''或者 '''image/jpeg'''。 &lt;br /&gt;
&lt;br /&gt;
从可用图形选项中选择的最简单方式就是使用Analytica打开你的模型。你可以实验设置各种默认设置或者替代选择的变量，看它们是如何工作的。但你选择了你想设置的选项，保存模型。当为每一个生成结果图形时，ADE将使用这些设置。 &lt;br /&gt;
&lt;br /&gt;
对于更高维度的结果，可能需要做一些必要工作，以便选择将绘制结果的切片和具体的轴（也就是相对于图例哪个维度作为X轴）。[[CATable/zh|CATable]]的[[CATable::Subscript/zh|Subscript]]或[[CATable::Slice/zh|Slice]]方法可以用来控制轴选择特殊的切片用来绘制，能够用来控制轴。详情请参考[[CATable/zh|CATable]]。在我们的&amp;lt;tt&amp;gt;Tutorial.NET&amp;lt;/tt&amp;gt;示例中，我们有一个一维结果（&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;），因此我们没有必要担心截取或者绕轴旋转。 &lt;br /&gt;
&lt;br /&gt;
[[CATable::GraphToStream/zh|GraphToStream]]方法被用来从ADE中直接转化图形图形到一个用户界面中。使用[[CATable::GraphToStream/zh|GraphToStream]]比起使用[[CATable::GraphToFile/zh|GraphToFile]]来要稍微复杂一点，因为[[CATable::GraphToFile/zh|GraphToFile]]除了需要文件名以外还需要其它一些信息，以便编写图形。要使用[[CATable::GraphToStream/zh|GraphToStream]]，我们必须在内存内设置一个流，允许ADE写入该留，然后从该留重建。因为.NET流和COM流不兼容，你必须使用ADE一同提供的[[StreamConnector]]类型.&amp;lt;tt&amp;gt;frmMain&amp;lt;/tt&amp;gt; 中的'''GraphResult_Click'''子程序演示了[[CATable::GraphToStream/zh|GraphToStream]]的使用。从主应用程序窗口选择 '''Graph Result'''菜单选项，结果将出现在一个如下所示的图形当中：&lt;br /&gt;
&lt;br /&gt;
[[File:resultgraph.jpg/zh|文件：resultgraph.jpg]]&lt;br /&gt;
&lt;br /&gt;
==结论==&lt;br /&gt;
&lt;br /&gt;
在此教程中，我们介绍了Analytica决策引擎的几个重要方面。我们看到了如何建立一个ADE服务器对象，使用ADE打开模型，获取模型中的单个对象、计算对象、获取表格中的元素，以及修改模型中的对象。但是ADE可以做的远不止这些。 &lt;br /&gt;
&lt;br /&gt;
我们希望你已经足够了解其基本特征，这样你现在才能独自开始探索更多新的高级特征。我们建议你现在开始阅读字教程的剩余部分以了解ADE能做什么。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
| [[Installation of ADE/zh|ADE 安装]] &amp;lt;- ||  [[The ADE Tutorial/zh|ADE 入门教程]] || -&amp;gt; [[Using the ADE Server/zh|使用ADE服务器]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=ADE_User_Guide/zh&amp;diff=36328</id>
		<title>ADE User Guide/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=ADE_User_Guide/zh&amp;diff=36328"/>
		<updated>2015-10-28T06:34:59Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南]]&lt;br /&gt;
Analytica决策引擎（ADE）是一个强大的COM组件，可以在计算机服务器上运行Analytica模型。其他应用程序可以通过COM标准接口使用ADE访问Analytica模型 。 ADE提供了一个应用程序设计界面（API），通过该界面其他应用程序可以建立、读取、检查、分析、评估、修改、以及保存 Analytica 模型。ADE本身不像Analytica那样在计算机上提供一个用户界面。如果你想要一个基于网络的用户界面，你可以使用 [[Analytica Cloud Player]] (ACP) ，其本身使用ADE。或者你可以从其他可以提供输入、运行模型以及采集和显示结果的应用程序使用ADE访问你的Analytica模型。 &lt;br /&gt;
&lt;br /&gt;
该用户指南给想使用ADE开发应用程序的编程人员用提供了详细参考。同时包含关于如何安装ADE的信息。&lt;br /&gt;
&lt;br /&gt;
==如何使用该文档==&lt;br /&gt;
在每页的标题下，列出了页面的层次结构以及母页。用户指南中的页面可以按照任何顺序浏览，但是对于那些想循序阅读该指南的用户，在每一页的底部都有Previous（上一页）和Next（下一页）连接按钮，用户可以通过按钮循序浏览完所有页面。&lt;br /&gt;
&lt;br /&gt;
在每一页的底部也提供了一个Navbox（导航模块），列出了该指南的所有内容，以便在该指南中可以访问任何页面。&lt;br /&gt;
&lt;br /&gt;
==ADE用户指南目录==&lt;br /&gt;
===[[Introduction to ADE/zh|ADE 介绍]]===&lt;br /&gt;
此章解释了ADE是什么以及如何使用ADE服务器。&lt;br /&gt;
&lt;br /&gt;
===[[Installation of ADE/zh|ADE 安装]]===&lt;br /&gt;
此章解释在Windows NT 4 (&amp;gt;SP 6)、2000、XP、或者Vista上安装 ADE 4.6的步骤。&lt;br /&gt;
&lt;br /&gt;
===[[The ADE Tutorial/zh|ADE 入门]]===&lt;br /&gt;
此章介绍如何在Visual Basic程序中使用ADE，以及基本步骤：如何使用Visual Basic建立你的第一个ADE应用程序。&lt;br /&gt;
&lt;br /&gt;
===[[Using the ADE Server/zh|使用ADE服务器]]===&lt;br /&gt;
此章提供了一个步进式指南，说明通过ADE可获得的功能。通过阅读此部分可以更好地熟悉类型、方法、和属性。通过使用在你的代码中出现的这部分中示例代码片断，你可以立即开始从你的Visual Basic应用程序访问你模型中的信息。&lt;br /&gt;
&lt;br /&gt;
===[[Working with Models, Modules, and Files in ADE/zh|在ADE中处理模型、模块和文件]]===&lt;br /&gt;
此章包含一些常见操作和处理示例，这些示例你可能在你的Analytica模型中对象上执行。&lt;br /&gt;
&lt;br /&gt;
===[[ADE Server Class Reference/zh|ADE服务器类型参考]]===&lt;br /&gt;
此章提供一些关于ADE中对象类型、对象属性和方法（包括方法语法、数据类型，以及属性访问信息）的参考材料。在你阅读完[[Using the ADE Server/zh|使用ADE服务器]] 后如果有关于方法和属性的具体问题，你可以参考此部分信息。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
* 关于ADE及其试用和采购信息请访问[http://ch.lumina.com/ lumina官方网站]上的[http://ch.lumina.com/products/analytica-editions/analytica-decision-engine/ Analytica决策引擎]。&lt;br /&gt;
&lt;br /&gt;
 {| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
|  &amp;lt;big&amp;gt;&amp;amp;#x21e6;&amp;lt;/big&amp;gt;  ||  [[ADE User Guide/zh|ADE用户指南]] || &amp;lt;big&amp;gt;&amp;amp;#x21e8;&amp;lt;/big&amp;gt; [[Introduction to ADE/zh|ADE 介绍]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=ADE_User_Guide/zh&amp;diff=36326</id>
		<title>ADE User Guide/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=ADE_User_Guide/zh&amp;diff=36326"/>
		<updated>2015-10-28T06:34:43Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南]]&lt;br /&gt;
Analytica决策引擎（ADE）是一个强大的COM组件，可以在计算机服务器上运行Analytica模型。其他应用程序可以通过COM标准接口使用ADE访问Analytica模型 。 ADE提供了一个应用程序设计界面（API），通过该界面其他应用程序可以建立、读取、检查、分析、评估、修改、以及保存 Analytica 模型。ADE本身不像Analytica那样在计算机上提供一个用户界面。如果你想要一个基于网络的用户界面，你可以使用 [[Analytica Cloud Player]] (ACP) ，其本身使用ADE。或者你可以从其他可以提供输入、运行模型以及采集和显示结果的应用程序使用ADE访问你的Analytica模型。 &lt;br /&gt;
&lt;br /&gt;
该用户指南给想使用ADE开发应用程序的编程人员用提供了详细参考。同时包含关于如何安装ADE的信息。&lt;br /&gt;
&lt;br /&gt;
==如何使用该文档==&lt;br /&gt;
在每页的标题下，列出了页面的层次结构以及母页。用户指南中的页面可以按照任何顺序浏览，但是对于那些想循序阅读该指南的用户，在每一页的底部都有Previous（上一页）和Next（下一页）连接按钮，用户可以通过按钮循序浏览完所有页面。&lt;br /&gt;
&lt;br /&gt;
在每一页的底部也提供了一个Navbox（导航模块），列出了该指南的所有内容，以便在该指南中可以访问任何页面。&lt;br /&gt;
&lt;br /&gt;
==ADE用户指南目录==&lt;br /&gt;
===[[Introduction to ADE/zh|ADE 介绍]]===&lt;br /&gt;
此章解释了ADE是什么以及如何使用ADE服务器。&lt;br /&gt;
&lt;br /&gt;
===[[Installation of ADE/zh|ADE 安装]]===&lt;br /&gt;
此章解释在Windows NT 4 (&amp;gt;SP 6)、2000、XP、或者Vista上安装 ADE 4.6的步骤。&lt;br /&gt;
&lt;br /&gt;
===[[The ADE Tutorial/zh|ADE 入门]]===&lt;br /&gt;
此章介绍如何在Visual Basic程序中使用ADE，以及基本步骤：如何使用Visual Basic建立你的第一个ADE应用程序。&lt;br /&gt;
&lt;br /&gt;
===[[Using the ADE Server/zh|使用ADE服务器]]===&lt;br /&gt;
此章提供了一个步进式指南，说明通过ADE可获得的功能。通过阅读此部分可以更好地熟悉类型、方法、和属性。通过使用在你的代码中出现的这部分中示例代码片断，你可以立即开始从你的Visual Basic应用程序访问你模型中的信息。&lt;br /&gt;
&lt;br /&gt;
===[[Working with Models, Modules, and Files in ADE/zh|在ADE中处理模型、模块和文件]]===&lt;br /&gt;
此章包含一些常见操作和处理示例，这些示例你可能在你的Analytica模型中对象上执行。&lt;br /&gt;
&lt;br /&gt;
===[[ADE Server Class Reference/zh|ADE服务器类型参考]]===&lt;br /&gt;
此章提供一些关于ADE中对象类型、对象属性和方法（包括方法语法、数据类型，以及属性访问信息）的参考材料。在你阅读完[[Using the ADE Server/zh|使用ADE服务器]] 后如果有关于方法和属性的具体问题，你可以参考此部分信息。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
* 关于ADE及其试用和采购信息请访问[http://ch.lumina.com/ |lumina官方网站]上的[http://ch.lumina.com/products/analytica-editions/analytica-decision-engine/ |Analytica决策引擎]。&lt;br /&gt;
&lt;br /&gt;
 {| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
|  &amp;lt;big&amp;gt;&amp;amp;#x21e6;&amp;lt;/big&amp;gt;  ||  [[ADE User Guide/zh|ADE用户指南]] || &amp;lt;big&amp;gt;&amp;amp;#x21e8;&amp;lt;/big&amp;gt; [[Introduction to ADE/zh|ADE 介绍]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=ADE_User_Guide/zh&amp;diff=36324</id>
		<title>ADE User Guide/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=ADE_User_Guide/zh&amp;diff=36324"/>
		<updated>2015-10-28T06:27:52Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南]]&lt;br /&gt;
Analytica决策引擎（ADE）是一个强大的COM组件，可以在计算机服务器上运行Analytica模型。其他应用程序可以通过COM标准接口使用ADE访问Analytica模型 。 ADE提供了一个应用程序设计界面（API），通过该界面其他应用程序可以建立、读取、检查、分析、评估、修改、以及保存 Analytica 模型。ADE本身不像Analytica那样在计算机上提供一个用户界面。如果你想要一个基于网络的用户界面，你可以使用 [[Analytica Cloud Player]] (ACP) ，其本身使用ADE。或者你可以从其他可以提供输入、运行模型以及采集和显示结果的应用程序使用ADE访问你的Analytica模型。 &lt;br /&gt;
&lt;br /&gt;
该用户指南给想使用ADE开发应用程序的编程人员用提供了详细参考。同时包含关于如何安装ADE的信息。&lt;br /&gt;
&lt;br /&gt;
==如何使用该文档==&lt;br /&gt;
在每页的标题下，列出了页面的层次结构以及母页。用户指南中的页面可以按照任何顺序浏览，但是对于那些想循序阅读该指南的用户，在每一页的底部都有Previous（上一页）和Next（下一页）连接按钮，用户可以通过按钮循序浏览完所有页面。&lt;br /&gt;
&lt;br /&gt;
在每一页的底部也提供了一个Navbox（导航模块），列出了该指南的所有内容，以便在该指南中可以访问任何页面。&lt;br /&gt;
&lt;br /&gt;
==ADE用户指南目录==&lt;br /&gt;
===[[Introduction to ADE/zh|ADE 介绍]]===&lt;br /&gt;
此章解释了ADE是什么以及如何使用ADE服务器。&lt;br /&gt;
&lt;br /&gt;
===[[Installation of ADE/zh|ADE 安装]]===&lt;br /&gt;
此章解释在Windows NT 4 (&amp;gt;SP 6)、2000、XP、或者Vista上安装 ADE 4.6的步骤。&lt;br /&gt;
&lt;br /&gt;
===[[The ADE Tutorial/zh|ADE 入门]]===&lt;br /&gt;
此章介绍如何在Visual Basic程序中使用ADE，以及基本步骤：如何使用Visual Basic建立你的第一个ADE应用程序。&lt;br /&gt;
&lt;br /&gt;
===[[Using the ADE Server/zh|使用ADE服务器]]===&lt;br /&gt;
此章提供了一个步进式指南，说明通过ADE可获得的功能。通过阅读此部分可以更好地熟悉类型、方法、和属性。通过使用在你的代码中出现的这部分中示例代码片断，你可以立即开始从你的Visual Basic应用程序访问你模型中的信息。&lt;br /&gt;
&lt;br /&gt;
===[[Working with Models, Modules, and Files in ADE/zh|在ADE中处理模型、模块和文件]]===&lt;br /&gt;
此章包含一些常见操作和处理示例，这些示例你可能在你的Analytica模型中对象上执行。&lt;br /&gt;
&lt;br /&gt;
===[[ADE Server Class Reference/zh|ADE服务器类型参考]]===&lt;br /&gt;
此章提供一些关于ADE中对象类型、对象属性和方法（包括方法语法、数据类型，以及属性访问信息）的参考材料。在你阅读完[[Using the ADE Server/zh|使用ADE服务器]] 后如果有关于方法和属性的具体问题，你可以参考此部分信息。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
* 关于ADE及其试用和采购信息请访问[http://ch.lumina.com/ lumina官方网站]上的[http://ch.lumina.com/products/analytica-editions/analytica-decision-engine/|Analytica决策引擎]。&lt;br /&gt;
&lt;br /&gt;
 {| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
|  &amp;lt;big&amp;gt;&amp;amp;#x21e6;&amp;lt;/big&amp;gt;  ||  [[ADE User Guide/zh|ADE用户指南]] || &amp;lt;big&amp;gt;&amp;amp;#x21e8;&amp;lt;/big&amp;gt; [[Introduction to ADE/zh|ADE 介绍]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=ADE_User_Guide/zh&amp;diff=36322</id>
		<title>ADE User Guide/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=ADE_User_Guide/zh&amp;diff=36322"/>
		<updated>2015-10-28T06:26:27Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南]]&lt;br /&gt;
Analytica决策引擎（ADE）是一个强大的COM组件，可以在计算机服务器上运行Analytica模型。其他应用程序可以通过COM标准接口使用ADE访问Analytica模型 。 ADE提供了一个应用程序设计界面（API），通过该界面其他应用程序可以建立、读取、检查、分析、评估、修改、以及保存 Analytica 模型。ADE本身不像Analytica那样在计算机上提供一个用户界面。如果你想要一个基于网络的用户界面，你可以使用 [[Analytica Cloud Player]] (ACP) ，其本身使用ADE。或者你可以从其他可以提供输入、运行模型以及采集和显示结果的应用程序使用ADE访问你的Analytica模型。 &lt;br /&gt;
&lt;br /&gt;
该用户指南给想使用ADE开发应用程序的编程人员用提供了详细参考。同时包含关于如何安装ADE的信息。&lt;br /&gt;
&lt;br /&gt;
==如何使用该文档==&lt;br /&gt;
在每页的标题下，列出了页面的层次结构以及母页。用户指南中的页面可以按照任何顺序浏览，但是对于那些想循序阅读该指南的用户，在每一页的底部都有Previous（上一页）和Next（下一页）连接按钮，用户可以通过按钮循序浏览完所有页面。&lt;br /&gt;
&lt;br /&gt;
在每一页的底部也提供了一个Navbox（导航模块），列出了该指南的所有内容，以便在该指南中可以访问任何页面。&lt;br /&gt;
&lt;br /&gt;
==ADE用户指南目录==&lt;br /&gt;
===[[Introduction to ADE/zh|ADE 介绍]]===&lt;br /&gt;
此章解释了ADE是什么以及如何使用ADE服务器。&lt;br /&gt;
&lt;br /&gt;
===[[Installation of ADE/zh|ADE 安装]]===&lt;br /&gt;
此章解释在Windows NT 4 (&amp;gt;SP 6)、2000、XP、或者Vista上安装 ADE 4.6的步骤。&lt;br /&gt;
&lt;br /&gt;
===[[The ADE Tutorial/zh|ADE 入门]]===&lt;br /&gt;
此章介绍如何在Visual Basic程序中使用ADE，以及基本步骤：如何使用Visual Basic建立你的第一个ADE应用程序。&lt;br /&gt;
&lt;br /&gt;
===[[Using the ADE Server/zh|使用ADE服务器]]===&lt;br /&gt;
此章提供了一个步进式指南，说明通过ADE可获得的功能。通过阅读此部分可以更好地熟悉类型、方法、和属性。通过使用在你的代码中出现的这部分中示例代码片断，你可以立即开始从你的Visual Basic应用程序访问你模型中的信息。&lt;br /&gt;
&lt;br /&gt;
===[[Working with Models, Modules, and Files in ADE/zh|在ADE中处理模型、模块和文件]]===&lt;br /&gt;
此章包含一些常见操作和处理示例，这些示例你可能在你的Analytica模型中对象上执行。&lt;br /&gt;
&lt;br /&gt;
===[[ADE Server Class Reference/zh|ADE服务器类型参考]]===&lt;br /&gt;
此章提供一些关于ADE中对象类型、对象属性和方法（包括方法语法、数据类型，以及属性访问信息）的参考材料。在你阅读完[[Using the ADE Server/zh|使用ADE服务器]] 后如果有关于方法和属性的具体问题，你可以参考此部分信息。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
* 关于ADE及其试用和采购信息请访问[http://ch.lumina.com/ lumina官方网站]上的[http://ch.lumina.com/products/analytica-editions/analytica-decision-engine/Analytica决策引擎]。&lt;br /&gt;
&lt;br /&gt;
 {| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
|  &amp;lt;big&amp;gt;&amp;amp;#x21e6;&amp;lt;/big&amp;gt;  ||  [[ADE User Guide/zh|ADE用户指南]] || &amp;lt;big&amp;gt;&amp;amp;#x21e8;&amp;lt;/big&amp;gt; [[Introduction to ADE/zh|ADE 介绍]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36316</id>
		<title>The ADE Tutorial/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36316"/>
		<updated>2015-10-27T06:39:57Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南 ]]&lt;br /&gt;
&lt;br /&gt;
此教程教你如何在一个Visual Basic程序中使用Analytica决策引擎（ADE）。&lt;br /&gt;
&lt;br /&gt;
==你的第一个ADE应用程序==&lt;br /&gt;
首先先从头开始写一个简单的ADE程序，只要确认一切设置正常。按照以下步骤操作：&lt;br /&gt;
&lt;br /&gt;
test&lt;br /&gt;
&lt;br /&gt;
第一个程序执行了以下操作：&lt;br /&gt;
*建立一个名称为ADE的[[CAEngine/zh|CAEngine]]自动化对象（通过使用&amp;lt;code&amp;gt;new [[CAEngine/zh|CAEngine]]&amp;lt;/code&amp;gt;).&lt;br /&gt;
*打开Analytica模型 (通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]] 方法。&lt;br /&gt;
*显示模型名称返回[[CAEngine::OpenModel/zh|OpenModel]]的值。&lt;br /&gt;
我们将在后面的章节详细了解这些信息。&lt;br /&gt;
&lt;br /&gt;
===接下来讲什么呢?===&lt;br /&gt;
我们不会尝试在此入门教程中解释ADE的特征。本指南后面几个章节会描述这些特征。 &lt;br /&gt;
&lt;br /&gt;
从现在开始，我们我们将使用名称为&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;的示例模型。打开 Analytica安装目录下 '''Example Models'''文件夹里面的'''Risk Analysis'''文件夹便可找到&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;文件。如果你找不到，或者你安装Analytica的时候未选择安装examples（示例）文件，在ADE安装目录下面的'''Examples\Tutorial.NET'''文件家中有一个副本。 &lt;br /&gt;
&lt;br /&gt;
Txc模型演示了减少污染物TXC排放的risk-benefit （风险-效益）分析。请用Analytica打开Txc查看它是如何工作的。 &lt;br /&gt;
&lt;br /&gt;
ADE '''Examples\Tutorial.NET''' 文件夹中名称为&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;的Visual Basic.NET程序示例显示了ADE很多方面。该程序建立了一个ADE自动化对象，打开包含该对象的&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，获取变量 &amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，计算变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;，通过获取每个表格的单独组件以表格的方式打印输出变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的结果，然后改变变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义。再次获取变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的值，看一下 变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;定义的改变对变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;有什么影响。如果设置正确的话,&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;将显示在“Text Txc window”中显示的窗口。 &lt;br /&gt;
&lt;br /&gt;
应用程序显示变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义（&amp;lt;tt&amp;gt;&amp;quot;Normal (30M, 3M)&amp;quot;&amp;lt;/tt&amp;gt;），以及与&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;关联的表格，这都基于&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义。你可以通过从主菜单选择'''File &amp;gt; Change Population Exposed'''改变&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，然后查看改变对&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;表格的影响。&lt;br /&gt;
&lt;br /&gt;
[[File:TextTxcWindow.png|400px/zh | 文件：TextTxcWindow.png|400px]]&lt;br /&gt;
&lt;br /&gt;
===区分title（名称） 和 identifier（标识符）===&lt;br /&gt;
无论什么时候，一个ADE函数都需要一个变量你必须传达变量的'''''[[Identifier|标识符]]''''' ，而不是它的'''''[[Title|名称]]'''''。这可能会引起混淆，因为在Analytica影响图中一般显示每一个变量的名称。默认情况下，在你最初建立每一个对象的时候，Analytica自动根据名称建立一个标识符。用（_）代替名称中的每一个空格或者其他非字母和数字字符。 &lt;br /&gt;
&lt;br /&gt;
你可以通过点击“Control+y”（或者从Object（对象）菜单选择'''Show by identifier''' ：显示标识符） 来以标识符显示变量。对于模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;，你可以看到名称为&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;变量的标识符为 &amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;。将变量传递给ADE函数时，使用标识符很重要。如果你传递&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;，ADE无法找到变量，并且将返回一个错误。&lt;br /&gt;
&lt;br /&gt;
===从Visual Basic中建立一个ADE 对象===&lt;br /&gt;
&lt;br /&gt;
如果你还没准备好，将名称为tt&amp;gt;Examples\Tutorial\TestTxc.sln&amp;lt;/tt&amp;gt;载入到Visual Basic.NET中，查看名称为&amp;lt;tt&amp;gt;TestTxc.vb&amp;lt;/tt&amp;gt;的文件的代码。其代码看起来像：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Imports ADEW &lt;br /&gt;
:. . . &lt;br /&gt;
:Public adeEngine As [[CAEngine/zh|CAEngine]]&lt;br /&gt;
&lt;br /&gt;
:Public Sub Main() &lt;br /&gt;
::Dim exeDirectory, theModel As String &lt;br /&gt;
::Dim theModelString As String &lt;br /&gt;
::exeDirectory = VB6.GetPath &lt;br /&gt;
::theModel = exeDirectory &amp;amp; &amp;quot;\..\&amp;quot; &amp;amp; &amp;quot;Txc.ana&amp;quot; &lt;br /&gt;
::adeEngine = New [[CAEngine/zh|CAEngine]]&lt;br /&gt;
::... &lt;br /&gt;
::theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
::... &lt;br /&gt;
::frmMain.DefInstance.Show() &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在每一个文件的顶部的代码将自动化对象 '''adeEngine''' 声明为一个[[CAEngine/zh|CAEngine]] 对象。使用此对象，我们能够访问[[CAEngine/zh|CAEngine]] 展示的所有公共函数（参考 [[ADE Server Class Reference/zh|ADE服务器类型参考]] ）&lt;br /&gt;
&lt;br /&gt;
变量&amp;lt;tt&amp;gt;adeEngine&amp;lt;/tt&amp;gt;包含我们的进程内对象[[CAEngine/zh|CAEngine]]。如果我们想使用ADE的本地（进程外）服务器版本，我们可以将一个项目参考添加到'''Analytica Decision Engine Server 4.6 COM''' 组件并将顶部行从&amp;lt;tt&amp;gt;Imports ADEW&amp;lt;/tt&amp;gt;改成&amp;lt;tt&amp;gt;Imports ADE&amp;lt;/tt&amp;gt;即可。 &lt;br /&gt;
&lt;br /&gt;
这里是另一种获得一个先[[CAEngine/zh|CAEngine]]对象的方法。此循序不需要给项目添加参考。&amp;lt;tt&amp;gt;&lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADEW4.6.CAEngine&amp;quot;) ’ in-process &lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADE4.6.CAEngine&amp;quot;) ’ out-of-process &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果想理解使用进程内和进程外（或本地）服务器的利与弊，以及哪一种自动化服务器用于不同的场景，参考[[Using_the_Analytica_Decision_Engine_Server#In-process_vs_Out-of-process/zh | In-process vs. out-of-process]]&lt;br /&gt;
&lt;br /&gt;
===COM和 Automation 接口比较===&lt;br /&gt;
在上面的例子当中，我们使用COM接口调用ADE。在一个COM 接口中，对象 在本例中为[[CAEngine/zh|CAEngine]] 被声明为[[CAEngine/zh|CAEngine]] ，编译器解决每一个成员函数，并且在编译时间内能探测几个明显的错误。另外，Visual Studio可以提供方法和参数类型列表当，在你编程的时候可以当做一个提示工具，在编写使用ADE程序是非常有用。COM调用比Automation调用要快一点，但是在ADE应用程序中速度差异通常不是很重要。对于ADE 4.6我们推荐使用COM结构，只要你的语言支持。&lt;br /&gt;
&lt;br /&gt;
在VB Automation中，你可以将一个对象简单声明为Object（对象），而不是像[[CAEngine/zh|CAEngine]]、[[CAObject/zh|CAObject]]等更加具体的类型。当使用Automation调用'''ADE'''方法时，在运行时间内确定方法。在编译时间内，编译器不知道你的 '''ADE''' 对象是否有一个名称为[[CAEngine::OpenModel/zh|OpenModel]]的函数。在VB中，调用COM方法或Automation 方法的语法是相通的——唯一的不同在于对象类型是否明确被声明。&lt;br /&gt;
&lt;br /&gt;
在VC++和C#中，调用COM的语法和调用Automatio的语法不同。在这些情况下，COM要方便的多，Automation能够获得相冗余。然而，同样的语言，包括VBScript和其他脚本语言，只支持Automation不支持COM。&lt;br /&gt;
&lt;br /&gt;
===监视Process（进程）===&lt;br /&gt;
当使用进程外ADE服务器时，你的代码必须在终止时释放[[CAEngine/zh|CAEngine]]COM对象。当最终[[CAEngine/zh|CAEngine]]使用被释放是，ADE.exe 进程自动终止。到目前为止所看到的代码，VB语言在达到程序末端时，自动处理释放对象。但是，当你调试你的代码是，你可以提前终止你的程序来修复bug，你的程序可能被Task Manager（任务管理器）终止，或者你自己的代码也可能奔溃，导致你的程序进程在它有机会释放对象之前终止。应为COM对象从来不会被释放，ADE.exe进程不知道它是否在使用中，你可能获得ADE.exe 僵尸进程。 &lt;br /&gt;
&lt;br /&gt;
为了避免这种情况发生，一种好的习惯就是在调用[[CAEngine/zh|CAEngine]]实例后 立即调用[[CAEngine::MonitorProcess/zh|CAEngine::MonitorProcess]]。通过这种方式，ADE能够得知哪一个进程正在使用它，同时将设置一个线程去探测你的进程是否在ADE被完全释放前终止。如果你的程序进程没有终止，ADE进程会立即将它关闭，消除了僵尸ADE进程的堆积。 &lt;br /&gt;
&lt;br /&gt;
要从一个.NET应用程序获得进程ID，使用System.Diagnostics.Process namespace中的'''GetCurrentProcess().Id''' 。在其他语言中，你可以使用Windows SDK 的'''GetProcessId( )'''函数。 &lt;br /&gt;
&lt;br /&gt;
'''[[CAEngine::MonitorProcess/zh|MonitorProcess]]()''' 只能用来监视运行ADE进程的同一台计算机的进程，一次当通过DCOM运行ADE时不能使用。当使用进程内ADEW服务器时没有必要使用。&lt;br /&gt;
&lt;br /&gt;
==使用ADE打开模型==&lt;br /&gt;
我们现在打开&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，显示我们的应用程序主窗口。使用以下调用：tt&amp;gt;&lt;br /&gt;
:theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
:frmMain.DefInstance.Show &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]]函数打开模型。如果成功的话，变量&amp;lt;tt&amp;gt;theModelString&amp;lt;/tt&amp;gt;将包含模型的名字。否则，将包含一个空的串。虽然由于为了简介的缘故，我们没有这样做，但是你应该检查从[[CAEngine::OpenModel/zh|OpenModel]]函数返回的是不是一个空的串。如果是，说明在你打开的模型中存在一个错误。你可以使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]]属性找出是哪种错误 （&amp;lt;tt&amp;gt;adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] 和adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]&amp;lt;/tt&amp;gt;）。&lt;br /&gt;
&lt;br /&gt;
==从Analytica模型中检索对象==&lt;br /&gt;
下一步就是从我们的模型中检索对象（变量、模块、函数等），以便我们能获取他们的属性（[[definition|定义]]、[[title|名称]]、[[class|类型]]等等 ）。我们的示例模型（&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;）操作&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;和&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;对象。尤其是，修改&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;可以查看这是如何影响&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt; 对象。&lt;br /&gt;
&lt;br /&gt;
我们的&amp;lt;tt&amp;gt;TxcTest.vbproj&amp;lt;/tt&amp;gt; （&amp;lt;tt&amp;gt;TxcText.sln&amp;lt;/tt&amp;gt;）项目中的&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;文件里的 '''PrintAttributes''' 函数演示了如何检索对象。该函数首先被&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''Form_Load''' 函数调用，当应用程序启动后，可以显示'''Cost'''表格。当然无论什么时候，只要我们想输出'''Cost'''表格的当前值，都可以调用。该函数如下所示：&lt;br /&gt;
:Public Sub PrintAttributes(ByRef inputIdentifier As String, ByRef  outputIdentifier As String) &lt;br /&gt;
::Dim inputObject, outputObject As [[CAObject/zh|CAObject]]&lt;br /&gt;
::Dim resultTable As [[CATable/zh|CATable]]&lt;br /&gt;
::Dim definitionAttrInput As String &lt;br /&gt;
::inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
::outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier) &lt;br /&gt;
::definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;definition&amp;quot;) &lt;br /&gt;
::resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]]&lt;br /&gt;
::Call PrintResultTable(resultTable, inputIdentifier, definitionAttrInput, outputIdentifier) &lt;br /&gt;
::ReleaseComObject(resultTable) &lt;br /&gt;
::ReleaseComObject(inputObject) &lt;br /&gt;
::ReleaseComObject(outputObject) &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''PrintAttributes'''和作为'''inputIdentifier'''参数的&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;变量标识符以及作为'''outputIdentifier'''参数的'''Cost'''变量一起使用。如下所示通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::GetObjectByName/zh|GetObjectByName]]函数提取相应对象：&amp;lt;tt&amp;gt;&lt;br /&gt;
:inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取成功，将返回一个[[CAObject/zh|CAObject]]类型对象。如果使用'''[[CAObject/zh|CAObject]]'''的函数，参考[[CAObject/zh|SendCommand(command)]]，可以获得一个[[CAObject/zh|CAObject]]的完整函数列表。如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取失败，返回值为&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;。代码应该检查以确保[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取的结果是有效的。如果找不到，可使用[[CAEngine/zh|CAEngine]]的 [[CAEngine::ErrorCode/zh|ErrorCode]]和 [[CAEngine::ErrorText/zh|ErrorText]]属性获取错误信息。例如：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Set inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:If inputObject Is Nothing Then &lt;br /&gt;
::MsgBox(“This error from GetObjectByName occurred: “&amp;amp; _ vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &amp;amp; “:” &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) &lt;br /&gt;
:Else &lt;br /&gt;
::'inputObject valid &lt;br /&gt;
:End If&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===获取对象属性===&lt;br /&gt;
每一个Analytica对象都有一组属性，例如[[identifier|标识符]]、[[title|名称]]、[[description| 描述]]和[[class|类型]]。你可以使用[[CAObject::GetAttribute/zh|GetAttribute]]函数来获去Analytica对象的属性。例如，如要获取'''inputObject'''的定义（当前为cost）：&amp;lt;tt&amp;gt;&lt;br /&gt;
:definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh|GetAttribute]](&amp;quot;[[Definition|定义]]&amp;quot;) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt; 中，&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;的定义为&amp;quot;&amp;lt;tt&amp;gt;[[Normal]](30M, 3M)&amp;lt;/tt&amp;gt;&amp;quot; ，我们将它储存在'''definitionAttrInput'''当中。.&lt;br /&gt;
&lt;br /&gt;
===计算对象和检索结果===&lt;br /&gt;
使用[[CAObject/zh|CAObject]]的[[CAObject::Result/zh|Result]]或[[CAObject::ResultTable/zh|ResultTable]]方法来获取变量的值。如果有必要的话，ADE先自动计算变量。如果你确定结果为基元（只有一个元素），使用[[CAObject::Result/zh|Result]]方法。否则使用[[CAObject::ResultTable/zh|ResultTable]]，检索结果为一个''数组''。基元结果当作一个特殊数组案例来处理，没有维度的数组。如果值为基元[[CATable::AtomicValue/zh|AtomicValue]]方法将返回一个数字或者字符串单一值。 &lt;br /&gt;
&lt;br /&gt;
默认情况下，[[CAObject::Result/zh|Result]]和[[CAObject::ResultTable/zh|ResultTable]]返回结果的中值，也就是说，ADE以确定性方式计算结果。对于一个概率值，将[[CAObject/zh|CAObject]]的[[CAObject::ResultType/zh|ResultType]]属性设置为想要的不确定性视图——Mean（平均值） Sample（样本）、PDF（概率密度函数）、CDF（累计分布函数）、Confidence bands（置信带）、或者Statistics（统计数据）详情请参考[[CAObject::ResultType/zh|ResultType]]。我们通过如下的方式获取outputObject 输出对象 的值：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]] &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
结果为一个[[CATable/zh|CATable]]对象，允许我们访问一个表格中的单个元素。 &lt;br /&gt;
&lt;br /&gt;
如果你通过调用[[CAObject::Result/zh|Result]]来获取一个数组（或者表格）的值，将返回数组为一个字符串，列出索引和元素，以逗号隔开。通常使用[[CAObject::ResultTable/zh|ResultTable]]更加简单，这样你没有必要从字符串中解析表格的元素。&lt;br /&gt;
&lt;br /&gt;
===获取表格索引元素===&lt;br /&gt;
一个Analytica表格包含0个或者多个索引。如果包含一个索引，那么该表格是1维表格；如果有2个索引，说他是2维表格，依此类推。0维度表格包含一个“单一基元”（或标量）值。你可以使用CATable的[[CATable::NumDims/zh|NumDims]]获取表格的维数（也就是索引数）。要想获取表格的单个索引，可使用[[CATable/zh|CATable]]的 [[CATable::IndexNames/zh|IndexNames]]和 [[CATable::GetIndexObject/zh|GetIndexObject]]函数。 &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''PrintResultTable'''函数说明了这两个函数的使用。从'''PrintAttributes'''中调用'''PrintResultTable'''，执行打印'''TestTxc'''中的表格的实际工作（为了简洁起见，我们只给出了关联ADE的该函数部分）。&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Public Sub PrintResultTable(ByRef resultTable As CATable, ByRef inputIdentifier As String, ByRef definitionAttrInput As String, ByRef outputIdentifier As String) &lt;br /&gt;
::Dim theIndexName, theTableName As String &lt;br /&gt;
::Dim theIndexElement As String &lt;br /&gt;
::Dim theTableElement &lt;br /&gt;
::Dim theIndexObj As [[CAIndex/zh|CAIndex]]&lt;br /&gt;
::Dim numEls As Integer &lt;br /&gt;
::Dim spaces, i As Integer &lt;br /&gt;
::Dim lenStr As Short &lt;br /&gt;
::Dim OutputStr As Short &lt;br /&gt;
::Dim spaceString, underlineString As String &lt;br /&gt;
::... &lt;br /&gt;
::theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1) &lt;br /&gt;
::theTableName = resultTable.[[CATable::Name/zh|Name]] &lt;br /&gt;
::theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName) &lt;br /&gt;
::numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
::... &lt;br /&gt;
::For i = 1 To numEls &lt;br /&gt;
:::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
:::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
:::... &lt;br /&gt;
::Next i &lt;br /&gt;
::InformationPane.Text = outputString &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
通过'''PrintResultTable'''获取一个表格的索引方法如下：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1)&lt;br /&gt;
:theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
我们通过使用[[CATable/zh|CATable]]的[[CATable::IndexNames/zh|IndexNames]]函数获取第一个索引的名字。我们将它传递给[[CATable/zh|CATable]]的[[CATable::GetIndexObject/zh|GetIndexObject]]函数以获取表示我们的索引的[[CAIndex/zh|CAIndex]]。该自动化对象返回其相应索引的相关信息。如果此函数调用失败，将返回&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;信息。在此情况下，使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]] 函数找出原因。&lt;br /&gt;
&lt;br /&gt;
==从CATable和CAIndex中获取信息==&lt;br /&gt;
[[PrintResultTable]]说明了如何从[[CATable/zh| CATable]]和[[CAIndex/zh|CAIndex]] 对象获取信息。该代码获取'''Cost'''表格的索引和表格元素：&lt;br /&gt;
: &amp;lt;tt&amp;gt;&lt;br /&gt;
:numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
:For i = 1 To numEls &lt;br /&gt;
::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
::... &lt;br /&gt;
:Next i &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[CAIndex/zh|CAIndex]]的[[CAIndex::IndexElements/zh|IndexElements]]属性返回第一个索引中的元素个数。[[CAIndex/zh|CAIndex]]的[[CAIndex::GetValueByNumber/zh|GetValueByNumber]]函数获取单个索引元素。 &lt;br /&gt;
&lt;br /&gt;
我们通过传递表格中元素的坐标，使用  [[CATable/zh|CATable]]的[[CATable::GetDataByElements/zh|GetDataByElements]]函数获取'''Cost'''表格对象的单个表格元素'''resultTable'''。 &lt;br /&gt;
&lt;br /&gt;
当我检索 [[CATable/zh|CATable]]对象中单个元素（'''resultTable'''）的时候，我们利用了该表格是一维的事实。因此，我们只需要传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个单一数（这个数代表表格中的位置）。但是，如果我们处理两个或者更多维度，我们必须传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个数组函数，并且指明我们要检索的表格元素的位置。因此，如果我们不想检索一个二维数组的position (4,3)位置的元素，我们可以这样写：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Dim W as Variant 'return element &lt;br /&gt;
:Dim IndexPtrs(1 To 2) As Variant 'position in table &lt;br /&gt;
::... &lt;br /&gt;
:IndexPtrs(1) = 4 &lt;br /&gt;
:IndexPtrs(2) = 3 &lt;br /&gt;
:W = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](IndexPtrs) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==控制基元值格式==&lt;br /&gt;
[[CATable/zh|CATable]]中的每个基元值可以是一个数、一个字符串，或者其它一些基本类型（''例如''：[[Null|空值]]、[[Undefined|未定义]]、[[Reference|参考]]，或 [[Handle|句柄]]。通过说明类型和值，它们作为''变体''被返回，这是一种Visual Basic能读懂的数据结构。[[CATable/zh|CATable]]的[[CATable::RenderingStyle|RenderingStyle]]属性控制Analytica基础值是如何映射到Visual Basic变体的。 &lt;br /&gt;
&lt;br /&gt;
例如：可以通过使用Analytica 模型的数字格式设置将一个数值返回成一个数字或者字符串。如果被指定格式，有一个选线控制是截断数字的位数，还是精确返回。 &lt;br /&gt;
&lt;br /&gt;
子程序[[PrintResultTable/zh|PrintResultTable]]在&amp;lt;tt&amp;gt;frmMain.vb&amp;lt;/tt&amp;gt;中载入,其渲染风格直接指明：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::NumberAsText/zh|NumberAsText]] = True &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::FullPrecision/zh|FullPrecision]] = False &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::StringQuotes/zh|StringQuotes]] = 2 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
第一行指明数值应该根据与结果对象有关的数字格式被格式化为文本。例如在其程序输出中，我们将看到&amp;lt;tt&amp;gt;30.103M&amp;lt;/tt&amp;gt;，而非&amp;lt;tt&amp;gt;30102995.6639812&amp;lt;/tt&amp;gt;，如果我们让Visual Basic将数值串联我们的结果字符串，将显示该结果。在此事件中，一个值为字符串的单元格出现在结果中，返回值将明确带双引号。对于[[CARenderingStyle/zh|CARenderingStyle]]对象中的所有可用属性，请参考[[CARenderingStyle/zh|CARenderingStyle]]。&lt;br /&gt;
&lt;br /&gt;
===其它访问表格的方式===&lt;br /&gt;
有几种访问多维表格[[CATable/zh|CATable]]中元素的方式。每一种都有可能在特定的场合使用起来比较方便。 &lt;br /&gt;
&lt;br /&gt;
第一种方式就是使用[[CATable/zh | CATable]]的 [[CATable::GetDataByElements/zh|GetDataByElements]]或[[CATable::GetDataByLabels/zh|GetDataByLabels]]方法，上面代码示例中有显示。在此情况下，利用你想获取的基元值的单元格位置。 &lt;br /&gt;
&lt;br /&gt;
第二种方式就是使用[[CATable/zh|CATable]][[CATable::Slice/zh|Slice]]或[[CATable::Subscript/zh | Subscript]]方法获取一个少一个维度的新[[CATable/zh|CATable]]对象。通过重复减少维度，最终将获得0维度，这时你将获得一个单一基元值。此时，[[CATable/zh|CATable]]的[[CATable::AtomicValue/zh|AtomicValue]]方法返回该值 。[[CATable::AtomicValue/zh|AtomicValue]]方法是唯一获取一个标值的方法（因为没有坐标位置）。如果你需要建立完整结果其中一个切片的图形图像，必须使用此方法。 &lt;br /&gt;
&lt;br /&gt;
第三种方式就是使用[[CATable/zh|CATable]]的[[CATable::GetSafeArray/zh|GetSafeArray]]方法，将多维数组转化成一个''安全数组''（或者一个.NET数组）。你可以在使用VB或者其它.NET语言直接处理多维数组。因为对于Analytica维度没有固定顺序，但是安全数组和.NET数组有一个明确的顺序，你必须先使用[[CATable/zh|CATable]]对象的[[CATable::SetIndexOrder/zh|SetIndexOrder]]方法在调用[[CATable::GetSafeArray/zh|GetSafeArray]]之前指明维度的顺序。注意如果你知道你的数组是一维的，那就没必要了。&lt;br /&gt;
&lt;br /&gt;
===修改对象===&lt;br /&gt;
一个自定义用户程序通常从一个用户或者其它外部源获取输入，以便转化成Analytica模型中的输入变量。你可以设定输入变量的定义或者通过使用定义表格来这样做。 &lt;br /&gt;
&lt;br /&gt;
'''TestTxc''' 说明了如何修改'''Pop_exp'''定义，此模型是一个影响结果变量Cost的模型输入。要想在该示例中设定该定义，从主菜单上选择'''File &amp;gt; Change Population'''。将出现一个对话框，如下图所示：&lt;br /&gt;
&lt;br /&gt;
[[File:RedefiningtheVariableDefinition.jpg|400px/zh|文件：RedefiningtheVariableDefinition.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
在信息栏中输入一个新定义并点击'''Ok'''确认。主窗口将显示一个新的Cost值。当点击该对话框中的'''Ok'''按钮时，调用了&amp;lt;tt&amp;gt;ChangeDef.frm&amp;lt;/tt&amp;gt;函数，然后调用[[PrintAttributes]]函数打印&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果。&lt;br /&gt;
&lt;br /&gt;
此函数类似于：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Private Sub OkButton_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles OkButton.Click &lt;br /&gt;
::Dim errorText As String&lt;br /&gt;
::Dim pop_exp_Object As [[CAObject/zh|CAObject]] &lt;br /&gt;
::Dim errorCode As Short &lt;br /&gt;
::Dim errorString As String &lt;br /&gt;
::newDefinition = PopExposedDef.Text &lt;br /&gt;
::pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
::pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]](&amp;quot;[[Definition]]&amp;quot;, newDefinition) &lt;br /&gt;
::errorCode = adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &lt;br /&gt;
::If errorCode &amp;lt;&amp;gt; 0 Then &lt;br /&gt;
:::MsgBox(&amp;quot;This error occurred while processing your definition: &amp;quot; &amp;amp; vbCrLf &amp;amp; vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) :::PopExposedDef.Focus()&lt;br /&gt;
::Else&lt;br /&gt;
:::Me.Close() &lt;br /&gt;
:::frmMain.DefInstance.PrintAttributes(&amp;quot;Pop_exp&amp;quot;, &amp;quot;Cost&amp;quot;) &lt;br /&gt;
::End If &lt;br /&gt;
::ReleaseComObject(pop_exp_Object) &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
该函数抓取了输入到'''New Definition''' 新定义给'''Population Exposed'''栏，并通过使用[[CAObject/zh|CAObject]]对象中的[[CAObject::SetAttribute/zh|SetAttribute]]函数将它设置给&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;对象。然后调用[[PrintAttributes/zh|PrintAttributes]]，以计算&amp;lt;tt&amp;gt;Cost object&amp;lt;/tt&amp;gt;，并打印新的结果。要想给变量&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;设定一个新定义，我们可以为&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;获取[[CAObject/zh|CAObject]]对象，然后将其定义设置成用户输入的定义。通过使用下面的代码来实现：&lt;br /&gt;
:pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
:pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]]( &amp;quot;[[Definition]]&amp;quot;, newDefinition )&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
无论什么时候调用[[CAObject::SetAttribute/zh|SetAttribute]]，都应该检查[[CAEngine/zh|CAEngine]]自动化对象（'''adeEngine'''）的[[CAEngine::ErrorCode/zh|ErrorCode]]，以免它的定义是非法的。尝试一下输入一个新定义，比如&amp;lt;code&amp;gt;[[Uniform]](25M,35M)&amp;lt;/code&amp;gt;，然后点击'''Ok'''。当&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;的定义被改变时， &amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果由ADE重新计算，此时'''ResultTable'''接下来调用给Cost变量（在应用程序窗口重新显示时）。&lt;br /&gt;
&lt;br /&gt;
使用ADE绘图&lt;br /&gt;
&lt;br /&gt;
通过Analytica 4.6使用相同的绘图引擎，你可以建立一个图表或者图形以显示一个数组值或者不确定值结果。在ADE4.6中，你可以使用 [[CATable/zh|CATable]]的[[CATable::GraphToFile/zh|GraphToFile]]和[[CATable::GraphToStream/zh|GraphToStream]]方法。图形可以以几种可能的图像格式返回，例如'''image/png'''、 '''image/bmp'''或者 '''image/jpeg'''。 &lt;br /&gt;
&lt;br /&gt;
从可用图形选项中选择的最简单方式就是使用Analytica打开你的模型。你可以实验设置各种默认设置或者替代选择的变量，看它们是如何工作的。但你选择了你想设置的选项，保存模型。当为每一个生成结果图形时，ADE将使用这些设置。 &lt;br /&gt;
&lt;br /&gt;
对于更高维度的结果，可能需要做一些必要工作，以便选择将绘制结果的切片和具体的轴（也就是相对于图例哪个维度作为X轴）。[[CATable/zh|CATable]]的[[CATable::Subscript/zh|Subscript]]或[[CATable::Slice/zh|Slice]]方法可以用来控制轴选择特殊的切片用来绘制，能够用来控制轴。详情请参考[[CATable/zh|CATable]]。在我们的&amp;lt;tt&amp;gt;Tutorial.NET&amp;lt;/tt&amp;gt;示例中，我们有一个一维结果（&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;），因此我们没有必要担心截取或者绕轴旋转。 &lt;br /&gt;
&lt;br /&gt;
[[CATable::GraphToStream/zh|GraphToStream]]方法被用来从ADE中直接转化图形图形到一个用户界面中。使用[[CATable::GraphToStream/zh|GraphToStream]]比起使用[[CATable::GraphToFile/zh|GraphToFile]]来要稍微复杂一点，因为[[CATable::GraphToFile/zh|GraphToFile]]除了需要文件名以外还需要其它一些信息，以便编写图形。要使用[[CATable::GraphToStream/zh|GraphToStream]]，我们必须在内存内设置一个流，允许ADE写入该留，然后从该留重建。因为.NET流和COM流不兼容，你必须使用ADE一同提供的[[StreamConnector]]类型.&amp;lt;tt&amp;gt;frmMain&amp;lt;/tt&amp;gt; 中的'''GraphResult_Click'''子程序演示了[[CATable::GraphToStream/zh|GraphToStream]]的使用。从主应用程序窗口选择 '''Graph Result'''菜单选项，结果将出现在一个如下所示的图形当中：&lt;br /&gt;
&lt;br /&gt;
[[File:resultgraph.jpg/zh|文件：resultgraph.jpg]]&lt;br /&gt;
&lt;br /&gt;
==结论==&lt;br /&gt;
&lt;br /&gt;
在此教程中，我们介绍了Analytica决策引擎的几个重要方面。我们看到了如何建立一个ADE服务器对象，使用ADE打开模型，获取模型中的单个对象、计算对象、获取表格中的元素，以及修改模型中的对象。但是ADE可以做的远不止这些。 &lt;br /&gt;
&lt;br /&gt;
我们希望你已经足够了解其基本特征，这样你现在才能独自开始探索更多新的高级特征。我们建议你现在开始阅读字教程的剩余部分以了解ADE能做什么。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
| [[Installation of ADE/zh|ADE 安装]] &amp;lt;- ||  [[The ADE Tutorial/zh|ADE 入门教程]] || -&amp;gt; [[Using the ADE Server/zh|使用ADE服务器]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36314</id>
		<title>The ADE Tutorial/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36314"/>
		<updated>2015-10-27T06:37:00Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南 ]]&lt;br /&gt;
&lt;br /&gt;
此教程教你如何在一个Visual Basic程序中使用Analytica决策引擎（ADE）。&lt;br /&gt;
&lt;br /&gt;
==你的第一个ADE应用程序==&lt;br /&gt;
首先先从头开始写一个简单的ADE程序，只要确认一切设置正常。按照以下步骤操作：&lt;br /&gt;
&lt;br /&gt;
test&lt;br /&gt;
&lt;br /&gt;
第一个程序执行了以下操作：&lt;br /&gt;
*建立一个名称为ADE的[[CAEngine/zh|CAEngine]]自动化对象（通过使用&amp;lt;code&amp;gt;new [[CAEngine/zh|CAEngine]]&amp;lt;/code&amp;gt;).&lt;br /&gt;
*打开Analytica模型 (通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]] 方法。&lt;br /&gt;
*显示模型名称返回[[CAEngine::OpenModel/zh|OpenModel]]的值。&lt;br /&gt;
我们将在后面的章节详细了解这些信息。&lt;br /&gt;
&lt;br /&gt;
===接下来讲什么呢?===&lt;br /&gt;
我们不会尝试在此入门教程中解释ADE的特征。本指南后面几个章节会描述这些特征。 &lt;br /&gt;
&lt;br /&gt;
从现在开始，我们我们将使用名称为&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;的示例模型。打开 Analytica安装目录下 '''Example Models'''文件夹里面的'''Risk Analysis'''文件夹便可找到&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;文件。如果你找不到，或者你安装Analytica的时候未选择安装examples（示例）文件，在ADE安装目录下面的'''Examples\Tutorial.NET'''文件家中有一个副本。 &lt;br /&gt;
&lt;br /&gt;
Txc模型演示了减少污染物TXC排放的risk-benefit （风险-效益）分析。请用Analytica打开Txc查看它是如何工作的。 &lt;br /&gt;
&lt;br /&gt;
ADE '''Examples\Tutorial.NET''' 文件夹中名称为&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;的Visual Basic.NET程序示例显示了ADE很多方面。该程序建立了一个ADE自动化对象，打开包含该对象的&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，获取变量 &amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，计算变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;，通过获取每个表格的单独组件以表格的方式打印输出变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的结果，然后改变变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义。再次获取变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的值，看一下 变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;定义的改变对变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;有什么影响。如果设置正确的话,&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;将显示在“Text Txc window”中显示的窗口。 &lt;br /&gt;
&lt;br /&gt;
应用程序显示变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义（&amp;lt;tt&amp;gt;&amp;quot;Normal (30M, 3M)&amp;quot;&amp;lt;/tt&amp;gt;），以及与&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;关联的表格，这都基于&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义。你可以通过从主菜单选择'''File &amp;gt; Change Population Exposed'''改变&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，然后查看改变对&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;表格的影响。&lt;br /&gt;
&lt;br /&gt;
[[File:TextTxcWindow.png|400px/zh | 文件：TextTxcWindow.png|400px]]&lt;br /&gt;
&lt;br /&gt;
===区分title（名称） 和 identifier（标识符）===&lt;br /&gt;
无论什么时候，一个ADE函数都需要一个变量你必须传达变量的'''''[[Identifier|标识符]]''''' ，而不是它的'''''[[Title|名称]]'''''。这可能会引起混淆，因为在Analytica影响图中一般显示每一个变量的名称。默认情况下，在你最初建立每一个对象的时候，Analytica自动根据名称建立一个标识符。用（_）代替名称中的每一个空格或者其他非字母和数字字符。 &lt;br /&gt;
&lt;br /&gt;
你可以通过点击“Control+y”（或者从Object（对象）菜单选择'''Show by identifier''' ：显示标识符） 来以标识符显示变量。对于模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;，你可以看到名称为&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;变量的标识符为 &amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;。将变量传递给ADE函数时，使用标识符很重要。如果你传递&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;，ADE无法找到变量，并且将返回一个错误。&lt;br /&gt;
&lt;br /&gt;
===从Visual Basic中建立一个ADE 对象===&lt;br /&gt;
&lt;br /&gt;
如果你还没准备好，将名称为tt&amp;gt;Examples\Tutorial\TestTxc.sln&amp;lt;/tt&amp;gt;载入到Visual Basic.NET中，查看名称为&amp;lt;tt&amp;gt;TestTxc.vb&amp;lt;/tt&amp;gt;的文件的代码。其代码看起来像：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Imports ADEW &lt;br /&gt;
:. . . &lt;br /&gt;
:Public adeEngine As [[CAEngine/zh|CAEngine]]&lt;br /&gt;
&lt;br /&gt;
:Public Sub Main() &lt;br /&gt;
::Dim exeDirectory, theModel As String &lt;br /&gt;
::Dim theModelString As String &lt;br /&gt;
::exeDirectory = VB6.GetPath &lt;br /&gt;
::theModel = exeDirectory &amp;amp; &amp;quot;\..\&amp;quot; &amp;amp; &amp;quot;Txc.ana&amp;quot; &lt;br /&gt;
::adeEngine = New [[CAEngine/zh|CAEngine]]&lt;br /&gt;
::... &lt;br /&gt;
::theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
::... &lt;br /&gt;
::frmMain.DefInstance.Show() &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在每一个文件的顶部的代码将自动化对象 '''adeEngine''' 声明为一个[[CAEngine/zh|CAEngine]] 对象。使用此对象，我们能够访问[[CAEngine/zh|CAEngine]] 展示的所有公共函数（参考 [[ADE Server Class Reference/zh|ADE服务器类型参考]] ）&lt;br /&gt;
&lt;br /&gt;
变量&amp;lt;tt&amp;gt;adeEngine&amp;lt;/tt&amp;gt;包含我们的进程内对象[[CAEngine/zh|CAEngine]]。如果我们想使用ADE的本地（进程外）服务器版本，我们可以将一个项目参考添加到'''Analytica Decision Engine Server 4.6 COM''' 组件并将顶部行从&amp;lt;tt&amp;gt;Imports ADEW&amp;lt;/tt&amp;gt;改成&amp;lt;tt&amp;gt;Imports ADE&amp;lt;/tt&amp;gt;即可。 &lt;br /&gt;
&lt;br /&gt;
这里是另一种获得一个先[[CAEngine/zh|CAEngine]]对象的方法。此循序不需要给项目添加参考。&amp;lt;tt&amp;gt;&lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADEW4.6.CAEngine&amp;quot;) ’ in-process &lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADE4.6.CAEngine&amp;quot;) ’ out-of-process &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果想理解使用进程内和进程外（或本地）服务器的利与弊，以及哪一种自动化服务器用于不同的场景，参考[[Using_the_Analytica_Decision_Engine_Server#In-process_vs_Out-of-process/zh | In-process vs. out-of-process]]&lt;br /&gt;
&lt;br /&gt;
===COM和 Automation 接口比较===&lt;br /&gt;
在上面的例子当中，我们使用COM接口调用ADE。在一个COM 接口中，对象 在本例中为[[CAEngine/zh|CAEngine]] 被声明为[[CAEngine/zh|CAEngine]] ，编译器解决每一个成员函数，并且在编译时间内能探测几个明显的错误。另外，Visual Studio可以提供方法和参数类型列表当，在你编程的时候可以当做一个提示工具，在编写使用ADE程序是非常有用。COM调用比Automation调用要快一点，但是在ADE应用程序中速度差异通常不是很重要。对于ADE 4.6我们推荐使用COM结构，只要你的语言支持。&lt;br /&gt;
&lt;br /&gt;
在VB Automation中，你可以将一个对象简单声明为Object（对象），而不是像[[CAEngine/zh|CAEngine]]、[[CAObject/zh|CAObject]]等更加具体的类型。当使用Automation调用'''ADE'''方法时，在运行时间内确定方法。在编译时间内，编译器不知道你的 '''ADE''' 对象是否有一个名称为[[CAEngine::OpenModel/zh|OpenModel]]的函数。在VB中，调用COM方法或Automation 方法的语法是相通的——唯一的不同在于对象类型是否明确被声明。&lt;br /&gt;
&lt;br /&gt;
在VC++和C#中，调用COM的语法和调用Automatio的语法不同。在这些情况下，COM要方便的多，Automation能够获得相冗余。然而，同样的语言，包括VBScript和其他脚本语言，只支持Automation不支持COM。&lt;br /&gt;
&lt;br /&gt;
===监视Process（进程）===&lt;br /&gt;
当使用进程外ADE服务器时，你的代码必须在终止时释放[[CAEngine/zh|CAEngine]]COM对象。当最终[[CAEngine/zh|CAEngine]]使用被释放是，ADE.exe 进程自动终止。到目前为止所看到的代码，VB语言在达到程序末端时，自动处理释放对象。但是，当你调试你的代码是，你可以提前终止你的程序来修复bug，你的程序可能被Task Manager（任务管理器）终止，或者你自己的代码也可能奔溃，导致你的程序进程在它有机会释放对象之前终止。应为COM对象从来不会被释放，ADE.exe进程不知道它是否在使用中，你可能获得ADE.exe 僵尸进程。 &lt;br /&gt;
&lt;br /&gt;
为了避免这种情况发生，一种好的习惯就是在调用[[CAEngine/zh|CAEngine]]实例后 立即调用[[CAEngine::MonitorProcess/zh|CAEngine::MonitorProcess]]。通过这种方式，ADE能够得知哪一个进程正在使用它，同时将设置一个线程去探测你的进程是否在ADE被完全释放前终止。如果你的程序进程没有终止，ADE进程会立即将它关闭，消除了僵尸ADE进程的堆积。 &lt;br /&gt;
&lt;br /&gt;
要从一个.NET应用程序获得进程ID，使用System.Diagnostics.Process namespace中的'''GetCurrentProcess().Id''' 。在其他语言中，你可以使用Windows SDK 的'''GetProcessId( )'''函数。 &lt;br /&gt;
&lt;br /&gt;
'''[[CAEngine::MonitorProcess/zh|MonitorProcess]]()''' 只能用来监视运行ADE进程的同一台计算机的进程，一次当通过DCOM运行ADE时不能使用。当使用进程内ADEW服务器时没有必要使用。&lt;br /&gt;
&lt;br /&gt;
==使用ADE打开模型==&lt;br /&gt;
我们现在打开&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，显示我们的应用程序主窗口。使用以下调用：tt&amp;gt;&lt;br /&gt;
:theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
:frmMain.DefInstance.Show &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]]函数打开模型。如果成功的话，变量&amp;lt;tt&amp;gt;theModelString&amp;lt;/tt&amp;gt;将包含模型的名字。否则，将包含一个空的串。虽然由于为了简介的缘故，我们没有这样做，但是你应该检查从[[CAEngine::OpenModel/zh|OpenModel]]函数返回的是不是一个空的串。如果是，说明在你打开的模型中存在一个错误。你可以使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]]属性找出是哪种错误 （&amp;lt;tt&amp;gt;adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] 和adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]&amp;lt;/tt&amp;gt;）。&lt;br /&gt;
&lt;br /&gt;
==从Analytica模型中检索对象==&lt;br /&gt;
下一步就是从我们的模型中检索对象（变量、模块、函数等），以便我们能获取他们的属性（[[definition|定义]]、[[title|名称]]、[[class|类型]]等等 ）。我们的示例模型（&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;）操作&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;和&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;对象。尤其是，修改&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;可以查看这是如何影响&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt; 对象。&lt;br /&gt;
&lt;br /&gt;
我们的&amp;lt;tt&amp;gt;TxcTest.vbproj&amp;lt;/tt&amp;gt; （&amp;lt;tt&amp;gt;TxcText.sln&amp;lt;/tt&amp;gt;）项目中的&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;文件里的 '''PrintAttributes''' 函数演示了如何检索对象。该函数首先被&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''Form_Load''' 函数调用，当应用程序启动后，可以显示'''Cost'''表格。当然无论什么时候，只要我们想输出'''Cost'''表格的当前值，都可以调用。该函数如下所示：&lt;br /&gt;
:Public Sub PrintAttributes(ByRef inputIdentifier As String, ByRef  outputIdentifier As String) &lt;br /&gt;
::Dim inputObject, outputObject As [[CAObject/zh|CAObject]]&lt;br /&gt;
::Dim resultTable As [[CATable/zh|CATable]]&lt;br /&gt;
::Dim definitionAttrInput As String &lt;br /&gt;
::inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
::outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier) &lt;br /&gt;
::definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;definition&amp;quot;) &lt;br /&gt;
::resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]]&lt;br /&gt;
::Call PrintResultTable(resultTable, inputIdentifier, definitionAttrInput, outputIdentifier) &lt;br /&gt;
::ReleaseComObject(resultTable) &lt;br /&gt;
::ReleaseComObject(inputObject) &lt;br /&gt;
::ReleaseComObject(outputObject) &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''PrintAttributes'''和作为'''inputIdentifier'''参数的&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;变量标识符以及作为'''outputIdentifier'''参数的'''Cost'''变量一起使用。如下所示通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::GetObjectByName/zh|GetObjectByName]]函数提取相应对象：&amp;lt;tt&amp;gt;&lt;br /&gt;
:inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取成功，将返回一个[[CAObject/zh|CAObject]]类型对象。如果使用'''[[CAObject/zh|CAObject]]'''的函数，参考[[CAObject/zh|SendCommand(command)]]，可以获得一个[[CAObject/zh|CAObject]]的完整函数列表。如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取失败，返回值为&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;。代码应该检查以确保[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取的结果是有效的。如果找不到，可使用[[CAEngine/zh|CAEngine]]的 [[CAEngine::ErrorCode/zh|ErrorCode]]和 [[CAEngine::ErrorText/zh|ErrorText]]属性获取错误信息。例如：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Set inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:If inputObject Is Nothing Then &lt;br /&gt;
::MsgBox(“This error from GetObjectByName occurred: “&amp;amp; _ vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &amp;amp; “:” &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) &lt;br /&gt;
:Else &lt;br /&gt;
::'inputObject valid &lt;br /&gt;
:End If&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===获取对象属性===&lt;br /&gt;
每一个Analytica对象都有一组属性，例如[[identifier|标识符]]、[[title|名称]]、[[description| 描述]]和[[class|类型]]。你可以使用[[CAObject::GetAttribute/zh|GetAttribute]]函数来获去Analytica对象的属性。例如，如要获取'''inputObject'''的定义（当前为cost）：&amp;lt;tt&amp;gt;&lt;br /&gt;
:definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh|GetAttribute]](&amp;quot;[[Definition|定义]]&amp;quot;) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt; 中，&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;的定义为&amp;quot;&amp;lt;tt&amp;gt;[[Normal]](30M, 3M)&amp;lt;/tt&amp;gt;&amp;quot; ，我们将它储存在'''definitionAttrInput'''当中。.&lt;br /&gt;
&lt;br /&gt;
===计算对象和检索结果===&lt;br /&gt;
使用[[CAObject/zh|CAObject]]的[[CAObject::Result/zh|Result]]或[[CAObject::ResultTable/zh|ResultTable]]方法来获取变量的值。如果有必要的话，ADE先自动计算变量。如果你确定结果为基元（只有一个元素），使用[[CAObject::Result/zh|Result]]方法。否则使用[[CAObject::ResultTable/zh|ResultTable]]，检索结果为一个''数组''。基元结果当作一个特殊数组案例来处理，没有维度的数组。如果值为基元[[CATable::AtomicValue/zh|AtomicValue]]方法将返回一个数字或者字符串单一值。 &lt;br /&gt;
&lt;br /&gt;
默认情况下，[[CAObject::Result/zh|Result]]和[[CAObject::ResultTable/zh|ResultTable]]返回结果的中值，也就是说，ADE以确定性方式计算结果。对于一个概率值，将[[CAObject/zh|CAObject]]的[[CAObject::ResultType/zh|ResultType]]属性设置为想要的不确定性视图——Mean（平均值） Sample（样本）、PDF（概率密度函数）、CDF（累计分布函数）、Confidence bands（置信带）、或者Statistics（统计数据）详情请参考[[CAObject::ResultType/zh|ResultType]]。我们通过如下的方式获取outputObject 输出对象 的值：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]] &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
结果为一个[[CATable/zh|CATable]]对象，允许我们访问一个表格中的单个元素。 &lt;br /&gt;
&lt;br /&gt;
如果你通过调用[[CAObject::Result/zh|Result]]来获取一个数组（或者表格）的值，将返回数组为一个字符串，列出索引和元素，以逗号隔开。通常使用[[CAObject::ResultTable/zh|ResultTable]]更加简单，这样你没有必要从字符串中解析表格的元素。&lt;br /&gt;
&lt;br /&gt;
===获取表格索引元素===&lt;br /&gt;
一个Analytica表格包含0个或者多个索引。如果包含一个索引，那么该表格是1维表格；如果有2个索引，说他是2维表格，依此类推。0维度表格包含一个“单一基元”（或标量）值。你可以使用CATable的[[CATable::NumDims/zh|NumDims]]获取表格的维数（也就是索引数）。要想获取表格的单个索引，可使用[[CATable/zh|CATable]]的 [[CATable::IndexNames/zh|IndexNames]]和 [[CATable::GetIndexObject/zh|GetIndexObject]]函数。 &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''PrintResultTable'''函数说明了这两个函数的使用。从'''PrintAttributes'''中调用'''PrintResultTable'''，执行打印'''TestTxc'''中的表格的实际工作（为了简洁起见，我们只给出了关联ADE的该函数部分）。&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Public Sub PrintResultTable(ByRef resultTable As CATable, ByRef inputIdentifier As String, ByRef definitionAttrInput As String, ByRef outputIdentifier As String) &lt;br /&gt;
::Dim theIndexName, theTableName As String &lt;br /&gt;
::Dim theIndexElement As String &lt;br /&gt;
::Dim theTableElement &lt;br /&gt;
::Dim theIndexObj As [[CAIndex/zh|CAIndex]]&lt;br /&gt;
::Dim numEls As Integer &lt;br /&gt;
::Dim spaces, i As Integer &lt;br /&gt;
::Dim lenStr As Short &lt;br /&gt;
::Dim OutputStr As Short &lt;br /&gt;
::Dim spaceString, underlineString As String &lt;br /&gt;
::... &lt;br /&gt;
::theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1) &lt;br /&gt;
::theTableName = resultTable.[[CATable::Name/zh|Name]] &lt;br /&gt;
::theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName) &lt;br /&gt;
::numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
::... &lt;br /&gt;
::For i = 1 To numEls &lt;br /&gt;
:::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
:::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
:::... &lt;br /&gt;
::Next i &lt;br /&gt;
::InformationPane.Text = outputString &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
通过'''PrintResultTable'''获取一个表格的索引方法如下：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1)&lt;br /&gt;
:theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
我们通过使用[[CATable/zh|CATable]]的[[CATable::IndexNames/zh|IndexNames]]函数获取第一个索引的名字。我们将它传递给[[CATable/zh|CATable]]的[[CATable::GetIndexObject/zh|GetIndexObject]]函数以获取表示我们的索引的[[CAIndex/zh|CAIndex]]。该自动化对象返回其相应索引的相关信息。如果此函数调用失败，将返回&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;信息。在此情况下，使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]] 函数找出原因。&lt;br /&gt;
&lt;br /&gt;
==从CATable和CAIndex中获取信息==&lt;br /&gt;
[[PrintResultTable]]说明了如何从[[CATable/zh| CATable]]和[[CAIndex/zh|CAIndex]] 对象获取信息。该代码获取'''Cost'''表格的索引和表格元素：&lt;br /&gt;
: &amp;lt;tt&amp;gt;&lt;br /&gt;
:numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
:For i = 1 To numEls &lt;br /&gt;
::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
::... &lt;br /&gt;
:Next i &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[CAIndex/zh|CAIndex]]的[[CAIndex::IndexElements/zh|IndexElements]]属性返回第一个索引中的元素个数。[[CAIndex/zh|CAIndex]]的[[CAIndex::GetValueByNumber/zh|GetValueByNumber]]函数获取单个索引元素。 &lt;br /&gt;
&lt;br /&gt;
我们通过传递表格中元素的坐标，使用  [[CATable/zh|CATable]]的[[CATable::GetDataByElements/zh|GetDataByElements]]函数获取'''Cost'''表格对象的单个表格元素'''resultTable'''。 &lt;br /&gt;
&lt;br /&gt;
当我检索 [[CATable/zh|CATable]]对象中单个元素（'''resultTable'''）的时候，我们利用了该表格是一维的事实。因此，我们只需要传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个单一数（这个数代表表格中的位置）。但是，如果我们处理两个或者更多维度，我们必须传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个数组函数，并且指明我们要检索的表格元素的位置。因此，如果我们不想检索一个二维数组的position (4,3)位置的元素，我们可以这样写：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Dim W as Variant 'return element &lt;br /&gt;
:Dim IndexPtrs(1 To 2) As Variant 'position in table &lt;br /&gt;
::... &lt;br /&gt;
:IndexPtrs(1) = 4 &lt;br /&gt;
:IndexPtrs(2) = 3 &lt;br /&gt;
:W = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](IndexPtrs) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==控制基元值格式==&lt;br /&gt;
[[CATable/zh|CATable]]中的每个基元值可以是一个数、一个字符串，或者其它一些基本类型（''例如''：[[Null|空值]]、[[Undefined|未定义]]、[[Reference|参考]]，或 [[Handle|句柄]]。通过说明类型和值，它们作为''变体''被返回，这是一种Visual Basic能读懂的数据结构。[[CATable/zh|CATable]]的[[CATable::RenderingStyle|RenderingStyle]]属性控制Analytica基础值是如何映射到Visual Basic变体的。 &lt;br /&gt;
&lt;br /&gt;
例如：可以通过使用Analytica 模型的数字格式设置将一个数值返回成一个数字或者字符串。如果被指定格式，有一个选线控制是截断数字的位数，还是精确返回。 &lt;br /&gt;
&lt;br /&gt;
子程序[[PrintResultTable/zh|PrintResultTable]]在&amp;lt;tt&amp;gt;frmMain.vb&amp;lt;/tt&amp;gt;中载入,其渲染风格直接指明：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::NumberAsText/zh|NumberAsText]] = True &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::FullPrecision/zh|FullPrecision]] = False &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::StringQuotes/zh|StringQuotes]] = 2 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
第一行指明数值应该根据与结果对象有关的数字格式被格式化为文本。例如在其程序输出中，我们将看到&amp;lt;tt&amp;gt;30.103M&amp;lt;/tt&amp;gt;，而非&amp;lt;tt&amp;gt;30102995.6639812&amp;lt;/tt&amp;gt;，如果我们让Visual Basic将数值串联我们的结果字符串，将显示该结果。在此事件中，一个值为字符串的单元格出现在结果中，返回值将明确带双引号。对于[[CARenderingStyle/zh|CARenderingStyle]]对象中的所有可用属性，请参考[[CARenderingStyle/zh|CARenderingStyle]]。&lt;br /&gt;
&lt;br /&gt;
===其它访问表格的方式===&lt;br /&gt;
有几种访问多维表格[[CATable/zh|CATable]]中元素的方式。每一种都有可能在特定的场合使用起来比较方便。 &lt;br /&gt;
&lt;br /&gt;
第一种方式就是使用[[CATable/zh | CATable]]的 [[CATable::GetDataByElements/zh|GetDataByElements]]或[[CATable::GetDataByLabels/zh|GetDataByLabels]]方法，上面代码示例中有显示。在此情况下，利用你想获取的基元值的单元格位置。 &lt;br /&gt;
&lt;br /&gt;
第二种方式就是使用[[CATable/zh|CATable]][[CATable::Slice/zh|Slice]]或[[CATable::Subscript/zh | Subscript]]方法获取一个少一个维度的新[[CATable/zh|CATable]]对象。通过重复减少维度，最终将获得0维度，这时你将获得一个单一基元值。此时，[[CATable/zh|CATable]]的[[CATable::AtomicValue/zh|AtomicValue]]方法返回该值 。[[CATable::AtomicValue/zh|AtomicValue]]方法是唯一获取一个标值的方法（因为没有坐标位置）。如果你需要建立完整结果其中一个切片的图形图像，必须使用此方法。 &lt;br /&gt;
&lt;br /&gt;
第三种方式就是使用[[CATable/zh|CATable]]的[[CATable::GetSafeArray/zh|GetSafeArray]]方法，将多维数组转化成一个''安全数组''（或者一个.NET数组）。你可以在使用VB或者其它.NET语言直接处理多维数组。因为对于Analytica维度没有固定顺序，但是安全数组和.NET数组有一个明确的顺序，你必须先使用[[CATable/zh|CATable]]对象的[[CATable::SetIndexOrder/zh|SetIndexOrder]]方法在调用[[CATable::GetSafeArray/zh|GetSafeArray]]之前指明维度的顺序。注意如果你知道你的数组是一维的，那就没必要了。&lt;br /&gt;
&lt;br /&gt;
===修改对象===&lt;br /&gt;
一个自定义用户程序通常从一个用户或者其它外部源获取输入，以便转化成Analytica模型中的输入变量。你可以设定输入变量的定义或者通过使用定义表格来这样做。 &lt;br /&gt;
&lt;br /&gt;
'''TestTxc''' 说明了如何修改'''Pop_exp'''定义，此模型是一个影响结果变量Cost的模型输入。要想在该示例中设定该定义，从主菜单上选择'''File &amp;gt; Change Population'''。将出现一个对话框，如下图所示：&lt;br /&gt;
&lt;br /&gt;
[[File:RedefiningtheVariableDefinition.jpg|400px/zh|文件：RedefiningtheVariableDefinition.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
在信息栏中输入一个新定义并点击'''Ok'''确认。主窗口将显示一个新的Cost值。当点击该对话框中的'''Ok'''按钮时，调用了&amp;lt;tt&amp;gt;ChangeDef.frm&amp;lt;/tt&amp;gt;函数，然后调用[[PrintAttributes/zh|PrintAttributes]]函数打印&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果。&lt;br /&gt;
&lt;br /&gt;
此函数类似于：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Private Sub OkButton_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles OkButton.Click &lt;br /&gt;
::Dim errorText As String&lt;br /&gt;
::Dim pop_exp_Object As [[CAObject/zh|CAObject]] &lt;br /&gt;
::Dim errorCode As Short &lt;br /&gt;
::Dim errorString As String &lt;br /&gt;
::newDefinition = PopExposedDef.Text &lt;br /&gt;
::pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
::pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]](&amp;quot;[[Definition]]&amp;quot;, newDefinition) &lt;br /&gt;
::errorCode = adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &lt;br /&gt;
::If errorCode &amp;lt;&amp;gt; 0 Then &lt;br /&gt;
:::MsgBox(&amp;quot;This error occurred while processing your definition: &amp;quot; &amp;amp; vbCrLf &amp;amp; vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) :::PopExposedDef.Focus()&lt;br /&gt;
::Else&lt;br /&gt;
:::Me.Close() &lt;br /&gt;
:::frmMain.DefInstance.PrintAttributes(&amp;quot;Pop_exp&amp;quot;, &amp;quot;Cost&amp;quot;) &lt;br /&gt;
::End If &lt;br /&gt;
::ReleaseComObject(pop_exp_Object) &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
该函数抓取了输入到'''New Definition''' 新定义给'''Population Exposed'''栏，并通过使用[[CAObject/zh|CAObject]]对象中的[[CAObject::SetAttribute/zh|SetAttribute]]函数将它设置给&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;对象。然后调用[[PrintAttributes/zh|PrintAttributes]]，以计算&amp;lt;tt&amp;gt;Cost object&amp;lt;/tt&amp;gt;，并打印新的结果。要想给变量&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;设定一个新定义，我们可以为&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;获取[[CAObject/zh|CAObject]]对象，然后将其定义设置成用户输入的定义。通过使用下面的代码来实现：&lt;br /&gt;
:pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
:pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]]( &amp;quot;[[Definition]]&amp;quot;, newDefinition )&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
无论什么时候调用[[CAObject::SetAttribute/zh|SetAttribute]]，都应该检查[[CAEngine/zh|CAEngine]]自动化对象（'''adeEngine'''）的[[CAEngine::ErrorCode/zh|ErrorCode]]，以免它的定义是非法的。尝试一下输入一个新定义，比如&amp;lt;code&amp;gt;[[Uniform]](25M,35M)&amp;lt;/code&amp;gt;，然后点击'''Ok'''。当&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;的定义被改变时， &amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果由ADE重新计算，此时'''ResultTable'''接下来调用给Cost变量（在应用程序窗口重新显示时）。&lt;br /&gt;
&lt;br /&gt;
使用ADE绘图&lt;br /&gt;
&lt;br /&gt;
通过Analytica 4.6使用相同的绘图引擎，你可以建立一个图表或者图形以显示一个数组值或者不确定值结果。在ADE4.6中，你可以使用 [[CATable/zh|CATable]]的[[CATable::GraphToFile/zh|GraphToFile]]和[[CATable::GraphToStream/zh|GraphToStream]]方法。图形可以以几种可能的图像格式返回，例如'''image/png'''、 '''image/bmp'''或者 '''image/jpeg'''。 &lt;br /&gt;
&lt;br /&gt;
从可用图形选项中选择的最简单方式就是使用Analytica打开你的模型。你可以实验设置各种默认设置或者替代选择的变量，看它们是如何工作的。但你选择了你想设置的选项，保存模型。当为每一个生成结果图形时，ADE将使用这些设置。 &lt;br /&gt;
&lt;br /&gt;
对于更高维度的结果，可能需要做一些必要工作，以便选择将绘制结果的切片和具体的轴（也就是相对于图例哪个维度作为X轴）。[[CATable/zh|CATable]]的[[CATable::Subscript/zh|Subscript]]或[[CATable::Slice/zh|Slice]]方法可以用来控制轴选择特殊的切片用来绘制，能够用来控制轴。详情请参考[[CATable/zh|CATable]]。在我们的&amp;lt;tt&amp;gt;Tutorial.NET&amp;lt;/tt&amp;gt;示例中，我们有一个一维结果（&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;），因此我们没有必要担心截取或者绕轴旋转。 &lt;br /&gt;
&lt;br /&gt;
[[CATable::GraphToStream/zh|GraphToStream]]方法被用来从ADE中直接转化图形图形到一个用户界面中。使用[[CATable::GraphToStream/zh|GraphToStream]]比起使用[[CATable::GraphToFile/zh|GraphToFile]]来要稍微复杂一点，因为[[CATable::GraphToFile/zh|GraphToFile]]除了需要文件名以外还需要其它一些信息，以便编写图形。要使用[[CATable::GraphToStream/zh|GraphToStream]]，我们必须在内存内设置一个流，允许ADE写入该留，然后从该留重建。因为.NET流和COM流不兼容，你必须使用ADE一同提供的[[StreamConnector]]类型.&amp;lt;tt&amp;gt;frmMain&amp;lt;/tt&amp;gt; 中的'''GraphResult_Click'''子程序演示了[[CATable::GraphToStream/zh|GraphToStream]]的使用。从主应用程序窗口选择 '''Graph Result'''菜单选项，结果将出现在一个如下所示的图形当中：&lt;br /&gt;
&lt;br /&gt;
[[File:resultgraph.jpg/zh|文件：resultgraph.jpg]]&lt;br /&gt;
&lt;br /&gt;
==结论==&lt;br /&gt;
&lt;br /&gt;
在此教程中，我们介绍了Analytica决策引擎的几个重要方面。我们看到了如何建立一个ADE服务器对象，使用ADE打开模型，获取模型中的单个对象、计算对象、获取表格中的元素，以及修改模型中的对象。但是ADE可以做的远不止这些。 &lt;br /&gt;
&lt;br /&gt;
我们希望你已经足够了解其基本特征，这样你现在才能独自开始探索更多新的高级特征。我们建议你现在开始阅读字教程的剩余部分以了解ADE能做什么。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
| [[Installation of ADE/zh|ADE 安装]] &amp;lt;- ||  [[The ADE Tutorial/zh|ADE 入门教程]] || -&amp;gt; [[Using the ADE Server/zh|使用ADE服务器]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36312</id>
		<title>The ADE Tutorial/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36312"/>
		<updated>2015-10-27T06:36:27Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南 ]]&lt;br /&gt;
&lt;br /&gt;
此教程教你如何在一个Visual Basic程序中使用Analytica决策引擎（ADE）。&lt;br /&gt;
&lt;br /&gt;
==你的第一个ADE应用程序==&lt;br /&gt;
首先先从头开始写一个简单的ADE程序，只要确认一切设置正常。按照以下步骤操作：&lt;br /&gt;
&lt;br /&gt;
test&lt;br /&gt;
&lt;br /&gt;
第一个程序执行了以下操作：&lt;br /&gt;
*建立一个名称为ADE的[[CAEngine/zh|CAEngine]]自动化对象（通过使用&amp;lt;code&amp;gt;new [[CAEngine/zh|CAEngine]]&amp;lt;/code&amp;gt;).&lt;br /&gt;
*打开Analytica模型 (通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]] 方法。&lt;br /&gt;
*显示模型名称返回[[CAEngine::OpenModel/zh|OpenModel]]的值。&lt;br /&gt;
我们将在后面的章节详细了解这些信息。&lt;br /&gt;
&lt;br /&gt;
===接下来讲什么呢?===&lt;br /&gt;
我们不会尝试在此入门教程中解释ADE的特征。本指南后面几个章节会描述这些特征。 &lt;br /&gt;
&lt;br /&gt;
从现在开始，我们我们将使用名称为&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;的示例模型。打开 Analytica安装目录下 '''Example Models'''文件夹里面的'''Risk Analysis'''文件夹便可找到&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;文件。如果你找不到，或者你安装Analytica的时候未选择安装examples（示例）文件，在ADE安装目录下面的'''Examples\Tutorial.NET'''文件家中有一个副本。 &lt;br /&gt;
&lt;br /&gt;
Txc模型演示了减少污染物TXC排放的risk-benefit （风险-效益）分析。请用Analytica打开Txc查看它是如何工作的。 &lt;br /&gt;
&lt;br /&gt;
ADE '''Examples\Tutorial.NET''' 文件夹中名称为&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;的Visual Basic.NET程序示例显示了ADE很多方面。该程序建立了一个ADE自动化对象，打开包含该对象的&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，获取变量 &amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，计算变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;，通过获取每个表格的单独组件以表格的方式打印输出变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的结果，然后改变变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义。再次获取变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的值，看一下 变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;定义的改变对变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;有什么影响。如果设置正确的话,&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;将显示在“Text Txc window”中显示的窗口。 &lt;br /&gt;
&lt;br /&gt;
应用程序显示变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义（&amp;lt;tt&amp;gt;&amp;quot;Normal (30M, 3M)&amp;quot;&amp;lt;/tt&amp;gt;），以及与&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;关联的表格，这都基于&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义。你可以通过从主菜单选择'''File &amp;gt; Change Population Exposed'''改变&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，然后查看改变对&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;表格的影响。&lt;br /&gt;
&lt;br /&gt;
[[File:TextTxcWindow.png|400px/zh | 文件：TextTxcWindow.png|400px]]&lt;br /&gt;
&lt;br /&gt;
===区分title（名称） 和 identifier（标识符）===&lt;br /&gt;
无论什么时候，一个ADE函数都需要一个变量你必须传达变量的'''''[[Identifier|标识符]]''''' ，而不是它的'''''[[Title|名称]]'''''。这可能会引起混淆，因为在Analytica影响图中一般显示每一个变量的名称。默认情况下，在你最初建立每一个对象的时候，Analytica自动根据名称建立一个标识符。用（_）代替名称中的每一个空格或者其他非字母和数字字符。 &lt;br /&gt;
&lt;br /&gt;
你可以通过点击“Control+y”（或者从Object（对象）菜单选择'''Show by identifier''' ：显示标识符） 来以标识符显示变量。对于模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;，你可以看到名称为&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;变量的标识符为 &amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;。将变量传递给ADE函数时，使用标识符很重要。如果你传递&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;，ADE无法找到变量，并且将返回一个错误。&lt;br /&gt;
&lt;br /&gt;
===从Visual Basic中建立一个ADE 对象===&lt;br /&gt;
&lt;br /&gt;
如果你还没准备好，将名称为tt&amp;gt;Examples\Tutorial\TestTxc.sln&amp;lt;/tt&amp;gt;载入到Visual Basic.NET中，查看名称为&amp;lt;tt&amp;gt;TestTxc.vb&amp;lt;/tt&amp;gt;的文件的代码。其代码看起来像：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Imports ADEW &lt;br /&gt;
:. . . &lt;br /&gt;
:Public adeEngine As [[CAEngine/zh|CAEngine]]&lt;br /&gt;
&lt;br /&gt;
:Public Sub Main() &lt;br /&gt;
::Dim exeDirectory, theModel As String &lt;br /&gt;
::Dim theModelString As String &lt;br /&gt;
::exeDirectory = VB6.GetPath &lt;br /&gt;
::theModel = exeDirectory &amp;amp; &amp;quot;\..\&amp;quot; &amp;amp; &amp;quot;Txc.ana&amp;quot; &lt;br /&gt;
::adeEngine = New [[CAEngine/zh|CAEngine]]&lt;br /&gt;
::... &lt;br /&gt;
::theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
::... &lt;br /&gt;
::frmMain.DefInstance.Show() &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在每一个文件的顶部的代码将自动化对象 '''adeEngine''' 声明为一个[[CAEngine/zh|CAEngine]] 对象。使用此对象，我们能够访问[[CAEngine/zh|CAEngine]] 展示的所有公共函数（参考 [[ADE Server Class Reference/zh|ADE服务器类型参考]] ）&lt;br /&gt;
&lt;br /&gt;
变量&amp;lt;tt&amp;gt;adeEngine&amp;lt;/tt&amp;gt;包含我们的进程内对象[[CAEngine/zh|CAEngine]]。如果我们想使用ADE的本地（进程外）服务器版本，我们可以将一个项目参考添加到'''Analytica Decision Engine Server 4.6 COM''' 组件并将顶部行从&amp;lt;tt&amp;gt;Imports ADEW&amp;lt;/tt&amp;gt;改成&amp;lt;tt&amp;gt;Imports ADE&amp;lt;/tt&amp;gt;即可。 &lt;br /&gt;
&lt;br /&gt;
这里是另一种获得一个先[[CAEngine/zh|CAEngine]]对象的方法。此循序不需要给项目添加参考。&amp;lt;tt&amp;gt;&lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADEW4.6.CAEngine&amp;quot;) ’ in-process &lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADE4.6.CAEngine&amp;quot;) ’ out-of-process &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果想理解使用进程内和进程外（或本地）服务器的利与弊，以及哪一种自动化服务器用于不同的场景，参考[[Using_the_Analytica_Decision_Engine_Server#In-process_vs_Out-of-process/zh | In-process vs. out-of-process]]&lt;br /&gt;
&lt;br /&gt;
===COM和 Automation 接口比较===&lt;br /&gt;
在上面的例子当中，我们使用COM接口调用ADE。在一个COM 接口中，对象 在本例中为[[CAEngine/zh|CAEngine]] 被声明为[[CAEngine/zh|CAEngine]] ，编译器解决每一个成员函数，并且在编译时间内能探测几个明显的错误。另外，Visual Studio可以提供方法和参数类型列表当，在你编程的时候可以当做一个提示工具，在编写使用ADE程序是非常有用。COM调用比Automation调用要快一点，但是在ADE应用程序中速度差异通常不是很重要。对于ADE 4.6我们推荐使用COM结构，只要你的语言支持。&lt;br /&gt;
&lt;br /&gt;
在VB Automation中，你可以将一个对象简单声明为Object（对象），而不是像 [[CAEngine/zh|CAEngine]]、[[CAObject/zh|CAObject]]等更加具体的类型。当使用Automation调用'''ADE'''方法时，在运行时间内确定方法。在编译时间内，编译器不知道你的 '''ADE''' 对象是否有一个名称为[[CAEngine::OpenModel/zh|OpenModel]]的函数。在VB中，调用COM方法或Automation 方法的语法是相通的——唯一的不同在于对象类型是否明确被声明。&lt;br /&gt;
&lt;br /&gt;
在VC++和C#中，调用COM的语法和调用Automatio的语法不同。在这些情况下，COM要方便的多，Automation能够获得相冗余。然而，同样的语言，包括VBScript和其他脚本语言，只支持Automation不支持COM。&lt;br /&gt;
&lt;br /&gt;
===监视Process（进程）===&lt;br /&gt;
当使用进程外ADE服务器时，你的代码必须在终止时释放[[CAEngine/zh|CAEngine]]COM对象。当最终[[CAEngine/zh|CAEngine]]使用被释放是，ADE.exe 进程自动终止。到目前为止所看到的代码，VB语言在达到程序末端时，自动处理释放对象。但是，当你调试你的代码是，你可以提前终止你的程序来修复bug，你的程序可能被Task Manager（任务管理器）终止，或者你自己的代码也可能奔溃，导致你的程序进程在它有机会释放对象之前终止。应为COM对象从来不会被释放，ADE.exe进程不知道它是否在使用中，你可能获得ADE.exe 僵尸进程。 &lt;br /&gt;
&lt;br /&gt;
为了避免这种情况发生，一种好的习惯就是在调用[[CAEngine/zh|CAEngine]]实例后 立即调用[[CAEngine::MonitorProcess/zh|CAEngine::MonitorProcess]]。通过这种方式，ADE能够得知哪一个进程正在使用它，同时将设置一个线程去探测你的进程是否在ADE被完全释放前终止。如果你的程序进程没有终止，ADE进程会立即将它关闭，消除了僵尸ADE进程的堆积。 &lt;br /&gt;
&lt;br /&gt;
要从一个.NET应用程序获得进程ID，使用System.Diagnostics.Process namespace中的'''GetCurrentProcess().Id''' 。在其他语言中，你可以使用Windows SDK 的'''GetProcessId( )'''函数。 &lt;br /&gt;
&lt;br /&gt;
'''[[CAEngine::MonitorProcess/zh|MonitorProcess]]()''' 只能用来监视运行ADE进程的同一台计算机的进程，一次当通过DCOM运行ADE时不能使用。当使用进程内ADEW服务器时没有必要使用。&lt;br /&gt;
&lt;br /&gt;
==使用ADE打开模型==&lt;br /&gt;
我们现在打开&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，显示我们的应用程序主窗口。使用以下调用：tt&amp;gt;&lt;br /&gt;
:theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
:frmMain.DefInstance.Show &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]]函数打开模型。如果成功的话，变量&amp;lt;tt&amp;gt;theModelString&amp;lt;/tt&amp;gt;将包含模型的名字。否则，将包含一个空的串。虽然由于为了简介的缘故，我们没有这样做，但是你应该检查从[[CAEngine::OpenModel/zh|OpenModel]]函数返回的是不是一个空的串。如果是，说明在你打开的模型中存在一个错误。你可以使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]]属性找出是哪种错误 （&amp;lt;tt&amp;gt;adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] 和adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]&amp;lt;/tt&amp;gt;）。&lt;br /&gt;
&lt;br /&gt;
==从Analytica模型中检索对象==&lt;br /&gt;
下一步就是从我们的模型中检索对象（变量、模块、函数等），以便我们能获取他们的属性（[[definition|定义]]、[[title|名称]]、[[class|类型]]等等 ）。我们的示例模型（&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;）操作&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;和&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;对象。尤其是，修改&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;可以查看这是如何影响&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt; 对象。&lt;br /&gt;
&lt;br /&gt;
我们的&amp;lt;tt&amp;gt;TxcTest.vbproj&amp;lt;/tt&amp;gt; （&amp;lt;tt&amp;gt;TxcText.sln&amp;lt;/tt&amp;gt;）项目中的&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;文件里的 '''PrintAttributes''' 函数演示了如何检索对象。该函数首先被&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''Form_Load''' 函数调用，当应用程序启动后，可以显示'''Cost'''表格。当然无论什么时候，只要我们想输出'''Cost'''表格的当前值，都可以调用。该函数如下所示：&lt;br /&gt;
:Public Sub PrintAttributes(ByRef inputIdentifier As String, ByRef  outputIdentifier As String) &lt;br /&gt;
::Dim inputObject, outputObject As [[CAObject/zh|CAObject]]&lt;br /&gt;
::Dim resultTable As [[CATable/zh|CATable]]&lt;br /&gt;
::Dim definitionAttrInput As String &lt;br /&gt;
::inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
::outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier) &lt;br /&gt;
::definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;definition&amp;quot;) &lt;br /&gt;
::resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]]&lt;br /&gt;
::Call PrintResultTable(resultTable, inputIdentifier, definitionAttrInput, outputIdentifier) &lt;br /&gt;
::ReleaseComObject(resultTable) &lt;br /&gt;
::ReleaseComObject(inputObject) &lt;br /&gt;
::ReleaseComObject(outputObject) &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''PrintAttributes'''和作为'''inputIdentifier'''参数的&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;变量标识符以及作为'''outputIdentifier'''参数的'''Cost'''变量一起使用。如下所示通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::GetObjectByName/zh|GetObjectByName]]函数提取相应对象：&amp;lt;tt&amp;gt;&lt;br /&gt;
:inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取成功，将返回一个[[CAObject/zh|CAObject]]类型对象。如果使用'''[[CAObject/zh|CAObject]]'''的函数，参考[[CAObject/zh|SendCommand(command)]]，可以获得一个[[CAObject/zh|CAObject]]的完整函数列表。如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取失败，返回值为&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;。代码应该检查以确保[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取的结果是有效的。如果找不到，可使用[[CAEngine/zh|CAEngine]]的 [[CAEngine::ErrorCode/zh|ErrorCode]]和 [[CAEngine::ErrorText/zh|ErrorText]]属性获取错误信息。例如：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Set inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:If inputObject Is Nothing Then &lt;br /&gt;
::MsgBox(“This error from GetObjectByName occurred: “&amp;amp; _ vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &amp;amp; “:” &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) &lt;br /&gt;
:Else &lt;br /&gt;
::'inputObject valid &lt;br /&gt;
:End If&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===获取对象属性===&lt;br /&gt;
每一个Analytica对象都有一组属性，例如[[identifier|标识符]]、[[title|名称]]、[[description| 描述]]和[[class|类型]]。你可以使用[[CAObject::GetAttribute/zh|GetAttribute]]函数来获去Analytica对象的属性。例如，如要获取'''inputObject'''的定义（当前为cost）：&amp;lt;tt&amp;gt;&lt;br /&gt;
:definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh|GetAttribute]](&amp;quot;[[Definition|定义]]&amp;quot;) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt; 中，&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;的定义为&amp;quot;&amp;lt;tt&amp;gt;[[Normal]](30M, 3M)&amp;lt;/tt&amp;gt;&amp;quot; ，我们将它储存在'''definitionAttrInput'''当中。.&lt;br /&gt;
&lt;br /&gt;
===计算对象和检索结果===&lt;br /&gt;
使用[[CAObject/zh|CAObject]]的[[CAObject::Result/zh|Result]]或[[CAObject::ResultTable/zh|ResultTable]]方法来获取变量的值。如果有必要的话，ADE先自动计算变量。如果你确定结果为基元（只有一个元素），使用[[CAObject::Result/zh|Result]]方法。否则使用[[CAObject::ResultTable/zh|ResultTable]]，检索结果为一个''数组''。基元结果当作一个特殊数组案例来处理，没有维度的数组。如果值为基元[[CATable::AtomicValue/zh|AtomicValue]]方法将返回一个数字或者字符串单一值。 &lt;br /&gt;
&lt;br /&gt;
默认情况下，[[CAObject::Result/zh|Result]]和[[CAObject::ResultTable/zh|ResultTable]]返回结果的中值，也就是说，ADE以确定性方式计算结果。对于一个概率值，将[[CAObject/zh|CAObject]]的[[CAObject::ResultType/zh|ResultType]]属性设置为想要的不确定性视图——Mean（平均值） Sample（样本）、PDF（概率密度函数）、CDF（累计分布函数）、Confidence bands（置信带）、或者Statistics（统计数据）详情请参考[[CAObject::ResultType/zh|ResultType]]。我们通过如下的方式获取outputObject 输出对象 的值：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]] &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
结果为一个[[CATable/zh|CATable]]对象，允许我们访问一个表格中的单个元素。 &lt;br /&gt;
&lt;br /&gt;
如果你通过调用[[CAObject::Result/zh|Result]]来获取一个数组（或者表格）的值，将返回数组为一个字符串，列出索引和元素，以逗号隔开。通常使用[[CAObject::ResultTable/zh|ResultTable]]更加简单，这样你没有必要从字符串中解析表格的元素。&lt;br /&gt;
&lt;br /&gt;
===获取表格索引元素===&lt;br /&gt;
一个Analytica表格包含0个或者多个索引。如果包含一个索引，那么该表格是1维表格；如果有2个索引，说他是2维表格，依此类推。0维度表格包含一个“单一基元”（或标量）值。你可以使用CATable的[[CATable::NumDims/zh|NumDims]]获取表格的维数（也就是索引数）。要想获取表格的单个索引，可使用[[CATable/zh|CATable]]的 [[CATable::IndexNames/zh|IndexNames]]和 [[CATable::GetIndexObject/zh|GetIndexObject]]函数。 &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''PrintResultTable'''函数说明了这两个函数的使用。从'''PrintAttributes'''中调用'''PrintResultTable'''，执行打印'''TestTxc'''中的表格的实际工作（为了简洁起见，我们只给出了关联ADE的该函数部分）。&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Public Sub PrintResultTable(ByRef resultTable As CATable, ByRef inputIdentifier As String, ByRef definitionAttrInput As String, ByRef outputIdentifier As String) &lt;br /&gt;
::Dim theIndexName, theTableName As String &lt;br /&gt;
::Dim theIndexElement As String &lt;br /&gt;
::Dim theTableElement &lt;br /&gt;
::Dim theIndexObj As [[CAIndex/zh|CAIndex]]&lt;br /&gt;
::Dim numEls As Integer &lt;br /&gt;
::Dim spaces, i As Integer &lt;br /&gt;
::Dim lenStr As Short &lt;br /&gt;
::Dim OutputStr As Short &lt;br /&gt;
::Dim spaceString, underlineString As String &lt;br /&gt;
::... &lt;br /&gt;
::theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1) &lt;br /&gt;
::theTableName = resultTable.[[CATable::Name/zh|Name]] &lt;br /&gt;
::theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName) &lt;br /&gt;
::numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
::... &lt;br /&gt;
::For i = 1 To numEls &lt;br /&gt;
:::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
:::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
:::... &lt;br /&gt;
::Next i &lt;br /&gt;
::InformationPane.Text = outputString &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
通过'''PrintResultTable'''获取一个表格的索引方法如下：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1)&lt;br /&gt;
:theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
我们通过使用[[CATable/zh|CATable]]的[[CATable::IndexNames/zh|IndexNames]]函数获取第一个索引的名字。我们将它传递给[[CATable/zh|CATable]]的[[CATable::GetIndexObject/zh|GetIndexObject]]函数以获取表示我们的索引的[[CAIndex/zh|CAIndex]]。该自动化对象返回其相应索引的相关信息。如果此函数调用失败，将返回&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;信息。在此情况下，使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]] 函数找出原因。&lt;br /&gt;
&lt;br /&gt;
==从CATable和CAIndex中获取信息==&lt;br /&gt;
[[PrintResultTable]]说明了如何从[[CATable/zh| CATable]]和[[CAIndex/zh|CAIndex]] 对象获取信息。该代码获取'''Cost'''表格的索引和表格元素：&lt;br /&gt;
: &amp;lt;tt&amp;gt;&lt;br /&gt;
:numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
:For i = 1 To numEls &lt;br /&gt;
::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
::... &lt;br /&gt;
:Next i &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[CAIndex/zh|CAIndex]]的[[CAIndex::IndexElements/zh|IndexElements]]属性返回第一个索引中的元素个数。[[CAIndex/zh|CAIndex]]的[[CAIndex::GetValueByNumber/zh|GetValueByNumber]]函数获取单个索引元素。 &lt;br /&gt;
&lt;br /&gt;
我们通过传递表格中元素的坐标，使用  [[CATable/zh|CATable]]的[[CATable::GetDataByElements/zh|GetDataByElements]]函数获取'''Cost'''表格对象的单个表格元素'''resultTable'''。 &lt;br /&gt;
&lt;br /&gt;
当我检索 [[CATable/zh|CATable]]对象中单个元素（'''resultTable'''）的时候，我们利用了该表格是一维的事实。因此，我们只需要传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个单一数（这个数代表表格中的位置）。但是，如果我们处理两个或者更多维度，我们必须传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个数组函数，并且指明我们要检索的表格元素的位置。因此，如果我们不想检索一个二维数组的position (4,3)位置的元素，我们可以这样写：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Dim W as Variant 'return element &lt;br /&gt;
:Dim IndexPtrs(1 To 2) As Variant 'position in table &lt;br /&gt;
::... &lt;br /&gt;
:IndexPtrs(1) = 4 &lt;br /&gt;
:IndexPtrs(2) = 3 &lt;br /&gt;
:W = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](IndexPtrs) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==控制基元值格式==&lt;br /&gt;
[[CATable/zh|CATable]]中的每个基元值可以是一个数、一个字符串，或者其它一些基本类型（''例如''：[[Null|空值]]、[[Undefined|未定义]]、[[Reference|参考]]，或 [[Handle|句柄]]。通过说明类型和值，它们作为''变体''被返回，这是一种Visual Basic能读懂的数据结构。[[CATable/zh|CATable]]的[[CATable::RenderingStyle|RenderingStyle]]属性控制Analytica基础值是如何映射到Visual Basic变体的。 &lt;br /&gt;
&lt;br /&gt;
例如：可以通过使用Analytica 模型的数字格式设置将一个数值返回成一个数字或者字符串。如果被指定格式，有一个选线控制是截断数字的位数，还是精确返回。 &lt;br /&gt;
&lt;br /&gt;
子程序[[PrintResultTable/zh|PrintResultTable]]在&amp;lt;tt&amp;gt;frmMain.vb&amp;lt;/tt&amp;gt;中载入,其渲染风格直接指明：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::NumberAsText/zh|NumberAsText]] = True &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::FullPrecision/zh|FullPrecision]] = False &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::StringQuotes/zh|StringQuotes]] = 2 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
第一行指明数值应该根据与结果对象有关的数字格式被格式化为文本。例如在其程序输出中，我们将看到&amp;lt;tt&amp;gt;30.103M&amp;lt;/tt&amp;gt;，而非&amp;lt;tt&amp;gt;30102995.6639812&amp;lt;/tt&amp;gt;，如果我们让Visual Basic将数值串联我们的结果字符串，将显示该结果。在此事件中，一个值为字符串的单元格出现在结果中，返回值将明确带双引号。对于[[CARenderingStyle/zh|CARenderingStyle]]对象中的所有可用属性，请参考[[CARenderingStyle/zh|CARenderingStyle]]。&lt;br /&gt;
&lt;br /&gt;
===其它访问表格的方式===&lt;br /&gt;
有几种访问多维表格[[CATable/zh|CATable]]中元素的方式。每一种都有可能在特定的场合使用起来比较方便。 &lt;br /&gt;
&lt;br /&gt;
第一种方式就是使用[[CATable/zh | CATable]]的 [[CATable::GetDataByElements/zh|GetDataByElements]]或[[CATable::GetDataByLabels/zh|GetDataByLabels]]方法，上面代码示例中有显示。在此情况下，利用你想获取的基元值的单元格位置。 &lt;br /&gt;
&lt;br /&gt;
第二种方式就是使用[[CATable/zh|CATable]][[CATable::Slice/zh|Slice]]或[[CATable::Subscript/zh | Subscript]]方法获取一个少一个维度的新[[CATable/zh|CATable]]对象。通过重复减少维度，最终将获得0维度，这时你将获得一个单一基元值。此时，[[CATable/zh|CATable]]的[[CATable::AtomicValue/zh|AtomicValue]]方法返回该值 。[[CATable::AtomicValue/zh|AtomicValue]]方法是唯一获取一个标值的方法（因为没有坐标位置）。如果你需要建立完整结果其中一个切片的图形图像，必须使用此方法。 &lt;br /&gt;
&lt;br /&gt;
第三种方式就是使用[[CATable/zh|CATable]]的[[CATable::GetSafeArray/zh|GetSafeArray]]方法，将多维数组转化成一个''安全数组''（或者一个.NET数组）。你可以在使用VB或者其它.NET语言直接处理多维数组。因为对于Analytica维度没有固定顺序，但是安全数组和.NET数组有一个明确的顺序，你必须先使用[[CATable/zh|CATable]]对象的[[CATable::SetIndexOrder/zh|SetIndexOrder]]方法在调用[[CATable::GetSafeArray/zh|GetSafeArray]]之前指明维度的顺序。注意如果你知道你的数组是一维的，那就没必要了。&lt;br /&gt;
&lt;br /&gt;
===修改对象===&lt;br /&gt;
一个自定义用户程序通常从一个用户或者其它外部源获取输入，以便转化成Analytica模型中的输入变量。你可以设定输入变量的定义或者通过使用定义表格来这样做。 &lt;br /&gt;
&lt;br /&gt;
'''TestTxc''' 说明了如何修改'''Pop_exp'''定义，此模型是一个影响结果变量Cost的模型输入。要想在该示例中设定该定义，从主菜单上选择'''File &amp;gt; Change Population'''。将出现一个对话框，如下图所示：&lt;br /&gt;
&lt;br /&gt;
[[File:RedefiningtheVariableDefinition.jpg|400px/zh|文件：RedefiningtheVariableDefinition.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
在信息栏中输入一个新定义并点击'''Ok'''确认。主窗口将显示一个新的Cost值。当点击该对话框中的'''Ok'''按钮时，调用了&amp;lt;tt&amp;gt;ChangeDef.frm&amp;lt;/tt&amp;gt;函数，然后调用[[PrintAttributes/zh|PrintAttributes]]函数打印&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果。&lt;br /&gt;
&lt;br /&gt;
此函数类似于：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Private Sub OkButton_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles OkButton.Click &lt;br /&gt;
::Dim errorText As String&lt;br /&gt;
::Dim pop_exp_Object As [[CAObject/zh|CAObject]] &lt;br /&gt;
::Dim errorCode As Short &lt;br /&gt;
::Dim errorString As String &lt;br /&gt;
::newDefinition = PopExposedDef.Text &lt;br /&gt;
::pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
::pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]](&amp;quot;[[Definition]]&amp;quot;, newDefinition) &lt;br /&gt;
::errorCode = adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &lt;br /&gt;
::If errorCode &amp;lt;&amp;gt; 0 Then &lt;br /&gt;
:::MsgBox(&amp;quot;This error occurred while processing your definition: &amp;quot; &amp;amp; vbCrLf &amp;amp; vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) :::PopExposedDef.Focus()&lt;br /&gt;
::Else&lt;br /&gt;
:::Me.Close() &lt;br /&gt;
:::frmMain.DefInstance.PrintAttributes(&amp;quot;Pop_exp&amp;quot;, &amp;quot;Cost&amp;quot;) &lt;br /&gt;
::End If &lt;br /&gt;
::ReleaseComObject(pop_exp_Object) &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
该函数抓取了输入到'''New Definition''' 新定义给'''Population Exposed'''栏，并通过使用[[CAObject/zh|CAObject]]对象中的[[CAObject::SetAttribute/zh|SetAttribute]]函数将它设置给&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;对象。然后调用[[PrintAttributes/zh|PrintAttributes]]，以计算&amp;lt;tt&amp;gt;Cost object&amp;lt;/tt&amp;gt;，并打印新的结果。要想给变量&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;设定一个新定义，我们可以为&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;获取[[CAObject/zh|CAObject]]对象，然后将其定义设置成用户输入的定义。通过使用下面的代码来实现：&lt;br /&gt;
:pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
:pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]]( &amp;quot;[[Definition]]&amp;quot;, newDefinition )&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
无论什么时候调用[[CAObject::SetAttribute/zh|SetAttribute]]，都应该检查[[CAEngine/zh|CAEngine]]自动化对象（'''adeEngine'''）的[[CAEngine::ErrorCode/zh|ErrorCode]]，以免它的定义是非法的。尝试一下输入一个新定义，比如&amp;lt;code&amp;gt;[[Uniform]](25M,35M)&amp;lt;/code&amp;gt;，然后点击'''Ok'''。当&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;的定义被改变时， &amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果由ADE重新计算，此时'''ResultTable'''接下来调用给Cost变量（在应用程序窗口重新显示时）。&lt;br /&gt;
&lt;br /&gt;
使用ADE绘图&lt;br /&gt;
&lt;br /&gt;
通过Analytica 4.6使用相同的绘图引擎，你可以建立一个图表或者图形以显示一个数组值或者不确定值结果。在ADE4.6中，你可以使用 [[CATable/zh|CATable]]的[[CATable::GraphToFile/zh|GraphToFile]]和[[CATable::GraphToStream/zh|GraphToStream]]方法。图形可以以几种可能的图像格式返回，例如'''image/png'''、 '''image/bmp'''或者 '''image/jpeg'''。 &lt;br /&gt;
&lt;br /&gt;
从可用图形选项中选择的最简单方式就是使用Analytica打开你的模型。你可以实验设置各种默认设置或者替代选择的变量，看它们是如何工作的。但你选择了你想设置的选项，保存模型。当为每一个生成结果图形时，ADE将使用这些设置。 &lt;br /&gt;
&lt;br /&gt;
对于更高维度的结果，可能需要做一些必要工作，以便选择将绘制结果的切片和具体的轴（也就是相对于图例哪个维度作为X轴）。[[CATable/zh|CATable]]的[[CATable::Subscript/zh|Subscript]]或[[CATable::Slice/zh|Slice]]方法可以用来控制轴选择特殊的切片用来绘制，能够用来控制轴。详情请参考[[CATable/zh|CATable]]。在我们的&amp;lt;tt&amp;gt;Tutorial.NET&amp;lt;/tt&amp;gt;示例中，我们有一个一维结果（&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;），因此我们没有必要担心截取或者绕轴旋转。 &lt;br /&gt;
&lt;br /&gt;
[[CATable::GraphToStream/zh|GraphToStream]]方法被用来从ADE中直接转化图形图形到一个用户界面中。使用[[CATable::GraphToStream/zh|GraphToStream]]比起使用[[CATable::GraphToFile/zh|GraphToFile]]来要稍微复杂一点，因为[[CATable::GraphToFile/zh|GraphToFile]]除了需要文件名以外还需要其它一些信息，以便编写图形。要使用[[CATable::GraphToStream/zh|GraphToStream]]，我们必须在内存内设置一个流，允许ADE写入该留，然后从该留重建。因为.NET流和COM流不兼容，你必须使用ADE一同提供的[[StreamConnector]]类型.&amp;lt;tt&amp;gt;frmMain&amp;lt;/tt&amp;gt; 中的'''GraphResult_Click'''子程序演示了[[CATable::GraphToStream/zh|GraphToStream]]的使用。从主应用程序窗口选择 '''Graph Result'''菜单选项，结果将出现在一个如下所示的图形当中：&lt;br /&gt;
&lt;br /&gt;
[[File:resultgraph.jpg/zh|文件：resultgraph.jpg]]&lt;br /&gt;
&lt;br /&gt;
==结论==&lt;br /&gt;
&lt;br /&gt;
在此教程中，我们介绍了Analytica决策引擎的几个重要方面。我们看到了如何建立一个ADE服务器对象，使用ADE打开模型，获取模型中的单个对象、计算对象、获取表格中的元素，以及修改模型中的对象。但是ADE可以做的远不止这些。 &lt;br /&gt;
&lt;br /&gt;
我们希望你已经足够了解其基本特征，这样你现在才能独自开始探索更多新的高级特征。我们建议你现在开始阅读字教程的剩余部分以了解ADE能做什么。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
| [[Installation of ADE/zh|ADE 安装]] &amp;lt;- ||  [[The ADE Tutorial/zh|ADE 入门教程]] || -&amp;gt; [[Using the ADE Server/zh|使用ADE服务器]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36310</id>
		<title>The ADE Tutorial/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36310"/>
		<updated>2015-10-27T06:36:15Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南 ]]&lt;br /&gt;
&lt;br /&gt;
此教程教你如何在一个Visual Basic程序中使用Analytica决策引擎（ADE）。&lt;br /&gt;
&lt;br /&gt;
==你的第一个ADE应用程序==&lt;br /&gt;
首先先从头开始写一个简单的ADE程序，只要确认一切设置正常。按照以下步骤操作：&lt;br /&gt;
&lt;br /&gt;
test&lt;br /&gt;
&lt;br /&gt;
第一个程序执行了以下操作：&lt;br /&gt;
*建立一个名称为ADE的[[CAEngine/zh|CAEngine]]自动化对象（通过使用&amp;lt;code&amp;gt;new [[CAEngine/zh|CAEngine]]&amp;lt;/code&amp;gt;).&lt;br /&gt;
*打开Analytica模型 (通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]] 方法。&lt;br /&gt;
*显示模型名称返回[[CAEngine::OpenModel/zh|OpenModel]]的值。&lt;br /&gt;
我们将在后面的章节详细了解这些信息。&lt;br /&gt;
&lt;br /&gt;
===接下来讲什么呢?===&lt;br /&gt;
我们不会尝试在此入门教程中解释ADE的特征。本指南后面几个章节会描述这些特征。 &lt;br /&gt;
&lt;br /&gt;
从现在开始，我们我们将使用名称为&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;的示例模型。打开 Analytica安装目录下 '''Example Models'''文件夹里面的'''Risk Analysis'''文件夹便可找到&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;文件。如果你找不到，或者你安装Analytica的时候未选择安装examples（示例）文件，在ADE安装目录下面的'''Examples\Tutorial.NET'''文件家中有一个副本。 &lt;br /&gt;
&lt;br /&gt;
Txc模型演示了减少污染物TXC排放的risk-benefit （风险-效益）分析。请用Analytica打开Txc查看它是如何工作的。 &lt;br /&gt;
&lt;br /&gt;
ADE '''Examples\Tutorial.NET''' 文件夹中名称为&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;的Visual Basic.NET程序示例显示了ADE很多方面。该程序建立了一个ADE自动化对象，打开包含该对象的&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，获取变量 &amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，计算变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;，通过获取每个表格的单独组件以表格的方式打印输出变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的结果，然后改变变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义。再次获取变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的值，看一下 变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;定义的改变对变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;有什么影响。如果设置正确的话,&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;将显示在“Text Txc window”中显示的窗口。 &lt;br /&gt;
&lt;br /&gt;
应用程序显示变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义（&amp;lt;tt&amp;gt;&amp;quot;Normal (30M, 3M)&amp;quot;&amp;lt;/tt&amp;gt;），以及与&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;关联的表格，这都基于&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义。你可以通过从主菜单选择'''File &amp;gt; Change Population Exposed'''改变&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，然后查看改变对&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;表格的影响。&lt;br /&gt;
&lt;br /&gt;
[[File:TextTxcWindow.png|400px/zh | 文件：TextTxcWindow.png|400px]]&lt;br /&gt;
&lt;br /&gt;
===区分title（名称） 和 identifier（标识符）===&lt;br /&gt;
无论什么时候，一个ADE函数都需要一个变量你必须传达变量的'''''[[Identifier|标识符]]''''' ，而不是它的'''''[[Title|名称]]'''''。这可能会引起混淆，因为在Analytica影响图中一般显示每一个变量的名称。默认情况下，在你最初建立每一个对象的时候，Analytica自动根据名称建立一个标识符。用（_）代替名称中的每一个空格或者其他非字母和数字字符。 &lt;br /&gt;
&lt;br /&gt;
你可以通过点击“Control+y”（或者从Object（对象）菜单选择'''Show by identifier''' ：显示标识符） 来以标识符显示变量。对于模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;，你可以看到名称为&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;变量的标识符为 &amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;。将变量传递给ADE函数时，使用标识符很重要。如果你传递&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;，ADE无法找到变量，并且将返回一个错误。&lt;br /&gt;
&lt;br /&gt;
===从Visual Basic中建立一个ADE 对象===&lt;br /&gt;
&lt;br /&gt;
如果你还没准备好，将名称为tt&amp;gt;Examples\Tutorial\TestTxc.sln&amp;lt;/tt&amp;gt;载入到Visual Basic.NET中，查看名称为&amp;lt;tt&amp;gt;TestTxc.vb&amp;lt;/tt&amp;gt;的文件的代码。其代码看起来像：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Imports ADEW &lt;br /&gt;
:. . . &lt;br /&gt;
:Public adeEngine As [[CAEngine/zh|CAEngine]]&lt;br /&gt;
&lt;br /&gt;
:Public Sub Main() &lt;br /&gt;
::Dim exeDirectory, theModel As String &lt;br /&gt;
::Dim theModelString As String &lt;br /&gt;
::exeDirectory = VB6.GetPath &lt;br /&gt;
::theModel = exeDirectory &amp;amp; &amp;quot;\..\&amp;quot; &amp;amp; &amp;quot;Txc.ana&amp;quot; &lt;br /&gt;
::adeEngine = New [[CAEngine/zh|CAEngine]]&lt;br /&gt;
::... &lt;br /&gt;
::theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
::... &lt;br /&gt;
::frmMain.DefInstance.Show() &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在每一个文件的顶部的代码将自动化对象 '''adeEngine''' 声明为一个[[CAEngine/zh|CAEngine]] 对象。使用此对象，我们能够访问[[CAEngine/zh|CAEngine]] 展示的所有公共函数（参考 [[ADE Server Class Reference/zh|ADE服务器类型参考]] ）&lt;br /&gt;
&lt;br /&gt;
变量&amp;lt;tt&amp;gt;adeEngine&amp;lt;/tt&amp;gt;包含我们的进程内对象[[CAEngine/zh|CAEngine]]。如果我们想使用ADE的本地（进程外）服务器版本，我们可以将一个项目参考添加到'''Analytica Decision Engine Server 4.6 COM''' 组件并将顶部行从&amp;lt;tt&amp;gt;Imports ADEW&amp;lt;/tt&amp;gt;改成&amp;lt;tt&amp;gt;Imports ADE&amp;lt;/tt&amp;gt;即可。 &lt;br /&gt;
&lt;br /&gt;
这里是另一种获得一个先[[CAEngine/zh|CAEngine]]对象的方法。此循序不需要给项目添加参考。&amp;lt;tt&amp;gt;&lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADEW4.6.CAEngine&amp;quot;) ’ in-process &lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADE4.6.CAEngine&amp;quot;) ’ out-of-process &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果想理解使用进程内和进程外（或本地）服务器的利与弊，以及哪一种自动化服务器用于不同的场景，参考[[Using_the_Analytica_Decision_Engine_Server#In-process_vs_Out-of-process/zh | In-process vs. out-of-process]]&lt;br /&gt;
&lt;br /&gt;
===COM和 Automation 接口比较===&lt;br /&gt;
在上面的例子当中，我们使用COM接口调用ADE。在一个COM 接口中，对象 在本例中为 [[CAEngine/zh|CAEngine]] 被声明为[[CAEngine/zh|CAEngine]] ，编译器解决每一个成员函数，并且在编译时间内能探测几个明显的错误。另外，Visual Studio可以提供方法和参数类型列表当，在你编程的时候可以当做一个提示工具，在编写使用ADE程序是非常有用。COM调用比Automation调用要快一点，但是在ADE应用程序中速度差异通常不是很重要。对于ADE 4.6我们推荐使用COM结构，只要你的语言支持。&lt;br /&gt;
&lt;br /&gt;
在VB Automation中，你可以将一个对象简单声明为Object（对象），而不是像 [[CAEngine/zh|CAEngine]]、[[CAObject/zh|CAObject]]等更加具体的类型。当使用Automation调用'''ADE'''方法时，在运行时间内确定方法。在编译时间内，编译器不知道你的 '''ADE''' 对象是否有一个名称为[[CAEngine::OpenModel/zh|OpenModel]]的函数。在VB中，调用COM方法或Automation 方法的语法是相通的——唯一的不同在于对象类型是否明确被声明。&lt;br /&gt;
&lt;br /&gt;
在VC++和C#中，调用COM的语法和调用Automatio的语法不同。在这些情况下，COM要方便的多，Automation能够获得相冗余。然而，同样的语言，包括VBScript和其他脚本语言，只支持Automation不支持COM。&lt;br /&gt;
&lt;br /&gt;
===监视Process（进程）===&lt;br /&gt;
当使用进程外ADE服务器时，你的代码必须在终止时释放[[CAEngine/zh|CAEngine]]COM对象。当最终[[CAEngine/zh|CAEngine]]使用被释放是，ADE.exe 进程自动终止。到目前为止所看到的代码，VB语言在达到程序末端时，自动处理释放对象。但是，当你调试你的代码是，你可以提前终止你的程序来修复bug，你的程序可能被Task Manager（任务管理器）终止，或者你自己的代码也可能奔溃，导致你的程序进程在它有机会释放对象之前终止。应为COM对象从来不会被释放，ADE.exe进程不知道它是否在使用中，你可能获得ADE.exe 僵尸进程。 &lt;br /&gt;
&lt;br /&gt;
为了避免这种情况发生，一种好的习惯就是在调用[[CAEngine/zh|CAEngine]]实例后 立即调用[[CAEngine::MonitorProcess/zh|CAEngine::MonitorProcess]]。通过这种方式，ADE能够得知哪一个进程正在使用它，同时将设置一个线程去探测你的进程是否在ADE被完全释放前终止。如果你的程序进程没有终止，ADE进程会立即将它关闭，消除了僵尸ADE进程的堆积。 &lt;br /&gt;
&lt;br /&gt;
要从一个.NET应用程序获得进程ID，使用System.Diagnostics.Process namespace中的'''GetCurrentProcess().Id''' 。在其他语言中，你可以使用Windows SDK 的'''GetProcessId( )'''函数。 &lt;br /&gt;
&lt;br /&gt;
'''[[CAEngine::MonitorProcess/zh|MonitorProcess]]()''' 只能用来监视运行ADE进程的同一台计算机的进程，一次当通过DCOM运行ADE时不能使用。当使用进程内ADEW服务器时没有必要使用。&lt;br /&gt;
&lt;br /&gt;
==使用ADE打开模型==&lt;br /&gt;
我们现在打开&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，显示我们的应用程序主窗口。使用以下调用：tt&amp;gt;&lt;br /&gt;
:theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
:frmMain.DefInstance.Show &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]]函数打开模型。如果成功的话，变量&amp;lt;tt&amp;gt;theModelString&amp;lt;/tt&amp;gt;将包含模型的名字。否则，将包含一个空的串。虽然由于为了简介的缘故，我们没有这样做，但是你应该检查从[[CAEngine::OpenModel/zh|OpenModel]]函数返回的是不是一个空的串。如果是，说明在你打开的模型中存在一个错误。你可以使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]]属性找出是哪种错误 （&amp;lt;tt&amp;gt;adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] 和adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]&amp;lt;/tt&amp;gt;）。&lt;br /&gt;
&lt;br /&gt;
==从Analytica模型中检索对象==&lt;br /&gt;
下一步就是从我们的模型中检索对象（变量、模块、函数等），以便我们能获取他们的属性（[[definition|定义]]、[[title|名称]]、[[class|类型]]等等 ）。我们的示例模型（&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;）操作&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;和&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;对象。尤其是，修改&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;可以查看这是如何影响&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt; 对象。&lt;br /&gt;
&lt;br /&gt;
我们的&amp;lt;tt&amp;gt;TxcTest.vbproj&amp;lt;/tt&amp;gt; （&amp;lt;tt&amp;gt;TxcText.sln&amp;lt;/tt&amp;gt;）项目中的&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;文件里的 '''PrintAttributes''' 函数演示了如何检索对象。该函数首先被&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''Form_Load''' 函数调用，当应用程序启动后，可以显示'''Cost'''表格。当然无论什么时候，只要我们想输出'''Cost'''表格的当前值，都可以调用。该函数如下所示：&lt;br /&gt;
:Public Sub PrintAttributes(ByRef inputIdentifier As String, ByRef  outputIdentifier As String) &lt;br /&gt;
::Dim inputObject, outputObject As [[CAObject/zh|CAObject]]&lt;br /&gt;
::Dim resultTable As [[CATable/zh|CATable]]&lt;br /&gt;
::Dim definitionAttrInput As String &lt;br /&gt;
::inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
::outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier) &lt;br /&gt;
::definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;definition&amp;quot;) &lt;br /&gt;
::resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]]&lt;br /&gt;
::Call PrintResultTable(resultTable, inputIdentifier, definitionAttrInput, outputIdentifier) &lt;br /&gt;
::ReleaseComObject(resultTable) &lt;br /&gt;
::ReleaseComObject(inputObject) &lt;br /&gt;
::ReleaseComObject(outputObject) &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''PrintAttributes'''和作为'''inputIdentifier'''参数的&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;变量标识符以及作为'''outputIdentifier'''参数的'''Cost'''变量一起使用。如下所示通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::GetObjectByName/zh|GetObjectByName]]函数提取相应对象：&amp;lt;tt&amp;gt;&lt;br /&gt;
:inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取成功，将返回一个[[CAObject/zh|CAObject]]类型对象。如果使用'''[[CAObject/zh|CAObject]]'''的函数，参考[[CAObject/zh|SendCommand(command)]]，可以获得一个[[CAObject/zh|CAObject]]的完整函数列表。如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取失败，返回值为&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;。代码应该检查以确保[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取的结果是有效的。如果找不到，可使用[[CAEngine/zh|CAEngine]]的 [[CAEngine::ErrorCode/zh|ErrorCode]]和 [[CAEngine::ErrorText/zh|ErrorText]]属性获取错误信息。例如：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Set inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:If inputObject Is Nothing Then &lt;br /&gt;
::MsgBox(“This error from GetObjectByName occurred: “&amp;amp; _ vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &amp;amp; “:” &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) &lt;br /&gt;
:Else &lt;br /&gt;
::'inputObject valid &lt;br /&gt;
:End If&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===获取对象属性===&lt;br /&gt;
每一个Analytica对象都有一组属性，例如[[identifier|标识符]]、[[title|名称]]、[[description| 描述]]和[[class|类型]]。你可以使用[[CAObject::GetAttribute/zh|GetAttribute]]函数来获去Analytica对象的属性。例如，如要获取'''inputObject'''的定义（当前为cost）：&amp;lt;tt&amp;gt;&lt;br /&gt;
:definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh|GetAttribute]](&amp;quot;[[Definition|定义]]&amp;quot;) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt; 中，&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;的定义为&amp;quot;&amp;lt;tt&amp;gt;[[Normal]](30M, 3M)&amp;lt;/tt&amp;gt;&amp;quot; ，我们将它储存在'''definitionAttrInput'''当中。.&lt;br /&gt;
&lt;br /&gt;
===计算对象和检索结果===&lt;br /&gt;
使用[[CAObject/zh|CAObject]]的[[CAObject::Result/zh|Result]]或[[CAObject::ResultTable/zh|ResultTable]]方法来获取变量的值。如果有必要的话，ADE先自动计算变量。如果你确定结果为基元（只有一个元素），使用[[CAObject::Result/zh|Result]]方法。否则使用[[CAObject::ResultTable/zh|ResultTable]]，检索结果为一个''数组''。基元结果当作一个特殊数组案例来处理，没有维度的数组。如果值为基元[[CATable::AtomicValue/zh|AtomicValue]]方法将返回一个数字或者字符串单一值。 &lt;br /&gt;
&lt;br /&gt;
默认情况下，[[CAObject::Result/zh|Result]]和[[CAObject::ResultTable/zh|ResultTable]]返回结果的中值，也就是说，ADE以确定性方式计算结果。对于一个概率值，将[[CAObject/zh|CAObject]]的[[CAObject::ResultType/zh|ResultType]]属性设置为想要的不确定性视图——Mean（平均值） Sample（样本）、PDF（概率密度函数）、CDF（累计分布函数）、Confidence bands（置信带）、或者Statistics（统计数据）详情请参考[[CAObject::ResultType/zh|ResultType]]。我们通过如下的方式获取outputObject 输出对象 的值：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]] &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
结果为一个[[CATable/zh|CATable]]对象，允许我们访问一个表格中的单个元素。 &lt;br /&gt;
&lt;br /&gt;
如果你通过调用[[CAObject::Result/zh|Result]]来获取一个数组（或者表格）的值，将返回数组为一个字符串，列出索引和元素，以逗号隔开。通常使用[[CAObject::ResultTable/zh|ResultTable]]更加简单，这样你没有必要从字符串中解析表格的元素。&lt;br /&gt;
&lt;br /&gt;
===获取表格索引元素===&lt;br /&gt;
一个Analytica表格包含0个或者多个索引。如果包含一个索引，那么该表格是1维表格；如果有2个索引，说他是2维表格，依此类推。0维度表格包含一个“单一基元”（或标量）值。你可以使用CATable的[[CATable::NumDims/zh|NumDims]]获取表格的维数（也就是索引数）。要想获取表格的单个索引，可使用[[CATable/zh|CATable]]的 [[CATable::IndexNames/zh|IndexNames]]和 [[CATable::GetIndexObject/zh|GetIndexObject]]函数。 &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''PrintResultTable'''函数说明了这两个函数的使用。从'''PrintAttributes'''中调用'''PrintResultTable'''，执行打印'''TestTxc'''中的表格的实际工作（为了简洁起见，我们只给出了关联ADE的该函数部分）。&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Public Sub PrintResultTable(ByRef resultTable As CATable, ByRef inputIdentifier As String, ByRef definitionAttrInput As String, ByRef outputIdentifier As String) &lt;br /&gt;
::Dim theIndexName, theTableName As String &lt;br /&gt;
::Dim theIndexElement As String &lt;br /&gt;
::Dim theTableElement &lt;br /&gt;
::Dim theIndexObj As [[CAIndex/zh|CAIndex]]&lt;br /&gt;
::Dim numEls As Integer &lt;br /&gt;
::Dim spaces, i As Integer &lt;br /&gt;
::Dim lenStr As Short &lt;br /&gt;
::Dim OutputStr As Short &lt;br /&gt;
::Dim spaceString, underlineString As String &lt;br /&gt;
::... &lt;br /&gt;
::theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1) &lt;br /&gt;
::theTableName = resultTable.[[CATable::Name/zh|Name]] &lt;br /&gt;
::theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName) &lt;br /&gt;
::numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
::... &lt;br /&gt;
::For i = 1 To numEls &lt;br /&gt;
:::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
:::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
:::... &lt;br /&gt;
::Next i &lt;br /&gt;
::InformationPane.Text = outputString &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
通过'''PrintResultTable'''获取一个表格的索引方法如下：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1)&lt;br /&gt;
:theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
我们通过使用[[CATable/zh|CATable]]的[[CATable::IndexNames/zh|IndexNames]]函数获取第一个索引的名字。我们将它传递给[[CATable/zh|CATable]]的[[CATable::GetIndexObject/zh|GetIndexObject]]函数以获取表示我们的索引的[[CAIndex/zh|CAIndex]]。该自动化对象返回其相应索引的相关信息。如果此函数调用失败，将返回&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;信息。在此情况下，使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]] 函数找出原因。&lt;br /&gt;
&lt;br /&gt;
==从CATable和CAIndex中获取信息==&lt;br /&gt;
[[PrintResultTable]]说明了如何从[[CATable/zh| CATable]]和[[CAIndex/zh|CAIndex]] 对象获取信息。该代码获取'''Cost'''表格的索引和表格元素：&lt;br /&gt;
: &amp;lt;tt&amp;gt;&lt;br /&gt;
:numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
:For i = 1 To numEls &lt;br /&gt;
::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
::... &lt;br /&gt;
:Next i &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[CAIndex/zh|CAIndex]]的[[CAIndex::IndexElements/zh|IndexElements]]属性返回第一个索引中的元素个数。[[CAIndex/zh|CAIndex]]的[[CAIndex::GetValueByNumber/zh|GetValueByNumber]]函数获取单个索引元素。 &lt;br /&gt;
&lt;br /&gt;
我们通过传递表格中元素的坐标，使用  [[CATable/zh|CATable]]的[[CATable::GetDataByElements/zh|GetDataByElements]]函数获取'''Cost'''表格对象的单个表格元素'''resultTable'''。 &lt;br /&gt;
&lt;br /&gt;
当我检索 [[CATable/zh|CATable]]对象中单个元素（'''resultTable'''）的时候，我们利用了该表格是一维的事实。因此，我们只需要传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个单一数（这个数代表表格中的位置）。但是，如果我们处理两个或者更多维度，我们必须传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个数组函数，并且指明我们要检索的表格元素的位置。因此，如果我们不想检索一个二维数组的position (4,3)位置的元素，我们可以这样写：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Dim W as Variant 'return element &lt;br /&gt;
:Dim IndexPtrs(1 To 2) As Variant 'position in table &lt;br /&gt;
::... &lt;br /&gt;
:IndexPtrs(1) = 4 &lt;br /&gt;
:IndexPtrs(2) = 3 &lt;br /&gt;
:W = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](IndexPtrs) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==控制基元值格式==&lt;br /&gt;
[[CATable/zh|CATable]]中的每个基元值可以是一个数、一个字符串，或者其它一些基本类型（''例如''：[[Null|空值]]、[[Undefined|未定义]]、[[Reference|参考]]，或 [[Handle|句柄]]。通过说明类型和值，它们作为''变体''被返回，这是一种Visual Basic能读懂的数据结构。[[CATable/zh|CATable]]的[[CATable::RenderingStyle|RenderingStyle]]属性控制Analytica基础值是如何映射到Visual Basic变体的。 &lt;br /&gt;
&lt;br /&gt;
例如：可以通过使用Analytica 模型的数字格式设置将一个数值返回成一个数字或者字符串。如果被指定格式，有一个选线控制是截断数字的位数，还是精确返回。 &lt;br /&gt;
&lt;br /&gt;
子程序[[PrintResultTable/zh|PrintResultTable]]在&amp;lt;tt&amp;gt;frmMain.vb&amp;lt;/tt&amp;gt;中载入,其渲染风格直接指明：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::NumberAsText/zh|NumberAsText]] = True &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::FullPrecision/zh|FullPrecision]] = False &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::StringQuotes/zh|StringQuotes]] = 2 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
第一行指明数值应该根据与结果对象有关的数字格式被格式化为文本。例如在其程序输出中，我们将看到&amp;lt;tt&amp;gt;30.103M&amp;lt;/tt&amp;gt;，而非&amp;lt;tt&amp;gt;30102995.6639812&amp;lt;/tt&amp;gt;，如果我们让Visual Basic将数值串联我们的结果字符串，将显示该结果。在此事件中，一个值为字符串的单元格出现在结果中，返回值将明确带双引号。对于[[CARenderingStyle/zh|CARenderingStyle]]对象中的所有可用属性，请参考[[CARenderingStyle/zh|CARenderingStyle]]。&lt;br /&gt;
&lt;br /&gt;
===其它访问表格的方式===&lt;br /&gt;
有几种访问多维表格[[CATable/zh|CATable]]中元素的方式。每一种都有可能在特定的场合使用起来比较方便。 &lt;br /&gt;
&lt;br /&gt;
第一种方式就是使用[[CATable/zh | CATable]]的 [[CATable::GetDataByElements/zh|GetDataByElements]]或[[CATable::GetDataByLabels/zh|GetDataByLabels]]方法，上面代码示例中有显示。在此情况下，利用你想获取的基元值的单元格位置。 &lt;br /&gt;
&lt;br /&gt;
第二种方式就是使用[[CATable/zh|CATable]][[CATable::Slice/zh|Slice]]或[[CATable::Subscript/zh | Subscript]]方法获取一个少一个维度的新[[CATable/zh|CATable]]对象。通过重复减少维度，最终将获得0维度，这时你将获得一个单一基元值。此时，[[CATable/zh|CATable]]的[[CATable::AtomicValue/zh|AtomicValue]]方法返回该值 。[[CATable::AtomicValue/zh|AtomicValue]]方法是唯一获取一个标值的方法（因为没有坐标位置）。如果你需要建立完整结果其中一个切片的图形图像，必须使用此方法。 &lt;br /&gt;
&lt;br /&gt;
第三种方式就是使用[[CATable/zh|CATable]]的[[CATable::GetSafeArray/zh|GetSafeArray]]方法，将多维数组转化成一个''安全数组''（或者一个.NET数组）。你可以在使用VB或者其它.NET语言直接处理多维数组。因为对于Analytica维度没有固定顺序，但是安全数组和.NET数组有一个明确的顺序，你必须先使用[[CATable/zh|CATable]]对象的[[CATable::SetIndexOrder/zh|SetIndexOrder]]方法在调用[[CATable::GetSafeArray/zh|GetSafeArray]]之前指明维度的顺序。注意如果你知道你的数组是一维的，那就没必要了。&lt;br /&gt;
&lt;br /&gt;
===修改对象===&lt;br /&gt;
一个自定义用户程序通常从一个用户或者其它外部源获取输入，以便转化成Analytica模型中的输入变量。你可以设定输入变量的定义或者通过使用定义表格来这样做。 &lt;br /&gt;
&lt;br /&gt;
'''TestTxc''' 说明了如何修改'''Pop_exp'''定义，此模型是一个影响结果变量Cost的模型输入。要想在该示例中设定该定义，从主菜单上选择'''File &amp;gt; Change Population'''。将出现一个对话框，如下图所示：&lt;br /&gt;
&lt;br /&gt;
[[File:RedefiningtheVariableDefinition.jpg|400px/zh|文件：RedefiningtheVariableDefinition.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
在信息栏中输入一个新定义并点击'''Ok'''确认。主窗口将显示一个新的Cost值。当点击该对话框中的'''Ok'''按钮时，调用了&amp;lt;tt&amp;gt;ChangeDef.frm&amp;lt;/tt&amp;gt;函数，然后调用[[PrintAttributes/zh|PrintAttributes]]函数打印&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果。&lt;br /&gt;
&lt;br /&gt;
此函数类似于：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Private Sub OkButton_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles OkButton.Click &lt;br /&gt;
::Dim errorText As String&lt;br /&gt;
::Dim pop_exp_Object As [[CAObject/zh|CAObject]] &lt;br /&gt;
::Dim errorCode As Short &lt;br /&gt;
::Dim errorString As String &lt;br /&gt;
::newDefinition = PopExposedDef.Text &lt;br /&gt;
::pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
::pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]](&amp;quot;[[Definition]]&amp;quot;, newDefinition) &lt;br /&gt;
::errorCode = adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &lt;br /&gt;
::If errorCode &amp;lt;&amp;gt; 0 Then &lt;br /&gt;
:::MsgBox(&amp;quot;This error occurred while processing your definition: &amp;quot; &amp;amp; vbCrLf &amp;amp; vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) :::PopExposedDef.Focus()&lt;br /&gt;
::Else&lt;br /&gt;
:::Me.Close() &lt;br /&gt;
:::frmMain.DefInstance.PrintAttributes(&amp;quot;Pop_exp&amp;quot;, &amp;quot;Cost&amp;quot;) &lt;br /&gt;
::End If &lt;br /&gt;
::ReleaseComObject(pop_exp_Object) &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
该函数抓取了输入到'''New Definition''' 新定义给'''Population Exposed'''栏，并通过使用[[CAObject/zh|CAObject]]对象中的[[CAObject::SetAttribute/zh|SetAttribute]]函数将它设置给&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;对象。然后调用[[PrintAttributes/zh|PrintAttributes]]，以计算&amp;lt;tt&amp;gt;Cost object&amp;lt;/tt&amp;gt;，并打印新的结果。要想给变量&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;设定一个新定义，我们可以为&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;获取[[CAObject/zh|CAObject]]对象，然后将其定义设置成用户输入的定义。通过使用下面的代码来实现：&lt;br /&gt;
:pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
:pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]]( &amp;quot;[[Definition]]&amp;quot;, newDefinition )&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
无论什么时候调用[[CAObject::SetAttribute/zh|SetAttribute]]，都应该检查[[CAEngine/zh|CAEngine]]自动化对象（'''adeEngine'''）的[[CAEngine::ErrorCode/zh|ErrorCode]]，以免它的定义是非法的。尝试一下输入一个新定义，比如&amp;lt;code&amp;gt;[[Uniform]](25M,35M)&amp;lt;/code&amp;gt;，然后点击'''Ok'''。当&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;的定义被改变时， &amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果由ADE重新计算，此时'''ResultTable'''接下来调用给Cost变量（在应用程序窗口重新显示时）。&lt;br /&gt;
&lt;br /&gt;
使用ADE绘图&lt;br /&gt;
&lt;br /&gt;
通过Analytica 4.6使用相同的绘图引擎，你可以建立一个图表或者图形以显示一个数组值或者不确定值结果。在ADE4.6中，你可以使用 [[CATable/zh|CATable]]的[[CATable::GraphToFile/zh|GraphToFile]]和[[CATable::GraphToStream/zh|GraphToStream]]方法。图形可以以几种可能的图像格式返回，例如'''image/png'''、 '''image/bmp'''或者 '''image/jpeg'''。 &lt;br /&gt;
&lt;br /&gt;
从可用图形选项中选择的最简单方式就是使用Analytica打开你的模型。你可以实验设置各种默认设置或者替代选择的变量，看它们是如何工作的。但你选择了你想设置的选项，保存模型。当为每一个生成结果图形时，ADE将使用这些设置。 &lt;br /&gt;
&lt;br /&gt;
对于更高维度的结果，可能需要做一些必要工作，以便选择将绘制结果的切片和具体的轴（也就是相对于图例哪个维度作为X轴）。[[CATable/zh|CATable]]的[[CATable::Subscript/zh|Subscript]]或[[CATable::Slice/zh|Slice]]方法可以用来控制轴选择特殊的切片用来绘制，能够用来控制轴。详情请参考[[CATable/zh|CATable]]。在我们的&amp;lt;tt&amp;gt;Tutorial.NET&amp;lt;/tt&amp;gt;示例中，我们有一个一维结果（&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;），因此我们没有必要担心截取或者绕轴旋转。 &lt;br /&gt;
&lt;br /&gt;
[[CATable::GraphToStream/zh|GraphToStream]]方法被用来从ADE中直接转化图形图形到一个用户界面中。使用[[CATable::GraphToStream/zh|GraphToStream]]比起使用[[CATable::GraphToFile/zh|GraphToFile]]来要稍微复杂一点，因为[[CATable::GraphToFile/zh|GraphToFile]]除了需要文件名以外还需要其它一些信息，以便编写图形。要使用[[CATable::GraphToStream/zh|GraphToStream]]，我们必须在内存内设置一个流，允许ADE写入该留，然后从该留重建。因为.NET流和COM流不兼容，你必须使用ADE一同提供的[[StreamConnector]]类型.&amp;lt;tt&amp;gt;frmMain&amp;lt;/tt&amp;gt; 中的'''GraphResult_Click'''子程序演示了[[CATable::GraphToStream/zh|GraphToStream]]的使用。从主应用程序窗口选择 '''Graph Result'''菜单选项，结果将出现在一个如下所示的图形当中：&lt;br /&gt;
&lt;br /&gt;
[[File:resultgraph.jpg/zh|文件：resultgraph.jpg]]&lt;br /&gt;
&lt;br /&gt;
==结论==&lt;br /&gt;
&lt;br /&gt;
在此教程中，我们介绍了Analytica决策引擎的几个重要方面。我们看到了如何建立一个ADE服务器对象，使用ADE打开模型，获取模型中的单个对象、计算对象、获取表格中的元素，以及修改模型中的对象。但是ADE可以做的远不止这些。 &lt;br /&gt;
&lt;br /&gt;
我们希望你已经足够了解其基本特征，这样你现在才能独自开始探索更多新的高级特征。我们建议你现在开始阅读字教程的剩余部分以了解ADE能做什么。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
| [[Installation of ADE/zh|ADE 安装]] &amp;lt;- ||  [[The ADE Tutorial/zh|ADE 入门教程]] || -&amp;gt; [[Using the ADE Server/zh|使用ADE服务器]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36308</id>
		<title>The ADE Tutorial/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36308"/>
		<updated>2015-10-27T06:35:55Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南 ]]&lt;br /&gt;
&lt;br /&gt;
此教程教你如何在一个Visual Basic程序中使用Analytica决策引擎（ADE）。&lt;br /&gt;
&lt;br /&gt;
==你的第一个ADE应用程序==&lt;br /&gt;
首先先从头开始写一个简单的ADE程序，只要确认一切设置正常。按照以下步骤操作：&lt;br /&gt;
&lt;br /&gt;
test&lt;br /&gt;
&lt;br /&gt;
第一个程序执行了以下操作：&lt;br /&gt;
*建立一个名称为ADE的[[CAEngine/zh|CAEngine]]自动化对象（通过使用&amp;lt;code&amp;gt;new [[CAEngine/zh|CAEngine]]&amp;lt;/code&amp;gt;).&lt;br /&gt;
*打开Analytica模型 (通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]] 方法。&lt;br /&gt;
*显示模型名称返回[[CAEngine::OpenModel/zh|OpenModel]]的值。&lt;br /&gt;
我们将在后面的章节详细了解这些信息。&lt;br /&gt;
&lt;br /&gt;
===接下来讲什么呢?===&lt;br /&gt;
我们不会尝试在此入门教程中解释ADE的特征。本指南后面几个章节会描述这些特征。 &lt;br /&gt;
&lt;br /&gt;
从现在开始，我们我们将使用名称为&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;的示例模型。打开 Analytica安装目录下 '''Example Models'''文件夹里面的'''Risk Analysis'''文件夹便可找到&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;文件。如果你找不到，或者你安装Analytica的时候未选择安装examples（示例）文件，在ADE安装目录下面的'''Examples\Tutorial.NET'''文件家中有一个副本。 &lt;br /&gt;
&lt;br /&gt;
Txc模型演示了减少污染物TXC排放的risk-benefit （风险-效益）分析。请用Analytica打开Txc查看它是如何工作的。 &lt;br /&gt;
&lt;br /&gt;
ADE '''Examples\Tutorial.NET''' 文件夹中名称为&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;的Visual Basic.NET程序示例显示了ADE很多方面。该程序建立了一个ADE自动化对象，打开包含该对象的&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，获取变量 &amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，计算变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;，通过获取每个表格的单独组件以表格的方式打印输出变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的结果，然后改变变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义。再次获取变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的值，看一下 变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;定义的改变对变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;有什么影响。如果设置正确的话,&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;将显示在“Text Txc window”中显示的窗口。 &lt;br /&gt;
&lt;br /&gt;
应用程序显示变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义（&amp;lt;tt&amp;gt;&amp;quot;Normal (30M, 3M)&amp;quot;&amp;lt;/tt&amp;gt;），以及与&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;关联的表格，这都基于&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义。你可以通过从主菜单选择'''File &amp;gt; Change Population Exposed'''改变&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，然后查看改变对&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;表格的影响。&lt;br /&gt;
&lt;br /&gt;
[[File:TextTxcWindow.png|400px/zh | 文件：TextTxcWindow.png|400px]]&lt;br /&gt;
&lt;br /&gt;
===区分title（名称） 和 identifier（标识符）===&lt;br /&gt;
无论什么时候，一个ADE函数都需要一个变量你必须传达变量的'''''[[Identifier|标识符]]''''' ，而不是它的'''''[[Title|名称]]'''''。这可能会引起混淆，因为在Analytica影响图中一般显示每一个变量的名称。默认情况下，在你最初建立每一个对象的时候，Analytica自动根据名称建立一个标识符。用（_）代替名称中的每一个空格或者其他非字母和数字字符。 &lt;br /&gt;
&lt;br /&gt;
你可以通过点击“Control+y”（或者从Object（对象）菜单选择'''Show by identifier''' ：显示标识符） 来以标识符显示变量。对于模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;，你可以看到名称为&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;变量的标识符为 &amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;。将变量传递给ADE函数时，使用标识符很重要。如果你传递&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;，ADE无法找到变量，并且将返回一个错误。&lt;br /&gt;
&lt;br /&gt;
===从Visual Basic中建立一个ADE 对象===&lt;br /&gt;
&lt;br /&gt;
如果你还没准备好，将名称为tt&amp;gt;Examples\Tutorial\TestTxc.sln&amp;lt;/tt&amp;gt;载入到Visual Basic.NET中，查看名称为&amp;lt;tt&amp;gt;TestTxc.vb&amp;lt;/tt&amp;gt;的文件的代码。其代码看起来像：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Imports ADEW &lt;br /&gt;
:. . . &lt;br /&gt;
:Public adeEngine As [[CAEngine/zh|CAEngine]]&lt;br /&gt;
&lt;br /&gt;
:Public Sub Main() &lt;br /&gt;
::Dim exeDirectory, theModel As String &lt;br /&gt;
::Dim theModelString As String &lt;br /&gt;
::exeDirectory = VB6.GetPath &lt;br /&gt;
::theModel = exeDirectory &amp;amp; &amp;quot;\..\&amp;quot; &amp;amp; &amp;quot;Txc.ana&amp;quot; &lt;br /&gt;
::adeEngine = New [[CAEngine/zh|CAEngine]]&lt;br /&gt;
::... &lt;br /&gt;
::theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
::... &lt;br /&gt;
::frmMain.DefInstance.Show() &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在每一个文件的顶部的代码将自动化对象 '''adeEngine''' 声明为一个[[CAEngine/zh|CAEngine]] 对象。使用此对象，我们能够访问[[CAEngine/zh|CAEngine]] 展示的所有公共函数（参考 [[ADE Server Class Reference/zh|ADE服务器类型参考]] ）&lt;br /&gt;
&lt;br /&gt;
变量&amp;lt;tt&amp;gt;adeEngine&amp;lt;/tt&amp;gt;包含我们的进程内对象 [[CAEngine/zh|CAEngine]]。如果我们想使用ADE的本地（进程外）服务器版本，我们可以将一个项目参考添加到'''Analytica Decision Engine Server 4.6 COM''' 组件并将顶部行从&amp;lt;tt&amp;gt;Imports ADEW&amp;lt;/tt&amp;gt;改成&amp;lt;tt&amp;gt;Imports ADE&amp;lt;/tt&amp;gt;即可。 &lt;br /&gt;
&lt;br /&gt;
这里是另一种获得一个先[[CAEngine/zh|CAEngine]]对象的方法。此循序不需要给项目添加参考。&amp;lt;tt&amp;gt;&lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADEW4.6.CAEngine&amp;quot;) ’ in-process &lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADE4.6.CAEngine&amp;quot;) ’ out-of-process &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果想理解使用进程内和进程外（或本地）服务器的利与弊，以及哪一种自动化服务器用于不同的场景，参考[[Using_the_Analytica_Decision_Engine_Server#In-process_vs_Out-of-process/zh | In-process vs. out-of-process]]&lt;br /&gt;
&lt;br /&gt;
===COM和 Automation 接口比较===&lt;br /&gt;
在上面的例子当中，我们使用COM接口调用ADE。在一个COM 接口中，对象 在本例中为 [[CAEngine/zh|CAEngine]] 被声明为[[CAEngine/zh|CAEngine]] ，编译器解决每一个成员函数，并且在编译时间内能探测几个明显的错误。另外，Visual Studio可以提供方法和参数类型列表当，在你编程的时候可以当做一个提示工具，在编写使用ADE程序是非常有用。COM调用比Automation调用要快一点，但是在ADE应用程序中速度差异通常不是很重要。对于ADE 4.6我们推荐使用COM结构，只要你的语言支持。&lt;br /&gt;
&lt;br /&gt;
在VB Automation中，你可以将一个对象简单声明为Object（对象），而不是像 [[CAEngine/zh|CAEngine]]、[[CAObject/zh|CAObject]]等更加具体的类型。当使用Automation调用'''ADE'''方法时，在运行时间内确定方法。在编译时间内，编译器不知道你的 '''ADE''' 对象是否有一个名称为[[CAEngine::OpenModel/zh|OpenModel]]的函数。在VB中，调用COM方法或Automation 方法的语法是相通的——唯一的不同在于对象类型是否明确被声明。&lt;br /&gt;
&lt;br /&gt;
在VC++和C#中，调用COM的语法和调用Automatio的语法不同。在这些情况下，COM要方便的多，Automation能够获得相冗余。然而，同样的语言，包括VBScript和其他脚本语言，只支持Automation不支持COM。&lt;br /&gt;
&lt;br /&gt;
===监视Process（进程）===&lt;br /&gt;
当使用进程外ADE服务器时，你的代码必须在终止时释放[[CAEngine/zh|CAEngine]]COM对象。当最终[[CAEngine/zh|CAEngine]]使用被释放是，ADE.exe 进程自动终止。到目前为止所看到的代码，VB语言在达到程序末端时，自动处理释放对象。但是，当你调试你的代码是，你可以提前终止你的程序来修复bug，你的程序可能被Task Manager（任务管理器）终止，或者你自己的代码也可能奔溃，导致你的程序进程在它有机会释放对象之前终止。应为COM对象从来不会被释放，ADE.exe进程不知道它是否在使用中，你可能获得ADE.exe 僵尸进程。 &lt;br /&gt;
&lt;br /&gt;
为了避免这种情况发生，一种好的习惯就是在调用[[CAEngine/zh|CAEngine]]实例后 立即调用[[CAEngine::MonitorProcess/zh|CAEngine::MonitorProcess]]。通过这种方式，ADE能够得知哪一个进程正在使用它，同时将设置一个线程去探测你的进程是否在ADE被完全释放前终止。如果你的程序进程没有终止，ADE进程会立即将它关闭，消除了僵尸ADE进程的堆积。 &lt;br /&gt;
&lt;br /&gt;
要从一个.NET应用程序获得进程ID，使用System.Diagnostics.Process namespace中的'''GetCurrentProcess().Id''' 。在其他语言中，你可以使用Windows SDK 的'''GetProcessId( )'''函数。 &lt;br /&gt;
&lt;br /&gt;
'''[[CAEngine::MonitorProcess/zh|MonitorProcess]]()''' 只能用来监视运行ADE进程的同一台计算机的进程，一次当通过DCOM运行ADE时不能使用。当使用进程内ADEW服务器时没有必要使用。&lt;br /&gt;
&lt;br /&gt;
==使用ADE打开模型==&lt;br /&gt;
我们现在打开&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，显示我们的应用程序主窗口。使用以下调用：tt&amp;gt;&lt;br /&gt;
:theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
:frmMain.DefInstance.Show &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]]函数打开模型。如果成功的话，变量&amp;lt;tt&amp;gt;theModelString&amp;lt;/tt&amp;gt;将包含模型的名字。否则，将包含一个空的串。虽然由于为了简介的缘故，我们没有这样做，但是你应该检查从[[CAEngine::OpenModel/zh|OpenModel]]函数返回的是不是一个空的串。如果是，说明在你打开的模型中存在一个错误。你可以使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]]属性找出是哪种错误 （&amp;lt;tt&amp;gt;adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] 和adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]&amp;lt;/tt&amp;gt;）。&lt;br /&gt;
&lt;br /&gt;
==从Analytica模型中检索对象==&lt;br /&gt;
下一步就是从我们的模型中检索对象（变量、模块、函数等），以便我们能获取他们的属性（[[definition|定义]]、[[title|名称]]、[[class|类型]]等等 ）。我们的示例模型（&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;）操作&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;和&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;对象。尤其是，修改&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;可以查看这是如何影响&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt; 对象。&lt;br /&gt;
&lt;br /&gt;
我们的&amp;lt;tt&amp;gt;TxcTest.vbproj&amp;lt;/tt&amp;gt; （&amp;lt;tt&amp;gt;TxcText.sln&amp;lt;/tt&amp;gt;）项目中的&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;文件里的 '''PrintAttributes''' 函数演示了如何检索对象。该函数首先被&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''Form_Load''' 函数调用，当应用程序启动后，可以显示'''Cost'''表格。当然无论什么时候，只要我们想输出'''Cost'''表格的当前值，都可以调用。该函数如下所示：&lt;br /&gt;
:Public Sub PrintAttributes(ByRef inputIdentifier As String, ByRef  outputIdentifier As String) &lt;br /&gt;
::Dim inputObject, outputObject As [[CAObject/zh|CAObject]]&lt;br /&gt;
::Dim resultTable As [[CATable/zh|CATable]]&lt;br /&gt;
::Dim definitionAttrInput As String &lt;br /&gt;
::inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
::outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier) &lt;br /&gt;
::definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;definition&amp;quot;) &lt;br /&gt;
::resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]]&lt;br /&gt;
::Call PrintResultTable(resultTable, inputIdentifier, definitionAttrInput, outputIdentifier) &lt;br /&gt;
::ReleaseComObject(resultTable) &lt;br /&gt;
::ReleaseComObject(inputObject) &lt;br /&gt;
::ReleaseComObject(outputObject) &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''PrintAttributes'''和作为'''inputIdentifier'''参数的&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;变量标识符以及作为'''outputIdentifier'''参数的'''Cost'''变量一起使用。如下所示通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::GetObjectByName/zh|GetObjectByName]]函数提取相应对象：&amp;lt;tt&amp;gt;&lt;br /&gt;
:inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取成功，将返回一个[[CAObject/zh|CAObject]]类型对象。如果使用'''[[CAObject/zh|CAObject]]'''的函数，参考[[CAObject/zh|SendCommand(command)]]，可以获得一个[[CAObject/zh|CAObject]]的完整函数列表。如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取失败，返回值为&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;。代码应该检查以确保[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取的结果是有效的。如果找不到，可使用[[CAEngine/zh|CAEngine]]的 [[CAEngine::ErrorCode/zh|ErrorCode]]和 [[CAEngine::ErrorText/zh|ErrorText]]属性获取错误信息。例如：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Set inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:If inputObject Is Nothing Then &lt;br /&gt;
::MsgBox(“This error from GetObjectByName occurred: “&amp;amp; _ vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &amp;amp; “:” &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) &lt;br /&gt;
:Else &lt;br /&gt;
::'inputObject valid &lt;br /&gt;
:End If&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===获取对象属性===&lt;br /&gt;
每一个Analytica对象都有一组属性，例如[[identifier|标识符]]、[[title|名称]]、[[description| 描述]]和[[class|类型]]。你可以使用[[CAObject::GetAttribute/zh|GetAttribute]]函数来获去Analytica对象的属性。例如，如要获取'''inputObject'''的定义（当前为cost）：&amp;lt;tt&amp;gt;&lt;br /&gt;
:definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh|GetAttribute]](&amp;quot;[[Definition|定义]]&amp;quot;) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt; 中，&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;的定义为&amp;quot;&amp;lt;tt&amp;gt;[[Normal]](30M, 3M)&amp;lt;/tt&amp;gt;&amp;quot; ，我们将它储存在'''definitionAttrInput'''当中。.&lt;br /&gt;
&lt;br /&gt;
===计算对象和检索结果===&lt;br /&gt;
使用[[CAObject/zh|CAObject]]的[[CAObject::Result/zh|Result]]或[[CAObject::ResultTable/zh|ResultTable]]方法来获取变量的值。如果有必要的话，ADE先自动计算变量。如果你确定结果为基元（只有一个元素），使用[[CAObject::Result/zh|Result]]方法。否则使用[[CAObject::ResultTable/zh|ResultTable]]，检索结果为一个''数组''。基元结果当作一个特殊数组案例来处理，没有维度的数组。如果值为基元[[CATable::AtomicValue/zh|AtomicValue]]方法将返回一个数字或者字符串单一值。 &lt;br /&gt;
&lt;br /&gt;
默认情况下，[[CAObject::Result/zh|Result]]和[[CAObject::ResultTable/zh|ResultTable]]返回结果的中值，也就是说，ADE以确定性方式计算结果。对于一个概率值，将[[CAObject/zh|CAObject]]的[[CAObject::ResultType/zh|ResultType]]属性设置为想要的不确定性视图——Mean（平均值） Sample（样本）、PDF（概率密度函数）、CDF（累计分布函数）、Confidence bands（置信带）、或者Statistics（统计数据）详情请参考[[CAObject::ResultType/zh|ResultType]]。我们通过如下的方式获取outputObject 输出对象 的值：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]] &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
结果为一个[[CATable/zh|CATable]]对象，允许我们访问一个表格中的单个元素。 &lt;br /&gt;
&lt;br /&gt;
如果你通过调用[[CAObject::Result/zh|Result]]来获取一个数组（或者表格）的值，将返回数组为一个字符串，列出索引和元素，以逗号隔开。通常使用[[CAObject::ResultTable/zh|ResultTable]]更加简单，这样你没有必要从字符串中解析表格的元素。&lt;br /&gt;
&lt;br /&gt;
===获取表格索引元素===&lt;br /&gt;
一个Analytica表格包含0个或者多个索引。如果包含一个索引，那么该表格是1维表格；如果有2个索引，说他是2维表格，依此类推。0维度表格包含一个“单一基元”（或标量）值。你可以使用CATable的[[CATable::NumDims/zh|NumDims]]获取表格的维数（也就是索引数）。要想获取表格的单个索引，可使用[[CATable/zh|CATable]]的 [[CATable::IndexNames/zh|IndexNames]]和 [[CATable::GetIndexObject/zh|GetIndexObject]]函数。 &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''PrintResultTable'''函数说明了这两个函数的使用。从'''PrintAttributes'''中调用'''PrintResultTable'''，执行打印'''TestTxc'''中的表格的实际工作（为了简洁起见，我们只给出了关联ADE的该函数部分）。&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Public Sub PrintResultTable(ByRef resultTable As CATable, ByRef inputIdentifier As String, ByRef definitionAttrInput As String, ByRef outputIdentifier As String) &lt;br /&gt;
::Dim theIndexName, theTableName As String &lt;br /&gt;
::Dim theIndexElement As String &lt;br /&gt;
::Dim theTableElement &lt;br /&gt;
::Dim theIndexObj As [[CAIndex/zh|CAIndex]]&lt;br /&gt;
::Dim numEls As Integer &lt;br /&gt;
::Dim spaces, i As Integer &lt;br /&gt;
::Dim lenStr As Short &lt;br /&gt;
::Dim OutputStr As Short &lt;br /&gt;
::Dim spaceString, underlineString As String &lt;br /&gt;
::... &lt;br /&gt;
::theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1) &lt;br /&gt;
::theTableName = resultTable.[[CATable::Name/zh|Name]] &lt;br /&gt;
::theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName) &lt;br /&gt;
::numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
::... &lt;br /&gt;
::For i = 1 To numEls &lt;br /&gt;
:::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
:::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
:::... &lt;br /&gt;
::Next i &lt;br /&gt;
::InformationPane.Text = outputString &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
通过'''PrintResultTable'''获取一个表格的索引方法如下：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1)&lt;br /&gt;
:theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
我们通过使用[[CATable/zh|CATable]]的[[CATable::IndexNames/zh|IndexNames]]函数获取第一个索引的名字。我们将它传递给[[CATable/zh|CATable]]的[[CATable::GetIndexObject/zh|GetIndexObject]]函数以获取表示我们的索引的[[CAIndex/zh|CAIndex]]。该自动化对象返回其相应索引的相关信息。如果此函数调用失败，将返回&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;信息。在此情况下，使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]] 函数找出原因。&lt;br /&gt;
&lt;br /&gt;
==从CATable和CAIndex中获取信息==&lt;br /&gt;
[[PrintResultTable]]说明了如何从[[CATable/zh| CATable]]和[[CAIndex/zh|CAIndex]] 对象获取信息。该代码获取'''Cost'''表格的索引和表格元素：&lt;br /&gt;
: &amp;lt;tt&amp;gt;&lt;br /&gt;
:numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
:For i = 1 To numEls &lt;br /&gt;
::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
::... &lt;br /&gt;
:Next i &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[CAIndex/zh|CAIndex]]的[[CAIndex::IndexElements/zh|IndexElements]]属性返回第一个索引中的元素个数。[[CAIndex/zh|CAIndex]]的[[CAIndex::GetValueByNumber/zh|GetValueByNumber]]函数获取单个索引元素。 &lt;br /&gt;
&lt;br /&gt;
我们通过传递表格中元素的坐标，使用  [[CATable/zh|CATable]]的[[CATable::GetDataByElements/zh|GetDataByElements]]函数获取'''Cost'''表格对象的单个表格元素'''resultTable'''。 &lt;br /&gt;
&lt;br /&gt;
当我检索 [[CATable/zh|CATable]]对象中单个元素（'''resultTable'''）的时候，我们利用了该表格是一维的事实。因此，我们只需要传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个单一数（这个数代表表格中的位置）。但是，如果我们处理两个或者更多维度，我们必须传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个数组函数，并且指明我们要检索的表格元素的位置。因此，如果我们不想检索一个二维数组的position (4,3)位置的元素，我们可以这样写：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Dim W as Variant 'return element &lt;br /&gt;
:Dim IndexPtrs(1 To 2) As Variant 'position in table &lt;br /&gt;
::... &lt;br /&gt;
:IndexPtrs(1) = 4 &lt;br /&gt;
:IndexPtrs(2) = 3 &lt;br /&gt;
:W = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](IndexPtrs) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==控制基元值格式==&lt;br /&gt;
[[CATable/zh|CATable]]中的每个基元值可以是一个数、一个字符串，或者其它一些基本类型（''例如''：[[Null|空值]]、[[Undefined|未定义]]、[[Reference|参考]]，或 [[Handle|句柄]]。通过说明类型和值，它们作为''变体''被返回，这是一种Visual Basic能读懂的数据结构。[[CATable/zh|CATable]]的[[CATable::RenderingStyle|RenderingStyle]]属性控制Analytica基础值是如何映射到Visual Basic变体的。 &lt;br /&gt;
&lt;br /&gt;
例如：可以通过使用Analytica 模型的数字格式设置将一个数值返回成一个数字或者字符串。如果被指定格式，有一个选线控制是截断数字的位数，还是精确返回。 &lt;br /&gt;
&lt;br /&gt;
子程序[[PrintResultTable/zh|PrintResultTable]]在&amp;lt;tt&amp;gt;frmMain.vb&amp;lt;/tt&amp;gt;中载入,其渲染风格直接指明：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::NumberAsText/zh|NumberAsText]] = True &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::FullPrecision/zh|FullPrecision]] = False &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::StringQuotes/zh|StringQuotes]] = 2 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
第一行指明数值应该根据与结果对象有关的数字格式被格式化为文本。例如在其程序输出中，我们将看到&amp;lt;tt&amp;gt;30.103M&amp;lt;/tt&amp;gt;，而非&amp;lt;tt&amp;gt;30102995.6639812&amp;lt;/tt&amp;gt;，如果我们让Visual Basic将数值串联我们的结果字符串，将显示该结果。在此事件中，一个值为字符串的单元格出现在结果中，返回值将明确带双引号。对于[[CARenderingStyle/zh|CARenderingStyle]]对象中的所有可用属性，请参考[[CARenderingStyle/zh|CARenderingStyle]]。&lt;br /&gt;
&lt;br /&gt;
===其它访问表格的方式===&lt;br /&gt;
有几种访问多维表格[[CATable/zh|CATable]]中元素的方式。每一种都有可能在特定的场合使用起来比较方便。 &lt;br /&gt;
&lt;br /&gt;
第一种方式就是使用[[CATable/zh | CATable]]的 [[CATable::GetDataByElements/zh|GetDataByElements]]或[[CATable::GetDataByLabels/zh|GetDataByLabels]]方法，上面代码示例中有显示。在此情况下，利用你想获取的基元值的单元格位置。 &lt;br /&gt;
&lt;br /&gt;
第二种方式就是使用[[CATable/zh|CATable]][[CATable::Slice/zh|Slice]]或[[CATable::Subscript/zh | Subscript]]方法获取一个少一个维度的新[[CATable/zh|CATable]]对象。通过重复减少维度，最终将获得0维度，这时你将获得一个单一基元值。此时，[[CATable/zh|CATable]]的[[CATable::AtomicValue/zh|AtomicValue]]方法返回该值 。[[CATable::AtomicValue/zh|AtomicValue]]方法是唯一获取一个标值的方法（因为没有坐标位置）。如果你需要建立完整结果其中一个切片的图形图像，必须使用此方法。 &lt;br /&gt;
&lt;br /&gt;
第三种方式就是使用[[CATable/zh|CATable]]的[[CATable::GetSafeArray/zh|GetSafeArray]]方法，将多维数组转化成一个''安全数组''（或者一个.NET数组）。你可以在使用VB或者其它.NET语言直接处理多维数组。因为对于Analytica维度没有固定顺序，但是安全数组和.NET数组有一个明确的顺序，你必须先使用[[CATable/zh|CATable]]对象的[[CATable::SetIndexOrder/zh|SetIndexOrder]]方法在调用[[CATable::GetSafeArray/zh|GetSafeArray]]之前指明维度的顺序。注意如果你知道你的数组是一维的，那就没必要了。&lt;br /&gt;
&lt;br /&gt;
===修改对象===&lt;br /&gt;
一个自定义用户程序通常从一个用户或者其它外部源获取输入，以便转化成Analytica模型中的输入变量。你可以设定输入变量的定义或者通过使用定义表格来这样做。 &lt;br /&gt;
&lt;br /&gt;
'''TestTxc''' 说明了如何修改'''Pop_exp'''定义，此模型是一个影响结果变量Cost的模型输入。要想在该示例中设定该定义，从主菜单上选择'''File &amp;gt; Change Population'''。将出现一个对话框，如下图所示：&lt;br /&gt;
&lt;br /&gt;
[[File:RedefiningtheVariableDefinition.jpg|400px/zh|文件：RedefiningtheVariableDefinition.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
在信息栏中输入一个新定义并点击'''Ok'''确认。主窗口将显示一个新的Cost值。当点击该对话框中的'''Ok'''按钮时，调用了&amp;lt;tt&amp;gt;ChangeDef.frm&amp;lt;/tt&amp;gt;函数，然后调用[[PrintAttributes/zh|PrintAttributes]]函数打印&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果。&lt;br /&gt;
&lt;br /&gt;
此函数类似于：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Private Sub OkButton_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles OkButton.Click &lt;br /&gt;
::Dim errorText As String&lt;br /&gt;
::Dim pop_exp_Object As [[CAObject/zh|CAObject]] &lt;br /&gt;
::Dim errorCode As Short &lt;br /&gt;
::Dim errorString As String &lt;br /&gt;
::newDefinition = PopExposedDef.Text &lt;br /&gt;
::pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
::pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]](&amp;quot;[[Definition]]&amp;quot;, newDefinition) &lt;br /&gt;
::errorCode = adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &lt;br /&gt;
::If errorCode &amp;lt;&amp;gt; 0 Then &lt;br /&gt;
:::MsgBox(&amp;quot;This error occurred while processing your definition: &amp;quot; &amp;amp; vbCrLf &amp;amp; vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) :::PopExposedDef.Focus()&lt;br /&gt;
::Else&lt;br /&gt;
:::Me.Close() &lt;br /&gt;
:::frmMain.DefInstance.PrintAttributes(&amp;quot;Pop_exp&amp;quot;, &amp;quot;Cost&amp;quot;) &lt;br /&gt;
::End If &lt;br /&gt;
::ReleaseComObject(pop_exp_Object) &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
该函数抓取了输入到'''New Definition''' 新定义给'''Population Exposed'''栏，并通过使用[[CAObject/zh|CAObject]]对象中的[[CAObject::SetAttribute/zh|SetAttribute]]函数将它设置给&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;对象。然后调用[[PrintAttributes/zh|PrintAttributes]]，以计算&amp;lt;tt&amp;gt;Cost object&amp;lt;/tt&amp;gt;，并打印新的结果。要想给变量&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;设定一个新定义，我们可以为&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;获取[[CAObject/zh|CAObject]]对象，然后将其定义设置成用户输入的定义。通过使用下面的代码来实现：&lt;br /&gt;
:pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
:pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]]( &amp;quot;[[Definition]]&amp;quot;, newDefinition )&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
无论什么时候调用[[CAObject::SetAttribute/zh|SetAttribute]]，都应该检查[[CAEngine/zh|CAEngine]]自动化对象（'''adeEngine'''）的[[CAEngine::ErrorCode/zh|ErrorCode]]，以免它的定义是非法的。尝试一下输入一个新定义，比如&amp;lt;code&amp;gt;[[Uniform]](25M,35M)&amp;lt;/code&amp;gt;，然后点击'''Ok'''。当&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;的定义被改变时， &amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果由ADE重新计算，此时'''ResultTable'''接下来调用给Cost变量（在应用程序窗口重新显示时）。&lt;br /&gt;
&lt;br /&gt;
使用ADE绘图&lt;br /&gt;
&lt;br /&gt;
通过Analytica 4.6使用相同的绘图引擎，你可以建立一个图表或者图形以显示一个数组值或者不确定值结果。在ADE4.6中，你可以使用 [[CATable/zh|CATable]]的[[CATable::GraphToFile/zh|GraphToFile]]和[[CATable::GraphToStream/zh|GraphToStream]]方法。图形可以以几种可能的图像格式返回，例如'''image/png'''、 '''image/bmp'''或者 '''image/jpeg'''。 &lt;br /&gt;
&lt;br /&gt;
从可用图形选项中选择的最简单方式就是使用Analytica打开你的模型。你可以实验设置各种默认设置或者替代选择的变量，看它们是如何工作的。但你选择了你想设置的选项，保存模型。当为每一个生成结果图形时，ADE将使用这些设置。 &lt;br /&gt;
&lt;br /&gt;
对于更高维度的结果，可能需要做一些必要工作，以便选择将绘制结果的切片和具体的轴（也就是相对于图例哪个维度作为X轴）。[[CATable/zh|CATable]]的[[CATable::Subscript/zh|Subscript]]或[[CATable::Slice/zh|Slice]]方法可以用来控制轴选择特殊的切片用来绘制，能够用来控制轴。详情请参考[[CATable/zh|CATable]]。在我们的&amp;lt;tt&amp;gt;Tutorial.NET&amp;lt;/tt&amp;gt;示例中，我们有一个一维结果（&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;），因此我们没有必要担心截取或者绕轴旋转。 &lt;br /&gt;
&lt;br /&gt;
[[CATable::GraphToStream/zh|GraphToStream]]方法被用来从ADE中直接转化图形图形到一个用户界面中。使用[[CATable::GraphToStream/zh|GraphToStream]]比起使用[[CATable::GraphToFile/zh|GraphToFile]]来要稍微复杂一点，因为[[CATable::GraphToFile/zh|GraphToFile]]除了需要文件名以外还需要其它一些信息，以便编写图形。要使用[[CATable::GraphToStream/zh|GraphToStream]]，我们必须在内存内设置一个流，允许ADE写入该留，然后从该留重建。因为.NET流和COM流不兼容，你必须使用ADE一同提供的[[StreamConnector]]类型.&amp;lt;tt&amp;gt;frmMain&amp;lt;/tt&amp;gt; 中的'''GraphResult_Click'''子程序演示了[[CATable::GraphToStream/zh|GraphToStream]]的使用。从主应用程序窗口选择 '''Graph Result'''菜单选项，结果将出现在一个如下所示的图形当中：&lt;br /&gt;
&lt;br /&gt;
[[File:resultgraph.jpg/zh|文件：resultgraph.jpg]]&lt;br /&gt;
&lt;br /&gt;
==结论==&lt;br /&gt;
&lt;br /&gt;
在此教程中，我们介绍了Analytica决策引擎的几个重要方面。我们看到了如何建立一个ADE服务器对象，使用ADE打开模型，获取模型中的单个对象、计算对象、获取表格中的元素，以及修改模型中的对象。但是ADE可以做的远不止这些。 &lt;br /&gt;
&lt;br /&gt;
我们希望你已经足够了解其基本特征，这样你现在才能独自开始探索更多新的高级特征。我们建议你现在开始阅读字教程的剩余部分以了解ADE能做什么。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
| [[Installation of ADE/zh|ADE 安装]] &amp;lt;- ||  [[The ADE Tutorial/zh|ADE 入门教程]] || -&amp;gt; [[Using the ADE Server/zh|使用ADE服务器]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36306</id>
		<title>The ADE Tutorial/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36306"/>
		<updated>2015-10-27T06:30:41Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南 ]]&lt;br /&gt;
&lt;br /&gt;
此教程教你如何在一个Visual Basic程序中使用Analytica决策引擎（ADE）。&lt;br /&gt;
&lt;br /&gt;
==你的第一个ADE应用程序==&lt;br /&gt;
首先先从头开始写一个简单的ADE程序，只要确认一切设置正常。按照以下步骤操作：&lt;br /&gt;
&lt;br /&gt;
test&lt;br /&gt;
&lt;br /&gt;
第一个程序执行了以下操作：&lt;br /&gt;
*建立一个名称为ADE的[[CAEngine/zh|CAEngine]]自动化对象（通过使用&amp;lt;code&amp;gt;new [[CAEngine/zh|CAEngine]]&amp;lt;/code&amp;gt;).&lt;br /&gt;
*打开Analytica模型 (通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]] 方法。&lt;br /&gt;
*显示模型名称返回[[CAEngine::OpenModel/zh|OpenModel]]的值。&lt;br /&gt;
我们将在后面的章节详细了解这些信息。&lt;br /&gt;
&lt;br /&gt;
===接下来讲什么呢?===&lt;br /&gt;
我们不会尝试在此入门教程中解释ADE的特征。本指南后面几个章节会描述这些特征。 &lt;br /&gt;
&lt;br /&gt;
从现在开始，我们我们将使用名称为&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;的示例模型。打开 Analytica安装目录下 '''Example Models'''文件夹里面的'''Risk Analysis'''文件夹便可找到&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;文件。如果你找不到，或者你安装Analytica的时候未选择安装examples（示例）文件，在ADE安装目录下面的'''Examples\Tutorial.NET'''文件家中有一个副本。 &lt;br /&gt;
&lt;br /&gt;
Txc模型演示了减少污染物TXC排放的risk-benefit （风险-效益）分析。请用Analytica打开Txc查看它是如何工作的。 &lt;br /&gt;
&lt;br /&gt;
ADE '''Examples\Tutorial.NET''' 文件夹中名称为&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;的Visual Basic.NET程序示例显示了ADE很多方面。该程序建立了一个ADE自动化对象，打开包含该对象的&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，获取变量 &amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，计算变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;，通过获取每个表格的单独组件以表格的方式打印输出变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的结果，然后改变变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义。再次获取变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的值，看一下 变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;定义的改变对变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;有什么影响。如果设置正确的话,&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;将显示在“Text Txc window”中显示的窗口。 &lt;br /&gt;
&lt;br /&gt;
应用程序显示变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义（&amp;lt;tt&amp;gt;&amp;quot;Normal (30M, 3M)&amp;quot;&amp;lt;/tt&amp;gt;），以及与&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;关联的表格，这都基于&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义。你可以通过从主菜单选择'''File &amp;gt; Change Population Exposed'''改变&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，然后查看改变对&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;表格的影响。&lt;br /&gt;
&lt;br /&gt;
[[File:TextTxcWindow.png|400px/zh | 文件：TextTxcWindow.png|400px]]&lt;br /&gt;
&lt;br /&gt;
===区分title（名称） 和 identifier（标识符）===&lt;br /&gt;
无论什么时候，一个ADE函数都需要一个变量你必须传达变量的'''''[[Identifier|标识符]]''''' ，而不是它的'''''[[Title|名称]]'''''。这可能会引起混淆，因为在Analytica影响图中一般显示每一个变量的名称。默认情况下，在你最初建立每一个对象的时候，Analytica自动根据名称建立一个标识符。用（_）代替名称中的每一个空格或者其他非字母和数字字符。 &lt;br /&gt;
&lt;br /&gt;
你可以通过点击“Control+y”（或者从Object（对象）菜单选择'''Show by identifier''' ：显示标识符） 来以标识符显示变量。对于模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;，你可以看到名称为&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;变量的标识符为 &amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;。将变量传递给ADE函数时，使用标识符很重要。如果你传递&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;，ADE无法找到变量，并且将返回一个错误。&lt;br /&gt;
&lt;br /&gt;
===从Visual Basic中建立一个ADE 对象===&lt;br /&gt;
&lt;br /&gt;
如果你还没准备好，将名称为tt&amp;gt;Examples\Tutorial\TestTxc.sln&amp;lt;/tt&amp;gt;载入到Visual Basic.NET中，查看名称为&amp;lt;tt&amp;gt;TestTxc.vb&amp;lt;/tt&amp;gt;的文件的代码。其代码看起来像：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Imports ADEW &lt;br /&gt;
:. . . &lt;br /&gt;
:Public adeEngine As [[CAEngine/zh|CAEngine]]&lt;br /&gt;
&lt;br /&gt;
:Public Sub Main() &lt;br /&gt;
::Dim exeDirectory, theModel As String &lt;br /&gt;
::Dim theModelString As String &lt;br /&gt;
::exeDirectory = VB6.GetPath &lt;br /&gt;
::theModel = exeDirectory &amp;amp; &amp;quot;\..\&amp;quot; &amp;amp; &amp;quot;Txc.ana&amp;quot; &lt;br /&gt;
::adeEngine = New [[CAEngine/zh|CAEngine]]&lt;br /&gt;
::... &lt;br /&gt;
::theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
::... &lt;br /&gt;
::frmMain.DefInstance.Show() &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在每一个文件的顶部的代码将自动化对象 '''adeEngine''' 声明为一个[[CAEngine/zh|CAEngine]] 对象。使用此对象，我们能够访问 [[CAEngine/zh|CAEngine]] 展示的所有公共函数（参考 [[ADE Server Class Reference/zh|ADE服务器类型参考]] ）&lt;br /&gt;
&lt;br /&gt;
变量&amp;lt;tt&amp;gt;adeEngine&amp;lt;/tt&amp;gt;包含我们的进程内对象 [[CAEngine/zh|CAEngine]]。如果我们想使用ADE的本地（进程外）服务器版本，我们可以将一个项目参考添加到'''Analytica Decision Engine Server 4.6 COM''' 组件并将顶部行从&amp;lt;tt&amp;gt;Imports ADEW&amp;lt;/tt&amp;gt;改成&amp;lt;tt&amp;gt;Imports ADE&amp;lt;/tt&amp;gt;即可。 &lt;br /&gt;
&lt;br /&gt;
这里是另一种获得一个先[[CAEngine/zh|CAEngine]]对象的方法。此循序不需要给项目添加参考。&amp;lt;tt&amp;gt;&lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADEW4.6.CAEngine&amp;quot;) ’ in-process &lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADE4.6.CAEngine&amp;quot;) ’ out-of-process &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果想理解使用进程内和进程外（或本地）服务器的利与弊，以及哪一种自动化服务器用于不同的场景，参考[[Using_the_Analytica_Decision_Engine_Server#In-process_vs_Out-of-process/zh | In-process vs. out-of-process]]&lt;br /&gt;
&lt;br /&gt;
===COM和 Automation 接口比较===&lt;br /&gt;
在上面的例子当中，我们使用COM接口调用ADE。在一个COM 接口中，对象 在本例中为 [[CAEngine/zh|CAEngine]] 被声明为[[CAEngine/zh|CAEngine]] ，编译器解决每一个成员函数，并且在编译时间内能探测几个明显的错误。另外，Visual Studio可以提供方法和参数类型列表当，在你编程的时候可以当做一个提示工具，在编写使用ADE程序是非常有用。COM调用比Automation调用要快一点，但是在ADE应用程序中速度差异通常不是很重要。对于ADE 4.6我们推荐使用COM结构，只要你的语言支持。&lt;br /&gt;
&lt;br /&gt;
在VB Automation中，你可以将一个对象简单声明为Object（对象），而不是像 [[CAEngine/zh|CAEngine]]、[[CAObject/zh|CAObject]]等更加具体的类型。当使用Automation调用'''ADE'''方法时，在运行时间内确定方法。在编译时间内，编译器不知道你的 '''ADE''' 对象是否有一个名称为[[CAEngine::OpenModel/zh|OpenModel]]的函数。在VB中，调用COM方法或Automation 方法的语法是相通的——唯一的不同在于对象类型是否明确被声明。&lt;br /&gt;
&lt;br /&gt;
在VC++和C#中，调用COM的语法和调用Automatio的语法不同。在这些情况下，COM要方便的多，Automation能够获得相冗余。然而，同样的语言，包括VBScript和其他脚本语言，只支持Automation不支持COM。&lt;br /&gt;
&lt;br /&gt;
===监视Process（进程）===&lt;br /&gt;
当使用进程外ADE服务器时，你的代码必须在终止时释放[[CAEngine/zh|CAEngine]]COM对象。当最终[[CAEngine/zh|CAEngine]]使用被释放是，ADE.exe 进程自动终止。到目前为止所看到的代码，VB语言在达到程序末端时，自动处理释放对象。但是，当你调试你的代码是，你可以提前终止你的程序来修复bug，你的程序可能被Task Manager（任务管理器）终止，或者你自己的代码也可能奔溃，导致你的程序进程在它有机会释放对象之前终止。应为COM对象从来不会被释放，ADE.exe进程不知道它是否在使用中，你可能获得ADE.exe 僵尸进程。 &lt;br /&gt;
&lt;br /&gt;
为了避免这种情况发生，一种好的习惯就是在调用[[CAEngine/zh|CAEngine]]实例后 立即调用[[CAEngine::MonitorProcess/zh|CAEngine::MonitorProcess]]。通过这种方式，ADE能够得知哪一个进程正在使用它，同时将设置一个线程去探测你的进程是否在ADE被完全释放前终止。如果你的程序进程没有终止，ADE进程会立即将它关闭，消除了僵尸ADE进程的堆积。 &lt;br /&gt;
&lt;br /&gt;
要从一个.NET应用程序获得进程ID，使用System.Diagnostics.Process namespace中的'''GetCurrentProcess().Id''' 。在其他语言中，你可以使用Windows SDK 的'''GetProcessId( )'''函数。 &lt;br /&gt;
&lt;br /&gt;
'''[[CAEngine::MonitorProcess/zh|MonitorProcess]]()''' 只能用来监视运行ADE进程的同一台计算机的进程，一次当通过DCOM运行ADE时不能使用。当使用进程内ADEW服务器时没有必要使用。&lt;br /&gt;
&lt;br /&gt;
==使用ADE打开模型==&lt;br /&gt;
我们现在打开&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，显示我们的应用程序主窗口。使用以下调用：tt&amp;gt;&lt;br /&gt;
:theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
:frmMain.DefInstance.Show &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]]函数打开模型。如果成功的话，变量&amp;lt;tt&amp;gt;theModelString&amp;lt;/tt&amp;gt;将包含模型的名字。否则，将包含一个空的串。虽然由于为了简介的缘故，我们没有这样做，但是你应该检查从[[CAEngine::OpenModel/zh|OpenModel]]函数返回的是不是一个空的串。如果是，说明在你打开的模型中存在一个错误。你可以使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]]属性找出是哪种错误 （&amp;lt;tt&amp;gt;adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] 和adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]&amp;lt;/tt&amp;gt;）。&lt;br /&gt;
&lt;br /&gt;
==从Analytica模型中检索对象==&lt;br /&gt;
下一步就是从我们的模型中检索对象（变量、模块、函数等），以便我们能获取他们的属性（[[definition|定义]]、[[title|名称]]、[[class|类型]]等等 ）。我们的示例模型（&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;）操作&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;和&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;对象。尤其是，修改&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;可以查看这是如何影响&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt; 对象。&lt;br /&gt;
&lt;br /&gt;
我们的&amp;lt;tt&amp;gt;TxcTest.vbproj&amp;lt;/tt&amp;gt; （&amp;lt;tt&amp;gt;TxcText.sln&amp;lt;/tt&amp;gt;）项目中的&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;文件里的 '''PrintAttributes''' 函数演示了如何检索对象。该函数首先被&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''Form_Load''' 函数调用，当应用程序启动后，可以显示'''Cost'''表格。当然无论什么时候，只要我们想输出'''Cost'''表格的当前值，都可以调用。该函数如下所示：&lt;br /&gt;
:Public Sub PrintAttributes(ByRef inputIdentifier As String, ByRef  outputIdentifier As String) &lt;br /&gt;
::Dim inputObject, outputObject As [[CAObject/zh|CAObject]]&lt;br /&gt;
::Dim resultTable As [[CATable/zh|CATable]]&lt;br /&gt;
::Dim definitionAttrInput As String &lt;br /&gt;
::inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
::outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier) &lt;br /&gt;
::definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;definition&amp;quot;) &lt;br /&gt;
::resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]]&lt;br /&gt;
::Call PrintResultTable(resultTable, inputIdentifier, definitionAttrInput, outputIdentifier) &lt;br /&gt;
::ReleaseComObject(resultTable) &lt;br /&gt;
::ReleaseComObject(inputObject) &lt;br /&gt;
::ReleaseComObject(outputObject) &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''PrintAttributes'''和作为'''inputIdentifier'''参数的&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;变量标识符以及作为'''outputIdentifier'''参数的'''Cost'''变量一起使用。如下所示通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::GetObjectByName/zh|GetObjectByName]]函数提取相应对象：&amp;lt;tt&amp;gt;&lt;br /&gt;
:inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取成功，将返回一个[[CAObject/zh|CAObject]]类型对象。如果使用'''[[CAObject/zh|CAObject]]'''的函数，参考[[CAObject/zh|SendCommand(command)]]，可以获得一个[[CAObject/zh|CAObject]]的完整函数列表。如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取失败，返回值为&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;。代码应该检查以确保[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取的结果是有效的。如果找不到，可使用[[CAEngine/zh|CAEngine]]的 [[CAEngine::ErrorCode/zh|ErrorCode]]和 [[CAEngine::ErrorText/zh|ErrorText]]属性获取错误信息。例如：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Set inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:If inputObject Is Nothing Then &lt;br /&gt;
::MsgBox(“This error from GetObjectByName occurred: “&amp;amp; _ vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &amp;amp; “:” &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) &lt;br /&gt;
:Else &lt;br /&gt;
::'inputObject valid &lt;br /&gt;
:End If&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===获取对象属性===&lt;br /&gt;
每一个Analytica对象都有一组属性，例如[[identifier|标识符]]、[[title|名称]]、[[description| 描述]]和[[class|类型]]。你可以使用[[CAObject::GetAttribute/zh|GetAttribute]]函数来获去Analytica对象的属性。例如，如要获取'''inputObject'''的定义（当前为cost）：&amp;lt;tt&amp;gt;&lt;br /&gt;
:definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh|GetAttribute]](&amp;quot;[[Definition|定义]]&amp;quot;) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt; 中，&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;的定义为&amp;quot;&amp;lt;tt&amp;gt;[[Normal]](30M, 3M)&amp;lt;/tt&amp;gt;&amp;quot; ，我们将它储存在'''definitionAttrInput'''当中。.&lt;br /&gt;
&lt;br /&gt;
===计算对象和检索结果===&lt;br /&gt;
使用[[CAObject/zh|CAObject]]的[[CAObject::Result/zh|Result]]或[[CAObject::ResultTable/zh|ResultTable]]方法来获取变量的值。如果有必要的话，ADE先自动计算变量。如果你确定结果为基元（只有一个元素），使用[[CAObject::Result/zh|Result]]方法。否则使用[[CAObject::ResultTable/zh|ResultTable]]，检索结果为一个''数组''。基元结果当作一个特殊数组案例来处理，没有维度的数组。如果值为基元[[CATable::AtomicValue/zh|AtomicValue]]方法将返回一个数字或者字符串单一值。 &lt;br /&gt;
&lt;br /&gt;
默认情况下，[[CAObject::Result/zh|Result]]和[[CAObject::ResultTable/zh|ResultTable]]返回结果的中值，也就是说，ADE以确定性方式计算结果。对于一个概率值，将[[CAObject/zh|CAObject]]的[[CAObject::ResultType/zh|ResultType]]属性设置为想要的不确定性视图——Mean（平均值） Sample（样本）、PDF（概率密度函数）、CDF（累计分布函数）、Confidence bands（置信带）、或者Statistics（统计数据）详情请参考[[CAObject::ResultType/zh|ResultType]]。我们通过如下的方式获取outputObject 输出对象 的值：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]] &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
结果为一个[[CATable/zh|CATable]]对象，允许我们访问一个表格中的单个元素。 &lt;br /&gt;
&lt;br /&gt;
如果你通过调用[[CAObject::Result/zh|Result]]来获取一个数组（或者表格）的值，将返回数组为一个字符串，列出索引和元素，以逗号隔开。通常使用[[CAObject::ResultTable/zh|ResultTable]]更加简单，这样你没有必要从字符串中解析表格的元素。&lt;br /&gt;
&lt;br /&gt;
===获取表格索引元素===&lt;br /&gt;
一个Analytica表格包含0个或者多个索引。如果包含一个索引，那么该表格是1维表格；如果有2个索引，说他是2维表格，依此类推。0维度表格包含一个“单一基元”（或标量）值。你可以使用CATable的[[CATable::NumDims/zh|NumDims]]获取表格的维数（也就是索引数）。要想获取表格的单个索引，可使用[[CATable/zh|CATable]]的 [[CATable::IndexNames/zh|IndexNames]]和 [[CATable::GetIndexObject/zh|GetIndexObject]]函数。 &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''PrintResultTable'''函数说明了这两个函数的使用。从'''PrintAttributes'''中调用'''PrintResultTable'''，执行打印'''TestTxc'''中的表格的实际工作（为了简洁起见，我们只给出了关联ADE的该函数部分）。&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Public Sub PrintResultTable(ByRef resultTable As CATable, ByRef inputIdentifier As String, ByRef definitionAttrInput As String, ByRef outputIdentifier As String) &lt;br /&gt;
::Dim theIndexName, theTableName As String &lt;br /&gt;
::Dim theIndexElement As String &lt;br /&gt;
::Dim theTableElement &lt;br /&gt;
::Dim theIndexObj As [[CAIndex/zh|CAIndex]]&lt;br /&gt;
::Dim numEls As Integer &lt;br /&gt;
::Dim spaces, i As Integer &lt;br /&gt;
::Dim lenStr As Short &lt;br /&gt;
::Dim OutputStr As Short &lt;br /&gt;
::Dim spaceString, underlineString As String &lt;br /&gt;
::... &lt;br /&gt;
::theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1) &lt;br /&gt;
::theTableName = resultTable.[[CATable::Name/zh|Name]] &lt;br /&gt;
::theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName) &lt;br /&gt;
::numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
::... &lt;br /&gt;
::For i = 1 To numEls &lt;br /&gt;
:::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
:::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
:::... &lt;br /&gt;
::Next i &lt;br /&gt;
::InformationPane.Text = outputString &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
通过'''PrintResultTable'''获取一个表格的索引方法如下：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1)&lt;br /&gt;
:theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
我们通过使用[[CATable/zh|CATable]]的[[CATable::IndexNames/zh|IndexNames]]函数获取第一个索引的名字。我们将它传递给[[CATable/zh|CATable]]的[[CATable::GetIndexObject/zh|GetIndexObject]]函数以获取表示我们的索引的[[CAIndex/zh|CAIndex]]。该自动化对象返回其相应索引的相关信息。如果此函数调用失败，将返回&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;信息。在此情况下，使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]] 函数找出原因。&lt;br /&gt;
&lt;br /&gt;
==从CATable和CAIndex中获取信息==&lt;br /&gt;
[[PrintResultTable]]说明了如何从[[CATable/zh| CATable]]和[[CAIndex/zh|CAIndex]] 对象获取信息。该代码获取'''Cost'''表格的索引和表格元素：&lt;br /&gt;
: &amp;lt;tt&amp;gt;&lt;br /&gt;
:numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
:For i = 1 To numEls &lt;br /&gt;
::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
::... &lt;br /&gt;
:Next i &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[CAIndex/zh|CAIndex]]的[[CAIndex::IndexElements/zh|IndexElements]]属性返回第一个索引中的元素个数。[[CAIndex/zh|CAIndex]]的[[CAIndex::GetValueByNumber/zh|GetValueByNumber]]函数获取单个索引元素。 &lt;br /&gt;
&lt;br /&gt;
我们通过传递表格中元素的坐标，使用  [[CATable/zh|CATable]]的[[CATable::GetDataByElements/zh|GetDataByElements]]函数获取'''Cost'''表格对象的单个表格元素'''resultTable'''。 &lt;br /&gt;
&lt;br /&gt;
当我检索 [[CATable/zh|CATable]]对象中单个元素（'''resultTable'''）的时候，我们利用了该表格是一维的事实。因此，我们只需要传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个单一数（这个数代表表格中的位置）。但是，如果我们处理两个或者更多维度，我们必须传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个数组函数，并且指明我们要检索的表格元素的位置。因此，如果我们不想检索一个二维数组的position (4,3)位置的元素，我们可以这样写：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Dim W as Variant 'return element &lt;br /&gt;
:Dim IndexPtrs(1 To 2) As Variant 'position in table &lt;br /&gt;
::... &lt;br /&gt;
:IndexPtrs(1) = 4 &lt;br /&gt;
:IndexPtrs(2) = 3 &lt;br /&gt;
:W = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](IndexPtrs) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==控制基元值格式==&lt;br /&gt;
[[CATable/zh|CATable]]中的每个基元值可以是一个数、一个字符串，或者其它一些基本类型（''例如''：[[Null|空值]]、[[Undefined|未定义]]、[[Reference|参考]]，或 [[Handle|句柄]]。通过说明类型和值，它们作为''变体''被返回，这是一种Visual Basic能读懂的数据结构。[[CATable/zh|CATable]]的[[CATable::RenderingStyle|RenderingStyle]]属性控制Analytica基础值是如何映射到Visual Basic变体的。 &lt;br /&gt;
&lt;br /&gt;
例如：可以通过使用Analytica 模型的数字格式设置将一个数值返回成一个数字或者字符串。如果被指定格式，有一个选线控制是截断数字的位数，还是精确返回。 &lt;br /&gt;
&lt;br /&gt;
子程序[[PrintResultTable/zh|PrintResultTable]]在&amp;lt;tt&amp;gt;frmMain.vb&amp;lt;/tt&amp;gt;中载入,其渲染风格直接指明：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::NumberAsText/zh|NumberAsText]] = True &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::FullPrecision/zh|FullPrecision]] = False &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::StringQuotes/zh|StringQuotes]] = 2 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
第一行指明数值应该根据与结果对象有关的数字格式被格式化为文本。例如在其程序输出中，我们将看到&amp;lt;tt&amp;gt;30.103M&amp;lt;/tt&amp;gt;，而非&amp;lt;tt&amp;gt;30102995.6639812&amp;lt;/tt&amp;gt;，如果我们让Visual Basic将数值串联我们的结果字符串，将显示该结果。在此事件中，一个值为字符串的单元格出现在结果中，返回值将明确带双引号。对于[[CARenderingStyle/zh|CARenderingStyle]]对象中的所有可用属性，请参考[[CARenderingStyle/zh|CARenderingStyle]]。&lt;br /&gt;
&lt;br /&gt;
===其它访问表格的方式===&lt;br /&gt;
有几种访问多维表格[[CATable/zh|CATable]]中元素的方式。每一种都有可能在特定的场合使用起来比较方便。 &lt;br /&gt;
&lt;br /&gt;
第一种方式就是使用[[CATable/zh | CATable]]的 [[CATable::GetDataByElements/zh|GetDataByElements]]或[[CATable::GetDataByLabels/zh|GetDataByLabels]]方法，上面代码示例中有显示。在此情况下，利用你想获取的基元值的单元格位置。 &lt;br /&gt;
&lt;br /&gt;
第二种方式就是使用[[CATable/zh|CATable]][[CATable::Slice/zh|Slice]]或[[CATable::Subscript/zh | Subscript]]方法获取一个少一个维度的新[[CATable/zh|CATable]]对象。通过重复减少维度，最终将获得0维度，这时你将获得一个单一基元值。此时，[[CATable/zh|CATable]]的[[CATable::AtomicValue/zh|AtomicValue]]方法返回该值 。[[CATable::AtomicValue/zh|AtomicValue]]方法是唯一获取一个标值的方法（因为没有坐标位置）。如果你需要建立完整结果其中一个切片的图形图像，必须使用此方法。 &lt;br /&gt;
&lt;br /&gt;
第三种方式就是使用[[CATable/zh|CATable]]的[[CATable::GetSafeArray/zh|GetSafeArray]]方法，将多维数组转化成一个''安全数组''（或者一个.NET数组）。你可以在使用VB或者其它.NET语言直接处理多维数组。因为对于Analytica维度没有固定顺序，但是安全数组和.NET数组有一个明确的顺序，你必须先使用[[CATable/zh|CATable]]对象的[[CATable::SetIndexOrder/zh|SetIndexOrder]]方法在调用[[CATable::GetSafeArray/zh|GetSafeArray]]之前指明维度的顺序。注意如果你知道你的数组是一维的，那就没必要了。&lt;br /&gt;
&lt;br /&gt;
===修改对象===&lt;br /&gt;
一个自定义用户程序通常从一个用户或者其它外部源获取输入，以便转化成Analytica模型中的输入变量。你可以设定输入变量的定义或者通过使用定义表格来这样做。 &lt;br /&gt;
&lt;br /&gt;
'''TestTxc''' 说明了如何修改'''Pop_exp'''定义，此模型是一个影响结果变量Cost的模型输入。要想在该示例中设定该定义，从主菜单上选择'''File &amp;gt; Change Population'''。将出现一个对话框，如下图所示：&lt;br /&gt;
&lt;br /&gt;
[[File:RedefiningtheVariableDefinition.jpg|400px/zh|文件：RedefiningtheVariableDefinition.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
在信息栏中输入一个新定义并点击'''Ok'''确认。主窗口将显示一个新的Cost值。当点击该对话框中的'''Ok'''按钮时，调用了&amp;lt;tt&amp;gt;ChangeDef.frm&amp;lt;/tt&amp;gt;函数，然后调用[[PrintAttributes/zh|PrintAttributes]]函数打印&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果。&lt;br /&gt;
&lt;br /&gt;
此函数类似于：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Private Sub OkButton_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles OkButton.Click &lt;br /&gt;
::Dim errorText As String&lt;br /&gt;
::Dim pop_exp_Object As [[CAObject/zh|CAObject]] &lt;br /&gt;
::Dim errorCode As Short &lt;br /&gt;
::Dim errorString As String &lt;br /&gt;
::newDefinition = PopExposedDef.Text &lt;br /&gt;
::pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
::pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]](&amp;quot;[[Definition]]&amp;quot;, newDefinition) &lt;br /&gt;
::errorCode = adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &lt;br /&gt;
::If errorCode &amp;lt;&amp;gt; 0 Then &lt;br /&gt;
:::MsgBox(&amp;quot;This error occurred while processing your definition: &amp;quot; &amp;amp; vbCrLf &amp;amp; vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) :::PopExposedDef.Focus()&lt;br /&gt;
::Else&lt;br /&gt;
:::Me.Close() &lt;br /&gt;
:::frmMain.DefInstance.PrintAttributes(&amp;quot;Pop_exp&amp;quot;, &amp;quot;Cost&amp;quot;) &lt;br /&gt;
::End If &lt;br /&gt;
::ReleaseComObject(pop_exp_Object) &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
该函数抓取了输入到'''New Definition''' 新定义给'''Population Exposed'''栏，并通过使用[[CAObject/zh|CAObject]]对象中的[[CAObject::SetAttribute/zh|SetAttribute]]函数将它设置给&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;对象。然后调用[[PrintAttributes/zh|PrintAttributes]]，以计算&amp;lt;tt&amp;gt;Cost object&amp;lt;/tt&amp;gt;，并打印新的结果。要想给变量&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;设定一个新定义，我们可以为&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;获取[[CAObject/zh|CAObject]]对象，然后将其定义设置成用户输入的定义。通过使用下面的代码来实现：&lt;br /&gt;
:pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
:pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]]( &amp;quot;[[Definition]]&amp;quot;, newDefinition )&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
无论什么时候调用[[CAObject::SetAttribute/zh|SetAttribute]]，都应该检查[[CAEngine/zh|CAEngine]]自动化对象（'''adeEngine'''）的[[CAEngine::ErrorCode/zh|ErrorCode]]，以免它的定义是非法的。尝试一下输入一个新定义，比如&amp;lt;code&amp;gt;[[Uniform]](25M,35M)&amp;lt;/code&amp;gt;，然后点击'''Ok'''。当&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;的定义被改变时， &amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果由ADE重新计算，此时'''ResultTable'''接下来调用给Cost变量（在应用程序窗口重新显示时）。&lt;br /&gt;
&lt;br /&gt;
使用ADE绘图&lt;br /&gt;
&lt;br /&gt;
通过Analytica 4.6使用相同的绘图引擎，你可以建立一个图表或者图形以显示一个数组值或者不确定值结果。在ADE4.6中，你可以使用 [[CATable/zh|CATable]]的[[CATable::GraphToFile/zh|GraphToFile]]和[[CATable::GraphToStream/zh|GraphToStream]]方法。图形可以以几种可能的图像格式返回，例如'''image/png'''、 '''image/bmp'''或者 '''image/jpeg'''。 &lt;br /&gt;
&lt;br /&gt;
从可用图形选项中选择的最简单方式就是使用Analytica打开你的模型。你可以实验设置各种默认设置或者替代选择的变量，看它们是如何工作的。但你选择了你想设置的选项，保存模型。当为每一个生成结果图形时，ADE将使用这些设置。 &lt;br /&gt;
&lt;br /&gt;
对于更高维度的结果，可能需要做一些必要工作，以便选择将绘制结果的切片和具体的轴（也就是相对于图例哪个维度作为X轴）。[[CATable/zh|CATable]]的[[CATable::Subscript/zh|Subscript]]或[[CATable::Slice/zh|Slice]]方法可以用来控制轴选择特殊的切片用来绘制，能够用来控制轴。详情请参考[[CATable/zh|CATable]]。在我们的&amp;lt;tt&amp;gt;Tutorial.NET&amp;lt;/tt&amp;gt;示例中，我们有一个一维结果（&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;），因此我们没有必要担心截取或者绕轴旋转。 &lt;br /&gt;
&lt;br /&gt;
[[CATable::GraphToStream/zh|GraphToStream]]方法被用来从ADE中直接转化图形图形到一个用户界面中。使用[[CATable::GraphToStream/zh|GraphToStream]]比起使用[[CATable::GraphToFile/zh|GraphToFile]]来要稍微复杂一点，因为[[CATable::GraphToFile/zh|GraphToFile]]除了需要文件名以外还需要其它一些信息，以便编写图形。要使用[[CATable::GraphToStream/zh|GraphToStream]]，我们必须在内存内设置一个流，允许ADE写入该留，然后从该留重建。因为.NET流和COM流不兼容，你必须使用ADE一同提供的[[StreamConnector]]类型.&amp;lt;tt&amp;gt;frmMain&amp;lt;/tt&amp;gt; 中的'''GraphResult_Click'''子程序演示了[[CATable::GraphToStream/zh|GraphToStream]]的使用。从主应用程序窗口选择 '''Graph Result'''菜单选项，结果将出现在一个如下所示的图形当中：&lt;br /&gt;
&lt;br /&gt;
[[File:resultgraph.jpg/zh|文件：resultgraph.jpg]]&lt;br /&gt;
&lt;br /&gt;
==结论==&lt;br /&gt;
&lt;br /&gt;
在此教程中，我们介绍了Analytica决策引擎的几个重要方面。我们看到了如何建立一个ADE服务器对象，使用ADE打开模型，获取模型中的单个对象、计算对象、获取表格中的元素，以及修改模型中的对象。但是ADE可以做的远不止这些。 &lt;br /&gt;
&lt;br /&gt;
我们希望你已经足够了解其基本特征，这样你现在才能独自开始探索更多新的高级特征。我们建议你现在开始阅读字教程的剩余部分以了解ADE能做什么。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
| [[Installation of ADE/zh|ADE 安装]] &amp;lt;- ||  [[The ADE Tutorial/zh|ADE 入门教程]] || -&amp;gt; [[Using the ADE Server/zh|使用ADE服务器]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36304</id>
		<title>The ADE Tutorial/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36304"/>
		<updated>2015-10-27T06:30:20Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南 ]]&lt;br /&gt;
&lt;br /&gt;
此教程教你如何在一个Visual Basic程序中使用Analytica决策引擎（ADE）。&lt;br /&gt;
&lt;br /&gt;
==你的第一个ADE应用程序==&lt;br /&gt;
首先先从头开始写一个简单的ADE程序，只要确认一切设置正常。按照以下步骤操作：&lt;br /&gt;
&lt;br /&gt;
test&lt;br /&gt;
&lt;br /&gt;
第一个程序执行了以下操作：&lt;br /&gt;
*建立一个名称为ADE的[[CAEngine/zh|CAEngine]]自动化对象（通过使用&amp;lt;code&amp;gt;new [[CAEngine/zh|CAEngine]]&amp;lt;/code&amp;gt;).&lt;br /&gt;
*打开Analytica模型 (通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]] 方法。&lt;br /&gt;
*显示模型名称返回[[CAEngine::OpenModel/zh|OpenModel]]的值。&lt;br /&gt;
我们将在后面的章节详细了解这些信息。&lt;br /&gt;
&lt;br /&gt;
===接下来讲什么呢?===&lt;br /&gt;
我们不会尝试在此入门教程中解释ADE的特征。本指南后面几个章节会描述这些特征。 &lt;br /&gt;
&lt;br /&gt;
从现在开始，我们我们将使用名称为&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;的示例模型。打开 Analytica安装目录下 '''Example Models'''文件夹里面的'''Risk Analysis'''文件夹便可找到&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;文件。如果你找不到，或者你安装Analytica的时候未选择安装examples（示例）文件，在ADE安装目录下面的'''Examples\Tutorial.NET'''文件家中有一个副本。 &lt;br /&gt;
&lt;br /&gt;
Txc模型演示了减少污染物TXC排放的risk-benefit （风险-效益）分析。请用Analytica打开Txc查看它是如何工作的。 &lt;br /&gt;
&lt;br /&gt;
ADE '''Examples\Tutorial.NET''' 文件夹中名称为&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;的Visual Basic.NET程序示例显示了ADE很多方面。该程序建立了一个ADE自动化对象，打开包含该对象的&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，获取变量 &amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，计算变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;，通过获取每个表格的单独组件以表格的方式打印输出变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的结果，然后改变变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义。再次获取变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的值，看一下 变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;定义的改变对变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;有什么影响。如果设置正确的话,&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;将显示在“Text Txc window”中显示的窗口。 &lt;br /&gt;
&lt;br /&gt;
应用程序显示变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义（&amp;lt;tt&amp;gt;&amp;quot;Normal (30M, 3M)&amp;quot;&amp;lt;/tt&amp;gt;），以及与&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;关联的表格，这都基于&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义。你可以通过从主菜单选择'''File &amp;gt; Change Population Exposed'''改变&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，然后查看改变对&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;表格的影响。&lt;br /&gt;
&lt;br /&gt;
[[File:TextTxcWindow.png|400px/zh | 文件：TextTxcWindow.png|400px]]&lt;br /&gt;
&lt;br /&gt;
===区分title（名称） 和 identifier（标识符）===&lt;br /&gt;
无论什么时候，一个ADE函数都需要一个变量你必须传达变量的'''''[[Identifier|标识符]]''''' ，而不是它的'''''[[Title|名称]]'''''。这可能会引起混淆，因为在Analytica影响图中一般显示每一个变量的名称。默认情况下，在你最初建立每一个对象的时候，Analytica自动根据名称建立一个标识符。用（_）代替名称中的每一个空格或者其他非字母和数字字符。 &lt;br /&gt;
&lt;br /&gt;
你可以通过点击“Control+y”（或者从Object（对象）菜单选择'''Show by identifier''' ：显示标识符） 来以标识符显示变量。对于模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;，你可以看到名称为&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;变量的标识符为 &amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;。将变量传递给ADE函数时，使用标识符很重要。如果你传递&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;，ADE无法找到变量，并且将返回一个错误。&lt;br /&gt;
&lt;br /&gt;
===从Visual Basic中建立一个ADE 对象===&lt;br /&gt;
&lt;br /&gt;
如果你还没准备好，将名称为tt&amp;gt;Examples\Tutorial\TestTxc.sln&amp;lt;/tt&amp;gt;载入到Visual Basic.NET中，查看名称为&amp;lt;tt&amp;gt;TestTxc.vb&amp;lt;/tt&amp;gt;的文件的代码。其代码看起来像：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Imports ADEW &lt;br /&gt;
:. . . &lt;br /&gt;
:Public adeEngine As [[CAEngine/zh|CAEngine]]&lt;br /&gt;
&lt;br /&gt;
:Public Sub Main() &lt;br /&gt;
::Dim exeDirectory, theModel As String &lt;br /&gt;
::Dim theModelString As String &lt;br /&gt;
::exeDirectory = VB6.GetPath &lt;br /&gt;
::theModel = exeDirectory &amp;amp; &amp;quot;\..\&amp;quot; &amp;amp; &amp;quot;Txc.ana&amp;quot; &lt;br /&gt;
::adeEngine = New [[CAEngine/zh|CAEngine]]&lt;br /&gt;
::... &lt;br /&gt;
::theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
::... &lt;br /&gt;
::frmMain.DefInstance.Show() &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在每一个文件的顶部的代码将自动化对象 '''adeEngine''' 声明为一个[[CAEngine/zh|CAEngine]] 对象。使用此对象，我们能够访问 [[CAEngine/zh|CAEngine]] 展示的所有公共函数（参考 [[ADE Server Class Reference/zh|ADE服务器类型参考]] ）&lt;br /&gt;
&lt;br /&gt;
变量&amp;lt;tt&amp;gt;adeEngine&amp;lt;/tt&amp;gt;包含我们的进程内对象 [[CAEngine/zh|CAEngine]]。如果我们想使用ADE的本地（进程外）服务器版本，我们可以将一个项目参考添加到'''Analytica Decision Engine Server 4.6 COM''' 组件并将顶部行从&amp;lt;tt&amp;gt;Imports ADEW&amp;lt;/tt&amp;gt;改成&amp;lt;tt&amp;gt;Imports ADE&amp;lt;/tt&amp;gt;即可。 &lt;br /&gt;
&lt;br /&gt;
这里是另一种获得一个先[[CAEngine/zh|CAEngine]]对象的方法。此循序不需要给项目添加参考。&amp;lt;tt&amp;gt;&lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADEW4.6.CAEngine&amp;quot;) ’ in-process &lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADE4.6.CAEngine&amp;quot;) ’ out-of-process &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果想理解使用进程内和进程外（或本地）服务器的利与弊，以及哪一种自动化服务器用于不同的场景，参考[[Using_the_Analytica_Decision_Engine_Server#In-process_vs_Out-of-process/zh | In-process vs. out-of-process]]&lt;br /&gt;
&lt;br /&gt;
===COM和 Automation 接口比较===&lt;br /&gt;
在上面的例子当中，我们使用COM接口调用ADE。在一个COM 接口中，对象 在本例中为 [[CAEngine/zh|CAEngine]] 被声明为[[CAEngine/zh|CAEngine]] ，编译器解决每一个成员函数，并且在编译时间内能探测几个明显的错误。另外，Visual Studio可以提供方法和参数类型列表当，在你编程的时候可以当做一个提示工具，在编写使用ADE程序是非常有用。COM调用比Automation调用要快一点，但是在ADE应用程序中速度差异通常不是很重要。对于ADE 4.6我们推荐使用COM结构，只要你的语言支持。&lt;br /&gt;
&lt;br /&gt;
在VB Automation中，你可以将一个对象简单声明为Object（对象），而不是像 [[CAEngine/zh|CAEngine]]、[[CAObject/zh|CAObject]]等更加具体的类型。当使用Automation调用'''ADE'''方法时，在运行时间内确定方法。在编译时间内，编译器不知道你的 '''ADE''' 对象是否有一个名称为[[CAEngine::OpenModel/zh|OpenModel]]的函数。在VB中，调用COM方法或Automation 方法的语法是相通的——唯一的不同在于对象类型是否明确被声明。&lt;br /&gt;
&lt;br /&gt;
在VC++和C#中，调用COM的语法和调用Automatio的语法不同。在这些情况下，COM要方便的多，Automation能够获得相冗余。然而，同样的语言，包括VBScript和其他脚本语言，只支持Automation不支持COM。&lt;br /&gt;
&lt;br /&gt;
===监视Process（进程）===&lt;br /&gt;
当使用进程外ADE服务器时，你的代码必须在终止时释放[[CAEngine/zh|CAEngine]]COM对象。当最终[[CAEngine/zh|CAEngine]]使用被释放是，ADE.exe 进程自动终止。到目前为止所看到的代码，VB语言在达到程序末端时，自动处理释放对象。但是，当你调试你的代码是，你可以提前终止你的程序来修复bug，你的程序可能被Task Manager（任务管理器）终止，或者你自己的代码也可能奔溃，导致你的程序进程在它有机会释放对象之前终止。应为COM对象从来不会被释放，ADE.exe进程不知道它是否在使用中，你可能获得ADE.exe 僵尸进程。 &lt;br /&gt;
&lt;br /&gt;
为了避免这种情况发生，一种好的习惯就是在调用[[CAEngine/zh|CAEngine]]实例后 立即调用[[CAEngine::MonitorProcess/zh|CAEngine::MonitorProcess]]。通过这种方式，ADE能够得知哪一个进程正在使用它，同时将设置一个线程去探测你的进程是否在ADE被完全释放前终止。如果你的程序进程没有终止，ADE进程会立即将它关闭，消除了僵尸ADE进程的堆积。 &lt;br /&gt;
&lt;br /&gt;
要从一个.NET应用程序获得进程ID，使用System.Diagnostics.Process namespace中的'''GetCurrentProcess().Id''' 。在其他语言中，你可以使用Windows SDK 的'''GetProcessId( )'''函数。 &lt;br /&gt;
&lt;br /&gt;
'''[[CAEngine::MonitorProcess/zh|MonitorProcess]]()''' 只能用来监视运行ADE进程的同一台计算机的进程，一次当通过DCOM运行ADE时不能使用。当使用进程内ADEW服务器时没有必要使用。&lt;br /&gt;
&lt;br /&gt;
==使用ADE打开模型==&lt;br /&gt;
我们现在打开&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，显示我们的应用程序主窗口。使用以下调用：tt&amp;gt;&lt;br /&gt;
:theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
:frmMain.DefInstance.Show &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]]函数打开模型。如果成功的话，变量&amp;lt;tt&amp;gt;theModelString&amp;lt;/tt&amp;gt;将包含模型的名字。否则，将包含一个空的串。虽然由于为了简介的缘故，我们没有这样做，但是你应该检查从[[CAEngine::OpenModel/zh|OpenModel]]函数返回的是不是一个空的串。如果是，说明在你打开的模型中存在一个错误。你可以使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/z |ErrorText]]属性找出是哪种错误 （&amp;lt;tt&amp;gt;adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] 和adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]&amp;lt;/tt&amp;gt;）。&lt;br /&gt;
&lt;br /&gt;
==从Analytica模型中检索对象==&lt;br /&gt;
下一步就是从我们的模型中检索对象（变量、模块、函数等），以便我们能获取他们的属性（[[definition|定义]]、[[title|名称]]、[[class|类型]]等等 ）。我们的示例模型（&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;）操作&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;和&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;对象。尤其是，修改&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;可以查看这是如何影响&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt; 对象。&lt;br /&gt;
&lt;br /&gt;
我们的&amp;lt;tt&amp;gt;TxcTest.vbproj&amp;lt;/tt&amp;gt; （&amp;lt;tt&amp;gt;TxcText.sln&amp;lt;/tt&amp;gt;）项目中的&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;文件里的 '''PrintAttributes''' 函数演示了如何检索对象。该函数首先被&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''Form_Load''' 函数调用，当应用程序启动后，可以显示'''Cost'''表格。当然无论什么时候，只要我们想输出'''Cost'''表格的当前值，都可以调用。该函数如下所示：&lt;br /&gt;
:Public Sub PrintAttributes(ByRef inputIdentifier As String, ByRef  outputIdentifier As String) &lt;br /&gt;
::Dim inputObject, outputObject As [[CAObject/zh|CAObject]]&lt;br /&gt;
::Dim resultTable As [[CATable/zh|CATable]]&lt;br /&gt;
::Dim definitionAttrInput As String &lt;br /&gt;
::inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
::outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier) &lt;br /&gt;
::definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;definition&amp;quot;) &lt;br /&gt;
::resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]]&lt;br /&gt;
::Call PrintResultTable(resultTable, inputIdentifier, definitionAttrInput, outputIdentifier) &lt;br /&gt;
::ReleaseComObject(resultTable) &lt;br /&gt;
::ReleaseComObject(inputObject) &lt;br /&gt;
::ReleaseComObject(outputObject) &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''PrintAttributes'''和作为'''inputIdentifier'''参数的&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;变量标识符以及作为'''outputIdentifier'''参数的'''Cost'''变量一起使用。如下所示通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::GetObjectByName/zh|GetObjectByName]]函数提取相应对象：&amp;lt;tt&amp;gt;&lt;br /&gt;
:inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取成功，将返回一个[[CAObject/zh|CAObject]]类型对象。如果使用'''[[CAObject/zh|CAObject]]'''的函数，参考[[CAObject/zh|SendCommand(command)]]，可以获得一个[[CAObject/zh|CAObject]]的完整函数列表。如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取失败，返回值为&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;。代码应该检查以确保[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取的结果是有效的。如果找不到，可使用[[CAEngine/zh|CAEngine]]的 [[CAEngine::ErrorCode/zh|ErrorCode]]和 [[CAEngine::ErrorText/zh|ErrorText]]属性获取错误信息。例如：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Set inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:If inputObject Is Nothing Then &lt;br /&gt;
::MsgBox(“This error from GetObjectByName occurred: “&amp;amp; _ vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &amp;amp; “:” &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) &lt;br /&gt;
:Else &lt;br /&gt;
::'inputObject valid &lt;br /&gt;
:End If&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===获取对象属性===&lt;br /&gt;
每一个Analytica对象都有一组属性，例如[[identifier|标识符]]、[[title|名称]]、[[description| 描述]]和[[class|类型]]。你可以使用[[CAObject::GetAttribute/zh|GetAttribute]]函数来获去Analytica对象的属性。例如，如要获取'''inputObject'''的定义（当前为cost）：&amp;lt;tt&amp;gt;&lt;br /&gt;
:definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh|GetAttribute]](&amp;quot;[[Definition|定义]]&amp;quot;) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt; 中，&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;的定义为&amp;quot;&amp;lt;tt&amp;gt;[[Normal]](30M, 3M)&amp;lt;/tt&amp;gt;&amp;quot; ，我们将它储存在'''definitionAttrInput'''当中。.&lt;br /&gt;
&lt;br /&gt;
===计算对象和检索结果===&lt;br /&gt;
使用[[CAObject/zh|CAObject]]的[[CAObject::Result/zh|Result]]或[[CAObject::ResultTable/zh|ResultTable]]方法来获取变量的值。如果有必要的话，ADE先自动计算变量。如果你确定结果为基元（只有一个元素），使用[[CAObject::Result/zh|Result]]方法。否则使用[[CAObject::ResultTable/zh|ResultTable]]，检索结果为一个''数组''。基元结果当作一个特殊数组案例来处理，没有维度的数组。如果值为基元[[CATable::AtomicValue/zh|AtomicValue]]方法将返回一个数字或者字符串单一值。 &lt;br /&gt;
&lt;br /&gt;
默认情况下，[[CAObject::Result/zh|Result]]和[[CAObject::ResultTable/zh|ResultTable]]返回结果的中值，也就是说，ADE以确定性方式计算结果。对于一个概率值，将[[CAObject/zh|CAObject]]的[[CAObject::ResultType/zh|ResultType]]属性设置为想要的不确定性视图——Mean（平均值） Sample（样本）、PDF（概率密度函数）、CDF（累计分布函数）、Confidence bands（置信带）、或者Statistics（统计数据）详情请参考[[CAObject::ResultType/zh|ResultType]]。我们通过如下的方式获取outputObject 输出对象 的值：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]] &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
结果为一个[[CATable/zh|CATable]]对象，允许我们访问一个表格中的单个元素。 &lt;br /&gt;
&lt;br /&gt;
如果你通过调用[[CAObject::Result/zh|Result]]来获取一个数组（或者表格）的值，将返回数组为一个字符串，列出索引和元素，以逗号隔开。通常使用[[CAObject::ResultTable/zh|ResultTable]]更加简单，这样你没有必要从字符串中解析表格的元素。&lt;br /&gt;
&lt;br /&gt;
===获取表格索引元素===&lt;br /&gt;
一个Analytica表格包含0个或者多个索引。如果包含一个索引，那么该表格是1维表格；如果有2个索引，说他是2维表格，依此类推。0维度表格包含一个“单一基元”（或标量）值。你可以使用CATable的[[CATable::NumDims/zh|NumDims]]获取表格的维数（也就是索引数）。要想获取表格的单个索引，可使用[[CATable/zh|CATable]]的 [[CATable::IndexNames/zh|IndexNames]]和 [[CATable::GetIndexObject/zh|GetIndexObject]]函数。 &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''PrintResultTable'''函数说明了这两个函数的使用。从'''PrintAttributes'''中调用'''PrintResultTable'''，执行打印'''TestTxc'''中的表格的实际工作（为了简洁起见，我们只给出了关联ADE的该函数部分）。&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Public Sub PrintResultTable(ByRef resultTable As CATable, ByRef inputIdentifier As String, ByRef definitionAttrInput As String, ByRef outputIdentifier As String) &lt;br /&gt;
::Dim theIndexName, theTableName As String &lt;br /&gt;
::Dim theIndexElement As String &lt;br /&gt;
::Dim theTableElement &lt;br /&gt;
::Dim theIndexObj As [[CAIndex/zh|CAIndex]]&lt;br /&gt;
::Dim numEls As Integer &lt;br /&gt;
::Dim spaces, i As Integer &lt;br /&gt;
::Dim lenStr As Short &lt;br /&gt;
::Dim OutputStr As Short &lt;br /&gt;
::Dim spaceString, underlineString As String &lt;br /&gt;
::... &lt;br /&gt;
::theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1) &lt;br /&gt;
::theTableName = resultTable.[[CATable::Name/zh|Name]] &lt;br /&gt;
::theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName) &lt;br /&gt;
::numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
::... &lt;br /&gt;
::For i = 1 To numEls &lt;br /&gt;
:::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
:::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
:::... &lt;br /&gt;
::Next i &lt;br /&gt;
::InformationPane.Text = outputString &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
通过'''PrintResultTable'''获取一个表格的索引方法如下：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1)&lt;br /&gt;
:theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
我们通过使用[[CATable/zh|CATable]]的[[CATable::IndexNames/zh|IndexNames]]函数获取第一个索引的名字。我们将它传递给[[CATable/zh|CATable]]的[[CATable::GetIndexObject/zh|GetIndexObject]]函数以获取表示我们的索引的[[CAIndex/zh|CAIndex]]。该自动化对象返回其相应索引的相关信息。如果此函数调用失败，将返回&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;信息。在此情况下，使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]] 函数找出原因。&lt;br /&gt;
&lt;br /&gt;
==从CATable和CAIndex中获取信息==&lt;br /&gt;
[[PrintResultTable]]说明了如何从[[CATable/zh| CATable]]和[[CAIndex/zh|CAIndex]] 对象获取信息。该代码获取'''Cost'''表格的索引和表格元素：&lt;br /&gt;
: &amp;lt;tt&amp;gt;&lt;br /&gt;
:numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
:For i = 1 To numEls &lt;br /&gt;
::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
::... &lt;br /&gt;
:Next i &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[CAIndex/zh|CAIndex]]的[[CAIndex::IndexElements/zh|IndexElements]]属性返回第一个索引中的元素个数。[[CAIndex/zh|CAIndex]]的[[CAIndex::GetValueByNumber/zh|GetValueByNumber]]函数获取单个索引元素。 &lt;br /&gt;
&lt;br /&gt;
我们通过传递表格中元素的坐标，使用  [[CATable/zh|CATable]]的[[CATable::GetDataByElements/zh|GetDataByElements]]函数获取'''Cost'''表格对象的单个表格元素'''resultTable'''。 &lt;br /&gt;
&lt;br /&gt;
当我检索 [[CATable/zh|CATable]]对象中单个元素（'''resultTable'''）的时候，我们利用了该表格是一维的事实。因此，我们只需要传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个单一数（这个数代表表格中的位置）。但是，如果我们处理两个或者更多维度，我们必须传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个数组函数，并且指明我们要检索的表格元素的位置。因此，如果我们不想检索一个二维数组的position (4,3)位置的元素，我们可以这样写：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Dim W as Variant 'return element &lt;br /&gt;
:Dim IndexPtrs(1 To 2) As Variant 'position in table &lt;br /&gt;
::... &lt;br /&gt;
:IndexPtrs(1) = 4 &lt;br /&gt;
:IndexPtrs(2) = 3 &lt;br /&gt;
:W = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](IndexPtrs) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==控制基元值格式==&lt;br /&gt;
[[CATable/zh|CATable]]中的每个基元值可以是一个数、一个字符串，或者其它一些基本类型（''例如''：[[Null|空值]]、[[Undefined|未定义]]、[[Reference|参考]]，或 [[Handle|句柄]]。通过说明类型和值，它们作为''变体''被返回，这是一种Visual Basic能读懂的数据结构。[[CATable/zh|CATable]]的[[CATable::RenderingStyle|RenderingStyle]]属性控制Analytica基础值是如何映射到Visual Basic变体的。 &lt;br /&gt;
&lt;br /&gt;
例如：可以通过使用Analytica 模型的数字格式设置将一个数值返回成一个数字或者字符串。如果被指定格式，有一个选线控制是截断数字的位数，还是精确返回。 &lt;br /&gt;
&lt;br /&gt;
子程序[[PrintResultTable/zh|PrintResultTable]]在&amp;lt;tt&amp;gt;frmMain.vb&amp;lt;/tt&amp;gt;中载入,其渲染风格直接指明：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::NumberAsText/zh|NumberAsText]] = True &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::FullPrecision/zh|FullPrecision]] = False &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::StringQuotes/zh|StringQuotes]] = 2 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
第一行指明数值应该根据与结果对象有关的数字格式被格式化为文本。例如在其程序输出中，我们将看到&amp;lt;tt&amp;gt;30.103M&amp;lt;/tt&amp;gt;，而非&amp;lt;tt&amp;gt;30102995.6639812&amp;lt;/tt&amp;gt;，如果我们让Visual Basic将数值串联我们的结果字符串，将显示该结果。在此事件中，一个值为字符串的单元格出现在结果中，返回值将明确带双引号。对于[[CARenderingStyle/zh|CARenderingStyle]]对象中的所有可用属性，请参考[[CARenderingStyle/zh|CARenderingStyle]]。&lt;br /&gt;
&lt;br /&gt;
===其它访问表格的方式===&lt;br /&gt;
有几种访问多维表格[[CATable/zh|CATable]]中元素的方式。每一种都有可能在特定的场合使用起来比较方便。 &lt;br /&gt;
&lt;br /&gt;
第一种方式就是使用[[CATable/zh | CATable]]的 [[CATable::GetDataByElements/zh|GetDataByElements]]或[[CATable::GetDataByLabels/zh|GetDataByLabels]]方法，上面代码示例中有显示。在此情况下，利用你想获取的基元值的单元格位置。 &lt;br /&gt;
&lt;br /&gt;
第二种方式就是使用[[CATable/zh|CATable]][[CATable::Slice/zh|Slice]]或[[CATable::Subscript/zh | Subscript]]方法获取一个少一个维度的新[[CATable/zh|CATable]]对象。通过重复减少维度，最终将获得0维度，这时你将获得一个单一基元值。此时，[[CATable/zh|CATable]]的[[CATable::AtomicValue/zh|AtomicValue]]方法返回该值 。[[CATable::AtomicValue/zh|AtomicValue]]方法是唯一获取一个标值的方法（因为没有坐标位置）。如果你需要建立完整结果其中一个切片的图形图像，必须使用此方法。 &lt;br /&gt;
&lt;br /&gt;
第三种方式就是使用[[CATable/zh|CATable]]的[[CATable::GetSafeArray/zh|GetSafeArray]]方法，将多维数组转化成一个''安全数组''（或者一个.NET数组）。你可以在使用VB或者其它.NET语言直接处理多维数组。因为对于Analytica维度没有固定顺序，但是安全数组和.NET数组有一个明确的顺序，你必须先使用[[CATable/zh|CATable]]对象的[[CATable::SetIndexOrder/zh|SetIndexOrder]]方法在调用[[CATable::GetSafeArray/zh|GetSafeArray]]之前指明维度的顺序。注意如果你知道你的数组是一维的，那就没必要了。&lt;br /&gt;
&lt;br /&gt;
===修改对象===&lt;br /&gt;
一个自定义用户程序通常从一个用户或者其它外部源获取输入，以便转化成Analytica模型中的输入变量。你可以设定输入变量的定义或者通过使用定义表格来这样做。 &lt;br /&gt;
&lt;br /&gt;
'''TestTxc''' 说明了如何修改'''Pop_exp'''定义，此模型是一个影响结果变量Cost的模型输入。要想在该示例中设定该定义，从主菜单上选择'''File &amp;gt; Change Population'''。将出现一个对话框，如下图所示：&lt;br /&gt;
&lt;br /&gt;
[[File:RedefiningtheVariableDefinition.jpg|400px/zh|文件：RedefiningtheVariableDefinition.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
在信息栏中输入一个新定义并点击'''Ok'''确认。主窗口将显示一个新的Cost值。当点击该对话框中的'''Ok'''按钮时，调用了&amp;lt;tt&amp;gt;ChangeDef.frm&amp;lt;/tt&amp;gt;函数，然后调用[[PrintAttributes/zh|PrintAttributes]]函数打印&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果。&lt;br /&gt;
&lt;br /&gt;
此函数类似于：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Private Sub OkButton_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles OkButton.Click &lt;br /&gt;
::Dim errorText As String&lt;br /&gt;
::Dim pop_exp_Object As [[CAObject/zh|CAObject]] &lt;br /&gt;
::Dim errorCode As Short &lt;br /&gt;
::Dim errorString As String &lt;br /&gt;
::newDefinition = PopExposedDef.Text &lt;br /&gt;
::pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
::pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]](&amp;quot;[[Definition]]&amp;quot;, newDefinition) &lt;br /&gt;
::errorCode = adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &lt;br /&gt;
::If errorCode &amp;lt;&amp;gt; 0 Then &lt;br /&gt;
:::MsgBox(&amp;quot;This error occurred while processing your definition: &amp;quot; &amp;amp; vbCrLf &amp;amp; vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) :::PopExposedDef.Focus()&lt;br /&gt;
::Else&lt;br /&gt;
:::Me.Close() &lt;br /&gt;
:::frmMain.DefInstance.PrintAttributes(&amp;quot;Pop_exp&amp;quot;, &amp;quot;Cost&amp;quot;) &lt;br /&gt;
::End If &lt;br /&gt;
::ReleaseComObject(pop_exp_Object) &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
该函数抓取了输入到'''New Definition''' 新定义给'''Population Exposed'''栏，并通过使用[[CAObject/zh|CAObject]]对象中的[[CAObject::SetAttribute/zh|SetAttribute]]函数将它设置给&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;对象。然后调用[[PrintAttributes/zh|PrintAttributes]]，以计算&amp;lt;tt&amp;gt;Cost object&amp;lt;/tt&amp;gt;，并打印新的结果。要想给变量&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;设定一个新定义，我们可以为&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;获取[[CAObject/zh|CAObject]]对象，然后将其定义设置成用户输入的定义。通过使用下面的代码来实现：&lt;br /&gt;
:pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
:pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]]( &amp;quot;[[Definition]]&amp;quot;, newDefinition )&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
无论什么时候调用[[CAObject::SetAttribute/zh|SetAttribute]]，都应该检查[[CAEngine/zh|CAEngine]]自动化对象（'''adeEngine'''）的[[CAEngine::ErrorCode/zh|ErrorCode]]，以免它的定义是非法的。尝试一下输入一个新定义，比如&amp;lt;code&amp;gt;[[Uniform]](25M,35M)&amp;lt;/code&amp;gt;，然后点击'''Ok'''。当&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;的定义被改变时， &amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果由ADE重新计算，此时'''ResultTable'''接下来调用给Cost变量（在应用程序窗口重新显示时）。&lt;br /&gt;
&lt;br /&gt;
使用ADE绘图&lt;br /&gt;
&lt;br /&gt;
通过Analytica 4.6使用相同的绘图引擎，你可以建立一个图表或者图形以显示一个数组值或者不确定值结果。在ADE4.6中，你可以使用 [[CATable/zh|CATable]]的[[CATable::GraphToFile/zh|GraphToFile]]和[[CATable::GraphToStream/zh|GraphToStream]]方法。图形可以以几种可能的图像格式返回，例如'''image/png'''、 '''image/bmp'''或者 '''image/jpeg'''。 &lt;br /&gt;
&lt;br /&gt;
从可用图形选项中选择的最简单方式就是使用Analytica打开你的模型。你可以实验设置各种默认设置或者替代选择的变量，看它们是如何工作的。但你选择了你想设置的选项，保存模型。当为每一个生成结果图形时，ADE将使用这些设置。 &lt;br /&gt;
&lt;br /&gt;
对于更高维度的结果，可能需要做一些必要工作，以便选择将绘制结果的切片和具体的轴（也就是相对于图例哪个维度作为X轴）。[[CATable/zh|CATable]]的[[CATable::Subscript/zh|Subscript]]或[[CATable::Slice/zh|Slice]]方法可以用来控制轴选择特殊的切片用来绘制，能够用来控制轴。详情请参考[[CATable/zh|CATable]]。在我们的&amp;lt;tt&amp;gt;Tutorial.NET&amp;lt;/tt&amp;gt;示例中，我们有一个一维结果（&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;），因此我们没有必要担心截取或者绕轴旋转。 &lt;br /&gt;
&lt;br /&gt;
[[CATable::GraphToStream/zh|GraphToStream]]方法被用来从ADE中直接转化图形图形到一个用户界面中。使用[[CATable::GraphToStream/zh|GraphToStream]]比起使用[[CATable::GraphToFile/zh|GraphToFile]]来要稍微复杂一点，因为[[CATable::GraphToFile/zh|GraphToFile]]除了需要文件名以外还需要其它一些信息，以便编写图形。要使用[[CATable::GraphToStream/zh|GraphToStream]]，我们必须在内存内设置一个流，允许ADE写入该留，然后从该留重建。因为.NET流和COM流不兼容，你必须使用ADE一同提供的[[StreamConnector]]类型.&amp;lt;tt&amp;gt;frmMain&amp;lt;/tt&amp;gt; 中的'''GraphResult_Click'''子程序演示了[[CATable::GraphToStream/zh|GraphToStream]]的使用。从主应用程序窗口选择 '''Graph Result'''菜单选项，结果将出现在一个如下所示的图形当中：&lt;br /&gt;
&lt;br /&gt;
[[File:resultgraph.jpg/zh|文件：resultgraph.jpg]]&lt;br /&gt;
&lt;br /&gt;
==结论==&lt;br /&gt;
&lt;br /&gt;
在此教程中，我们介绍了Analytica决策引擎的几个重要方面。我们看到了如何建立一个ADE服务器对象，使用ADE打开模型，获取模型中的单个对象、计算对象、获取表格中的元素，以及修改模型中的对象。但是ADE可以做的远不止这些。 &lt;br /&gt;
&lt;br /&gt;
我们希望你已经足够了解其基本特征，这样你现在才能独自开始探索更多新的高级特征。我们建议你现在开始阅读字教程的剩余部分以了解ADE能做什么。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
| [[Installation of ADE/zh|ADE 安装]] &amp;lt;- ||  [[The ADE Tutorial/zh|ADE 入门教程]] || -&amp;gt; [[Using the ADE Server/zh|使用ADE服务器]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36302</id>
		<title>The ADE Tutorial/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36302"/>
		<updated>2015-10-27T06:27:46Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南 ]]&lt;br /&gt;
&lt;br /&gt;
此教程教你如何在一个Visual Basic程序中使用Analytica决策引擎（ADE）。&lt;br /&gt;
&lt;br /&gt;
==你的第一个ADE应用程序==&lt;br /&gt;
首先先从头开始写一个简单的ADE程序，只要确认一切设置正常。按照以下步骤操作：&lt;br /&gt;
&lt;br /&gt;
test&lt;br /&gt;
&lt;br /&gt;
第一个程序执行了以下操作：&lt;br /&gt;
*建立一个名称为ADE的[[CAEngine/zh|CAEngine]]自动化对象（通过使用&amp;lt;code&amp;gt;new [[CAEngine/zh|CAEngine]]&amp;lt;/code&amp;gt;).&lt;br /&gt;
*打开Analytica模型 (通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]] 方法。&lt;br /&gt;
*显示模型名称返回[[CAEngine::OpenModel/zh|OpenModel]]的值。&lt;br /&gt;
我们将在后面的章节详细了解这些信息。&lt;br /&gt;
&lt;br /&gt;
===接下来讲什么呢?===&lt;br /&gt;
我们不会尝试在此入门教程中解释ADE的特征。本指南后面几个章节会描述这些特征。 &lt;br /&gt;
&lt;br /&gt;
从现在开始，我们我们将使用名称为&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;的示例模型。打开 Analytica安装目录下 '''Example Models'''文件夹里面的'''Risk Analysis'''文件夹便可找到&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;文件。如果你找不到，或者你安装Analytica的时候未选择安装examples（示例）文件，在ADE安装目录下面的'''Examples\Tutorial.NET'''文件家中有一个副本。 &lt;br /&gt;
&lt;br /&gt;
Txc模型演示了减少污染物TXC排放的risk-benefit （风险-效益）分析。请用Analytica打开Txc查看它是如何工作的。 &lt;br /&gt;
&lt;br /&gt;
ADE '''Examples\Tutorial.NET''' 文件夹中名称为&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;的Visual Basic.NET程序示例显示了ADE很多方面。该程序建立了一个ADE自动化对象，打开包含该对象的&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，获取变量 &amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，计算变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;，通过获取每个表格的单独组件以表格的方式打印输出变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的结果，然后改变变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义。再次获取变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的值，看一下 变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;定义的改变对变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;有什么影响。如果设置正确的话,&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;将显示在“Text Txc window”中显示的窗口。 &lt;br /&gt;
&lt;br /&gt;
应用程序显示变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义（&amp;lt;tt&amp;gt;&amp;quot;Normal (30M, 3M)&amp;quot;&amp;lt;/tt&amp;gt;），以及与&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;关联的表格，这都基于&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义。你可以通过从主菜单选择'''File &amp;gt; Change Population Exposed'''改变&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，然后查看改变对&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;表格的影响。&lt;br /&gt;
&lt;br /&gt;
[[File:TextTxcWindow.png|400px/zh | 文件：TextTxcWindow.png|400px]]&lt;br /&gt;
&lt;br /&gt;
===区分title（名称） 和 identifier（标识符）===&lt;br /&gt;
无论什么时候，一个ADE函数都需要一个变量你必须传达变量的'''''[[Identifier|标识符]]''''' ，而不是它的'''''[[Title|名称]]'''''。这可能会引起混淆，因为在Analytica影响图中一般显示每一个变量的名称。默认情况下，在你最初建立每一个对象的时候，Analytica自动根据名称建立一个标识符。用（_）代替名称中的每一个空格或者其他非字母和数字字符。 &lt;br /&gt;
&lt;br /&gt;
你可以通过点击“Control+y”（或者从Object（对象）菜单选择'''Show by identifier''' ：显示标识符） 来以标识符显示变量。对于模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;，你可以看到名称为&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;变量的标识符为 &amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;。将变量传递给ADE函数时，使用标识符很重要。如果你传递&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;，ADE无法找到变量，并且将返回一个错误。&lt;br /&gt;
&lt;br /&gt;
===从Visual Basic中建立一个ADE 对象===&lt;br /&gt;
&lt;br /&gt;
如果你还没准备好，将名称为tt&amp;gt;Examples\Tutorial\TestTxc.sln&amp;lt;/tt&amp;gt;载入到Visual Basic.NET中，查看名称为&amp;lt;tt&amp;gt;TestTxc.vb&amp;lt;/tt&amp;gt;的文件的代码。其代码看起来像：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Imports ADEW &lt;br /&gt;
:. . . &lt;br /&gt;
:Public adeEngine As [[CAEngine/zh|CAEngine]]&lt;br /&gt;
&lt;br /&gt;
:Public Sub Main() &lt;br /&gt;
::Dim exeDirectory, theModel As String &lt;br /&gt;
::Dim theModelString As String &lt;br /&gt;
::exeDirectory = VB6.GetPath &lt;br /&gt;
::theModel = exeDirectory &amp;amp; &amp;quot;\..\&amp;quot; &amp;amp; &amp;quot;Txc.ana&amp;quot; &lt;br /&gt;
::adeEngine = New [[CAEngine/zh|CAEngine]]&lt;br /&gt;
::... &lt;br /&gt;
::theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
::... &lt;br /&gt;
::frmMain.DefInstance.Show() &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在每一个文件的顶部的代码将自动化对象 '''adeEngine''' 声明为一个[[CAEngine/zh|CAEngine]] 对象。使用此对象，我们能够访问 [[CAEngine/zh|CAEngine]] 展示的所有公共函数（参考 [[ADE Server Class Reference/zh|ADE服务器类型参考]] ）&lt;br /&gt;
&lt;br /&gt;
变量&amp;lt;tt&amp;gt;adeEngine&amp;lt;/tt&amp;gt;包含我们的进程内对象 [[CAEngine/zh|CAEngine]]。如果我们想使用ADE的本地（进程外）服务器版本，我们可以将一个项目参考添加到'''Analytica Decision Engine Server 4.6 COM''' 组件并将顶部行从&amp;lt;tt&amp;gt;Imports ADEW&amp;lt;/tt&amp;gt;改成&amp;lt;tt&amp;gt;Imports ADE&amp;lt;/tt&amp;gt;即可。 &lt;br /&gt;
&lt;br /&gt;
这里是另一种获得一个先[[CAEngine/zh|CAEngine]]对象的方法。此循序不需要给项目添加参考。&amp;lt;tt&amp;gt;&lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADEW4.6.CAEngine&amp;quot;) ’ in-process &lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADE4.6.CAEngine&amp;quot;) ’ out-of-process &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果想理解使用进程内和进程外（或本地）服务器的利与弊，以及哪一种自动化服务器用于不同的场景，参考[[Using_the_Analytica_Decision_Engine_Server#In-process_vs_Out-of-process/zh | In-process vs. out-of-process]]&lt;br /&gt;
&lt;br /&gt;
===COM和 Automation 接口比较===&lt;br /&gt;
在上面的例子当中，我们使用COM接口调用ADE。在一个COM 接口中，对象 在本例中为 [[CAEngine/zh|CAEngine]] 被声明为[[CAEngine/zh|CAEngine]] ，编译器解决每一个成员函数，并且在编译时间内能探测几个明显的错误。另外，Visual Studio可以提供方法和参数类型列表当，在你编程的时候可以当做一个提示工具，在编写使用ADE程序是非常有用。COM调用比Automation调用要快一点，但是在ADE应用程序中速度差异通常不是很重要。对于ADE 4.6我们推荐使用COM结构，只要你的语言支持。&lt;br /&gt;
&lt;br /&gt;
在VB Automation中，你可以将一个对象简单声明为Object（对象），而不是像 [[CAEngine/zh|CAEngine]]、[[CAObject/zh|CAObject]]等更加具体的类型。当使用Automation调用'''ADE'''方法时，在运行时间内确定方法。在编译时间内，编译器不知道你的 '''ADE''' 对象是否有一个名称为[[CAEngine::OpenModel/zh|OpenModel]]的函数。在VB中，调用COM方法或Automation 方法的语法是相通的——唯一的不同在于对象类型是否明确被声明。&lt;br /&gt;
&lt;br /&gt;
在VC++和C#中，调用COM的语法和调用Automatio的语法不同。在这些情况下，COM要方便的多，Automation能够获得相冗余。然而，同样的语言，包括VBScript和其他脚本语言，只支持Automation不支持COM。&lt;br /&gt;
&lt;br /&gt;
===监视Process（进程）===&lt;br /&gt;
当使用进程外ADE服务器时，你的代码必须在终止时释放[[CAEngine/zh|CAEngine]]COM对象。当最终[[CAEngine/zh|CAEngine]]使用被释放是，ADE.exe 进程自动终止。到目前为止所看到的代码，VB语言在达到程序末端时，自动处理释放对象。但是，当你调试你的代码是，你可以提前终止你的程序来修复bug，你的程序可能被Task Manager（任务管理器）终止，或者你自己的代码也可能奔溃，导致你的程序进程在它有机会释放对象之前终止。应为COM对象从来不会被释放，ADE.exe进程不知道它是否在使用中，你可能获得ADE.exe 僵尸进程。 &lt;br /&gt;
&lt;br /&gt;
为了避免这种情况发生，一种好的习惯就是在调用[[CAEngine/zh|CAEngine]]实例后 立即调用[[CAEngine::MonitorProcess/zh|CAEngine::MonitorProcess]]。通过这种方式，ADE能够得知哪一个进程正在使用它，同时将设置一个线程去探测你的进程是否在ADE被完全释放前终止。如果你的程序进程没有终止，ADE进程会立即将它关闭，消除了僵尸ADE进程的堆积。 &lt;br /&gt;
&lt;br /&gt;
要从一个.NET应用程序获得进程ID，使用System.Diagnostics.Process namespace中的'''GetCurrentProcess().Id''' 。在其他语言中，你可以使用Windows SDK 的'''GetProcessId( )'''函数。 &lt;br /&gt;
&lt;br /&gt;
'''[[CAEngine::MonitorProcess/zh|MonitorProcess]]()''' 只能用来监视运行ADE进程的同一台计算机的进程，一次当通过DCOM运行ADE时不能使用。当使用进程内ADEW服务器时没有必要使用。&lt;br /&gt;
&lt;br /&gt;
==打开使用ADE的模型==&lt;br /&gt;
我们现在打开&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，显示我们的应用程序主窗口。使用以下调用：tt&amp;gt;&lt;br /&gt;
:theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
:frmMain.DefInstance.Show &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]]函数打开模型。如果成功的话，变量&amp;lt;tt&amp;gt;theModelString&amp;lt;/tt&amp;gt;将包含模型的名字。否则，将包含一个空的串。虽然由于为了简介的缘故，我们没有这样做，但是你应该检查从[[CAEngine::OpenModel/zh|OpenModel]]函数返回的是不是一个空的串。如果是，说明在你打开的模型中存在一个错误。你可以使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/z |ErrorText]]属性找出是哪种错误 （&amp;lt;tt&amp;gt;adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] 和adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]&amp;lt;/tt&amp;gt;）。&lt;br /&gt;
&lt;br /&gt;
==从Analytica模型中检索对象==&lt;br /&gt;
下一步就是从我们的模型中检索对象（变量、模块、函数等），以便我们能获取他们的属性（[[definition|定义]]、[[title|名称]]、[[class|类型]]等等 ）。我们的示例模型（&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;）操作&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;和&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;对象。尤其是，修改&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;可以查看这是如何影响&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt; 对象。&lt;br /&gt;
&lt;br /&gt;
我们的&amp;lt;tt&amp;gt;TxcTest.vbproj&amp;lt;/tt&amp;gt; （&amp;lt;tt&amp;gt;TxcText.sln&amp;lt;/tt&amp;gt;）项目中的&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;文件里的 '''PrintAttributes''' 函数演示了如何检索对象。该函数首先被&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''Form_Load''' 函数调用，当应用程序启动后，可以显示'''Cost'''表格。当然无论什么时候，只要我们想输出'''Cost'''表格的当前值，都可以调用。该函数如下所示：&lt;br /&gt;
:Public Sub PrintAttributes(ByRef inputIdentifier As String, ByRef  outputIdentifier As String) &lt;br /&gt;
::Dim inputObject, outputObject As [[CAObject/zh|CAObject]]&lt;br /&gt;
::Dim resultTable As [[CATable/zh|CATable]]&lt;br /&gt;
::Dim definitionAttrInput As String &lt;br /&gt;
::inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
::outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier) &lt;br /&gt;
::definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;definition&amp;quot;) &lt;br /&gt;
::resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]]&lt;br /&gt;
::Call PrintResultTable(resultTable, inputIdentifier, definitionAttrInput, outputIdentifier) &lt;br /&gt;
::ReleaseComObject(resultTable) &lt;br /&gt;
::ReleaseComObject(inputObject) &lt;br /&gt;
::ReleaseComObject(outputObject) &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''PrintAttributes'''和作为'''inputIdentifier'''参数的&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;变量标识符以及作为'''outputIdentifier'''参数的'''Cost'''变量一起使用。如下所示通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::GetObjectByName/zh|GetObjectByName]]函数提取相应对象：&amp;lt;tt&amp;gt;&lt;br /&gt;
:inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取成功，将返回一个[[CAObject/zh|CAObject]]类型对象。如果使用'''[[CAObject/zh|CAObject]]'''的函数，参考[[CAObject/zh|SendCommand(command)]]，可以获得一个[[CAObject/zh|CAObject]]的完整函数列表。如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取失败，返回值为&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;。代码应该检查以确保[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取的结果是有效的。如果找不到，可使用[[CAEngine/zh|CAEngine]]的 [[CAEngine::ErrorCode/zh|ErrorCode]]和 [[CAEngine::ErrorText/zh|ErrorText]]属性获取错误信息。例如：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Set inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:If inputObject Is Nothing Then &lt;br /&gt;
::MsgBox(“This error from GetObjectByName occurred: “&amp;amp; _ vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &amp;amp; “:” &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) &lt;br /&gt;
:Else &lt;br /&gt;
::'inputObject valid &lt;br /&gt;
:End If&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===获取对象属性===&lt;br /&gt;
每一个Analytica对象都有一组属性，例如[[identifier|标识符]]、[[title|名称]]、[[description| 描述]]和[[class|类型]]。你可以使用[[CAObject::GetAttribute/zh|GetAttribute]]函数来获去Analytica对象的属性。例如，如要获取'''inputObject'''的定义（当前为cost）：&amp;lt;tt&amp;gt;&lt;br /&gt;
:definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh|GetAttribute]](&amp;quot;[[Definition|定义]]&amp;quot;) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt; 中，&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;的定义为&amp;quot;&amp;lt;tt&amp;gt;[[Normal]](30M, 3M)&amp;lt;/tt&amp;gt;&amp;quot; ，我们将它储存在'''definitionAttrInput'''当中。.&lt;br /&gt;
&lt;br /&gt;
===计算对象和检索结果===&lt;br /&gt;
使用[[CAObject/zh|CAObject]]的[[CAObject::Result/zh|Result]]或[[CAObject::ResultTable/zh|ResultTable]]方法来获取变量的值。如果有必要的话，ADE先自动计算变量。如果你确定结果为基元（只有一个元素），使用[[CAObject::Result/zh|Result]]方法。否则使用[[CAObject::ResultTable/zh|ResultTable]]，检索结果为一个''数组''。基元结果当作一个特殊数组案例来处理，没有维度的数组。如果值为基元[[CATable::AtomicValue/zh|AtomicValue]]方法将返回一个数字或者字符串单一值。 &lt;br /&gt;
&lt;br /&gt;
默认情况下，[[CAObject::Result/zh|Result]]和[[CAObject::ResultTable/zh|ResultTable]]返回结果的中值，也就是说，ADE以确定性方式计算结果。对于一个概率值，将[[CAObject/zh|CAObject]]的[[CAObject::ResultType/zh|ResultType]]属性设置为想要的不确定性视图——Mean（平均值） Sample（样本）、PDF（概率密度函数）、CDF（累计分布函数）、Confidence bands（置信带）、或者Statistics（统计数据）详情请参考[[CAObject::ResultType/zh|ResultType]]。我们通过如下的方式获取outputObject 输出对象 的值：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]] &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
结果为一个[[CATable/zh|CATable]]对象，允许我们访问一个表格中的单个元素。 &lt;br /&gt;
&lt;br /&gt;
如果你通过调用[[CAObject::Result/zh|Result]]来获取一个数组（或者表格）的值，将返回数组为一个字符串，列出索引和元素，以逗号隔开。通常使用[[CAObject::ResultTable/zh|ResultTable]]更加简单，这样你没有必要从字符串中解析表格的元素。&lt;br /&gt;
&lt;br /&gt;
===获取表格索引元素===&lt;br /&gt;
一个Analytica表格包含0个或者多个索引。如果包含一个索引，那么该表格是1维表格；如果有2个索引，说他是2维表格，依此类推。0维度表格包含一个“单一基元”（或标量）值。你可以使用CATable的[[CATable::NumDims/zh|NumDims]]获取表格的维数（也就是索引数）。要想获取表格的单个索引，可使用[[CATable/zh|CATable]]的 [[CATable::IndexNames/zh|IndexNames]]和 [[CATable::GetIndexObject/zh|GetIndexObject]]函数。 &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''PrintResultTable'''函数说明了这两个函数的使用。从'''PrintAttributes'''中调用'''PrintResultTable'''，执行打印'''TestTxc'''中的表格的实际工作（为了简洁起见，我们只给出了关联ADE的该函数部分）。&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Public Sub PrintResultTable(ByRef resultTable As CATable, ByRef inputIdentifier As String, ByRef definitionAttrInput As String, ByRef outputIdentifier As String) &lt;br /&gt;
::Dim theIndexName, theTableName As String &lt;br /&gt;
::Dim theIndexElement As String &lt;br /&gt;
::Dim theTableElement &lt;br /&gt;
::Dim theIndexObj As [[CAIndex/zh|CAIndex]]&lt;br /&gt;
::Dim numEls As Integer &lt;br /&gt;
::Dim spaces, i As Integer &lt;br /&gt;
::Dim lenStr As Short &lt;br /&gt;
::Dim OutputStr As Short &lt;br /&gt;
::Dim spaceString, underlineString As String &lt;br /&gt;
::... &lt;br /&gt;
::theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1) &lt;br /&gt;
::theTableName = resultTable.[[CATable::Name/zh|Name]] &lt;br /&gt;
::theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName) &lt;br /&gt;
::numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
::... &lt;br /&gt;
::For i = 1 To numEls &lt;br /&gt;
:::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
:::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
:::... &lt;br /&gt;
::Next i &lt;br /&gt;
::InformationPane.Text = outputString &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
通过'''PrintResultTable'''获取一个表格的索引方法如下：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1)&lt;br /&gt;
:theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
我们通过使用[[CATable/zh|CATable]]的[[CATable::IndexNames/zh|IndexNames]]函数获取第一个索引的名字。我们将它传递给[[CATable/zh|CATable]]的[[CATable::GetIndexObject/zh|GetIndexObject]]函数以获取表示我们的索引的[[CAIndex/zh|CAIndex]]。该自动化对象返回其相应索引的相关信息。如果此函数调用失败，将返回&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;信息。在此情况下，使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]] 函数找出原因。&lt;br /&gt;
&lt;br /&gt;
==从CATable和CAIndex中获取信息==&lt;br /&gt;
[[PrintResultTable]]说明了如何从[[CATable/zh| CATable]]和[[CAIndex/zh|CAIndex]] 对象获取信息。该代码获取'''Cost'''表格的索引和表格元素：&lt;br /&gt;
: &amp;lt;tt&amp;gt;&lt;br /&gt;
:numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
:For i = 1 To numEls &lt;br /&gt;
::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
::... &lt;br /&gt;
:Next i &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[CAIndex/zh|CAIndex]]的[[CAIndex::IndexElements/zh|IndexElements]]属性返回第一个索引中的元素个数。[[CAIndex/zh|CAIndex]]的[[CAIndex::GetValueByNumber/zh|GetValueByNumber]]函数获取单个索引元素。 &lt;br /&gt;
&lt;br /&gt;
我们通过传递表格中元素的坐标，使用  [[CATable/zh|CATable]]的[[CATable::GetDataByElements/zh|GetDataByElements]]函数获取'''Cost'''表格对象的单个表格元素'''resultTable'''。 &lt;br /&gt;
&lt;br /&gt;
当我检索 [[CATable/zh|CATable]]对象中单个元素（'''resultTable'''）的时候，我们利用了该表格是一维的事实。因此，我们只需要传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个单一数（这个数代表表格中的位置）。但是，如果我们处理两个或者更多维度，我们必须传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个数组函数，并且指明我们要检索的表格元素的位置。因此，如果我们不想检索一个二维数组的position (4,3)位置的元素，我们可以这样写：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Dim W as Variant 'return element &lt;br /&gt;
:Dim IndexPtrs(1 To 2) As Variant 'position in table &lt;br /&gt;
::... &lt;br /&gt;
:IndexPtrs(1) = 4 &lt;br /&gt;
:IndexPtrs(2) = 3 &lt;br /&gt;
:W = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](IndexPtrs) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==控制基元值格式==&lt;br /&gt;
[[CATable/zh|CATable]]中的每个基元值可以是一个数、一个字符串，或者其它一些基本类型（''例如''：[[Null|空值]]、[[Undefined|未定义]]、[[Reference|参考]]，或 [[Handle|句柄]]。通过说明类型和值，它们作为''变体''被返回，这是一种Visual Basic能读懂的数据结构。[[CATable/zh|CATable]]的[[CATable::RenderingStyle|RenderingStyle]]属性控制Analytica基础值是如何映射到Visual Basic变体的。 &lt;br /&gt;
&lt;br /&gt;
例如：可以通过使用Analytica 模型的数字格式设置将一个数值返回成一个数字或者字符串。如果被指定格式，有一个选线控制是截断数字的位数，还是精确返回。 &lt;br /&gt;
&lt;br /&gt;
子程序[[PrintResultTable/zh|PrintResultTable]]在&amp;lt;tt&amp;gt;frmMain.vb&amp;lt;/tt&amp;gt;中载入,其渲染风格直接指明：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::NumberAsText/zh|NumberAsText]] = True &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::FullPrecision/zh|FullPrecision]] = False &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::StringQuotes/zh|StringQuotes]] = 2 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
第一行指明数值应该根据与结果对象有关的数字格式被格式化为文本。例如在其程序输出中，我们将看到&amp;lt;tt&amp;gt;30.103M&amp;lt;/tt&amp;gt;，而非&amp;lt;tt&amp;gt;30102995.6639812&amp;lt;/tt&amp;gt;，如果我们让Visual Basic将数值串联我们的结果字符串，将显示该结果。在此事件中，一个值为字符串的单元格出现在结果中，返回值将明确带双引号。对于[[CARenderingStyle/zh|CARenderingStyle]]对象中的所有可用属性，请参考[[CARenderingStyle/zh|CARenderingStyle]]。&lt;br /&gt;
&lt;br /&gt;
===其它访问表格的方式===&lt;br /&gt;
有几种访问多维表格[[CATable/zh|CATable]]中元素的方式。每一种都有可能在特定的场合使用起来比较方便。 &lt;br /&gt;
&lt;br /&gt;
第一种方式就是使用[[CATable/zh | CATable]]的 [[CATable::GetDataByElements/zh|GetDataByElements]]或[[CATable::GetDataByLabels/zh|GetDataByLabels]]方法，上面代码示例中有显示。在此情况下，利用你想获取的基元值的单元格位置。 &lt;br /&gt;
&lt;br /&gt;
第二种方式就是使用[[CATable/zh|CATable]][[CATable::Slice/zh|Slice]]或[[CATable::Subscript/zh | Subscript]]方法获取一个少一个维度的新[[CATable/zh|CATable]]对象。通过重复减少维度，最终将获得0维度，这时你将获得一个单一基元值。此时，[[CATable/zh|CATable]]的[[CATable::AtomicValue/zh|AtomicValue]]方法返回该值 。[[CATable::AtomicValue/zh|AtomicValue]]方法是唯一获取一个标值的方法（因为没有坐标位置）。如果你需要建立完整结果其中一个切片的图形图像，必须使用此方法。 &lt;br /&gt;
&lt;br /&gt;
第三种方式就是使用[[CATable/zh|CATable]]的[[CATable::GetSafeArray/zh|GetSafeArray]]方法，将多维数组转化成一个''安全数组''（或者一个.NET数组）。你可以在使用VB或者其它.NET语言直接处理多维数组。因为对于Analytica维度没有固定顺序，但是安全数组和.NET数组有一个明确的顺序，你必须先使用[[CATable/zh|CATable]]对象的[[CATable::SetIndexOrder/zh|SetIndexOrder]]方法在调用[[CATable::GetSafeArray/zh|GetSafeArray]]之前指明维度的顺序。注意如果你知道你的数组是一维的，那就没必要了。&lt;br /&gt;
&lt;br /&gt;
===修改对象===&lt;br /&gt;
一个自定义用户程序通常从一个用户或者其它外部源获取输入，以便转化成Analytica模型中的输入变量。你可以设定输入变量的定义或者通过使用定义表格来这样做。 &lt;br /&gt;
&lt;br /&gt;
'''TestTxc''' 说明了如何修改'''Pop_exp'''定义，此模型是一个影响结果变量Cost的模型输入。要想在该示例中设定该定义，从主菜单上选择'''File &amp;gt; Change Population'''。将出现一个对话框，如下图所示：&lt;br /&gt;
&lt;br /&gt;
[[File:RedefiningtheVariableDefinition.jpg|400px/zh|文件：RedefiningtheVariableDefinition.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
在信息栏中输入一个新定义并点击'''Ok'''确认。主窗口将显示一个新的Cost值。当点击该对话框中的'''Ok'''按钮时，调用了&amp;lt;tt&amp;gt;ChangeDef.frm&amp;lt;/tt&amp;gt;函数，然后调用[[PrintAttributes/zh|PrintAttributes]]函数打印&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果。&lt;br /&gt;
&lt;br /&gt;
此函数类似于：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Private Sub OkButton_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles OkButton.Click &lt;br /&gt;
::Dim errorText As String&lt;br /&gt;
::Dim pop_exp_Object As [[CAObject/zh|CAObject]] &lt;br /&gt;
::Dim errorCode As Short &lt;br /&gt;
::Dim errorString As String &lt;br /&gt;
::newDefinition = PopExposedDef.Text &lt;br /&gt;
::pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
::pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]](&amp;quot;[[Definition]]&amp;quot;, newDefinition) &lt;br /&gt;
::errorCode = adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &lt;br /&gt;
::If errorCode &amp;lt;&amp;gt; 0 Then &lt;br /&gt;
:::MsgBox(&amp;quot;This error occurred while processing your definition: &amp;quot; &amp;amp; vbCrLf &amp;amp; vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) :::PopExposedDef.Focus()&lt;br /&gt;
::Else&lt;br /&gt;
:::Me.Close() &lt;br /&gt;
:::frmMain.DefInstance.PrintAttributes(&amp;quot;Pop_exp&amp;quot;, &amp;quot;Cost&amp;quot;) &lt;br /&gt;
::End If &lt;br /&gt;
::ReleaseComObject(pop_exp_Object) &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
该函数抓取了输入到'''New Definition''' 新定义给'''Population Exposed'''栏，并通过使用[[CAObject/zh|CAObject]]对象中的[[CAObject::SetAttribute/zh|SetAttribute]]函数将它设置给&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;对象。然后调用[[PrintAttributes/zh|PrintAttributes]]，以计算&amp;lt;tt&amp;gt;Cost object&amp;lt;/tt&amp;gt;，并打印新的结果。要想给变量&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;设定一个新定义，我们可以为&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;获取[[CAObject/zh|CAObject]]对象，然后将其定义设置成用户输入的定义。通过使用下面的代码来实现：&lt;br /&gt;
:pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
:pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]]( &amp;quot;[[Definition]]&amp;quot;, newDefinition )&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
无论什么时候调用[[CAObject::SetAttribute/zh|SetAttribute]]，都应该检查[[CAEngine/zh|CAEngine]]自动化对象（'''adeEngine'''）的[[CAEngine::ErrorCode/zh|ErrorCode]]，以免它的定义是非法的。尝试一下输入一个新定义，比如&amp;lt;code&amp;gt;[[Uniform]](25M,35M)&amp;lt;/code&amp;gt;，然后点击'''Ok'''。当&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;的定义被改变时， &amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果由ADE重新计算，此时'''ResultTable'''接下来调用给Cost变量（在应用程序窗口重新显示时）。&lt;br /&gt;
&lt;br /&gt;
使用ADE绘图&lt;br /&gt;
&lt;br /&gt;
通过Analytica 4.6使用相同的绘图引擎，你可以建立一个图表或者图形以显示一个数组值或者不确定值结果。在ADE4.6中，你可以使用 [[CATable/zh|CATable]]的[[CATable::GraphToFile/zh|GraphToFile]]和[[CATable::GraphToStream/zh|GraphToStream]]方法。图形可以以几种可能的图像格式返回，例如'''image/png'''、 '''image/bmp'''或者 '''image/jpeg'''。 &lt;br /&gt;
&lt;br /&gt;
从可用图形选项中选择的最简单方式就是使用Analytica打开你的模型。你可以实验设置各种默认设置或者替代选择的变量，看它们是如何工作的。但你选择了你想设置的选项，保存模型。当为每一个生成结果图形时，ADE将使用这些设置。 &lt;br /&gt;
&lt;br /&gt;
对于更高维度的结果，可能需要做一些必要工作，以便选择将绘制结果的切片和具体的轴（也就是相对于图例哪个维度作为X轴）。[[CATable/zh|CATable]]的[[CATable::Subscript/zh|Subscript]]或[[CATable::Slice/zh|Slice]]方法可以用来控制轴选择特殊的切片用来绘制，能够用来控制轴。详情请参考[[CATable/zh|CATable]]。在我们的&amp;lt;tt&amp;gt;Tutorial.NET&amp;lt;/tt&amp;gt;示例中，我们有一个一维结果（&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;），因此我们没有必要担心截取或者绕轴旋转。 &lt;br /&gt;
&lt;br /&gt;
[[CATable::GraphToStream/zh|GraphToStream]]方法被用来从ADE中直接转化图形图形到一个用户界面中。使用[[CATable::GraphToStream/zh|GraphToStream]]比起使用[[CATable::GraphToFile/zh|GraphToFile]]来要稍微复杂一点，因为[[CATable::GraphToFile/zh|GraphToFile]]除了需要文件名以外还需要其它一些信息，以便编写图形。要使用[[CATable::GraphToStream/zh|GraphToStream]]，我们必须在内存内设置一个流，允许ADE写入该留，然后从该留重建。因为.NET流和COM流不兼容，你必须使用ADE一同提供的[[StreamConnector]]类型.&amp;lt;tt&amp;gt;frmMain&amp;lt;/tt&amp;gt; 中的'''GraphResult_Click'''子程序演示了[[CATable::GraphToStream/zh|GraphToStream]]的使用。从主应用程序窗口选择 '''Graph Result'''菜单选项，结果将出现在一个如下所示的图形当中：&lt;br /&gt;
&lt;br /&gt;
[[File:resultgraph.jpg/zh|文件：resultgraph.jpg]]&lt;br /&gt;
&lt;br /&gt;
==结论==&lt;br /&gt;
&lt;br /&gt;
在此教程中，我们介绍了Analytica决策引擎的几个重要方面。我们看到了如何建立一个ADE服务器对象，使用ADE打开模型，获取模型中的单个对象、计算对象、获取表格中的元素，以及修改模型中的对象。但是ADE可以做的远不止这些。 &lt;br /&gt;
&lt;br /&gt;
我们希望你已经足够了解其基本特征，这样你现在才能独自开始探索更多新的高级特征。我们建议你现在开始阅读字教程的剩余部分以了解ADE能做什么。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
| [[Installation of ADE/zh|ADE 安装]] &amp;lt;- ||  [[The ADE Tutorial/zh|ADE 入门教程]] || -&amp;gt; [[Using the ADE Server/zh|使用ADE服务器]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36300</id>
		<title>The ADE Tutorial/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36300"/>
		<updated>2015-10-27T06:27:27Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南 ]]&lt;br /&gt;
&lt;br /&gt;
此教程教你如何在一个Visual Basic程序中使用Analytica决策引擎（ADE）。&lt;br /&gt;
&lt;br /&gt;
==你的第一个ADE应用程序==&lt;br /&gt;
首先先从头开始写一个简单的ADE程序，只要确认一切设置正常。按照以下步骤操作：&lt;br /&gt;
&lt;br /&gt;
test&lt;br /&gt;
&lt;br /&gt;
第一个程序执行了以下操作：&lt;br /&gt;
*建立一个名称为ADE的[[CAEngine/zh|CAEngine]]自动化对象（通过使用&amp;lt;code&amp;gt;new [[CAEngine/zh|CAEngine]]&amp;lt;/code&amp;gt;).&lt;br /&gt;
*打开Analytica模型 (通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]] 方法。&lt;br /&gt;
*显示模型名称返回[[CAEngine::OpenModel/zh|OpenModel]]的值。&lt;br /&gt;
我们将在后面的章节详细了解这些信息。&lt;br /&gt;
&lt;br /&gt;
===接下来讲什么呢?===&lt;br /&gt;
我们不会尝试在此入门教程中解释ADE的特征。本指南后面几个章节会描述这些特征。 &lt;br /&gt;
&lt;br /&gt;
从现在开始，我们我们将使用名称为&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;的示例模型。打开 Analytica安装目录下 '''Example Models'''文件夹里面的'''Risk Analysis'''文件夹便可找到&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;文件。如果你找不到，或者你安装Analytica的时候未选择安装examples（示例）文件，在ADE安装目录下面的'''Examples\Tutorial.NET'''文件家中有一个副本。 &lt;br /&gt;
&lt;br /&gt;
Txc模型演示了减少污染物TXC排放的risk-benefit （风险-效益）分析。请用Analytica打开Txc查看它是如何工作的。 &lt;br /&gt;
&lt;br /&gt;
ADE '''Examples\Tutorial.NET''' 文件夹中名称为&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;的Visual Basic.NET程序示例显示了ADE很多方面。该程序建立了一个ADE自动化对象，打开包含该对象的&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，获取变量 &amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，计算变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;，通过获取每个表格的单独组件以表格的方式打印输出变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的结果，然后改变变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义。再次获取变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的值，看一下 变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;定义的改变对变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;有什么影响。如果设置正确的话,&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;将显示在“Text Txc window”中显示的窗口。 &lt;br /&gt;
&lt;br /&gt;
应用程序显示变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义（&amp;lt;tt&amp;gt;&amp;quot;Normal (30M, 3M)&amp;quot;&amp;lt;/tt&amp;gt;），以及与&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;关联的表格，这都基于&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义。你可以通过从主菜单选择'''File &amp;gt; Change Population Exposed'''改变&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，然后查看改变对&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;表格的影响。&lt;br /&gt;
&lt;br /&gt;
[[File:TextTxcWindow.png|400px/zh | 文件：TextTxcWindow.png|400px]]&lt;br /&gt;
&lt;br /&gt;
===区分title（名称） 和 identifier（标识符）===&lt;br /&gt;
无论什么时候，一个ADE函数都需要一个变量你必须传达变量的'''''[[Identifier|标识符]]''''' ，而不是它的'''''[[Title|名称]]'''''。这可能会引起混淆，因为在Analytica影响图中一般显示每一个变量的名称。默认情况下，在你最初建立每一个对象的时候，Analytica自动根据名称建立一个标识符。用（_）代替名称中的每一个空格或者其他非字母和数字字符。 &lt;br /&gt;
&lt;br /&gt;
你可以通过点击“Control+y”（或者从Object（对象）菜单选择'''Show by identifier''' ：显示标识符） 来以标识符显示变量。对于模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;，你可以看到名称为&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;变量的标识符为 &amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;。将变量传递给ADE函数时，使用标识符很重要。如果你传递&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;，ADE无法找到变量，并且将返回一个错误。&lt;br /&gt;
&lt;br /&gt;
===从Visual Basic中建立一个ADE 对象===&lt;br /&gt;
&lt;br /&gt;
如果你还没准备好，将名称为tt&amp;gt;Examples\Tutorial\TestTxc.sln&amp;lt;/tt&amp;gt;载入到Visual Basic.NET中，查看名称为&amp;lt;tt&amp;gt;TestTxc.vb&amp;lt;/tt&amp;gt;的文件的代码。其代码看起来像：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Imports ADEW &lt;br /&gt;
:. . . &lt;br /&gt;
:Public adeEngine As [[CAEngine/zh|CAEngine]]&lt;br /&gt;
&lt;br /&gt;
:Public Sub Main() &lt;br /&gt;
::Dim exeDirectory, theModel As String &lt;br /&gt;
::Dim theModelString As String &lt;br /&gt;
::exeDirectory = VB6.GetPath &lt;br /&gt;
::theModel = exeDirectory &amp;amp; &amp;quot;\..\&amp;quot; &amp;amp; &amp;quot;Txc.ana&amp;quot; &lt;br /&gt;
::adeEngine = New [[CAEngine/zh|CAEngine]]&lt;br /&gt;
::... &lt;br /&gt;
::theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
::... &lt;br /&gt;
::frmMain.DefInstance.Show() &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在每一个文件的顶部的代码将自动化对象 '''adeEngine''' 声明为一个[[CAEngine/zh|CAEngine]] 对象。使用此对象，我们能够访问 [[CAEngine/zh|CAEngine]] 展示的所有公共函数（参考 [[ADE Server Class Reference/zh|ADE服务器类型参考]] ）&lt;br /&gt;
&lt;br /&gt;
变量&amp;lt;tt&amp;gt;adeEngine&amp;lt;/tt&amp;gt;包含我们的进程内对象 [[CAEngine/zh|CAEngine]]。如果我们想使用ADE的本地（进程外）服务器版本，我们可以将一个项目参考添加到'''Analytica Decision Engine Server 4.6 COM''' 组件并将顶部行从&amp;lt;tt&amp;gt;Imports ADEW&amp;lt;/tt&amp;gt;改成&amp;lt;tt&amp;gt;Imports ADE&amp;lt;/tt&amp;gt;即可。 &lt;br /&gt;
&lt;br /&gt;
这里是另一种获得一个先[[CAEngine/zh|CAEngine]]对象的方法。此循序不需要给项目添加参考。&amp;lt;tt&amp;gt;&lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADEW4.6.CAEngine&amp;quot;) ’ in-process &lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADE4.6.CAEngine&amp;quot;) ’ out-of-process &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果想理解使用进程内和进程外（或本地）服务器的利与弊，以及哪一种自动化服务器用于不同的场景，参考[[Using_the_Analytica_Decision_Engine_Server#In-process_vs_Out-of-process/zh | In-process vs. out-of-process]]&lt;br /&gt;
&lt;br /&gt;
===COM和 Automation 接口比较===&lt;br /&gt;
在上面的例子当中，我们使用COM接口调用ADE。在一个COM 接口中，对象 在本例中为 [[CAEngine/zh|CAEngine]] 被声明为[[CAEngine/zh|CAEngine]] ，编译器解决每一个成员函数，并且在编译时间内能探测几个明显的错误。另外，Visual Studio可以提供方法和参数类型列表当，在你编程的时候可以当做一个提示工具，在编写使用ADE程序是非常有用。COM调用比Automation调用要快一点，但是在ADE应用程序中速度差异通常不是很重要。对于ADE 4.6我们推荐使用COM结构，只要你的语言支持。&lt;br /&gt;
&lt;br /&gt;
在VB Automation中，你可以将一个对象简单声明为Object（对象），而不是像 [[CAEngine/zh|CAEngine]]、[[CAObject/zh|CAObject]]等更加具体的类型。当使用Automation调用'''ADE'''方法时，在运行时间内确定方法。在编译时间内，编译器不知道你的 '''ADE''' 对象是否有一个名称为[[CAEngine::OpenModel/zh|OpenModel]]的函数。在VB中，调用COM方法或Automation 方法的语法是相通的——唯一的不同在于对象类型是否明确被声明。&lt;br /&gt;
&lt;br /&gt;
在VC++和C#中，调用COM的语法和调用Automatio的语法不同。在这些情况下，COM要方便的多，Automation能够获得相冗余。然而，同样的语言，包括VBScript和其他脚本语言，只支持Automation不支持COM。&lt;br /&gt;
&lt;br /&gt;
===监视Process（进程）===&lt;br /&gt;
当使用进程外ADE服务器时，你的代码必须在终止时释放[[CAEngine/zh|CAEngine]]COM对象。当最终[[CAEngine/zh|CAEngine]]使用被释放是，ADE.exe 进程自动终止。到目前为止所看到的代码，VB语言在达到程序末端时，自动处理释放对象。但是，当你调试你的代码是，你可以提前终止你的程序来修复bug，你的程序可能被Task Manager（任务管理器）终止，或者你自己的代码也可能奔溃，导致你的程序进程在它有机会释放对象之前终止。应为COM对象从来不会被释放，ADE.exe进程不知道它是否在使用中，你可能获得ADE.exe 僵尸进程。 &lt;br /&gt;
&lt;br /&gt;
为了避免这种情况发生，一种好的习惯就是在调用[[CAEngine/zh|CAEngine]]实例后 立即调用[[CAEngine::MonitorProcess/zh|CAEngine::MonitorProcess]]。通过这种方式，ADE能够得知哪一个进程正在使用它，同时将设置一个线程去探测你的进程是否在ADE被完全释放前终止。如果你的程序进程没有终止，ADE进程会立即将它关闭，消除了僵尸ADE进程的堆积。 &lt;br /&gt;
&lt;br /&gt;
要从一个.NET应用程序获得进程ID，使用System.Diagnostics.Process namespace中的'''GetCurrentProcess().Id''' 。在其他语言中，你可以使用Windows SDK 的'''GetProcessId( )'''函数。 &lt;br /&gt;
&lt;br /&gt;
'''[[CAEngine::MonitorProcess/zh|MonitorProcess]]()''' 只能用来监视运行ADE进程的同一台计算机的进程，一次当通过DCOM运行ADE时不能使用。当使用进程内ADEW服务器时没有必要使用。&lt;br /&gt;
&lt;br /&gt;
==打开使用ADE的模型==&lt;br /&gt;
我们现在打开&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，显示我们的应用程序主窗口。使用以下调用：tt&amp;gt;&lt;br /&gt;
:theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
:frmMain.DefInstance.Show &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]]函数打开模型。如果成功的话，变量&amp;lt;tt&amp;gt;theModelString&amp;lt;/tt&amp;gt;将包含模型的名字。否则，将包含一个空的串。虽然由于为了简介的缘故，我们没有这样做，但是你应该检查从[[CAEngine::OpenModel/zh|OpenModel]]函数返回的是不是一个空的串。如果是，说明在你打开的模型中存在一个错误。你可以使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/z |ErrorText]]属性找出是哪种错误 （&amp;lt;tt&amp;gt;adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] 和adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]&amp;lt;/tt&amp;gt;）。&lt;br /&gt;
&lt;br /&gt;
==从Analytica模型中检索对象==&lt;br /&gt;
下一步就是从我们的模型中检索对象（变量、模块、函数等），以便我们能获取他们的属性（[[definition|定义]]、[[title|名称]]、[[class|类型]]等等 ）。我们的示例模型（&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;）操作&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;和&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;对象。尤其是，修改&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;可以查看这是如何影响&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt; 对象。&lt;br /&gt;
&lt;br /&gt;
我们的&amp;lt;tt&amp;gt;TxcTest.vbproj&amp;lt;/tt&amp;gt; （&amp;lt;tt&amp;gt;TxcText.sln&amp;lt;/tt&amp;gt;）项目中的&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;文件里的 '''PrintAttributes''' 函数演示了如何检索对象。该函数首先被&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''Form_Load''' 函数调用，当应用程序启动后，可以显示'''Cost'''表格。当然无论什么时候，只要我们想输出'''Cost'''表格的当前值，都可以调用。该函数如下所示：&lt;br /&gt;
:Public Sub PrintAttributes(ByRef inputIdentifier As String, ByRef  outputIdentifier As String) &lt;br /&gt;
::Dim inputObject, outputObject As [[CAObject/zh|CAObject]]&lt;br /&gt;
::Dim resultTable As [[CATable/zh|CATable]]&lt;br /&gt;
::Dim definitionAttrInput As String &lt;br /&gt;
::inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
::outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier) &lt;br /&gt;
::definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;definition&amp;quot;) &lt;br /&gt;
::resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]]&lt;br /&gt;
::Call PrintResultTable(resultTable, inputIdentifier, definitionAttrInput, outputIdentifier) &lt;br /&gt;
::ReleaseComObject(resultTable) &lt;br /&gt;
::ReleaseComObject(inputObject) &lt;br /&gt;
::ReleaseComObject(outputObject) &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''PrintAttributes'''和作为'''inputIdentifier'''参数的&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;变量标识符以及作为'''outputIdentifier'''参数的'''Cost'''变量一起使用。如下所示通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::GetObjectByName/zh|GetObjectByName]]函数提取相应对象：&amp;lt;tt&amp;gt;&lt;br /&gt;
:inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取成功，将返回一个[[CAObject/zh|CAObject]]类型对象。如果使用'''[[CAObject/zh|CAObject]]'''的函数，参考[[CAObject/zh|SendCommand(command)]]，可以获得一个[[CAObject/zh|CAObject]]的完整函数列表。如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取失败，返回值为&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;。代码应该检查以确保[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取的结果是有效的。如果找不到，可使用[[CAEngine/zh|CAEngine]]的 [[CAEngine::ErrorCode/zh|ErrorCode]]和 [[CAEngine::ErrorText/zh|ErrorText]]属性获取错误信息。例如：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Set inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:If inputObject Is Nothing Then &lt;br /&gt;
::MsgBox(“This error from GetObjectByName occurred: “&amp;amp; _ vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &amp;amp; “:” &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) &lt;br /&gt;
:Else &lt;br /&gt;
::'inputObject valid &lt;br /&gt;
:End If&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===获取对象属性===&lt;br /&gt;
每一个Analytica对象都有一组属性，例如[[identifier|标识符]]、[[title|名称]]、[[description| 描述]]和[[class|类型]]。你可以使用[[CAObject::GetAttribute/zh|GetAttribute]]函数来获去Analytica对象的属性。例如，如要获取'''inputObject'''的定义（当前为cost）：&amp;lt;tt&amp;gt;&lt;br /&gt;
:definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh|GetAttribute]](&amp;quot;[[Definition|定义]]&amp;quot;) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt; 中，&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;的定义为&amp;quot;&amp;lt;tt&amp;gt;[[Normal]](30M, 3M)&amp;lt;/tt&amp;gt;&amp;quot; ，我们将它储存在'''definitionAttrInput'''当中。.&lt;br /&gt;
&lt;br /&gt;
===计算对象和检索结果===&lt;br /&gt;
使用[[CAObject/zh|CAObject]]的[[CAObject::Result/zh|Result]]或[[CAObject::ResultTable/zh|ResultTable]]方法来获取变量的值。如果有必要的话，ADE先自动计算变量。如果你确定结果为基元（只有一个元素），使用[[CAObject::Result/zh|Result]]方法。否则使用[[CAObject::ResultTable/zh|ResultTable]]，检索结果为一个''数组''。基元结果当作一个特殊数组案例来处理，没有维度的数组。如果值为基元[[CATable::AtomicValue/zh|AtomicValue]]方法将返回一个数字或者字符串单一值。 &lt;br /&gt;
&lt;br /&gt;
默认情况下，[[CAObject::Result/zh|Result]]和[[CAObject::ResultTable/zh|ResultTable]]返回结果的中值，也就是说，ADE以确定性方式计算结果。对于一个概率值，将[[CAObject/zh|CAObject]]的[[CAObject::ResultType/zh|ResultType]]属性设置为想要的不确定性视图——Mean（平均值） Sample（样本）、PDF（概率密度函数）、CDF（累计分布函数）、Confidence bands（置信带）、或者Statistics（统计数据）详情请参考[[CAObject::ResultType/zh|ResultType]]。我们通过如下的方式获取outputObject 输出对象 的值：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]] &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
结果为一个[[CATable/zh|CATable]]对象，允许我们访问一个表格中的单个元素。 &lt;br /&gt;
&lt;br /&gt;
如果你通过调用[[CAObject::Result/zh|Result]]来获取一个数组（或者表格）的值，将返回数组为一个字符串，列出索引和元素，以逗号隔开。通常使用[[CAObject::ResultTable/zh|ResultTable]]更加简单，这样你没有必要从字符串中解析表格的元素。&lt;br /&gt;
&lt;br /&gt;
===获取表格索引元素===&lt;br /&gt;
一个Analytica表格包含0个或者多个索引。如果包含一个索引，那么该表格是1维表格；如果有2个索引，说他是2维表格，依此类推。0维度表格包含一个“单一基元”（或标量）值。你可以使用CATable的[[CATable::NumDims/zh|NumDims]]获取表格的维数（也就是索引数）。要想获取表格的单个索引，可使用[[CATable/zh|CATable]]的 [[CATable::IndexNames/zh|IndexNames]]和 [[CATable::GetIndexObject/zh|GetIndexObject]]函数。 &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''PrintResultTable'''函数说明了这两个函数的使用。从'''PrintAttributes'''中调用'''PrintResultTable'''，执行打印'''TestTxc'''中的表格的实际工作（为了简洁起见，我们只给出了关联ADE的该函数部分）。&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Public Sub PrintResultTable(ByRef resultTable As CATable, ByRef inputIdentifier As String, ByRef definitionAttrInput As String, ByRef outputIdentifier As String) &lt;br /&gt;
::Dim theIndexName, theTableName As String &lt;br /&gt;
::Dim theIndexElement As String &lt;br /&gt;
::Dim theTableElement &lt;br /&gt;
::Dim theIndexObj As [[CAIndex/zh | CAIndex]]&lt;br /&gt;
::Dim numEls As Integer &lt;br /&gt;
::Dim spaces, i As Integer &lt;br /&gt;
::Dim lenStr As Short &lt;br /&gt;
::Dim OutputStr As Short &lt;br /&gt;
::Dim spaceString, underlineString As String &lt;br /&gt;
::... &lt;br /&gt;
::theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1) &lt;br /&gt;
::theTableName = resultTable.[[CATable::Name/zh|Name]] &lt;br /&gt;
::theIndexObj = resultTable.[[CATable::GetIndexObject/zh | GetIndexObject]](theIndexName) &lt;br /&gt;
::numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
::... &lt;br /&gt;
::For i = 1 To numEls &lt;br /&gt;
:::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
:::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
:::... &lt;br /&gt;
::Next i &lt;br /&gt;
::InformationPane.Text = outputString &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
通过'''PrintResultTable'''获取一个表格的索引方法如下：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1)&lt;br /&gt;
:theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
我们通过使用[[CATable/zh|CATable]]的[[CATable::IndexNames/zh|IndexNames]]函数获取第一个索引的名字。我们将它传递给[[CATable/zh|CATable]]的[[CATable::GetIndexObject/zh|GetIndexObject]]函数以获取表示我们的索引的[[CAIndex/zh|CAIndex]]。该自动化对象返回其相应索引的相关信息。如果此函数调用失败，将返回&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;信息。在此情况下，使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]] 函数找出原因。&lt;br /&gt;
&lt;br /&gt;
==从CATable和CAIndex中获取信息==&lt;br /&gt;
[[PrintResultTable]]说明了如何从[[CATable/zh| CATable]]和[[CAIndex/zh|CAIndex]] 对象获取信息。该代码获取'''Cost'''表格的索引和表格元素：&lt;br /&gt;
: &amp;lt;tt&amp;gt;&lt;br /&gt;
:numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
:For i = 1 To numEls &lt;br /&gt;
::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
::... &lt;br /&gt;
:Next i &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[CAIndex/zh|CAIndex]]的[[CAIndex::IndexElements/zh|IndexElements]]属性返回第一个索引中的元素个数。[[CAIndex/zh|CAIndex]]的[[CAIndex::GetValueByNumber/zh|GetValueByNumber]]函数获取单个索引元素。 &lt;br /&gt;
&lt;br /&gt;
我们通过传递表格中元素的坐标，使用  [[CATable/zh|CATable]]的[[CATable::GetDataByElements/zh|GetDataByElements]]函数获取'''Cost'''表格对象的单个表格元素'''resultTable'''。 &lt;br /&gt;
&lt;br /&gt;
当我检索 [[CATable/zh|CATable]]对象中单个元素（'''resultTable'''）的时候，我们利用了该表格是一维的事实。因此，我们只需要传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个单一数（这个数代表表格中的位置）。但是，如果我们处理两个或者更多维度，我们必须传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个数组函数，并且指明我们要检索的表格元素的位置。因此，如果我们不想检索一个二维数组的position (4,3)位置的元素，我们可以这样写：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Dim W as Variant 'return element &lt;br /&gt;
:Dim IndexPtrs(1 To 2) As Variant 'position in table &lt;br /&gt;
::... &lt;br /&gt;
:IndexPtrs(1) = 4 &lt;br /&gt;
:IndexPtrs(2) = 3 &lt;br /&gt;
:W = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](IndexPtrs) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==控制基元值格式==&lt;br /&gt;
[[CATable/zh|CATable]]中的每个基元值可以是一个数、一个字符串，或者其它一些基本类型（''例如''：[[Null|空值]]、[[Undefined|未定义]]、[[Reference|参考]]，或 [[Handle|句柄]]。通过说明类型和值，它们作为''变体''被返回，这是一种Visual Basic能读懂的数据结构。[[CATable/zh|CATable]]的[[CATable::RenderingStyle|RenderingStyle]]属性控制Analytica基础值是如何映射到Visual Basic变体的。 &lt;br /&gt;
&lt;br /&gt;
例如：可以通过使用Analytica 模型的数字格式设置将一个数值返回成一个数字或者字符串。如果被指定格式，有一个选线控制是截断数字的位数，还是精确返回。 &lt;br /&gt;
&lt;br /&gt;
子程序[[PrintResultTable/zh|PrintResultTable]]在&amp;lt;tt&amp;gt;frmMain.vb&amp;lt;/tt&amp;gt;中载入,其渲染风格直接指明：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::NumberAsText/zh|NumberAsText]] = True &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::FullPrecision/zh|FullPrecision]] = False &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::StringQuotes/zh|StringQuotes]] = 2 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
第一行指明数值应该根据与结果对象有关的数字格式被格式化为文本。例如在其程序输出中，我们将看到&amp;lt;tt&amp;gt;30.103M&amp;lt;/tt&amp;gt;，而非&amp;lt;tt&amp;gt;30102995.6639812&amp;lt;/tt&amp;gt;，如果我们让Visual Basic将数值串联我们的结果字符串，将显示该结果。在此事件中，一个值为字符串的单元格出现在结果中，返回值将明确带双引号。对于[[CARenderingStyle/zh|CARenderingStyle]]对象中的所有可用属性，请参考[[CARenderingStyle/zh|CARenderingStyle]]。&lt;br /&gt;
&lt;br /&gt;
===其它访问表格的方式===&lt;br /&gt;
有几种访问多维表格[[CATable/zh|CATable]]中元素的方式。每一种都有可能在特定的场合使用起来比较方便。 &lt;br /&gt;
&lt;br /&gt;
第一种方式就是使用[[CATable/zh | CATable]]的 [[CATable::GetDataByElements/zh|GetDataByElements]]或[[CATable::GetDataByLabels/zh|GetDataByLabels]]方法，上面代码示例中有显示。在此情况下，利用你想获取的基元值的单元格位置。 &lt;br /&gt;
&lt;br /&gt;
第二种方式就是使用[[CATable/zh|CATable]][[CATable::Slice/zh|Slice]]或[[CATable::Subscript/zh | Subscript]]方法获取一个少一个维度的新[[CATable/zh|CATable]]对象。通过重复减少维度，最终将获得0维度，这时你将获得一个单一基元值。此时，[[CATable/zh|CATable]]的[[CATable::AtomicValue/zh|AtomicValue]]方法返回该值 。[[CATable::AtomicValue/zh|AtomicValue]]方法是唯一获取一个标值的方法（因为没有坐标位置）。如果你需要建立完整结果其中一个切片的图形图像，必须使用此方法。 &lt;br /&gt;
&lt;br /&gt;
第三种方式就是使用[[CATable/zh|CATable]]的[[CATable::GetSafeArray/zh|GetSafeArray]]方法，将多维数组转化成一个''安全数组''（或者一个.NET数组）。你可以在使用VB或者其它.NET语言直接处理多维数组。因为对于Analytica维度没有固定顺序，但是安全数组和.NET数组有一个明确的顺序，你必须先使用[[CATable/zh|CATable]]对象的[[CATable::SetIndexOrder/zh|SetIndexOrder]]方法在调用[[CATable::GetSafeArray/zh|GetSafeArray]]之前指明维度的顺序。注意如果你知道你的数组是一维的，那就没必要了。&lt;br /&gt;
&lt;br /&gt;
===修改对象===&lt;br /&gt;
一个自定义用户程序通常从一个用户或者其它外部源获取输入，以便转化成Analytica模型中的输入变量。你可以设定输入变量的定义或者通过使用定义表格来这样做。 &lt;br /&gt;
&lt;br /&gt;
'''TestTxc''' 说明了如何修改'''Pop_exp'''定义，此模型是一个影响结果变量Cost的模型输入。要想在该示例中设定该定义，从主菜单上选择'''File &amp;gt; Change Population'''。将出现一个对话框，如下图所示：&lt;br /&gt;
&lt;br /&gt;
[[File:RedefiningtheVariableDefinition.jpg|400px/zh|文件：RedefiningtheVariableDefinition.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
在信息栏中输入一个新定义并点击'''Ok'''确认。主窗口将显示一个新的Cost值。当点击该对话框中的'''Ok'''按钮时，调用了&amp;lt;tt&amp;gt;ChangeDef.frm&amp;lt;/tt&amp;gt;函数，然后调用[[PrintAttributes/zh|PrintAttributes]]函数打印&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果。&lt;br /&gt;
&lt;br /&gt;
此函数类似于：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Private Sub OkButton_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles OkButton.Click &lt;br /&gt;
::Dim errorText As String&lt;br /&gt;
::Dim pop_exp_Object As [[CAObject/zh|CAObject]] &lt;br /&gt;
::Dim errorCode As Short &lt;br /&gt;
::Dim errorString As String &lt;br /&gt;
::newDefinition = PopExposedDef.Text &lt;br /&gt;
::pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
::pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]](&amp;quot;[[Definition]]&amp;quot;, newDefinition) &lt;br /&gt;
::errorCode = adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &lt;br /&gt;
::If errorCode &amp;lt;&amp;gt; 0 Then &lt;br /&gt;
:::MsgBox(&amp;quot;This error occurred while processing your definition: &amp;quot; &amp;amp; vbCrLf &amp;amp; vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) :::PopExposedDef.Focus()&lt;br /&gt;
::Else&lt;br /&gt;
:::Me.Close() &lt;br /&gt;
:::frmMain.DefInstance.PrintAttributes(&amp;quot;Pop_exp&amp;quot;, &amp;quot;Cost&amp;quot;) &lt;br /&gt;
::End If &lt;br /&gt;
::ReleaseComObject(pop_exp_Object) &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
该函数抓取了输入到'''New Definition''' 新定义给'''Population Exposed'''栏，并通过使用[[CAObject/zh|CAObject]]对象中的[[CAObject::SetAttribute/zh|SetAttribute]]函数将它设置给&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;对象。然后调用[[PrintAttributes/zh|PrintAttributes]]，以计算&amp;lt;tt&amp;gt;Cost object&amp;lt;/tt&amp;gt;，并打印新的结果。要想给变量&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;设定一个新定义，我们可以为&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;获取[[CAObject/zh|CAObject]]对象，然后将其定义设置成用户输入的定义。通过使用下面的代码来实现：&lt;br /&gt;
:pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
:pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]]( &amp;quot;[[Definition]]&amp;quot;, newDefinition )&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
无论什么时候调用[[CAObject::SetAttribute/zh|SetAttribute]]，都应该检查[[CAEngine/zh|CAEngine]]自动化对象（'''adeEngine'''）的[[CAEngine::ErrorCode/zh|ErrorCode]]，以免它的定义是非法的。尝试一下输入一个新定义，比如&amp;lt;code&amp;gt;[[Uniform]](25M,35M)&amp;lt;/code&amp;gt;，然后点击'''Ok'''。当&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;的定义被改变时， &amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果由ADE重新计算，此时'''ResultTable'''接下来调用给Cost变量（在应用程序窗口重新显示时）。&lt;br /&gt;
&lt;br /&gt;
使用ADE绘图&lt;br /&gt;
&lt;br /&gt;
通过Analytica 4.6使用相同的绘图引擎，你可以建立一个图表或者图形以显示一个数组值或者不确定值结果。在ADE4.6中，你可以使用 [[CATable/zh|CATable]]的[[CATable::GraphToFile/zh|GraphToFile]]和[[CATable::GraphToStream/zh|GraphToStream]]方法。图形可以以几种可能的图像格式返回，例如'''image/png'''、 '''image/bmp'''或者 '''image/jpeg'''。 &lt;br /&gt;
&lt;br /&gt;
从可用图形选项中选择的最简单方式就是使用Analytica打开你的模型。你可以实验设置各种默认设置或者替代选择的变量，看它们是如何工作的。但你选择了你想设置的选项，保存模型。当为每一个生成结果图形时，ADE将使用这些设置。 &lt;br /&gt;
&lt;br /&gt;
对于更高维度的结果，可能需要做一些必要工作，以便选择将绘制结果的切片和具体的轴（也就是相对于图例哪个维度作为X轴）。[[CATable/zh|CATable]]的[[CATable::Subscript/zh|Subscript]]或[[CATable::Slice/zh|Slice]]方法可以用来控制轴选择特殊的切片用来绘制，能够用来控制轴。详情请参考[[CATable/zh|CATable]]。在我们的&amp;lt;tt&amp;gt;Tutorial.NET&amp;lt;/tt&amp;gt;示例中，我们有一个一维结果（&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;），因此我们没有必要担心截取或者绕轴旋转。 &lt;br /&gt;
&lt;br /&gt;
[[CATable::GraphToStream/zh|GraphToStream]]方法被用来从ADE中直接转化图形图形到一个用户界面中。使用[[CATable::GraphToStream/zh|GraphToStream]]比起使用[[CATable::GraphToFile/zh|GraphToFile]]来要稍微复杂一点，因为[[CATable::GraphToFile/zh|GraphToFile]]除了需要文件名以外还需要其它一些信息，以便编写图形。要使用[[CATable::GraphToStream/zh|GraphToStream]]，我们必须在内存内设置一个流，允许ADE写入该留，然后从该留重建。因为.NET流和COM流不兼容，你必须使用ADE一同提供的[[StreamConnector]]类型.&amp;lt;tt&amp;gt;frmMain&amp;lt;/tt&amp;gt; 中的'''GraphResult_Click'''子程序演示了[[CATable::GraphToStream/zh|GraphToStream]]的使用。从主应用程序窗口选择 '''Graph Result'''菜单选项，结果将出现在一个如下所示的图形当中：&lt;br /&gt;
&lt;br /&gt;
[[File:resultgraph.jpg/zh|文件：resultgraph.jpg]]&lt;br /&gt;
&lt;br /&gt;
==结论==&lt;br /&gt;
&lt;br /&gt;
在此教程中，我们介绍了Analytica决策引擎的几个重要方面。我们看到了如何建立一个ADE服务器对象，使用ADE打开模型，获取模型中的单个对象、计算对象、获取表格中的元素，以及修改模型中的对象。但是ADE可以做的远不止这些。 &lt;br /&gt;
&lt;br /&gt;
我们希望你已经足够了解其基本特征，这样你现在才能独自开始探索更多新的高级特征。我们建议你现在开始阅读字教程的剩余部分以了解ADE能做什么。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
| [[Installation of ADE/zh|ADE 安装]] &amp;lt;- ||  [[The ADE Tutorial/zh|ADE 入门教程]] || -&amp;gt; [[Using the ADE Server/zh|使用ADE服务器]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36298</id>
		<title>The ADE Tutorial/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36298"/>
		<updated>2015-10-27T06:27:09Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南 ]]&lt;br /&gt;
&lt;br /&gt;
此教程教你如何在一个Visual Basic程序中使用Analytica决策引擎（ADE）。&lt;br /&gt;
&lt;br /&gt;
==你的第一个ADE应用程序==&lt;br /&gt;
首先先从头开始写一个简单的ADE程序，只要确认一切设置正常。按照以下步骤操作：&lt;br /&gt;
&lt;br /&gt;
test&lt;br /&gt;
&lt;br /&gt;
第一个程序执行了以下操作：&lt;br /&gt;
*建立一个名称为ADE的[[CAEngine/zh|CAEngine]]自动化对象（通过使用&amp;lt;code&amp;gt;new [[CAEngine/zh|CAEngine]]&amp;lt;/code&amp;gt;).&lt;br /&gt;
*打开Analytica模型 (通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]] 方法。&lt;br /&gt;
*显示模型名称返回[[CAEngine::OpenModel/zh|OpenModel]]的值。&lt;br /&gt;
我们将在后面的章节详细了解这些信息。&lt;br /&gt;
&lt;br /&gt;
===接下来讲什么呢?===&lt;br /&gt;
我们不会尝试在此入门教程中解释ADE的特征。本指南后面几个章节会描述这些特征。 &lt;br /&gt;
&lt;br /&gt;
从现在开始，我们我们将使用名称为&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;的示例模型。打开 Analytica安装目录下 '''Example Models'''文件夹里面的'''Risk Analysis'''文件夹便可找到&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;文件。如果你找不到，或者你安装Analytica的时候未选择安装examples（示例）文件，在ADE安装目录下面的'''Examples\Tutorial.NET'''文件家中有一个副本。 &lt;br /&gt;
&lt;br /&gt;
Txc模型演示了减少污染物TXC排放的risk-benefit （风险-效益）分析。请用Analytica打开Txc查看它是如何工作的。 &lt;br /&gt;
&lt;br /&gt;
ADE '''Examples\Tutorial.NET''' 文件夹中名称为&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;的Visual Basic.NET程序示例显示了ADE很多方面。该程序建立了一个ADE自动化对象，打开包含该对象的&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，获取变量 &amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，计算变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;，通过获取每个表格的单独组件以表格的方式打印输出变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的结果，然后改变变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义。再次获取变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的值，看一下 变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;定义的改变对变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;有什么影响。如果设置正确的话,&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;将显示在“Text Txc window”中显示的窗口。 &lt;br /&gt;
&lt;br /&gt;
应用程序显示变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义（&amp;lt;tt&amp;gt;&amp;quot;Normal (30M, 3M)&amp;quot;&amp;lt;/tt&amp;gt;），以及与&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;关联的表格，这都基于&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义。你可以通过从主菜单选择'''File &amp;gt; Change Population Exposed'''改变&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，然后查看改变对&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;表格的影响。&lt;br /&gt;
&lt;br /&gt;
[[File:TextTxcWindow.png|400px/zh | 文件：TextTxcWindow.png|400px]]&lt;br /&gt;
&lt;br /&gt;
===区分title（名称） 和 identifier（标识符）===&lt;br /&gt;
无论什么时候，一个ADE函数都需要一个变量你必须传达变量的'''''[[Identifier|标识符]]''''' ，而不是它的'''''[[Title|名称]]'''''。这可能会引起混淆，因为在Analytica影响图中一般显示每一个变量的名称。默认情况下，在你最初建立每一个对象的时候，Analytica自动根据名称建立一个标识符。用（_）代替名称中的每一个空格或者其他非字母和数字字符。 &lt;br /&gt;
&lt;br /&gt;
你可以通过点击“Control+y”（或者从Object（对象）菜单选择'''Show by identifier''' ：显示标识符） 来以标识符显示变量。对于模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;，你可以看到名称为&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;变量的标识符为 &amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;。将变量传递给ADE函数时，使用标识符很重要。如果你传递&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;，ADE无法找到变量，并且将返回一个错误。&lt;br /&gt;
&lt;br /&gt;
===从Visual Basic中建立一个ADE 对象===&lt;br /&gt;
&lt;br /&gt;
如果你还没准备好，将名称为tt&amp;gt;Examples\Tutorial\TestTxc.sln&amp;lt;/tt&amp;gt;载入到Visual Basic.NET中，查看名称为&amp;lt;tt&amp;gt;TestTxc.vb&amp;lt;/tt&amp;gt;的文件的代码。其代码看起来像：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Imports ADEW &lt;br /&gt;
:. . . &lt;br /&gt;
:Public adeEngine As [[CAEngine/zh|CAEngine]]&lt;br /&gt;
&lt;br /&gt;
:Public Sub Main() &lt;br /&gt;
::Dim exeDirectory, theModel As String &lt;br /&gt;
::Dim theModelString As String &lt;br /&gt;
::exeDirectory = VB6.GetPath &lt;br /&gt;
::theModel = exeDirectory &amp;amp; &amp;quot;\..\&amp;quot; &amp;amp; &amp;quot;Txc.ana&amp;quot; &lt;br /&gt;
::adeEngine = New [[CAEngine/zh|CAEngine]]&lt;br /&gt;
::... &lt;br /&gt;
::theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
::... &lt;br /&gt;
::frmMain.DefInstance.Show() &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在每一个文件的顶部的代码将自动化对象 '''adeEngine''' 声明为一个[[CAEngine/zh|CAEngine]] 对象。使用此对象，我们能够访问 [[CAEngine/zh|CAEngine]] 展示的所有公共函数（参考 [[ADE Server Class Reference/zh|ADE服务器类型参考]] ）&lt;br /&gt;
&lt;br /&gt;
变量&amp;lt;tt&amp;gt;adeEngine&amp;lt;/tt&amp;gt;包含我们的进程内对象 [[CAEngine/zh|CAEngine]]。如果我们想使用ADE的本地（进程外）服务器版本，我们可以将一个项目参考添加到'''Analytica Decision Engine Server 4.6 COM''' 组件并将顶部行从&amp;lt;tt&amp;gt;Imports ADEW&amp;lt;/tt&amp;gt;改成&amp;lt;tt&amp;gt;Imports ADE&amp;lt;/tt&amp;gt;即可。 &lt;br /&gt;
&lt;br /&gt;
这里是另一种获得一个先[[CAEngine/zh|CAEngine]]对象的方法。此循序不需要给项目添加参考。&amp;lt;tt&amp;gt;&lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADEW4.6.CAEngine&amp;quot;) ’ in-process &lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADE4.6.CAEngine&amp;quot;) ’ out-of-process &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果想理解使用进程内和进程外（或本地）服务器的利与弊，以及哪一种自动化服务器用于不同的场景，参考[[Using_the_Analytica_Decision_Engine_Server#In-process_vs_Out-of-process/zh | In-process vs. out-of-process]]&lt;br /&gt;
&lt;br /&gt;
===COM和 Automation 接口比较===&lt;br /&gt;
在上面的例子当中，我们使用COM接口调用ADE。在一个COM 接口中，对象 在本例中为 [[CAEngine/zh|CAEngine]] 被声明为[[CAEngine/zh|CAEngine]] ，编译器解决每一个成员函数，并且在编译时间内能探测几个明显的错误。另外，Visual Studio可以提供方法和参数类型列表当，在你编程的时候可以当做一个提示工具，在编写使用ADE程序是非常有用。COM调用比Automation调用要快一点，但是在ADE应用程序中速度差异通常不是很重要。对于ADE 4.6我们推荐使用COM结构，只要你的语言支持。&lt;br /&gt;
&lt;br /&gt;
在VB Automation中，你可以将一个对象简单声明为Object（对象），而不是像 [[CAEngine/zh|CAEngine]]、[[CAObject/zh|CAObject]]等更加具体的类型。当使用Automation调用'''ADE'''方法时，在运行时间内确定方法。在编译时间内，编译器不知道你的 '''ADE''' 对象是否有一个名称为[[CAEngine::OpenModel/zh|OpenModel]]的函数。在VB中，调用COM方法或Automation 方法的语法是相通的——唯一的不同在于对象类型是否明确被声明。&lt;br /&gt;
&lt;br /&gt;
在VC++和C#中，调用COM的语法和调用Automatio的语法不同。在这些情况下，COM要方便的多，Automation能够获得相冗余。然而，同样的语言，包括VBScript和其他脚本语言，只支持Automation不支持COM。&lt;br /&gt;
&lt;br /&gt;
===监视Process（进程）===&lt;br /&gt;
当使用进程外ADE服务器时，你的代码必须在终止时释放[[CAEngine/zh|CAEngine]]COM对象。当最终[[CAEngine/zh|CAEngine]]使用被释放是，ADE.exe 进程自动终止。到目前为止所看到的代码，VB语言在达到程序末端时，自动处理释放对象。但是，当你调试你的代码是，你可以提前终止你的程序来修复bug，你的程序可能被Task Manager（任务管理器）终止，或者你自己的代码也可能奔溃，导致你的程序进程在它有机会释放对象之前终止。应为COM对象从来不会被释放，ADE.exe进程不知道它是否在使用中，你可能获得ADE.exe 僵尸进程。 &lt;br /&gt;
&lt;br /&gt;
为了避免这种情况发生，一种好的习惯就是在调用[[CAEngine/zh|CAEngine]]实例后 立即调用[[CAEngine::MonitorProcess/zh|CAEngine::MonitorProcess]]。通过这种方式，ADE能够得知哪一个进程正在使用它，同时将设置一个线程去探测你的进程是否在ADE被完全释放前终止。如果你的程序进程没有终止，ADE进程会立即将它关闭，消除了僵尸ADE进程的堆积。 &lt;br /&gt;
&lt;br /&gt;
要从一个.NET应用程序获得进程ID，使用System.Diagnostics.Process namespace中的'''GetCurrentProcess().Id''' 。在其他语言中，你可以使用Windows SDK 的'''GetProcessId( )'''函数。 &lt;br /&gt;
&lt;br /&gt;
'''[[CAEngine::MonitorProcess/zh|MonitorProcess]]()''' 只能用来监视运行ADE进程的同一台计算机的进程，一次当通过DCOM运行ADE时不能使用。当使用进程内ADEW服务器时没有必要使用。&lt;br /&gt;
&lt;br /&gt;
==打开使用ADE的模型==&lt;br /&gt;
我们现在打开&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，显示我们的应用程序主窗口。使用以下调用：tt&amp;gt;&lt;br /&gt;
:theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
:frmMain.DefInstance.Show &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]]函数打开模型。如果成功的话，变量&amp;lt;tt&amp;gt;theModelString&amp;lt;/tt&amp;gt;将包含模型的名字。否则，将包含一个空的串。虽然由于为了简介的缘故，我们没有这样做，但是你应该检查从[[CAEngine::OpenModel/zh|OpenModel]]函数返回的是不是一个空的串。如果是，说明在你打开的模型中存在一个错误。你可以使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/z |ErrorText]]属性找出是哪种错误 （&amp;lt;tt&amp;gt;adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] 和adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]&amp;lt;/tt&amp;gt;）。&lt;br /&gt;
&lt;br /&gt;
==从Analytica模型中检索对象==&lt;br /&gt;
下一步就是从我们的模型中检索对象（变量、模块、函数等），以便我们能获取他们的属性（[[definition|定义]]、[[title|名称]]、[[class|类型]]等等 ）。我们的示例模型（&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;）操作&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;和&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;对象。尤其是，修改&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;可以查看这是如何影响&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt; 对象。&lt;br /&gt;
&lt;br /&gt;
我们的&amp;lt;tt&amp;gt;TxcTest.vbproj&amp;lt;/tt&amp;gt; （&amp;lt;tt&amp;gt;TxcText.sln&amp;lt;/tt&amp;gt;）项目中的&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;文件里的 '''PrintAttributes''' 函数演示了如何检索对象。该函数首先被&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''Form_Load''' 函数调用，当应用程序启动后，可以显示'''Cost'''表格。当然无论什么时候，只要我们想输出'''Cost'''表格的当前值，都可以调用。该函数如下所示：&lt;br /&gt;
:Public Sub PrintAttributes(ByRef inputIdentifier As String, ByRef  outputIdentifier As String) &lt;br /&gt;
::Dim inputObject, outputObject As [[CAObject/zh|CAObject]]&lt;br /&gt;
::Dim resultTable As [[CATable/zh|CATable]]&lt;br /&gt;
::Dim definitionAttrInput As String &lt;br /&gt;
::inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
::outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier) &lt;br /&gt;
::definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;definition&amp;quot;) &lt;br /&gt;
::resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]]&lt;br /&gt;
::Call PrintResultTable(resultTable, inputIdentifier, definitionAttrInput, outputIdentifier) &lt;br /&gt;
::ReleaseComObject(resultTable) &lt;br /&gt;
::ReleaseComObject(inputObject) &lt;br /&gt;
::ReleaseComObject(outputObject) &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''PrintAttributes'''和作为'''inputIdentifier'''参数的&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;变量标识符以及作为'''outputIdentifier'''参数的'''Cost'''变量一起使用。如下所示通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::GetObjectByName/zh|GetObjectByName]]函数提取相应对象：&amp;lt;tt&amp;gt;&lt;br /&gt;
:inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取成功，将返回一个[[CAObject/zh|CAObject]]类型对象。如果使用'''[[CAObject/zh|CAObject]]'''的函数，参考[[CAObject/zh|SendCommand(command)]]，可以获得一个[[CAObject/zh|CAObject]]的完整函数列表。如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取失败，返回值为&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;。代码应该检查以确保[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取的结果是有效的。如果找不到，可使用[[CAEngine/zh|CAEngine]]的 [[CAEngine::ErrorCode/zh|ErrorCode]]和 [[CAEngine::ErrorText/zh|ErrorText]]属性获取错误信息。例如：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Set inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:If inputObject Is Nothing Then &lt;br /&gt;
::MsgBox(“This error from GetObjectByName occurred: “&amp;amp; _ vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &amp;amp; “:” &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) &lt;br /&gt;
:Else &lt;br /&gt;
::'inputObject valid &lt;br /&gt;
:End If&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===获取对象属性===&lt;br /&gt;
每一个Analytica对象都有一组属性，例如[[identifier|标识符]]、[[title|名称]]、[[description| 描述]]和[[class|类型]]。你可以使用[[CAObject::GetAttribute/zh|GetAttribute]]函数来获去Analytica对象的属性。例如，如要获取'''inputObject'''的定义（当前为cost）：&amp;lt;tt&amp;gt;&lt;br /&gt;
:definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh|GetAttribute]](&amp;quot;[[Definition|定义]]&amp;quot;) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt; 中，&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;的定义为&amp;quot;&amp;lt;tt&amp;gt;[[Normal]](30M, 3M)&amp;lt;/tt&amp;gt;&amp;quot; ，我们将它储存在'''definitionAttrInput'''当中。.&lt;br /&gt;
&lt;br /&gt;
===计算对象和检索结果===&lt;br /&gt;
使用[[CAObject/zh|CAObject]]的[[CAObject::Result/zh|Result]]或[[CAObject::ResultTable/zh|ResultTable]]方法来获取变量的值。如果有必要的话，ADE先自动计算变量。如果你确定结果为基元（只有一个元素），使用[[CAObject::Result/zh|Result]]方法。否则使用[[CAObject::ResultTable/zh|ResultTable]]，检索结果为一个''数组''。基元结果当作一个特殊数组案例来处理，没有维度的数组。如果值为基元[[CATable::AtomicValue/zh|AtomicValue]]方法将返回一个数字或者字符串单一值。 &lt;br /&gt;
&lt;br /&gt;
默认情况下，[[CAObject::Result/zh|Result]]和[[CAObject::ResultTable/zh|ResultTable]]返回结果的中值，也就是说，ADE以确定性方式计算结果。对于一个概率值，将[[CAObject/zh|CAObject]]的[[CAObject::ResultType/zh|ResultType]]属性设置为想要的不确定性视图——Mean（平均值） Sample（样本）、PDF（概率密度函数）、CDF（累计分布函数）、Confidence bands（置信带）、或者Statistics（统计数据）详情请参考[[CAObject::ResultType/zh|ResultType]]。我们通过如下的方式获取outputObject 输出对象 的值：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]] &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
结果为一个[[CATable/zh|CATable]]对象，允许我们访问一个表格中的单个元素。 &lt;br /&gt;
&lt;br /&gt;
如果你通过调用[[CAObject::Result/zh|Result]]来获取一个数组（或者表格）的值，将返回数组为一个字符串，列出索引和元素，以逗号隔开。通常使用[[CAObject::ResultTable/zh|ResultTable]]更加简单，这样你没有必要从字符串中解析表格的元素。&lt;br /&gt;
&lt;br /&gt;
===获取表格索引元素===&lt;br /&gt;
一个Analytica表格包含0个或者多个索引。如果包含一个索引，那么该表格是1维表格；如果有2个索引，说他是2维表格，依此类推。0维度表格包含一个“单一基元”（或标量）值。你可以使用CATable的[[CATable::NumDims/zh | NumDims]]获取表格的维数（也就是索引数）。要想获取表格的单个索引，可使用[[CATable/zh | CATable]]的 [[CATable::IndexNames/zh | IndexNames]]和 [[CATable::GetIndexObject/zh | GetIndexObject]]函数。 &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''PrintResultTable'''函数说明了这两个函数的使用。从'''PrintAttributes'''中调用'''PrintResultTable'''，执行打印'''TestTxc'''中的表格的实际工作（为了简洁起见，我们只给出了关联ADE的该函数部分）。&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Public Sub PrintResultTable(ByRef resultTable As CATable, ByRef inputIdentifier As String, ByRef definitionAttrInput As String, ByRef outputIdentifier As String) &lt;br /&gt;
::Dim theIndexName, theTableName As String &lt;br /&gt;
::Dim theIndexElement As String &lt;br /&gt;
::Dim theTableElement &lt;br /&gt;
::Dim theIndexObj As [[CAIndex/zh | CAIndex]]&lt;br /&gt;
::Dim numEls As Integer &lt;br /&gt;
::Dim spaces, i As Integer &lt;br /&gt;
::Dim lenStr As Short &lt;br /&gt;
::Dim OutputStr As Short &lt;br /&gt;
::Dim spaceString, underlineString As String &lt;br /&gt;
::... &lt;br /&gt;
::theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1) &lt;br /&gt;
::theTableName = resultTable.[[CATable::Name/zh|Name]] &lt;br /&gt;
::theIndexObj = resultTable.[[CATable::GetIndexObject/zh | GetIndexObject]](theIndexName) &lt;br /&gt;
::numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
::... &lt;br /&gt;
::For i = 1 To numEls &lt;br /&gt;
:::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
:::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
:::... &lt;br /&gt;
::Next i &lt;br /&gt;
::InformationPane.Text = outputString &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
通过'''PrintResultTable'''获取一个表格的索引方法如下：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1)&lt;br /&gt;
:theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
我们通过使用[[CATable/zh|CATable]]的[[CATable::IndexNames/zh|IndexNames]]函数获取第一个索引的名字。我们将它传递给[[CATable/zh|CATable]]的[[CATable::GetIndexObject/zh|GetIndexObject]]函数以获取表示我们的索引的[[CAIndex/zh|CAIndex]]。该自动化对象返回其相应索引的相关信息。如果此函数调用失败，将返回&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;信息。在此情况下，使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]] 函数找出原因。&lt;br /&gt;
&lt;br /&gt;
==从CATable和CAIndex中获取信息==&lt;br /&gt;
[[PrintResultTable]]说明了如何从[[CATable/zh| CATable]]和[[CAIndex/zh|CAIndex]] 对象获取信息。该代码获取'''Cost'''表格的索引和表格元素：&lt;br /&gt;
: &amp;lt;tt&amp;gt;&lt;br /&gt;
:numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
:For i = 1 To numEls &lt;br /&gt;
::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
::... &lt;br /&gt;
:Next i &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[CAIndex/zh|CAIndex]]的[[CAIndex::IndexElements/zh|IndexElements]]属性返回第一个索引中的元素个数。[[CAIndex/zh|CAIndex]]的[[CAIndex::GetValueByNumber/zh|GetValueByNumber]]函数获取单个索引元素。 &lt;br /&gt;
&lt;br /&gt;
我们通过传递表格中元素的坐标，使用  [[CATable/zh|CATable]]的[[CATable::GetDataByElements/zh|GetDataByElements]]函数获取'''Cost'''表格对象的单个表格元素'''resultTable'''。 &lt;br /&gt;
&lt;br /&gt;
当我检索 [[CATable/zh|CATable]]对象中单个元素（'''resultTable'''）的时候，我们利用了该表格是一维的事实。因此，我们只需要传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个单一数（这个数代表表格中的位置）。但是，如果我们处理两个或者更多维度，我们必须传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个数组函数，并且指明我们要检索的表格元素的位置。因此，如果我们不想检索一个二维数组的position (4,3)位置的元素，我们可以这样写：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Dim W as Variant 'return element &lt;br /&gt;
:Dim IndexPtrs(1 To 2) As Variant 'position in table &lt;br /&gt;
::... &lt;br /&gt;
:IndexPtrs(1) = 4 &lt;br /&gt;
:IndexPtrs(2) = 3 &lt;br /&gt;
:W = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](IndexPtrs) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==控制基元值格式==&lt;br /&gt;
[[CATable/zh|CATable]]中的每个基元值可以是一个数、一个字符串，或者其它一些基本类型（''例如''：[[Null|空值]]、[[Undefined|未定义]]、[[Reference|参考]]，或 [[Handle|句柄]]。通过说明类型和值，它们作为''变体''被返回，这是一种Visual Basic能读懂的数据结构。[[CATable/zh|CATable]]的[[CATable::RenderingStyle|RenderingStyle]]属性控制Analytica基础值是如何映射到Visual Basic变体的。 &lt;br /&gt;
&lt;br /&gt;
例如：可以通过使用Analytica 模型的数字格式设置将一个数值返回成一个数字或者字符串。如果被指定格式，有一个选线控制是截断数字的位数，还是精确返回。 &lt;br /&gt;
&lt;br /&gt;
子程序[[PrintResultTable/zh|PrintResultTable]]在&amp;lt;tt&amp;gt;frmMain.vb&amp;lt;/tt&amp;gt;中载入,其渲染风格直接指明：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::NumberAsText/zh|NumberAsText]] = True &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::FullPrecision/zh|FullPrecision]] = False &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::StringQuotes/zh|StringQuotes]] = 2 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
第一行指明数值应该根据与结果对象有关的数字格式被格式化为文本。例如在其程序输出中，我们将看到&amp;lt;tt&amp;gt;30.103M&amp;lt;/tt&amp;gt;，而非&amp;lt;tt&amp;gt;30102995.6639812&amp;lt;/tt&amp;gt;，如果我们让Visual Basic将数值串联我们的结果字符串，将显示该结果。在此事件中，一个值为字符串的单元格出现在结果中，返回值将明确带双引号。对于[[CARenderingStyle/zh|CARenderingStyle]]对象中的所有可用属性，请参考[[CARenderingStyle/zh|CARenderingStyle]]。&lt;br /&gt;
&lt;br /&gt;
===其它访问表格的方式===&lt;br /&gt;
有几种访问多维表格[[CATable/zh|CATable]]中元素的方式。每一种都有可能在特定的场合使用起来比较方便。 &lt;br /&gt;
&lt;br /&gt;
第一种方式就是使用[[CATable/zh | CATable]]的 [[CATable::GetDataByElements/zh|GetDataByElements]]或[[CATable::GetDataByLabels/zh|GetDataByLabels]]方法，上面代码示例中有显示。在此情况下，利用你想获取的基元值的单元格位置。 &lt;br /&gt;
&lt;br /&gt;
第二种方式就是使用[[CATable/zh|CATable]][[CATable::Slice/zh|Slice]]或[[CATable::Subscript/zh | Subscript]]方法获取一个少一个维度的新[[CATable/zh|CATable]]对象。通过重复减少维度，最终将获得0维度，这时你将获得一个单一基元值。此时，[[CATable/zh|CATable]]的[[CATable::AtomicValue/zh|AtomicValue]]方法返回该值 。[[CATable::AtomicValue/zh|AtomicValue]]方法是唯一获取一个标值的方法（因为没有坐标位置）。如果你需要建立完整结果其中一个切片的图形图像，必须使用此方法。 &lt;br /&gt;
&lt;br /&gt;
第三种方式就是使用[[CATable/zh|CATable]]的[[CATable::GetSafeArray/zh|GetSafeArray]]方法，将多维数组转化成一个''安全数组''（或者一个.NET数组）。你可以在使用VB或者其它.NET语言直接处理多维数组。因为对于Analytica维度没有固定顺序，但是安全数组和.NET数组有一个明确的顺序，你必须先使用[[CATable/zh|CATable]]对象的[[CATable::SetIndexOrder/zh|SetIndexOrder]]方法在调用[[CATable::GetSafeArray/zh|GetSafeArray]]之前指明维度的顺序。注意如果你知道你的数组是一维的，那就没必要了。&lt;br /&gt;
&lt;br /&gt;
===修改对象===&lt;br /&gt;
一个自定义用户程序通常从一个用户或者其它外部源获取输入，以便转化成Analytica模型中的输入变量。你可以设定输入变量的定义或者通过使用定义表格来这样做。 &lt;br /&gt;
&lt;br /&gt;
'''TestTxc''' 说明了如何修改'''Pop_exp'''定义，此模型是一个影响结果变量Cost的模型输入。要想在该示例中设定该定义，从主菜单上选择'''File &amp;gt; Change Population'''。将出现一个对话框，如下图所示：&lt;br /&gt;
&lt;br /&gt;
[[File:RedefiningtheVariableDefinition.jpg|400px/zh|文件：RedefiningtheVariableDefinition.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
在信息栏中输入一个新定义并点击'''Ok'''确认。主窗口将显示一个新的Cost值。当点击该对话框中的'''Ok'''按钮时，调用了&amp;lt;tt&amp;gt;ChangeDef.frm&amp;lt;/tt&amp;gt;函数，然后调用[[PrintAttributes/zh|PrintAttributes]]函数打印&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果。&lt;br /&gt;
&lt;br /&gt;
此函数类似于：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Private Sub OkButton_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles OkButton.Click &lt;br /&gt;
::Dim errorText As String&lt;br /&gt;
::Dim pop_exp_Object As [[CAObject/zh|CAObject]] &lt;br /&gt;
::Dim errorCode As Short &lt;br /&gt;
::Dim errorString As String &lt;br /&gt;
::newDefinition = PopExposedDef.Text &lt;br /&gt;
::pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
::pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]](&amp;quot;[[Definition]]&amp;quot;, newDefinition) &lt;br /&gt;
::errorCode = adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &lt;br /&gt;
::If errorCode &amp;lt;&amp;gt; 0 Then &lt;br /&gt;
:::MsgBox(&amp;quot;This error occurred while processing your definition: &amp;quot; &amp;amp; vbCrLf &amp;amp; vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) :::PopExposedDef.Focus()&lt;br /&gt;
::Else&lt;br /&gt;
:::Me.Close() &lt;br /&gt;
:::frmMain.DefInstance.PrintAttributes(&amp;quot;Pop_exp&amp;quot;, &amp;quot;Cost&amp;quot;) &lt;br /&gt;
::End If &lt;br /&gt;
::ReleaseComObject(pop_exp_Object) &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
该函数抓取了输入到'''New Definition''' 新定义给'''Population Exposed'''栏，并通过使用[[CAObject/zh|CAObject]]对象中的[[CAObject::SetAttribute/zh|SetAttribute]]函数将它设置给&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;对象。然后调用[[PrintAttributes/zh|PrintAttributes]]，以计算&amp;lt;tt&amp;gt;Cost object&amp;lt;/tt&amp;gt;，并打印新的结果。要想给变量&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;设定一个新定义，我们可以为&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;获取[[CAObject/zh|CAObject]]对象，然后将其定义设置成用户输入的定义。通过使用下面的代码来实现：&lt;br /&gt;
:pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
:pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]]( &amp;quot;[[Definition]]&amp;quot;, newDefinition )&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
无论什么时候调用[[CAObject::SetAttribute/zh|SetAttribute]]，都应该检查[[CAEngine/zh|CAEngine]]自动化对象（'''adeEngine'''）的[[CAEngine::ErrorCode/zh|ErrorCode]]，以免它的定义是非法的。尝试一下输入一个新定义，比如&amp;lt;code&amp;gt;[[Uniform]](25M,35M)&amp;lt;/code&amp;gt;，然后点击'''Ok'''。当&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;的定义被改变时， &amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果由ADE重新计算，此时'''ResultTable'''接下来调用给Cost变量（在应用程序窗口重新显示时）。&lt;br /&gt;
&lt;br /&gt;
使用ADE绘图&lt;br /&gt;
&lt;br /&gt;
通过Analytica 4.6使用相同的绘图引擎，你可以建立一个图表或者图形以显示一个数组值或者不确定值结果。在ADE4.6中，你可以使用 [[CATable/zh|CATable]]的[[CATable::GraphToFile/zh|GraphToFile]]和[[CATable::GraphToStream/zh|GraphToStream]]方法。图形可以以几种可能的图像格式返回，例如'''image/png'''、 '''image/bmp'''或者 '''image/jpeg'''。 &lt;br /&gt;
&lt;br /&gt;
从可用图形选项中选择的最简单方式就是使用Analytica打开你的模型。你可以实验设置各种默认设置或者替代选择的变量，看它们是如何工作的。但你选择了你想设置的选项，保存模型。当为每一个生成结果图形时，ADE将使用这些设置。 &lt;br /&gt;
&lt;br /&gt;
对于更高维度的结果，可能需要做一些必要工作，以便选择将绘制结果的切片和具体的轴（也就是相对于图例哪个维度作为X轴）。[[CATable/zh|CATable]]的[[CATable::Subscript/zh|Subscript]]或[[CATable::Slice/zh|Slice]]方法可以用来控制轴选择特殊的切片用来绘制，能够用来控制轴。详情请参考[[CATable/zh|CATable]]。在我们的&amp;lt;tt&amp;gt;Tutorial.NET&amp;lt;/tt&amp;gt;示例中，我们有一个一维结果（&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;），因此我们没有必要担心截取或者绕轴旋转。 &lt;br /&gt;
&lt;br /&gt;
[[CATable::GraphToStream/zh|GraphToStream]]方法被用来从ADE中直接转化图形图形到一个用户界面中。使用[[CATable::GraphToStream/zh|GraphToStream]]比起使用[[CATable::GraphToFile/zh|GraphToFile]]来要稍微复杂一点，因为[[CATable::GraphToFile/zh|GraphToFile]]除了需要文件名以外还需要其它一些信息，以便编写图形。要使用[[CATable::GraphToStream/zh|GraphToStream]]，我们必须在内存内设置一个流，允许ADE写入该留，然后从该留重建。因为.NET流和COM流不兼容，你必须使用ADE一同提供的[[StreamConnector]]类型.&amp;lt;tt&amp;gt;frmMain&amp;lt;/tt&amp;gt; 中的'''GraphResult_Click'''子程序演示了[[CATable::GraphToStream/zh|GraphToStream]]的使用。从主应用程序窗口选择 '''Graph Result'''菜单选项，结果将出现在一个如下所示的图形当中：&lt;br /&gt;
&lt;br /&gt;
[[File:resultgraph.jpg/zh|文件：resultgraph.jpg]]&lt;br /&gt;
&lt;br /&gt;
==结论==&lt;br /&gt;
&lt;br /&gt;
在此教程中，我们介绍了Analytica决策引擎的几个重要方面。我们看到了如何建立一个ADE服务器对象，使用ADE打开模型，获取模型中的单个对象、计算对象、获取表格中的元素，以及修改模型中的对象。但是ADE可以做的远不止这些。 &lt;br /&gt;
&lt;br /&gt;
我们希望你已经足够了解其基本特征，这样你现在才能独自开始探索更多新的高级特征。我们建议你现在开始阅读字教程的剩余部分以了解ADE能做什么。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
| [[Installation of ADE/zh|ADE 安装]] &amp;lt;- ||  [[The ADE Tutorial/zh|ADE 入门教程]] || -&amp;gt; [[Using the ADE Server/zh|使用ADE服务器]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36296</id>
		<title>The ADE Tutorial/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36296"/>
		<updated>2015-10-27T06:27:06Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南 ]]&lt;br /&gt;
&lt;br /&gt;
此教程教你如何在一个Visual Basic程序中使用Analytica决策引擎（ADE）。&lt;br /&gt;
&lt;br /&gt;
==你的第一个ADE应用程序==&lt;br /&gt;
首先先从头开始写一个简单的ADE程序，只要确认一切设置正常。按照以下步骤操作：&lt;br /&gt;
&lt;br /&gt;
test&lt;br /&gt;
&lt;br /&gt;
第一个程序执行了以下操作：&lt;br /&gt;
*建立一个名称为ADE的[[CAEngine/zh|CAEngine]]自动化对象（通过使用&amp;lt;code&amp;gt;new [[CAEngine/zh|CAEngine]]&amp;lt;/code&amp;gt;).&lt;br /&gt;
*打开Analytica模型 (通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]] 方法。&lt;br /&gt;
*显示模型名称返回[[CAEngine::OpenModel/zh|OpenModel]]的值。&lt;br /&gt;
我们将在后面的章节详细了解这些信息。&lt;br /&gt;
&lt;br /&gt;
===接下来讲什么呢?===&lt;br /&gt;
我们不会尝试在此入门教程中解释ADE的特征。本指南后面几个章节会描述这些特征。 &lt;br /&gt;
&lt;br /&gt;
从现在开始，我们我们将使用名称为&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;的示例模型。打开 Analytica安装目录下 '''Example Models'''文件夹里面的'''Risk Analysis'''文件夹便可找到&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;文件。如果你找不到，或者你安装Analytica的时候未选择安装examples（示例）文件，在ADE安装目录下面的'''Examples\Tutorial.NET'''文件家中有一个副本。 &lt;br /&gt;
&lt;br /&gt;
Txc模型演示了减少污染物TXC排放的risk-benefit （风险-效益）分析。请用Analytica打开Txc查看它是如何工作的。 &lt;br /&gt;
&lt;br /&gt;
ADE '''Examples\Tutorial.NET''' 文件夹中名称为&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;的Visual Basic.NET程序示例显示了ADE很多方面。该程序建立了一个ADE自动化对象，打开包含该对象的&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，获取变量 &amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，计算变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;，通过获取每个表格的单独组件以表格的方式打印输出变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的结果，然后改变变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义。再次获取变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的值，看一下 变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;定义的改变对变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;有什么影响。如果设置正确的话,&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;将显示在“Text Txc window”中显示的窗口。 &lt;br /&gt;
&lt;br /&gt;
应用程序显示变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义（&amp;lt;tt&amp;gt;&amp;quot;Normal (30M, 3M)&amp;quot;&amp;lt;/tt&amp;gt;），以及与&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;关联的表格，这都基于&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义。你可以通过从主菜单选择'''File &amp;gt; Change Population Exposed'''改变&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，然后查看改变对&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;表格的影响。&lt;br /&gt;
&lt;br /&gt;
[[File:TextTxcWindow.png|400px/zh | 文件：TextTxcWindow.png|400px]]&lt;br /&gt;
&lt;br /&gt;
===区分title（名称） 和 identifier（标识符）===&lt;br /&gt;
无论什么时候，一个ADE函数都需要一个变量你必须传达变量的'''''[[Identifier|标识符]]''''' ，而不是它的'''''[[Title|名称]]'''''。这可能会引起混淆，因为在Analytica影响图中一般显示每一个变量的名称。默认情况下，在你最初建立每一个对象的时候，Analytica自动根据名称建立一个标识符。用（_）代替名称中的每一个空格或者其他非字母和数字字符。 &lt;br /&gt;
&lt;br /&gt;
你可以通过点击“Control+y”（或者从Object（对象）菜单选择'''Show by identifier''' ：显示标识符） 来以标识符显示变量。对于模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;，你可以看到名称为&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;变量的标识符为 &amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;。将变量传递给ADE函数时，使用标识符很重要。如果你传递&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;，ADE无法找到变量，并且将返回一个错误。&lt;br /&gt;
&lt;br /&gt;
===从Visual Basic中建立一个ADE 对象===&lt;br /&gt;
&lt;br /&gt;
如果你还没准备好，将名称为tt&amp;gt;Examples\Tutorial\TestTxc.sln&amp;lt;/tt&amp;gt;载入到Visual Basic.NET中，查看名称为&amp;lt;tt&amp;gt;TestTxc.vb&amp;lt;/tt&amp;gt;的文件的代码。其代码看起来像：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Imports ADEW &lt;br /&gt;
:. . . &lt;br /&gt;
:Public adeEngine As [[CAEngine/zh|CAEngine]]&lt;br /&gt;
&lt;br /&gt;
:Public Sub Main() &lt;br /&gt;
::Dim exeDirectory, theModel As String &lt;br /&gt;
::Dim theModelString As String &lt;br /&gt;
::exeDirectory = VB6.GetPath &lt;br /&gt;
::theModel = exeDirectory &amp;amp; &amp;quot;\..\&amp;quot; &amp;amp; &amp;quot;Txc.ana&amp;quot; &lt;br /&gt;
::adeEngine = New [[CAEngine/zh|CAEngine]]&lt;br /&gt;
::... &lt;br /&gt;
::theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
::... &lt;br /&gt;
::frmMain.DefInstance.Show() &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在每一个文件的顶部的代码将自动化对象 '''adeEngine''' 声明为一个[[CAEngine/zh|CAEngine]] 对象。使用此对象，我们能够访问 [[CAEngine/zh|CAEngine]] 展示的所有公共函数（参考 [[ADE Server Class Reference/zh|ADE服务器类型参考]] ）&lt;br /&gt;
&lt;br /&gt;
变量&amp;lt;tt&amp;gt;adeEngine&amp;lt;/tt&amp;gt;包含我们的进程内对象 [[CAEngine/zh|CAEngine]]。如果我们想使用ADE的本地（进程外）服务器版本，我们可以将一个项目参考添加到'''Analytica Decision Engine Server 4.6 COM''' 组件并将顶部行从&amp;lt;tt&amp;gt;Imports ADEW&amp;lt;/tt&amp;gt;改成&amp;lt;tt&amp;gt;Imports ADE&amp;lt;/tt&amp;gt;即可。 &lt;br /&gt;
&lt;br /&gt;
这里是另一种获得一个先[[CAEngine/zh|CAEngine]]对象的方法。此循序不需要给项目添加参考。&amp;lt;tt&amp;gt;&lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADEW4.6.CAEngine&amp;quot;) ’ in-process &lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADE4.6.CAEngine&amp;quot;) ’ out-of-process &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果想理解使用进程内和进程外（或本地）服务器的利与弊，以及哪一种自动化服务器用于不同的场景，参考[[Using_the_Analytica_Decision_Engine_Server#In-process_vs_Out-of-process/zh | In-process vs. out-of-process]]&lt;br /&gt;
&lt;br /&gt;
===COM和 Automation 接口比较===&lt;br /&gt;
在上面的例子当中，我们使用COM接口调用ADE。在一个COM 接口中，对象 在本例中为 [[CAEngine/zh|CAEngine]] 被声明为[[CAEngine/zh|CAEngine]] ，编译器解决每一个成员函数，并且在编译时间内能探测几个明显的错误。另外，Visual Studio可以提供方法和参数类型列表当，在你编程的时候可以当做一个提示工具，在编写使用ADE程序是非常有用。COM调用比Automation调用要快一点，但是在ADE应用程序中速度差异通常不是很重要。对于ADE 4.6我们推荐使用COM结构，只要你的语言支持。&lt;br /&gt;
&lt;br /&gt;
在VB Automation中，你可以将一个对象简单声明为Object（对象），而不是像 [[CAEngine/zh|CAEngine]]、[[CAObject/zh|CAObject]]等更加具体的类型。当使用Automation调用'''ADE'''方法时，在运行时间内确定方法。在编译时间内，编译器不知道你的 '''ADE''' 对象是否有一个名称为[[CAEngine::OpenModel/zh|OpenModel]]的函数。在VB中，调用COM方法或Automation 方法的语法是相通的——唯一的不同在于对象类型是否明确被声明。&lt;br /&gt;
&lt;br /&gt;
在VC++和C#中，调用COM的语法和调用Automatio的语法不同。在这些情况下，COM要方便的多，Automation能够获得相冗余。然而，同样的语言，包括VBScript和其他脚本语言，只支持Automation不支持COM。&lt;br /&gt;
&lt;br /&gt;
===监视Process（进程）===&lt;br /&gt;
当使用进程外ADE服务器时，你的代码必须在终止时释放[[CAEngine/zh|CAEngine]]COM对象。当最终[[CAEngine/zh|CAEngine]]使用被释放是，ADE.exe 进程自动终止。到目前为止所看到的代码，VB语言在达到程序末端时，自动处理释放对象。但是，当你调试你的代码是，你可以提前终止你的程序来修复bug，你的程序可能被Task Manager（任务管理器）终止，或者你自己的代码也可能奔溃，导致你的程序进程在它有机会释放对象之前终止。应为COM对象从来不会被释放，ADE.exe进程不知道它是否在使用中，你可能获得ADE.exe 僵尸进程。 &lt;br /&gt;
&lt;br /&gt;
为了避免这种情况发生，一种好的习惯就是在调用[[CAEngine/zh|CAEngine]]实例后 立即调用[[CAEngine::MonitorProcess/zh|CAEngine::MonitorProcess]]。通过这种方式，ADE能够得知哪一个进程正在使用它，同时将设置一个线程去探测你的进程是否在ADE被完全释放前终止。如果你的程序进程没有终止，ADE进程会立即将它关闭，消除了僵尸ADE进程的堆积。 &lt;br /&gt;
&lt;br /&gt;
要从一个.NET应用程序获得进程ID，使用System.Diagnostics.Process namespace中的'''GetCurrentProcess().Id''' 。在其他语言中，你可以使用Windows SDK 的'''GetProcessId( )'''函数。 &lt;br /&gt;
&lt;br /&gt;
'''[[CAEngine::MonitorProcess/zh|MonitorProcess]]()''' 只能用来监视运行ADE进程的同一台计算机的进程，一次当通过DCOM运行ADE时不能使用。当使用进程内ADEW服务器时没有必要使用。&lt;br /&gt;
&lt;br /&gt;
==打开使用ADE的模型==&lt;br /&gt;
我们现在打开&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，显示我们的应用程序主窗口。使用以下调用：tt&amp;gt;&lt;br /&gt;
:theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
:frmMain.DefInstance.Show &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]]函数打开模型。如果成功的话，变量&amp;lt;tt&amp;gt;theModelString&amp;lt;/tt&amp;gt;将包含模型的名字。否则，将包含一个空的串。虽然由于为了简介的缘故，我们没有这样做，但是你应该检查从[[CAEngine::OpenModel/zh|OpenModel]]函数返回的是不是一个空的串。如果是，说明在你打开的模型中存在一个错误。你可以使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/z |ErrorText]]属性找出是哪种错误 （&amp;lt;tt&amp;gt;adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] 和adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]&amp;lt;/tt&amp;gt;）。&lt;br /&gt;
&lt;br /&gt;
==从Analytica模型中检索对象==&lt;br /&gt;
下一步就是从我们的模型中检索对象（变量、模块、函数等），以便我们能获取他们的属性（[[definition|定义]]、[[title|名称]]、[[class|类型]]等等 ）。我们的示例模型（&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;）操作&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;和&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;对象。尤其是，修改&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;可以查看这是如何影响&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt; 对象。&lt;br /&gt;
&lt;br /&gt;
我们的&amp;lt;tt&amp;gt;TxcTest.vbproj&amp;lt;/tt&amp;gt; （&amp;lt;tt&amp;gt;TxcText.sln&amp;lt;/tt&amp;gt;）项目中的&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;文件里的 '''PrintAttributes''' 函数演示了如何检索对象。该函数首先被&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''Form_Load''' 函数调用，当应用程序启动后，可以显示'''Cost'''表格。当然无论什么时候，只要我们想输出'''Cost'''表格的当前值，都可以调用。该函数如下所示：&lt;br /&gt;
:Public Sub PrintAttributes(ByRef inputIdentifier As String, ByRef  outputIdentifier As String) &lt;br /&gt;
::Dim inputObject, outputObject As [[CAObject/zh|CAObject]]&lt;br /&gt;
::Dim resultTable As [[CATable/zh|CATable]]&lt;br /&gt;
::Dim definitionAttrInput As String &lt;br /&gt;
::inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
::outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier) &lt;br /&gt;
::definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;definition&amp;quot;) &lt;br /&gt;
::resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]]&lt;br /&gt;
::Call PrintResultTable(resultTable, inputIdentifier, definitionAttrInput, outputIdentifier) &lt;br /&gt;
::ReleaseComObject(resultTable) &lt;br /&gt;
::ReleaseComObject(inputObject) &lt;br /&gt;
::ReleaseComObject(outputObject) &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''PrintAttributes'''和作为'''inputIdentifier'''参数的&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;变量标识符以及作为'''outputIdentifier'''参数的'''Cost'''变量一起使用。如下所示通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::GetObjectByName/zh|GetObjectByName]]函数提取相应对象：&amp;lt;tt&amp;gt;&lt;br /&gt;
:inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取成功，将返回一个[[CAObject/zh|CAObject]]类型对象。如果使用'''[[CAObject/zh|CAObject]]'''的函数，参考[[CAObject/zh|SendCommand(command)]]，可以获得一个[[CAObject/zh|CAObject]]的完整函数列表。如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取失败，返回值为&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;。代码应该检查以确保[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取的结果是有效的。如果找不到，可使用[[CAEngine/zh|CAEngine]]的 [[CAEngine::ErrorCode/zh|ErrorCode]]和 [[CAEngine::ErrorText/zh|ErrorText]]属性获取错误信息。例如：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Set inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:If inputObject Is Nothing Then &lt;br /&gt;
::MsgBox(“This error from GetObjectByName occurred: “&amp;amp; _ vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &amp;amp; “:” &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) &lt;br /&gt;
:Else &lt;br /&gt;
::'inputObject valid &lt;br /&gt;
:End If&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===获取对象属性===&lt;br /&gt;
每一个Analytica对象都有一组属性，例如[[identifier|标识符]]、[[title|名称]]、[[description| 描述]]和[[class|类型]]。你可以使用[[CAObject::GetAttribute/zh|GetAttribute]]函数来获去Analytica对象的属性。例如，如要获取'''inputObject'''的定义（当前为cost）：&amp;lt;tt&amp;gt;&lt;br /&gt;
:definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh|GetAttribute]](&amp;quot;[[Definition|定义]]&amp;quot;) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt; 中，&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;的定义为&amp;quot;&amp;lt;tt&amp;gt;[[Normal]](30M, 3M)&amp;lt;/tt&amp;gt;&amp;quot; ，我们将它储存在'''definitionAttrInput'''当中。.&lt;br /&gt;
&lt;br /&gt;
===计算对象和检索结果===&lt;br /&gt;
使用[[CAObject/zh|CAObject]]的[[CAObject::Result/zh|Result]]或[[CAObject::ResultTable/zh|ResultTable]]方法来获取变量的值。如果有必要的话，ADE先自动计算变量。如果你确定结果为基元（只有一个元素），使用[[CAObject::Result/zh|Result]]方法。否则使用[[CAObject::ResultTable/zh|ResultTable]]，检索结果为一个''数组''。基元结果当作一个特殊数组案例来处理，没有维度的数组。如果值为基元[[CATable::AtomicValue/zh|AtomicValue]]方法将返回一个数字或者字符串单一值。 &lt;br /&gt;
&lt;br /&gt;
默认情况下，[[CAObject::Result/zh|Result]]和[[CAObject::ResultTable/zh|ResultTable]]返回结果的中值，也就是说，ADE以确定性方式计算结果。对于一个概率值，将[[CAObject/zh|CAObject]]的[[CAObject::ResultType/zh|ResultType]]属性设置为想要的不确定性视图——Mean（平均值） Sample（样本）、PDF（概率密度函数）、CDF（累计分布函数）、Confidence bands（置信带）、或者Statistics（统计数据）详情请参考[[CAObject::ResultType/zh|ResultType]]。我们通过如下的方式获取outputObject 输出对象 的值：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]] &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
结果为一个[[CATable/zh|CATable]]对象，允许我们访问一个表格中的单个元素。 &lt;br /&gt;
&lt;br /&gt;
如果你通过调用[[CAObject::Result/zh | Result]]来获取一个数组（或者表格）的值，将返回数组为一个字符串，列出索引和元素，以逗号隔开。通常使用[[CAObject::ResultTable/zh | ResultTable]]更加简单，这样你没有必要从字符串中解析表格的元素。&lt;br /&gt;
&lt;br /&gt;
===获取表格索引元素===&lt;br /&gt;
一个Analytica表格包含0个或者多个索引。如果包含一个索引，那么该表格是1维表格；如果有2个索引，说他是2维表格，依此类推。0维度表格包含一个“单一基元”（或标量）值。你可以使用CATable的[[CATable::NumDims/zh | NumDims]]获取表格的维数（也就是索引数）。要想获取表格的单个索引，可使用[[CATable/zh | CATable]]的 [[CATable::IndexNames/zh | IndexNames]]和 [[CATable::GetIndexObject/zh | GetIndexObject]]函数。 &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''PrintResultTable'''函数说明了这两个函数的使用。从'''PrintAttributes'''中调用'''PrintResultTable'''，执行打印'''TestTxc'''中的表格的实际工作（为了简洁起见，我们只给出了关联ADE的该函数部分）。&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Public Sub PrintResultTable(ByRef resultTable As CATable, ByRef inputIdentifier As String, ByRef definitionAttrInput As String, ByRef outputIdentifier As String) &lt;br /&gt;
::Dim theIndexName, theTableName As String &lt;br /&gt;
::Dim theIndexElement As String &lt;br /&gt;
::Dim theTableElement &lt;br /&gt;
::Dim theIndexObj As [[CAIndex/zh | CAIndex]]&lt;br /&gt;
::Dim numEls As Integer &lt;br /&gt;
::Dim spaces, i As Integer &lt;br /&gt;
::Dim lenStr As Short &lt;br /&gt;
::Dim OutputStr As Short &lt;br /&gt;
::Dim spaceString, underlineString As String &lt;br /&gt;
::... &lt;br /&gt;
::theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1) &lt;br /&gt;
::theTableName = resultTable.[[CATable::Name/zh|Name]] &lt;br /&gt;
::theIndexObj = resultTable.[[CATable::GetIndexObject/zh | GetIndexObject]](theIndexName) &lt;br /&gt;
::numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
::... &lt;br /&gt;
::For i = 1 To numEls &lt;br /&gt;
:::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
:::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
:::... &lt;br /&gt;
::Next i &lt;br /&gt;
::InformationPane.Text = outputString &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
通过'''PrintResultTable'''获取一个表格的索引方法如下：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1)&lt;br /&gt;
:theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
我们通过使用[[CATable/zh|CATable]]的[[CATable::IndexNames/zh|IndexNames]]函数获取第一个索引的名字。我们将它传递给[[CATable/zh|CATable]]的[[CATable::GetIndexObject/zh|GetIndexObject]]函数以获取表示我们的索引的[[CAIndex/zh|CAIndex]]。该自动化对象返回其相应索引的相关信息。如果此函数调用失败，将返回&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;信息。在此情况下，使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]] 函数找出原因。&lt;br /&gt;
&lt;br /&gt;
==从CATable和CAIndex中获取信息==&lt;br /&gt;
[[PrintResultTable]]说明了如何从[[CATable/zh| CATable]]和[[CAIndex/zh|CAIndex]] 对象获取信息。该代码获取'''Cost'''表格的索引和表格元素：&lt;br /&gt;
: &amp;lt;tt&amp;gt;&lt;br /&gt;
:numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
:For i = 1 To numEls &lt;br /&gt;
::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
::... &lt;br /&gt;
:Next i &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[CAIndex/zh|CAIndex]]的[[CAIndex::IndexElements/zh|IndexElements]]属性返回第一个索引中的元素个数。[[CAIndex/zh|CAIndex]]的[[CAIndex::GetValueByNumber/zh|GetValueByNumber]]函数获取单个索引元素。 &lt;br /&gt;
&lt;br /&gt;
我们通过传递表格中元素的坐标，使用  [[CATable/zh|CATable]]的[[CATable::GetDataByElements/zh|GetDataByElements]]函数获取'''Cost'''表格对象的单个表格元素'''resultTable'''。 &lt;br /&gt;
&lt;br /&gt;
当我检索 [[CATable/zh|CATable]]对象中单个元素（'''resultTable'''）的时候，我们利用了该表格是一维的事实。因此，我们只需要传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个单一数（这个数代表表格中的位置）。但是，如果我们处理两个或者更多维度，我们必须传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个数组函数，并且指明我们要检索的表格元素的位置。因此，如果我们不想检索一个二维数组的position (4,3)位置的元素，我们可以这样写：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Dim W as Variant 'return element &lt;br /&gt;
:Dim IndexPtrs(1 To 2) As Variant 'position in table &lt;br /&gt;
::... &lt;br /&gt;
:IndexPtrs(1) = 4 &lt;br /&gt;
:IndexPtrs(2) = 3 &lt;br /&gt;
:W = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](IndexPtrs) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==控制基元值格式==&lt;br /&gt;
[[CATable/zh|CATable]]中的每个基元值可以是一个数、一个字符串，或者其它一些基本类型（''例如''：[[Null|空值]]、[[Undefined|未定义]]、[[Reference|参考]]，或 [[Handle|句柄]]。通过说明类型和值，它们作为''变体''被返回，这是一种Visual Basic能读懂的数据结构。[[CATable/zh|CATable]]的[[CATable::RenderingStyle|RenderingStyle]]属性控制Analytica基础值是如何映射到Visual Basic变体的。 &lt;br /&gt;
&lt;br /&gt;
例如：可以通过使用Analytica 模型的数字格式设置将一个数值返回成一个数字或者字符串。如果被指定格式，有一个选线控制是截断数字的位数，还是精确返回。 &lt;br /&gt;
&lt;br /&gt;
子程序[[PrintResultTable/zh|PrintResultTable]]在&amp;lt;tt&amp;gt;frmMain.vb&amp;lt;/tt&amp;gt;中载入,其渲染风格直接指明：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::NumberAsText/zh|NumberAsText]] = True &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::FullPrecision/zh|FullPrecision]] = False &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::StringQuotes/zh|StringQuotes]] = 2 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
第一行指明数值应该根据与结果对象有关的数字格式被格式化为文本。例如在其程序输出中，我们将看到&amp;lt;tt&amp;gt;30.103M&amp;lt;/tt&amp;gt;，而非&amp;lt;tt&amp;gt;30102995.6639812&amp;lt;/tt&amp;gt;，如果我们让Visual Basic将数值串联我们的结果字符串，将显示该结果。在此事件中，一个值为字符串的单元格出现在结果中，返回值将明确带双引号。对于[[CARenderingStyle/zh|CARenderingStyle]]对象中的所有可用属性，请参考[[CARenderingStyle/zh|CARenderingStyle]]。&lt;br /&gt;
&lt;br /&gt;
===其它访问表格的方式===&lt;br /&gt;
有几种访问多维表格[[CATable/zh|CATable]]中元素的方式。每一种都有可能在特定的场合使用起来比较方便。 &lt;br /&gt;
&lt;br /&gt;
第一种方式就是使用[[CATable/zh | CATable]]的 [[CATable::GetDataByElements/zh|GetDataByElements]]或[[CATable::GetDataByLabels/zh|GetDataByLabels]]方法，上面代码示例中有显示。在此情况下，利用你想获取的基元值的单元格位置。 &lt;br /&gt;
&lt;br /&gt;
第二种方式就是使用[[CATable/zh|CATable]][[CATable::Slice/zh|Slice]]或[[CATable::Subscript/zh | Subscript]]方法获取一个少一个维度的新[[CATable/zh|CATable]]对象。通过重复减少维度，最终将获得0维度，这时你将获得一个单一基元值。此时，[[CATable/zh|CATable]]的[[CATable::AtomicValue/zh|AtomicValue]]方法返回该值 。[[CATable::AtomicValue/zh|AtomicValue]]方法是唯一获取一个标值的方法（因为没有坐标位置）。如果你需要建立完整结果其中一个切片的图形图像，必须使用此方法。 &lt;br /&gt;
&lt;br /&gt;
第三种方式就是使用[[CATable/zh|CATable]]的[[CATable::GetSafeArray/zh|GetSafeArray]]方法，将多维数组转化成一个''安全数组''（或者一个.NET数组）。你可以在使用VB或者其它.NET语言直接处理多维数组。因为对于Analytica维度没有固定顺序，但是安全数组和.NET数组有一个明确的顺序，你必须先使用[[CATable/zh|CATable]]对象的[[CATable::SetIndexOrder/zh|SetIndexOrder]]方法在调用[[CATable::GetSafeArray/zh|GetSafeArray]]之前指明维度的顺序。注意如果你知道你的数组是一维的，那就没必要了。&lt;br /&gt;
&lt;br /&gt;
===修改对象===&lt;br /&gt;
一个自定义用户程序通常从一个用户或者其它外部源获取输入，以便转化成Analytica模型中的输入变量。你可以设定输入变量的定义或者通过使用定义表格来这样做。 &lt;br /&gt;
&lt;br /&gt;
'''TestTxc''' 说明了如何修改'''Pop_exp'''定义，此模型是一个影响结果变量Cost的模型输入。要想在该示例中设定该定义，从主菜单上选择'''File &amp;gt; Change Population'''。将出现一个对话框，如下图所示：&lt;br /&gt;
&lt;br /&gt;
[[File:RedefiningtheVariableDefinition.jpg|400px/zh|文件：RedefiningtheVariableDefinition.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
在信息栏中输入一个新定义并点击'''Ok'''确认。主窗口将显示一个新的Cost值。当点击该对话框中的'''Ok'''按钮时，调用了&amp;lt;tt&amp;gt;ChangeDef.frm&amp;lt;/tt&amp;gt;函数，然后调用[[PrintAttributes/zh|PrintAttributes]]函数打印&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果。&lt;br /&gt;
&lt;br /&gt;
此函数类似于：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Private Sub OkButton_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles OkButton.Click &lt;br /&gt;
::Dim errorText As String&lt;br /&gt;
::Dim pop_exp_Object As [[CAObject/zh|CAObject]] &lt;br /&gt;
::Dim errorCode As Short &lt;br /&gt;
::Dim errorString As String &lt;br /&gt;
::newDefinition = PopExposedDef.Text &lt;br /&gt;
::pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
::pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]](&amp;quot;[[Definition]]&amp;quot;, newDefinition) &lt;br /&gt;
::errorCode = adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &lt;br /&gt;
::If errorCode &amp;lt;&amp;gt; 0 Then &lt;br /&gt;
:::MsgBox(&amp;quot;This error occurred while processing your definition: &amp;quot; &amp;amp; vbCrLf &amp;amp; vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) :::PopExposedDef.Focus()&lt;br /&gt;
::Else&lt;br /&gt;
:::Me.Close() &lt;br /&gt;
:::frmMain.DefInstance.PrintAttributes(&amp;quot;Pop_exp&amp;quot;, &amp;quot;Cost&amp;quot;) &lt;br /&gt;
::End If &lt;br /&gt;
::ReleaseComObject(pop_exp_Object) &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
该函数抓取了输入到'''New Definition''' 新定义给'''Population Exposed'''栏，并通过使用[[CAObject/zh|CAObject]]对象中的[[CAObject::SetAttribute/zh|SetAttribute]]函数将它设置给&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;对象。然后调用[[PrintAttributes/zh|PrintAttributes]]，以计算&amp;lt;tt&amp;gt;Cost object&amp;lt;/tt&amp;gt;，并打印新的结果。要想给变量&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;设定一个新定义，我们可以为&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;获取[[CAObject/zh|CAObject]]对象，然后将其定义设置成用户输入的定义。通过使用下面的代码来实现：&lt;br /&gt;
:pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
:pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]]( &amp;quot;[[Definition]]&amp;quot;, newDefinition )&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
无论什么时候调用[[CAObject::SetAttribute/zh|SetAttribute]]，都应该检查[[CAEngine/zh|CAEngine]]自动化对象（'''adeEngine'''）的[[CAEngine::ErrorCode/zh|ErrorCode]]，以免它的定义是非法的。尝试一下输入一个新定义，比如&amp;lt;code&amp;gt;[[Uniform]](25M,35M)&amp;lt;/code&amp;gt;，然后点击'''Ok'''。当&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;的定义被改变时， &amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果由ADE重新计算，此时'''ResultTable'''接下来调用给Cost变量（在应用程序窗口重新显示时）。&lt;br /&gt;
&lt;br /&gt;
使用ADE绘图&lt;br /&gt;
&lt;br /&gt;
通过Analytica 4.6使用相同的绘图引擎，你可以建立一个图表或者图形以显示一个数组值或者不确定值结果。在ADE4.6中，你可以使用 [[CATable/zh|CATable]]的[[CATable::GraphToFile/zh|GraphToFile]]和[[CATable::GraphToStream/zh|GraphToStream]]方法。图形可以以几种可能的图像格式返回，例如'''image/png'''、 '''image/bmp'''或者 '''image/jpeg'''。 &lt;br /&gt;
&lt;br /&gt;
从可用图形选项中选择的最简单方式就是使用Analytica打开你的模型。你可以实验设置各种默认设置或者替代选择的变量，看它们是如何工作的。但你选择了你想设置的选项，保存模型。当为每一个生成结果图形时，ADE将使用这些设置。 &lt;br /&gt;
&lt;br /&gt;
对于更高维度的结果，可能需要做一些必要工作，以便选择将绘制结果的切片和具体的轴（也就是相对于图例哪个维度作为X轴）。[[CATable/zh|CATable]]的[[CATable::Subscript/zh|Subscript]]或[[CATable::Slice/zh|Slice]]方法可以用来控制轴选择特殊的切片用来绘制，能够用来控制轴。详情请参考[[CATable/zh|CATable]]。在我们的&amp;lt;tt&amp;gt;Tutorial.NET&amp;lt;/tt&amp;gt;示例中，我们有一个一维结果（&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;），因此我们没有必要担心截取或者绕轴旋转。 &lt;br /&gt;
&lt;br /&gt;
[[CATable::GraphToStream/zh|GraphToStream]]方法被用来从ADE中直接转化图形图形到一个用户界面中。使用[[CATable::GraphToStream/zh|GraphToStream]]比起使用[[CATable::GraphToFile/zh|GraphToFile]]来要稍微复杂一点，因为[[CATable::GraphToFile/zh|GraphToFile]]除了需要文件名以外还需要其它一些信息，以便编写图形。要使用[[CATable::GraphToStream/zh|GraphToStream]]，我们必须在内存内设置一个流，允许ADE写入该留，然后从该留重建。因为.NET流和COM流不兼容，你必须使用ADE一同提供的[[StreamConnector]]类型.&amp;lt;tt&amp;gt;frmMain&amp;lt;/tt&amp;gt; 中的'''GraphResult_Click'''子程序演示了[[CATable::GraphToStream/zh|GraphToStream]]的使用。从主应用程序窗口选择 '''Graph Result'''菜单选项，结果将出现在一个如下所示的图形当中：&lt;br /&gt;
&lt;br /&gt;
[[File:resultgraph.jpg/zh|文件：resultgraph.jpg]]&lt;br /&gt;
&lt;br /&gt;
==结论==&lt;br /&gt;
&lt;br /&gt;
在此教程中，我们介绍了Analytica决策引擎的几个重要方面。我们看到了如何建立一个ADE服务器对象，使用ADE打开模型，获取模型中的单个对象、计算对象、获取表格中的元素，以及修改模型中的对象。但是ADE可以做的远不止这些。 &lt;br /&gt;
&lt;br /&gt;
我们希望你已经足够了解其基本特征，这样你现在才能独自开始探索更多新的高级特征。我们建议你现在开始阅读字教程的剩余部分以了解ADE能做什么。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
| [[Installation of ADE/zh|ADE 安装]] &amp;lt;- ||  [[The ADE Tutorial/zh|ADE 入门教程]] || -&amp;gt; [[Using the ADE Server/zh|使用ADE服务器]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36294</id>
		<title>The ADE Tutorial/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36294"/>
		<updated>2015-10-27T06:26:53Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南 ]]&lt;br /&gt;
&lt;br /&gt;
此教程教你如何在一个Visual Basic程序中使用Analytica决策引擎（ADE）。&lt;br /&gt;
&lt;br /&gt;
==你的第一个ADE应用程序==&lt;br /&gt;
首先先从头开始写一个简单的ADE程序，只要确认一切设置正常。按照以下步骤操作：&lt;br /&gt;
&lt;br /&gt;
test&lt;br /&gt;
&lt;br /&gt;
第一个程序执行了以下操作：&lt;br /&gt;
*建立一个名称为ADE的[[CAEngine/zh|CAEngine]]自动化对象（通过使用&amp;lt;code&amp;gt;new [[CAEngine/zh|CAEngine]]&amp;lt;/code&amp;gt;).&lt;br /&gt;
*打开Analytica模型 (通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]] 方法。&lt;br /&gt;
*显示模型名称返回[[CAEngine::OpenModel/zh|OpenModel]]的值。&lt;br /&gt;
我们将在后面的章节详细了解这些信息。&lt;br /&gt;
&lt;br /&gt;
===接下来讲什么呢?===&lt;br /&gt;
我们不会尝试在此入门教程中解释ADE的特征。本指南后面几个章节会描述这些特征。 &lt;br /&gt;
&lt;br /&gt;
从现在开始，我们我们将使用名称为&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;的示例模型。打开 Analytica安装目录下 '''Example Models'''文件夹里面的'''Risk Analysis'''文件夹便可找到&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;文件。如果你找不到，或者你安装Analytica的时候未选择安装examples（示例）文件，在ADE安装目录下面的'''Examples\Tutorial.NET'''文件家中有一个副本。 &lt;br /&gt;
&lt;br /&gt;
Txc模型演示了减少污染物TXC排放的risk-benefit （风险-效益）分析。请用Analytica打开Txc查看它是如何工作的。 &lt;br /&gt;
&lt;br /&gt;
ADE '''Examples\Tutorial.NET''' 文件夹中名称为&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;的Visual Basic.NET程序示例显示了ADE很多方面。该程序建立了一个ADE自动化对象，打开包含该对象的&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，获取变量 &amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，计算变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;，通过获取每个表格的单独组件以表格的方式打印输出变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的结果，然后改变变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义。再次获取变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的值，看一下 变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;定义的改变对变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;有什么影响。如果设置正确的话,&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;将显示在“Text Txc window”中显示的窗口。 &lt;br /&gt;
&lt;br /&gt;
应用程序显示变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义（&amp;lt;tt&amp;gt;&amp;quot;Normal (30M, 3M)&amp;quot;&amp;lt;/tt&amp;gt;），以及与&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;关联的表格，这都基于&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义。你可以通过从主菜单选择'''File &amp;gt; Change Population Exposed'''改变&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，然后查看改变对&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;表格的影响。&lt;br /&gt;
&lt;br /&gt;
[[File:TextTxcWindow.png|400px/zh | 文件：TextTxcWindow.png|400px]]&lt;br /&gt;
&lt;br /&gt;
===区分title（名称） 和 identifier（标识符）===&lt;br /&gt;
无论什么时候，一个ADE函数都需要一个变量你必须传达变量的'''''[[Identifier|标识符]]''''' ，而不是它的'''''[[Title|名称]]'''''。这可能会引起混淆，因为在Analytica影响图中一般显示每一个变量的名称。默认情况下，在你最初建立每一个对象的时候，Analytica自动根据名称建立一个标识符。用（_）代替名称中的每一个空格或者其他非字母和数字字符。 &lt;br /&gt;
&lt;br /&gt;
你可以通过点击“Control+y”（或者从Object（对象）菜单选择'''Show by identifier''' ：显示标识符） 来以标识符显示变量。对于模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;，你可以看到名称为&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;变量的标识符为 &amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;。将变量传递给ADE函数时，使用标识符很重要。如果你传递&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;，ADE无法找到变量，并且将返回一个错误。&lt;br /&gt;
&lt;br /&gt;
===从Visual Basic中建立一个ADE 对象===&lt;br /&gt;
&lt;br /&gt;
如果你还没准备好，将名称为tt&amp;gt;Examples\Tutorial\TestTxc.sln&amp;lt;/tt&amp;gt;载入到Visual Basic.NET中，查看名称为&amp;lt;tt&amp;gt;TestTxc.vb&amp;lt;/tt&amp;gt;的文件的代码。其代码看起来像：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Imports ADEW &lt;br /&gt;
:. . . &lt;br /&gt;
:Public adeEngine As [[CAEngine/zh|CAEngine]]&lt;br /&gt;
&lt;br /&gt;
:Public Sub Main() &lt;br /&gt;
::Dim exeDirectory, theModel As String &lt;br /&gt;
::Dim theModelString As String &lt;br /&gt;
::exeDirectory = VB6.GetPath &lt;br /&gt;
::theModel = exeDirectory &amp;amp; &amp;quot;\..\&amp;quot; &amp;amp; &amp;quot;Txc.ana&amp;quot; &lt;br /&gt;
::adeEngine = New [[CAEngine/zh|CAEngine]]&lt;br /&gt;
::... &lt;br /&gt;
::theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
::... &lt;br /&gt;
::frmMain.DefInstance.Show() &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在每一个文件的顶部的代码将自动化对象 '''adeEngine''' 声明为一个[[CAEngine/zh|CAEngine]] 对象。使用此对象，我们能够访问 [[CAEngine/zh|CAEngine]] 展示的所有公共函数（参考 [[ADE Server Class Reference/zh|ADE服务器类型参考]] ）&lt;br /&gt;
&lt;br /&gt;
变量&amp;lt;tt&amp;gt;adeEngine&amp;lt;/tt&amp;gt;包含我们的进程内对象 [[CAEngine/zh|CAEngine]]。如果我们想使用ADE的本地（进程外）服务器版本，我们可以将一个项目参考添加到'''Analytica Decision Engine Server 4.6 COM''' 组件并将顶部行从&amp;lt;tt&amp;gt;Imports ADEW&amp;lt;/tt&amp;gt;改成&amp;lt;tt&amp;gt;Imports ADE&amp;lt;/tt&amp;gt;即可。 &lt;br /&gt;
&lt;br /&gt;
这里是另一种获得一个先[[CAEngine/zh|CAEngine]]对象的方法。此循序不需要给项目添加参考。&amp;lt;tt&amp;gt;&lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADEW4.6.CAEngine&amp;quot;) ’ in-process &lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADE4.6.CAEngine&amp;quot;) ’ out-of-process &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果想理解使用进程内和进程外（或本地）服务器的利与弊，以及哪一种自动化服务器用于不同的场景，参考[[Using_the_Analytica_Decision_Engine_Server#In-process_vs_Out-of-process/zh | In-process vs. out-of-process]]&lt;br /&gt;
&lt;br /&gt;
===COM和 Automation 接口比较===&lt;br /&gt;
在上面的例子当中，我们使用COM接口调用ADE。在一个COM 接口中，对象 在本例中为 [[CAEngine/zh|CAEngine]] 被声明为[[CAEngine/zh|CAEngine]] ，编译器解决每一个成员函数，并且在编译时间内能探测几个明显的错误。另外，Visual Studio可以提供方法和参数类型列表当，在你编程的时候可以当做一个提示工具，在编写使用ADE程序是非常有用。COM调用比Automation调用要快一点，但是在ADE应用程序中速度差异通常不是很重要。对于ADE 4.6我们推荐使用COM结构，只要你的语言支持。&lt;br /&gt;
&lt;br /&gt;
在VB Automation中，你可以将一个对象简单声明为Object（对象），而不是像 [[CAEngine/zh|CAEngine]]、[[CAObject/zh|CAObject]]等更加具体的类型。当使用Automation调用'''ADE'''方法时，在运行时间内确定方法。在编译时间内，编译器不知道你的 '''ADE''' 对象是否有一个名称为[[CAEngine::OpenModel/zh|OpenModel]]的函数。在VB中，调用COM方法或Automation 方法的语法是相通的——唯一的不同在于对象类型是否明确被声明。&lt;br /&gt;
&lt;br /&gt;
在VC++和C#中，调用COM的语法和调用Automatio的语法不同。在这些情况下，COM要方便的多，Automation能够获得相冗余。然而，同样的语言，包括VBScript和其他脚本语言，只支持Automation不支持COM。&lt;br /&gt;
&lt;br /&gt;
===监视Process（进程）===&lt;br /&gt;
当使用进程外ADE服务器时，你的代码必须在终止时释放[[CAEngine/zh|CAEngine]]COM对象。当最终[[CAEngine/zh|CAEngine]]使用被释放是，ADE.exe 进程自动终止。到目前为止所看到的代码，VB语言在达到程序末端时，自动处理释放对象。但是，当你调试你的代码是，你可以提前终止你的程序来修复bug，你的程序可能被Task Manager（任务管理器）终止，或者你自己的代码也可能奔溃，导致你的程序进程在它有机会释放对象之前终止。应为COM对象从来不会被释放，ADE.exe进程不知道它是否在使用中，你可能获得ADE.exe 僵尸进程。 &lt;br /&gt;
&lt;br /&gt;
为了避免这种情况发生，一种好的习惯就是在调用[[CAEngine/zh|CAEngine]]实例后 立即调用[[CAEngine::MonitorProcess/zh|CAEngine::MonitorProcess]]。通过这种方式，ADE能够得知哪一个进程正在使用它，同时将设置一个线程去探测你的进程是否在ADE被完全释放前终止。如果你的程序进程没有终止，ADE进程会立即将它关闭，消除了僵尸ADE进程的堆积。 &lt;br /&gt;
&lt;br /&gt;
要从一个.NET应用程序获得进程ID，使用System.Diagnostics.Process namespace中的'''GetCurrentProcess().Id''' 。在其他语言中，你可以使用Windows SDK 的'''GetProcessId( )'''函数。 &lt;br /&gt;
&lt;br /&gt;
'''[[CAEngine::MonitorProcess/zh|MonitorProcess]]()''' 只能用来监视运行ADE进程的同一台计算机的进程，一次当通过DCOM运行ADE时不能使用。当使用进程内ADEW服务器时没有必要使用。&lt;br /&gt;
&lt;br /&gt;
==打开使用ADE的模型==&lt;br /&gt;
我们现在打开&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，显示我们的应用程序主窗口。使用以下调用：tt&amp;gt;&lt;br /&gt;
:theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
:frmMain.DefInstance.Show &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]]函数打开模型。如果成功的话，变量&amp;lt;tt&amp;gt;theModelString&amp;lt;/tt&amp;gt;将包含模型的名字。否则，将包含一个空的串。虽然由于为了简介的缘故，我们没有这样做，但是你应该检查从[[CAEngine::OpenModel/zh|OpenModel]]函数返回的是不是一个空的串。如果是，说明在你打开的模型中存在一个错误。你可以使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/z |ErrorText]]属性找出是哪种错误 （&amp;lt;tt&amp;gt;adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] 和adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]&amp;lt;/tt&amp;gt;）。&lt;br /&gt;
&lt;br /&gt;
==从Analytica模型中检索对象==&lt;br /&gt;
下一步就是从我们的模型中检索对象（变量、模块、函数等），以便我们能获取他们的属性（[[definition|定义]]、[[title|名称]]、[[class|类型]]等等 ）。我们的示例模型（&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;）操作&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;和&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;对象。尤其是，修改&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;可以查看这是如何影响&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt; 对象。&lt;br /&gt;
&lt;br /&gt;
我们的&amp;lt;tt&amp;gt;TxcTest.vbproj&amp;lt;/tt&amp;gt; （&amp;lt;tt&amp;gt;TxcText.sln&amp;lt;/tt&amp;gt;）项目中的&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;文件里的 '''PrintAttributes''' 函数演示了如何检索对象。该函数首先被&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''Form_Load''' 函数调用，当应用程序启动后，可以显示'''Cost'''表格。当然无论什么时候，只要我们想输出'''Cost'''表格的当前值，都可以调用。该函数如下所示：&lt;br /&gt;
:Public Sub PrintAttributes(ByRef inputIdentifier As String, ByRef  outputIdentifier As String) &lt;br /&gt;
::Dim inputObject, outputObject As [[CAObject/zh|CAObject]]&lt;br /&gt;
::Dim resultTable As [[CATable/zh|CATable]]&lt;br /&gt;
::Dim definitionAttrInput As String &lt;br /&gt;
::inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
::outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier) &lt;br /&gt;
::definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;definition&amp;quot;) &lt;br /&gt;
::resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]]&lt;br /&gt;
::Call PrintResultTable(resultTable, inputIdentifier, definitionAttrInput, outputIdentifier) &lt;br /&gt;
::ReleaseComObject(resultTable) &lt;br /&gt;
::ReleaseComObject(inputObject) &lt;br /&gt;
::ReleaseComObject(outputObject) &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''PrintAttributes'''和作为'''inputIdentifier'''参数的&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;变量标识符以及作为'''outputIdentifier'''参数的'''Cost'''变量一起使用。如下所示通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::GetObjectByName/zh|GetObjectByName]]函数提取相应对象：&amp;lt;tt&amp;gt;&lt;br /&gt;
:inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取成功，将返回一个[[CAObject/zh|CAObject]]类型对象。如果使用'''[[CAObject/zh|CAObject]]'''的函数，参考[[CAObject/zh|SendCommand(command)]]，可以获得一个[[CAObject/zh|CAObject]]的完整函数列表。如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取失败，返回值为&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;。代码应该检查以确保[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取的结果是有效的。如果找不到，可使用[[CAEngine/zh|CAEngine]]的 [[CAEngine::ErrorCode/zh|ErrorCode]]和 [[CAEngine::ErrorText/zh|ErrorText]]属性获取错误信息。例如：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Set inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:If inputObject Is Nothing Then &lt;br /&gt;
::MsgBox(“This error from GetObjectByName occurred: “&amp;amp; _ vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &amp;amp; “:” &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) &lt;br /&gt;
:Else &lt;br /&gt;
::'inputObject valid &lt;br /&gt;
:End If&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===获取对象属性===&lt;br /&gt;
每一个Analytica对象都有一组属性，例如[[identifier|标识符]]、[[title|名称]]、[[description| 描述]]和[[class|类型]]。你可以使用[[CAObject::GetAttribute/zh|GetAttribute]]函数来获去Analytica对象的属性。例如，如要获取'''inputObject'''的定义（当前为cost）：&amp;lt;tt&amp;gt;&lt;br /&gt;
:definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh|GetAttribute]](&amp;quot;[[Definition|定义]]&amp;quot;) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt; 中，&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;的定义为&amp;quot;&amp;lt;tt&amp;gt;[[Normal]](30M, 3M)&amp;lt;/tt&amp;gt;&amp;quot; ，我们将它储存在'''definitionAttrInput'''当中。.&lt;br /&gt;
&lt;br /&gt;
===计算对象和检索结果===&lt;br /&gt;
使用[[CAObject/zh|CAObject]]的[[CAObject::Result/zh|Result]]或[[CAObject::ResultTable/zh|ResultTable]]方法来获取变量的值。如果有必要的话，ADE先自动计算变量。如果你确定结果为基元（只有一个元素），使用[[CAObject::Result/zh|Result]]方法。否则使用[[CAObject::ResultTable/zh|ResultTable]]，检索结果为一个''数组''。基元结果当作一个特殊数组案例来处理，没有维度的数组。如果值为基元[[CATable::AtomicValue/zh|AtomicValue]]方法将返回一个数字或者字符串单一值。 &lt;br /&gt;
&lt;br /&gt;
默认情况下，[[CAObject::Result/zh|Result]]和[[CAObject::ResultTable/zh|ResultTable]]返回结果的中值，也就是说，ADE以确定性方式计算结果。对于一个概率值，将[[CAObject/zh|CAObject]]的[[CAObject::ResultType/zh|ResultType]]属性设置为想要的不确定性视图——Mean（平均值） Sample（样本）、PDF（概率密度函数）、CDF（累计分布函数）、Confidence bands（置信带）、或者Statistics（统计数据）详情请参考[[CAObject::ResultType/zh|ResultType]]。我们通过如下的方式获取outputObject 输出对象 的值：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]] &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
结果为一个[[CATable/zh | CATable]]对象，允许我们访问一个表格中的单个元素。 &lt;br /&gt;
&lt;br /&gt;
如果你通过调用[[CAObject::Result/zh | Result]]来获取一个数组（或者表格）的值，将返回数组为一个字符串，列出索引和元素，以逗号隔开。通常使用[[CAObject::ResultTable/zh | ResultTable]]更加简单，这样你没有必要从字符串中解析表格的元素。&lt;br /&gt;
&lt;br /&gt;
===获取表格索引元素===&lt;br /&gt;
一个Analytica表格包含0个或者多个索引。如果包含一个索引，那么该表格是1维表格；如果有2个索引，说他是2维表格，依此类推。0维度表格包含一个“单一基元”（或标量）值。你可以使用CATable的[[CATable::NumDims/zh | NumDims]]获取表格的维数（也就是索引数）。要想获取表格的单个索引，可使用[[CATable/zh | CATable]]的 [[CATable::IndexNames/zh | IndexNames]]和 [[CATable::GetIndexObject/zh | GetIndexObject]]函数。 &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''PrintResultTable'''函数说明了这两个函数的使用。从'''PrintAttributes'''中调用'''PrintResultTable'''，执行打印'''TestTxc'''中的表格的实际工作（为了简洁起见，我们只给出了关联ADE的该函数部分）。&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Public Sub PrintResultTable(ByRef resultTable As CATable, ByRef inputIdentifier As String, ByRef definitionAttrInput As String, ByRef outputIdentifier As String) &lt;br /&gt;
::Dim theIndexName, theTableName As String &lt;br /&gt;
::Dim theIndexElement As String &lt;br /&gt;
::Dim theTableElement &lt;br /&gt;
::Dim theIndexObj As [[CAIndex/zh | CAIndex]]&lt;br /&gt;
::Dim numEls As Integer &lt;br /&gt;
::Dim spaces, i As Integer &lt;br /&gt;
::Dim lenStr As Short &lt;br /&gt;
::Dim OutputStr As Short &lt;br /&gt;
::Dim spaceString, underlineString As String &lt;br /&gt;
::... &lt;br /&gt;
::theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1) &lt;br /&gt;
::theTableName = resultTable.[[CATable::Name/zh|Name]] &lt;br /&gt;
::theIndexObj = resultTable.[[CATable::GetIndexObject/zh | GetIndexObject]](theIndexName) &lt;br /&gt;
::numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
::... &lt;br /&gt;
::For i = 1 To numEls &lt;br /&gt;
:::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
:::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
:::... &lt;br /&gt;
::Next i &lt;br /&gt;
::InformationPane.Text = outputString &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
通过'''PrintResultTable'''获取一个表格的索引方法如下：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1)&lt;br /&gt;
:theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
我们通过使用[[CATable/zh|CATable]]的[[CATable::IndexNames/zh|IndexNames]]函数获取第一个索引的名字。我们将它传递给[[CATable/zh|CATable]]的[[CATable::GetIndexObject/zh|GetIndexObject]]函数以获取表示我们的索引的[[CAIndex/zh|CAIndex]]。该自动化对象返回其相应索引的相关信息。如果此函数调用失败，将返回&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;信息。在此情况下，使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]] 函数找出原因。&lt;br /&gt;
&lt;br /&gt;
==从CATable和CAIndex中获取信息==&lt;br /&gt;
[[PrintResultTable]]说明了如何从[[CATable/zh| CATable]]和[[CAIndex/zh|CAIndex]] 对象获取信息。该代码获取'''Cost'''表格的索引和表格元素：&lt;br /&gt;
: &amp;lt;tt&amp;gt;&lt;br /&gt;
:numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
:For i = 1 To numEls &lt;br /&gt;
::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
::... &lt;br /&gt;
:Next i &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[CAIndex/zh|CAIndex]]的[[CAIndex::IndexElements/zh|IndexElements]]属性返回第一个索引中的元素个数。[[CAIndex/zh|CAIndex]]的[[CAIndex::GetValueByNumber/zh|GetValueByNumber]]函数获取单个索引元素。 &lt;br /&gt;
&lt;br /&gt;
我们通过传递表格中元素的坐标，使用  [[CATable/zh|CATable]]的[[CATable::GetDataByElements/zh|GetDataByElements]]函数获取'''Cost'''表格对象的单个表格元素'''resultTable'''。 &lt;br /&gt;
&lt;br /&gt;
当我检索 [[CATable/zh|CATable]]对象中单个元素（'''resultTable'''）的时候，我们利用了该表格是一维的事实。因此，我们只需要传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个单一数（这个数代表表格中的位置）。但是，如果我们处理两个或者更多维度，我们必须传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个数组函数，并且指明我们要检索的表格元素的位置。因此，如果我们不想检索一个二维数组的position (4,3)位置的元素，我们可以这样写：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Dim W as Variant 'return element &lt;br /&gt;
:Dim IndexPtrs(1 To 2) As Variant 'position in table &lt;br /&gt;
::... &lt;br /&gt;
:IndexPtrs(1) = 4 &lt;br /&gt;
:IndexPtrs(2) = 3 &lt;br /&gt;
:W = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](IndexPtrs) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==控制基元值格式==&lt;br /&gt;
[[CATable/zh|CATable]]中的每个基元值可以是一个数、一个字符串，或者其它一些基本类型（''例如''：[[Null|空值]]、[[Undefined|未定义]]、[[Reference|参考]]，或 [[Handle|句柄]]。通过说明类型和值，它们作为''变体''被返回，这是一种Visual Basic能读懂的数据结构。[[CATable/zh|CATable]]的[[CATable::RenderingStyle|RenderingStyle]]属性控制Analytica基础值是如何映射到Visual Basic变体的。 &lt;br /&gt;
&lt;br /&gt;
例如：可以通过使用Analytica 模型的数字格式设置将一个数值返回成一个数字或者字符串。如果被指定格式，有一个选线控制是截断数字的位数，还是精确返回。 &lt;br /&gt;
&lt;br /&gt;
子程序[[PrintResultTable/zh|PrintResultTable]]在&amp;lt;tt&amp;gt;frmMain.vb&amp;lt;/tt&amp;gt;中载入,其渲染风格直接指明：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::NumberAsText/zh|NumberAsText]] = True &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::FullPrecision/zh|FullPrecision]] = False &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::StringQuotes/zh|StringQuotes]] = 2 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
第一行指明数值应该根据与结果对象有关的数字格式被格式化为文本。例如在其程序输出中，我们将看到&amp;lt;tt&amp;gt;30.103M&amp;lt;/tt&amp;gt;，而非&amp;lt;tt&amp;gt;30102995.6639812&amp;lt;/tt&amp;gt;，如果我们让Visual Basic将数值串联我们的结果字符串，将显示该结果。在此事件中，一个值为字符串的单元格出现在结果中，返回值将明确带双引号。对于[[CARenderingStyle/zh|CARenderingStyle]]对象中的所有可用属性，请参考[[CARenderingStyle/zh|CARenderingStyle]]。&lt;br /&gt;
&lt;br /&gt;
===其它访问表格的方式===&lt;br /&gt;
有几种访问多维表格[[CATable/zh|CATable]]中元素的方式。每一种都有可能在特定的场合使用起来比较方便。 &lt;br /&gt;
&lt;br /&gt;
第一种方式就是使用[[CATable/zh | CATable]]的 [[CATable::GetDataByElements/zh|GetDataByElements]]或[[CATable::GetDataByLabels/zh|GetDataByLabels]]方法，上面代码示例中有显示。在此情况下，利用你想获取的基元值的单元格位置。 &lt;br /&gt;
&lt;br /&gt;
第二种方式就是使用[[CATable/zh|CATable]][[CATable::Slice/zh|Slice]]或[[CATable::Subscript/zh | Subscript]]方法获取一个少一个维度的新[[CATable/zh|CATable]]对象。通过重复减少维度，最终将获得0维度，这时你将获得一个单一基元值。此时，[[CATable/zh|CATable]]的[[CATable::AtomicValue/zh|AtomicValue]]方法返回该值 。[[CATable::AtomicValue/zh|AtomicValue]]方法是唯一获取一个标值的方法（因为没有坐标位置）。如果你需要建立完整结果其中一个切片的图形图像，必须使用此方法。 &lt;br /&gt;
&lt;br /&gt;
第三种方式就是使用[[CATable/zh|CATable]]的[[CATable::GetSafeArray/zh|GetSafeArray]]方法，将多维数组转化成一个''安全数组''（或者一个.NET数组）。你可以在使用VB或者其它.NET语言直接处理多维数组。因为对于Analytica维度没有固定顺序，但是安全数组和.NET数组有一个明确的顺序，你必须先使用[[CATable/zh|CATable]]对象的[[CATable::SetIndexOrder/zh|SetIndexOrder]]方法在调用[[CATable::GetSafeArray/zh|GetSafeArray]]之前指明维度的顺序。注意如果你知道你的数组是一维的，那就没必要了。&lt;br /&gt;
&lt;br /&gt;
===修改对象===&lt;br /&gt;
一个自定义用户程序通常从一个用户或者其它外部源获取输入，以便转化成Analytica模型中的输入变量。你可以设定输入变量的定义或者通过使用定义表格来这样做。 &lt;br /&gt;
&lt;br /&gt;
'''TestTxc''' 说明了如何修改'''Pop_exp'''定义，此模型是一个影响结果变量Cost的模型输入。要想在该示例中设定该定义，从主菜单上选择'''File &amp;gt; Change Population'''。将出现一个对话框，如下图所示：&lt;br /&gt;
&lt;br /&gt;
[[File:RedefiningtheVariableDefinition.jpg|400px/zh|文件：RedefiningtheVariableDefinition.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
在信息栏中输入一个新定义并点击'''Ok'''确认。主窗口将显示一个新的Cost值。当点击该对话框中的'''Ok'''按钮时，调用了&amp;lt;tt&amp;gt;ChangeDef.frm&amp;lt;/tt&amp;gt;函数，然后调用[[PrintAttributes/zh|PrintAttributes]]函数打印&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果。&lt;br /&gt;
&lt;br /&gt;
此函数类似于：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Private Sub OkButton_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles OkButton.Click &lt;br /&gt;
::Dim errorText As String&lt;br /&gt;
::Dim pop_exp_Object As [[CAObject/zh|CAObject]] &lt;br /&gt;
::Dim errorCode As Short &lt;br /&gt;
::Dim errorString As String &lt;br /&gt;
::newDefinition = PopExposedDef.Text &lt;br /&gt;
::pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
::pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]](&amp;quot;[[Definition]]&amp;quot;, newDefinition) &lt;br /&gt;
::errorCode = adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &lt;br /&gt;
::If errorCode &amp;lt;&amp;gt; 0 Then &lt;br /&gt;
:::MsgBox(&amp;quot;This error occurred while processing your definition: &amp;quot; &amp;amp; vbCrLf &amp;amp; vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) :::PopExposedDef.Focus()&lt;br /&gt;
::Else&lt;br /&gt;
:::Me.Close() &lt;br /&gt;
:::frmMain.DefInstance.PrintAttributes(&amp;quot;Pop_exp&amp;quot;, &amp;quot;Cost&amp;quot;) &lt;br /&gt;
::End If &lt;br /&gt;
::ReleaseComObject(pop_exp_Object) &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
该函数抓取了输入到'''New Definition''' 新定义给'''Population Exposed'''栏，并通过使用[[CAObject/zh|CAObject]]对象中的[[CAObject::SetAttribute/zh|SetAttribute]]函数将它设置给&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;对象。然后调用[[PrintAttributes/zh|PrintAttributes]]，以计算&amp;lt;tt&amp;gt;Cost object&amp;lt;/tt&amp;gt;，并打印新的结果。要想给变量&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;设定一个新定义，我们可以为&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;获取[[CAObject/zh|CAObject]]对象，然后将其定义设置成用户输入的定义。通过使用下面的代码来实现：&lt;br /&gt;
:pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
:pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]]( &amp;quot;[[Definition]]&amp;quot;, newDefinition )&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
无论什么时候调用[[CAObject::SetAttribute/zh|SetAttribute]]，都应该检查[[CAEngine/zh|CAEngine]]自动化对象（'''adeEngine'''）的[[CAEngine::ErrorCode/zh|ErrorCode]]，以免它的定义是非法的。尝试一下输入一个新定义，比如&amp;lt;code&amp;gt;[[Uniform]](25M,35M)&amp;lt;/code&amp;gt;，然后点击'''Ok'''。当&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;的定义被改变时， &amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果由ADE重新计算，此时'''ResultTable'''接下来调用给Cost变量（在应用程序窗口重新显示时）。&lt;br /&gt;
&lt;br /&gt;
使用ADE绘图&lt;br /&gt;
&lt;br /&gt;
通过Analytica 4.6使用相同的绘图引擎，你可以建立一个图表或者图形以显示一个数组值或者不确定值结果。在ADE4.6中，你可以使用 [[CATable/zh|CATable]]的[[CATable::GraphToFile/zh|GraphToFile]]和[[CATable::GraphToStream/zh|GraphToStream]]方法。图形可以以几种可能的图像格式返回，例如'''image/png'''、 '''image/bmp'''或者 '''image/jpeg'''。 &lt;br /&gt;
&lt;br /&gt;
从可用图形选项中选择的最简单方式就是使用Analytica打开你的模型。你可以实验设置各种默认设置或者替代选择的变量，看它们是如何工作的。但你选择了你想设置的选项，保存模型。当为每一个生成结果图形时，ADE将使用这些设置。 &lt;br /&gt;
&lt;br /&gt;
对于更高维度的结果，可能需要做一些必要工作，以便选择将绘制结果的切片和具体的轴（也就是相对于图例哪个维度作为X轴）。[[CATable/zh|CATable]]的[[CATable::Subscript/zh|Subscript]]或[[CATable::Slice/zh|Slice]]方法可以用来控制轴选择特殊的切片用来绘制，能够用来控制轴。详情请参考[[CATable/zh|CATable]]。在我们的&amp;lt;tt&amp;gt;Tutorial.NET&amp;lt;/tt&amp;gt;示例中，我们有一个一维结果（&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;），因此我们没有必要担心截取或者绕轴旋转。 &lt;br /&gt;
&lt;br /&gt;
[[CATable::GraphToStream/zh|GraphToStream]]方法被用来从ADE中直接转化图形图形到一个用户界面中。使用[[CATable::GraphToStream/zh|GraphToStream]]比起使用[[CATable::GraphToFile/zh|GraphToFile]]来要稍微复杂一点，因为[[CATable::GraphToFile/zh|GraphToFile]]除了需要文件名以外还需要其它一些信息，以便编写图形。要使用[[CATable::GraphToStream/zh|GraphToStream]]，我们必须在内存内设置一个流，允许ADE写入该留，然后从该留重建。因为.NET流和COM流不兼容，你必须使用ADE一同提供的[[StreamConnector]]类型.&amp;lt;tt&amp;gt;frmMain&amp;lt;/tt&amp;gt; 中的'''GraphResult_Click'''子程序演示了[[CATable::GraphToStream/zh|GraphToStream]]的使用。从主应用程序窗口选择 '''Graph Result'''菜单选项，结果将出现在一个如下所示的图形当中：&lt;br /&gt;
&lt;br /&gt;
[[File:resultgraph.jpg/zh|文件：resultgraph.jpg]]&lt;br /&gt;
&lt;br /&gt;
==结论==&lt;br /&gt;
&lt;br /&gt;
在此教程中，我们介绍了Analytica决策引擎的几个重要方面。我们看到了如何建立一个ADE服务器对象，使用ADE打开模型，获取模型中的单个对象、计算对象、获取表格中的元素，以及修改模型中的对象。但是ADE可以做的远不止这些。 &lt;br /&gt;
&lt;br /&gt;
我们希望你已经足够了解其基本特征，这样你现在才能独自开始探索更多新的高级特征。我们建议你现在开始阅读字教程的剩余部分以了解ADE能做什么。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
| [[Installation of ADE/zh|ADE 安装]] &amp;lt;- ||  [[The ADE Tutorial/zh|ADE 入门教程]] || -&amp;gt; [[Using the ADE Server/zh|使用ADE服务器]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36292</id>
		<title>The ADE Tutorial/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36292"/>
		<updated>2015-10-27T06:26:26Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南 ]]&lt;br /&gt;
&lt;br /&gt;
此教程教你如何在一个Visual Basic程序中使用Analytica决策引擎（ADE）。&lt;br /&gt;
&lt;br /&gt;
==你的第一个ADE应用程序==&lt;br /&gt;
首先先从头开始写一个简单的ADE程序，只要确认一切设置正常。按照以下步骤操作：&lt;br /&gt;
&lt;br /&gt;
test&lt;br /&gt;
&lt;br /&gt;
第一个程序执行了以下操作：&lt;br /&gt;
*建立一个名称为ADE的[[CAEngine/zh|CAEngine]]自动化对象（通过使用&amp;lt;code&amp;gt;new [[CAEngine/zh|CAEngine]]&amp;lt;/code&amp;gt;).&lt;br /&gt;
*打开Analytica模型 (通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]] 方法。&lt;br /&gt;
*显示模型名称返回[[CAEngine::OpenModel/zh|OpenModel]]的值。&lt;br /&gt;
我们将在后面的章节详细了解这些信息。&lt;br /&gt;
&lt;br /&gt;
===接下来讲什么呢?===&lt;br /&gt;
我们不会尝试在此入门教程中解释ADE的特征。本指南后面几个章节会描述这些特征。 &lt;br /&gt;
&lt;br /&gt;
从现在开始，我们我们将使用名称为&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;的示例模型。打开 Analytica安装目录下 '''Example Models'''文件夹里面的'''Risk Analysis'''文件夹便可找到&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;文件。如果你找不到，或者你安装Analytica的时候未选择安装examples（示例）文件，在ADE安装目录下面的'''Examples\Tutorial.NET'''文件家中有一个副本。 &lt;br /&gt;
&lt;br /&gt;
Txc模型演示了减少污染物TXC排放的risk-benefit （风险-效益）分析。请用Analytica打开Txc查看它是如何工作的。 &lt;br /&gt;
&lt;br /&gt;
ADE '''Examples\Tutorial.NET''' 文件夹中名称为&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;的Visual Basic.NET程序示例显示了ADE很多方面。该程序建立了一个ADE自动化对象，打开包含该对象的&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，获取变量 &amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，计算变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;，通过获取每个表格的单独组件以表格的方式打印输出变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的结果，然后改变变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义。再次获取变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的值，看一下 变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;定义的改变对变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;有什么影响。如果设置正确的话,&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;将显示在“Text Txc window”中显示的窗口。 &lt;br /&gt;
&lt;br /&gt;
应用程序显示变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义（&amp;lt;tt&amp;gt;&amp;quot;Normal (30M, 3M)&amp;quot;&amp;lt;/tt&amp;gt;），以及与&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;关联的表格，这都基于&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义。你可以通过从主菜单选择'''File &amp;gt; Change Population Exposed'''改变&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，然后查看改变对&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;表格的影响。&lt;br /&gt;
&lt;br /&gt;
[[File:TextTxcWindow.png|400px/zh | 文件：TextTxcWindow.png|400px]]&lt;br /&gt;
&lt;br /&gt;
===区分title（名称） 和 identifier（标识符）===&lt;br /&gt;
无论什么时候，一个ADE函数都需要一个变量你必须传达变量的'''''[[Identifier|标识符]]''''' ，而不是它的'''''[[Title|名称]]'''''。这可能会引起混淆，因为在Analytica影响图中一般显示每一个变量的名称。默认情况下，在你最初建立每一个对象的时候，Analytica自动根据名称建立一个标识符。用（_）代替名称中的每一个空格或者其他非字母和数字字符。 &lt;br /&gt;
&lt;br /&gt;
你可以通过点击“Control+y”（或者从Object（对象）菜单选择'''Show by identifier''' ：显示标识符） 来以标识符显示变量。对于模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;，你可以看到名称为&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;变量的标识符为 &amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;。将变量传递给ADE函数时，使用标识符很重要。如果你传递&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;，ADE无法找到变量，并且将返回一个错误。&lt;br /&gt;
&lt;br /&gt;
===从Visual Basic中建立一个ADE 对象===&lt;br /&gt;
&lt;br /&gt;
如果你还没准备好，将名称为tt&amp;gt;Examples\Tutorial\TestTxc.sln&amp;lt;/tt&amp;gt;载入到Visual Basic.NET中，查看名称为&amp;lt;tt&amp;gt;TestTxc.vb&amp;lt;/tt&amp;gt;的文件的代码。其代码看起来像：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Imports ADEW &lt;br /&gt;
:. . . &lt;br /&gt;
:Public adeEngine As [[CAEngine/zh|CAEngine]]&lt;br /&gt;
&lt;br /&gt;
:Public Sub Main() &lt;br /&gt;
::Dim exeDirectory, theModel As String &lt;br /&gt;
::Dim theModelString As String &lt;br /&gt;
::exeDirectory = VB6.GetPath &lt;br /&gt;
::theModel = exeDirectory &amp;amp; &amp;quot;\..\&amp;quot; &amp;amp; &amp;quot;Txc.ana&amp;quot; &lt;br /&gt;
::adeEngine = New [[CAEngine/zh|CAEngine]]&lt;br /&gt;
::... &lt;br /&gt;
::theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
::... &lt;br /&gt;
::frmMain.DefInstance.Show() &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在每一个文件的顶部的代码将自动化对象 '''adeEngine''' 声明为一个[[CAEngine/zh|CAEngine]] 对象。使用此对象，我们能够访问 [[CAEngine/zh|CAEngine]] 展示的所有公共函数（参考 [[ADE Server Class Reference/zh|ADE服务器类型参考]] ）&lt;br /&gt;
&lt;br /&gt;
变量&amp;lt;tt&amp;gt;adeEngine&amp;lt;/tt&amp;gt;包含我们的进程内对象 [[CAEngine/zh|CAEngine]]。如果我们想使用ADE的本地（进程外）服务器版本，我们可以将一个项目参考添加到'''Analytica Decision Engine Server 4.6 COM''' 组件并将顶部行从&amp;lt;tt&amp;gt;Imports ADEW&amp;lt;/tt&amp;gt;改成&amp;lt;tt&amp;gt;Imports ADE&amp;lt;/tt&amp;gt;即可。 &lt;br /&gt;
&lt;br /&gt;
这里是另一种获得一个先[[CAEngine/zh|CAEngine]]对象的方法。此循序不需要给项目添加参考。&amp;lt;tt&amp;gt;&lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADEW4.6.CAEngine&amp;quot;) ’ in-process &lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADE4.6.CAEngine&amp;quot;) ’ out-of-process &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果想理解使用进程内和进程外（或本地）服务器的利与弊，以及哪一种自动化服务器用于不同的场景，参考[[Using_the_Analytica_Decision_Engine_Server#In-process_vs_Out-of-process/zh | In-process vs. out-of-process]]&lt;br /&gt;
&lt;br /&gt;
===COM和 Automation 接口比较===&lt;br /&gt;
在上面的例子当中，我们使用COM接口调用ADE。在一个COM 接口中，对象 在本例中为 [[CAEngine/zh|CAEngine]] 被声明为[[CAEngine/zh|CAEngine]] ，编译器解决每一个成员函数，并且在编译时间内能探测几个明显的错误。另外，Visual Studio可以提供方法和参数类型列表当，在你编程的时候可以当做一个提示工具，在编写使用ADE程序是非常有用。COM调用比Automation调用要快一点，但是在ADE应用程序中速度差异通常不是很重要。对于ADE 4.6我们推荐使用COM结构，只要你的语言支持。&lt;br /&gt;
&lt;br /&gt;
在VB Automation中，你可以将一个对象简单声明为Object（对象），而不是像 [[CAEngine/zh|CAEngine]]、[[CAObject/zh|CAObject]]等更加具体的类型。当使用Automation调用'''ADE'''方法时，在运行时间内确定方法。在编译时间内，编译器不知道你的 '''ADE''' 对象是否有一个名称为[[CAEngine::OpenModel/zh|OpenModel]]的函数。在VB中，调用COM方法或Automation 方法的语法是相通的——唯一的不同在于对象类型是否明确被声明。&lt;br /&gt;
&lt;br /&gt;
在VC++和C#中，调用COM的语法和调用Automatio的语法不同。在这些情况下，COM要方便的多，Automation能够获得相冗余。然而，同样的语言，包括VBScript和其他脚本语言，只支持Automation不支持COM。&lt;br /&gt;
&lt;br /&gt;
===监视Process（进程）===&lt;br /&gt;
当使用进程外ADE服务器时，你的代码必须在终止时释放[[CAEngine/zh|CAEngine]]COM对象。当最终[[CAEngine/zh|CAEngine]]使用被释放是，ADE.exe 进程自动终止。到目前为止所看到的代码，VB语言在达到程序末端时，自动处理释放对象。但是，当你调试你的代码是，你可以提前终止你的程序来修复bug，你的程序可能被Task Manager（任务管理器）终止，或者你自己的代码也可能奔溃，导致你的程序进程在它有机会释放对象之前终止。应为COM对象从来不会被释放，ADE.exe进程不知道它是否在使用中，你可能获得ADE.exe 僵尸进程。 &lt;br /&gt;
&lt;br /&gt;
为了避免这种情况发生，一种好的习惯就是在调用[[CAEngine/zh|CAEngine]]实例后 立即调用[[CAEngine::MonitorProcess/zh|CAEngine::MonitorProcess]]。通过这种方式，ADE能够得知哪一个进程正在使用它，同时将设置一个线程去探测你的进程是否在ADE被完全释放前终止。如果你的程序进程没有终止，ADE进程会立即将它关闭，消除了僵尸ADE进程的堆积。 &lt;br /&gt;
&lt;br /&gt;
要从一个.NET应用程序获得进程ID，使用System.Diagnostics.Process namespace中的'''GetCurrentProcess().Id''' 。在其他语言中，你可以使用Windows SDK 的'''GetProcessId( )'''函数。 &lt;br /&gt;
&lt;br /&gt;
'''[[CAEngine::MonitorProcess/zh|MonitorProcess]]()''' 只能用来监视运行ADE进程的同一台计算机的进程，一次当通过DCOM运行ADE时不能使用。当使用进程内ADEW服务器时没有必要使用。&lt;br /&gt;
&lt;br /&gt;
==打开使用ADE的模型==&lt;br /&gt;
我们现在打开&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，显示我们的应用程序主窗口。使用以下调用：tt&amp;gt;&lt;br /&gt;
:theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
:frmMain.DefInstance.Show &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]]函数打开模型。如果成功的话，变量&amp;lt;tt&amp;gt;theModelString&amp;lt;/tt&amp;gt;将包含模型的名字。否则，将包含一个空的串。虽然由于为了简介的缘故，我们没有这样做，但是你应该检查从[[CAEngine::OpenModel/zh|OpenModel]]函数返回的是不是一个空的串。如果是，说明在你打开的模型中存在一个错误。你可以使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/z |ErrorText]]属性找出是哪种错误 （&amp;lt;tt&amp;gt;adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] 和adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]&amp;lt;/tt&amp;gt;）。&lt;br /&gt;
&lt;br /&gt;
==从Analytica模型中检索对象==&lt;br /&gt;
下一步就是从我们的模型中检索对象（变量、模块、函数等），以便我们能获取他们的属性（[[definition|定义]]、[[title|名称]]、[[class|类型]]等等 ）。我们的示例模型（&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;）操作&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;和&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;对象。尤其是，修改&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;可以查看这是如何影响&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt; 对象。&lt;br /&gt;
&lt;br /&gt;
我们的&amp;lt;tt&amp;gt;TxcTest.vbproj&amp;lt;/tt&amp;gt; （&amp;lt;tt&amp;gt;TxcText.sln&amp;lt;/tt&amp;gt;）项目中的&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;文件里的 '''PrintAttributes''' 函数演示了如何检索对象。该函数首先被&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''Form_Load''' 函数调用，当应用程序启动后，可以显示'''Cost'''表格。当然无论什么时候，只要我们想输出'''Cost'''表格的当前值，都可以调用。该函数如下所示：&lt;br /&gt;
:Public Sub PrintAttributes(ByRef inputIdentifier As String, ByRef  outputIdentifier As String) &lt;br /&gt;
::Dim inputObject, outputObject As [[CAObject/zh|CAObject]]&lt;br /&gt;
::Dim resultTable As [[CATable/zh|CATable]]&lt;br /&gt;
::Dim definitionAttrInput As String &lt;br /&gt;
::inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
::outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier) &lt;br /&gt;
::definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;definition&amp;quot;) &lt;br /&gt;
::resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]]&lt;br /&gt;
::Call PrintResultTable(resultTable, inputIdentifier, definitionAttrInput, outputIdentifier) &lt;br /&gt;
::ReleaseComObject(resultTable) &lt;br /&gt;
::ReleaseComObject(inputObject) &lt;br /&gt;
::ReleaseComObject(outputObject) &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''PrintAttributes'''和作为'''inputIdentifier'''参数的&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;变量标识符以及作为'''outputIdentifier'''参数的'''Cost'''变量一起使用。如下所示通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::GetObjectByName/zh|GetObjectByName]]函数提取相应对象：&amp;lt;tt&amp;gt;&lt;br /&gt;
:inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取成功，将返回一个[[CAObject/zh|CAObject]]类型对象。如果使用'''[[CAObject/zh|CAObject]]'''的函数，参考[[CAObject/zh|SendCommand(command)]]，可以获得一个[[CAObject/zh|CAObject]]的完整函数列表。如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取失败，返回值为&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;。代码应该检查以确保[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取的结果是有效的。如果找不到，可使用[[CAEngine/zh|CAEngine]]的 [[CAEngine::ErrorCode/zh|ErrorCode]]和 [[CAEngine::ErrorText/zh|ErrorText]]属性获取错误信息。例如：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Set inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:If inputObject Is Nothing Then &lt;br /&gt;
::MsgBox(“This error from GetObjectByName occurred: “&amp;amp; _ vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &amp;amp; “:” &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) &lt;br /&gt;
:Else &lt;br /&gt;
::'inputObject valid &lt;br /&gt;
:End If&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===获取对象属性===&lt;br /&gt;
每一个Analytica对象都有一组属性，例如[[identifier|标识符]]、[[title|名称]]、[[description| 描述]]和[[class|类型]]。你可以使用[[CAObject::GetAttribute/zh|GetAttribute]]函数来获去Analytica对象的属性。例如，如要获取'''inputObject'''的定义（当前为cost）：&amp;lt;tt&amp;gt;&lt;br /&gt;
:definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh|GetAttribute]](&amp;quot;[[Definition|定义]]&amp;quot;) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt; 中，&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;的定义为&amp;quot;&amp;lt;tt&amp;gt;[[Normal]](30M, 3M)&amp;lt;/tt&amp;gt;&amp;quot; ，我们将它储存在'''definitionAttrInput'''当中。.&lt;br /&gt;
&lt;br /&gt;
===计算对象和检索结果===&lt;br /&gt;
使用[[CAObject/zh|CAObject]]的[[CAObject::Result/zh|Result]]或[[CAObject::ResultTable/zh|ResultTable]]方法来获取变量的值。如果有必要的话，ADE先自动计算变量。如果你确定结果为基元（只有一个元素），使用[[CAObject::Result/zh|Result]]方法。否则使用[[CAObject::ResultTable/zh|ResultTable]]，检索结果为一个''数组''。基元结果当作一个特殊数组案例来处理，没有维度的数组。如果值为基元[[CATable::AtomicValue/zh|AtomicValue]]方法将返回一个数字或者字符串单一值。 &lt;br /&gt;
&lt;br /&gt;
默认情况下，[[CAObject::Result/zh | Result]]和[[CAObject::ResultTable/zh | ResultTable]]返回结果的中值，也就是说，ADE以确定性方式计算结果。对于一个概率值，将[[CAObject/zh | CAObject]]的[[CAObject::ResultType/zh | ResultType]]属性设置为想要的不确定性视图——Mean（平均值） Sample（样本）、PDF（概率密度函数）、CDF（累计分布函数）、Confidence bands（置信带）、或者Statistics（统计数据）详情请参考[[CAObject::ResultType/zh | ResultType]]。我们通过如下的方式获取outputObject 输出对象 的值：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable = outputObject.[[CAObject::ResultTable/zh |ResultTable]] &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
结果为一个[[CATable/zh | CATable]]对象，允许我们访问一个表格中的单个元素。 &lt;br /&gt;
&lt;br /&gt;
如果你通过调用[[CAObject::Result/zh | Result]]来获取一个数组（或者表格）的值，将返回数组为一个字符串，列出索引和元素，以逗号隔开。通常使用[[CAObject::ResultTable/zh | ResultTable]]更加简单，这样你没有必要从字符串中解析表格的元素。&lt;br /&gt;
&lt;br /&gt;
===获取表格索引元素===&lt;br /&gt;
一个Analytica表格包含0个或者多个索引。如果包含一个索引，那么该表格是1维表格；如果有2个索引，说他是2维表格，依此类推。0维度表格包含一个“单一基元”（或标量）值。你可以使用CATable的[[CATable::NumDims/zh | NumDims]]获取表格的维数（也就是索引数）。要想获取表格的单个索引，可使用[[CATable/zh | CATable]]的 [[CATable::IndexNames/zh | IndexNames]]和 [[CATable::GetIndexObject/zh | GetIndexObject]]函数。 &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''PrintResultTable'''函数说明了这两个函数的使用。从'''PrintAttributes'''中调用'''PrintResultTable'''，执行打印'''TestTxc'''中的表格的实际工作（为了简洁起见，我们只给出了关联ADE的该函数部分）。&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Public Sub PrintResultTable(ByRef resultTable As CATable, ByRef inputIdentifier As String, ByRef definitionAttrInput As String, ByRef outputIdentifier As String) &lt;br /&gt;
::Dim theIndexName, theTableName As String &lt;br /&gt;
::Dim theIndexElement As String &lt;br /&gt;
::Dim theTableElement &lt;br /&gt;
::Dim theIndexObj As [[CAIndex/zh | CAIndex]]&lt;br /&gt;
::Dim numEls As Integer &lt;br /&gt;
::Dim spaces, i As Integer &lt;br /&gt;
::Dim lenStr As Short &lt;br /&gt;
::Dim OutputStr As Short &lt;br /&gt;
::Dim spaceString, underlineString As String &lt;br /&gt;
::... &lt;br /&gt;
::theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1) &lt;br /&gt;
::theTableName = resultTable.[[CATable::Name/zh|Name]] &lt;br /&gt;
::theIndexObj = resultTable.[[CATable::GetIndexObject/zh | GetIndexObject]](theIndexName) &lt;br /&gt;
::numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
::... &lt;br /&gt;
::For i = 1 To numEls &lt;br /&gt;
:::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
:::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
:::... &lt;br /&gt;
::Next i &lt;br /&gt;
::InformationPane.Text = outputString &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
通过'''PrintResultTable'''获取一个表格的索引方法如下：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1)&lt;br /&gt;
:theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
我们通过使用[[CATable/zh|CATable]]的[[CATable::IndexNames/zh|IndexNames]]函数获取第一个索引的名字。我们将它传递给[[CATable/zh|CATable]]的[[CATable::GetIndexObject/zh|GetIndexObject]]函数以获取表示我们的索引的[[CAIndex/zh|CAIndex]]。该自动化对象返回其相应索引的相关信息。如果此函数调用失败，将返回&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;信息。在此情况下，使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]] 函数找出原因。&lt;br /&gt;
&lt;br /&gt;
==从CATable和CAIndex中获取信息==&lt;br /&gt;
[[PrintResultTable]]说明了如何从[[CATable/zh| CATable]]和[[CAIndex/zh|CAIndex]] 对象获取信息。该代码获取'''Cost'''表格的索引和表格元素：&lt;br /&gt;
: &amp;lt;tt&amp;gt;&lt;br /&gt;
:numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
:For i = 1 To numEls &lt;br /&gt;
::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
::... &lt;br /&gt;
:Next i &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[CAIndex/zh|CAIndex]]的[[CAIndex::IndexElements/zh|IndexElements]]属性返回第一个索引中的元素个数。[[CAIndex/zh|CAIndex]]的[[CAIndex::GetValueByNumber/zh|GetValueByNumber]]函数获取单个索引元素。 &lt;br /&gt;
&lt;br /&gt;
我们通过传递表格中元素的坐标，使用  [[CATable/zh|CATable]]的[[CATable::GetDataByElements/zh|GetDataByElements]]函数获取'''Cost'''表格对象的单个表格元素'''resultTable'''。 &lt;br /&gt;
&lt;br /&gt;
当我检索 [[CATable/zh|CATable]]对象中单个元素（'''resultTable'''）的时候，我们利用了该表格是一维的事实。因此，我们只需要传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个单一数（这个数代表表格中的位置）。但是，如果我们处理两个或者更多维度，我们必须传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个数组函数，并且指明我们要检索的表格元素的位置。因此，如果我们不想检索一个二维数组的position (4,3)位置的元素，我们可以这样写：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Dim W as Variant 'return element &lt;br /&gt;
:Dim IndexPtrs(1 To 2) As Variant 'position in table &lt;br /&gt;
::... &lt;br /&gt;
:IndexPtrs(1) = 4 &lt;br /&gt;
:IndexPtrs(2) = 3 &lt;br /&gt;
:W = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](IndexPtrs) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==控制基元值格式==&lt;br /&gt;
[[CATable/zh|CATable]]中的每个基元值可以是一个数、一个字符串，或者其它一些基本类型（''例如''：[[Null|空值]]、[[Undefined|未定义]]、[[Reference|参考]]，或 [[Handle|句柄]]。通过说明类型和值，它们作为''变体''被返回，这是一种Visual Basic能读懂的数据结构。[[CATable/zh|CATable]]的[[CATable::RenderingStyle|RenderingStyle]]属性控制Analytica基础值是如何映射到Visual Basic变体的。 &lt;br /&gt;
&lt;br /&gt;
例如：可以通过使用Analytica 模型的数字格式设置将一个数值返回成一个数字或者字符串。如果被指定格式，有一个选线控制是截断数字的位数，还是精确返回。 &lt;br /&gt;
&lt;br /&gt;
子程序[[PrintResultTable/zh|PrintResultTable]]在&amp;lt;tt&amp;gt;frmMain.vb&amp;lt;/tt&amp;gt;中载入,其渲染风格直接指明：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::NumberAsText/zh|NumberAsText]] = True &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::FullPrecision/zh|FullPrecision]] = False &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::StringQuotes/zh|StringQuotes]] = 2 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
第一行指明数值应该根据与结果对象有关的数字格式被格式化为文本。例如在其程序输出中，我们将看到&amp;lt;tt&amp;gt;30.103M&amp;lt;/tt&amp;gt;，而非&amp;lt;tt&amp;gt;30102995.6639812&amp;lt;/tt&amp;gt;，如果我们让Visual Basic将数值串联我们的结果字符串，将显示该结果。在此事件中，一个值为字符串的单元格出现在结果中，返回值将明确带双引号。对于[[CARenderingStyle/zh|CARenderingStyle]]对象中的所有可用属性，请参考[[CARenderingStyle/zh|CARenderingStyle]]。&lt;br /&gt;
&lt;br /&gt;
===其它访问表格的方式===&lt;br /&gt;
有几种访问多维表格[[CATable/zh|CATable]]中元素的方式。每一种都有可能在特定的场合使用起来比较方便。 &lt;br /&gt;
&lt;br /&gt;
第一种方式就是使用[[CATable/zh | CATable]]的 [[CATable::GetDataByElements/zh|GetDataByElements]]或[[CATable::GetDataByLabels/zh|GetDataByLabels]]方法，上面代码示例中有显示。在此情况下，利用你想获取的基元值的单元格位置。 &lt;br /&gt;
&lt;br /&gt;
第二种方式就是使用[[CATable/zh|CATable]][[CATable::Slice/zh|Slice]]或[[CATable::Subscript/zh | Subscript]]方法获取一个少一个维度的新[[CATable/zh|CATable]]对象。通过重复减少维度，最终将获得0维度，这时你将获得一个单一基元值。此时，[[CATable/zh|CATable]]的[[CATable::AtomicValue/zh|AtomicValue]]方法返回该值 。[[CATable::AtomicValue/zh|AtomicValue]]方法是唯一获取一个标值的方法（因为没有坐标位置）。如果你需要建立完整结果其中一个切片的图形图像，必须使用此方法。 &lt;br /&gt;
&lt;br /&gt;
第三种方式就是使用[[CATable/zh|CATable]]的[[CATable::GetSafeArray/zh|GetSafeArray]]方法，将多维数组转化成一个''安全数组''（或者一个.NET数组）。你可以在使用VB或者其它.NET语言直接处理多维数组。因为对于Analytica维度没有固定顺序，但是安全数组和.NET数组有一个明确的顺序，你必须先使用[[CATable/zh|CATable]]对象的[[CATable::SetIndexOrder/zh|SetIndexOrder]]方法在调用[[CATable::GetSafeArray/zh|GetSafeArray]]之前指明维度的顺序。注意如果你知道你的数组是一维的，那就没必要了。&lt;br /&gt;
&lt;br /&gt;
===修改对象===&lt;br /&gt;
一个自定义用户程序通常从一个用户或者其它外部源获取输入，以便转化成Analytica模型中的输入变量。你可以设定输入变量的定义或者通过使用定义表格来这样做。 &lt;br /&gt;
&lt;br /&gt;
'''TestTxc''' 说明了如何修改'''Pop_exp'''定义，此模型是一个影响结果变量Cost的模型输入。要想在该示例中设定该定义，从主菜单上选择'''File &amp;gt; Change Population'''。将出现一个对话框，如下图所示：&lt;br /&gt;
&lt;br /&gt;
[[File:RedefiningtheVariableDefinition.jpg|400px/zh|文件：RedefiningtheVariableDefinition.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
在信息栏中输入一个新定义并点击'''Ok'''确认。主窗口将显示一个新的Cost值。当点击该对话框中的'''Ok'''按钮时，调用了&amp;lt;tt&amp;gt;ChangeDef.frm&amp;lt;/tt&amp;gt;函数，然后调用[[PrintAttributes/zh|PrintAttributes]]函数打印&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果。&lt;br /&gt;
&lt;br /&gt;
此函数类似于：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Private Sub OkButton_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles OkButton.Click &lt;br /&gt;
::Dim errorText As String&lt;br /&gt;
::Dim pop_exp_Object As [[CAObject/zh|CAObject]] &lt;br /&gt;
::Dim errorCode As Short &lt;br /&gt;
::Dim errorString As String &lt;br /&gt;
::newDefinition = PopExposedDef.Text &lt;br /&gt;
::pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
::pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]](&amp;quot;[[Definition]]&amp;quot;, newDefinition) &lt;br /&gt;
::errorCode = adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &lt;br /&gt;
::If errorCode &amp;lt;&amp;gt; 0 Then &lt;br /&gt;
:::MsgBox(&amp;quot;This error occurred while processing your definition: &amp;quot; &amp;amp; vbCrLf &amp;amp; vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) :::PopExposedDef.Focus()&lt;br /&gt;
::Else&lt;br /&gt;
:::Me.Close() &lt;br /&gt;
:::frmMain.DefInstance.PrintAttributes(&amp;quot;Pop_exp&amp;quot;, &amp;quot;Cost&amp;quot;) &lt;br /&gt;
::End If &lt;br /&gt;
::ReleaseComObject(pop_exp_Object) &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
该函数抓取了输入到'''New Definition''' 新定义给'''Population Exposed'''栏，并通过使用[[CAObject/zh|CAObject]]对象中的[[CAObject::SetAttribute/zh|SetAttribute]]函数将它设置给&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;对象。然后调用[[PrintAttributes/zh|PrintAttributes]]，以计算&amp;lt;tt&amp;gt;Cost object&amp;lt;/tt&amp;gt;，并打印新的结果。要想给变量&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;设定一个新定义，我们可以为&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;获取[[CAObject/zh|CAObject]]对象，然后将其定义设置成用户输入的定义。通过使用下面的代码来实现：&lt;br /&gt;
:pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
:pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]]( &amp;quot;[[Definition]]&amp;quot;, newDefinition )&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
无论什么时候调用[[CAObject::SetAttribute/zh|SetAttribute]]，都应该检查[[CAEngine/zh|CAEngine]]自动化对象（'''adeEngine'''）的[[CAEngine::ErrorCode/zh|ErrorCode]]，以免它的定义是非法的。尝试一下输入一个新定义，比如&amp;lt;code&amp;gt;[[Uniform]](25M,35M)&amp;lt;/code&amp;gt;，然后点击'''Ok'''。当&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;的定义被改变时， &amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果由ADE重新计算，此时'''ResultTable'''接下来调用给Cost变量（在应用程序窗口重新显示时）。&lt;br /&gt;
&lt;br /&gt;
使用ADE绘图&lt;br /&gt;
&lt;br /&gt;
通过Analytica 4.6使用相同的绘图引擎，你可以建立一个图表或者图形以显示一个数组值或者不确定值结果。在ADE4.6中，你可以使用 [[CATable/zh|CATable]]的[[CATable::GraphToFile/zh|GraphToFile]]和[[CATable::GraphToStream/zh|GraphToStream]]方法。图形可以以几种可能的图像格式返回，例如'''image/png'''、 '''image/bmp'''或者 '''image/jpeg'''。 &lt;br /&gt;
&lt;br /&gt;
从可用图形选项中选择的最简单方式就是使用Analytica打开你的模型。你可以实验设置各种默认设置或者替代选择的变量，看它们是如何工作的。但你选择了你想设置的选项，保存模型。当为每一个生成结果图形时，ADE将使用这些设置。 &lt;br /&gt;
&lt;br /&gt;
对于更高维度的结果，可能需要做一些必要工作，以便选择将绘制结果的切片和具体的轴（也就是相对于图例哪个维度作为X轴）。[[CATable/zh|CATable]]的[[CATable::Subscript/zh|Subscript]]或[[CATable::Slice/zh|Slice]]方法可以用来控制轴选择特殊的切片用来绘制，能够用来控制轴。详情请参考[[CATable/zh|CATable]]。在我们的&amp;lt;tt&amp;gt;Tutorial.NET&amp;lt;/tt&amp;gt;示例中，我们有一个一维结果（&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;），因此我们没有必要担心截取或者绕轴旋转。 &lt;br /&gt;
&lt;br /&gt;
[[CATable::GraphToStream/zh|GraphToStream]]方法被用来从ADE中直接转化图形图形到一个用户界面中。使用[[CATable::GraphToStream/zh|GraphToStream]]比起使用[[CATable::GraphToFile/zh|GraphToFile]]来要稍微复杂一点，因为[[CATable::GraphToFile/zh|GraphToFile]]除了需要文件名以外还需要其它一些信息，以便编写图形。要使用[[CATable::GraphToStream/zh|GraphToStream]]，我们必须在内存内设置一个流，允许ADE写入该留，然后从该留重建。因为.NET流和COM流不兼容，你必须使用ADE一同提供的[[StreamConnector]]类型.&amp;lt;tt&amp;gt;frmMain&amp;lt;/tt&amp;gt; 中的'''GraphResult_Click'''子程序演示了[[CATable::GraphToStream/zh|GraphToStream]]的使用。从主应用程序窗口选择 '''Graph Result'''菜单选项，结果将出现在一个如下所示的图形当中：&lt;br /&gt;
&lt;br /&gt;
[[File:resultgraph.jpg/zh|文件：resultgraph.jpg]]&lt;br /&gt;
&lt;br /&gt;
==结论==&lt;br /&gt;
&lt;br /&gt;
在此教程中，我们介绍了Analytica决策引擎的几个重要方面。我们看到了如何建立一个ADE服务器对象，使用ADE打开模型，获取模型中的单个对象、计算对象、获取表格中的元素，以及修改模型中的对象。但是ADE可以做的远不止这些。 &lt;br /&gt;
&lt;br /&gt;
我们希望你已经足够了解其基本特征，这样你现在才能独自开始探索更多新的高级特征。我们建议你现在开始阅读字教程的剩余部分以了解ADE能做什么。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
| [[Installation of ADE/zh|ADE 安装]] &amp;lt;- ||  [[The ADE Tutorial/zh|ADE 入门教程]] || -&amp;gt; [[Using the ADE Server/zh|使用ADE服务器]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36290</id>
		<title>The ADE Tutorial/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36290"/>
		<updated>2015-10-27T06:26:02Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南 ]]&lt;br /&gt;
&lt;br /&gt;
此教程教你如何在一个Visual Basic程序中使用Analytica决策引擎（ADE）。&lt;br /&gt;
&lt;br /&gt;
==你的第一个ADE应用程序==&lt;br /&gt;
首先先从头开始写一个简单的ADE程序，只要确认一切设置正常。按照以下步骤操作：&lt;br /&gt;
&lt;br /&gt;
test&lt;br /&gt;
&lt;br /&gt;
第一个程序执行了以下操作：&lt;br /&gt;
*建立一个名称为ADE的[[CAEngine/zh|CAEngine]]自动化对象（通过使用&amp;lt;code&amp;gt;new [[CAEngine/zh|CAEngine]]&amp;lt;/code&amp;gt;).&lt;br /&gt;
*打开Analytica模型 (通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]] 方法。&lt;br /&gt;
*显示模型名称返回[[CAEngine::OpenModel/zh|OpenModel]]的值。&lt;br /&gt;
我们将在后面的章节详细了解这些信息。&lt;br /&gt;
&lt;br /&gt;
===接下来讲什么呢?===&lt;br /&gt;
我们不会尝试在此入门教程中解释ADE的特征。本指南后面几个章节会描述这些特征。 &lt;br /&gt;
&lt;br /&gt;
从现在开始，我们我们将使用名称为&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;的示例模型。打开 Analytica安装目录下 '''Example Models'''文件夹里面的'''Risk Analysis'''文件夹便可找到&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;文件。如果你找不到，或者你安装Analytica的时候未选择安装examples（示例）文件，在ADE安装目录下面的'''Examples\Tutorial.NET'''文件家中有一个副本。 &lt;br /&gt;
&lt;br /&gt;
Txc模型演示了减少污染物TXC排放的risk-benefit （风险-效益）分析。请用Analytica打开Txc查看它是如何工作的。 &lt;br /&gt;
&lt;br /&gt;
ADE '''Examples\Tutorial.NET''' 文件夹中名称为&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;的Visual Basic.NET程序示例显示了ADE很多方面。该程序建立了一个ADE自动化对象，打开包含该对象的&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，获取变量 &amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，计算变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;，通过获取每个表格的单独组件以表格的方式打印输出变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的结果，然后改变变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义。再次获取变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的值，看一下 变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;定义的改变对变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;有什么影响。如果设置正确的话,&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;将显示在“Text Txc window”中显示的窗口。 &lt;br /&gt;
&lt;br /&gt;
应用程序显示变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义（&amp;lt;tt&amp;gt;&amp;quot;Normal (30M, 3M)&amp;quot;&amp;lt;/tt&amp;gt;），以及与&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;关联的表格，这都基于&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义。你可以通过从主菜单选择'''File &amp;gt; Change Population Exposed'''改变&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，然后查看改变对&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;表格的影响。&lt;br /&gt;
&lt;br /&gt;
[[File:TextTxcWindow.png|400px/zh | 文件：TextTxcWindow.png|400px]]&lt;br /&gt;
&lt;br /&gt;
===区分title（名称） 和 identifier（标识符）===&lt;br /&gt;
无论什么时候，一个ADE函数都需要一个变量你必须传达变量的'''''[[Identifier|标识符]]''''' ，而不是它的'''''[[Title|名称]]'''''。这可能会引起混淆，因为在Analytica影响图中一般显示每一个变量的名称。默认情况下，在你最初建立每一个对象的时候，Analytica自动根据名称建立一个标识符。用（_）代替名称中的每一个空格或者其他非字母和数字字符。 &lt;br /&gt;
&lt;br /&gt;
你可以通过点击“Control+y”（或者从Object（对象）菜单选择'''Show by identifier''' ：显示标识符） 来以标识符显示变量。对于模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;，你可以看到名称为&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;变量的标识符为 &amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;。将变量传递给ADE函数时，使用标识符很重要。如果你传递&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;，ADE无法找到变量，并且将返回一个错误。&lt;br /&gt;
&lt;br /&gt;
===从Visual Basic中建立一个ADE 对象===&lt;br /&gt;
&lt;br /&gt;
如果你还没准备好，将名称为tt&amp;gt;Examples\Tutorial\TestTxc.sln&amp;lt;/tt&amp;gt;载入到Visual Basic.NET中，查看名称为&amp;lt;tt&amp;gt;TestTxc.vb&amp;lt;/tt&amp;gt;的文件的代码。其代码看起来像：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Imports ADEW &lt;br /&gt;
:. . . &lt;br /&gt;
:Public adeEngine As [[CAEngine/zh|CAEngine]]&lt;br /&gt;
&lt;br /&gt;
:Public Sub Main() &lt;br /&gt;
::Dim exeDirectory, theModel As String &lt;br /&gt;
::Dim theModelString As String &lt;br /&gt;
::exeDirectory = VB6.GetPath &lt;br /&gt;
::theModel = exeDirectory &amp;amp; &amp;quot;\..\&amp;quot; &amp;amp; &amp;quot;Txc.ana&amp;quot; &lt;br /&gt;
::adeEngine = New [[CAEngine/zh|CAEngine]]&lt;br /&gt;
::... &lt;br /&gt;
::theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
::... &lt;br /&gt;
::frmMain.DefInstance.Show() &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在每一个文件的顶部的代码将自动化对象 '''adeEngine''' 声明为一个[[CAEngine/zh|CAEngine]] 对象。使用此对象，我们能够访问 [[CAEngine/zh|CAEngine]] 展示的所有公共函数（参考 [[ADE Server Class Reference/zh|ADE服务器类型参考]] ）&lt;br /&gt;
&lt;br /&gt;
变量&amp;lt;tt&amp;gt;adeEngine&amp;lt;/tt&amp;gt;包含我们的进程内对象 [[CAEngine/zh|CAEngine]]。如果我们想使用ADE的本地（进程外）服务器版本，我们可以将一个项目参考添加到'''Analytica Decision Engine Server 4.6 COM''' 组件并将顶部行从&amp;lt;tt&amp;gt;Imports ADEW&amp;lt;/tt&amp;gt;改成&amp;lt;tt&amp;gt;Imports ADE&amp;lt;/tt&amp;gt;即可。 &lt;br /&gt;
&lt;br /&gt;
这里是另一种获得一个先[[CAEngine/zh|CAEngine]]对象的方法。此循序不需要给项目添加参考。&amp;lt;tt&amp;gt;&lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADEW4.6.CAEngine&amp;quot;) ’ in-process &lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADE4.6.CAEngine&amp;quot;) ’ out-of-process &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果想理解使用进程内和进程外（或本地）服务器的利与弊，以及哪一种自动化服务器用于不同的场景，参考[[Using_the_Analytica_Decision_Engine_Server#In-process_vs_Out-of-process/zh | In-process vs. out-of-process]]&lt;br /&gt;
&lt;br /&gt;
===COM和 Automation 接口比较===&lt;br /&gt;
在上面的例子当中，我们使用COM接口调用ADE。在一个COM 接口中，对象 在本例中为 [[CAEngine/zh|CAEngine]] 被声明为[[CAEngine/zh|CAEngine]] ，编译器解决每一个成员函数，并且在编译时间内能探测几个明显的错误。另外，Visual Studio可以提供方法和参数类型列表当，在你编程的时候可以当做一个提示工具，在编写使用ADE程序是非常有用。COM调用比Automation调用要快一点，但是在ADE应用程序中速度差异通常不是很重要。对于ADE 4.6我们推荐使用COM结构，只要你的语言支持。&lt;br /&gt;
&lt;br /&gt;
在VB Automation中，你可以将一个对象简单声明为Object（对象），而不是像 [[CAEngine/zh|CAEngine]]、[[CAObject/zh|CAObject]]等更加具体的类型。当使用Automation调用'''ADE'''方法时，在运行时间内确定方法。在编译时间内，编译器不知道你的 '''ADE''' 对象是否有一个名称为[[CAEngine::OpenModel/zh|OpenModel]]的函数。在VB中，调用COM方法或Automation 方法的语法是相通的——唯一的不同在于对象类型是否明确被声明。&lt;br /&gt;
&lt;br /&gt;
在VC++和C#中，调用COM的语法和调用Automatio的语法不同。在这些情况下，COM要方便的多，Automation能够获得相冗余。然而，同样的语言，包括VBScript和其他脚本语言，只支持Automation不支持COM。&lt;br /&gt;
&lt;br /&gt;
===监视Process（进程）===&lt;br /&gt;
当使用进程外ADE服务器时，你的代码必须在终止时释放[[CAEngine/zh|CAEngine]]COM对象。当最终[[CAEngine/zh|CAEngine]]使用被释放是，ADE.exe 进程自动终止。到目前为止所看到的代码，VB语言在达到程序末端时，自动处理释放对象。但是，当你调试你的代码是，你可以提前终止你的程序来修复bug，你的程序可能被Task Manager（任务管理器）终止，或者你自己的代码也可能奔溃，导致你的程序进程在它有机会释放对象之前终止。应为COM对象从来不会被释放，ADE.exe进程不知道它是否在使用中，你可能获得ADE.exe 僵尸进程。 &lt;br /&gt;
&lt;br /&gt;
为了避免这种情况发生，一种好的习惯就是在调用[[CAEngine/zh|CAEngine]]实例后 立即调用[[CAEngine::MonitorProcess/zh|CAEngine::MonitorProcess]]。通过这种方式，ADE能够得知哪一个进程正在使用它，同时将设置一个线程去探测你的进程是否在ADE被完全释放前终止。如果你的程序进程没有终止，ADE进程会立即将它关闭，消除了僵尸ADE进程的堆积。 &lt;br /&gt;
&lt;br /&gt;
要从一个.NET应用程序获得进程ID，使用System.Diagnostics.Process namespace中的'''GetCurrentProcess().Id''' 。在其他语言中，你可以使用Windows SDK 的'''GetProcessId( )'''函数。 &lt;br /&gt;
&lt;br /&gt;
'''[[CAEngine::MonitorProcess/zh|MonitorProcess]]()''' 只能用来监视运行ADE进程的同一台计算机的进程，一次当通过DCOM运行ADE时不能使用。当使用进程内ADEW服务器时没有必要使用。&lt;br /&gt;
&lt;br /&gt;
==打开使用ADE的模型==&lt;br /&gt;
我们现在打开&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，显示我们的应用程序主窗口。使用以下调用：tt&amp;gt;&lt;br /&gt;
:theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
:frmMain.DefInstance.Show &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]]函数打开模型。如果成功的话，变量&amp;lt;tt&amp;gt;theModelString&amp;lt;/tt&amp;gt;将包含模型的名字。否则，将包含一个空的串。虽然由于为了简介的缘故，我们没有这样做，但是你应该检查从[[CAEngine::OpenModel/zh|OpenModel]]函数返回的是不是一个空的串。如果是，说明在你打开的模型中存在一个错误。你可以使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/z |ErrorText]]属性找出是哪种错误 （&amp;lt;tt&amp;gt;adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] 和adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]&amp;lt;/tt&amp;gt;）。&lt;br /&gt;
&lt;br /&gt;
==从Analytica模型中检索对象==&lt;br /&gt;
下一步就是从我们的模型中检索对象（变量、模块、函数等），以便我们能获取他们的属性（[[definition|定义]]、[[title|名称]]、[[class|类型]]等等 ）。我们的示例模型（&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;）操作&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;和&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;对象。尤其是，修改&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;可以查看这是如何影响&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt; 对象。&lt;br /&gt;
&lt;br /&gt;
我们的&amp;lt;tt&amp;gt;TxcTest.vbproj&amp;lt;/tt&amp;gt; （&amp;lt;tt&amp;gt;TxcText.sln&amp;lt;/tt&amp;gt;）项目中的&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;文件里的 '''PrintAttributes''' 函数演示了如何检索对象。该函数首先被&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''Form_Load''' 函数调用，当应用程序启动后，可以显示'''Cost'''表格。当然无论什么时候，只要我们想输出'''Cost'''表格的当前值，都可以调用。该函数如下所示：&lt;br /&gt;
:Public Sub PrintAttributes(ByRef inputIdentifier As String, ByRef  outputIdentifier As String) &lt;br /&gt;
::Dim inputObject, outputObject As [[CAObject/zh|CAObject]]&lt;br /&gt;
::Dim resultTable As [[CATable/zh|CATable]]&lt;br /&gt;
::Dim definitionAttrInput As String &lt;br /&gt;
::inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
::outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier) &lt;br /&gt;
::definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;definition&amp;quot;) &lt;br /&gt;
::resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]]&lt;br /&gt;
::Call PrintResultTable(resultTable, inputIdentifier, definitionAttrInput, outputIdentifier) &lt;br /&gt;
::ReleaseComObject(resultTable) &lt;br /&gt;
::ReleaseComObject(inputObject) &lt;br /&gt;
::ReleaseComObject(outputObject) &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''PrintAttributes'''和作为'''inputIdentifier'''参数的&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;变量标识符以及作为'''outputIdentifier'''参数的'''Cost'''变量一起使用。如下所示通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::GetObjectByName/zh|GetObjectByName]]函数提取相应对象：&amp;lt;tt&amp;gt;&lt;br /&gt;
:inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取成功，将返回一个[[CAObject/zh|CAObject]]类型对象。如果使用'''[[CAObject/zh|CAObject]]'''的函数，参考[[CAObject/zh|SendCommand(command)]]，可以获得一个[[CAObject/zh|CAObject]]的完整函数列表。如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取失败，返回值为&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;。代码应该检查以确保[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取的结果是有效的。如果找不到，可使用[[CAEngine/zh|CAEngine]]的 [[CAEngine::ErrorCode/zh|ErrorCode]]和 [[CAEngine::ErrorText/zh|ErrorText]]属性获取错误信息。例如：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Set inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:If inputObject Is Nothing Then &lt;br /&gt;
::MsgBox(“This error from GetObjectByName occurred: “&amp;amp; _ vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &amp;amp; “:” &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) &lt;br /&gt;
:Else &lt;br /&gt;
::'inputObject valid &lt;br /&gt;
:End If&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===获取对象属性===&lt;br /&gt;
每一个Analytica对象都有一组属性，例如[[identifier|标识符]]、[[title|名称]]、[[description| 描述]]和[[class|类型]]。你可以使用[[CAObject::GetAttribute/zh|GetAttribute]]函数来获去Analytica对象的属性。例如，如要获取'''inputObject'''的定义（当前为cost）：&amp;lt;tt&amp;gt;&lt;br /&gt;
:definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh|GetAttribute]](&amp;quot;[[Definition|定义]]&amp;quot;) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt; 中，&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;的定义为&amp;quot;&amp;lt;tt&amp;gt;[[Normal]](30M, 3M)&amp;lt;/tt&amp;gt;&amp;quot; ，我们将它储存在'''definitionAttrInput'''当中。.&lt;br /&gt;
&lt;br /&gt;
===计算对象和检索结果===&lt;br /&gt;
使用[[CAObject/zh | CAObject]]的[[CAObject::Result/zh | Result]]或[[CAObject::ResultTable/zh | ResultTable]]方法来获取变量的值。如果有必要的话，ADE先自动计算变量。如果你确定结果为基元（只有一个元素），使用[[CAObject::Result/zh | Result]]方法。否则使用[[CAObject::ResultTable/zh | ResultTable]]，检索结果为一个''数组''。基元结果当作一个特殊数组案例来处理，没有维度的数组。如果值为基元[[CATable::AtomicValue/zh | AtomicValue]]方法将返回一个数字或者字符串单一值。 &lt;br /&gt;
&lt;br /&gt;
默认情况下，[[CAObject::Result/zh | Result]]和[[CAObject::ResultTable/zh | ResultTable]]返回结果的中值，也就是说，ADE以确定性方式计算结果。对于一个概率值，将[[CAObject/zh | CAObject]]的[[CAObject::ResultType/zh | ResultType]]属性设置为想要的不确定性视图——Mean（平均值） Sample（样本）、PDF（概率密度函数）、CDF（累计分布函数）、Confidence bands（置信带）、或者Statistics（统计数据）详情请参考[[CAObject::ResultType/zh | ResultType]]。我们通过如下的方式获取outputObject 输出对象 的值：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable = outputObject.[[CAObject::ResultTable/zh |ResultTable]] &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
结果为一个[[CATable/zh | CATable]]对象，允许我们访问一个表格中的单个元素。 &lt;br /&gt;
&lt;br /&gt;
如果你通过调用[[CAObject::Result/zh | Result]]来获取一个数组（或者表格）的值，将返回数组为一个字符串，列出索引和元素，以逗号隔开。通常使用[[CAObject::ResultTable/zh | ResultTable]]更加简单，这样你没有必要从字符串中解析表格的元素。&lt;br /&gt;
&lt;br /&gt;
===获取表格索引元素===&lt;br /&gt;
一个Analytica表格包含0个或者多个索引。如果包含一个索引，那么该表格是1维表格；如果有2个索引，说他是2维表格，依此类推。0维度表格包含一个“单一基元”（或标量）值。你可以使用CATable的[[CATable::NumDims/zh | NumDims]]获取表格的维数（也就是索引数）。要想获取表格的单个索引，可使用[[CATable/zh | CATable]]的 [[CATable::IndexNames/zh | IndexNames]]和 [[CATable::GetIndexObject/zh | GetIndexObject]]函数。 &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''PrintResultTable'''函数说明了这两个函数的使用。从'''PrintAttributes'''中调用'''PrintResultTable'''，执行打印'''TestTxc'''中的表格的实际工作（为了简洁起见，我们只给出了关联ADE的该函数部分）。&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Public Sub PrintResultTable(ByRef resultTable As CATable, ByRef inputIdentifier As String, ByRef definitionAttrInput As String, ByRef outputIdentifier As String) &lt;br /&gt;
::Dim theIndexName, theTableName As String &lt;br /&gt;
::Dim theIndexElement As String &lt;br /&gt;
::Dim theTableElement &lt;br /&gt;
::Dim theIndexObj As [[CAIndex/zh | CAIndex]]&lt;br /&gt;
::Dim numEls As Integer &lt;br /&gt;
::Dim spaces, i As Integer &lt;br /&gt;
::Dim lenStr As Short &lt;br /&gt;
::Dim OutputStr As Short &lt;br /&gt;
::Dim spaceString, underlineString As String &lt;br /&gt;
::... &lt;br /&gt;
::theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1) &lt;br /&gt;
::theTableName = resultTable.[[CATable::Name/zh|Name]] &lt;br /&gt;
::theIndexObj = resultTable.[[CATable::GetIndexObject/zh | GetIndexObject]](theIndexName) &lt;br /&gt;
::numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
::... &lt;br /&gt;
::For i = 1 To numEls &lt;br /&gt;
:::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
:::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
:::... &lt;br /&gt;
::Next i &lt;br /&gt;
::InformationPane.Text = outputString &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
通过'''PrintResultTable'''获取一个表格的索引方法如下：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1)&lt;br /&gt;
:theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
我们通过使用[[CATable/zh|CATable]]的[[CATable::IndexNames/zh|IndexNames]]函数获取第一个索引的名字。我们将它传递给[[CATable/zh|CATable]]的[[CATable::GetIndexObject/zh|GetIndexObject]]函数以获取表示我们的索引的[[CAIndex/zh|CAIndex]]。该自动化对象返回其相应索引的相关信息。如果此函数调用失败，将返回&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;信息。在此情况下，使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]] 函数找出原因。&lt;br /&gt;
&lt;br /&gt;
==从CATable和CAIndex中获取信息==&lt;br /&gt;
[[PrintResultTable]]说明了如何从[[CATable/zh| CATable]]和[[CAIndex/zh|CAIndex]] 对象获取信息。该代码获取'''Cost'''表格的索引和表格元素：&lt;br /&gt;
: &amp;lt;tt&amp;gt;&lt;br /&gt;
:numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
:For i = 1 To numEls &lt;br /&gt;
::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
::... &lt;br /&gt;
:Next i &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[CAIndex/zh|CAIndex]]的[[CAIndex::IndexElements/zh|IndexElements]]属性返回第一个索引中的元素个数。[[CAIndex/zh|CAIndex]]的[[CAIndex::GetValueByNumber/zh|GetValueByNumber]]函数获取单个索引元素。 &lt;br /&gt;
&lt;br /&gt;
我们通过传递表格中元素的坐标，使用  [[CATable/zh|CATable]]的[[CATable::GetDataByElements/zh|GetDataByElements]]函数获取'''Cost'''表格对象的单个表格元素'''resultTable'''。 &lt;br /&gt;
&lt;br /&gt;
当我检索 [[CATable/zh|CATable]]对象中单个元素（'''resultTable'''）的时候，我们利用了该表格是一维的事实。因此，我们只需要传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个单一数（这个数代表表格中的位置）。但是，如果我们处理两个或者更多维度，我们必须传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个数组函数，并且指明我们要检索的表格元素的位置。因此，如果我们不想检索一个二维数组的position (4,3)位置的元素，我们可以这样写：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Dim W as Variant 'return element &lt;br /&gt;
:Dim IndexPtrs(1 To 2) As Variant 'position in table &lt;br /&gt;
::... &lt;br /&gt;
:IndexPtrs(1) = 4 &lt;br /&gt;
:IndexPtrs(2) = 3 &lt;br /&gt;
:W = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](IndexPtrs) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==控制基元值格式==&lt;br /&gt;
[[CATable/zh|CATable]]中的每个基元值可以是一个数、一个字符串，或者其它一些基本类型（''例如''：[[Null|空值]]、[[Undefined|未定义]]、[[Reference|参考]]，或 [[Handle|句柄]]。通过说明类型和值，它们作为''变体''被返回，这是一种Visual Basic能读懂的数据结构。[[CATable/zh|CATable]]的[[CATable::RenderingStyle|RenderingStyle]]属性控制Analytica基础值是如何映射到Visual Basic变体的。 &lt;br /&gt;
&lt;br /&gt;
例如：可以通过使用Analytica 模型的数字格式设置将一个数值返回成一个数字或者字符串。如果被指定格式，有一个选线控制是截断数字的位数，还是精确返回。 &lt;br /&gt;
&lt;br /&gt;
子程序[[PrintResultTable/zh|PrintResultTable]]在&amp;lt;tt&amp;gt;frmMain.vb&amp;lt;/tt&amp;gt;中载入,其渲染风格直接指明：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::NumberAsText/zh|NumberAsText]] = True &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::FullPrecision/zh|FullPrecision]] = False &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::StringQuotes/zh|StringQuotes]] = 2 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
第一行指明数值应该根据与结果对象有关的数字格式被格式化为文本。例如在其程序输出中，我们将看到&amp;lt;tt&amp;gt;30.103M&amp;lt;/tt&amp;gt;，而非&amp;lt;tt&amp;gt;30102995.6639812&amp;lt;/tt&amp;gt;，如果我们让Visual Basic将数值串联我们的结果字符串，将显示该结果。在此事件中，一个值为字符串的单元格出现在结果中，返回值将明确带双引号。对于[[CARenderingStyle/zh|CARenderingStyle]]对象中的所有可用属性，请参考[[CARenderingStyle/zh|CARenderingStyle]]。&lt;br /&gt;
&lt;br /&gt;
===其它访问表格的方式===&lt;br /&gt;
有几种访问多维表格[[CATable/zh|CATable]]中元素的方式。每一种都有可能在特定的场合使用起来比较方便。 &lt;br /&gt;
&lt;br /&gt;
第一种方式就是使用[[CATable/zh | CATable]]的 [[CATable::GetDataByElements/zh|GetDataByElements]]或[[CATable::GetDataByLabels/zh|GetDataByLabels]]方法，上面代码示例中有显示。在此情况下，利用你想获取的基元值的单元格位置。 &lt;br /&gt;
&lt;br /&gt;
第二种方式就是使用[[CATable/zh|CATable]][[CATable::Slice/zh|Slice]]或[[CATable::Subscript/zh | Subscript]]方法获取一个少一个维度的新[[CATable/zh|CATable]]对象。通过重复减少维度，最终将获得0维度，这时你将获得一个单一基元值。此时，[[CATable/zh|CATable]]的[[CATable::AtomicValue/zh|AtomicValue]]方法返回该值 。[[CATable::AtomicValue/zh|AtomicValue]]方法是唯一获取一个标值的方法（因为没有坐标位置）。如果你需要建立完整结果其中一个切片的图形图像，必须使用此方法。 &lt;br /&gt;
&lt;br /&gt;
第三种方式就是使用[[CATable/zh|CATable]]的[[CATable::GetSafeArray/zh|GetSafeArray]]方法，将多维数组转化成一个''安全数组''（或者一个.NET数组）。你可以在使用VB或者其它.NET语言直接处理多维数组。因为对于Analytica维度没有固定顺序，但是安全数组和.NET数组有一个明确的顺序，你必须先使用[[CATable/zh|CATable]]对象的[[CATable::SetIndexOrder/zh|SetIndexOrder]]方法在调用[[CATable::GetSafeArray/zh|GetSafeArray]]之前指明维度的顺序。注意如果你知道你的数组是一维的，那就没必要了。&lt;br /&gt;
&lt;br /&gt;
===修改对象===&lt;br /&gt;
一个自定义用户程序通常从一个用户或者其它外部源获取输入，以便转化成Analytica模型中的输入变量。你可以设定输入变量的定义或者通过使用定义表格来这样做。 &lt;br /&gt;
&lt;br /&gt;
'''TestTxc''' 说明了如何修改'''Pop_exp'''定义，此模型是一个影响结果变量Cost的模型输入。要想在该示例中设定该定义，从主菜单上选择'''File &amp;gt; Change Population'''。将出现一个对话框，如下图所示：&lt;br /&gt;
&lt;br /&gt;
[[File:RedefiningtheVariableDefinition.jpg|400px/zh|文件：RedefiningtheVariableDefinition.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
在信息栏中输入一个新定义并点击'''Ok'''确认。主窗口将显示一个新的Cost值。当点击该对话框中的'''Ok'''按钮时，调用了&amp;lt;tt&amp;gt;ChangeDef.frm&amp;lt;/tt&amp;gt;函数，然后调用[[PrintAttributes/zh|PrintAttributes]]函数打印&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果。&lt;br /&gt;
&lt;br /&gt;
此函数类似于：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Private Sub OkButton_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles OkButton.Click &lt;br /&gt;
::Dim errorText As String&lt;br /&gt;
::Dim pop_exp_Object As [[CAObject/zh|CAObject]] &lt;br /&gt;
::Dim errorCode As Short &lt;br /&gt;
::Dim errorString As String &lt;br /&gt;
::newDefinition = PopExposedDef.Text &lt;br /&gt;
::pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
::pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]](&amp;quot;[[Definition]]&amp;quot;, newDefinition) &lt;br /&gt;
::errorCode = adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &lt;br /&gt;
::If errorCode &amp;lt;&amp;gt; 0 Then &lt;br /&gt;
:::MsgBox(&amp;quot;This error occurred while processing your definition: &amp;quot; &amp;amp; vbCrLf &amp;amp; vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) :::PopExposedDef.Focus()&lt;br /&gt;
::Else&lt;br /&gt;
:::Me.Close() &lt;br /&gt;
:::frmMain.DefInstance.PrintAttributes(&amp;quot;Pop_exp&amp;quot;, &amp;quot;Cost&amp;quot;) &lt;br /&gt;
::End If &lt;br /&gt;
::ReleaseComObject(pop_exp_Object) &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
该函数抓取了输入到'''New Definition''' 新定义给'''Population Exposed'''栏，并通过使用[[CAObject/zh|CAObject]]对象中的[[CAObject::SetAttribute/zh|SetAttribute]]函数将它设置给&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;对象。然后调用[[PrintAttributes/zh|PrintAttributes]]，以计算&amp;lt;tt&amp;gt;Cost object&amp;lt;/tt&amp;gt;，并打印新的结果。要想给变量&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;设定一个新定义，我们可以为&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;获取[[CAObject/zh|CAObject]]对象，然后将其定义设置成用户输入的定义。通过使用下面的代码来实现：&lt;br /&gt;
:pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
:pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]]( &amp;quot;[[Definition]]&amp;quot;, newDefinition )&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
无论什么时候调用[[CAObject::SetAttribute/zh|SetAttribute]]，都应该检查[[CAEngine/zh|CAEngine]]自动化对象（'''adeEngine'''）的[[CAEngine::ErrorCode/zh|ErrorCode]]，以免它的定义是非法的。尝试一下输入一个新定义，比如&amp;lt;code&amp;gt;[[Uniform]](25M,35M)&amp;lt;/code&amp;gt;，然后点击'''Ok'''。当&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;的定义被改变时， &amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果由ADE重新计算，此时'''ResultTable'''接下来调用给Cost变量（在应用程序窗口重新显示时）。&lt;br /&gt;
&lt;br /&gt;
使用ADE绘图&lt;br /&gt;
&lt;br /&gt;
通过Analytica 4.6使用相同的绘图引擎，你可以建立一个图表或者图形以显示一个数组值或者不确定值结果。在ADE4.6中，你可以使用 [[CATable/zh|CATable]]的[[CATable::GraphToFile/zh|GraphToFile]]和[[CATable::GraphToStream/zh|GraphToStream]]方法。图形可以以几种可能的图像格式返回，例如'''image/png'''、 '''image/bmp'''或者 '''image/jpeg'''。 &lt;br /&gt;
&lt;br /&gt;
从可用图形选项中选择的最简单方式就是使用Analytica打开你的模型。你可以实验设置各种默认设置或者替代选择的变量，看它们是如何工作的。但你选择了你想设置的选项，保存模型。当为每一个生成结果图形时，ADE将使用这些设置。 &lt;br /&gt;
&lt;br /&gt;
对于更高维度的结果，可能需要做一些必要工作，以便选择将绘制结果的切片和具体的轴（也就是相对于图例哪个维度作为X轴）。[[CATable/zh|CATable]]的[[CATable::Subscript/zh|Subscript]]或[[CATable::Slice/zh|Slice]]方法可以用来控制轴选择特殊的切片用来绘制，能够用来控制轴。详情请参考[[CATable/zh|CATable]]。在我们的&amp;lt;tt&amp;gt;Tutorial.NET&amp;lt;/tt&amp;gt;示例中，我们有一个一维结果（&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;），因此我们没有必要担心截取或者绕轴旋转。 &lt;br /&gt;
&lt;br /&gt;
[[CATable::GraphToStream/zh|GraphToStream]]方法被用来从ADE中直接转化图形图形到一个用户界面中。使用[[CATable::GraphToStream/zh|GraphToStream]]比起使用[[CATable::GraphToFile/zh|GraphToFile]]来要稍微复杂一点，因为[[CATable::GraphToFile/zh|GraphToFile]]除了需要文件名以外还需要其它一些信息，以便编写图形。要使用[[CATable::GraphToStream/zh|GraphToStream]]，我们必须在内存内设置一个流，允许ADE写入该留，然后从该留重建。因为.NET流和COM流不兼容，你必须使用ADE一同提供的[[StreamConnector]]类型.&amp;lt;tt&amp;gt;frmMain&amp;lt;/tt&amp;gt; 中的'''GraphResult_Click'''子程序演示了[[CATable::GraphToStream/zh|GraphToStream]]的使用。从主应用程序窗口选择 '''Graph Result'''菜单选项，结果将出现在一个如下所示的图形当中：&lt;br /&gt;
&lt;br /&gt;
[[File:resultgraph.jpg/zh|文件：resultgraph.jpg]]&lt;br /&gt;
&lt;br /&gt;
==结论==&lt;br /&gt;
&lt;br /&gt;
在此教程中，我们介绍了Analytica决策引擎的几个重要方面。我们看到了如何建立一个ADE服务器对象，使用ADE打开模型，获取模型中的单个对象、计算对象、获取表格中的元素，以及修改模型中的对象。但是ADE可以做的远不止这些。 &lt;br /&gt;
&lt;br /&gt;
我们希望你已经足够了解其基本特征，这样你现在才能独自开始探索更多新的高级特征。我们建议你现在开始阅读字教程的剩余部分以了解ADE能做什么。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
| [[Installation of ADE/zh|ADE 安装]] &amp;lt;- ||  [[The ADE Tutorial/zh|ADE 入门教程]] || -&amp;gt; [[Using the ADE Server/zh|使用ADE服务器]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36288</id>
		<title>The ADE Tutorial/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36288"/>
		<updated>2015-10-27T06:25:36Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南 ]]&lt;br /&gt;
&lt;br /&gt;
此教程教你如何在一个Visual Basic程序中使用Analytica决策引擎（ADE）。&lt;br /&gt;
&lt;br /&gt;
==你的第一个ADE应用程序==&lt;br /&gt;
首先先从头开始写一个简单的ADE程序，只要确认一切设置正常。按照以下步骤操作：&lt;br /&gt;
&lt;br /&gt;
test&lt;br /&gt;
&lt;br /&gt;
第一个程序执行了以下操作：&lt;br /&gt;
*建立一个名称为ADE的[[CAEngine/zh|CAEngine]]自动化对象（通过使用&amp;lt;code&amp;gt;new [[CAEngine/zh|CAEngine]]&amp;lt;/code&amp;gt;).&lt;br /&gt;
*打开Analytica模型 (通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]] 方法。&lt;br /&gt;
*显示模型名称返回[[CAEngine::OpenModel/zh|OpenModel]]的值。&lt;br /&gt;
我们将在后面的章节详细了解这些信息。&lt;br /&gt;
&lt;br /&gt;
===接下来讲什么呢?===&lt;br /&gt;
我们不会尝试在此入门教程中解释ADE的特征。本指南后面几个章节会描述这些特征。 &lt;br /&gt;
&lt;br /&gt;
从现在开始，我们我们将使用名称为&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;的示例模型。打开 Analytica安装目录下 '''Example Models'''文件夹里面的'''Risk Analysis'''文件夹便可找到&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;文件。如果你找不到，或者你安装Analytica的时候未选择安装examples（示例）文件，在ADE安装目录下面的'''Examples\Tutorial.NET'''文件家中有一个副本。 &lt;br /&gt;
&lt;br /&gt;
Txc模型演示了减少污染物TXC排放的risk-benefit （风险-效益）分析。请用Analytica打开Txc查看它是如何工作的。 &lt;br /&gt;
&lt;br /&gt;
ADE '''Examples\Tutorial.NET''' 文件夹中名称为&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;的Visual Basic.NET程序示例显示了ADE很多方面。该程序建立了一个ADE自动化对象，打开包含该对象的&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，获取变量 &amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，计算变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;，通过获取每个表格的单独组件以表格的方式打印输出变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的结果，然后改变变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义。再次获取变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的值，看一下 变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;定义的改变对变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;有什么影响。如果设置正确的话,&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;将显示在“Text Txc window”中显示的窗口。 &lt;br /&gt;
&lt;br /&gt;
应用程序显示变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义（&amp;lt;tt&amp;gt;&amp;quot;Normal (30M, 3M)&amp;quot;&amp;lt;/tt&amp;gt;），以及与&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;关联的表格，这都基于&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义。你可以通过从主菜单选择'''File &amp;gt; Change Population Exposed'''改变&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，然后查看改变对&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;表格的影响。&lt;br /&gt;
&lt;br /&gt;
[[File:TextTxcWindow.png|400px/zh | 文件：TextTxcWindow.png|400px]]&lt;br /&gt;
&lt;br /&gt;
===区分title（名称） 和 identifier（标识符）===&lt;br /&gt;
无论什么时候，一个ADE函数都需要一个变量你必须传达变量的'''''[[Identifier|标识符]]''''' ，而不是它的'''''[[Title|名称]]'''''。这可能会引起混淆，因为在Analytica影响图中一般显示每一个变量的名称。默认情况下，在你最初建立每一个对象的时候，Analytica自动根据名称建立一个标识符。用（_）代替名称中的每一个空格或者其他非字母和数字字符。 &lt;br /&gt;
&lt;br /&gt;
你可以通过点击“Control+y”（或者从Object（对象）菜单选择'''Show by identifier''' ：显示标识符） 来以标识符显示变量。对于模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;，你可以看到名称为&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;变量的标识符为 &amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;。将变量传递给ADE函数时，使用标识符很重要。如果你传递&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;，ADE无法找到变量，并且将返回一个错误。&lt;br /&gt;
&lt;br /&gt;
===从Visual Basic中建立一个ADE 对象===&lt;br /&gt;
&lt;br /&gt;
如果你还没准备好，将名称为tt&amp;gt;Examples\Tutorial\TestTxc.sln&amp;lt;/tt&amp;gt;载入到Visual Basic.NET中，查看名称为&amp;lt;tt&amp;gt;TestTxc.vb&amp;lt;/tt&amp;gt;的文件的代码。其代码看起来像：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Imports ADEW &lt;br /&gt;
:. . . &lt;br /&gt;
:Public adeEngine As [[CAEngine/zh|CAEngine]]&lt;br /&gt;
&lt;br /&gt;
:Public Sub Main() &lt;br /&gt;
::Dim exeDirectory, theModel As String &lt;br /&gt;
::Dim theModelString As String &lt;br /&gt;
::exeDirectory = VB6.GetPath &lt;br /&gt;
::theModel = exeDirectory &amp;amp; &amp;quot;\..\&amp;quot; &amp;amp; &amp;quot;Txc.ana&amp;quot; &lt;br /&gt;
::adeEngine = New [[CAEngine/zh|CAEngine]]&lt;br /&gt;
::... &lt;br /&gt;
::theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
::... &lt;br /&gt;
::frmMain.DefInstance.Show() &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在每一个文件的顶部的代码将自动化对象 '''adeEngine''' 声明为一个[[CAEngine/zh|CAEngine]] 对象。使用此对象，我们能够访问 [[CAEngine/zh|CAEngine]] 展示的所有公共函数（参考 [[ADE Server Class Reference/zh|ADE服务器类型参考]] ）&lt;br /&gt;
&lt;br /&gt;
变量&amp;lt;tt&amp;gt;adeEngine&amp;lt;/tt&amp;gt;包含我们的进程内对象 [[CAEngine/zh|CAEngine]]。如果我们想使用ADE的本地（进程外）服务器版本，我们可以将一个项目参考添加到'''Analytica Decision Engine Server 4.6 COM''' 组件并将顶部行从&amp;lt;tt&amp;gt;Imports ADEW&amp;lt;/tt&amp;gt;改成&amp;lt;tt&amp;gt;Imports ADE&amp;lt;/tt&amp;gt;即可。 &lt;br /&gt;
&lt;br /&gt;
这里是另一种获得一个先[[CAEngine/zh|CAEngine]]对象的方法。此循序不需要给项目添加参考。&amp;lt;tt&amp;gt;&lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADEW4.6.CAEngine&amp;quot;) ’ in-process &lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADE4.6.CAEngine&amp;quot;) ’ out-of-process &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果想理解使用进程内和进程外（或本地）服务器的利与弊，以及哪一种自动化服务器用于不同的场景，参考[[Using_the_Analytica_Decision_Engine_Server#In-process_vs_Out-of-process/zh | In-process vs. out-of-process]]&lt;br /&gt;
&lt;br /&gt;
===COM和 Automation 接口比较===&lt;br /&gt;
在上面的例子当中，我们使用COM接口调用ADE。在一个COM 接口中，对象 在本例中为 [[CAEngine/zh|CAEngine]] 被声明为[[CAEngine/zh|CAEngine]] ，编译器解决每一个成员函数，并且在编译时间内能探测几个明显的错误。另外，Visual Studio可以提供方法和参数类型列表当，在你编程的时候可以当做一个提示工具，在编写使用ADE程序是非常有用。COM调用比Automation调用要快一点，但是在ADE应用程序中速度差异通常不是很重要。对于ADE 4.6我们推荐使用COM结构，只要你的语言支持。&lt;br /&gt;
&lt;br /&gt;
在VB Automation中，你可以将一个对象简单声明为Object（对象），而不是像 [[CAEngine/zh|CAEngine]]、[[CAObject/zh|CAObject]]等更加具体的类型。当使用Automation调用'''ADE'''方法时，在运行时间内确定方法。在编译时间内，编译器不知道你的 '''ADE''' 对象是否有一个名称为[[CAEngine::OpenModel/zh|OpenModel]]的函数。在VB中，调用COM方法或Automation 方法的语法是相通的——唯一的不同在于对象类型是否明确被声明。&lt;br /&gt;
&lt;br /&gt;
在VC++和C#中，调用COM的语法和调用Automatio的语法不同。在这些情况下，COM要方便的多，Automation能够获得相冗余。然而，同样的语言，包括VBScript和其他脚本语言，只支持Automation不支持COM。&lt;br /&gt;
&lt;br /&gt;
===监视Process（进程）===&lt;br /&gt;
当使用进程外ADE服务器时，你的代码必须在终止时释放[[CAEngine/zh|CAEngine]]COM对象。当最终[[CAEngine/zh|CAEngine]]使用被释放是，ADE.exe 进程自动终止。到目前为止所看到的代码，VB语言在达到程序末端时，自动处理释放对象。但是，当你调试你的代码是，你可以提前终止你的程序来修复bug，你的程序可能被Task Manager（任务管理器）终止，或者你自己的代码也可能奔溃，导致你的程序进程在它有机会释放对象之前终止。应为COM对象从来不会被释放，ADE.exe进程不知道它是否在使用中，你可能获得ADE.exe 僵尸进程。 &lt;br /&gt;
&lt;br /&gt;
为了避免这种情况发生，一种好的习惯就是在调用[[CAEngine/zh|CAEngine]]实例后 立即调用[[CAEngine::MonitorProcess/zh|CAEngine::MonitorProcess]]。通过这种方式，ADE能够得知哪一个进程正在使用它，同时将设置一个线程去探测你的进程是否在ADE被完全释放前终止。如果你的程序进程没有终止，ADE进程会立即将它关闭，消除了僵尸ADE进程的堆积。 &lt;br /&gt;
&lt;br /&gt;
要从一个.NET应用程序获得进程ID，使用System.Diagnostics.Process namespace中的'''GetCurrentProcess().Id''' 。在其他语言中，你可以使用Windows SDK 的'''GetProcessId( )'''函数。 &lt;br /&gt;
&lt;br /&gt;
'''[[CAEngine::MonitorProcess/zh|MonitorProcess]]()''' 只能用来监视运行ADE进程的同一台计算机的进程，一次当通过DCOM运行ADE时不能使用。当使用进程内ADEW服务器时没有必要使用。&lt;br /&gt;
&lt;br /&gt;
==打开使用ADE的模型==&lt;br /&gt;
我们现在打开&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，显示我们的应用程序主窗口。使用以下调用：tt&amp;gt;&lt;br /&gt;
:theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
:frmMain.DefInstance.Show &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]]函数打开模型。如果成功的话，变量&amp;lt;tt&amp;gt;theModelString&amp;lt;/tt&amp;gt;将包含模型的名字。否则，将包含一个空的串。虽然由于为了简介的缘故，我们没有这样做，但是你应该检查从[[CAEngine::OpenModel/zh|OpenModel]]函数返回的是不是一个空的串。如果是，说明在你打开的模型中存在一个错误。你可以使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/z |ErrorText]]属性找出是哪种错误 （&amp;lt;tt&amp;gt;adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] 和adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]&amp;lt;/tt&amp;gt;）。&lt;br /&gt;
&lt;br /&gt;
==从Analytica模型中检索对象==&lt;br /&gt;
下一步就是从我们的模型中检索对象（变量、模块、函数等），以便我们能获取他们的属性（[[definition|定义]]、[[title|名称]]、[[class|类型]]等等 ）。我们的示例模型（&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;）操作&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;和&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;对象。尤其是，修改&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;可以查看这是如何影响&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt; 对象。&lt;br /&gt;
&lt;br /&gt;
我们的&amp;lt;tt&amp;gt;TxcTest.vbproj&amp;lt;/tt&amp;gt; （&amp;lt;tt&amp;gt;TxcText.sln&amp;lt;/tt&amp;gt;）项目中的&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;文件里的 '''PrintAttributes''' 函数演示了如何检索对象。该函数首先被&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''Form_Load''' 函数调用，当应用程序启动后，可以显示'''Cost'''表格。当然无论什么时候，只要我们想输出'''Cost'''表格的当前值，都可以调用。该函数如下所示：&lt;br /&gt;
:Public Sub PrintAttributes(ByRef inputIdentifier As String, ByRef  outputIdentifier As String) &lt;br /&gt;
::Dim inputObject, outputObject As [[CAObject/zh|CAObject]]&lt;br /&gt;
::Dim resultTable As [[CATable/zh|CATable]]&lt;br /&gt;
::Dim definitionAttrInput As String &lt;br /&gt;
::inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
::outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier) &lt;br /&gt;
::definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;definition&amp;quot;) &lt;br /&gt;
::resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]]&lt;br /&gt;
::Call PrintResultTable(resultTable, inputIdentifier, definitionAttrInput, outputIdentifier) &lt;br /&gt;
::ReleaseComObject(resultTable) &lt;br /&gt;
::ReleaseComObject(inputObject) &lt;br /&gt;
::ReleaseComObject(outputObject) &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''PrintAttributes'''和作为'''inputIdentifier'''参数的&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;变量标识符以及作为'''outputIdentifier'''参数的'''Cost'''变量一起使用。如下所示通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::GetObjectByName/zh|GetObjectByName]]函数提取相应对象：&amp;lt;tt&amp;gt;&lt;br /&gt;
:inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取成功，将返回一个[[CAObject/zh|CAObject]]类型对象。如果使用'''[[CAObject/zh|CAObject]]'''的函数，参考[[CAObject/zh|SendCommand(command)]]，可以获得一个[[CAObject/zh|CAObject]]的完整函数列表。如果函数[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取失败，返回值为&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;。代码应该检查以确保[[CAEngine::GetObjectByName/zh|GetObjectByName]]提取的结果是有效的。如果找不到，可使用[[CAEngine/zh|CAEngine]]的 [[CAEngine::ErrorCode/zh|ErrorCode]]和 [[CAEngine::ErrorText/zh|ErrorText]]属性获取错误信息。例如：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Set inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:If inputObject Is Nothing Then &lt;br /&gt;
::MsgBox(“This error from GetObjectByName occurred: “&amp;amp; _ vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &amp;amp; “:” &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) &lt;br /&gt;
:Else &lt;br /&gt;
::'inputObject valid &lt;br /&gt;
:End If&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===获取对象属性===&lt;br /&gt;
每一个Analytica对象都有一组属性，例如[[identifier | 标识符]]、[[title | 名称]]、[[description |  描述]]和[[class | 类型]]。你可以使用[[CAObject::GetAttribute/zh | GetAttribute]]函数来获去Analytica对象的属性。例如，如要获取'''inputObject'''的定义（当前为cost）：&amp;lt;tt&amp;gt;&lt;br /&gt;
:definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;[[Definition | 定义]]&amp;quot;) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt; 中，&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;的定义为&amp;quot;&amp;lt;tt&amp;gt;[[Normal]](30M, 3M)&amp;lt;/tt&amp;gt;&amp;quot; ，我们将它储存在'''definitionAttrInput'''当中。.&lt;br /&gt;
&lt;br /&gt;
===计算对象和检索结果===&lt;br /&gt;
使用[[CAObject/zh | CAObject]]的[[CAObject::Result/zh | Result]]或[[CAObject::ResultTable/zh | ResultTable]]方法来获取变量的值。如果有必要的话，ADE先自动计算变量。如果你确定结果为基元（只有一个元素），使用[[CAObject::Result/zh | Result]]方法。否则使用[[CAObject::ResultTable/zh | ResultTable]]，检索结果为一个''数组''。基元结果当作一个特殊数组案例来处理，没有维度的数组。如果值为基元[[CATable::AtomicValue/zh | AtomicValue]]方法将返回一个数字或者字符串单一值。 &lt;br /&gt;
&lt;br /&gt;
默认情况下，[[CAObject::Result/zh | Result]]和[[CAObject::ResultTable/zh | ResultTable]]返回结果的中值，也就是说，ADE以确定性方式计算结果。对于一个概率值，将[[CAObject/zh | CAObject]]的[[CAObject::ResultType/zh | ResultType]]属性设置为想要的不确定性视图——Mean（平均值） Sample（样本）、PDF（概率密度函数）、CDF（累计分布函数）、Confidence bands（置信带）、或者Statistics（统计数据）详情请参考[[CAObject::ResultType/zh | ResultType]]。我们通过如下的方式获取outputObject 输出对象 的值：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable = outputObject.[[CAObject::ResultTable/zh |ResultTable]] &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
结果为一个[[CATable/zh | CATable]]对象，允许我们访问一个表格中的单个元素。 &lt;br /&gt;
&lt;br /&gt;
如果你通过调用[[CAObject::Result/zh | Result]]来获取一个数组（或者表格）的值，将返回数组为一个字符串，列出索引和元素，以逗号隔开。通常使用[[CAObject::ResultTable/zh | ResultTable]]更加简单，这样你没有必要从字符串中解析表格的元素。&lt;br /&gt;
&lt;br /&gt;
===获取表格索引元素===&lt;br /&gt;
一个Analytica表格包含0个或者多个索引。如果包含一个索引，那么该表格是1维表格；如果有2个索引，说他是2维表格，依此类推。0维度表格包含一个“单一基元”（或标量）值。你可以使用CATable的[[CATable::NumDims/zh | NumDims]]获取表格的维数（也就是索引数）。要想获取表格的单个索引，可使用[[CATable/zh | CATable]]的 [[CATable::IndexNames/zh | IndexNames]]和 [[CATable::GetIndexObject/zh | GetIndexObject]]函数。 &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''PrintResultTable'''函数说明了这两个函数的使用。从'''PrintAttributes'''中调用'''PrintResultTable'''，执行打印'''TestTxc'''中的表格的实际工作（为了简洁起见，我们只给出了关联ADE的该函数部分）。&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Public Sub PrintResultTable(ByRef resultTable As CATable, ByRef inputIdentifier As String, ByRef definitionAttrInput As String, ByRef outputIdentifier As String) &lt;br /&gt;
::Dim theIndexName, theTableName As String &lt;br /&gt;
::Dim theIndexElement As String &lt;br /&gt;
::Dim theTableElement &lt;br /&gt;
::Dim theIndexObj As [[CAIndex/zh | CAIndex]]&lt;br /&gt;
::Dim numEls As Integer &lt;br /&gt;
::Dim spaces, i As Integer &lt;br /&gt;
::Dim lenStr As Short &lt;br /&gt;
::Dim OutputStr As Short &lt;br /&gt;
::Dim spaceString, underlineString As String &lt;br /&gt;
::... &lt;br /&gt;
::theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1) &lt;br /&gt;
::theTableName = resultTable.[[CATable::Name/zh|Name]] &lt;br /&gt;
::theIndexObj = resultTable.[[CATable::GetIndexObject/zh | GetIndexObject]](theIndexName) &lt;br /&gt;
::numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
::... &lt;br /&gt;
::For i = 1 To numEls &lt;br /&gt;
:::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
:::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
:::... &lt;br /&gt;
::Next i &lt;br /&gt;
::InformationPane.Text = outputString &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
通过'''PrintResultTable'''获取一个表格的索引方法如下：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1)&lt;br /&gt;
:theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
我们通过使用[[CATable/zh|CATable]]的[[CATable::IndexNames/zh|IndexNames]]函数获取第一个索引的名字。我们将它传递给[[CATable/zh|CATable]]的[[CATable::GetIndexObject/zh|GetIndexObject]]函数以获取表示我们的索引的[[CAIndex/zh|CAIndex]]。该自动化对象返回其相应索引的相关信息。如果此函数调用失败，将返回&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;信息。在此情况下，使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]] 函数找出原因。&lt;br /&gt;
&lt;br /&gt;
==从CATable和CAIndex中获取信息==&lt;br /&gt;
[[PrintResultTable]]说明了如何从[[CATable/zh| CATable]]和[[CAIndex/zh|CAIndex]] 对象获取信息。该代码获取'''Cost'''表格的索引和表格元素：&lt;br /&gt;
: &amp;lt;tt&amp;gt;&lt;br /&gt;
:numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
:For i = 1 To numEls &lt;br /&gt;
::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
::... &lt;br /&gt;
:Next i &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[CAIndex/zh|CAIndex]]的[[CAIndex::IndexElements/zh|IndexElements]]属性返回第一个索引中的元素个数。[[CAIndex/zh|CAIndex]]的[[CAIndex::GetValueByNumber/zh|GetValueByNumber]]函数获取单个索引元素。 &lt;br /&gt;
&lt;br /&gt;
我们通过传递表格中元素的坐标，使用  [[CATable/zh|CATable]]的[[CATable::GetDataByElements/zh|GetDataByElements]]函数获取'''Cost'''表格对象的单个表格元素'''resultTable'''。 &lt;br /&gt;
&lt;br /&gt;
当我检索 [[CATable/zh|CATable]]对象中单个元素（'''resultTable'''）的时候，我们利用了该表格是一维的事实。因此，我们只需要传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个单一数（这个数代表表格中的位置）。但是，如果我们处理两个或者更多维度，我们必须传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个数组函数，并且指明我们要检索的表格元素的位置。因此，如果我们不想检索一个二维数组的position (4,3)位置的元素，我们可以这样写：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Dim W as Variant 'return element &lt;br /&gt;
:Dim IndexPtrs(1 To 2) As Variant 'position in table &lt;br /&gt;
::... &lt;br /&gt;
:IndexPtrs(1) = 4 &lt;br /&gt;
:IndexPtrs(2) = 3 &lt;br /&gt;
:W = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](IndexPtrs) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==控制基元值格式==&lt;br /&gt;
[[CATable/zh|CATable]]中的每个基元值可以是一个数、一个字符串，或者其它一些基本类型（''例如''：[[Null|空值]]、[[Undefined|未定义]]、[[Reference|参考]]，或 [[Handle|句柄]]。通过说明类型和值，它们作为''变体''被返回，这是一种Visual Basic能读懂的数据结构。[[CATable/zh|CATable]]的[[CATable::RenderingStyle|RenderingStyle]]属性控制Analytica基础值是如何映射到Visual Basic变体的。 &lt;br /&gt;
&lt;br /&gt;
例如：可以通过使用Analytica 模型的数字格式设置将一个数值返回成一个数字或者字符串。如果被指定格式，有一个选线控制是截断数字的位数，还是精确返回。 &lt;br /&gt;
&lt;br /&gt;
子程序[[PrintResultTable/zh|PrintResultTable]]在&amp;lt;tt&amp;gt;frmMain.vb&amp;lt;/tt&amp;gt;中载入,其渲染风格直接指明：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::NumberAsText/zh|NumberAsText]] = True &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::FullPrecision/zh|FullPrecision]] = False &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::StringQuotes/zh|StringQuotes]] = 2 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
第一行指明数值应该根据与结果对象有关的数字格式被格式化为文本。例如在其程序输出中，我们将看到&amp;lt;tt&amp;gt;30.103M&amp;lt;/tt&amp;gt;，而非&amp;lt;tt&amp;gt;30102995.6639812&amp;lt;/tt&amp;gt;，如果我们让Visual Basic将数值串联我们的结果字符串，将显示该结果。在此事件中，一个值为字符串的单元格出现在结果中，返回值将明确带双引号。对于[[CARenderingStyle/zh|CARenderingStyle]]对象中的所有可用属性，请参考[[CARenderingStyle/zh|CARenderingStyle]]。&lt;br /&gt;
&lt;br /&gt;
===其它访问表格的方式===&lt;br /&gt;
有几种访问多维表格[[CATable/zh|CATable]]中元素的方式。每一种都有可能在特定的场合使用起来比较方便。 &lt;br /&gt;
&lt;br /&gt;
第一种方式就是使用[[CATable/zh | CATable]]的 [[CATable::GetDataByElements/zh|GetDataByElements]]或[[CATable::GetDataByLabels/zh|GetDataByLabels]]方法，上面代码示例中有显示。在此情况下，利用你想获取的基元值的单元格位置。 &lt;br /&gt;
&lt;br /&gt;
第二种方式就是使用[[CATable/zh|CATable]][[CATable::Slice/zh|Slice]]或[[CATable::Subscript/zh | Subscript]]方法获取一个少一个维度的新[[CATable/zh|CATable]]对象。通过重复减少维度，最终将获得0维度，这时你将获得一个单一基元值。此时，[[CATable/zh|CATable]]的[[CATable::AtomicValue/zh|AtomicValue]]方法返回该值 。[[CATable::AtomicValue/zh|AtomicValue]]方法是唯一获取一个标值的方法（因为没有坐标位置）。如果你需要建立完整结果其中一个切片的图形图像，必须使用此方法。 &lt;br /&gt;
&lt;br /&gt;
第三种方式就是使用[[CATable/zh|CATable]]的[[CATable::GetSafeArray/zh|GetSafeArray]]方法，将多维数组转化成一个''安全数组''（或者一个.NET数组）。你可以在使用VB或者其它.NET语言直接处理多维数组。因为对于Analytica维度没有固定顺序，但是安全数组和.NET数组有一个明确的顺序，你必须先使用[[CATable/zh|CATable]]对象的[[CATable::SetIndexOrder/zh|SetIndexOrder]]方法在调用[[CATable::GetSafeArray/zh|GetSafeArray]]之前指明维度的顺序。注意如果你知道你的数组是一维的，那就没必要了。&lt;br /&gt;
&lt;br /&gt;
===修改对象===&lt;br /&gt;
一个自定义用户程序通常从一个用户或者其它外部源获取输入，以便转化成Analytica模型中的输入变量。你可以设定输入变量的定义或者通过使用定义表格来这样做。 &lt;br /&gt;
&lt;br /&gt;
'''TestTxc''' 说明了如何修改'''Pop_exp'''定义，此模型是一个影响结果变量Cost的模型输入。要想在该示例中设定该定义，从主菜单上选择'''File &amp;gt; Change Population'''。将出现一个对话框，如下图所示：&lt;br /&gt;
&lt;br /&gt;
[[File:RedefiningtheVariableDefinition.jpg|400px/zh|文件：RedefiningtheVariableDefinition.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
在信息栏中输入一个新定义并点击'''Ok'''确认。主窗口将显示一个新的Cost值。当点击该对话框中的'''Ok'''按钮时，调用了&amp;lt;tt&amp;gt;ChangeDef.frm&amp;lt;/tt&amp;gt;函数，然后调用[[PrintAttributes/zh|PrintAttributes]]函数打印&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果。&lt;br /&gt;
&lt;br /&gt;
此函数类似于：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Private Sub OkButton_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles OkButton.Click &lt;br /&gt;
::Dim errorText As String&lt;br /&gt;
::Dim pop_exp_Object As [[CAObject/zh|CAObject]] &lt;br /&gt;
::Dim errorCode As Short &lt;br /&gt;
::Dim errorString As String &lt;br /&gt;
::newDefinition = PopExposedDef.Text &lt;br /&gt;
::pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
::pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]](&amp;quot;[[Definition]]&amp;quot;, newDefinition) &lt;br /&gt;
::errorCode = adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &lt;br /&gt;
::If errorCode &amp;lt;&amp;gt; 0 Then &lt;br /&gt;
:::MsgBox(&amp;quot;This error occurred while processing your definition: &amp;quot; &amp;amp; vbCrLf &amp;amp; vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) :::PopExposedDef.Focus()&lt;br /&gt;
::Else&lt;br /&gt;
:::Me.Close() &lt;br /&gt;
:::frmMain.DefInstance.PrintAttributes(&amp;quot;Pop_exp&amp;quot;, &amp;quot;Cost&amp;quot;) &lt;br /&gt;
::End If &lt;br /&gt;
::ReleaseComObject(pop_exp_Object) &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
该函数抓取了输入到'''New Definition''' 新定义给'''Population Exposed'''栏，并通过使用[[CAObject/zh|CAObject]]对象中的[[CAObject::SetAttribute/zh|SetAttribute]]函数将它设置给&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;对象。然后调用[[PrintAttributes/zh|PrintAttributes]]，以计算&amp;lt;tt&amp;gt;Cost object&amp;lt;/tt&amp;gt;，并打印新的结果。要想给变量&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;设定一个新定义，我们可以为&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;获取[[CAObject/zh|CAObject]]对象，然后将其定义设置成用户输入的定义。通过使用下面的代码来实现：&lt;br /&gt;
:pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
:pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]]( &amp;quot;[[Definition]]&amp;quot;, newDefinition )&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
无论什么时候调用[[CAObject::SetAttribute/zh|SetAttribute]]，都应该检查[[CAEngine/zh|CAEngine]]自动化对象（'''adeEngine'''）的[[CAEngine::ErrorCode/zh|ErrorCode]]，以免它的定义是非法的。尝试一下输入一个新定义，比如&amp;lt;code&amp;gt;[[Uniform]](25M,35M)&amp;lt;/code&amp;gt;，然后点击'''Ok'''。当&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;的定义被改变时， &amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果由ADE重新计算，此时'''ResultTable'''接下来调用给Cost变量（在应用程序窗口重新显示时）。&lt;br /&gt;
&lt;br /&gt;
使用ADE绘图&lt;br /&gt;
&lt;br /&gt;
通过Analytica 4.6使用相同的绘图引擎，你可以建立一个图表或者图形以显示一个数组值或者不确定值结果。在ADE4.6中，你可以使用 [[CATable/zh|CATable]]的[[CATable::GraphToFile/zh|GraphToFile]]和[[CATable::GraphToStream/zh|GraphToStream]]方法。图形可以以几种可能的图像格式返回，例如'''image/png'''、 '''image/bmp'''或者 '''image/jpeg'''。 &lt;br /&gt;
&lt;br /&gt;
从可用图形选项中选择的最简单方式就是使用Analytica打开你的模型。你可以实验设置各种默认设置或者替代选择的变量，看它们是如何工作的。但你选择了你想设置的选项，保存模型。当为每一个生成结果图形时，ADE将使用这些设置。 &lt;br /&gt;
&lt;br /&gt;
对于更高维度的结果，可能需要做一些必要工作，以便选择将绘制结果的切片和具体的轴（也就是相对于图例哪个维度作为X轴）。[[CATable/zh|CATable]]的[[CATable::Subscript/zh|Subscript]]或[[CATable::Slice/zh|Slice]]方法可以用来控制轴选择特殊的切片用来绘制，能够用来控制轴。详情请参考[[CATable/zh|CATable]]。在我们的&amp;lt;tt&amp;gt;Tutorial.NET&amp;lt;/tt&amp;gt;示例中，我们有一个一维结果（&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;），因此我们没有必要担心截取或者绕轴旋转。 &lt;br /&gt;
&lt;br /&gt;
[[CATable::GraphToStream/zh|GraphToStream]]方法被用来从ADE中直接转化图形图形到一个用户界面中。使用[[CATable::GraphToStream/zh|GraphToStream]]比起使用[[CATable::GraphToFile/zh|GraphToFile]]来要稍微复杂一点，因为[[CATable::GraphToFile/zh|GraphToFile]]除了需要文件名以外还需要其它一些信息，以便编写图形。要使用[[CATable::GraphToStream/zh|GraphToStream]]，我们必须在内存内设置一个流，允许ADE写入该留，然后从该留重建。因为.NET流和COM流不兼容，你必须使用ADE一同提供的[[StreamConnector]]类型.&amp;lt;tt&amp;gt;frmMain&amp;lt;/tt&amp;gt; 中的'''GraphResult_Click'''子程序演示了[[CATable::GraphToStream/zh|GraphToStream]]的使用。从主应用程序窗口选择 '''Graph Result'''菜单选项，结果将出现在一个如下所示的图形当中：&lt;br /&gt;
&lt;br /&gt;
[[File:resultgraph.jpg/zh|文件：resultgraph.jpg]]&lt;br /&gt;
&lt;br /&gt;
==结论==&lt;br /&gt;
&lt;br /&gt;
在此教程中，我们介绍了Analytica决策引擎的几个重要方面。我们看到了如何建立一个ADE服务器对象，使用ADE打开模型，获取模型中的单个对象、计算对象、获取表格中的元素，以及修改模型中的对象。但是ADE可以做的远不止这些。 &lt;br /&gt;
&lt;br /&gt;
我们希望你已经足够了解其基本特征，这样你现在才能独自开始探索更多新的高级特征。我们建议你现在开始阅读字教程的剩余部分以了解ADE能做什么。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
| [[Installation of ADE/zh|ADE 安装]] &amp;lt;- ||  [[The ADE Tutorial/zh|ADE 入门教程]] || -&amp;gt; [[Using the ADE Server/zh|使用ADE服务器]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36286</id>
		<title>The ADE Tutorial/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36286"/>
		<updated>2015-10-27T06:24:50Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南 ]]&lt;br /&gt;
&lt;br /&gt;
此教程教你如何在一个Visual Basic程序中使用Analytica决策引擎（ADE）。&lt;br /&gt;
&lt;br /&gt;
==你的第一个ADE应用程序==&lt;br /&gt;
首先先从头开始写一个简单的ADE程序，只要确认一切设置正常。按照以下步骤操作：&lt;br /&gt;
&lt;br /&gt;
test&lt;br /&gt;
&lt;br /&gt;
第一个程序执行了以下操作：&lt;br /&gt;
*建立一个名称为ADE的[[CAEngine/zh|CAEngine]]自动化对象（通过使用&amp;lt;code&amp;gt;new [[CAEngine/zh|CAEngine]]&amp;lt;/code&amp;gt;).&lt;br /&gt;
*打开Analytica模型 (通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]] 方法。&lt;br /&gt;
*显示模型名称返回[[CAEngine::OpenModel/zh|OpenModel]]的值。&lt;br /&gt;
我们将在后面的章节详细了解这些信息。&lt;br /&gt;
&lt;br /&gt;
===接下来讲什么呢?===&lt;br /&gt;
我们不会尝试在此入门教程中解释ADE的特征。本指南后面几个章节会描述这些特征。 &lt;br /&gt;
&lt;br /&gt;
从现在开始，我们我们将使用名称为&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;的示例模型。打开 Analytica安装目录下 '''Example Models'''文件夹里面的'''Risk Analysis'''文件夹便可找到&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;文件。如果你找不到，或者你安装Analytica的时候未选择安装examples（示例）文件，在ADE安装目录下面的'''Examples\Tutorial.NET'''文件家中有一个副本。 &lt;br /&gt;
&lt;br /&gt;
Txc模型演示了减少污染物TXC排放的risk-benefit （风险-效益）分析。请用Analytica打开Txc查看它是如何工作的。 &lt;br /&gt;
&lt;br /&gt;
ADE '''Examples\Tutorial.NET''' 文件夹中名称为&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;的Visual Basic.NET程序示例显示了ADE很多方面。该程序建立了一个ADE自动化对象，打开包含该对象的&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，获取变量 &amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，计算变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;，通过获取每个表格的单独组件以表格的方式打印输出变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的结果，然后改变变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义。再次获取变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的值，看一下 变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;定义的改变对变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;有什么影响。如果设置正确的话,&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;将显示在“Text Txc window”中显示的窗口。 &lt;br /&gt;
&lt;br /&gt;
应用程序显示变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义（&amp;lt;tt&amp;gt;&amp;quot;Normal (30M, 3M)&amp;quot;&amp;lt;/tt&amp;gt;），以及与&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;关联的表格，这都基于&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义。你可以通过从主菜单选择'''File &amp;gt; Change Population Exposed'''改变&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，然后查看改变对&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;表格的影响。&lt;br /&gt;
&lt;br /&gt;
[[File:TextTxcWindow.png|400px/zh | 文件：TextTxcWindow.png|400px]]&lt;br /&gt;
&lt;br /&gt;
===区分title（名称） 和 identifier（标识符）===&lt;br /&gt;
无论什么时候，一个ADE函数都需要一个变量你必须传达变量的'''''[[Identifier|标识符]]''''' ，而不是它的'''''[[Title|名称]]'''''。这可能会引起混淆，因为在Analytica影响图中一般显示每一个变量的名称。默认情况下，在你最初建立每一个对象的时候，Analytica自动根据名称建立一个标识符。用（_）代替名称中的每一个空格或者其他非字母和数字字符。 &lt;br /&gt;
&lt;br /&gt;
你可以通过点击“Control+y”（或者从Object（对象）菜单选择'''Show by identifier''' ：显示标识符） 来以标识符显示变量。对于模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;，你可以看到名称为&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;变量的标识符为 &amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;。将变量传递给ADE函数时，使用标识符很重要。如果你传递&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;，ADE无法找到变量，并且将返回一个错误。&lt;br /&gt;
&lt;br /&gt;
===从Visual Basic中建立一个ADE 对象===&lt;br /&gt;
&lt;br /&gt;
如果你还没准备好，将名称为tt&amp;gt;Examples\Tutorial\TestTxc.sln&amp;lt;/tt&amp;gt;载入到Visual Basic.NET中，查看名称为&amp;lt;tt&amp;gt;TestTxc.vb&amp;lt;/tt&amp;gt;的文件的代码。其代码看起来像：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Imports ADEW &lt;br /&gt;
:. . . &lt;br /&gt;
:Public adeEngine As [[CAEngine/zh|CAEngine]]&lt;br /&gt;
&lt;br /&gt;
:Public Sub Main() &lt;br /&gt;
::Dim exeDirectory, theModel As String &lt;br /&gt;
::Dim theModelString As String &lt;br /&gt;
::exeDirectory = VB6.GetPath &lt;br /&gt;
::theModel = exeDirectory &amp;amp; &amp;quot;\..\&amp;quot; &amp;amp; &amp;quot;Txc.ana&amp;quot; &lt;br /&gt;
::adeEngine = New [[CAEngine/zh|CAEngine]]&lt;br /&gt;
::... &lt;br /&gt;
::theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
::... &lt;br /&gt;
::frmMain.DefInstance.Show() &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在每一个文件的顶部的代码将自动化对象 '''adeEngine''' 声明为一个[[CAEngine/zh|CAEngine]] 对象。使用此对象，我们能够访问 [[CAEngine/zh|CAEngine]] 展示的所有公共函数（参考 [[ADE Server Class Reference/zh|ADE服务器类型参考]] ）&lt;br /&gt;
&lt;br /&gt;
变量&amp;lt;tt&amp;gt;adeEngine&amp;lt;/tt&amp;gt;包含我们的进程内对象 [[CAEngine/zh|CAEngine]]。如果我们想使用ADE的本地（进程外）服务器版本，我们可以将一个项目参考添加到'''Analytica Decision Engine Server 4.6 COM''' 组件并将顶部行从&amp;lt;tt&amp;gt;Imports ADEW&amp;lt;/tt&amp;gt;改成&amp;lt;tt&amp;gt;Imports ADE&amp;lt;/tt&amp;gt;即可。 &lt;br /&gt;
&lt;br /&gt;
这里是另一种获得一个先[[CAEngine/zh|CAEngine]]对象的方法。此循序不需要给项目添加参考。&amp;lt;tt&amp;gt;&lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADEW4.6.CAEngine&amp;quot;) ’ in-process &lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADE4.6.CAEngine&amp;quot;) ’ out-of-process &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果想理解使用进程内和进程外（或本地）服务器的利与弊，以及哪一种自动化服务器用于不同的场景，参考[[Using_the_Analytica_Decision_Engine_Server#In-process_vs_Out-of-process/zh | In-process vs. out-of-process]]&lt;br /&gt;
&lt;br /&gt;
===COM和 Automation 接口比较===&lt;br /&gt;
在上面的例子当中，我们使用COM接口调用ADE。在一个COM 接口中，对象 在本例中为 [[CAEngine/zh|CAEngine]] 被声明为[[CAEngine/zh|CAEngine]] ，编译器解决每一个成员函数，并且在编译时间内能探测几个明显的错误。另外，Visual Studio可以提供方法和参数类型列表当，在你编程的时候可以当做一个提示工具，在编写使用ADE程序是非常有用。COM调用比Automation调用要快一点，但是在ADE应用程序中速度差异通常不是很重要。对于ADE 4.6我们推荐使用COM结构，只要你的语言支持。&lt;br /&gt;
&lt;br /&gt;
在VB Automation中，你可以将一个对象简单声明为Object（对象），而不是像 [[CAEngine/zh|CAEngine]]、[[CAObject/zh|CAObject]]等更加具体的类型。当使用Automation调用'''ADE'''方法时，在运行时间内确定方法。在编译时间内，编译器不知道你的 '''ADE''' 对象是否有一个名称为[[CAEngine::OpenModel/zh|OpenModel]]的函数。在VB中，调用COM方法或Automation 方法的语法是相通的——唯一的不同在于对象类型是否明确被声明。&lt;br /&gt;
&lt;br /&gt;
在VC++和C#中，调用COM的语法和调用Automatio的语法不同。在这些情况下，COM要方便的多，Automation能够获得相冗余。然而，同样的语言，包括VBScript和其他脚本语言，只支持Automation不支持COM。&lt;br /&gt;
&lt;br /&gt;
===监视Process（进程）===&lt;br /&gt;
当使用进程外ADE服务器时，你的代码必须在终止时释放[[CAEngine/zh|CAEngine]]COM对象。当最终[[CAEngine/zh|CAEngine]]使用被释放是，ADE.exe 进程自动终止。到目前为止所看到的代码，VB语言在达到程序末端时，自动处理释放对象。但是，当你调试你的代码是，你可以提前终止你的程序来修复bug，你的程序可能被Task Manager（任务管理器）终止，或者你自己的代码也可能奔溃，导致你的程序进程在它有机会释放对象之前终止。应为COM对象从来不会被释放，ADE.exe进程不知道它是否在使用中，你可能获得ADE.exe 僵尸进程。 &lt;br /&gt;
&lt;br /&gt;
为了避免这种情况发生，一种好的习惯就是在调用[[CAEngine/zh|CAEngine]]实例后 立即调用[[CAEngine::MonitorProcess/zh|CAEngine::MonitorProcess]]。通过这种方式，ADE能够得知哪一个进程正在使用它，同时将设置一个线程去探测你的进程是否在ADE被完全释放前终止。如果你的程序进程没有终止，ADE进程会立即将它关闭，消除了僵尸ADE进程的堆积。 &lt;br /&gt;
&lt;br /&gt;
要从一个.NET应用程序获得进程ID，使用System.Diagnostics.Process namespace中的'''GetCurrentProcess().Id''' 。在其他语言中，你可以使用Windows SDK 的'''GetProcessId( )'''函数。 &lt;br /&gt;
&lt;br /&gt;
'''[[CAEngine::MonitorProcess/zh|MonitorProcess]]()''' 只能用来监视运行ADE进程的同一台计算机的进程，一次当通过DCOM运行ADE时不能使用。当使用进程内ADEW服务器时没有必要使用。&lt;br /&gt;
&lt;br /&gt;
==打开使用ADE的模型==&lt;br /&gt;
我们现在打开&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，显示我们的应用程序主窗口。使用以下调用：tt&amp;gt;&lt;br /&gt;
:theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
:frmMain.DefInstance.Show &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]]函数打开模型。如果成功的话，变量&amp;lt;tt&amp;gt;theModelString&amp;lt;/tt&amp;gt;将包含模型的名字。否则，将包含一个空的串。虽然由于为了简介的缘故，我们没有这样做，但是你应该检查从[[CAEngine::OpenModel/zh|OpenModel]]函数返回的是不是一个空的串。如果是，说明在你打开的模型中存在一个错误。你可以使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/z |ErrorText]]属性找出是哪种错误 （&amp;lt;tt&amp;gt;adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] 和adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]&amp;lt;/tt&amp;gt;）。&lt;br /&gt;
&lt;br /&gt;
==从Analytica模型中检索对象==&lt;br /&gt;
下一步就是从我们的模型中检索对象（变量、模块、函数等），以便我们能获取他们的属性（[[definition|定义]]、[[title|名称]]、[[class|类型]]等等 ）。我们的示例模型（&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;）操作&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;和&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;对象。尤其是，修改&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;可以查看这是如何影响&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt; 对象。&lt;br /&gt;
&lt;br /&gt;
我们的&amp;lt;tt&amp;gt;TxcTest.vbproj&amp;lt;/tt&amp;gt; （&amp;lt;tt&amp;gt;TxcText.sln&amp;lt;/tt&amp;gt;）项目中的&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;文件里的 '''PrintAttributes''' 函数演示了如何检索对象。该函数首先被&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''Form_Load''' 函数调用，当应用程序启动后，可以显示'''Cost'''表格。当然无论什么时候，只要我们想输出'''Cost'''表格的当前值，都可以调用。该函数如下所示：&lt;br /&gt;
:Public Sub PrintAttributes(ByRef inputIdentifier As String, ByRef  outputIdentifier As String) &lt;br /&gt;
::Dim inputObject, outputObject As [[CAObject/zh|CAObject]]&lt;br /&gt;
::Dim resultTable As [[CATable/zh|CATable]]&lt;br /&gt;
::Dim definitionAttrInput As String &lt;br /&gt;
::inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
::outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier) &lt;br /&gt;
::definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;definition&amp;quot;) &lt;br /&gt;
::resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]]&lt;br /&gt;
::Call PrintResultTable(resultTable, inputIdentifier, definitionAttrInput, outputIdentifier) &lt;br /&gt;
::ReleaseComObject(resultTable) &lt;br /&gt;
::ReleaseComObject(inputObject) &lt;br /&gt;
::ReleaseComObject(outputObject) &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''PrintAttributes'''和作为'''inputIdentifier'''参数的&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;变量标识符以及作为'''outputIdentifier'''参数的'''Cost'''变量一起使用。如下所示通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::GetObjectByName/zh|GetObjectByName]]函数提取相应对象：&amp;lt;tt&amp;gt;&lt;br /&gt;
:inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
:outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
如果函数[[CAEngine::GetObjectByName/zh | GetObjectByName]]提取成功，将返回一个[[CAObject/zh | CAObject]]类型对象。如果使用'''[[CAObject/zh | CAObject]]'''的函数，参考[[CAObject/zh |  SendCommand(command)]]，可以获得一个[[CAObject/zh | CAObject]]的完整函数列表。如果函数[[CAEngine::GetObjectByName/zh | GetObjectByName]]提取失败，返回值为&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;。代码应该检查以确保[[CAEngine::GetObjectByName/zh | GetObjectByName]]提取的结果是有效的。如果找不到，可使用[[CAEngine/zh | CAEngine]]的 [[CAEngine::ErrorCode/zh | ErrorCode]]和 [[CAEngine::ErrorText/zh | ErrorText]]属性获取错误信息。例如：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Set inputObject = adeEngine.[[CAEngine::GetObjectByName/zh | GetObjectByName]](inputIdentifier) &lt;br /&gt;
:If inputObject Is Nothing Then &lt;br /&gt;
::MsgBox(“This error from GetObjectByName occurred: “&amp;amp; _ vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorCode/zh | ErrorCode]] &amp;amp; “:” &amp;amp; adeEngine.[[CAEngine::ErrorText/zh | ErrorText]]) &lt;br /&gt;
:Else &lt;br /&gt;
::'inputObject valid &lt;br /&gt;
:End If&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===获取对象属性===&lt;br /&gt;
每一个Analytica对象都有一组属性，例如[[identifier | 标识符]]、[[title | 名称]]、[[description |  描述]]和[[class | 类型]]。你可以使用[[CAObject::GetAttribute/zh | GetAttribute]]函数来获去Analytica对象的属性。例如，如要获取'''inputObject'''的定义（当前为cost）：&amp;lt;tt&amp;gt;&lt;br /&gt;
:definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;[[Definition | 定义]]&amp;quot;) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt; 中，&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;的定义为&amp;quot;&amp;lt;tt&amp;gt;[[Normal]](30M, 3M)&amp;lt;/tt&amp;gt;&amp;quot; ，我们将它储存在'''definitionAttrInput'''当中。.&lt;br /&gt;
&lt;br /&gt;
===计算对象和检索结果===&lt;br /&gt;
使用[[CAObject/zh | CAObject]]的[[CAObject::Result/zh | Result]]或[[CAObject::ResultTable/zh | ResultTable]]方法来获取变量的值。如果有必要的话，ADE先自动计算变量。如果你确定结果为基元（只有一个元素），使用[[CAObject::Result/zh | Result]]方法。否则使用[[CAObject::ResultTable/zh | ResultTable]]，检索结果为一个''数组''。基元结果当作一个特殊数组案例来处理，没有维度的数组。如果值为基元[[CATable::AtomicValue/zh | AtomicValue]]方法将返回一个数字或者字符串单一值。 &lt;br /&gt;
&lt;br /&gt;
默认情况下，[[CAObject::Result/zh | Result]]和[[CAObject::ResultTable/zh | ResultTable]]返回结果的中值，也就是说，ADE以确定性方式计算结果。对于一个概率值，将[[CAObject/zh | CAObject]]的[[CAObject::ResultType/zh | ResultType]]属性设置为想要的不确定性视图——Mean（平均值） Sample（样本）、PDF（概率密度函数）、CDF（累计分布函数）、Confidence bands（置信带）、或者Statistics（统计数据）详情请参考[[CAObject::ResultType/zh | ResultType]]。我们通过如下的方式获取outputObject 输出对象 的值：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable = outputObject.[[CAObject::ResultTable/zh |ResultTable]] &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
结果为一个[[CATable/zh | CATable]]对象，允许我们访问一个表格中的单个元素。 &lt;br /&gt;
&lt;br /&gt;
如果你通过调用[[CAObject::Result/zh | Result]]来获取一个数组（或者表格）的值，将返回数组为一个字符串，列出索引和元素，以逗号隔开。通常使用[[CAObject::ResultTable/zh | ResultTable]]更加简单，这样你没有必要从字符串中解析表格的元素。&lt;br /&gt;
&lt;br /&gt;
===获取表格索引元素===&lt;br /&gt;
一个Analytica表格包含0个或者多个索引。如果包含一个索引，那么该表格是1维表格；如果有2个索引，说他是2维表格，依此类推。0维度表格包含一个“单一基元”（或标量）值。你可以使用CATable的[[CATable::NumDims/zh | NumDims]]获取表格的维数（也就是索引数）。要想获取表格的单个索引，可使用[[CATable/zh | CATable]]的 [[CATable::IndexNames/zh | IndexNames]]和 [[CATable::GetIndexObject/zh | GetIndexObject]]函数。 &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''PrintResultTable'''函数说明了这两个函数的使用。从'''PrintAttributes'''中调用'''PrintResultTable'''，执行打印'''TestTxc'''中的表格的实际工作（为了简洁起见，我们只给出了关联ADE的该函数部分）。&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Public Sub PrintResultTable(ByRef resultTable As CATable, ByRef inputIdentifier As String, ByRef definitionAttrInput As String, ByRef outputIdentifier As String) &lt;br /&gt;
::Dim theIndexName, theTableName As String &lt;br /&gt;
::Dim theIndexElement As String &lt;br /&gt;
::Dim theTableElement &lt;br /&gt;
::Dim theIndexObj As [[CAIndex/zh | CAIndex]]&lt;br /&gt;
::Dim numEls As Integer &lt;br /&gt;
::Dim spaces, i As Integer &lt;br /&gt;
::Dim lenStr As Short &lt;br /&gt;
::Dim OutputStr As Short &lt;br /&gt;
::Dim spaceString, underlineString As String &lt;br /&gt;
::... &lt;br /&gt;
::theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1) &lt;br /&gt;
::theTableName = resultTable.[[CATable::Name/zh|Name]] &lt;br /&gt;
::theIndexObj = resultTable.[[CATable::GetIndexObject/zh | GetIndexObject]](theIndexName) &lt;br /&gt;
::numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
::... &lt;br /&gt;
::For i = 1 To numEls &lt;br /&gt;
:::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
:::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
:::... &lt;br /&gt;
::Next i &lt;br /&gt;
::InformationPane.Text = outputString &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
通过'''PrintResultTable'''获取一个表格的索引方法如下：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1)&lt;br /&gt;
:theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
我们通过使用[[CATable/zh|CATable]]的[[CATable::IndexNames/zh|IndexNames]]函数获取第一个索引的名字。我们将它传递给[[CATable/zh|CATable]]的[[CATable::GetIndexObject/zh|GetIndexObject]]函数以获取表示我们的索引的[[CAIndex/zh|CAIndex]]。该自动化对象返回其相应索引的相关信息。如果此函数调用失败，将返回&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;信息。在此情况下，使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]] 函数找出原因。&lt;br /&gt;
&lt;br /&gt;
==从CATable和CAIndex中获取信息==&lt;br /&gt;
[[PrintResultTable]]说明了如何从[[CATable/zh| CATable]]和[[CAIndex/zh|CAIndex]] 对象获取信息。该代码获取'''Cost'''表格的索引和表格元素：&lt;br /&gt;
: &amp;lt;tt&amp;gt;&lt;br /&gt;
:numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
:For i = 1 To numEls &lt;br /&gt;
::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
::... &lt;br /&gt;
:Next i &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[CAIndex/zh|CAIndex]]的[[CAIndex::IndexElements/zh|IndexElements]]属性返回第一个索引中的元素个数。[[CAIndex/zh|CAIndex]]的[[CAIndex::GetValueByNumber/zh|GetValueByNumber]]函数获取单个索引元素。 &lt;br /&gt;
&lt;br /&gt;
我们通过传递表格中元素的坐标，使用  [[CATable/zh|CATable]]的[[CATable::GetDataByElements/zh|GetDataByElements]]函数获取'''Cost'''表格对象的单个表格元素'''resultTable'''。 &lt;br /&gt;
&lt;br /&gt;
当我检索 [[CATable/zh|CATable]]对象中单个元素（'''resultTable'''）的时候，我们利用了该表格是一维的事实。因此，我们只需要传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个单一数（这个数代表表格中的位置）。但是，如果我们处理两个或者更多维度，我们必须传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个数组函数，并且指明我们要检索的表格元素的位置。因此，如果我们不想检索一个二维数组的position (4,3)位置的元素，我们可以这样写：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Dim W as Variant 'return element &lt;br /&gt;
:Dim IndexPtrs(1 To 2) As Variant 'position in table &lt;br /&gt;
::... &lt;br /&gt;
:IndexPtrs(1) = 4 &lt;br /&gt;
:IndexPtrs(2) = 3 &lt;br /&gt;
:W = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](IndexPtrs) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==控制基元值格式==&lt;br /&gt;
[[CATable/zh|CATable]]中的每个基元值可以是一个数、一个字符串，或者其它一些基本类型（''例如''：[[Null|空值]]、[[Undefined|未定义]]、[[Reference|参考]]，或 [[Handle|句柄]]。通过说明类型和值，它们作为''变体''被返回，这是一种Visual Basic能读懂的数据结构。[[CATable/zh|CATable]]的[[CATable::RenderingStyle|RenderingStyle]]属性控制Analytica基础值是如何映射到Visual Basic变体的。 &lt;br /&gt;
&lt;br /&gt;
例如：可以通过使用Analytica 模型的数字格式设置将一个数值返回成一个数字或者字符串。如果被指定格式，有一个选线控制是截断数字的位数，还是精确返回。 &lt;br /&gt;
&lt;br /&gt;
子程序[[PrintResultTable/zh|PrintResultTable]]在&amp;lt;tt&amp;gt;frmMain.vb&amp;lt;/tt&amp;gt;中载入,其渲染风格直接指明：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::NumberAsText/zh|NumberAsText]] = True &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::FullPrecision/zh|FullPrecision]] = False &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::StringQuotes/zh|StringQuotes]] = 2 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
第一行指明数值应该根据与结果对象有关的数字格式被格式化为文本。例如在其程序输出中，我们将看到&amp;lt;tt&amp;gt;30.103M&amp;lt;/tt&amp;gt;，而非&amp;lt;tt&amp;gt;30102995.6639812&amp;lt;/tt&amp;gt;，如果我们让Visual Basic将数值串联我们的结果字符串，将显示该结果。在此事件中，一个值为字符串的单元格出现在结果中，返回值将明确带双引号。对于[[CARenderingStyle/zh|CARenderingStyle]]对象中的所有可用属性，请参考[[CARenderingStyle/zh|CARenderingStyle]]。&lt;br /&gt;
&lt;br /&gt;
===其它访问表格的方式===&lt;br /&gt;
有几种访问多维表格[[CATable/zh|CATable]]中元素的方式。每一种都有可能在特定的场合使用起来比较方便。 &lt;br /&gt;
&lt;br /&gt;
第一种方式就是使用[[CATable/zh | CATable]]的 [[CATable::GetDataByElements/zh|GetDataByElements]]或[[CATable::GetDataByLabels/zh|GetDataByLabels]]方法，上面代码示例中有显示。在此情况下，利用你想获取的基元值的单元格位置。 &lt;br /&gt;
&lt;br /&gt;
第二种方式就是使用[[CATable/zh|CATable]][[CATable::Slice/zh|Slice]]或[[CATable::Subscript/zh | Subscript]]方法获取一个少一个维度的新[[CATable/zh|CATable]]对象。通过重复减少维度，最终将获得0维度，这时你将获得一个单一基元值。此时，[[CATable/zh|CATable]]的[[CATable::AtomicValue/zh|AtomicValue]]方法返回该值 。[[CATable::AtomicValue/zh|AtomicValue]]方法是唯一获取一个标值的方法（因为没有坐标位置）。如果你需要建立完整结果其中一个切片的图形图像，必须使用此方法。 &lt;br /&gt;
&lt;br /&gt;
第三种方式就是使用[[CATable/zh|CATable]]的[[CATable::GetSafeArray/zh|GetSafeArray]]方法，将多维数组转化成一个''安全数组''（或者一个.NET数组）。你可以在使用VB或者其它.NET语言直接处理多维数组。因为对于Analytica维度没有固定顺序，但是安全数组和.NET数组有一个明确的顺序，你必须先使用[[CATable/zh|CATable]]对象的[[CATable::SetIndexOrder/zh|SetIndexOrder]]方法在调用[[CATable::GetSafeArray/zh|GetSafeArray]]之前指明维度的顺序。注意如果你知道你的数组是一维的，那就没必要了。&lt;br /&gt;
&lt;br /&gt;
===修改对象===&lt;br /&gt;
一个自定义用户程序通常从一个用户或者其它外部源获取输入，以便转化成Analytica模型中的输入变量。你可以设定输入变量的定义或者通过使用定义表格来这样做。 &lt;br /&gt;
&lt;br /&gt;
'''TestTxc''' 说明了如何修改'''Pop_exp'''定义，此模型是一个影响结果变量Cost的模型输入。要想在该示例中设定该定义，从主菜单上选择'''File &amp;gt; Change Population'''。将出现一个对话框，如下图所示：&lt;br /&gt;
&lt;br /&gt;
[[File:RedefiningtheVariableDefinition.jpg|400px/zh|文件：RedefiningtheVariableDefinition.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
在信息栏中输入一个新定义并点击'''Ok'''确认。主窗口将显示一个新的Cost值。当点击该对话框中的'''Ok'''按钮时，调用了&amp;lt;tt&amp;gt;ChangeDef.frm&amp;lt;/tt&amp;gt;函数，然后调用[[PrintAttributes/zh|PrintAttributes]]函数打印&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果。&lt;br /&gt;
&lt;br /&gt;
此函数类似于：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Private Sub OkButton_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles OkButton.Click &lt;br /&gt;
::Dim errorText As String&lt;br /&gt;
::Dim pop_exp_Object As [[CAObject/zh|CAObject]] &lt;br /&gt;
::Dim errorCode As Short &lt;br /&gt;
::Dim errorString As String &lt;br /&gt;
::newDefinition = PopExposedDef.Text &lt;br /&gt;
::pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
::pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]](&amp;quot;[[Definition]]&amp;quot;, newDefinition) &lt;br /&gt;
::errorCode = adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &lt;br /&gt;
::If errorCode &amp;lt;&amp;gt; 0 Then &lt;br /&gt;
:::MsgBox(&amp;quot;This error occurred while processing your definition: &amp;quot; &amp;amp; vbCrLf &amp;amp; vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) :::PopExposedDef.Focus()&lt;br /&gt;
::Else&lt;br /&gt;
:::Me.Close() &lt;br /&gt;
:::frmMain.DefInstance.PrintAttributes(&amp;quot;Pop_exp&amp;quot;, &amp;quot;Cost&amp;quot;) &lt;br /&gt;
::End If &lt;br /&gt;
::ReleaseComObject(pop_exp_Object) &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
该函数抓取了输入到'''New Definition''' 新定义给'''Population Exposed'''栏，并通过使用[[CAObject/zh|CAObject]]对象中的[[CAObject::SetAttribute/zh|SetAttribute]]函数将它设置给&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;对象。然后调用[[PrintAttributes/zh|PrintAttributes]]，以计算&amp;lt;tt&amp;gt;Cost object&amp;lt;/tt&amp;gt;，并打印新的结果。要想给变量&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;设定一个新定义，我们可以为&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;获取[[CAObject/zh|CAObject]]对象，然后将其定义设置成用户输入的定义。通过使用下面的代码来实现：&lt;br /&gt;
:pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
:pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]]( &amp;quot;[[Definition]]&amp;quot;, newDefinition )&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
无论什么时候调用[[CAObject::SetAttribute/zh|SetAttribute]]，都应该检查[[CAEngine/zh|CAEngine]]自动化对象（'''adeEngine'''）的[[CAEngine::ErrorCode/zh|ErrorCode]]，以免它的定义是非法的。尝试一下输入一个新定义，比如&amp;lt;code&amp;gt;[[Uniform]](25M,35M)&amp;lt;/code&amp;gt;，然后点击'''Ok'''。当&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;的定义被改变时， &amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果由ADE重新计算，此时'''ResultTable'''接下来调用给Cost变量（在应用程序窗口重新显示时）。&lt;br /&gt;
&lt;br /&gt;
使用ADE绘图&lt;br /&gt;
&lt;br /&gt;
通过Analytica 4.6使用相同的绘图引擎，你可以建立一个图表或者图形以显示一个数组值或者不确定值结果。在ADE4.6中，你可以使用 [[CATable/zh|CATable]]的[[CATable::GraphToFile/zh|GraphToFile]]和[[CATable::GraphToStream/zh|GraphToStream]]方法。图形可以以几种可能的图像格式返回，例如'''image/png'''、 '''image/bmp'''或者 '''image/jpeg'''。 &lt;br /&gt;
&lt;br /&gt;
从可用图形选项中选择的最简单方式就是使用Analytica打开你的模型。你可以实验设置各种默认设置或者替代选择的变量，看它们是如何工作的。但你选择了你想设置的选项，保存模型。当为每一个生成结果图形时，ADE将使用这些设置。 &lt;br /&gt;
&lt;br /&gt;
对于更高维度的结果，可能需要做一些必要工作，以便选择将绘制结果的切片和具体的轴（也就是相对于图例哪个维度作为X轴）。[[CATable/zh|CATable]]的[[CATable::Subscript/zh|Subscript]]或[[CATable::Slice/zh|Slice]]方法可以用来控制轴选择特殊的切片用来绘制，能够用来控制轴。详情请参考[[CATable/zh|CATable]]。在我们的&amp;lt;tt&amp;gt;Tutorial.NET&amp;lt;/tt&amp;gt;示例中，我们有一个一维结果（&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;），因此我们没有必要担心截取或者绕轴旋转。 &lt;br /&gt;
&lt;br /&gt;
[[CATable::GraphToStream/zh|GraphToStream]]方法被用来从ADE中直接转化图形图形到一个用户界面中。使用[[CATable::GraphToStream/zh|GraphToStream]]比起使用[[CATable::GraphToFile/zh|GraphToFile]]来要稍微复杂一点，因为[[CATable::GraphToFile/zh|GraphToFile]]除了需要文件名以外还需要其它一些信息，以便编写图形。要使用[[CATable::GraphToStream/zh|GraphToStream]]，我们必须在内存内设置一个流，允许ADE写入该留，然后从该留重建。因为.NET流和COM流不兼容，你必须使用ADE一同提供的[[StreamConnector]]类型.&amp;lt;tt&amp;gt;frmMain&amp;lt;/tt&amp;gt; 中的'''GraphResult_Click'''子程序演示了[[CATable::GraphToStream/zh|GraphToStream]]的使用。从主应用程序窗口选择 '''Graph Result'''菜单选项，结果将出现在一个如下所示的图形当中：&lt;br /&gt;
&lt;br /&gt;
[[File:resultgraph.jpg/zh|文件：resultgraph.jpg]]&lt;br /&gt;
&lt;br /&gt;
==结论==&lt;br /&gt;
&lt;br /&gt;
在此教程中，我们介绍了Analytica决策引擎的几个重要方面。我们看到了如何建立一个ADE服务器对象，使用ADE打开模型，获取模型中的单个对象、计算对象、获取表格中的元素，以及修改模型中的对象。但是ADE可以做的远不止这些。 &lt;br /&gt;
&lt;br /&gt;
我们希望你已经足够了解其基本特征，这样你现在才能独自开始探索更多新的高级特征。我们建议你现在开始阅读字教程的剩余部分以了解ADE能做什么。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
| [[Installation of ADE/zh|ADE 安装]] &amp;lt;- ||  [[The ADE Tutorial/zh|ADE 入门教程]] || -&amp;gt; [[Using the ADE Server/zh|使用ADE服务器]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36284</id>
		<title>The ADE Tutorial/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36284"/>
		<updated>2015-10-27T06:24:30Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南 ]]&lt;br /&gt;
&lt;br /&gt;
此教程教你如何在一个Visual Basic程序中使用Analytica决策引擎（ADE）。&lt;br /&gt;
&lt;br /&gt;
==你的第一个ADE应用程序==&lt;br /&gt;
首先先从头开始写一个简单的ADE程序，只要确认一切设置正常。按照以下步骤操作：&lt;br /&gt;
&lt;br /&gt;
test&lt;br /&gt;
&lt;br /&gt;
第一个程序执行了以下操作：&lt;br /&gt;
*建立一个名称为ADE的[[CAEngine/zh|CAEngine]]自动化对象（通过使用&amp;lt;code&amp;gt;new [[CAEngine/zh|CAEngine]]&amp;lt;/code&amp;gt;).&lt;br /&gt;
*打开Analytica模型 (通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]] 方法。&lt;br /&gt;
*显示模型名称返回[[CAEngine::OpenModel/zh|OpenModel]]的值。&lt;br /&gt;
我们将在后面的章节详细了解这些信息。&lt;br /&gt;
&lt;br /&gt;
===接下来讲什么呢?===&lt;br /&gt;
我们不会尝试在此入门教程中解释ADE的特征。本指南后面几个章节会描述这些特征。 &lt;br /&gt;
&lt;br /&gt;
从现在开始，我们我们将使用名称为&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;的示例模型。打开 Analytica安装目录下 '''Example Models'''文件夹里面的'''Risk Analysis'''文件夹便可找到&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;文件。如果你找不到，或者你安装Analytica的时候未选择安装examples（示例）文件，在ADE安装目录下面的'''Examples\Tutorial.NET'''文件家中有一个副本。 &lt;br /&gt;
&lt;br /&gt;
Txc模型演示了减少污染物TXC排放的risk-benefit （风险-效益）分析。请用Analytica打开Txc查看它是如何工作的。 &lt;br /&gt;
&lt;br /&gt;
ADE '''Examples\Tutorial.NET''' 文件夹中名称为&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;的Visual Basic.NET程序示例显示了ADE很多方面。该程序建立了一个ADE自动化对象，打开包含该对象的&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，获取变量 &amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，计算变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;，通过获取每个表格的单独组件以表格的方式打印输出变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的结果，然后改变变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义。再次获取变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的值，看一下 变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;定义的改变对变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;有什么影响。如果设置正确的话,&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;将显示在“Text Txc window”中显示的窗口。 &lt;br /&gt;
&lt;br /&gt;
应用程序显示变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义（&amp;lt;tt&amp;gt;&amp;quot;Normal (30M, 3M)&amp;quot;&amp;lt;/tt&amp;gt;），以及与&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;关联的表格，这都基于&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义。你可以通过从主菜单选择'''File &amp;gt; Change Population Exposed'''改变&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，然后查看改变对&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;表格的影响。&lt;br /&gt;
&lt;br /&gt;
[[File:TextTxcWindow.png|400px/zh | 文件：TextTxcWindow.png|400px]]&lt;br /&gt;
&lt;br /&gt;
===区分title（名称） 和 identifier（标识符）===&lt;br /&gt;
无论什么时候，一个ADE函数都需要一个变量你必须传达变量的'''''[[Identifier|标识符]]''''' ，而不是它的'''''[[Title|名称]]'''''。这可能会引起混淆，因为在Analytica影响图中一般显示每一个变量的名称。默认情况下，在你最初建立每一个对象的时候，Analytica自动根据名称建立一个标识符。用（_）代替名称中的每一个空格或者其他非字母和数字字符。 &lt;br /&gt;
&lt;br /&gt;
你可以通过点击“Control+y”（或者从Object（对象）菜单选择'''Show by identifier''' ：显示标识符） 来以标识符显示变量。对于模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;，你可以看到名称为&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;变量的标识符为 &amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;。将变量传递给ADE函数时，使用标识符很重要。如果你传递&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;，ADE无法找到变量，并且将返回一个错误。&lt;br /&gt;
&lt;br /&gt;
===从Visual Basic中建立一个ADE 对象===&lt;br /&gt;
&lt;br /&gt;
如果你还没准备好，将名称为tt&amp;gt;Examples\Tutorial\TestTxc.sln&amp;lt;/tt&amp;gt;载入到Visual Basic.NET中，查看名称为&amp;lt;tt&amp;gt;TestTxc.vb&amp;lt;/tt&amp;gt;的文件的代码。其代码看起来像：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Imports ADEW &lt;br /&gt;
:. . . &lt;br /&gt;
:Public adeEngine As [[CAEngine/zh|CAEngine]]&lt;br /&gt;
&lt;br /&gt;
:Public Sub Main() &lt;br /&gt;
::Dim exeDirectory, theModel As String &lt;br /&gt;
::Dim theModelString As String &lt;br /&gt;
::exeDirectory = VB6.GetPath &lt;br /&gt;
::theModel = exeDirectory &amp;amp; &amp;quot;\..\&amp;quot; &amp;amp; &amp;quot;Txc.ana&amp;quot; &lt;br /&gt;
::adeEngine = New [[CAEngine/zh|CAEngine]]&lt;br /&gt;
::... &lt;br /&gt;
::theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
::... &lt;br /&gt;
::frmMain.DefInstance.Show() &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在每一个文件的顶部的代码将自动化对象 '''adeEngine''' 声明为一个[[CAEngine/zh|CAEngine]] 对象。使用此对象，我们能够访问 [[CAEngine/zh|CAEngine]] 展示的所有公共函数（参考 [[ADE Server Class Reference/zh|ADE服务器类型参考]] ）&lt;br /&gt;
&lt;br /&gt;
变量&amp;lt;tt&amp;gt;adeEngine&amp;lt;/tt&amp;gt;包含我们的进程内对象 [[CAEngine/zh|CAEngine]]。如果我们想使用ADE的本地（进程外）服务器版本，我们可以将一个项目参考添加到'''Analytica Decision Engine Server 4.6 COM''' 组件并将顶部行从&amp;lt;tt&amp;gt;Imports ADEW&amp;lt;/tt&amp;gt;改成&amp;lt;tt&amp;gt;Imports ADE&amp;lt;/tt&amp;gt;即可。 &lt;br /&gt;
&lt;br /&gt;
这里是另一种获得一个先[[CAEngine/zh|CAEngine]]对象的方法。此循序不需要给项目添加参考。&amp;lt;tt&amp;gt;&lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADEW4.6.CAEngine&amp;quot;) ’ in-process &lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADE4.6.CAEngine&amp;quot;) ’ out-of-process &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果想理解使用进程内和进程外（或本地）服务器的利与弊，以及哪一种自动化服务器用于不同的场景，参考[[Using_the_Analytica_Decision_Engine_Server#In-process_vs_Out-of-process/zh | In-process vs. out-of-process]]&lt;br /&gt;
&lt;br /&gt;
===COM和 Automation 接口比较===&lt;br /&gt;
在上面的例子当中，我们使用COM接口调用ADE。在一个COM 接口中，对象 在本例中为 [[CAEngine/zh|CAEngine]] 被声明为[[CAEngine/zh|CAEngine]] ，编译器解决每一个成员函数，并且在编译时间内能探测几个明显的错误。另外，Visual Studio可以提供方法和参数类型列表当，在你编程的时候可以当做一个提示工具，在编写使用ADE程序是非常有用。COM调用比Automation调用要快一点，但是在ADE应用程序中速度差异通常不是很重要。对于ADE 4.6我们推荐使用COM结构，只要你的语言支持。&lt;br /&gt;
&lt;br /&gt;
在VB Automation中，你可以将一个对象简单声明为Object（对象），而不是像 [[CAEngine/zh|CAEngine]]、[[CAObject/zh|CAObject]]等更加具体的类型。当使用Automation调用'''ADE'''方法时，在运行时间内确定方法。在编译时间内，编译器不知道你的 '''ADE''' 对象是否有一个名称为[[CAEngine::OpenModel/zh|OpenModel]]的函数。在VB中，调用COM方法或Automation 方法的语法是相通的——唯一的不同在于对象类型是否明确被声明。&lt;br /&gt;
&lt;br /&gt;
在VC++和C#中，调用COM的语法和调用Automatio的语法不同。在这些情况下，COM要方便的多，Automation能够获得相冗余。然而，同样的语言，包括VBScript和其他脚本语言，只支持Automation不支持COM。&lt;br /&gt;
&lt;br /&gt;
===监视Process（进程）===&lt;br /&gt;
当使用进程外ADE服务器时，你的代码必须在终止时释放[[CAEngine/zh|CAEngine]]COM对象。当最终[[CAEngine/zh|CAEngine]]使用被释放是，ADE.exe 进程自动终止。到目前为止所看到的代码，VB语言在达到程序末端时，自动处理释放对象。但是，当你调试你的代码是，你可以提前终止你的程序来修复bug，你的程序可能被Task Manager（任务管理器）终止，或者你自己的代码也可能奔溃，导致你的程序进程在它有机会释放对象之前终止。应为COM对象从来不会被释放，ADE.exe进程不知道它是否在使用中，你可能获得ADE.exe 僵尸进程。 &lt;br /&gt;
&lt;br /&gt;
为了避免这种情况发生，一种好的习惯就是在调用[[CAEngine/zh|CAEngine]]实例后 立即调用[[CAEngine::MonitorProcess/zh|CAEngine::MonitorProcess]]。通过这种方式，ADE能够得知哪一个进程正在使用它，同时将设置一个线程去探测你的进程是否在ADE被完全释放前终止。如果你的程序进程没有终止，ADE进程会立即将它关闭，消除了僵尸ADE进程的堆积。 &lt;br /&gt;
&lt;br /&gt;
要从一个.NET应用程序获得进程ID，使用System.Diagnostics.Process namespace中的'''GetCurrentProcess().Id''' 。在其他语言中，你可以使用Windows SDK 的'''GetProcessId( )'''函数。 &lt;br /&gt;
&lt;br /&gt;
'''[[CAEngine::MonitorProcess/zh|MonitorProcess]]()''' 只能用来监视运行ADE进程的同一台计算机的进程，一次当通过DCOM运行ADE时不能使用。当使用进程内ADEW服务器时没有必要使用。&lt;br /&gt;
&lt;br /&gt;
==打开使用ADE的模型==&lt;br /&gt;
我们现在打开&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，显示我们的应用程序主窗口。使用以下调用：tt&amp;gt;&lt;br /&gt;
:theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
:frmMain.DefInstance.Show &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]]函数打开模型。如果成功的话，变量&amp;lt;tt&amp;gt;theModelString&amp;lt;/tt&amp;gt;将包含模型的名字。否则，将包含一个空的串。虽然由于为了简介的缘故，我们没有这样做，但是你应该检查从[[CAEngine::OpenModel/zh|OpenModel]]函数返回的是不是一个空的串。如果是，说明在你打开的模型中存在一个错误。你可以使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/z |ErrorText]]属性找出是哪种错误 （&amp;lt;tt&amp;gt;adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] 和adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]&amp;lt;/tt&amp;gt;）。&lt;br /&gt;
&lt;br /&gt;
==从Analytica模型中检索对象==&lt;br /&gt;
下一步就是从我们的模型中检索对象（变量、模块、函数等），以便我们能获取他们的属性（[[definition|定义]]、[[title|名称]]、[[class|类型]]等等 ）。我们的示例模型（&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;）操作&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;和&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;对象。尤其是，修改&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;可以查看这是如何影响&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt; 对象。&lt;br /&gt;
&lt;br /&gt;
我们的&amp;lt;tt&amp;gt;TxcTest.vbproj&amp;lt;/tt&amp;gt; （&amp;lt;tt&amp;gt;TxcText.sln&amp;lt;/tt&amp;gt;）项目中的&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;文件里的 '''PrintAttributes''' 函数演示了如何检索对象。该函数首先被&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''Form_Load''' 函数调用，当应用程序启动后，可以显示'''Cost'''表格。当然无论什么时候，只要我们想输出'''Cost'''表格的当前值，都可以调用。该函数如下所示：&lt;br /&gt;
:Public Sub PrintAttributes(ByRef inputIdentifier As String, ByRef  outputIdentifier As String) &lt;br /&gt;
::Dim inputObject, outputObject As [[CAObject/zh|CAObject]]&lt;br /&gt;
::Dim resultTable As [[CATable/zh|CATable]]&lt;br /&gt;
::Dim definitionAttrInput As String &lt;br /&gt;
::inputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](inputIdentifier) &lt;br /&gt;
::outputObject = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](outputIdentifier) &lt;br /&gt;
::definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;definition&amp;quot;) &lt;br /&gt;
::resultTable = outputObject.[[CAObject::ResultTable/zh|ResultTable]]&lt;br /&gt;
::Call PrintResultTable(resultTable, inputIdentifier, definitionAttrInput, outputIdentifier) &lt;br /&gt;
::ReleaseComObject(resultTable) &lt;br /&gt;
::ReleaseComObject(inputObject) &lt;br /&gt;
::ReleaseComObject(outputObject) &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''PrintAttributes'''和作为'''inputIdentifier'''参数的&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;变量标识符以及作为'''outputIdentifier'''参数的'''Cost'''变量一起使用。如下所示通过使用[[CAEngine/zh | CAEngine]]的[[CAEngine::GetObjectByName/zh | GetObjectByName]]函数提取相应对象：&amp;lt;tt&amp;gt;&lt;br /&gt;
:inputObject = adeEngine.[[CAEngine::GetObjectByName/zh | GetObjectByName]](inputIdentifier) &lt;br /&gt;
:outputObject = adeEngine.[[CAEngine::GetObjectByName/zh | GetObjectByName]](outputIdentifier)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
如果函数[[CAEngine::GetObjectByName/zh | GetObjectByName]]提取成功，将返回一个[[CAObject/zh | CAObject]]类型对象。如果使用'''[[CAObject/zh | CAObject]]'''的函数，参考[[CAObject/zh |  SendCommand(command)]]，可以获得一个[[CAObject/zh | CAObject]]的完整函数列表。如果函数[[CAEngine::GetObjectByName/zh | GetObjectByName]]提取失败，返回值为&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;。代码应该检查以确保[[CAEngine::GetObjectByName/zh | GetObjectByName]]提取的结果是有效的。如果找不到，可使用[[CAEngine/zh | CAEngine]]的 [[CAEngine::ErrorCode/zh | ErrorCode]]和 [[CAEngine::ErrorText/zh | ErrorText]]属性获取错误信息。例如：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Set inputObject = adeEngine.[[CAEngine::GetObjectByName/zh | GetObjectByName]](inputIdentifier) &lt;br /&gt;
:If inputObject Is Nothing Then &lt;br /&gt;
::MsgBox(“This error from GetObjectByName occurred: “&amp;amp; _ vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorCode/zh | ErrorCode]] &amp;amp; “:” &amp;amp; adeEngine.[[CAEngine::ErrorText/zh | ErrorText]]) &lt;br /&gt;
:Else &lt;br /&gt;
::'inputObject valid &lt;br /&gt;
:End If&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===获取对象属性===&lt;br /&gt;
每一个Analytica对象都有一组属性，例如[[identifier | 标识符]]、[[title | 名称]]、[[description |  描述]]和[[class | 类型]]。你可以使用[[CAObject::GetAttribute/zh | GetAttribute]]函数来获去Analytica对象的属性。例如，如要获取'''inputObject'''的定义（当前为cost）：&amp;lt;tt&amp;gt;&lt;br /&gt;
:definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;[[Definition | 定义]]&amp;quot;) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt; 中，&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;的定义为&amp;quot;&amp;lt;tt&amp;gt;[[Normal]](30M, 3M)&amp;lt;/tt&amp;gt;&amp;quot; ，我们将它储存在'''definitionAttrInput'''当中。.&lt;br /&gt;
&lt;br /&gt;
===计算对象和检索结果===&lt;br /&gt;
使用[[CAObject/zh | CAObject]]的[[CAObject::Result/zh | Result]]或[[CAObject::ResultTable/zh | ResultTable]]方法来获取变量的值。如果有必要的话，ADE先自动计算变量。如果你确定结果为基元（只有一个元素），使用[[CAObject::Result/zh | Result]]方法。否则使用[[CAObject::ResultTable/zh | ResultTable]]，检索结果为一个''数组''。基元结果当作一个特殊数组案例来处理，没有维度的数组。如果值为基元[[CATable::AtomicValue/zh | AtomicValue]]方法将返回一个数字或者字符串单一值。 &lt;br /&gt;
&lt;br /&gt;
默认情况下，[[CAObject::Result/zh | Result]]和[[CAObject::ResultTable/zh | ResultTable]]返回结果的中值，也就是说，ADE以确定性方式计算结果。对于一个概率值，将[[CAObject/zh | CAObject]]的[[CAObject::ResultType/zh | ResultType]]属性设置为想要的不确定性视图——Mean（平均值） Sample（样本）、PDF（概率密度函数）、CDF（累计分布函数）、Confidence bands（置信带）、或者Statistics（统计数据）详情请参考[[CAObject::ResultType/zh | ResultType]]。我们通过如下的方式获取outputObject 输出对象 的值：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable = outputObject.[[CAObject::ResultTable/zh |ResultTable]] &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
结果为一个[[CATable/zh | CATable]]对象，允许我们访问一个表格中的单个元素。 &lt;br /&gt;
&lt;br /&gt;
如果你通过调用[[CAObject::Result/zh | Result]]来获取一个数组（或者表格）的值，将返回数组为一个字符串，列出索引和元素，以逗号隔开。通常使用[[CAObject::ResultTable/zh | ResultTable]]更加简单，这样你没有必要从字符串中解析表格的元素。&lt;br /&gt;
&lt;br /&gt;
===获取表格索引元素===&lt;br /&gt;
一个Analytica表格包含0个或者多个索引。如果包含一个索引，那么该表格是1维表格；如果有2个索引，说他是2维表格，依此类推。0维度表格包含一个“单一基元”（或标量）值。你可以使用CATable的[[CATable::NumDims/zh | NumDims]]获取表格的维数（也就是索引数）。要想获取表格的单个索引，可使用[[CATable/zh | CATable]]的 [[CATable::IndexNames/zh | IndexNames]]和 [[CATable::GetIndexObject/zh | GetIndexObject]]函数。 &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''PrintResultTable'''函数说明了这两个函数的使用。从'''PrintAttributes'''中调用'''PrintResultTable'''，执行打印'''TestTxc'''中的表格的实际工作（为了简洁起见，我们只给出了关联ADE的该函数部分）。&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Public Sub PrintResultTable(ByRef resultTable As CATable, ByRef inputIdentifier As String, ByRef definitionAttrInput As String, ByRef outputIdentifier As String) &lt;br /&gt;
::Dim theIndexName, theTableName As String &lt;br /&gt;
::Dim theIndexElement As String &lt;br /&gt;
::Dim theTableElement &lt;br /&gt;
::Dim theIndexObj As [[CAIndex/zh | CAIndex]]&lt;br /&gt;
::Dim numEls As Integer &lt;br /&gt;
::Dim spaces, i As Integer &lt;br /&gt;
::Dim lenStr As Short &lt;br /&gt;
::Dim OutputStr As Short &lt;br /&gt;
::Dim spaceString, underlineString As String &lt;br /&gt;
::... &lt;br /&gt;
::theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1) &lt;br /&gt;
::theTableName = resultTable.[[CATable::Name/zh|Name]] &lt;br /&gt;
::theIndexObj = resultTable.[[CATable::GetIndexObject/zh | GetIndexObject]](theIndexName) &lt;br /&gt;
::numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
::... &lt;br /&gt;
::For i = 1 To numEls &lt;br /&gt;
:::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
:::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
:::... &lt;br /&gt;
::Next i &lt;br /&gt;
::InformationPane.Text = outputString &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
通过'''PrintResultTable'''获取一个表格的索引方法如下：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1)&lt;br /&gt;
:theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
我们通过使用[[CATable/zh|CATable]]的[[CATable::IndexNames/zh|IndexNames]]函数获取第一个索引的名字。我们将它传递给[[CATable/zh|CATable]]的[[CATable::GetIndexObject/zh|GetIndexObject]]函数以获取表示我们的索引的[[CAIndex/zh|CAIndex]]。该自动化对象返回其相应索引的相关信息。如果此函数调用失败，将返回&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;信息。在此情况下，使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]] 函数找出原因。&lt;br /&gt;
&lt;br /&gt;
==从CATable和CAIndex中获取信息==&lt;br /&gt;
[[PrintResultTable]]说明了如何从[[CATable/zh| CATable]]和[[CAIndex/zh|CAIndex]] 对象获取信息。该代码获取'''Cost'''表格的索引和表格元素：&lt;br /&gt;
: &amp;lt;tt&amp;gt;&lt;br /&gt;
:numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
:For i = 1 To numEls &lt;br /&gt;
::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
::... &lt;br /&gt;
:Next i &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[CAIndex/zh|CAIndex]]的[[CAIndex::IndexElements/zh|IndexElements]]属性返回第一个索引中的元素个数。[[CAIndex/zh|CAIndex]]的[[CAIndex::GetValueByNumber/zh|GetValueByNumber]]函数获取单个索引元素。 &lt;br /&gt;
&lt;br /&gt;
我们通过传递表格中元素的坐标，使用  [[CATable/zh|CATable]]的[[CATable::GetDataByElements/zh|GetDataByElements]]函数获取'''Cost'''表格对象的单个表格元素'''resultTable'''。 &lt;br /&gt;
&lt;br /&gt;
当我检索 [[CATable/zh|CATable]]对象中单个元素（'''resultTable'''）的时候，我们利用了该表格是一维的事实。因此，我们只需要传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个单一数（这个数代表表格中的位置）。但是，如果我们处理两个或者更多维度，我们必须传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个数组函数，并且指明我们要检索的表格元素的位置。因此，如果我们不想检索一个二维数组的position (4,3)位置的元素，我们可以这样写：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Dim W as Variant 'return element &lt;br /&gt;
:Dim IndexPtrs(1 To 2) As Variant 'position in table &lt;br /&gt;
::... &lt;br /&gt;
:IndexPtrs(1) = 4 &lt;br /&gt;
:IndexPtrs(2) = 3 &lt;br /&gt;
:W = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](IndexPtrs) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==控制基元值格式==&lt;br /&gt;
[[CATable/zh|CATable]]中的每个基元值可以是一个数、一个字符串，或者其它一些基本类型（''例如''：[[Null|空值]]、[[Undefined|未定义]]、[[Reference|参考]]，或 [[Handle|句柄]]。通过说明类型和值，它们作为''变体''被返回，这是一种Visual Basic能读懂的数据结构。[[CATable/zh|CATable]]的[[CATable::RenderingStyle|RenderingStyle]]属性控制Analytica基础值是如何映射到Visual Basic变体的。 &lt;br /&gt;
&lt;br /&gt;
例如：可以通过使用Analytica 模型的数字格式设置将一个数值返回成一个数字或者字符串。如果被指定格式，有一个选线控制是截断数字的位数，还是精确返回。 &lt;br /&gt;
&lt;br /&gt;
子程序[[PrintResultTable/zh|PrintResultTable]]在&amp;lt;tt&amp;gt;frmMain.vb&amp;lt;/tt&amp;gt;中载入,其渲染风格直接指明：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::NumberAsText/zh|NumberAsText]] = True &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::FullPrecision/zh|FullPrecision]] = False &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::StringQuotes/zh|StringQuotes]] = 2 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
第一行指明数值应该根据与结果对象有关的数字格式被格式化为文本。例如在其程序输出中，我们将看到&amp;lt;tt&amp;gt;30.103M&amp;lt;/tt&amp;gt;，而非&amp;lt;tt&amp;gt;30102995.6639812&amp;lt;/tt&amp;gt;，如果我们让Visual Basic将数值串联我们的结果字符串，将显示该结果。在此事件中，一个值为字符串的单元格出现在结果中，返回值将明确带双引号。对于[[CARenderingStyle/zh|CARenderingStyle]]对象中的所有可用属性，请参考[[CARenderingStyle/zh|CARenderingStyle]]。&lt;br /&gt;
&lt;br /&gt;
===其它访问表格的方式===&lt;br /&gt;
有几种访问多维表格[[CATable/zh|CATable]]中元素的方式。每一种都有可能在特定的场合使用起来比较方便。 &lt;br /&gt;
&lt;br /&gt;
第一种方式就是使用[[CATable/zh | CATable]]的 [[CATable::GetDataByElements/zh|GetDataByElements]]或[[CATable::GetDataByLabels/zh|GetDataByLabels]]方法，上面代码示例中有显示。在此情况下，利用你想获取的基元值的单元格位置。 &lt;br /&gt;
&lt;br /&gt;
第二种方式就是使用[[CATable/zh|CATable]][[CATable::Slice/zh|Slice]]或[[CATable::Subscript/zh | Subscript]]方法获取一个少一个维度的新[[CATable/zh|CATable]]对象。通过重复减少维度，最终将获得0维度，这时你将获得一个单一基元值。此时，[[CATable/zh|CATable]]的[[CATable::AtomicValue/zh|AtomicValue]]方法返回该值 。[[CATable::AtomicValue/zh|AtomicValue]]方法是唯一获取一个标值的方法（因为没有坐标位置）。如果你需要建立完整结果其中一个切片的图形图像，必须使用此方法。 &lt;br /&gt;
&lt;br /&gt;
第三种方式就是使用[[CATable/zh|CATable]]的[[CATable::GetSafeArray/zh|GetSafeArray]]方法，将多维数组转化成一个''安全数组''（或者一个.NET数组）。你可以在使用VB或者其它.NET语言直接处理多维数组。因为对于Analytica维度没有固定顺序，但是安全数组和.NET数组有一个明确的顺序，你必须先使用[[CATable/zh|CATable]]对象的[[CATable::SetIndexOrder/zh|SetIndexOrder]]方法在调用[[CATable::GetSafeArray/zh|GetSafeArray]]之前指明维度的顺序。注意如果你知道你的数组是一维的，那就没必要了。&lt;br /&gt;
&lt;br /&gt;
===修改对象===&lt;br /&gt;
一个自定义用户程序通常从一个用户或者其它外部源获取输入，以便转化成Analytica模型中的输入变量。你可以设定输入变量的定义或者通过使用定义表格来这样做。 &lt;br /&gt;
&lt;br /&gt;
'''TestTxc''' 说明了如何修改'''Pop_exp'''定义，此模型是一个影响结果变量Cost的模型输入。要想在该示例中设定该定义，从主菜单上选择'''File &amp;gt; Change Population'''。将出现一个对话框，如下图所示：&lt;br /&gt;
&lt;br /&gt;
[[File:RedefiningtheVariableDefinition.jpg|400px/zh|文件：RedefiningtheVariableDefinition.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
在信息栏中输入一个新定义并点击'''Ok'''确认。主窗口将显示一个新的Cost值。当点击该对话框中的'''Ok'''按钮时，调用了&amp;lt;tt&amp;gt;ChangeDef.frm&amp;lt;/tt&amp;gt;函数，然后调用[[PrintAttributes/zh|PrintAttributes]]函数打印&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果。&lt;br /&gt;
&lt;br /&gt;
此函数类似于：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Private Sub OkButton_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles OkButton.Click &lt;br /&gt;
::Dim errorText As String&lt;br /&gt;
::Dim pop_exp_Object As [[CAObject/zh|CAObject]] &lt;br /&gt;
::Dim errorCode As Short &lt;br /&gt;
::Dim errorString As String &lt;br /&gt;
::newDefinition = PopExposedDef.Text &lt;br /&gt;
::pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
::pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]](&amp;quot;[[Definition]]&amp;quot;, newDefinition) &lt;br /&gt;
::errorCode = adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &lt;br /&gt;
::If errorCode &amp;lt;&amp;gt; 0 Then &lt;br /&gt;
:::MsgBox(&amp;quot;This error occurred while processing your definition: &amp;quot; &amp;amp; vbCrLf &amp;amp; vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) :::PopExposedDef.Focus()&lt;br /&gt;
::Else&lt;br /&gt;
:::Me.Close() &lt;br /&gt;
:::frmMain.DefInstance.PrintAttributes(&amp;quot;Pop_exp&amp;quot;, &amp;quot;Cost&amp;quot;) &lt;br /&gt;
::End If &lt;br /&gt;
::ReleaseComObject(pop_exp_Object) &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
该函数抓取了输入到'''New Definition''' 新定义给'''Population Exposed'''栏，并通过使用[[CAObject/zh|CAObject]]对象中的[[CAObject::SetAttribute/zh|SetAttribute]]函数将它设置给&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;对象。然后调用[[PrintAttributes/zh|PrintAttributes]]，以计算&amp;lt;tt&amp;gt;Cost object&amp;lt;/tt&amp;gt;，并打印新的结果。要想给变量&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;设定一个新定义，我们可以为&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;获取[[CAObject/zh|CAObject]]对象，然后将其定义设置成用户输入的定义。通过使用下面的代码来实现：&lt;br /&gt;
:pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
:pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]]( &amp;quot;[[Definition]]&amp;quot;, newDefinition )&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
无论什么时候调用[[CAObject::SetAttribute/zh|SetAttribute]]，都应该检查[[CAEngine/zh|CAEngine]]自动化对象（'''adeEngine'''）的[[CAEngine::ErrorCode/zh|ErrorCode]]，以免它的定义是非法的。尝试一下输入一个新定义，比如&amp;lt;code&amp;gt;[[Uniform]](25M,35M)&amp;lt;/code&amp;gt;，然后点击'''Ok'''。当&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;的定义被改变时， &amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果由ADE重新计算，此时'''ResultTable'''接下来调用给Cost变量（在应用程序窗口重新显示时）。&lt;br /&gt;
&lt;br /&gt;
使用ADE绘图&lt;br /&gt;
&lt;br /&gt;
通过Analytica 4.6使用相同的绘图引擎，你可以建立一个图表或者图形以显示一个数组值或者不确定值结果。在ADE4.6中，你可以使用 [[CATable/zh|CATable]]的[[CATable::GraphToFile/zh|GraphToFile]]和[[CATable::GraphToStream/zh|GraphToStream]]方法。图形可以以几种可能的图像格式返回，例如'''image/png'''、 '''image/bmp'''或者 '''image/jpeg'''。 &lt;br /&gt;
&lt;br /&gt;
从可用图形选项中选择的最简单方式就是使用Analytica打开你的模型。你可以实验设置各种默认设置或者替代选择的变量，看它们是如何工作的。但你选择了你想设置的选项，保存模型。当为每一个生成结果图形时，ADE将使用这些设置。 &lt;br /&gt;
&lt;br /&gt;
对于更高维度的结果，可能需要做一些必要工作，以便选择将绘制结果的切片和具体的轴（也就是相对于图例哪个维度作为X轴）。[[CATable/zh|CATable]]的[[CATable::Subscript/zh|Subscript]]或[[CATable::Slice/zh|Slice]]方法可以用来控制轴选择特殊的切片用来绘制，能够用来控制轴。详情请参考[[CATable/zh|CATable]]。在我们的&amp;lt;tt&amp;gt;Tutorial.NET&amp;lt;/tt&amp;gt;示例中，我们有一个一维结果（&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;），因此我们没有必要担心截取或者绕轴旋转。 &lt;br /&gt;
&lt;br /&gt;
[[CATable::GraphToStream/zh|GraphToStream]]方法被用来从ADE中直接转化图形图形到一个用户界面中。使用[[CATable::GraphToStream/zh|GraphToStream]]比起使用[[CATable::GraphToFile/zh|GraphToFile]]来要稍微复杂一点，因为[[CATable::GraphToFile/zh|GraphToFile]]除了需要文件名以外还需要其它一些信息，以便编写图形。要使用[[CATable::GraphToStream/zh|GraphToStream]]，我们必须在内存内设置一个流，允许ADE写入该留，然后从该留重建。因为.NET流和COM流不兼容，你必须使用ADE一同提供的[[StreamConnector]]类型.&amp;lt;tt&amp;gt;frmMain&amp;lt;/tt&amp;gt; 中的'''GraphResult_Click'''子程序演示了[[CATable::GraphToStream/zh|GraphToStream]]的使用。从主应用程序窗口选择 '''Graph Result'''菜单选项，结果将出现在一个如下所示的图形当中：&lt;br /&gt;
&lt;br /&gt;
[[File:resultgraph.jpg/zh|文件：resultgraph.jpg]]&lt;br /&gt;
&lt;br /&gt;
==结论==&lt;br /&gt;
&lt;br /&gt;
在此教程中，我们介绍了Analytica决策引擎的几个重要方面。我们看到了如何建立一个ADE服务器对象，使用ADE打开模型，获取模型中的单个对象、计算对象、获取表格中的元素，以及修改模型中的对象。但是ADE可以做的远不止这些。 &lt;br /&gt;
&lt;br /&gt;
我们希望你已经足够了解其基本特征，这样你现在才能独自开始探索更多新的高级特征。我们建议你现在开始阅读字教程的剩余部分以了解ADE能做什么。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
| [[Installation of ADE/zh|ADE 安装]] &amp;lt;- ||  [[The ADE Tutorial/zh|ADE 入门教程]] || -&amp;gt; [[Using the ADE Server/zh|使用ADE服务器]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36282</id>
		<title>The ADE Tutorial/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36282"/>
		<updated>2015-10-27T06:24:11Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南 ]]&lt;br /&gt;
&lt;br /&gt;
此教程教你如何在一个Visual Basic程序中使用Analytica决策引擎（ADE）。&lt;br /&gt;
&lt;br /&gt;
==你的第一个ADE应用程序==&lt;br /&gt;
首先先从头开始写一个简单的ADE程序，只要确认一切设置正常。按照以下步骤操作：&lt;br /&gt;
&lt;br /&gt;
test&lt;br /&gt;
&lt;br /&gt;
第一个程序执行了以下操作：&lt;br /&gt;
*建立一个名称为ADE的[[CAEngine/zh|CAEngine]]自动化对象（通过使用&amp;lt;code&amp;gt;new [[CAEngine/zh|CAEngine]]&amp;lt;/code&amp;gt;).&lt;br /&gt;
*打开Analytica模型 (通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]] 方法。&lt;br /&gt;
*显示模型名称返回[[CAEngine::OpenModel/zh|OpenModel]]的值。&lt;br /&gt;
我们将在后面的章节详细了解这些信息。&lt;br /&gt;
&lt;br /&gt;
===接下来讲什么呢?===&lt;br /&gt;
我们不会尝试在此入门教程中解释ADE的特征。本指南后面几个章节会描述这些特征。 &lt;br /&gt;
&lt;br /&gt;
从现在开始，我们我们将使用名称为&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;的示例模型。打开 Analytica安装目录下 '''Example Models'''文件夹里面的'''Risk Analysis'''文件夹便可找到&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;文件。如果你找不到，或者你安装Analytica的时候未选择安装examples（示例）文件，在ADE安装目录下面的'''Examples\Tutorial.NET'''文件家中有一个副本。 &lt;br /&gt;
&lt;br /&gt;
Txc模型演示了减少污染物TXC排放的risk-benefit （风险-效益）分析。请用Analytica打开Txc查看它是如何工作的。 &lt;br /&gt;
&lt;br /&gt;
ADE '''Examples\Tutorial.NET''' 文件夹中名称为&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;的Visual Basic.NET程序示例显示了ADE很多方面。该程序建立了一个ADE自动化对象，打开包含该对象的&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，获取变量 &amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，计算变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;，通过获取每个表格的单独组件以表格的方式打印输出变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的结果，然后改变变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义。再次获取变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的值，看一下 变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;定义的改变对变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;有什么影响。如果设置正确的话,&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;将显示在“Text Txc window”中显示的窗口。 &lt;br /&gt;
&lt;br /&gt;
应用程序显示变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义（&amp;lt;tt&amp;gt;&amp;quot;Normal (30M, 3M)&amp;quot;&amp;lt;/tt&amp;gt;），以及与&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;关联的表格，这都基于&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义。你可以通过从主菜单选择'''File &amp;gt; Change Population Exposed'''改变&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，然后查看改变对&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;表格的影响。&lt;br /&gt;
&lt;br /&gt;
[[File:TextTxcWindow.png|400px/zh | 文件：TextTxcWindow.png|400px]]&lt;br /&gt;
&lt;br /&gt;
===区分title（名称） 和 identifier（标识符）===&lt;br /&gt;
无论什么时候，一个ADE函数都需要一个变量你必须传达变量的'''''[[Identifier|标识符]]''''' ，而不是它的'''''[[Title|名称]]'''''。这可能会引起混淆，因为在Analytica影响图中一般显示每一个变量的名称。默认情况下，在你最初建立每一个对象的时候，Analytica自动根据名称建立一个标识符。用（_）代替名称中的每一个空格或者其他非字母和数字字符。 &lt;br /&gt;
&lt;br /&gt;
你可以通过点击“Control+y”（或者从Object（对象）菜单选择'''Show by identifier''' ：显示标识符） 来以标识符显示变量。对于模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;，你可以看到名称为&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;变量的标识符为 &amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;。将变量传递给ADE函数时，使用标识符很重要。如果你传递&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;，ADE无法找到变量，并且将返回一个错误。&lt;br /&gt;
&lt;br /&gt;
===从Visual Basic中建立一个ADE 对象===&lt;br /&gt;
&lt;br /&gt;
如果你还没准备好，将名称为tt&amp;gt;Examples\Tutorial\TestTxc.sln&amp;lt;/tt&amp;gt;载入到Visual Basic.NET中，查看名称为&amp;lt;tt&amp;gt;TestTxc.vb&amp;lt;/tt&amp;gt;的文件的代码。其代码看起来像：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Imports ADEW &lt;br /&gt;
:. . . &lt;br /&gt;
:Public adeEngine As [[CAEngine/zh|CAEngine]]&lt;br /&gt;
&lt;br /&gt;
:Public Sub Main() &lt;br /&gt;
::Dim exeDirectory, theModel As String &lt;br /&gt;
::Dim theModelString As String &lt;br /&gt;
::exeDirectory = VB6.GetPath &lt;br /&gt;
::theModel = exeDirectory &amp;amp; &amp;quot;\..\&amp;quot; &amp;amp; &amp;quot;Txc.ana&amp;quot; &lt;br /&gt;
::adeEngine = New [[CAEngine/zh|CAEngine]]&lt;br /&gt;
::... &lt;br /&gt;
::theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
::... &lt;br /&gt;
::frmMain.DefInstance.Show() &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在每一个文件的顶部的代码将自动化对象 '''adeEngine''' 声明为一个[[CAEngine/zh|CAEngine]] 对象。使用此对象，我们能够访问 [[CAEngine/zh|CAEngine]] 展示的所有公共函数（参考 [[ADE Server Class Reference/zh|ADE服务器类型参考]] ）&lt;br /&gt;
&lt;br /&gt;
变量&amp;lt;tt&amp;gt;adeEngine&amp;lt;/tt&amp;gt;包含我们的进程内对象 [[CAEngine/zh|CAEngine]]。如果我们想使用ADE的本地（进程外）服务器版本，我们可以将一个项目参考添加到'''Analytica Decision Engine Server 4.6 COM''' 组件并将顶部行从&amp;lt;tt&amp;gt;Imports ADEW&amp;lt;/tt&amp;gt;改成&amp;lt;tt&amp;gt;Imports ADE&amp;lt;/tt&amp;gt;即可。 &lt;br /&gt;
&lt;br /&gt;
这里是另一种获得一个先[[CAEngine/zh|CAEngine]]对象的方法。此循序不需要给项目添加参考。&amp;lt;tt&amp;gt;&lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADEW4.6.CAEngine&amp;quot;) ’ in-process &lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADE4.6.CAEngine&amp;quot;) ’ out-of-process &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果想理解使用进程内和进程外（或本地）服务器的利与弊，以及哪一种自动化服务器用于不同的场景，参考[[Using_the_Analytica_Decision_Engine_Server#In-process_vs_Out-of-process/zh | In-process vs. out-of-process]]&lt;br /&gt;
&lt;br /&gt;
===COM和 Automation 接口比较===&lt;br /&gt;
在上面的例子当中，我们使用COM接口调用ADE。在一个COM 接口中，对象 在本例中为 [[CAEngine/zh|CAEngine]] 被声明为[[CAEngine/zh|CAEngine]] ，编译器解决每一个成员函数，并且在编译时间内能探测几个明显的错误。另外，Visual Studio可以提供方法和参数类型列表当，在你编程的时候可以当做一个提示工具，在编写使用ADE程序是非常有用。COM调用比Automation调用要快一点，但是在ADE应用程序中速度差异通常不是很重要。对于ADE 4.6我们推荐使用COM结构，只要你的语言支持。&lt;br /&gt;
&lt;br /&gt;
在VB Automation中，你可以将一个对象简单声明为Object（对象），而不是像 [[CAEngine/zh|CAEngine]]、[[CAObject/zh|CAObject]]等更加具体的类型。当使用Automation调用'''ADE'''方法时，在运行时间内确定方法。在编译时间内，编译器不知道你的 '''ADE''' 对象是否有一个名称为[[CAEngine::OpenModel/zh|OpenModel]]的函数。在VB中，调用COM方法或Automation 方法的语法是相通的——唯一的不同在于对象类型是否明确被声明。&lt;br /&gt;
&lt;br /&gt;
在VC++和C#中，调用COM的语法和调用Automatio的语法不同。在这些情况下，COM要方便的多，Automation能够获得相冗余。然而，同样的语言，包括VBScript和其他脚本语言，只支持Automation不支持COM。&lt;br /&gt;
&lt;br /&gt;
===监视Process（进程）===&lt;br /&gt;
当使用进程外ADE服务器时，你的代码必须在终止时释放[[CAEngine/zh|CAEngine]]COM对象。当最终[[CAEngine/zh|CAEngine]]使用被释放是，ADE.exe 进程自动终止。到目前为止所看到的代码，VB语言在达到程序末端时，自动处理释放对象。但是，当你调试你的代码是，你可以提前终止你的程序来修复bug，你的程序可能被Task Manager（任务管理器）终止，或者你自己的代码也可能奔溃，导致你的程序进程在它有机会释放对象之前终止。应为COM对象从来不会被释放，ADE.exe进程不知道它是否在使用中，你可能获得ADE.exe 僵尸进程。 &lt;br /&gt;
&lt;br /&gt;
为了避免这种情况发生，一种好的习惯就是在调用[[CAEngine/zh|CAEngine]]实例后 立即调用[[CAEngine::MonitorProcess/zh|CAEngine::MonitorProcess]]。通过这种方式，ADE能够得知哪一个进程正在使用它，同时将设置一个线程去探测你的进程是否在ADE被完全释放前终止。如果你的程序进程没有终止，ADE进程会立即将它关闭，消除了僵尸ADE进程的堆积。 &lt;br /&gt;
&lt;br /&gt;
要从一个.NET应用程序获得进程ID，使用System.Diagnostics.Process namespace中的'''GetCurrentProcess().Id''' 。在其他语言中，你可以使用Windows SDK 的'''GetProcessId( )'''函数。 &lt;br /&gt;
&lt;br /&gt;
'''[[CAEngine::MonitorProcess/zh|MonitorProcess]]()''' 只能用来监视运行ADE进程的同一台计算机的进程，一次当通过DCOM运行ADE时不能使用。当使用进程内ADEW服务器时没有必要使用。&lt;br /&gt;
&lt;br /&gt;
==打开使用ADE的模型==&lt;br /&gt;
我们现在打开&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，显示我们的应用程序主窗口。使用以下调用：tt&amp;gt;&lt;br /&gt;
:theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
:frmMain.DefInstance.Show &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]]函数打开模型。如果成功的话，变量&amp;lt;tt&amp;gt;theModelString&amp;lt;/tt&amp;gt;将包含模型的名字。否则，将包含一个空的串。虽然由于为了简介的缘故，我们没有这样做，但是你应该检查从[[CAEngine::OpenModel/zh|OpenModel]]函数返回的是不是一个空的串。如果是，说明在你打开的模型中存在一个错误。你可以使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/z |ErrorText]]属性找出是哪种错误 （&amp;lt;tt&amp;gt;adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] 和adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]&amp;lt;/tt&amp;gt;）。&lt;br /&gt;
&lt;br /&gt;
==从Analytica模型中检索对象==&lt;br /&gt;
下一步就是从我们的模型中检索对象（变量、模块、函数等），以便我们能获取他们的属性（[[definition|定义]]、[[title|名称]]、[[class|类型]]等等 ）。我们的示例模型（&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;）操作&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;和&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;对象。尤其是，修改&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;可以查看这是如何影响&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt; 对象。&lt;br /&gt;
&lt;br /&gt;
我们的&amp;lt;tt&amp;gt;TxcTest.vbproj&amp;lt;/tt&amp;gt; （&amp;lt;tt&amp;gt;TxcText.sln&amp;lt;/tt&amp;gt;）项目中的&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;文件里的 '''PrintAttributes''' 函数演示了如何检索对象。该函数首先被&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''Form_Load''' 函数调用，当应用程序启动后，可以显示'''Cost'''表格。当然无论什么时候，只要我们想输出'''Cost'''表格的当前值，都可以调用。该函数如下所示：&lt;br /&gt;
:Public Sub PrintAttributes(ByRef inputIdentifier As String, ByRef  outputIdentifier As String) &lt;br /&gt;
::Dim inputObject, outputObject As [[CAObject/zh | CAObject]]&lt;br /&gt;
::Dim resultTable As [[CATable/zh | CATable]]&lt;br /&gt;
::Dim definitionAttrInput As String &lt;br /&gt;
::inputObject = adeEngine.[[CAEngine::GetObjectByName/zh | GetObjectByName]](inputIdentifier) &lt;br /&gt;
::outputObject = adeEngine.[[CAEngine::GetObjectByName/zh | GetObjectByName]](outputIdentifier) &lt;br /&gt;
::definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;definition&amp;quot;) &lt;br /&gt;
::resultTable = outputObject.[[CAObject::ResultTable/zh | ResultTable]]&lt;br /&gt;
::Call PrintResultTable(resultTable, inputIdentifier, definitionAttrInput, outputIdentifier) &lt;br /&gt;
::ReleaseComObject(resultTable) &lt;br /&gt;
::ReleaseComObject(inputObject) &lt;br /&gt;
::ReleaseComObject(outputObject) &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''PrintAttributes'''和作为'''inputIdentifier'''参数的&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;变量标识符以及作为'''outputIdentifier'''参数的'''Cost'''变量一起使用。如下所示通过使用[[CAEngine/zh | CAEngine]]的[[CAEngine::GetObjectByName/zh | GetObjectByName]]函数提取相应对象：&amp;lt;tt&amp;gt;&lt;br /&gt;
:inputObject = adeEngine.[[CAEngine::GetObjectByName/zh | GetObjectByName]](inputIdentifier) &lt;br /&gt;
:outputObject = adeEngine.[[CAEngine::GetObjectByName/zh | GetObjectByName]](outputIdentifier)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
如果函数[[CAEngine::GetObjectByName/zh | GetObjectByName]]提取成功，将返回一个[[CAObject/zh | CAObject]]类型对象。如果使用'''[[CAObject/zh | CAObject]]'''的函数，参考[[CAObject/zh |  SendCommand(command)]]，可以获得一个[[CAObject/zh | CAObject]]的完整函数列表。如果函数[[CAEngine::GetObjectByName/zh | GetObjectByName]]提取失败，返回值为&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;。代码应该检查以确保[[CAEngine::GetObjectByName/zh | GetObjectByName]]提取的结果是有效的。如果找不到，可使用[[CAEngine/zh | CAEngine]]的 [[CAEngine::ErrorCode/zh | ErrorCode]]和 [[CAEngine::ErrorText/zh | ErrorText]]属性获取错误信息。例如：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Set inputObject = adeEngine.[[CAEngine::GetObjectByName/zh | GetObjectByName]](inputIdentifier) &lt;br /&gt;
:If inputObject Is Nothing Then &lt;br /&gt;
::MsgBox(“This error from GetObjectByName occurred: “&amp;amp; _ vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorCode/zh | ErrorCode]] &amp;amp; “:” &amp;amp; adeEngine.[[CAEngine::ErrorText/zh | ErrorText]]) &lt;br /&gt;
:Else &lt;br /&gt;
::'inputObject valid &lt;br /&gt;
:End If&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===获取对象属性===&lt;br /&gt;
每一个Analytica对象都有一组属性，例如[[identifier | 标识符]]、[[title | 名称]]、[[description |  描述]]和[[class | 类型]]。你可以使用[[CAObject::GetAttribute/zh | GetAttribute]]函数来获去Analytica对象的属性。例如，如要获取'''inputObject'''的定义（当前为cost）：&amp;lt;tt&amp;gt;&lt;br /&gt;
:definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;[[Definition | 定义]]&amp;quot;) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt; 中，&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;的定义为&amp;quot;&amp;lt;tt&amp;gt;[[Normal]](30M, 3M)&amp;lt;/tt&amp;gt;&amp;quot; ，我们将它储存在'''definitionAttrInput'''当中。.&lt;br /&gt;
&lt;br /&gt;
===计算对象和检索结果===&lt;br /&gt;
使用[[CAObject/zh | CAObject]]的[[CAObject::Result/zh | Result]]或[[CAObject::ResultTable/zh | ResultTable]]方法来获取变量的值。如果有必要的话，ADE先自动计算变量。如果你确定结果为基元（只有一个元素），使用[[CAObject::Result/zh | Result]]方法。否则使用[[CAObject::ResultTable/zh | ResultTable]]，检索结果为一个''数组''。基元结果当作一个特殊数组案例来处理，没有维度的数组。如果值为基元[[CATable::AtomicValue/zh | AtomicValue]]方法将返回一个数字或者字符串单一值。 &lt;br /&gt;
&lt;br /&gt;
默认情况下，[[CAObject::Result/zh | Result]]和[[CAObject::ResultTable/zh | ResultTable]]返回结果的中值，也就是说，ADE以确定性方式计算结果。对于一个概率值，将[[CAObject/zh | CAObject]]的[[CAObject::ResultType/zh | ResultType]]属性设置为想要的不确定性视图——Mean（平均值） Sample（样本）、PDF（概率密度函数）、CDF（累计分布函数）、Confidence bands（置信带）、或者Statistics（统计数据）详情请参考[[CAObject::ResultType/zh | ResultType]]。我们通过如下的方式获取outputObject 输出对象 的值：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable = outputObject.[[CAObject::ResultTable/zh |ResultTable]] &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
结果为一个[[CATable/zh | CATable]]对象，允许我们访问一个表格中的单个元素。 &lt;br /&gt;
&lt;br /&gt;
如果你通过调用[[CAObject::Result/zh | Result]]来获取一个数组（或者表格）的值，将返回数组为一个字符串，列出索引和元素，以逗号隔开。通常使用[[CAObject::ResultTable/zh | ResultTable]]更加简单，这样你没有必要从字符串中解析表格的元素。&lt;br /&gt;
&lt;br /&gt;
===获取表格索引元素===&lt;br /&gt;
一个Analytica表格包含0个或者多个索引。如果包含一个索引，那么该表格是1维表格；如果有2个索引，说他是2维表格，依此类推。0维度表格包含一个“单一基元”（或标量）值。你可以使用CATable的[[CATable::NumDims/zh | NumDims]]获取表格的维数（也就是索引数）。要想获取表格的单个索引，可使用[[CATable/zh | CATable]]的 [[CATable::IndexNames/zh | IndexNames]]和 [[CATable::GetIndexObject/zh | GetIndexObject]]函数。 &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''PrintResultTable'''函数说明了这两个函数的使用。从'''PrintAttributes'''中调用'''PrintResultTable'''，执行打印'''TestTxc'''中的表格的实际工作（为了简洁起见，我们只给出了关联ADE的该函数部分）。&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Public Sub PrintResultTable(ByRef resultTable As CATable, ByRef inputIdentifier As String, ByRef definitionAttrInput As String, ByRef outputIdentifier As String) &lt;br /&gt;
::Dim theIndexName, theTableName As String &lt;br /&gt;
::Dim theIndexElement As String &lt;br /&gt;
::Dim theTableElement &lt;br /&gt;
::Dim theIndexObj As [[CAIndex/zh | CAIndex]]&lt;br /&gt;
::Dim numEls As Integer &lt;br /&gt;
::Dim spaces, i As Integer &lt;br /&gt;
::Dim lenStr As Short &lt;br /&gt;
::Dim OutputStr As Short &lt;br /&gt;
::Dim spaceString, underlineString As String &lt;br /&gt;
::... &lt;br /&gt;
::theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1) &lt;br /&gt;
::theTableName = resultTable.[[CATable::Name/zh|Name]] &lt;br /&gt;
::theIndexObj = resultTable.[[CATable::GetIndexObject/zh | GetIndexObject]](theIndexName) &lt;br /&gt;
::numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
::... &lt;br /&gt;
::For i = 1 To numEls &lt;br /&gt;
:::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
:::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
:::... &lt;br /&gt;
::Next i &lt;br /&gt;
::InformationPane.Text = outputString &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
通过'''PrintResultTable'''获取一个表格的索引方法如下：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1)&lt;br /&gt;
:theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
我们通过使用[[CATable/zh|CATable]]的[[CATable::IndexNames/zh|IndexNames]]函数获取第一个索引的名字。我们将它传递给[[CATable/zh|CATable]]的[[CATable::GetIndexObject/zh|GetIndexObject]]函数以获取表示我们的索引的[[CAIndex/zh|CAIndex]]。该自动化对象返回其相应索引的相关信息。如果此函数调用失败，将返回&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;信息。在此情况下，使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]] 函数找出原因。&lt;br /&gt;
&lt;br /&gt;
==从CATable和CAIndex中获取信息==&lt;br /&gt;
[[PrintResultTable]]说明了如何从[[CATable/zh| CATable]]和[[CAIndex/zh|CAIndex]] 对象获取信息。该代码获取'''Cost'''表格的索引和表格元素：&lt;br /&gt;
: &amp;lt;tt&amp;gt;&lt;br /&gt;
:numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
:For i = 1 To numEls &lt;br /&gt;
::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
::... &lt;br /&gt;
:Next i &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[CAIndex/zh|CAIndex]]的[[CAIndex::IndexElements/zh|IndexElements]]属性返回第一个索引中的元素个数。[[CAIndex/zh|CAIndex]]的[[CAIndex::GetValueByNumber/zh|GetValueByNumber]]函数获取单个索引元素。 &lt;br /&gt;
&lt;br /&gt;
我们通过传递表格中元素的坐标，使用  [[CATable/zh|CATable]]的[[CATable::GetDataByElements/zh|GetDataByElements]]函数获取'''Cost'''表格对象的单个表格元素'''resultTable'''。 &lt;br /&gt;
&lt;br /&gt;
当我检索 [[CATable/zh|CATable]]对象中单个元素（'''resultTable'''）的时候，我们利用了该表格是一维的事实。因此，我们只需要传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个单一数（这个数代表表格中的位置）。但是，如果我们处理两个或者更多维度，我们必须传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个数组函数，并且指明我们要检索的表格元素的位置。因此，如果我们不想检索一个二维数组的position (4,3)位置的元素，我们可以这样写：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Dim W as Variant 'return element &lt;br /&gt;
:Dim IndexPtrs(1 To 2) As Variant 'position in table &lt;br /&gt;
::... &lt;br /&gt;
:IndexPtrs(1) = 4 &lt;br /&gt;
:IndexPtrs(2) = 3 &lt;br /&gt;
:W = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](IndexPtrs) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==控制基元值格式==&lt;br /&gt;
[[CATable/zh|CATable]]中的每个基元值可以是一个数、一个字符串，或者其它一些基本类型（''例如''：[[Null|空值]]、[[Undefined|未定义]]、[[Reference|参考]]，或 [[Handle|句柄]]。通过说明类型和值，它们作为''变体''被返回，这是一种Visual Basic能读懂的数据结构。[[CATable/zh|CATable]]的[[CATable::RenderingStyle|RenderingStyle]]属性控制Analytica基础值是如何映射到Visual Basic变体的。 &lt;br /&gt;
&lt;br /&gt;
例如：可以通过使用Analytica 模型的数字格式设置将一个数值返回成一个数字或者字符串。如果被指定格式，有一个选线控制是截断数字的位数，还是精确返回。 &lt;br /&gt;
&lt;br /&gt;
子程序[[PrintResultTable/zh|PrintResultTable]]在&amp;lt;tt&amp;gt;frmMain.vb&amp;lt;/tt&amp;gt;中载入,其渲染风格直接指明：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::NumberAsText/zh|NumberAsText]] = True &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::FullPrecision/zh|FullPrecision]] = False &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::StringQuotes/zh|StringQuotes]] = 2 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
第一行指明数值应该根据与结果对象有关的数字格式被格式化为文本。例如在其程序输出中，我们将看到&amp;lt;tt&amp;gt;30.103M&amp;lt;/tt&amp;gt;，而非&amp;lt;tt&amp;gt;30102995.6639812&amp;lt;/tt&amp;gt;，如果我们让Visual Basic将数值串联我们的结果字符串，将显示该结果。在此事件中，一个值为字符串的单元格出现在结果中，返回值将明确带双引号。对于[[CARenderingStyle/zh|CARenderingStyle]]对象中的所有可用属性，请参考[[CARenderingStyle/zh|CARenderingStyle]]。&lt;br /&gt;
&lt;br /&gt;
===其它访问表格的方式===&lt;br /&gt;
有几种访问多维表格[[CATable/zh|CATable]]中元素的方式。每一种都有可能在特定的场合使用起来比较方便。 &lt;br /&gt;
&lt;br /&gt;
第一种方式就是使用[[CATable/zh | CATable]]的 [[CATable::GetDataByElements/zh|GetDataByElements]]或[[CATable::GetDataByLabels/zh|GetDataByLabels]]方法，上面代码示例中有显示。在此情况下，利用你想获取的基元值的单元格位置。 &lt;br /&gt;
&lt;br /&gt;
第二种方式就是使用[[CATable/zh|CATable]][[CATable::Slice/zh|Slice]]或[[CATable::Subscript/zh | Subscript]]方法获取一个少一个维度的新[[CATable/zh|CATable]]对象。通过重复减少维度，最终将获得0维度，这时你将获得一个单一基元值。此时，[[CATable/zh|CATable]]的[[CATable::AtomicValue/zh|AtomicValue]]方法返回该值 。[[CATable::AtomicValue/zh|AtomicValue]]方法是唯一获取一个标值的方法（因为没有坐标位置）。如果你需要建立完整结果其中一个切片的图形图像，必须使用此方法。 &lt;br /&gt;
&lt;br /&gt;
第三种方式就是使用[[CATable/zh|CATable]]的[[CATable::GetSafeArray/zh|GetSafeArray]]方法，将多维数组转化成一个''安全数组''（或者一个.NET数组）。你可以在使用VB或者其它.NET语言直接处理多维数组。因为对于Analytica维度没有固定顺序，但是安全数组和.NET数组有一个明确的顺序，你必须先使用[[CATable/zh|CATable]]对象的[[CATable::SetIndexOrder/zh|SetIndexOrder]]方法在调用[[CATable::GetSafeArray/zh|GetSafeArray]]之前指明维度的顺序。注意如果你知道你的数组是一维的，那就没必要了。&lt;br /&gt;
&lt;br /&gt;
===修改对象===&lt;br /&gt;
一个自定义用户程序通常从一个用户或者其它外部源获取输入，以便转化成Analytica模型中的输入变量。你可以设定输入变量的定义或者通过使用定义表格来这样做。 &lt;br /&gt;
&lt;br /&gt;
'''TestTxc''' 说明了如何修改'''Pop_exp'''定义，此模型是一个影响结果变量Cost的模型输入。要想在该示例中设定该定义，从主菜单上选择'''File &amp;gt; Change Population'''。将出现一个对话框，如下图所示：&lt;br /&gt;
&lt;br /&gt;
[[File:RedefiningtheVariableDefinition.jpg|400px/zh|文件：RedefiningtheVariableDefinition.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
在信息栏中输入一个新定义并点击'''Ok'''确认。主窗口将显示一个新的Cost值。当点击该对话框中的'''Ok'''按钮时，调用了&amp;lt;tt&amp;gt;ChangeDef.frm&amp;lt;/tt&amp;gt;函数，然后调用[[PrintAttributes/zh|PrintAttributes]]函数打印&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果。&lt;br /&gt;
&lt;br /&gt;
此函数类似于：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Private Sub OkButton_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles OkButton.Click &lt;br /&gt;
::Dim errorText As String&lt;br /&gt;
::Dim pop_exp_Object As [[CAObject/zh|CAObject]] &lt;br /&gt;
::Dim errorCode As Short &lt;br /&gt;
::Dim errorString As String &lt;br /&gt;
::newDefinition = PopExposedDef.Text &lt;br /&gt;
::pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
::pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]](&amp;quot;[[Definition]]&amp;quot;, newDefinition) &lt;br /&gt;
::errorCode = adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &lt;br /&gt;
::If errorCode &amp;lt;&amp;gt; 0 Then &lt;br /&gt;
:::MsgBox(&amp;quot;This error occurred while processing your definition: &amp;quot; &amp;amp; vbCrLf &amp;amp; vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) :::PopExposedDef.Focus()&lt;br /&gt;
::Else&lt;br /&gt;
:::Me.Close() &lt;br /&gt;
:::frmMain.DefInstance.PrintAttributes(&amp;quot;Pop_exp&amp;quot;, &amp;quot;Cost&amp;quot;) &lt;br /&gt;
::End If &lt;br /&gt;
::ReleaseComObject(pop_exp_Object) &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
该函数抓取了输入到'''New Definition''' 新定义给'''Population Exposed'''栏，并通过使用[[CAObject/zh|CAObject]]对象中的[[CAObject::SetAttribute/zh|SetAttribute]]函数将它设置给&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;对象。然后调用[[PrintAttributes/zh|PrintAttributes]]，以计算&amp;lt;tt&amp;gt;Cost object&amp;lt;/tt&amp;gt;，并打印新的结果。要想给变量&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;设定一个新定义，我们可以为&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;获取[[CAObject/zh|CAObject]]对象，然后将其定义设置成用户输入的定义。通过使用下面的代码来实现：&lt;br /&gt;
:pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
:pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]]( &amp;quot;[[Definition]]&amp;quot;, newDefinition )&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
无论什么时候调用[[CAObject::SetAttribute/zh|SetAttribute]]，都应该检查[[CAEngine/zh|CAEngine]]自动化对象（'''adeEngine'''）的[[CAEngine::ErrorCode/zh|ErrorCode]]，以免它的定义是非法的。尝试一下输入一个新定义，比如&amp;lt;code&amp;gt;[[Uniform]](25M,35M)&amp;lt;/code&amp;gt;，然后点击'''Ok'''。当&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;的定义被改变时， &amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果由ADE重新计算，此时'''ResultTable'''接下来调用给Cost变量（在应用程序窗口重新显示时）。&lt;br /&gt;
&lt;br /&gt;
使用ADE绘图&lt;br /&gt;
&lt;br /&gt;
通过Analytica 4.6使用相同的绘图引擎，你可以建立一个图表或者图形以显示一个数组值或者不确定值结果。在ADE4.6中，你可以使用 [[CATable/zh|CATable]]的[[CATable::GraphToFile/zh|GraphToFile]]和[[CATable::GraphToStream/zh|GraphToStream]]方法。图形可以以几种可能的图像格式返回，例如'''image/png'''、 '''image/bmp'''或者 '''image/jpeg'''。 &lt;br /&gt;
&lt;br /&gt;
从可用图形选项中选择的最简单方式就是使用Analytica打开你的模型。你可以实验设置各种默认设置或者替代选择的变量，看它们是如何工作的。但你选择了你想设置的选项，保存模型。当为每一个生成结果图形时，ADE将使用这些设置。 &lt;br /&gt;
&lt;br /&gt;
对于更高维度的结果，可能需要做一些必要工作，以便选择将绘制结果的切片和具体的轴（也就是相对于图例哪个维度作为X轴）。[[CATable/zh|CATable]]的[[CATable::Subscript/zh|Subscript]]或[[CATable::Slice/zh|Slice]]方法可以用来控制轴选择特殊的切片用来绘制，能够用来控制轴。详情请参考[[CATable/zh|CATable]]。在我们的&amp;lt;tt&amp;gt;Tutorial.NET&amp;lt;/tt&amp;gt;示例中，我们有一个一维结果（&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;），因此我们没有必要担心截取或者绕轴旋转。 &lt;br /&gt;
&lt;br /&gt;
[[CATable::GraphToStream/zh|GraphToStream]]方法被用来从ADE中直接转化图形图形到一个用户界面中。使用[[CATable::GraphToStream/zh|GraphToStream]]比起使用[[CATable::GraphToFile/zh|GraphToFile]]来要稍微复杂一点，因为[[CATable::GraphToFile/zh|GraphToFile]]除了需要文件名以外还需要其它一些信息，以便编写图形。要使用[[CATable::GraphToStream/zh|GraphToStream]]，我们必须在内存内设置一个流，允许ADE写入该留，然后从该留重建。因为.NET流和COM流不兼容，你必须使用ADE一同提供的[[StreamConnector]]类型.&amp;lt;tt&amp;gt;frmMain&amp;lt;/tt&amp;gt; 中的'''GraphResult_Click'''子程序演示了[[CATable::GraphToStream/zh|GraphToStream]]的使用。从主应用程序窗口选择 '''Graph Result'''菜单选项，结果将出现在一个如下所示的图形当中：&lt;br /&gt;
&lt;br /&gt;
[[File:resultgraph.jpg/zh|文件：resultgraph.jpg]]&lt;br /&gt;
&lt;br /&gt;
==结论==&lt;br /&gt;
&lt;br /&gt;
在此教程中，我们介绍了Analytica决策引擎的几个重要方面。我们看到了如何建立一个ADE服务器对象，使用ADE打开模型，获取模型中的单个对象、计算对象、获取表格中的元素，以及修改模型中的对象。但是ADE可以做的远不止这些。 &lt;br /&gt;
&lt;br /&gt;
我们希望你已经足够了解其基本特征，这样你现在才能独自开始探索更多新的高级特征。我们建议你现在开始阅读字教程的剩余部分以了解ADE能做什么。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
| [[Installation of ADE/zh|ADE 安装]] &amp;lt;- ||  [[The ADE Tutorial/zh|ADE 入门教程]] || -&amp;gt; [[Using the ADE Server/zh|使用ADE服务器]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
	<entry>
		<id>https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36280</id>
		<title>The ADE Tutorial/zh</title>
		<link rel="alternate" type="text/html" href="https://docs.analytica.com/index.php?title=The_ADE_Tutorial/zh&amp;diff=36280"/>
		<updated>2015-10-27T06:23:57Z</updated>

		<summary type="html">&lt;p&gt;Jhuawen: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ADE User Guide]]&lt;br /&gt;
&amp;lt;languages /&amp;gt;&lt;br /&gt;
[[Category:ADE User Guide/zh|ADE用户指南 ]]&lt;br /&gt;
&lt;br /&gt;
此教程教你如何在一个Visual Basic程序中使用Analytica决策引擎（ADE）。&lt;br /&gt;
&lt;br /&gt;
==你的第一个ADE应用程序==&lt;br /&gt;
首先先从头开始写一个简单的ADE程序，只要确认一切设置正常。按照以下步骤操作：&lt;br /&gt;
&lt;br /&gt;
test&lt;br /&gt;
&lt;br /&gt;
第一个程序执行了以下操作：&lt;br /&gt;
*建立一个名称为ADE的[[CAEngine/zh|CAEngine]]自动化对象（通过使用&amp;lt;code&amp;gt;new [[CAEngine/zh|CAEngine]]&amp;lt;/code&amp;gt;).&lt;br /&gt;
*打开Analytica模型 (通过使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]] 方法。&lt;br /&gt;
*显示模型名称返回[[CAEngine::OpenModel/zh|OpenModel]]的值。&lt;br /&gt;
我们将在后面的章节详细了解这些信息。&lt;br /&gt;
&lt;br /&gt;
===接下来讲什么呢?===&lt;br /&gt;
我们不会尝试在此入门教程中解释ADE的特征。本指南后面几个章节会描述这些特征。 &lt;br /&gt;
&lt;br /&gt;
从现在开始，我们我们将使用名称为&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;的示例模型。打开 Analytica安装目录下 '''Example Models'''文件夹里面的'''Risk Analysis'''文件夹便可找到&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;文件。如果你找不到，或者你安装Analytica的时候未选择安装examples（示例）文件，在ADE安装目录下面的'''Examples\Tutorial.NET'''文件家中有一个副本。 &lt;br /&gt;
&lt;br /&gt;
Txc模型演示了减少污染物TXC排放的risk-benefit （风险-效益）分析。请用Analytica打开Txc查看它是如何工作的。 &lt;br /&gt;
&lt;br /&gt;
ADE '''Examples\Tutorial.NET''' 文件夹中名称为&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;的Visual Basic.NET程序示例显示了ADE很多方面。该程序建立了一个ADE自动化对象，打开包含该对象的&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，获取变量 &amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，计算变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;，通过获取每个表格的单独组件以表格的方式打印输出变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的结果，然后改变变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义。再次获取变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt; 的值，看一下 变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;定义的改变对变量&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;有什么影响。如果设置正确的话,&amp;lt;tt&amp;gt;TestTxc&amp;lt;/tt&amp;gt;将显示在“Text Txc window”中显示的窗口。 &lt;br /&gt;
&lt;br /&gt;
应用程序显示变量&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt; 的定义（&amp;lt;tt&amp;gt;&amp;quot;Normal (30M, 3M)&amp;quot;&amp;lt;/tt&amp;gt;），以及与&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;关联的表格，这都基于&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义。你可以通过从主菜单选择'''File &amp;gt; Change Population Exposed'''改变&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;的定义，然后查看改变对&amp;lt;tt&amp;gt;Total Cost&amp;lt;/tt&amp;gt;表格的影响。&lt;br /&gt;
&lt;br /&gt;
[[File:TextTxcWindow.png|400px/zh | 文件：TextTxcWindow.png|400px]]&lt;br /&gt;
&lt;br /&gt;
===区分title（名称） 和 identifier（标识符）===&lt;br /&gt;
无论什么时候，一个ADE函数都需要一个变量你必须传达变量的'''''[[Identifier|标识符]]''''' ，而不是它的'''''[[Title|名称]]'''''。这可能会引起混淆，因为在Analytica影响图中一般显示每一个变量的名称。默认情况下，在你最初建立每一个对象的时候，Analytica自动根据名称建立一个标识符。用（_）代替名称中的每一个空格或者其他非字母和数字字符。 &lt;br /&gt;
&lt;br /&gt;
你可以通过点击“Control+y”（或者从Object（对象）菜单选择'''Show by identifier''' ：显示标识符） 来以标识符显示变量。对于模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;，你可以看到名称为&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;变量的标识符为 &amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;。将变量传递给ADE函数时，使用标识符很重要。如果你传递&amp;lt;tt&amp;gt;Population Exposed&amp;lt;/tt&amp;gt;，ADE无法找到变量，并且将返回一个错误。&lt;br /&gt;
&lt;br /&gt;
===从Visual Basic中建立一个ADE 对象===&lt;br /&gt;
&lt;br /&gt;
如果你还没准备好，将名称为tt&amp;gt;Examples\Tutorial\TestTxc.sln&amp;lt;/tt&amp;gt;载入到Visual Basic.NET中，查看名称为&amp;lt;tt&amp;gt;TestTxc.vb&amp;lt;/tt&amp;gt;的文件的代码。其代码看起来像：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Imports ADEW &lt;br /&gt;
:. . . &lt;br /&gt;
:Public adeEngine As [[CAEngine/zh|CAEngine]]&lt;br /&gt;
&lt;br /&gt;
:Public Sub Main() &lt;br /&gt;
::Dim exeDirectory, theModel As String &lt;br /&gt;
::Dim theModelString As String &lt;br /&gt;
::exeDirectory = VB6.GetPath &lt;br /&gt;
::theModel = exeDirectory &amp;amp; &amp;quot;\..\&amp;quot; &amp;amp; &amp;quot;Txc.ana&amp;quot; &lt;br /&gt;
::adeEngine = New [[CAEngine/zh|CAEngine]]&lt;br /&gt;
::... &lt;br /&gt;
::theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
::... &lt;br /&gt;
::frmMain.DefInstance.Show() &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在每一个文件的顶部的代码将自动化对象 '''adeEngine''' 声明为一个[[CAEngine/zh|CAEngine]] 对象。使用此对象，我们能够访问 [[CAEngine/zh|CAEngine]] 展示的所有公共函数（参考 [[ADE Server Class Reference/zh|ADE服务器类型参考]] ）&lt;br /&gt;
&lt;br /&gt;
变量&amp;lt;tt&amp;gt;adeEngine&amp;lt;/tt&amp;gt;包含我们的进程内对象 [[CAEngine/zh|CAEngine]]。如果我们想使用ADE的本地（进程外）服务器版本，我们可以将一个项目参考添加到'''Analytica Decision Engine Server 4.6 COM''' 组件并将顶部行从&amp;lt;tt&amp;gt;Imports ADEW&amp;lt;/tt&amp;gt;改成&amp;lt;tt&amp;gt;Imports ADE&amp;lt;/tt&amp;gt;即可。 &lt;br /&gt;
&lt;br /&gt;
这里是另一种获得一个先[[CAEngine/zh|CAEngine]]对象的方法。此循序不需要给项目添加参考。&amp;lt;tt&amp;gt;&lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADEW4.6.CAEngine&amp;quot;) ’ in-process &lt;br /&gt;
:adeEngine = CreateObject(&amp;quot;ADE4.6.CAEngine&amp;quot;) ’ out-of-process &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果想理解使用进程内和进程外（或本地）服务器的利与弊，以及哪一种自动化服务器用于不同的场景，参考[[Using_the_Analytica_Decision_Engine_Server#In-process_vs_Out-of-process/zh | In-process vs. out-of-process]]&lt;br /&gt;
&lt;br /&gt;
===COM和 Automation 接口比较===&lt;br /&gt;
在上面的例子当中，我们使用COM接口调用ADE。在一个COM 接口中，对象 在本例中为 [[CAEngine/zh|CAEngine]] 被声明为[[CAEngine/zh|CAEngine]] ，编译器解决每一个成员函数，并且在编译时间内能探测几个明显的错误。另外，Visual Studio可以提供方法和参数类型列表当，在你编程的时候可以当做一个提示工具，在编写使用ADE程序是非常有用。COM调用比Automation调用要快一点，但是在ADE应用程序中速度差异通常不是很重要。对于ADE 4.6我们推荐使用COM结构，只要你的语言支持。&lt;br /&gt;
&lt;br /&gt;
在VB Automation中，你可以将一个对象简单声明为Object（对象），而不是像 [[CAEngine/zh|CAEngine]]、[[CAObject/zh|CAObject]]等更加具体的类型。当使用Automation调用'''ADE'''方法时，在运行时间内确定方法。在编译时间内，编译器不知道你的 '''ADE''' 对象是否有一个名称为[[CAEngine::OpenModel/zh|OpenModel]]的函数。在VB中，调用COM方法或Automation 方法的语法是相通的——唯一的不同在于对象类型是否明确被声明。&lt;br /&gt;
&lt;br /&gt;
在VC++和C#中，调用COM的语法和调用Automatio的语法不同。在这些情况下，COM要方便的多，Automation能够获得相冗余。然而，同样的语言，包括VBScript和其他脚本语言，只支持Automation不支持COM。&lt;br /&gt;
&lt;br /&gt;
===监视Process（进程）===&lt;br /&gt;
当使用进程外ADE服务器时，你的代码必须在终止时释放[[CAEngine/zh|CAEngine]]COM对象。当最终[[CAEngine/zh|CAEngine]]使用被释放是，ADE.exe 进程自动终止。到目前为止所看到的代码，VB语言在达到程序末端时，自动处理释放对象。但是，当你调试你的代码是，你可以提前终止你的程序来修复bug，你的程序可能被Task Manager（任务管理器）终止，或者你自己的代码也可能奔溃，导致你的程序进程在它有机会释放对象之前终止。应为COM对象从来不会被释放，ADE.exe进程不知道它是否在使用中，你可能获得ADE.exe 僵尸进程。 &lt;br /&gt;
&lt;br /&gt;
为了避免这种情况发生，一种好的习惯就是在调用[[CAEngine/zh|CAEngine]]实例后 立即调用[[CAEngine::MonitorProcess/zh|CAEngine::MonitorProcess]]。通过这种方式，ADE能够得知哪一个进程正在使用它，同时将设置一个线程去探测你的进程是否在ADE被完全释放前终止。如果你的程序进程没有终止，ADE进程会立即将它关闭，消除了僵尸ADE进程的堆积。 &lt;br /&gt;
&lt;br /&gt;
要从一个.NET应用程序获得进程ID，使用System.Diagnostics.Process namespace中的'''GetCurrentProcess().Id''' 。在其他语言中，你可以使用Windows SDK 的'''GetProcessId( )'''函数。 &lt;br /&gt;
&lt;br /&gt;
'''[[CAEngine::MonitorProcess/zh|MonitorProcess]]()''' 只能用来监视运行ADE进程的同一台计算机的进程，一次当通过DCOM运行ADE时不能使用。当使用进程内ADEW服务器时没有必要使用。&lt;br /&gt;
&lt;br /&gt;
==打开使用ADE的模型==&lt;br /&gt;
我们现在打开&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;模型，显示我们的应用程序主窗口。使用以下调用：tt&amp;gt;&lt;br /&gt;
:theModelString = adeEngine.[[CAEngine::OpenModel/zh|OpenModel]](theModel) &lt;br /&gt;
:frmMain.DefInstance.Show &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
使用[[CAEngine/zh|CAEngine]]的[[CAEngine::OpenModel/zh|OpenModel]]函数打开模型。如果成功的话，变量&amp;lt;tt&amp;gt;theModelString&amp;lt;/tt&amp;gt;将包含模型的名字。否则，将包含一个空的串。虽然由于为了简介的缘故，我们没有这样做，但是你应该检查从[[CAEngine::OpenModel/zh|OpenModel]]函数返回的是不是一个空的串。如果是，说明在你打开的模型中存在一个错误。你可以使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/z |ErrorText]]属性找出是哪种错误 （&amp;lt;tt&amp;gt;adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] 和adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]&amp;lt;/tt&amp;gt;）。&lt;br /&gt;
&lt;br /&gt;
==从Analytica模型中检索对象==&lt;br /&gt;
下一步就是从我们的模型中检索对象（变量、模块、函数等），以便我们能获取他们的属性（[[definition | 定义]]、[[title | 名称]]、[[class | 类型]]等等 ）。我们的示例模型（&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt;）操作&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;和&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;对象。尤其是，修改&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;可以查看这是如何影响&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt; 对象。&lt;br /&gt;
&lt;br /&gt;
我们的&amp;lt;tt&amp;gt;TxcTest.vbproj&amp;lt;/tt&amp;gt; （&amp;lt;tt&amp;gt;TxcText.sln&amp;lt;/tt&amp;gt;）项目中的&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;文件里的 '''PrintAttributes''' 函数演示了如何检索对象。该函数首先被&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''Form_Load''' 函数调用，当应用程序启动后，可以显示'''Cost'''表格。当然无论什么时候，只要我们想输出'''Cost'''表格的当前值，都可以调用。该函数如下所示：&lt;br /&gt;
:Public Sub PrintAttributes(ByRef inputIdentifier As String, ByRef  outputIdentifier As String) &lt;br /&gt;
::Dim inputObject, outputObject As [[CAObject/zh | CAObject]]&lt;br /&gt;
::Dim resultTable As [[CATable/zh | CATable]]&lt;br /&gt;
::Dim definitionAttrInput As String &lt;br /&gt;
::inputObject = adeEngine.[[CAEngine::GetObjectByName/zh | GetObjectByName]](inputIdentifier) &lt;br /&gt;
::outputObject = adeEngine.[[CAEngine::GetObjectByName/zh | GetObjectByName]](outputIdentifier) &lt;br /&gt;
::definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;definition&amp;quot;) &lt;br /&gt;
::resultTable = outputObject.[[CAObject::ResultTable/zh | ResultTable]]&lt;br /&gt;
::Call PrintResultTable(resultTable, inputIdentifier, definitionAttrInput, outputIdentifier) &lt;br /&gt;
::ReleaseComObject(resultTable) &lt;br /&gt;
::ReleaseComObject(inputObject) &lt;br /&gt;
::ReleaseComObject(outputObject) &lt;br /&gt;
:End Sub &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''PrintAttributes'''和作为'''inputIdentifier'''参数的&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;变量标识符以及作为'''outputIdentifier'''参数的'''Cost'''变量一起使用。如下所示通过使用[[CAEngine/zh | CAEngine]]的[[CAEngine::GetObjectByName/zh | GetObjectByName]]函数提取相应对象：&amp;lt;tt&amp;gt;&lt;br /&gt;
:inputObject = adeEngine.[[CAEngine::GetObjectByName/zh | GetObjectByName]](inputIdentifier) &lt;br /&gt;
:outputObject = adeEngine.[[CAEngine::GetObjectByName/zh | GetObjectByName]](outputIdentifier)&amp;lt;/tt&amp;gt; &lt;br /&gt;
&lt;br /&gt;
如果函数[[CAEngine::GetObjectByName/zh | GetObjectByName]]提取成功，将返回一个[[CAObject/zh | CAObject]]类型对象。如果使用'''[[CAObject/zh | CAObject]]'''的函数，参考[[CAObject/zh |  SendCommand(command)]]，可以获得一个[[CAObject/zh | CAObject]]的完整函数列表。如果函数[[CAEngine::GetObjectByName/zh | GetObjectByName]]提取失败，返回值为&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;。代码应该检查以确保[[CAEngine::GetObjectByName/zh | GetObjectByName]]提取的结果是有效的。如果找不到，可使用[[CAEngine/zh | CAEngine]]的 [[CAEngine::ErrorCode/zh | ErrorCode]]和 [[CAEngine::ErrorText/zh | ErrorText]]属性获取错误信息。例如：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Set inputObject = adeEngine.[[CAEngine::GetObjectByName/zh | GetObjectByName]](inputIdentifier) &lt;br /&gt;
:If inputObject Is Nothing Then &lt;br /&gt;
::MsgBox(“This error from GetObjectByName occurred: “&amp;amp; _ vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorCode/zh | ErrorCode]] &amp;amp; “:” &amp;amp; adeEngine.[[CAEngine::ErrorText/zh | ErrorText]]) &lt;br /&gt;
:Else &lt;br /&gt;
::'inputObject valid &lt;br /&gt;
:End If&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===获取对象属性===&lt;br /&gt;
每一个Analytica对象都有一组属性，例如[[identifier | 标识符]]、[[title | 名称]]、[[description |  描述]]和[[class | 类型]]。你可以使用[[CAObject::GetAttribute/zh | GetAttribute]]函数来获去Analytica对象的属性。例如，如要获取'''inputObject'''的定义（当前为cost）：&amp;lt;tt&amp;gt;&lt;br /&gt;
:definitionAttrInput = inputObject.[[CAObject::GetAttribute/zh | GetAttribute]](&amp;quot;[[Definition | 定义]]&amp;quot;) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在模型&amp;lt;tt&amp;gt;Txc.ana&amp;lt;/tt&amp;gt; 中，&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;的定义为&amp;quot;&amp;lt;tt&amp;gt;[[Normal]](30M, 3M)&amp;lt;/tt&amp;gt;&amp;quot; ，我们将它储存在'''definitionAttrInput'''当中。.&lt;br /&gt;
&lt;br /&gt;
===计算对象和检索结果===&lt;br /&gt;
使用[[CAObject/zh | CAObject]]的[[CAObject::Result/zh | Result]]或[[CAObject::ResultTable/zh | ResultTable]]方法来获取变量的值。如果有必要的话，ADE先自动计算变量。如果你确定结果为基元（只有一个元素），使用[[CAObject::Result/zh | Result]]方法。否则使用[[CAObject::ResultTable/zh | ResultTable]]，检索结果为一个''数组''。基元结果当作一个特殊数组案例来处理，没有维度的数组。如果值为基元[[CATable::AtomicValue/zh | AtomicValue]]方法将返回一个数字或者字符串单一值。 &lt;br /&gt;
&lt;br /&gt;
默认情况下，[[CAObject::Result/zh | Result]]和[[CAObject::ResultTable/zh | ResultTable]]返回结果的中值，也就是说，ADE以确定性方式计算结果。对于一个概率值，将[[CAObject/zh | CAObject]]的[[CAObject::ResultType/zh | ResultType]]属性设置为想要的不确定性视图——Mean（平均值） Sample（样本）、PDF（概率密度函数）、CDF（累计分布函数）、Confidence bands（置信带）、或者Statistics（统计数据）详情请参考[[CAObject::ResultType/zh | ResultType]]。我们通过如下的方式获取outputObject 输出对象 的值：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable = outputObject.[[CAObject::ResultTable/zh |ResultTable]] &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
结果为一个[[CATable/zh | CATable]]对象，允许我们访问一个表格中的单个元素。 &lt;br /&gt;
&lt;br /&gt;
如果你通过调用[[CAObject::Result/zh | Result]]来获取一个数组（或者表格）的值，将返回数组为一个字符串，列出索引和元素，以逗号隔开。通常使用[[CAObject::ResultTable/zh | ResultTable]]更加简单，这样你没有必要从字符串中解析表格的元素。&lt;br /&gt;
&lt;br /&gt;
===获取表格索引元素===&lt;br /&gt;
一个Analytica表格包含0个或者多个索引。如果包含一个索引，那么该表格是1维表格；如果有2个索引，说他是2维表格，依此类推。0维度表格包含一个“单一基元”（或标量）值。你可以使用CATable的[[CATable::NumDims/zh | NumDims]]获取表格的维数（也就是索引数）。要想获取表格的单个索引，可使用[[CATable/zh | CATable]]的 [[CATable::IndexNames/zh | IndexNames]]和 [[CATable::GetIndexObject/zh | GetIndexObject]]函数。 &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;frmMain.frm&amp;lt;/tt&amp;gt;中的'''PrintResultTable'''函数说明了这两个函数的使用。从'''PrintAttributes'''中调用'''PrintResultTable'''，执行打印'''TestTxc'''中的表格的实际工作（为了简洁起见，我们只给出了关联ADE的该函数部分）。&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:Public Sub PrintResultTable(ByRef resultTable As CATable, ByRef inputIdentifier As String, ByRef definitionAttrInput As String, ByRef outputIdentifier As String) &lt;br /&gt;
::Dim theIndexName, theTableName As String &lt;br /&gt;
::Dim theIndexElement As String &lt;br /&gt;
::Dim theTableElement &lt;br /&gt;
::Dim theIndexObj As [[CAIndex/zh | CAIndex]]&lt;br /&gt;
::Dim numEls As Integer &lt;br /&gt;
::Dim spaces, i As Integer &lt;br /&gt;
::Dim lenStr As Short &lt;br /&gt;
::Dim OutputStr As Short &lt;br /&gt;
::Dim spaceString, underlineString As String &lt;br /&gt;
::... &lt;br /&gt;
::theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1) &lt;br /&gt;
::theTableName = resultTable.[[CATable::Name/zh|Name]] &lt;br /&gt;
::theIndexObj = resultTable.[[CATable::GetIndexObject/zh | GetIndexObject]](theIndexName) &lt;br /&gt;
::numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
::... &lt;br /&gt;
::For i = 1 To numEls &lt;br /&gt;
:::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
:::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
:::... &lt;br /&gt;
::Next i &lt;br /&gt;
::InformationPane.Text = outputString &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
通过'''PrintResultTable'''获取一个表格的索引方法如下：&lt;br /&gt;
&amp;lt;tt&amp;gt;&lt;br /&gt;
:theIndexName = resultTable.[[CATable::IndexNames/zh|IndexNames]](1)&lt;br /&gt;
:theIndexObj = resultTable.[[CATable::GetIndexObject/zh|GetIndexObject]](theIndexName)&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
我们通过使用[[CATable/zh|CATable]]的[[CATable::IndexNames/zh|IndexNames]]函数获取第一个索引的名字。我们将它传递给[[CATable/zh|CATable]]的[[CATable::GetIndexObject/zh|GetIndexObject]]函数以获取表示我们的索引的[[CAIndex/zh|CAIndex]]。该自动化对象返回其相应索引的相关信息。如果此函数调用失败，将返回&amp;lt;tt&amp;gt;Nothing&amp;lt;/tt&amp;gt;信息。在此情况下，使用[[CAEngine/zh|CAEngine]]的[[CAEngine::ErrorCode/zh|ErrorCode]]和[[CAEngine::ErrorText/zh|ErrorText]] 函数找出原因。&lt;br /&gt;
&lt;br /&gt;
==从CATable和CAIndex中获取信息==&lt;br /&gt;
[[PrintResultTable]]说明了如何从[[CATable/zh| CATable]]和[[CAIndex/zh|CAIndex]] 对象获取信息。该代码获取'''Cost'''表格的索引和表格元素：&lt;br /&gt;
: &amp;lt;tt&amp;gt;&lt;br /&gt;
:numEls = theIndexObj.[[CAIndex::IndexElements/zh|IndexElements]] &lt;br /&gt;
:For i = 1 To numEls &lt;br /&gt;
::theIndexElement = theIndexObj.[[CAIndex::GetValueByNumber/zh|GetValueByNumber]](i) &lt;br /&gt;
::theTableElement = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](i) &lt;br /&gt;
::... &lt;br /&gt;
:Next i &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[CAIndex/zh|CAIndex]]的[[CAIndex::IndexElements/zh|IndexElements]]属性返回第一个索引中的元素个数。[[CAIndex/zh|CAIndex]]的[[CAIndex::GetValueByNumber/zh|GetValueByNumber]]函数获取单个索引元素。 &lt;br /&gt;
&lt;br /&gt;
我们通过传递表格中元素的坐标，使用  [[CATable/zh|CATable]]的[[CATable::GetDataByElements/zh|GetDataByElements]]函数获取'''Cost'''表格对象的单个表格元素'''resultTable'''。 &lt;br /&gt;
&lt;br /&gt;
当我检索 [[CATable/zh|CATable]]对象中单个元素（'''resultTable'''）的时候，我们利用了该表格是一维的事实。因此，我们只需要传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个单一数（这个数代表表格中的位置）。但是，如果我们处理两个或者更多维度，我们必须传递给[[CATable::GetDataByElements/zh|GetDataByElements]]一个数组函数，并且指明我们要检索的表格元素的位置。因此，如果我们不想检索一个二维数组的position (4,3)位置的元素，我们可以这样写：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Dim W as Variant 'return element &lt;br /&gt;
:Dim IndexPtrs(1 To 2) As Variant 'position in table &lt;br /&gt;
::... &lt;br /&gt;
:IndexPtrs(1) = 4 &lt;br /&gt;
:IndexPtrs(2) = 3 &lt;br /&gt;
:W = resultTable.[[CATable::GetDataByElements/zh|GetDataByElements]](IndexPtrs) &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==控制基元值格式==&lt;br /&gt;
[[CATable/zh|CATable]]中的每个基元值可以是一个数、一个字符串，或者其它一些基本类型（''例如''：[[Null|空值]]、[[Undefined|未定义]]、[[Reference|参考]]，或 [[Handle|句柄]]。通过说明类型和值，它们作为''变体''被返回，这是一种Visual Basic能读懂的数据结构。[[CATable/zh|CATable]]的[[CATable::RenderingStyle|RenderingStyle]]属性控制Analytica基础值是如何映射到Visual Basic变体的。 &lt;br /&gt;
&lt;br /&gt;
例如：可以通过使用Analytica 模型的数字格式设置将一个数值返回成一个数字或者字符串。如果被指定格式，有一个选线控制是截断数字的位数，还是精确返回。 &lt;br /&gt;
&lt;br /&gt;
子程序[[PrintResultTable/zh|PrintResultTable]]在&amp;lt;tt&amp;gt;frmMain.vb&amp;lt;/tt&amp;gt;中载入,其渲染风格直接指明：&amp;lt;tt&amp;gt;&lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::NumberAsText/zh|NumberAsText]] = True &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::FullPrecision/zh|FullPrecision]] = False &lt;br /&gt;
:resultTable.[[CATable::RenderingStyle|RenderingStyle]].[[CARenderingStyle::StringQuotes/zh|StringQuotes]] = 2 &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
第一行指明数值应该根据与结果对象有关的数字格式被格式化为文本。例如在其程序输出中，我们将看到&amp;lt;tt&amp;gt;30.103M&amp;lt;/tt&amp;gt;，而非&amp;lt;tt&amp;gt;30102995.6639812&amp;lt;/tt&amp;gt;，如果我们让Visual Basic将数值串联我们的结果字符串，将显示该结果。在此事件中，一个值为字符串的单元格出现在结果中，返回值将明确带双引号。对于[[CARenderingStyle/zh|CARenderingStyle]]对象中的所有可用属性，请参考[[CARenderingStyle/zh|CARenderingStyle]]。&lt;br /&gt;
&lt;br /&gt;
===其它访问表格的方式===&lt;br /&gt;
有几种访问多维表格[[CATable/zh|CATable]]中元素的方式。每一种都有可能在特定的场合使用起来比较方便。 &lt;br /&gt;
&lt;br /&gt;
第一种方式就是使用[[CATable/zh | CATable]]的 [[CATable::GetDataByElements/zh|GetDataByElements]]或[[CATable::GetDataByLabels/zh|GetDataByLabels]]方法，上面代码示例中有显示。在此情况下，利用你想获取的基元值的单元格位置。 &lt;br /&gt;
&lt;br /&gt;
第二种方式就是使用[[CATable/zh|CATable]][[CATable::Slice/zh|Slice]]或[[CATable::Subscript/zh | Subscript]]方法获取一个少一个维度的新[[CATable/zh|CATable]]对象。通过重复减少维度，最终将获得0维度，这时你将获得一个单一基元值。此时，[[CATable/zh|CATable]]的[[CATable::AtomicValue/zh|AtomicValue]]方法返回该值 。[[CATable::AtomicValue/zh|AtomicValue]]方法是唯一获取一个标值的方法（因为没有坐标位置）。如果你需要建立完整结果其中一个切片的图形图像，必须使用此方法。 &lt;br /&gt;
&lt;br /&gt;
第三种方式就是使用[[CATable/zh|CATable]]的[[CATable::GetSafeArray/zh|GetSafeArray]]方法，将多维数组转化成一个''安全数组''（或者一个.NET数组）。你可以在使用VB或者其它.NET语言直接处理多维数组。因为对于Analytica维度没有固定顺序，但是安全数组和.NET数组有一个明确的顺序，你必须先使用[[CATable/zh|CATable]]对象的[[CATable::SetIndexOrder/zh|SetIndexOrder]]方法在调用[[CATable::GetSafeArray/zh|GetSafeArray]]之前指明维度的顺序。注意如果你知道你的数组是一维的，那就没必要了。&lt;br /&gt;
&lt;br /&gt;
===修改对象===&lt;br /&gt;
一个自定义用户程序通常从一个用户或者其它外部源获取输入，以便转化成Analytica模型中的输入变量。你可以设定输入变量的定义或者通过使用定义表格来这样做。 &lt;br /&gt;
&lt;br /&gt;
'''TestTxc''' 说明了如何修改'''Pop_exp'''定义，此模型是一个影响结果变量Cost的模型输入。要想在该示例中设定该定义，从主菜单上选择'''File &amp;gt; Change Population'''。将出现一个对话框，如下图所示：&lt;br /&gt;
&lt;br /&gt;
[[File:RedefiningtheVariableDefinition.jpg|400px/zh|文件：RedefiningtheVariableDefinition.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
在信息栏中输入一个新定义并点击'''Ok'''确认。主窗口将显示一个新的Cost值。当点击该对话框中的'''Ok'''按钮时，调用了&amp;lt;tt&amp;gt;ChangeDef.frm&amp;lt;/tt&amp;gt;函数，然后调用[[PrintAttributes/zh|PrintAttributes]]函数打印&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果。&lt;br /&gt;
&lt;br /&gt;
此函数类似于：&amp;lt;tt&amp;gt;&lt;br /&gt;
:Private Sub OkButton_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles OkButton.Click &lt;br /&gt;
::Dim errorText As String&lt;br /&gt;
::Dim pop_exp_Object As [[CAObject/zh|CAObject]] &lt;br /&gt;
::Dim errorCode As Short &lt;br /&gt;
::Dim errorString As String &lt;br /&gt;
::newDefinition = PopExposedDef.Text &lt;br /&gt;
::pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
::pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]](&amp;quot;[[Definition]]&amp;quot;, newDefinition) &lt;br /&gt;
::errorCode = adeEngine.[[CAEngine::ErrorCode/zh|ErrorCode]] &lt;br /&gt;
::If errorCode &amp;lt;&amp;gt; 0 Then &lt;br /&gt;
:::MsgBox(&amp;quot;This error occurred while processing your definition: &amp;quot; &amp;amp; vbCrLf &amp;amp; vbCrLf &amp;amp; adeEngine.[[CAEngine::ErrorText/zh|ErrorText]]) :::PopExposedDef.Focus()&lt;br /&gt;
::Else&lt;br /&gt;
:::Me.Close() &lt;br /&gt;
:::frmMain.DefInstance.PrintAttributes(&amp;quot;Pop_exp&amp;quot;, &amp;quot;Cost&amp;quot;) &lt;br /&gt;
::End If &lt;br /&gt;
::ReleaseComObject(pop_exp_Object) &lt;br /&gt;
:End Sub&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
该函数抓取了输入到'''New Definition''' 新定义给'''Population Exposed'''栏，并通过使用[[CAObject/zh|CAObject]]对象中的[[CAObject::SetAttribute/zh|SetAttribute]]函数将它设置给&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;对象。然后调用[[PrintAttributes/zh|PrintAttributes]]，以计算&amp;lt;tt&amp;gt;Cost object&amp;lt;/tt&amp;gt;，并打印新的结果。要想给变量&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;设定一个新定义，我们可以为&amp;lt;tt&amp;gt;Pop_exp&amp;lt;/tt&amp;gt;获取[[CAObject/zh|CAObject]]对象，然后将其定义设置成用户输入的定义。通过使用下面的代码来实现：&lt;br /&gt;
:pop_exp_Object = adeEngine.[[CAEngine::GetObjectByName/zh|GetObjectByName]](&amp;quot;pop_exp&amp;quot;) &lt;br /&gt;
:pop_exp_Object.[[CAObject::SetAttribute/zh|SetAttribute]]( &amp;quot;[[Definition]]&amp;quot;, newDefinition )&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
无论什么时候调用[[CAObject::SetAttribute/zh|SetAttribute]]，都应该检查[[CAEngine/zh|CAEngine]]自动化对象（'''adeEngine'''）的[[CAEngine::ErrorCode/zh|ErrorCode]]，以免它的定义是非法的。尝试一下输入一个新定义，比如&amp;lt;code&amp;gt;[[Uniform]](25M,35M)&amp;lt;/code&amp;gt;，然后点击'''Ok'''。当&amp;lt;tt&amp;gt;pop_exp&amp;lt;/tt&amp;gt;的定义被改变时， &amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;的结果由ADE重新计算，此时'''ResultTable'''接下来调用给Cost变量（在应用程序窗口重新显示时）。&lt;br /&gt;
&lt;br /&gt;
使用ADE绘图&lt;br /&gt;
&lt;br /&gt;
通过Analytica 4.6使用相同的绘图引擎，你可以建立一个图表或者图形以显示一个数组值或者不确定值结果。在ADE4.6中，你可以使用 [[CATable/zh|CATable]]的[[CATable::GraphToFile/zh|GraphToFile]]和[[CATable::GraphToStream/zh|GraphToStream]]方法。图形可以以几种可能的图像格式返回，例如'''image/png'''、 '''image/bmp'''或者 '''image/jpeg'''。 &lt;br /&gt;
&lt;br /&gt;
从可用图形选项中选择的最简单方式就是使用Analytica打开你的模型。你可以实验设置各种默认设置或者替代选择的变量，看它们是如何工作的。但你选择了你想设置的选项，保存模型。当为每一个生成结果图形时，ADE将使用这些设置。 &lt;br /&gt;
&lt;br /&gt;
对于更高维度的结果，可能需要做一些必要工作，以便选择将绘制结果的切片和具体的轴（也就是相对于图例哪个维度作为X轴）。[[CATable/zh|CATable]]的[[CATable::Subscript/zh|Subscript]]或[[CATable::Slice/zh|Slice]]方法可以用来控制轴选择特殊的切片用来绘制，能够用来控制轴。详情请参考[[CATable/zh|CATable]]。在我们的&amp;lt;tt&amp;gt;Tutorial.NET&amp;lt;/tt&amp;gt;示例中，我们有一个一维结果（&amp;lt;tt&amp;gt;Cost&amp;lt;/tt&amp;gt;），因此我们没有必要担心截取或者绕轴旋转。 &lt;br /&gt;
&lt;br /&gt;
[[CATable::GraphToStream/zh|GraphToStream]]方法被用来从ADE中直接转化图形图形到一个用户界面中。使用[[CATable::GraphToStream/zh|GraphToStream]]比起使用[[CATable::GraphToFile/zh|GraphToFile]]来要稍微复杂一点，因为[[CATable::GraphToFile/zh|GraphToFile]]除了需要文件名以外还需要其它一些信息，以便编写图形。要使用[[CATable::GraphToStream/zh|GraphToStream]]，我们必须在内存内设置一个流，允许ADE写入该留，然后从该留重建。因为.NET流和COM流不兼容，你必须使用ADE一同提供的[[StreamConnector]]类型.&amp;lt;tt&amp;gt;frmMain&amp;lt;/tt&amp;gt; 中的'''GraphResult_Click'''子程序演示了[[CATable::GraphToStream/zh|GraphToStream]]的使用。从主应用程序窗口选择 '''Graph Result'''菜单选项，结果将出现在一个如下所示的图形当中：&lt;br /&gt;
&lt;br /&gt;
[[File:resultgraph.jpg/zh|文件：resultgraph.jpg]]&lt;br /&gt;
&lt;br /&gt;
==结论==&lt;br /&gt;
&lt;br /&gt;
在此教程中，我们介绍了Analytica决策引擎的几个重要方面。我们看到了如何建立一个ADE服务器对象，使用ADE打开模型，获取模型中的单个对象、计算对象、获取表格中的元素，以及修改模型中的对象。但是ADE可以做的远不止这些。 &lt;br /&gt;
&lt;br /&gt;
我们希望你已经足够了解其基本特征，这样你现在才能独自开始探索更多新的高级特征。我们建议你现在开始阅读字教程的剩余部分以了解ADE能做什么。&lt;br /&gt;
&lt;br /&gt;
== 另请参考 ==&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;margin: 1em auto 1em auto;width: 100%;border:0;table-layout: fixed;&amp;quot; cellpadding=5&lt;br /&gt;
|- style=&amp;quot;text-align: center&amp;quot;&lt;br /&gt;
| [[Installation of ADE/zh|ADE 安装]] &amp;lt;- ||  [[The ADE Tutorial/zh|ADE 入门教程]] || -&amp;gt; [[Using the ADE Server/zh|使用ADE服务器]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jhuawen</name></author>
	</entry>
</feed>