admin管理员组

文章数量:1534190

2024年7月2日发(作者:)

UAP开发样例指导

用友研发中心 U8平台技术部

<

本文档适用于

U871

版本

>

目 录

一、 摘要 ........................................................................................................................... 3

二、 样例开发前提 ........................................................................................................... 3

三、 建立UAP项目 ......................................................................................................... 3

四、 建立表单模型 ........................................................................................................... 5

(一) 新建实体 ............................................................................................................... 6

(二) 新建实体属性 ....................................................................................................... 8

五、 建立表单布局 ......................................................................................................... 14

六、 行为对象开发 ......................................................................................................... 15

(一) 表单开发 ............................................................................................................. 17

(二) 列表开发 ............................................................................................................. 30

(三) 生单二次开发 ..................................................................................................... 36

(四) 联查报表 ............................................................................................................. 37

(五) 联查UAP列表 ................................................................................................... 38

(六) UAP列表联查U8单据 ..................................................................................... 39

(七) 用户自定义控件开发 ......................................................................................... 42

(八) U8单据引用UAP档案 ..................................................................................... 43

七、 行为对象注册 ......................................................................................................... 56

功能介绍: ..................................................................................................................... 56

使用说明: ..................................................................................................................... 56

应用技巧: ..................................................................................................................... 58

八、 建立数据引擎 ......................................................................................................... 59

功能介绍: ..................................................................................................................... 59

使用说明: ..................................................................................................................... 60

应用技巧: ..................................................................................................................... 82

九、 设置过滤条件 ......................................................................................................... 82

功能介绍: ..................................................................................................................... 82

使用说明: ..................................................................................................................... 82

应用技巧: ..................................................................................................................... 87

十、 设置栏目 ................................................................................................................. 88

功能介绍 ......................................................................................................................... 88

使用说明 ......................................................................................................................... 88

应用技巧 ......................................................................................................................... 89

十一、 权限 ..................................................................................................................... 89

功能权限 ......................................................................................................................... 89

记录级权限 ..................................................................................................................... 90

字段级权限 ..................................................................................................................... 91

十二、 部署 ..................................................................................................................... 92

附录:功能介绍 ..................................................................................................................... 93

1、行为对象升级说明 ................................................................................................... 93

2、LoginInfo 对象介绍................................................................................................. 95

一、 摘要

本文以U8-ERP中的销售订单为应用原型,介绍了如何通过UAP进行软件开发,文中

给出了开发方法和丰富样例。内容包括:

UAP表单开发原理

UAP项目的建立和导入、导出

UAP表单的模型设计和布局设计

UAP表单的行为对象开发

UAP表单列表设计与开发

UAP表单列表的行为对象开发

如何对UAP表单的缺省按钮进行扩展性开发

如何对UAP表单的缺省按钮进行取代性开发

如何为UAP表单增加新的按钮及行为

如何用程序代码调用UAP报表

如何用程序代码调用UAP表单列表

如何在UAP表单中增加权限控制:功能权限、字段权限、记录权限

如何为UAP表单开发自定义控件

如何开发树形档案

如何维护UAP数据引擎

如何维护栏目

如何维护过滤条件

如何调用U8API

U8单据自定义项如何引用UAP档案

本文档中使用的示例文件为“销售订单二次开发”,可以通过UAP将该文件导入到帐套

中。项目名称为“ SaleVoucher ”,导入后在项目中包括几个自定义单据:“销售订单”为二

次开发的Demo示例;“零售日报”为自定义空间二次开发的Demo示例;“列表档案示例”、

“树形编辑档案示例”、“树形导航档案示例”分别为各个对应的档案类型的示例。

二、 样例开发前提

首先,需要安装U8产品,并建立一个帐套。

其次,您需要向用友公司购买UAP表单设计许可;不过您可以使用UAP的演示版本,

但是演示版本不能新建UAP项目,也不能注册行为对象。

三、 建立UAP项目

使用UAP登录您的帐套后,在系统界面上的新建项目选项卡,选中“供应链”后,在

右边的列表中选择“销售管理”,在界面下方的几个文本框中输入项目名称,编号,描述等;

顺序选择框使用“默认”即可。点击“确定”如果输入信息与先前创建的项目信息不冲突,

项目就可被成功创建。

您也可以导入我们为您提供的UAP样例项目,导入方法如下。

1、登录UAP;

2、打开菜单“文件-导入和导出”;

3、选中“导入项目数据到目前的服务器”,点“确定”按钮;

4、点“导入”按钮,选取U8安装目录下的“uapsdk”目录中的文件“Samplefile”;

5、导入成功后;

6、在UAP已存在的项目中产生了一个名称为“SaleVoucher”的项目;

四、 建立表单模型

选中“自定义表单”节点,单击右键,使用“新建自定义表单”功能创建一个新的表单。

然后在弹出的选择界面中选择“表单类型”下的“单据”,在名称文本框中输入一个表单名

字,不要与以前创建的表单名字重复。在成功创建后,系统界面会如下图(图表1)所示:

图表 1

在上图所示的实体节点,默认有两个子节点,分别为“主表和第一子表”,根据当前表单的

需要设计实体,包括增加实体和实体属性等。

(一) 新建实体

需要为实体填写“实体名称”,和选择“实体类型”。除此以外,还可以通过实体的属性编辑

窗口为实体设置各项信息。

实体的相关属性:

 名称:实体显示的名称,仅用于设计时。

 发布状态:实体是否已发布,只读。

 功能:为实体定义自定义功能,在运行时显示为表格对应的工具栏按钮。

 状态设置:设置实体属性、功能在表单运行时的状态,决定实体属性、功能在不同

的环境下是否可用。

 物理表模式:设置实体物理表的创建模式,默认为由UAP在发布时自动创建。在

特殊的应用场景中可以使用“使用已存在的对象”或“无”。后两种情况下UAP

不负责实体物理表的维护。

 物理表:设置该实体在数据库存储时使用的物理表,一般情况下一个实体对应一个

物理表。

 数据引擎模式:设置实体运行时数据的访问方式。默认为UAP系统在发布时自动

创建,特殊的应用场景中可以使用“使用已存在的对象”或“无”,这两种情况下

系统不负责实体数据的读取,只能通过用户定义的接口获取数据集。

 数据引擎:当数据引擎模式为“使用已存在的对象”时,设置要使用的数据引擎对

象。

 主键:设置实体物理表的主键字段名。

 主键类型:设置实体物理表主键字段的类型,可选“整数”或“GUID”或“字符

串”。

 行模式:多行或单行。一般主表设置为单行。

(二) 新建实体属性

实体必须包含实体属性时才有效。可以在UAP界面“表单”窗口中,右键点击实体对

应的节点,选择“新建实体属性”菜单向实体添加实体属性:

实体属性通用属性:

 类型:该实体属性的类型。

 描述:对该实体属性的单体描述。

 属性名称:实体属性的名称。

 默认值:实体属性的默认值。

 使用默认值:用户未提供数据时,是否使用实体属性的默认值。

 发布:该实体属性是否已经发布。

 常用条件:该实体属性是否可以在过滤中作为常用条件使用。

 区间条件:该实体属性是否可以在过滤中作为区间条件使用。

 值更新事件:设置该实体属性值更新时需要处理的脚本列表。

基础资料类型字段共有三种类型的值更新事件:“携带当前字段相关参照属性到指

定列”、“计算定义公式的值到指定列”、“表达式为真/假时改变指定栏目编辑状态”;

其余类型字段比基础资料类型字段缺少第一种类型的值更新事件。

1. 携带当前字段相关参照属性到指定列

2. 计算定义公式的值到指定列

3. 表达式为真/假时改变指定栏目编辑状态

表单式为真假时修改指定栏目的编辑状态

表单式为真假时修改指定栏目的显示状态

表单式为真假时修改指定功能状态

表单功能

实体功能

 唯一约束:是否检查该实体属性的值在整个表单范围内唯一。

 文本对齐:实体属性文本的显示位置。

 显示文本:实体属性的不同语言环境中显示的文本。

 允许空值:实体属性的值是否可以为空。

 物理表:实体属性对应物理字段的表名,即该实体属性所属实体的物理表。

 字段:实体属性对应的物理字段名。

除了支持以上通用属性外,不同类型的实体属性还具有不同的特性:

1. 表单编号

表单编号只能出现的主表实体中,并且只能有一个表单编号类型的实体属性。

2. 表单名称

表单名称类型的实体属性只能在档案类型的表单中使用,同表单编号一样,表单名

称类型的实体属性只能出现主表实体中,并且只能出现一次。

3. 整数和正整数

 可否为0:数值型的值是否可为0。

 录入长度:限制用户可录入数值的最多位数。

 数据格式:数值类型的显示格式。

 最大值和最小值:数据的有效范围。正整数的最小值必须等于或大于0。

4. 小数和正小数

 可否为0:数值型的值是否可为0。

 录入长度:限制用户可录入数值的最多位数。

 数据格式:数值类型的显示格式。

 最大值和最小值:数据的有效范围。正小数的最小值必须等于或大于0。

 小数位数:数据保留的小数位数。

5. 文本

 多行输入:运行时是否支持录入多行文本。

 最大长度:最多可录入的文本长度。

6. 日期和日期时间

日期类型运行短日期格式,即只包含年月日。日期时间类型包含年月日和时分秒。

7. 枚举

