功能概述
首先,简单介绍一下自动赋值的意思。就是程序根据给定的条件,给某一个数据对象的某个字段自动填值。
类似功能单独定制开发写程序也能实现。通用赋值程序只是赋值规则简化到了配置文件中。后续如果赋值规则变更,只需要修改配置文件。不需要修改源代码。
通用程序还解决了一些AgilePLM的公共技术问题。例如:并发控制,更新事件的递归触发问题。
目前主要应用场景:自动合并描述,自动编号等,下面还会有详细功能介绍。
功能特性
- 支持给多种对象自动赋值,例如:物件,变更,供应商等。
- 支持给同一个对象的多个字段自动赋值,例如:编号、描述、工作流等字段。
- 支持同一个字段在多种事件配置下自动赋值,例如:同一个自动编码规则可以标题块更新事件,创建对象事件,另存为事件下触发执行。
- 支持给变更的所有受影响物件字段自动赋值(可通过状态变更事件)。
- 支持给不同分类对象配置不同赋值规则。也支持分类再加其他自定义条件。
- 支持给大文本字段配置默认值,可以配置表格或其他html元素。
- 支持动态列表类型字段,可以获取列表中对象的字段,并且支持多级获取。例如:`$3521.3210.1543`
- 支持变更受控字段,在当前待定变更中的读取值和自动赋值。
- 要赋值的字段支持文本,数字,单列表,对象。赋值条件支持动态列表。
- 支持多种途径修改xml配置文件。每个项目不同环境可以指定不同的配置文件。可以内置在程序内部也可以是程序外部,也可以通过plm的变更流程上传xml配置文件
- 赋值规则支持Aviator表达式引擎。支持加、减、乘、除、三目运算符等多种运算符以及内置函数,还可以自定义函数。aviator参考文档。
暂不支持的功能
- 不支持给多列表字段赋值。
- 不支持赋值之前给要赋的值做校验。可根据要求额外定制开发。
- 变更受控字段,以下场景不支持。
- 由于流程中的编辑是可以撤销的。但撤销时是不会触发更新标题块事件的。所以无法自动赋值
安装使用
- 前提:请将agile-support项目的jar包安装到Agile进程扩展目录中。
- 根据当前项目公司名称,新建新的定制px项目。建议:从老的项目或者模板上复制。
- 根据业务要求,将赋值规则写入到AutoSetValue.xml文件中。
- 启动Agile控制台,在控制台中新建事件程序,指向com.purvar.px.AutoSetValueEvent
- 根据业务要求,新建事件和事件订户关联事件处理程序。
- 登录Agile,进行业务操作,测试功能是否符合预期。
功能案例
自动编码
总体说明
自动编码的意思是:根据用户给的业务规则自动给编码字段赋值,例如,物料编码,变更编码等。
自动赋值涉及2个部分,一个是赋值条件,另一个是赋值规则表达式。
当前的数据符合赋值条件才会执行对应的赋值规则表达式。
按照部件类型区分赋值规则
业务需求
要求自动合成物件编码,根据不同的部件类型区分不同的赋值规则。
例如:
- 成品:固定前缀'A'+$1550字段的值
- 半成品:固定前缀'B'+$1550字段的值
- 原材料:固定前缀'C'+$1550字段的值
xml配置参考如下
<AutoSetValue class="com.purvar.px.AutoSetValueEvent">
<setValues>
<!-- 1001是编号字段,1081是部件类型字段 -->
<setValue className="Item" setFieldId="1001" subClassId="1081" useName="true">
<valueMaps>
<!--autoNumber函数会根据api名称,自动读取agile的自动编码下一个值 -->
<map key="成品" expression="'A'+$1550" />
<map key="半成品" expression="'B'+$1550" />
<map key="原材料" expression="'C'+$1550" />
</valueMaps>
</setValue>
</setValues>
</AutoSetValue>
多个字段组合区分赋值规则
案例:部件类型+第三页的产品线(字段id:2024)组合决定赋值规则。例如:
- 成品产品线1,赋值规则:固定前缀A+固定产品线代号c1+序号
- 成品产品线2,赋值规则:固定前缀A+固定产品线代号c2+序号
- 半成品产品线1,赋值规则:固定前缀B+固定产品线代号c1+序号
- 半成品产品线2,赋值规则:固定前缀B+固定产品线代号c2+序号
这种场景需要多配置一个key的映射规则,xml配置如下
<AutoSetValue class="com.purvar.px.AutoSetValueEvent">
<setValues>
<!-- 1001是编号字段,1081是部件类型字段 -->
<setValue className="Item" setFieldId="1001" subClassId="1081" useName="true">
<keyMaps>
<!-- 将部件类型和产品线组成一个复合条件来匹配表达式 -->
<map value="*" expression="$1081+$2024"/>
</keyMaps>
<valueMaps>
<!--autoNumber函数会根据api名称,自动读取agile的自动编码下一个值 -->
<map key="成品产品线1" expression="'AC1'+autoNumber('n1')" />
<map key="成品产品线2" expression="'AC2'+autoNumber('n1')" />
<map key="半成品产品线1" expression="'BC1'+autoNumber('n1')" />
<map key="半成品产品线1" expression="'BC2'+autoNumber('n1')" />
</valueMaps>
</setValue>
</setValues>
</AutoSetValue>
自动读取数据库最大值生成编码
业务需求
要求对实验仪器物件对象进行自动编号,需要根据部件类型+1543字段进行区分不同的编码规则。自动读取数据库中的最大值+1,然后生成4位编码
<!-- 对实验仪器编号进行赋值 updateNewNumber="true"用于将生成的新编号放入内存中方便后续的事件读取-->
<setValue className="Item" setFieldId="1001" subClassId="1081" updateNewNumber="true" disableAgileWarning="true">
<keyMaps>
<!--部件类型+1543字段做为组合赋值条件-->
<map key="YIQI" expression="$1081+getApi(1543)"/>
</keyMaps>
<valueMaps>
<!--dbNext函数,自动根据前缀读取数据库中的最大值+1,4代表生成的编号为4位。例如:0001,0002-->
<map key="YIQICWJS" expression="dbNext('CW-TZ-YF-J',4)" />
<map key="YIQICWBF" expression="dbNext('CW-TZ-YF-J',4)" />
<map key="YIQIHWZZ" expression="dbNext('HW-TZ-YF-J',4)" />
<map key="YIQIGWBJ" expression="dbNext('JW-TZ-YF-J',4)" />
<map key="YIQIGWZD" expression="dbNext('JW-TZ-YF-J',4)" />
<map key="YIQIGWTZ" expression="dbNext('JW-TZ-YF-J',4)" />
</valueMaps>
</setValue>
只在草稿状态时合成编码
业务要求
当物料处在草稿状态时,符合指定条件才需要自动合成编码。当物料走过变更指令发布之后则不再需要合成编码。也可以理解为一旦物料同步给其他系统之后物料编码不能再改变了。
xml参考配置,
<setValue className="Item" setFieldId="1001" useName="true" subClassId="1081">
<keyMaps>
<!-- 1539是第三页上的字段将他和生命周期形成一个组合条件 -->
<map key="RZ体系文档" expression="$1539+'-'+$1084"/>
</keyMaps>
<valueMaps>
<!-- checkUpdateIds的意思是只有当这里面指定的字段值发生变更时才会执行自动赋值规则 -->
<map key="三级部门文件-草稿" expression="dbNext('R'+getApi(1540)+'I_', 3)" checkUpdateIds="1540,1539"/>
</valueMaps>
</setValue>
自动合成描述
业务需求
自动根据规则合成描述字段的值。需要根据物料不同的部件类型指定不同的合成规则。还要获取到制造商页签中的信息。
参考xml配置
<setValue className="Item" setFieldId="1002" useName="true" subClassId="1081" trimString=",">
<!-- trimString的功能:当合成描述的字段中某个字段为空时,导致首尾或者中间出现多个逗号,例如:aa,,bb,,会自动删除变成:aa,bb -->
<!-- getManuFunction是一个自定义函数,用于获取物料制造商页签的值 -->
<valueMaps>
<map key="Industrial Computer" expression="$1081+','+getManuFunction(1902)+','+$1575+','+$1576+','+$1577"/>
<map key="MB" expression="'PC,'+$1081+','+getManuFunction(1902)+','+$1575+','+$1579+','+$1576"/>
<map key="BP" expression="'PC,'+$1081+','+getManuFunction(1902)+','+$1575+','+$1579+','+$1576"/>
<map key="PDB" expression="'PC,'+$1081+','+getManuFunction(1902)+','+$1575+','+$1579+','+$1576"/>
<map key="PIB" expression="'PC,'+$1081+','+getManuFunction(1902)+','+$1575+','+$1579+','+$1576"/>
<map key="FP" expression="'PC,'+$1081+','+getManuFunction(1902)+','+$1575+','+$1579+','+$1576"/>
<map key="VROC Key" expression="$1081+','+getManuFunction(1902)"/>
<map key="replaceGroup" expression="$1577+','+$1575+','+$1576"/>
</valueMaps>
</setValue>
自动升级版本和生命周期
业务需求
当变更提交时需要根据给定的规则自动升级版本和指定生命周期字段。并且不同的变更类型可以指定不同的版本升级规则。
<!-- 对变更受影响物件的新版本字段进行赋值 -->
<setValue className="IRow" setFieldId="1056" subClassId="1081">
<valueMaps>
<!-- versionNext说明:判断变更类型,读取每一行的老版本,如果老版本为空则为V01,如果不为空则解析其中的数字,然后+1,再补足2位。 -->
<map keyExpression="dataObjSrcType == '文档发布审批单'" expression="versionNext($1055, 'V01', 1)" checkEmpty="true"/>
<map keyExpression="dataObjSrcType == '文档变更审批单'" expression="versionNext($1055, 'V02', 1)" checkEmpty="true"/>
<map keyExpression="dataObjSrcType == '文档废弃审批单'" expression="versionNext($1055, 'O02', 1)" checkEmpty="true"/>
<map keyExpression="dataObjSrcType == '转产申请单'" expression="versionNext($1055, 'V02', 1)" checkEmpty="true"/>
</valueMaps>
</setValue>
<!-- 对变更受影响物件的生命周期字段进行赋值 -->
<setValue className="IRow" setFieldId="1057" subClassId="1081">
<valueMaps>
<map keyExpression="dataObjSrcType == '文档发布审批单'" expression="'生效'" checkEmpty="true"/>
<map keyExpression="dataObjSrcType == '文档变更审批单'" expression="'生效'" checkEmpty="true"/>
<map keyExpression="dataObjSrcType == '文档废弃审批单'" expression="'作废'" checkEmpty="true"/>
<map keyExpression="dataObjSrcType == '转产申请单'" expression="'生效'" checkEmpty="true"/>
</valueMaps>
</setValue>
<setValue className="Change.IRow">
<!-- 当发生状态变更事件时。要对变更受影响物件中的每一行执行自动赋值,默认只会处理变更本身 -->
</setValue>
自动给大文本字段赋值
业务需求
当变更创建时,自动给大文本字段初始化一个表格,用户可以在表格中填写内容。
<!-- 变更流程-设置大文本 -->
<setValue className="Change" setFieldId="2000025512" subClassId="1081">
<keyMaps>
<map key="CPBG" expression="$1069"/>
</keyMaps>
<valueMaps>
<map key="CPBG" checkEmpty="true">
<value>
<![CDATA[<table align="left" border="1" cellspacing="0" style="width:750px">
<tbody>
<tr>
<td style="height:21px; text-align:center; width:10%"><strong>序号</strong></td>
<td style="text-align:center; width:45%"><strong>变更前</strong></td>
<td style="text-align:center; width:45%"><strong>变更</strong>后</td>
</tr>
<tr>
<td style="height:20px; text-align:center"> </td>
<td style="text-align:center"> </td>
<td style="text-align:center"> </td>
</tr>
<tr>
<td style="height:20px; text-align:center"> </td>
<td style="text-align:center"> </td>
<td style="text-align:center"> </td>
</tr>
<tr>
<td style="height:20px; text-align:center"> </td>
<td style="text-align:center"> </td>
<td style="text-align:center"> </td>
</tr>
<tr>
<td style="height:20px; text-align:center"> </td>
<td style="text-align:center"> </td>
<td style="text-align:center"> </td>
</tr>
</tbody>
</table>]]>
</value>
</map>
</valueMaps>
</setValue>
自动带出动态列表的某个字段
业务需求
产品品名为文档对象,当他的客户品名字段(动态列表型字段)选中了某个客户品名时,自动将选中值的9384字段带到12503字段上。
参考xml配置
<!-- 产品品名,属性复制客户品名 -->
<setValue className="Item" setFieldId="12503" useName="true" disable="false" disableAgileWarning="true">
<valueMaps>
<map key="01-产品品名" expression="$1555.9384" checkUpdateIds="1555"/>
</valueMaps>
</setValue>
自动设置默认工作流
业务需求
要求自动给工作流赋值,如果用户选了工作流,则不覆盖。
参考xml配置
<!--流程,对工作流赋值-->
<setValue className="Change" setFieldId="3742" subClassId="1069">
<valueMaps>
<!-- checkEmpty="true"意思是,只有当工作流为空时才赋值。如果用户自己选了工作流则不覆盖 -->
<map key="WDNBFB" expression="'WF_WD_NB_FB'" checkEmpty="true"/>
<map key="WDNBBG" expression="'WF_ED_NB_BG'" checkEmpty="true"/>
<map key="WDNBFQ" expression="'WF_WD_NB_FQ'" checkEmpty="true"/>
<map key="WDHQFB" expression="'WF_WD_HQ_FB'" checkEmpty="true"/>
<map key="WDHQBG" expression="'WF_WD_HQ_BG'" checkEmpty="true"/>
<map key="WDHQFQ" expression="'WF_WD_HQ_FQ'" checkEmpty="true"/>
<map key="YFWLFB" expression="'WF_YFYWL_FB'" checkEmpty="true"/>
<map key="YFWLBG" expression="'WF_YFYWL_BG'" checkEmpty="true"/>
<map key="YFWLFQ" expression="'WF_YFYWL_FQ'" checkEmpty="true"/>
<map key="LCWLFB" expression="'WF_LCWL_FB'" checkEmpty="true"/>
<map key="LCWLBG" expression="'WF_LCWL_BG'" checkEmpty="true"/>
<map key="LCWLFQ" expression="'WF_LCWL_FQ'" checkEmpty="true"/>
<map key="CPBG" expression="'WF_CPBG'" checkEmpty="true"/>
<map key="ECR" expression="'WF_SJBG'" checkEmpty="true"/>
<map key="SY_SH" expression="'WF_SYLC'" checkEmpty="true"/>
<map key="SY_IVD" expression="'WF_SYLC'" checkEmpty="true"/>
<map key="SY_JWYX" expression="'WF_SYLC'" checkEmpty="true"/>
<map key="SY_YLQX" expression="'WF_SYLC'" checkEmpty="true"/>
<map key="SY_FJ" expression="'WF_SYLC'" checkEmpty="true"/>
<map key="SY_CH" expression="'WF_SYLC'" checkEmpty="true"/>
<map key="SY_YP" expression="'WF_SYLC'" checkEmpty="true"/>
<map key="SY_MSJ" expression="'WF_SYLC'" checkEmpty="true"/>
<map key="ZCSQ" expression="'WF_ZCSQ'" checkEmpty="true"/>
<map key="CPZLWT" expression="'WF_CPZLWT'" checkEmpty="true"/>
</valueMaps>
</setValue>