使用 ERPConnect 服务将 SAP 业务数据集成到 SharePoint 2010





5.00/5 (2投票s)
本文档描述了如何轻松地将 SAP 业务数据集成到 SharePoint 2010 应用程序中。
引言
SharePoint 2010 通过业务连接服务 (BCS) 为开发人员提供了将 SAP 业务数据等外部数据源集成到 SharePoint 系统的能力。BCS 的概念基于实体和关联的立体化操作。这非常适合像 SAP 表这样扁平且结构简单的数据库。
在 SharePoint 中使用 SAP 数据的另一种更灵活的选择是使用 ERPConnect Services for SharePoint 2010 (ECS)。该产品套件包含三个组件:ERPConnect Services 运行时、BCS 连接器应用程序和 Xtract PPS for PerformancePoint Services。运行时提供了一个服务应用程序,该应用程序与 SharePoint 2010 的新服务架构集成。运行时提供了一个安全的中介层,用于将各种 SAP 对象(如表和函数模块)集成到您的 SharePoint 应用程序中。
BCS 连接器应用程序允许开发人员在没有编程知识的情况下创建 BCS 服务的 BDC 模型。您可以将 BCS 连接器创建的 BDC 模型导出到 Visual Studio 2010 进行进一步定制。Xtract PPS 组件为 SharePoint 2010 的 PerformancePoint Services 提供了 SAP 数据源提供程序。本文档概述了 ERPConnect Services 运行时,并展示了如何创建和整合来自 SAP 的业务数据到不同的 SharePoint 应用程序类型中,例如 Web 部件、应用程序页面或 Silverlight 模块。本文档不介绍其他组件。
背景
本节将简要解释和介绍 ERPConnect Services 中可用的 SAP 对象。最重要的对象是 SAP 表和函数模块。函数模块基本上类似于传统编程语言中的普通过程。函数模块是用 ABAP(SAP 编程语言)编写的,并且可以被 SAP 系统内的任何其他程序访问。它们接受导入和导出参数以及其他类型的特殊参数。此外,BAPI(Business-API)是特殊函数模块,它们组织在 SAP 业务对象存储库中。为了在运行时使用函数模块,它们必须被标记为远程 (RFC)。也可以检索 SAP 表数据。SAP 中的表基本上是关系数据库表。其他 SAP 对象,如 BW Cube 或 SAP Query,可以通过 XtractQL 查询语言(见下文)访问。
安装与配置
在 SharePoint 2010 服务器上安装 ERPConnect Services 通过安装程序完成,非常简单。SharePoint 管理服务必须在本地服务器上运行(请参阅 Windows 服务)。更多信息请参阅产品文档。安装成功后,请导航到 SharePoint 的中央管理 (CA) 中的服务应用程序屏幕。
在创建第一个服务应用程序之前,必须创建一个安全存储,ERPConnect Services 将在此存储 SAP 用户凭据。在“安全存储服务”的设置页面中,创建一个新的目标应用程序,并将其命名为“ERPConnect Services”。单击“下一步”按钮,定义存储字段如下:
通过单击“下一步”完成创建过程,并定义应用程序管理员。然后,选择该应用程序,单击“设置凭据”并输入 SAP 用户凭据。
让我们继续创建新的 ERPConnect 服务应用程序!
在服务应用程序页面的“新建”菜单中,单击“ERPConnect 服务应用程序”链接(另请参阅上面的第一个屏幕截图)。这将打开一个对话框,用于定义服务应用程序的名称、SAP 连接数据和 IIS 应用程序池。
输入所有数据后,单击“创建”,您将在服务应用程序屏幕中看到以下条目:
搞定!您现在已经完成了第一个 ERPConnect 服务应用程序的设置。
开发
运行时功能涵盖不同的编程需求,例如通用可检索的接口函数。服务应用程序由 SharePoint 的中央管理进行管理。提供以下服务和功能区域:
- 直接从 SAP 表执行和检索数据
- 执行 SAP 函数模块/BAPI
- 执行 XtractQL 查询语句
接下来的章节将展示如何使用这些服务和功能区域,并通过 ERPConnect Services 从自定义 SharePoint 应用程序中访问不同的 SAP 对象。运行时可以在 SharePoint 上下文的应用程序中使用,例如 Web 部件或应用程序页面。为此,您需要在项目中引用程序集。在访问 SAP 系统中的数据之前,您必须创建一个 ERPConnectServiceClient
类的实例。这是所有 SAP 对象和运行时通用 API 的入口。在 SharePoint 上下文中,有两种选项可以创建客户端对象实例:
// Option #1
ERPConnectServiceClient client = new ERPConnectServiceClient();
// Option #2
ERPConnectServiceApplicationProxy proxy = SPServiceContext.Current.GetDefaultProxy(
typeof(ERPConnectServiceApplicationProxy)) as ERPConnectServiceApplicationProxy;
ERPConnectServiceClient client = proxy.GetClient();
有关在 Silverlight 或桌面应用程序中使用 ECS 的更多详细信息,请参阅下面的具体章节。
查询表
查询和检索表数据是开发人员的常见任务。运行时允许直接从 SAP 表检索数据。ERPConnectServiceClient
类提供了一个名为 ExecuteTableQuery
的方法,该方法有两个重载,可以以简单的方式查询 SAP 表。该方法还支持传递杂项参数,如行数和跳过数、自定义函数、WHERE 子句定义和返回字段列表。这些参数可以使用 ExecuteTableQuerySettings
类实例进行定义。
DataTable dt = client.ExecuteTableQuery("T001");
…
ExecuteTableQuerySettings settings = new ExecuteTableQuerySettings {
RowCount = 100,
WhereClause = "ORT01 = 'Paris' AND LAND1 = 'FR'",
Fields = new ERPCollection<string> { "BUKRS", "BUTXT", "ORT01", "LAND1" }
};
DataTable dt = client.ExecuteTableQuery("T001", settings);
…
// Sample 2
DataTable dt = client.ExecuteTableQuery("MAKT",
new ExecuteTableQuerySettings {
RowCount = 10,
WhereClause = "MATNR = '60-100C'",
OrderClause = "SPRAS DESC"
});
第一个查询读取 SAP 表 T001 中 ORT01 等于 Paris 且 LAND1 等于 FR(法国)的所有记录。查询返回前 100 条记录,结果集仅包含 BUKRS、BUTXT、ORT01 和 LAND1 字段。第二个查询返回 SAP 表 MAKT 的前十条记录,其中 MATNR 字段等于物料号 60-100C。结果集按 SPRAS 字段排序。
执行函数模块
除了查询 SAP 表之外,运行时 API 还执行 SAP 函数模块 (BAPI)。函数模块必须在 SAP 中被标记为远程启用模块 (RFC)。ERPConnectServiceClient
类提供了一个名为 CreateFunction 的方法来创建函数模块的元数据结构。该方法返回一个 ERPFunction 数据结构的实例。此对象实例包含可用于函数模块的所有参数类型(导入、导出、更改和表)。
在下面的示例中,我们调用函数 SD_RFC_CUSTOMER_GET
,并为名为 NAME1
的导出参数传递一个名称模式 (T*)。然后,我们调用 ERPFunction
实例上的 Execute
方法。方法执行后,数据结构会更新。该函数在 CUSTOMER_T
表中返回所有客户。
ERPFunction function = client.CreateFunction("SD_RFC_CUSTOMER_GET");
function.Exports["NAME1"].ParamValue = "T*";
function.Execute();
foreach(ERPStructure row in function.Tables["CUSTOMER_T"])
Console.WriteLine(row["NAME1"] + ", " + row["ORT01"]);
以下代码显示了一个附加示例。在执行此函数模块之前,我们需要定义一个包含 HR 数据的表作为输入参数。所需的参数以及函数模块返回的值取决于函数模块的实现。
ERPFunction function = client.CreateFunction("BAPI_CATIMESHEETMGR_INSERT");
function.Exports["PROFILE"].ParamValue = "TEST";
function.Exports["TESTRUN"].ParamValue = "X";
ERPTable records = function.Tables["CATSRECORDS_IN"];
ERPStructure r1 = records.AddRow();
r1["EMPLOYEENUMBER"] = "100096";
r1["WORKDATE"] = "20110704";
r1["ABS_ATT_TYPE"] = "0001";
r1["CATSHOURS"] = (decimal)8.0;
r1["UNIT"] = "H";
function.Execute();
ERPTable ret = function.Tables["RETURN"];
foreach(var i in ret)
Console.WriteLine("{0} - {1}", i["TYPE"], i["MESSAGE"]);
执行 XtractQL 查询语句
ECS 运行时提供了一种名为 XtractQL 的 SAP 查询语言。XtractQL 查询语言,也称为 XQL,包含 ABAP 和 SQL 语法元素。XtractQL 允许查询 SAP 表、BW Cube、SAP Query 并执行函数模块。可以返回对象的元数据,并且可以使用 XQL 执行 MDX 语句。所有 XQL 查询都返回一个数据表对象作为结果集。在执行函数模块的情况下,调用者必须定义返回表(请参阅下面的示例 - INTO @RETVAL)。在需要处理动态语句的情况下,XQL 非常有用。以下列表显示了一些您可以在应用程序中使用的查询示例:
SELECT TOP 5 * FROM T001W WHERE FABKL = 'US'
此查询选择 SAP 表 T001W 中 FABKL 字段等于值 US 的前 5 条记录。
SELECT * FROM MARA WITH-OPTIONS(CUSTOMFUNCTIONNAME = 'Z_XTRACT_IS_TABLE')
此查询使用自定义 SAP 函数模块 Z_XTRACT_IS_TABLE
选择 SAP 表 MARA 的所有记录和字段以检索数据。
SELECT MAKTX AS [ShortDesc], MANDT, SPRAS AS Language FROM MAKT
此查询选择 SAP 表 MAKT
的所有记录。结果集将包含三个字段,名为 ShortDesc
、MANDT
和 Language
。
EXECUTE FUNCTION 'SD_RFC_CUSTOMER_GET'
EXPORTS KUNNR='0000003340'
TABLES CUSTOMER_T INTO @RETVAL;
此查询执行 SAP 函数模块 SD_RFC_CUSTOMER_GET
,并以表 CUSTOMER_T
(定义为 @RETVAL
)作为结果返回。
DESCRIBE FUNCTION 'SD_RFC_CUSTOMER_GET' GET EXPORTS
此查询返回有关 SAP 函数模块导出参数的元数据。
SELECT TOP 30 LIPS-LFIMG, LIPS-MATNR, TEXT_LIKP_KUNNR AS CustomerID
FROM QUERY 'S|ZTHEO02|ZLIKP'
WHERE SP$00002 BT '0080011000'AND '0080011999'
此语句执行 SAP Query "S|ZTHEO02|ZLIKP"(名称包括工作区、用户组和查询名称)。如您所见,XtractQL 使用 ABAP 或 SAP 特定语法元素扩展了 SQL 语法。这样,您就可以使用 LIPS-MATNR 格式的字段和类似 SAP 的 WHERE 子句,例如“SP$00002 BT '0080011000'AND '0080011999'”。
ERPConnect Services 提供了一个小助手工具 XtractQL Explorer(见下图),用于了解查询语言并测试 XQL 查询。您可以独立于 SharePoint 使用此工具,但需要访问 SAP 系统。
要了解 XtractQL 语言语法的更多信息,请参阅产品手册。
Silverlight 和桌面应用程序
到目前为止,所有示例都使用 ERPConnectServices.Server.Common.dll 程序集作为项目引用,并且所有展示的代码片段都在 SharePoint 上下文中运行,例如 Web 部件。ERPConnect Services 还为 Silverlight 和桌面应用程序提供了客户端库:
ERPConnectServices.Client.dll 用于桌面应用程序
ERPConnectServices.Client.Silverlight.dll 用于 Silverlight 应用程序
您需要根据您正在实现的项目的类型来添加相应的引用。
在 Silverlight 中,实现和设计模式会稍微复杂一些,因为所有 Web 服务都将以异步方式调用。也不可能使用 DataTable
类,因为它没有为 Silverlight 实现。运行时提供了一个类似的类 ERPDataTable
,在这些情况下由 API 使用。用于 Silverlight 的 ERPConnectServiceClient
类提供了 ExecuteTableQueryAsync
方法和一个名为 ExecuteTableQueryCompleted
的事件作为回调委托。
public event EventHandler<ExecuteTableQueryCompletedEventArgs> ExecuteTableQueryCompleted;
public void ExecuteTableQueryAsync(string tableName)
public void ExecuteTableQueryAsync(string tableName, ExecuteTableQuerySettings settings)
以下代码示例展示了在 Silverlight 客户端中查询 SAP 表 T001 的简单过程。首先,使用 ERPConnectService.svc 的 URI 创建 ERPConnectServiceClient
的实例,然后定义一个委托来处理完成的回调。接下来,执行查询,其中 RowCount 设置为 10,以便结果集中只返回前 10 条记录。一旦返回结果,数据集将在回调方法中的 DataGrid 控件(见下图)中显示。
void OnGetTableDataButtonClick(object sender, RoutedEventArgs e)
{
ERPConnectServiceClient client = new ERPConnectServiceClient(
new Uri("http://<SERVERNAME>/_vti_bin/ERPConnectService.svc"));
client.ExecuteTableQueryCompleted += OnExecuteTableQueryCompleted;
client.ExecuteTableQueryAsync("T001",
new ExecuteTableQuerySettings { RowCount = 150 });
}
void OnExecuteTableQueryCompleted(object sender, ExecuteTableQueryCompletedEventArgs e)
{
if(e.Error != null)
MessageBox.Show(e.Error.Message);
else
{
e.Table.View.GroupDescriptions.Add(new PropertyGroupDescription("ORT01"));
TableGrid.ItemsSource = e.Table.View;
}
}
下图显示了 Silverlight 页面的 XAML。
最终结果可以在下面看到。
ECS Designer
ERPConnect Services 包含一个 Visual Studio 2010 插件 ECS Designer,它允许开发人员可视化地设计 SAP 接口。它的工作方式类似于我之前写过的 LINQ to SAP Designer,请参阅 CodeProject 上的文章:LINQ to SAP。
ECS Designer 不会在您安装产品后自动安装。您需要手动运行安装程序。安装程序会将一个新的项目项类型添加到 Visual Studio 2010 中,文件扩展名为 .ecs,并将其与设计器链接。添加 ECS 项目项后,所需的引用会自动添加。项目项保存后,设计器会生成用于与 ERPConnect Services 运行时集成的源代码。生成的上下文类包含表示已定义 SAP 对象的类和子类(见下图)。
在您首次访问 SAP 系统之前,系统会要求您输入连接数据。您也可以从 SharePoint 系统加载连接数据。设计器 GUI 如图所示(见下图)。
例如,上图显示了表对话框。在主设计器屏幕上单击“添加 (+)”按钮并在搜索对话框中搜索 SAP 表后,设计器会打开表对话框。在此对话框中,您可以更改生成的类的名称、类修饰符以及最终类应包含的所有必需属性(字段)。要预览您的选择,请按“预览”按钮。下一张截图显示了名为 EC1.Designer.cs 的文件中的自动生成的类。
使用生成的代码很简单。我们在此示例中使用的项目类型是标准的控制台应用程序,因此设计器引用了桌面应用程序的 ERPConnectServices.Client.dll。由于我们不在 SharePoint 上下文中,因此必须通过将此值传递到 ERPConnectServicesContext 类的构造函数来定义 SharePoint 系统的 URI。
设计器为表 MAKT
的上下文类生成了 MAKT
类和一个访问属性 MAKTList
。此属性 MAKTList
的类型为 ERPTableQuery<MAKT>
,这是一个 LINQ 可查询的数据类型。这意味着您可以使用 LINQ 语句来定义底层查询。内部,ERPTableQuery<T>
类型会将您的 LINQ 查询转换为对 ExecuteTableQuery
的调用。
就是这样!
高级技术
在某些情况下,您需要使用完全相同的 SAP 连接来调用一系列函数模块,以获得正确的结果。例如,以下代码:
ERPConnectServiceClient client = new ERPConnectServiceClient();
using(client.BeginConnectionScope())
{
ERPFunction f = client.CreateFunction("BAPI_GOODSMVT_CREATE");
ERPStructure s = f.Exports["GOODSMVT_HEADER"].ToStructure();
s["PSTNG_DATE"] = "20110609"; // Posting Date in the Document
s["PR_UNAME"] = "BAEURLE"; // UserName
s["HEADER_TXT"] = "XXX"; // HeaderText
s["DOC_DATE"] = "20110609"; // Document Date in Document
f.Exports["GOODSMVT_CODE"].ToStructure()["GM_CODE"] = "01";
ERPStructure r = f.Tables["GOODSMVT_ITEM"].AddRow();
r["PLANT"] = "1000"; // Plant
r["PO_NUMBER"] = "4500017210"; // Purchase Order Number
r["PO_ITEM"] = "010"; // Item Number of Purchasing Document
r["ENTRY_QNT"] = 1; // Quantity in Unit of Entry
r["MOVE_TYPE"] = "101"; // Movement Type
r["MVT_IND"] = "B"; // Movement Indicator
r["STGE_LOC"] = "0001"; // Storage Location
f.Execute();
string matDocument = f.Imports["MATERIALDOCUMENT"].ParamValue as string;
string matDocumentYear = f.Imports["MATDOCUMENTYEAR"].ParamValue as string;
ERPTable ret = f.Tables["RETURN"]; //.ToADOTable();
foreach(var i in ret)
Console.WriteLine("{0} - {1}", i["TYPE"], i["MESSAGE"]);
ERPFunction fCommit = client.CreateFunction("BAPI_TRANSACTION_COMMIT");
fCommit.Exports["WAIT"].ParamValue = "X";
fCommit.Execute();
}
在此示例中,我们使用 BAPI_GOODSMVT_CREATE
为货物移动创建收货。最终对 BAPI_TRANSACTION_COMMIT
的调用仅在系统在后台使用同一连接对象的情况下才有效。运行时不直接提供对底层 SAP 连接的访问,但该库提供了一种称为连接范围的技术。您可以使用客户端库创建一个新的连接范围,并告知 ECS 使用相同的 SAP 连接,直到您关闭连接范围。在连接范围内,所有库调用都将使用相同的 SAP 连接。
要创建新的连接范围,您需要调用 ERPConnectServiceClient
类的 BeginConnectionScope
方法。该方法返回一个 IDisposable 对象,该对象可与 C# 的 using 语句结合使用以结束连接范围。或者,您可以调用 EndConnectionScope 方法。使用具有嵌套结构的函数模块作为参数也是可能的。这是 SAP 的一种特殊构造。上面的收货示例在导出参数 GOODSMVT_CODE
中使用了嵌套结构。有关嵌套结构和表的更多详细信息,请参阅产品文档。