枚举类型的实体属性需要设置枚举值列表,枚举值的显示值为在界面显示的文本,

保存值为实际保存到数据库的数据,如枚举类型的实体属性“销售类型”的枚举值

可设置为如下图所示:

U872中枚举字段支持选择“枚举模式”:使用已存在枚举、新创建枚举。选择“使

用已存在枚举”后,需要为“枚举类型”选择一个U8系统中现有的枚举中的一个。

8. 基础资料

基础资料类型的值来自指定参照档案的对照值。

 参照对象:设置基础资料类型实体属性的参照档案对象,可以从U8档案列表

中选择,包含UAP中定义为档案类型的表单。

 参照显示值:该属性是设置当前就“基础资料”字段在运行时的文本框里显示

参照的那个字段的值。如上面的“参照对象”属性选择的存货档案,如果不设

参照显示值,则运行时默认显示为存货编码,如果将“参照显示值”属性设置

为存货档案的“存货”名称,运行是该字段就会显示为存货的名称。

 选择方式:设置在运行时的对照选择方式。

 自动校验:是否对录入的值进入检验以确定数据是否来自指定的参照对象。选

择“否”时允许用户录入参照对象中不存在的值。

9. 基础资料属性

基础资料属性类型的实体属性必须和基础资料类型的实体属性结合使用。

 参照属性:设置基础资料属性类型实体属性要绑定的基础资料类型实体属性,

并指定关联的参照字段。当基础资料类型的实体属性值变化时,基础资料属性

类型的实体属性值随之改变。

10. 数量、价格和金额

数量、价格和金额类型的实体属性实质上为小数类型,设置等同于小数类型的实体

属性。

11. 复选框

特殊类型的整数值,运行时显示为复选框,保存的数据为0(未选择)或1(选择)。

12. 制单人

当前单据的作者,一般设为登录用户。

13. 制单日期和修改日期

制单日期保存当前表单生成的日期,修改日期保存表单最后一次修改的日期。这两种类型的

实体属性实质上为日期时间类型,设置等同于日期时间类型的实体属性。

五、 建立表单布局

在完成实体的设计后,可以设计表单布局,UAP支持一个表单多个布局视图,用户可

根据自己的使用习惯选择一种布局视图。布局视图的设计与普通window界面的布局设计基

本一致。

六、 行为对象开发

行为对象开发是指增加表单或列表的功能按钮,除了UAP系统自带的功能按钮外,还

可以增加按钮,这些增加的功能按钮是UAP表单开发的基础。

UAP提供了多种增加功能的途径,首先通过设计界面的树形菜单中的“功能”节点下

的表单功能和列表功能的“功能管理”(图表2)添加功能按钮,这些功能按钮最终在运行

时会被加载到U8产品的门户上;其次可以为每个表单实体添加功能按钮(图表3),为实体

添加完成这些功能按钮后,还需要在布局视图上为该表单实体的“功能”属性设置使用这些

功能(图表4),这些功能按钮最终在运行时会被加载到该实体的工具栏按钮上。

图表 2 图表 3 图表 4

图表 5

增加功能按钮时,很多工作都可以通过上图(图5)的设计界面完成,开发人员关心的

仅仅是表单开发业务逻辑的实现。这些按钮的作用主要是通过在运行时对模型对象中数据的

修改以及最终将修改的数据持久化来完成的。

UAP表单开发分为表单开发和列表开发两种。因此对应了两种不同的开发类型定义了

两种不同的访问模型对象数据的接口。

新增功能开发(锁定、解

锁、关闭、打开)

表单功能开发

表单开发

已有功能修改(审核、弃

审等)

新增功能开发(复制选中行、查询订单对应报

价单、订单追溯查询)

UAP分

层开发

列表开发

表单实体功能开

新增功能开发(批审、批

弃、批量关闭、批量打开)

已有功能修改(暂无)

已有功能修改(暂无)

(一) 表单开发

表单开发访问模型对象的接口

pt,该接

口被定义在中,所以在做表单开发前,你需要为

新建的表单开发项目添加的引用。

表单开发又可细分为表单功能开发和表单实体功能开发,每个不同部分的开发又都分为

UAP已有按钮的功能修改开发和新增按钮的功能开发。目前为止,只要是表单开发,只需

要实现上述接口即可。在实现 IReceipt 接口后,在实现类中会继承以下这些方法:

///

/// 门户工具栏按钮被点击时触发该方法,可以根据参数判断是哪个按钮被触发

/// 被点击门户工具栏按钮参数

///

IButtonEventHandler GetButtonEventHandler(VoucherButtonArgs

ButtonArgs);

///

/// 运行时表单加载之前调用的接口,可以处理表单加载之前的业务要求。

///

/// U8登录对象

/// .Net登录对象

/// 表单编号

/// 表单数据

/// 表单状态

/// 表单载入参数

void ReceiptLoading(in login, string Cardnumber, DataSet ds,

VoucherStateEnum state,ReceiptLoadingParas loadingParas);

///

/// 运行时表单加载之后调用的接口,可以处理表单加载之后的业务要求。

///

/// 所属表单对象

void ReceiptLoaded(VoucherProxy ReceiptObject);

///

/// 值更新之前的接口,对值的合法性检查在这里进行

/// Cell的值变动参数

/// 所属业务对象

/// 所属表单对象

///

void CellChanging(CellChangeEventArgs para, BusinessProxy

businessObject, VoucherProxy voucherObject);

///

/// 值更新之后的接口,对值的后续处理(如对其他Cell值的变更)在这里进行

/// Cell的值变动参数

/// 所属业务对象

/// 所属表单对象

///

void CellChanged(CellChangeEventArgs para, BusinessProxy

businessObject, VoucherProxy voucherObject);

///

/// 增加行之前的接口,对行的合法性检查在这里进行

/// 新增的行参数

/// 所属业务对象

/// 所属表单对象

///

void RowAdding(RowChangeEventArgs para, BusinessProxy

businessObject, VoucherProxy voucherObject);

///

/// 增加行之后的接口,对新增行的后续处理在这里进行

/// 新增的行参数

/// 所属业务对象

/// 所属表单对象

///

void RowAdded(RowChangeEventArgs para, BusinessProxy businessObject,

VoucherProxy voucherObject);

///

/// 删除行之前的接口,对行的合法性检查在这里进行

/// RowChangeEventArgs[]类型,要删除的行参数

/// 所属业务对象

/// 所属表单对象

///

void RowsDeleting(RowChangeEventArgs[] para, BusinessProxy

businessObject, VoucherProxy voucherObject);

///

/// 删除行之后的接口,对删除行的后续处理在这里进行

/// RowChangeEventArgs[]类型,要删除的行参数

/// 所属业务对象

/// 所属表单对象

///

void RowsDeleted(RowChangeEventArgs[] para, BusinessProxy

businessObject, VoucherProxy voucherObject);

///

/// 观察者视图工具条按钮单击事件的接口

/// 被单击的按钮参数

/// 所属业务对象

/// 所属表单对象

///

void ClickToolBarButton(ToolBarActionEventArgs para, BusinessProxy

businessObject, VoucherProxy voucherObject);

///

/// 设置为当前行之前的接口

/// 被选择的行参数

/// 所属业务对象

/// 所属表单对象

///

void RowSelecting(RowSelectEventArgs para, BusinessProxy

businessObject, VoucherProxy voucherObject);

///

/// 设置为当前行之后的接口

/// 被选择的行参数

/// 所属业务对象

/// 所属表单对象

///

void RowSelected(RowSelectEventArgs para, BusinessProxy

businessObject, VoucherProxy voucherObject);

///

/// 业务数据合法性检查之前的接口

/// 所属业务对象

/// 所属表单对象

///

void DataChecking(BusinessProxy businessObject, VoucherProxy

voucherObject);

///

/// 业务数据合法性检查之后的接口

/// 所属业务对象

/// 所属表单对象

///

void DataChecked(BusinessProxy businessObject, VoucherProxy

voucherObject);

///

/// 观察者视图填充数据前的接口

/// 观察者视图接口(IEditWindow)对象

/// 即将要填充的数据

///

void EditWindowFilling(IEditWindow view, DataTable fillDataTable,

BusinessProxy businessObject, VoucherProxy voucherObject);

///

/// 观察者视图填充数据后的接口

/// 观察者视图接口(IEditWindow)对象

/// 已经填充的数据

///

void EditWindowFilled(IEditWindow view, DataTable fillDataTable,

BusinessProxy businessObject, VoucherProxy voucherObject);

///

/// 参照打开前的接口

/// 观察者视图接口(IEditWindow)对象

/// ReferOpenEventArgs参照信息

/// 所属业务对象

/// 所属表单对象

///

void ReferOpening(ReferOpenEventArgs para, BusinessProxy

businessObject, VoucherProxy voucherObject);

///

/// 参照返回(关闭)后的接口

/// 观察者视图接口(IEditWindow)对象

/// ReferCloseEventArgs参照信息

/// 所属业务对象

/// 所属表单对象

///

void ReferClosed(ReferCloseEventArgs para, BusinessProxy

businessObject, VoucherProxy voucherObject);

///

/// 创建用户自定义控件接口,开发人员可以在这里创建用户自定义控件。运行时会把这

个控件加载到布局视图中。(版本新增)

///

/// 所属业务对象

/// 所属表单对象

/// 布局视图中指定的自定义控件“控件ID”

/// 用户自定义控件对象

Control CreateControl(BusinessProxy businessObject, VoucherProxy

voucherObject, string ID);

///

/// 表单状态更新之前的接口

/// 状态的变动参数

/// 所属表单对象

/// 是否允许改变状态false-不允许改变状态,表单仍将处于当前状态

///

bool StateChanging(VoucherStateChangeEventArgs para, VoucherProxy

voucherObject);

///

/// 表单状态更新之后的接口

/// 状态的变动参数

/// 所属表单对象

///

void StateChanged(VoucherStateChangeEventArgs para, VoucherProxy

voucherObject);

///

/// 鼠标左键双击数据行的接口

///

/// 鼠标双击信息

///

///

void RowDoubleClick(RowDoubleClickEventArgs para, BusinessProxy

businessObject, VoucherProxy voucherObject);

///

/// 鼠标左键双击数据单元格的接口

///

/// 鼠标双击信息

/// 所属业务对象

/// 所属表单对象

void CellDoubleClick(CellDoubleClickEventArgs para, BusinessProxy

businessObject, VoucherProxy voucherObject);

///

/// 鼠标左键双击表格的标题的接口

///

/// 鼠标双击信息

/// 所属业务对象

/// 所属表单对象

void HeaderDoubleClick(HeaderDoubleClickEventArgs para, BusinessProxy

businessObject, VoucherProxy voucherObject);

///

/// 设置当前列之后的接口

///

/// 列信息

/// 所属业务对象

/// 所属表单对象

void CellSelected(CellSelectEventArgs para, BusinessProxy businessObject,

VoucherProxy voucherObject);

1、

说明

表单功能开发(门户工具栏按钮功能开发)

IRecepit接口中的方法

///

/// 门户工具栏按钮被点击时触发该方法,可以根据参数判断是哪个按钮被触发

/// 被点击门户工具栏按钮参数

///

IButtonEventHandler GetButtonEventHandler(VoucherButtonArgs

ButtonArgs);

这个方法是表单功能按钮执行的入口,根据在UAP表单功能的功能管理(见

图2)里添加的不同功能按钮的ButtonKey来区别不同的功能。返回值类型为

nEventHandler接口,该返回值对象会被UAP运行

时调用来执行该对象中的方法。IButtonEventHandler接口定义了三个方法,按照运行时被调

用执行的先后顺序分别为:

string Excuting (VoucherProxy ReceiptObject)、

string Excute (VoucherProxy ReceiptObject, string PreExcuteResult)、

string Excuted(VoucherProxy ReceiptObject, string PreExcuteResult)。

注:

(1)三个方法的返回值为xml字符串,其格式为

"",该返回值用来标示

当前方法是否成功执行,记录在result属性里,errinfo属性用来记录任何可能的信息。Excuting

方法的返回值可以作为Excute方法的第二个参数PreExcuteResult传入Excute,你可以在

Excute方法体重分析传入的信息决定程序是否继续执行,或作出其他处理等,同样,Excute

方法的返回值也可作为Excuted方法的参数传入,并作必要检查。另外,你可以在保证上面

规定的xml结构的前提下,在节点内扩展该xml结构,以适应你的应用逻辑的需要。

(2)三个方法共有的参数就是当前表单功能按钮可以操作的表单模型。可以从该对象

中取到当前可以操作的任何数据。

示例

[IsImplementAttribute(true)]

public IButtonEventHandler GetButtonEventHandler(VoucherButtonArgs

ButtonArgs)

{

//保存按钮----UAP已有功能的部分修改开发

if (Key == "btnSaveVoucher")

{

return new AcceptOrderButton();

}

//审核按钮----UAP已有功能替代修改开发

if (Key == "btnAudit")

{

return new AuditButton();

}

//锁定按钮----新增功能开发

if (Key == "SenDevLock")

{

return new LockVoucherButton();

}

}

这个方法是表单功能按钮执行的入口,IsImplementAttribute属性需要手工添加到方法上

面。根据在UAP表单的功能管理里不同功能按钮的ButtonKey来区别不同的功能。上述代

码的返回值类型AcceptOrderButton、AuditButton、LockVoucherButton都是继承自

nEventHandler接口。

注意项

1) 新增功能开发

说明

在使用UAP进行表单开发时,UAP已经提供的功能都是一些公共功能,而一些表单可

能需要很多特别的功能,此时就需要进行新增功能的开发。新增功能开发需要开发者要完全

理解当前功能的实际业务,并在实现业务的基础上将对表单相关数据的修改持久化到数据库

中,持久化的操作及可能的事务控制等完全由开发人员自己来做。

示例

//锁定按钮----新增功能开发

双击查看代码

#region 锁定按钮----新增功能开发

using System;

using c;

using ;

using ;

using ;

using ent;

namespace oucher

{

public class LockVoucherButton : IButtonEventHandler

{

public LockVoucherButton()

{

}

#region IButtonEventHandler 成员

public string Excute(VoucherProxy ReceiptObject, string PreExcuteResult)

{

bool result = false;

SqlConnection conn=new SqlConnection(SqlConSt

SqlTransaction tran = null;

SqlDataReader rd = null;

try

{

();

tran=ransaction(mmi

tted);

SqlCommand cmd = Command();

Business b = sses["SaleVouche_0001_E001"] as

Business;

BusinessCell cell = ["cSOCode"] as BusinessCell;

string pkValue = ;

dText = "select cVerifier, cCloser,cLocker from so_somain

where cSOCode = '" + pkValue + "'";

ction = tran;

rd = eReader();

if (())

{

string auditMan = "";

string closeMan = "";

string lockMan = "";

if (!ll(0))

{

auditMan = ing(0);

}

if (!ll(1))

{

closeMan = ing(1);

}

if (!ll(2))

{

lockMan = ing(2);

注意项

2) UAP已有功能的修改开发

说明

UAP已经实现了新增表单的保存方法,但是我们可能在使用UAP保存逻辑的基础之上,

在保存之前或保存之后对表单的某些数据做一定的修改。具体就是对表单模型中的某些实体

属性的值根据业务逻辑的需要做必要的修改再执行已有的表单保存。

示例

using System;

using c;

using ;

using ;

using ;

using ;

namespace oucher

{

///

/// 接受订单按钮处理

///

public class AcceptOrderButton : IButtonEventHandler

{

#region IButtonEventHandler 成员

public string Excute(VoucherProxy ReceiptObject, string PreExcuteResult)

{

return null;

}

public string Excuted(VoucherProxy ReceiptObject, string PreExcuteResult)

{

if (!ReadExcuteState(PreExcuteResult))

{

if (rState == )

{

if

(nsKey("SaleVouche_0001_E001"))

{

Business b = sses["SaleVouche_0001_E001"]

as Business;

if ( > 0)

{

if (nsKey("iStatus"))

{

BusinessCell cell = ["iStatus"] as BusinessCell;

= "";

}

}

}

}

return null;

}

return MakeExcuteState(true, "保存成功");

}

public string Excuting(VoucherProxy ReceiptObject)

{

if (rState == )

{

if (nsKey("SaleVouche_0001_E001"))

{

Business b = sses["SaleVouche_0001_E001"] as

Business;

if ( > 0)

双击查看代码

注意项

3) UAP已有功能的替代开发

说明

UAP系统中已经实现了一些公共功能,但这些功能并不一定适用于每种不同表单的具

体情况,所以有些时候我们可能需要对UAP的已经实现的功能进行替代开发。替代开发分

为两种:在实现业务基础上直接操作数据库、调用U8已经实现的该表单审核功能的API方

法。

直接操作数据库:直接操作数据库的开发方法与下面的“新增功能开发”的开发方法大

体一致,此处不再细述。

调用业务API:调用业务API方法避免了开发人员必须去了解当前功能的具体业务,降

低了开发的复杂程度,有利于快速而准确的开发。但是在使用业务API之前,必须首先掌

握在.Net中调用U8中API的方法,其次需要知道有那些API可以使用,各个API方法的参

数和返回值代表的意义,以及根据API的参数和返回值确定你的表单开发过程的业务流程

等。

Net中如何调用U8中的API

参照U8API资源管理器中为每个已有的API生成的调用代码示例

示例

Business b = sses["SaleVouche_0001_E001"] as Business;

if (["iswfcontrolled"].Value == "1")

return null;

DataSet ds = [0].t;

ument dom =

tDataSetToDOM(ds, ame);

U8EnvContext envContext = new U8EnvContext();

envContext.U8Login = nObject;

Context("VoucherType", 12);

U8ApiAddress myApiAddress = new

U8ApiAddress("U8API/SaleOrder/Audit");

U8ApiBroker broker = new U8ApiBroker(myApiAddress, envContext);

NormalValue("domHead", dom);

if (ype == )

{

//审核处理

NormalValue("bVerify", true);

}

else if (ype == nAudit)

{

//弃审处理

NormalValue("bVerify", false);

}

if (!())

{

//错误处理

Exception apiEx = eption();

if (apiEx != null)

{

if (apiEx is MomSysException)

{

MomSysException sysEx = apiEx as MomSysException;

ine("系统异常:" + e);

(e);

}

else if (apiEx is MomBizException)

{

MomBizException bizEx = apiEx as MomBizException;

ine("API异常:" + e);

(e);

}

result = false;

}

//结束本次调用,释放API资源

e();

}

注意项

2、

说明

表单实体功能开发(表单实体工具栏按钮功能开发)

表单实体的功能开发主要是针对表单中的某个实体的数据相应的功能操作。

IRecepit接口中的方法

///

/// 观察者视图工具条按钮单击事件的接口

/// 被单击的按钮参数

/// 所属业务对象

/// 所属表单对象

///

void ClickToolBarButton(ToolBarActionEventArgs para, BusinessProxy

businessObject, VoucherProxy voucherObject);

这个方法是表单实体功能按钮执

行的入口

方法的参数

para

代表触发当前方法的工具栏上的一个按钮,

businessObject

代表当前表单实体的模型对象

,voucherObject

代表当前表单的模型对象

根据UAP中

实体功能设计里不同的ButtonKey来区别不同的功能按钮。从UAP给出的接口的参数中可

以看出,对当前表单实体的功能操作,不仅能访问当前的表单实体模型对象,还能访问当前

的表单模型对象。在表单开发过程中可以访问两个模型对象中的数据。

示例

[IsImplementAttribute(true)]

public void ClickToolBarButton(ToolBarActionEventArgs para,

BusinessProxy businessObject, VoucherProxy voucherObject)

{

switch ()

{

//复制选中行

case "SenDevCopyLine":

CopyCurrentLineToNewLine(businessObject, voucherObject);

break;

//查看存货量

case "SenDevViewCount":

ViewCount(businessObject, voucherObject);

break;

//查看当前订单对应报价单

case "SenDevViewBaoJiaDan":

ViewBaoJiaDan(businessObject, voucherObject);

break;

//订单追溯汇总查询

case "SenDevVoucherZhuiSuHuiZongChaXun":

VoucherZhuiSuHuiZongChaXun(businessObject, voucherObject);

break;

default:

break;

}

}

这个方法是表单实体功能按钮执行的入口,

IsImplementAttribute属性需要手工添加到方法上

面。方法的参数

para

代表触发当前方法的工具栏上的一个按钮,

businessObject代表当

前表单实体的模型对象,voucherObject代表当前表单的模型对象。

根据UAP中实体功能

设计里不同的ButtonKey来区别不同的功能按钮。

注意项

(二) 列表开发

说明

列表开发访问列表模型对象的接口为

e.

EventHandler,

该接口是一个已经包括部分功能代码的.Net类。该类

被定义在

中,所以在列表开发前,你需要为新建

的表单开发项目添加的引用。你需要做的就是

重写该类中的一个方法:

///

/// 批审按钮处理方法

///

/// 事件触发者

/// 事件对应的参数信息

public override void ProcessEvent(

tTypeEnum eventType,

object sender,

object args)

{

}

列表的分成开发时,就是通过上面方法的参数sender来区分在各个不同的功能,然后开

发着需要针对各个不同的功能实现其具体的业务逻辑,并将业务逻辑执行后对表单相关数据

的修改持久化。

U872在列表二次开发时新增接口如下,这些接口主要作用是为生单开发而添加。每个

方法都有自己的注释(该方法何时被调用,作用是什么)

///

/// 过滤窗口弹出时的处理,可以动态设置缺省过滤条件

///

/// 列表服务

/// 过滤组件

public virtual void ReceiptListFiltering(UFGeneralListService

listService, FilterSrvClass filterSrv)

{

}

///

/// 根据条件过滤源单据列表数据,可以重写缺省的过滤算法

///

/// 过滤参数

public virtual void ReceiptListFilter(FilterPluginArgs filterArgs)

{

if (filterArgs != null)

{

tPageData = null;

ntData = null;

}

}

///

/// 过滤操作执行后的事件

///

/// 列表服务

/// 查询后的数据(如果是分页的,只包含一页的数据)(该

DataSet中只应该包含一个DataTable)

/// 查询到的数据总行数(该DataSet中只包含一

个DataTable,并且DataTable中只有一行一列)

public virtual void ReceiptListFiltered(UFGeneralListService listService,

DataSet dataSet, DataSet dataRowCountDataSet)

{

}

///

/// 源单据列表过滤结果填充之前的处理

///

/// 列表服务

/// 查询后的数据(如果是分页的,只包含一页的数据)(该

DataSet中只应该包含一个DataTable)

public virtual void ReceiptListFilling(UFGeneralListService listService,

DataSet dataSet)

{

}

///

/// 源单据列表过滤结果填充之后的处理

///

/// 列表服务

/// 查询后的数据(如果是分页的,只包含一页的数据)(该

DataSet中只应该包含一个DataTable)

public virtual void ReceiptListFilled(UFGeneralListService listService,

DataSet dataSet)

{

}

///

/// 源单据被选择事件,可以重写缺省的选择算法

///

/// 列表服务

/// 触发对象

/// 事件

public virtual void ReceiptChecking(UFGeneralListService listService,

object sender, CellEventArgs e)

{

}

///

/// 源单据被选择事件,可以重写缺省的选择算法

///

/// 列表服务

/// 触发对象

/// 事件

///

public virtual DataSet ReceiptCheck(UFGeneralListService

listService,object sender,string voucherId)

{

return null;

}

///

/// 源单据被选择事件,可以重写缺省的选择算法

///

/// 列表服务

/// 触发对象

/// 事件

public virtual void ReceiptChecked(UFGeneralListService

listService,object sender, CellEventArgs e)

{

}

U872已经默认的生单插件就是继承了该接口类,重写了上述的U872新增接口中的三个方法:

ReceiptListFilter(负责查询生单的源单据列表的数据)、ReceiptCheck(当单据列表上的一条单

据被选择后,负责查询该单据的数据)、ReceiptChecked(负责为生单源单据列表上刚刚选择或取消选

择的记录添加或取消CheckBox)。如果在实际的业务开发中需要做二次开发,只需要继承U872的默认

的生单插件的实现类ugin.

BasePluginUIEvent,重写基类中的方法即可。

示例一 列表门户按钮二次开发

双击查看代码

using System;

using c;

using ;

using ;

using ;

using ;

using ;

using tions;

using ent;

using stics;

using ds;

using ory;

namespace oucher

{

public class SalesOrderList :

EventHandler

{

///

/// 实现该方法

///

/// UI事件类型

/// 事件触发者

/// 事件对应的参数信息

public override void ProcessEvent(

tTypeEnum eventType,

object sender,

object args)

{

//检验事件类型是否为自定义按钮事件

if (eventType == BUTTONCLICK)

{

//取出按钮元数据信息

ToolbarItemMeta item = args as ToolbarItemMeta;

//批审

if ( == "SenDevBatchAudit")

{

sSenDevBatchAuditBtnEvent(sender, args);

return;

}

}

else if (eventType == K)

{

}

sEvent(eventType, sender, args);

}

///

/// 批审按钮处理方法

///

/// 事件触发者

/// 事件对应的参数信息

示例二 生单二次开发列表部分

public class

BasePluginUIEvent:EventHandler

{

///

/// 根据条件过滤源单据列表数据,可以重写缺省的过滤算法

///

/// 列表服务

/// 查询后的数据(如果是分页的,只包含一页的数据)(该

DataSet中只应该包含一个DataTable)

/// 查询到的数据总行数(该DataSet中只包含一

个DataTable,并且DataTable中只有一行一列)

public override void ReceiptListFilter(FilterPluginArgs filterArgs)

{

string scriptSql = "";

string selectCountSql = "";

tPageData = new DataSet();

ntData = new DataSet();

ine("开始解析转换规则获取........." +

TimeString());

nfo tempLogin = new

nfo(n);

sQueryReponse(Script,

OID, ver, SqlConStr,

oucherRuleID, ref scriptSql, ref selectCountSql);

using (SqlConnection conn = new

SqlConnection(SqlConStr))

{

();

if (ginate)

{

SqlDataAdapter adapter = new SqlDataAdapter(scriptSql, conn);

(tPageData,

(tPageIndex - 1) * ze, ze,

"temp");

}

else

{

SqlDataAdapter adapter = new SqlDataAdapter(scriptSql, conn);

(tPageData);

}

SqlDataAdapter adapter1 = new SqlDataAdapter(selectCountSql,

conn);

(ntData);

}

}

///

/// 源单据被选择事件,可以重写缺省的选择算法

///

/// 列表服务

/// 触发对象

/// 事件

///

public override DataSet ReceiptCheck(UFGeneralListService listService,

object sender, string voucherId)

{

DataSet result = null;

if (sender is MakeVoucher)

{

MakeVoucher tempObj = sender as MakeVoucher;

result =

cherTransformData(voucherId,

ucherRuleId);

}

}

///

/// 源单据被选择事件,可以重写缺省的选择算法

///

/// 列表服务

/// 触发对象

/// 事件

public override void ReceiptChecked(UFGeneralListService listService,

object sender, CellEventArgs e)

{

SameReceiptList(e, sender);

}

}

return result;

注意项

(三) 生单二次开发

生单二次开发共涉及到三个方面的二次开发:

生单接口二次开发;

列表接口二次开发;

单据接口二次开发;

其中列表接口和单据接口的二次开发参照行为对象二次开发章节的“表单二次开发”、“列表

二次开发”。本节主要讲述生单的二次开发接口。

生单二次开发访问生单模型对象的接口为

ller

.

IMakeReceipt

该接口是生单二次开发的基础接口。被定义在

中,所以在生单二次开发前,你需要为新

建的表单开发项目添加

的引用。然后根

据你的业务需要实现接口IMakeReceipt接口中的方法:

///

/// 生单二次开发接口

///

public interface IMakeReceipt

{

///

/// 单据转化前调用接口

///

/// 生单窗体对象

/// 源单据数据

/// 单据转化是否继续执行

bool DataConverting(MakeVoucher makeReceipt, DataSet sourceDataSet);

///

/// 单据转化接口

///

/// 生单窗体对象

/// 源单据数据

/// 转化后的数据

DataSet DataConvert(MakeVoucher makeReceipt,DataSet sourceDataSet);

///

/// 单据转化后接口

///

/// 生单窗体对象

/// 转化后的数据

/// 单据转化是否继续执行

bool DataConverted(MakeVoucher makeReceipt, DataSet convertedDataSet);

///

/// 生单窗体工具栏按钮二次开发

///

/// 按钮对象

/// 按钮二次开发接口实现类

IMakeVoucherButtonEventHandler GetButtonEventHandler(VoucherButtonArgs

ButtonArgs);

}

该接口中的DataConverting、DataConvert、DataConverted方法分别为生单转换前方法、

具体的生单转换方法、生单转换后方法。其中生单转换算法最好在DataConvert方法中实现;

GetButtonEventHandler方法为生单弹出窗体上按钮的二次开发接口,该方法类似于单据按钮的二次

开发接口。该接口的返回值为IMakeVoucherButtonEventHandler类型,

返回对象会被UAP运

行时调用来执行该对象中的方法。

IMakeVoucherButtonEventHandler

接口定义了三个方法,

按照运行时被调用执行的先后顺序分别为:

string Excuting (VoucherProxy ReceiptObject)、

string Excute (VoucherProxy ReceiptObject, string PreExcuteResult)、

string Excuted(VoucherProxy ReceiptObject, string PreExcuteResult)。

注:

(1)三个方法的返回值为xml字符串,其格式为

"",该返回值用来标示

当前方法是否成功执行,记录在result属性里,errinfo属性用来记录任何可能的信息。Excuting

方法的返回值可以作为Excute方法的第二个参数PreExcuteResult传入Excute,你可以在

Excute方法体重分析传入的信息决定程序是否继续执行,或作出其他处理等,同样,Excute

方法的返回值也可作为Excuted方法的参数传入,并作必要检查。另外,你可以在保证上面

规定的xml结构的前提下,在节点内扩展该xml结构,以适应你的应用逻辑的需要。

(2)三个方法共有的参数就是当前表单功能按钮可以操作的表单模型。可以从该对象

中取到当前可以操作的任何数据。

(四) 联查报表

说明

联查报表是指在UAP表单中,通过表单功能或表单实体功能查询与表单或表单实体中

的某些数据相关的U8报表。这种查询操作是针对特定的表单或表单实体,所以可以不必输

入过滤条件,而是使用默认过滤条件,所以此处的联查报表有别于使用过滤条件的报表查询。

示例

联查报表示例----在UAP表单中打开U8报表

此处以销售订单中查看某个存货的现存量来描述。在销售订单的表单单据体中描述了一

组(多行)存货数据信息。首先从当前表单实体模型中获得当前实体的主键值,进而获得当

前主键值对应得存货信息,将存货信息封装到过滤条件中传入报表即可。

(1)

获得存货编码

BusinessRow currentRow =[tPKValue];

DataRow someRow = a;

string invCode = someRow[invcodeColumnName].ToString();

(2)

封装过滤条件 封装过滤条件涉及到一个过滤窗口是否显示的问题。如果过滤窗口显示,

我们可以通过过滤窗口为过滤查询赋值;如果要求过滤窗口不显示,并且需要设置查询条

件,此时只能是先通过代码封装查询过滤条件,然后再传入打开报表的方法。

//

封装过滤条件

FilterSrv filter = new FilterSrvClass();

bool hiddenFlag = true;

object errInfo = new object();

object temp2 = (object)filterColumnName;

lter((object)login, "SA[__]销售现存量查询", "", "", ref

errInfo, ref hiddenFlag);

if (_Item(ref temp2).IsSingleItem == true)

{

_Item(ref temp2).varValue = filterValue1;

}

else

{

_Item(ref temp2).varValue = filterValue1;

_Item(ref temp2).varValue2 = filterValue2;

}

//将过滤条件传入打开报表的方法

clsReportOpen clsReport = new clsReportOpenClass();

bool hiddenFlag = true;

object tmp =(object)filter;

port(reportName, (object)login, ref hiddenFlag,ref

tmp );

clsReport = null;

注意项

(五) 联查UAP列表

说明

联查UAP列表是指从UAP表单中打开UAP样式的U8表单列表。在现在的UAP中,

打开UAP列表必须使用UAP列表的一些基础服务,在联查过程中,可以使用过滤设置设置

列表查询的过滤条件,也可不使用过滤设置而使用默认的过滤条件。

示例

该部分示例与下一部分“UAP列表联查U8单据”一起展示

(六) UAP列表联查U8单据

说明

此处UAP列表是指UAP列表样式的U8表单列表,通过该列表联查U8单据必须与上

面所讲的“联查UAP列表”结合使用。

从UAP表单中穿透到(打开)UAP列表样式的U8表单列表,并且从打开的UAP列表

样式的U8表单列表中穿透到(打开)U8表单。

要获得U8表单列表需要实例化

ralListService

ralListService

类,而要实例化

类,需要实例化

类,实例化ralListMeta

UFGeneralListMeta时一般需要的参数为数据源、过滤条件、栏目、用户自定义事件等。

数据源:

类:. DataAccessMeta

实例化该类时需要两个参数new DataAccessMeta("BizDAE",

erQuerySetting),第一个参数目前可支持两种类型分别为:"BizDAE","SqlQuery";第

二个参数为对应第一个参数的用xml描述的数据源详细信息。如果第一个参数为"BizDAE",则

xml结构为:

boid="829345d6-79ce-48e5-9fa2-f78b5031d167"

functionName="QuerySA_QuoHeadData" type="ER"/>;如果第一个参数为

"SqlQuery",则xml结构为:

from部分

where部分

order部分

group部分

having部分

过滤条件:

类:. FilterMeta

实例化该类new FilterMeta("SA[__]16", filterSet)需要两个参数,第一个

参数为本次查询需要的过滤条件编号ID,第二个为不显示过滤窗口时传入默认的过滤条件,其

为xml结构的字符串,默认过滤条件的组织样式如下格式要求:

1、 过滤列的名称必须在该处列表过滤条件所有可选的字段中。

2、 操作符operator1为正常的Sql表到式中的where条件操作符。like等操作时需要自

己添加必要的"%"等

3、 区间条件时需要最终的格式为间条件时值" operator2="<=" val2="区间条件时值"/>。 当然也可以将一个区间条件项

分为两个条件项

operator2="<=" val2="区间条件时值"/>

栏目:

类:Meta

实例化该类new ColumnMeta("SaleVoucher")需要一个参数,该参数为在UAP

的栏目设计器中对应栏目的编号ID。

用户自定义事件:

该参数为当表单开发人员对查询后的列表有自定义按钮事件或其他操作时使用,该参

数为实现基类EventHandler的子类的完

整的命名路径。

至此使用上述几个参数可以实例化UFGeneralListMeta类的一个对象,然后再使用该对

象实例化UFGeneralListService类的对象,就可以得到UAP列表。如果想从该列表中某一

行数据穿透到该条数据对应的表单中,需要在实例化UFGeneralListMeta类的对象时做一个

额外的工作。就是为UFGeneralListMeta类的对象的ExtendInfo属性赋值,该属性值为

xml格式的字符串类型。其格式为:

限ID" voucherName="表单名称" voucherIDCol="表单主表的主键列名"

voucherDetailIDCol="子表的主键列名" cardNum="表单的CardNumber,在Vouchers

表中能够查询得到" voucherType="在Vouchers表中某个表单特别时,会在该表中的

Vouchertype中有相应值,如果是一般的表单,该值与表单的CardNumber一致"

voucherTypeEnum="表示即将打开的表单是U8表单,还是UAP表单。UAP表单为0,U8表

单为1" instance="该参数含义待定"/>。

示例

UFGeneralListMeta listMeta = new UFGeneralListMeta();

//组织数据源,此处使用数据引擎查询数据。

DAEERQueryInfo(listMeta,

"829345d6-79ce-48e5-9fa2-f78b5031d167", "QuerySA_QuoHeadData");

#region 设置数据引擎过滤条件

Business b = sses["SaleVouche_0001_E002"] as Business;

string curentRow = tPKValue;

BusinessRows rows = ;

//此处不再使用过滤,只能给其传输默认过滤条件。默认过滤条件的组织样式如下格式。

//1、过滤列的名称必须在该处列表过滤条件所有可选的字段中。

//2、操作符operator1为正常的Sql表到式中的where条件操作符。like等操作时需要自己添加必要的"%"

//3、区间条件时需要最终的格式为

operator2="<=" val2="区间条件时值"/>

// 当然也可以将一个区间条件项分为两个条件项

//

//

//

// 区间条件时值"/>

//

StringBuilder sb = new StringBuilder("");

for (int i = 0; i < ; i++)

{

BusinessRow someRow = rows[i];

if (["iSOsID"].Value == curentRow)

{

string quoCode = ["cQuoCode"].Value;

("

"%"/>");

break;

}

}

("");

DAEFilterInfo(listMeta, "SA[__]16", ng());

#endregion

#region 设置列表的栏目信息

DAEColumnInfo(listMeta, "SaleVoucher");

#endregion

//设置列表的二次开发界面事件实现类

tomeUIEventHandler(listMeta,

"rderList,oucher

");

ySet = new DisplaySetMeta(true,200);

//设置从列表中打开单据时需要的扩展信息

Info = endInfo("SAM030101", "SA", "SA03000101", "销售报价

单", "ID", "AutoID", "16", "16",

(七) 用户自定义控件开发

说明

UAP表单开发支持在表单视图中添加用户自定义控件,并将该自定义控件与该表单中

的某一个表单实体模型关联,根据用户的实际需求,对实体模型中数据做更加丰富的展示,

或者通过对自定义控件上展示的数据的修改影响实体模型的数据。

IRecepit接口中的方法

///

/// 创建用户自定义控件接口,开发人员可以在这里创建用户自定义控件。运行时会把这

个控件加载到布局视图中。(版本新增)

///

/// 所属业务对象

/// 所属表单对象

/// 布局视图中指定的自定义控件“控件ID”

/// 用户自定义控件对象

Control CreateControl(BusinessProxy businessObject, VoucherProxy

voucherObject, string ID);

开发人员通过实现该方法返回自己定义的控件对象,UAP

将控件对象加载到布局视图中。

示例

[IsImplementAttribute(true)]

public l CreateControl(BusinessProxy

businessObject, VoucherProxy voucherObject, string ID)

{

Control resultControl = null;

//此处的ID为UAP布局视图中自定义控件的属性“控件ID”

if (ID == "09a86fa8-11d2-4e4c-8d1c-2cb2c0839fa3")

{

SaleCountReportControl tempControl = new

SaleCountReportControl();

resultControl = tempControl;

= ;

}

return resultControl;

}

样例运行

样例项目中的“零售日报”表单为自定义控件表单例子,表体部分的数据被修改时自定义的图表

信息会相应的做出修改。

(八) U8单据引用UAP档案

说明

示例

新建UAP档案

UAP档案分为“复杂档案”、“列表档案”、“树形编辑档案”、“树形导航档案”四种类

型。“复杂档案”类型的档案设计方法与普通单据基本一致,唯一的区别就是设计“主

表”实体时必须设计类型为“表单名称”的实体属性。其他三种类型档案新建方法分别

如下:

1) 新建列表档案:

选择档案类型及填写档案名称

列表档案类型的档案只有“主表”实体,不能再添加新实体。所以只需要为“主表”实

体设计实体属性

表单编号类型(必须添加)

表单名称类型(必须添加)

根据需要可以再添加其他类型的实体属性。

设计布局视图

可以再对该列表档案的“功能”、“栏目”、“过滤”等设计项或实体的属性等信息项做设

定,设计完成之后可以发布该档案

2) 新建树形编辑档案:

选择档案类型及填写档案名称

列表档案的实体设计同上述的列表档案,只有“主表”实体,“表单编号”和“表单名

称”类型的实体属性必须设计。

布局视图的设计比较特别,需要在界面视图上添加“树形控件”

然后为“树形空间”绑定实体,在设计界面上的树形控件点击“右键”绑定实体“主

表*********”。

然后在布局视图中添加“主表”实体控件。

可以再对该列表档案的“功能”、“栏目”、“过滤”等设计项或实体的属性等信息项做设

定,设计完成之后可以发布该档案

3) 新建树形导航档案:

选择档案类型及填写档案名称

树形导航档案的实体包括“主表”和“子表”两个,不能再添加别的实体。并且“主表”

中不能再添加实体属性,只有“编码字段”和“显示字段”两个实体属性;而“子表”

实体的实体属性可以根据需要自己添加,当然“表单编号”和“表单名称”两种类型的

实体属性必须在“子表”实体中添加。树形导航档案类型的档案与其他类型的档案的区

别是必须通过“主表”实体的属性编辑窗口为“主表”实体编辑几项属性。

图中红框圈中的几项属性必须要添加。

首先,添加“数据引擎”,通过下面的方式选择一个合适的数据引擎。

其次,设置编码规则,根据选择的数据引擎编码字段的编码规则来设置该属性,因为“部

门档案信息”的编码规则为“1:2”,所以此处属性设置为“1:2”。

再次,设置编码字段和显示字段

,在设置了“数据引擎”后,编码字段

会通过“数据引擎”读取该引擎可以得到的所有的字段信息,通过下拉框可以为“编码

字段”属性选择合适的字段;同样的方式设置“显示字段”属性。

设计布局视图,树形导航档案的布局视图的设计与树形编辑档案布局视图的设计相同。

可以再对该列表档案的“功能”、“栏目”、“过滤”等设计项或实体的属性等信息项做设

定,设计完成之后可以发布该档案

使用参照设计器

在将新建完成的档案发布以后使用“参照设计器”将该档案设置为“自定义字段参照”。步

骤如下:

打开“参照设计器”

根据档案名称定位到档案

修改该档案将其设置为“自定义字段参照”档案并保存。

设置U8单据显示格式

登录U8后,选择“基础设置”—>“单据设置”—>“单据格式设置”,双击进入“单据格

式设置”。选择某个子产品下的一个需要修改的单据的显示模板,此处以“销售管理”“发

货单”—>“显示”为例,打开显示模板后如下图所示:

假如我们需要在表头部分添加一个参照项,在打开的显示模板上执行右键菜单里的“表头项

目”(需要修改表体部分就选择“表体项目”)

选择一个需要显示的项目

为其参照类型从下拉框中选择“档案”

进入“自定义项属性”标签

“数据来源”选择“来源档案”,并选择“档案名称”和“参照栏目”,其中“档案名称”选

择使用“参照设计器”将档案修改为“自定义字段参照”的档案。

“确定”后保存当前单据的显示模板

在U8中打开“发货单”并执行“增加”后显示的样式为

注意项

1、档案被重新发布后其在“参照设计器”中设置的信息会丢失。例如将“列表档案示例”

在“参照设计器”将档案设置为“自定义字段参照”后,在重新发布“列表档案示例”后,

该项信息丢失。

七、 行为对象注册

功能介绍:

UAP表单开发的组件最终都是通过组件接口挂接到系统中,在运行时被调用执行。此

功能一般是在表单开发的代码完成之后使用。

使用说明:

行为对象注册分为两种类型:表单对象、列表对象、服务器端对象、生单对象。

在表单的行为对象时,类名属性选择实现了IReceipt接口的类;

从“对象类型”中选择实现了Ireceipt接口的类,如下图展示的是示例中实现了Ireceipt接

口的类

确定后

在性选择

EventHandler

的类

列表的行为对象时,类名属继承了

确定后

在生单的行为对象注册时,需要选择实现类生单二次开发接口IMakeReceipt接口的类。

应用技巧:

1、在选择二次开发生成的dll文件时有时会出现以下错误,这是由于选择的dll文件引用的

其他的程序集文件没有被加载成功导致的。此时检查配置文件u8softuap目录下

文件中的节点

中的属性

privatePath的值,用“;”分割开的值分别代表路径u8softuapInfragistics和u8softuapRuntime,

即UAP在启动后会加载这两个目录下的所有程序集文件,如果二次开发的dll文件引用了

不在这两个目录下的程序集文件,UAP便不能加载引用的文件于是在选择二次开发的dll时,

便会出现下面的错误。

此时可以将二次开发的dll文件引用程序集所在的目录添加到privatePath中,要与已有的值

用“;”分开。

八、 建立数据引擎

功能介绍:

在U870前由于没有统一的商务数据引擎,数据的读取和写入都是通过直接操作数据库

的方式完成的,这样的方式由于没有封装,存在以下的几个问题。

 业务数据的读取没有统一,造成复用能力比较低,增加了开发的成本。

 目前需要新开发报表和参照,这些数据读取必须足够灵活且高效,这些都对数据的

读取提出的更高的要求,目前必须通过一个引擎对其进行控制。

 U8对二次开发和产业链的支持的要求也要求提供一个业务引擎支持其对数据的灵

活的使用要求。

数据引擎针对上面问题而产生,它为U8通用报表、U8通用单据、列表、档案、参照

提供原始的数据源的支持。

在BizDAE中有三种类型的元数据:物理表/视图元数据、实体元数据、业务对象元数

据,下面具体描述一下各自的意义:

 物理表/视图元数据:描述数据库中物理表或者视图的具体信息,包括物理表/视图

名称,物理表列名称,列数据类型,物理表主键等信息。

 实体元数据:所谓实体是根据业务进行划分的,是指与一个业务相关的所有物理表

信息的一个集合(类似视图),实体元数据信息包括该实体中包含的所有物理表,

以及物理表与物理表之间的关系,实体的属性集合信息(实体属性可来自于一个物

理表列,或者一个计算公式,或者一个枚举)。在实体中物理表有三种类别:主表

(对应表头信息,例如订单Head表),事实表(对应明细信息,与主表是1:N的

关系,例如订单Detail表),纬度表(对应主表或者事实表的相关应用信息,与主表

或者事实表示1:1的关系,例如一些单位参照表等信息)。

 业务对象元数据:业务对象是指在与一个业务相关的所有操作的集合(与程序设置

语言中类的概念相近),一个业务对象中包含多个功能(与类方法相近),一个功能

中可以包含多个查询(方法中所作的操作)

使用说明:

登陆UAP环境

配制物理表

枚举出当前登录U8账套数据库中所有的物理表以及视图信息

点击“确定”按钮后,可以在BizDAE中显示出新增加的物理表信息:

配制实体

实体配制界面

添加实体对应的主表(SO_SOMain)

添加事实表(SO_SODetail)

添加于SO_SOMain相关的Department纬度表

添加完毕后,在元数据列表中显示所有与实体相关的所有物理表

设置物理表关系

添加完毕后所有物理表关系显示如下:

设置一些特殊的物理表关系如下所示(表达式注意事项参考计算列设置):

其中的作用对象是指构造SQL的时候,On表达式所作用的物理表,如上面配置的信息可能

会产生如下的SQL表达式:

Select * From SO_SOMain Left Join SO_SODetails on SO_e = SO_SODetails.

cSOCode or SO_SODetails. cSOCode = null

添加基础属性(来自物理表列的属性)

添加完毕基础属性显示如下:

添加计算属性

添加完毕,计算属性显示如下:

添加枚举属性:

注意其中的枚举类型来自于UFMeta中注册的枚举类型,枚举值表以及枚举值列是设置保存

枚举类型ID所对应的列,构建SQL的时候会去该列的值与所有的枚举值进行匹配比较,并

取出对应得枚举类型名称

在实体添加完毕后,点击“确定”按钮,在主窗体中显示出新增加的实体:

业务对象

修改业务对象基础信息

添加功能

添加实体关系查询

实体关系查询设置窗体

添加查询涉及的实体

如果该查询设计多个实体,可以设置实体与实体之间的关系

其中也可以进行实体关系自定义设置,参考实体中物理表关系设置部分

添加查询结果列(Select)

修改列名称以及描述信息

添加计算列

其中的表达式使用方法参考 《备注1》

添加查询条件(Where)

添加组内查询条件(Having)

添加方法同添加查询条件

添加排序(Sort)

添加分组(Group)

添加完毕后再业务对象窗体显示新增加的实体关系查询

添加SQL查询

SQL查询又分为两种,分别为SQL脚本以及储存过程查询,其中的存储过程查询设置如下

所示:

如果为SQL脚本查询,则按照下面的方式分别设置各个部分的SQL脚本:

设置Select部分

设置Where部分

其它各个部分的设置类同

业务对象信息设置完毕后,点击“确定”按钮,则在主窗体中显示出新增加的业务对象信息

业务对象配置完毕,可以使用工具测试该业务对象配置信息是否正确

查询完毕,可以在查询结果栏中查看当前查询过程中的日志信息,其中可以看出每个步骤地

耗时,动态产生的SQL脚本信息等

备注

:

1、 在BizDAE中所有的SQL表达式(如计算列表达式、查询条件,实体计算属性,运行时

动态设置的SQL脚本等)如果要使用物理表列或者实体属性必须按照下面方式使用:

#P[物理表别名.列名称]:在实体设置中使用物理表列方法

#P[实体别名.属性名称]:在查询中使用实体属性方法

#FN[查询结果列名称]:在查询中使用查询结果列方法(不推荐使用)

应用技巧:

在配置完业务对象后应该使用测试工具检验该配置信息是否正确,如果出现问题可以从日志

中检验原因

九、 设置过滤条件

功能介绍:

过滤设计器是通用控件,主要用于报表、单据列表、表单等过滤条件的设置。有丰富的

类型,可供设置过滤条件时选择,还可以将过滤条件设置为区间条件或多选条件,可以为过

滤条件赋默认值,同时支持将过滤条件分组显示。

使用说明:

A. 过滤设计器主窗口

界面说明:

是否支持高级条件:选此项后,在运行时过滤窗口中会出现“高级条件”页签,用于用

户自由选择过滤条件的组合。

是否显示汇总选择:选此项后,将在运行时窗口的最下端显示“查看汇总信息”复选框。

规则组件:此项定义由过滤控件回调的规则组件类。

是否取消二次开发:此复选项只有在以“U870”项目进入UAP时才会显示,如果被选

中,那么以其它项目进入UAP的过滤设计器不能新增和删除过滤条件。

B. 过滤条件项窗口基本页签

界面说明:

语种:设置过滤条件项显示的语种。

中文简体名称:过滤条件项的键值,唯一标识此过滤条件项,不能重复。可以以字母、

数字或汉字来命名。

标题:在运行时过滤窗口中显示的文字,支持多语种设置。

编辑类型:过滤条件项的类型,分别为文本框、参照、日期、数字、枚举、SQL语句、

自定义。

参照ID:当编辑类型选择参照类型后,必须选定一个参照ID。

比较符:过滤条件项比较符号。

小数位数:当编辑类型为数字类型时,此选项可以设置小数位数。

分组:为过滤条件选定一个分组,在运行时将按照分组来显示过滤条件项。

数据源:为过滤条件项选定数据源,可以下拉选择或直接手工输入。

顺序号:指定过滤条件项在运行时显示的位置,如果不输入,将自动产生。

是否常用条件:如果选中,将在运行时显示在“常用”页签中。

是否必输:如果选中,在运行时必须输入值,否则会出现提示信息。

是否区间条件:如果选中,在运行时将显示为两个输入框组合而成的形式,表示从值1

到值2的意思。在运行时,用户选择或输入的不是单值,而表示一个取值范围。

是否多选:如果选中,表示此过滤条件项可以选择多个值。

允许用户修改比较符:如果选中,用户在运行时可以通过滤设功能改变比较符。

作为或条件:如果选中,在运行时将以“或”条件来组合到过滤条件生成的SQL语句

中,默认是以“与”条件组合的。

参照返回字段:当编辑类型为参照类型时,此选项表示参照返回的是哪个字段的值。编

码对应参照中的主键字段,名称对应参照中的描述字段。也可以手工输入要返回的字段名,

一定要与参照中的字段名一致。

默认值、到:设置过滤条件项的默认值,将在运行时自动显示。如果为区间条件,可以

设置“到”默认值。

C. 过滤条件项窗口枚举页签

界面说明:

枚举(aa_enum):指在U861中使用的枚举型,此类型是在AA_Enum数据表中定义的。

枚举类型,枚举类型名称,是EnumType字段值。默认显示,在运行时当用户点击下拉按钮

后显示的可供选择的项,注意是以“,”分隔的EnumCode字段的值。

枚举类型:指明在Meta库中的MetaEnumDef表中的枚举,对应MetaID字段。

枚举串:如果没有在数据库中预制枚举类型,也可以通过此项输入一个枚举串。格式为

“0{#}1{##}A{#}B”,在“{##}”前的为返回值,之后的则为显示值,并且在返回值与显示

值中分别以“{#}”分隔。

只能定义以上三种枚举中的一种,否则会出现提示信息。

D. 过滤条件项窗口SQL语句页签

界面说明:

SQL文本框:在SQL文本框中输入SQL语句,可以不用加别名。

标题:在运行时中显示的列标题,标题数量与上面的SQL的字段对应,并用“,”分隔,

例如“标题1,标题2”。

返回字段:用此字段的值构成过滤控件返回调用者的过滤SQL语句。

显示字段:显示在运行时过滤窗口中的值。

在U870中,SQL语句类型的过滤条件主要为兼容以前版本,所以如果在U870中新建

过滤条件时,请不要选用SQL语句类型,而改用参照类型。

E. 过滤条件项窗口样式页签

属性说明:

参照样式:当编辑类型选择为参照类型时,可以指定参照的样式,分别为弹出式和下

拉式,默认为弹出式。

应用技巧:

A. 过滤控件中预制了项目大类、项目分类及项目的处理,如果要使用此功能,请将过

滤条件项的编辑类型指定为参照类型,并在参照ID框中分别输入

sys__FinanceItemFirstClass、sys__FinanceItemClass、sys__FinanceItem即可。

B. 编辑类型为自定义类型的过滤条件项需要由开发人员实现功能,实际上对于自定义

类型的过滤条件项,过滤控件什么都不做,只是调用开发人员的回调方法。开发人员必须在

自己的类中声明并实现CallBack_UserBrowse方法,方法原型如下:

Public Function CallBack_UserBrowse(ByVal sKey As String, flt As

Srv)

并且要在调用过滤控件前,执行Set orObject = MyClass,MyClass是开发人员自

己的类。

十、 设置栏目

功能介绍

预置列表(包括但不限于单据列表)的栏目数据。

使用说明

1、 登陆UAP后,进入“工具->栏目设计器”,按照产品模块列出了系统中已有的所有

栏目;

2、 此时,可以新增一个栏目设置;

3、 也可以对已有的栏目设置进行修改;

支持: 作为汇总项进行显示

不支持:不作为汇总项,不显示

设置。

置。

合计: 作为合计项,数值类型才

平均: 取平均值,数值类型才需

最大: 取最大值,数值类型才需要

设置。

最小: 取最小值, 数值类型才

应用技巧

1、 只能修改和删除同一个UAP项目中的栏目;

2、 UAP表单发布时,自动新建一个栏目设置。

十一、 权限

功能权限

功能权限的控制主要是通过在UAP中为已有功能或新增功能的“控制权限”属性修改

来控制的。在UAP中权限控制选择“是”后,还需要使用“系统管理”工具,为具体的角

色分配该功能的权限,拥有该角色的用户就可以使用该功能。如果一个功能的权限控制选择

“否”,那么该功能能被所有人员使用。

记录级权限

记录级权限是指在创建表单模型时,为模型的某个属性列添加“记录级权限”属性设置,

然后还需要在U8中为用户作出相应得授权。注:如果需要设置权限控制的模型的属性列已

经被发布,则不能为其设置权限控制,需要首先将该属性列解除发布。下图展示的是为模型

的属性列“销售部门”添加记录级权限控制,在UAP设置完成后,还需要在U8中为用户

作出相应得授权。

字段级权限

记录级权限控制是通过在UAP中使用敏感数据维护工具将表单模型中的字段映射到一

个或多个已有或新建的敏感数据对象属性上,然后再在U8中的系统服务中数据权限分配里

为用户授权敏感数据对象属性。

下图展示了为一个新增的敏感数据对象test的属性tt建立与销售订单表单模型中的字段

建立映射。

在建立映射后,就可以在U8中适应数据权限分配为用户分配刚刚创建的数据敏感对象。

十二、 部署

1. UAP表单导出与导入

2. UAP项目导出与导入

3. 行为对象部署----表单开发代码部署

在行为对象开发生成的dll文件需要部署在U8安装目录UAPRUNTIME目录下;在开

发过程中可能会需要调用一些互操作的dll,将这些互操作的dll部署在U8安装目录

Interop目录下。

4. 安装包制作?

附录:功能介绍

1、行为对象升级说明

1.1 IReceipt新增接口

所有871版本中新增的接口必须在原870版本基础上作的二次开发接口实现

类中添加,将编译后的文件放到u8softuapruntime目录下。

///

/// 创建用户自定义控件接口,开发人员可以在这里创建用户自定义控件。运行时会把这个

控件加载到布局视图中。

///

/// 所属业务对象

/// 所属表单对象

/// 布局视图中指定的自定义控件“控件ID”

/// 用户自定义控件对象

Control CreateControl(BusinessProxy businessObject, VoucherProxy voucherObject, string ID);

///

/// 表单状态更新之前的接口

/// 状态的变动参数

/// 所属表单对象

///

void StateChanging(VoucherStateChangeEventArgs para, VoucherProxy voucherObject);

///

/// 表单状态更新之后的接口

/// 状态的变动参数

/// 所属表单对象

///

void StateChanged(VoucherStateChangeEventArgs para, VoucherProxy voucherObject);

///

/// 运行时表单加载之前调用的接口,可以处理表单加载之前的业务要求。

///

/// U8登录对象

/// .Net登录对象

/// 表单编号

/// 表单数据

/// 表单状态

void ReceiptLoading(in login, string Cardnumber, DataSet ds, VoucherStateEnum

state);

1.2 IReceipt修改接口

所有修改接口必须在原870版本基础上的二次开发接口实现类中做出修改。

将编译后的文件放到u8softuapruntime目录下。

1. InitReceipt修改为ReceiptLoaded

///

/// 运行时表单加载之后调用的接口,可以处理表单加载之后的业务要求。

///

/// 所属表单对象

void InitReceipt(VoucherProxy ReceiptObject);

该接口改为

///

/// 运行时表单加载之后调用的接口,可以处理表单加载之后的业务要求。

///

/// 所属表单对象

void ReceiptLoaded(VoucherProxy ReceiptObject);

2. 修改ClickToolBarButton接口的返回值

///

/// 观察者视图工具条按钮单击事件的接口

/// 被单击的按钮参数

/// 所属业务对象

/// 所属表单对象

///

void ClickToolBarButton(ToolBarActionEventArgs para, BusinessProxy businessObject,

VoucherProxy voucherObject);

该接口修改为

///

/// 观察者视图工具条按钮单击事件的接口

/// 被单击的按钮参数

/// 所属业务对象

/// 所属表单对象

/// true表示实现了相应按钮的方法;false表示没有实现相应按钮的方法。

///

bool ClickToolBarButton(ToolBarActionEventArgs para, BusinessProxy businessObject,

VoucherProxy voucherObject);

3. 修改GetButtonEventHandler接口参数

///

/// 门户按钮处理接口

///

/// 按钮参数

/// 门户按钮对应处理类对象。该类对象必须实现接口IButtonEventHandler

IButtonEventHandler GetButtonEventHandler(VoucherButtonArgs ButtonArgs);

该接口修改为

///

/// 门户按钮处理接口

///

/// 按钮参数

/// 所属表单对象

/// 门户按钮对应处理类对象。该类对象必须实现接口IButtonEventHandler

IButtonEventHandler GetButtonEventHandler(VoucherButtonArgs ButtonArgs,

VoucherProxy voucherObject);

2、LoginInfo 对象介绍

在U8中主要有两个login对象:U8Login对象(,inClass

类型)、.Net的LoginInfo对象(,.

LoginInfo类型)。

.Net的LoginInfo提供了一个构造函数,其参数为U8Login对象,既.Net的LoginInfo

对象可以通过U8Login对象获得。在表单开发过程中可以通过这个方法获得用户登录的信

息。

LoginInfo对象中获得信息如下:

属性:

AccID 帐套ID

AccName 帐套名称

AccYear 帐套年度

AppPath 系统运行目录

AppServer 当前登录到的应用服务器机器名

DataServer 当前登录到的数据库服务器

DbUser 登录数据库用户名

DbPwd 登录数据库密码

LanguageRegion 语言ID

LoginDate 登录系统时间

ProjectID 项目ID

ProjectName 项目名称

ProjectSubs 项目包含的子产品列表(哈希表,Key保存ID,Value保存名称)

U8Login U8登录对象(Interop.U8Login程序集,inClass

类型),以object类型返回

U8Subs U8全部子产品列表

UapProjects UAP系统中所有的项目列表

UFDataDbName 帐套数据库名称

UFMetaDbName UFMeta数据库名称

UFDataOleDbConStr 帐套数据库的ADO 2.X和 OLEDB Connection连接

字符串

UFMetaSqlConStr UFMeta数据库的 SqlConnection连接字符串

UFMetaOleDbConStr UFMeta数据库的ADO 2.X和 OLEDB Connection

连接字符串

UFSystemSqlConStr UFSystem数据库的 SqlConnection连接字符串

UFSystemOleDbConStr UFSystem数据库的ADO 2.X和 OLEDB

Connection连接字符串.

UnitName 账套机构名

UserID 登录用户ID

UserName 登录用户名称

方法:

ClearInfo() 清空所有信息

U8Login对象中获得信息如下:

属性:

AuthString *

cAccName 帐套名称

cDbServerSerial *

cEmployeeId *

cIYear *

cSerial *

cServer *

cServerSerial *

cSub_Id 子产品编号

cSubName 子产品名称

CurDate 当前日期

cUserId 用户编码

cUserName 用户名称

cUserPassWord 用户密码

cWebClient *

DataSource *

dbServerName 数据服务器

EntTypeID *

iMonth *

IsAdmin 是否管理员

IsGroupVer *

LanguageID 语言编号

LanguageRegion 语言区域编号

LogState *

ResFormat *

ResLayoutSvr *

ResLocalSvr *

ResSvr *

ShareString *

SysPassword *

UfCurrentDb *

UfDbName *

UfDbPath *

UfMetaName *

UfSystemADODb *

UfSystemDb *

UfZtPath *

userToken *

方法:

short BGAbateMonth(ref Connection cn); *

short CADemoMonth(ref Connection dbs); *

void ClearError(); *

bool ClosingStatus(short nIndex, string cSubId, short iYear, ref bool bStateValue);

*

bool ConstructLogin(string userToken); *

bool ConstructLoginEx(string userToken, object LoginUserData); *

short FD_Month_Used(ref Connection dbszj); *

short FMMonthHandled(ref Connection cnn); *

string get_cAcc_Id(); *

string get_TaskId(); *

bool GetAccInfo(int nIndex, ref object vValue); *

string GetEndSubAuthID(ref string pAuth_id); *

bool GetFileServerInfo(ref string fsInfo); *

string GetIstallPath(); *

object GetLastErrorResID(); *

int GetNatureDate(ref short iPeriod, ref DateTime dateBegin, ref DateTime dateEnd);

*

int GetPeriod(DateTime dCurDate, ref short iYear, ref short iPeriod); *

short IAMonthHandled(ref Connection ObjDatabase); *

bool InternalConstructLogin(string userToken, object LoginUserData);*

bool Login(ref string pSubId, ref string pAccId, ref string pYearId, ref string pUserId,

ref string pPassword, ref string pDate, ref string cSrv, ref string cSerial); *

bool LoginEx(ref string pSubId, ref object SSData); *

short PSExpireThreeMonth(ref Connection dbs); *

short PUMonthHandled(ref Connection cnn); *

object RemoteExec(ref string cCmd); *

void set_cAcc_Id(ref string __p1); *

void set_TaskId(ref string __p1); *

void ShutDown(); *

bool TaskExec(string pAuth_id, short bIsLock, short iYear); *

bool TaskExecEx(string pAuth_id, short bIsLock, short iYear, string pAuthClassCode);

*

string UnlockInfoEx(string cIn);

本文标签: 表单实体属性类型