【转】金蝶EAS BOS工作流开发(附带JAVA脚本)
目录(?)[+]
- 流程配置基本知识及示例
- 重要概念
- 流程变量
- 任务输入输出
- 注意事项
- 基本流程的配置示例
- 单流程
- 审批流程
- 带分支的审批流程
- 常见的流程配置需求
- 配置参与人
- 配置多级审批
- 函数节点
- 用流程变量配置条件参予人
- 工作流脚本
- JAVA脚本
- 多UI相同实体需要触发不同的流程条件启动流程
- 重要概念
1. 流程配置基本知识及示例
1.1. 重要概念
1.1.1.流程变量
流程变量是工作流引擎和业务系统的数据交互的桥梁。
工作流承载业务,驱动业务流程,但是不会执行业务。工作流中的业务执行,全部都会委托给具体的业务模块执行。那么,这些被工作流分割的业务功能,在工作流中被调用执行的时候,如何保证做操作的数据的一致性?
通过流程变量,在每一步的业务功能执行的过程中,将业务数据保存在流程变量中,那么整个流程的后续活动中,都可以引用该流程变量,来完成业务功能,保证业务数据的一致性。
例如:在凭证的审批流程中,新增凭证审批,审批的时候为什么可以正确定为到刚刚提交的那张凭证,而不是别的凭证?流程变量起到了重要的作用。在凭证新增之后,将可唯一标示凭证的ID保存到流程变量中,在审批的时候将流程变量中的值传递给凭证,就可以根据这个ID获取到一张凭证了。
流程变量在流程实例的生命周期内都是有效的。
1.1.2.任务输入输出
任务输入:在业务发生之前,有工作流传递给业务的数据。以凭证的过账为例,某个用户收到一条凭证过账的消息,双击消息处理。在双击之后、凭证的界面弹出之前,工作流会把定义的入口参数变量中的值传递给凭证,凭证根据这个值来展现特定的单据,展现特定的功能。
任务输出:在业务发生之后,由业务系统传递给工作流,需要保存在流程变量中的数据。仍以凭证过账为例,在用户操作完凭证过账之后,工作流继续流转之前,如果流程定义中定义了任务的输出,那么,就会将凭证对应的属性的数据,保存在流程变量中。已备在后续的流程活动中使用。
1.2. 注意事项
l 绘画工作流图之前一定要先将业务流整理清楚,分析业务流的特性,提取可以抽象出来公用的东西,分析是否可以进行优化等,好的业务流程可以直接映射为工作流流程。
l 利用“流程变量”的威力,建立单据和流程之间数据交换的桥梁。输入输出参数用来在流程和单据之间进行数据的传递。输入输出参数和流程变量搭建了流程和单据之间的数据联系通道。
l 流程变量赋值时需注意:变量是否在另外地方被改变,有子流程时变量关系如何匹配,对应的是否正确,每个节点对应的变量是否正确,不同的节点可能对应不同的单据id,给变量赋值时需特别细心。
l 如存在一些系统预定义功能无法满足的需求,可以采用自己开发功能,根据输入参数和输出参数来与工作流交互,如在单据中增加function,绑定到自动节点执行,或者是利用脚本节点,获取一些有用的信息输出到流程变量中在工作流中使用。还可以利用工作流的一些新增功能,比如利用函数节点,BOTP节点等来执行特殊需求。
l 参与人动态变化或根据条件变化时,可以充分利用“参与人变量”作为动态值,变量的值可以通过各种方式获取,比如脚本式(后置脚本或脚本活动)、或者任务输出属性方式等。(流程变量中可以定义类型为参与人的变量)
l 利用条件参与人设置一些动态的参与人场景。比如当某条件满足时,设置为某些参与人,当条件不满足或为另外情况时,设置为另外的参与人,通过条件参与人和参与人变量可以满足大部分复杂的参与人场景。条件参与人的参与人范围还可以做为运行期指定下一步活动的参与人范围。
l 善于利用路由节点,除了可设置模式外,还可以对流程图进行美化。
l 一些公用的业务逻辑可以单独抽取出来配置为子流程给其他流程共用,减少维护的流程数量,比如一些常用的审批流程等。
1.3. 基本流程的配置示例
1.3.1.单流程
说明:流程只有一个人工型活动,完成凭证提交的任务,流程结束。没有具体的业务含义。
以凭证提交的业务为例。流程图如下:
定义步骤:
1、 拖入开始、结束活动
2、 拖入人工型活动,用连接弧连接起来。
3、 定义人工型活动
首先,定义人工型活动的任务,选择任务
选定任务后,定制任务的输入输出。
输入参数是由任务定义带出的
根据任务输入的意义,指的是在凭证提交之前,由工作流告知凭证的数据。新建一个流程变量,绑定该输入。
这里绑定的意思是:在提交之前,工作流会将billID这个流程变量中的数据传递给业务。业务拿到这个值之后,会根据业务需要做出判断。
[说明]所有人工型任务的输入参数,全部是在定义任务的时候就定义好的。每个任务的输出参数可能不同,是由于各个不同的业务系统对于业务开始之前,所需要的数据不同导致。但是在EAS系统中,基本上任务的输入参数只有一个BOID类型的参数。这是因为一般来说,通过这样一个类型的值,就可以完全定位一个业务单据,并且拿到这个业务单据,就可以满足大部分的业务需求了。
这里,将ID属性输出,并且选定输出的流程变量是billID
凭证提交完毕后,将可以唯一标示一张凭证的ID属性保存在流程变量billID中,在后续的活动中,如果还需要操作这张凭证,就可以通过billID来唯一定位这张凭证,保证业务的一致性。
参与人定义中,分为了默认参与人和条件参与人。工作流在获取执行人的时候,首先根据条件来逐个扫描条件参与人,发现没有符合,那么会取默认参与人。
这里简单处理,选择任意人。
提交就可以匹配到该流程
到现在为止,这条简单的流程就已经定义完毕。发布。到EAS中提交凭证,然后到工作流监控中,会发现有一条流程实例,并且状态是已完成。
1.3.2.审批流程
说明:单据提交之后,经过一层审批,流程结束。
以凭证为示例。流程图如下
定义步骤:
1、 同场景1.3.1拖入活动
2、 增加一个审批活动,如图画连接弧
3、 配置提交活动。和场景1.3.1中一样选择任务,参与人也是任意人。但是任务的输出夺一项。由于在后续的消息中想展现出单据的编码,所以多输出一个单据编码到一个流程变量number中
4、 配置审批活动。为了方便测试,参与人设定为流程发起人的本人
这一部分,就是任务输入。对于现在的场景,审批凭证,那么在业务单据内码这一栏选中billID。此时billID已经在提交之后,保存了刚刚提交的凭证的ID。一旦这个审批任务发生执行,那么,在执行前,工作流会将billID这个变量中保存的值传给业务系统。那么审批时就可以唯一定位到一条业务单据。
任务输出,选择将审批结果输出到一个枚举型的流程变量 审批结果 中。
定制审批消息
流程定义完毕。发布,在EAS中执行。
提交凭证,在消息中心收到一条消息,审批,通过。然后回到凭证序时簿,察看该流程,发现,凭证的状态还是“提交”而不是“审核”。
这是因为工作流中的多极审批,只是单纯的驱动流程,做一个选择而已,不会修改业务数据。
为了能够让凭证打上审批标记,按照如下方式修改流程定义
最后的这个自动活动,就完成给凭证打审核标记的功能。
任务选择如下:
保存、发布,再到EAS中执行一下。发现审批状态打上了。
1.3.3.带分支的审批流程
说明:审批通过,则打审批状态。审批不通过,返回修改。
仍以凭证为例。流程定义如下:
定义步骤
1、 提交、审批、自动节点的设置和场景2中一样。
2、 增加一个人工型活动,修改。选择的任务和“提交”一样。但是由于单据的ID和单据的编码是新增的时候就定好的,无法修改。所以只需要定义任务输入就可以了,不需要定义任务输出。
谁提交的谁修改,参与人设置为流程发起人本人
定制修改消息
3、 编辑连接弧
首先编辑“审批”到“自动”的连接弧。
建模工具会自动根据之前的定义识别枚举,然后将枚举的值也会自动列在选择范围内。
然后编辑“审批”到“修改”的连接弧。按照如下方式设置条件
保存。流程定制完毕。发布。
[说明]业务单据一旦进入工作流,就要受到工作流的约束。例如,刚刚提交完凭证,流程执行到审批节点。这个时候工作流要求的行为是“某个人执行审批操作”。如果这个时候修改凭证,会提示:“已在工作流处理中,任务不匹配”。
1.4. 常见的流程配置需求
1.4.1.配置参与人
1.4.2.配置多级审批
管理员收到申请单后,传给多个领导。由各领导分别进行审批,审批不通过的要能够来回进行审批。直到审批通过,也即是多级审批,每级审批不通过回到相应的审批节点继续进行审批。
流程配置
面对此种问题首先想到的应该是通过流程变量来设置审批节点的标志,在每级审批节点完成后设置一个标志,标志目前走到那个审批级别,如果不通过,根据流程变量上审批标志的值直接回到此审批节点。具体配置请查看下面截图:
完整流程图
综合处审批节点后置脚本
总结:充分利用流程变量作为流程流转的条件
1.4.3.函数节点
需要重复使用某些脚本,希望能减低脚本维护的复杂度,同时提高脚本的复用率和使用效率。
解决办法
已经内置了函数节点的支持,函数节点本质上和脚本节点没有任何区别,所处理的任务和职责都是一样,但脚本节点脚本散落在流程中各个地方,维护和使用非常困难。函数节点的目的就是为了减低流程配置中脚本维护的复杂度和可重用性低的问题。具体使用请参考如下的说明:
在工具菜单 窗口->显示视图,查找选择工作流视图组->函数定义
点击确定后会出现函数定义的界面,其中已经内置了一些函数,双击选择的某个函数可以打开函数编辑界面
函数编辑界面,在此可以定义函数的输入输出以及一些描述性的说明,并可在编辑框内输入具体的代码(目前支持KScript和java代码),代码其实就是脚本。
然后定义工作流,在流程定义中增加一个函数节点。
在函数任务界面选择函数定义,会弹出函数定义选择界面,选择合适的函数即可。
在函数任务界面配置好函数的输入输出参数即可在流程中使用此函数的输出值。
如需自己定义函数,直接在函数视图中按照右键菜单提示进行操作即可。
1.4.4.用流程变量配置条件参予人
员工提交单据后,进行第一级审批,第一级审批参与人设置条件:如果是提交单据的是财务部员工,则参与人为财务部某一职员进行审批,如果不是财务部提交的单据,则提交人所在部门(归口部门)的直接上级进行审批,如果直接上级是部门负责人则上级审批完成流程就继续往下走,如果直接上级不是部门的负责人则还需要部门的负责人进行审批。
配置步骤:
首先画出流程草图,将大致的图形先画出来。
在提交单据节点输出提交人的部门到流程变量“归口部门”,并在后置脚本中根据归口部门的值设置流程变量“是否财务部”的值。
在审批节点设置条件参与人,根据流程变量 “是否财务部”来设置相关的条件参与人,并将审批人输出到流程变量“审批人”中。
在审批节点后设置一脚本节点->负责人判断,用来判断上级审批的人员是否是部门负责人。如果是则流程结束。如果不是则继续在部门内多级审批,直到部门负责人审批完成(循环过程)。负责人判断的脚本内容为:
是否部门负责人=
com.kingdee.bos.workflow.participant.ParticipantHelper.isOrgPrincipal(
__bosContext,审批人,归口部门);
其中,是否为部门负责人,审批人,归口部门为流程变量。
最终流程如下:
总结:充分利用了条件参与人与流程变量,并通过脚本来获取流程必须的信息。
2. 工作流脚本
2.1.JAVA脚本
在工作流中经常会需要使用到一些脚本来获取单据的信息或者是执行一些特殊的操作,脚本应如何写?需要注意那些地方?有没有更好的定义和使用方法?
解决方法
工作流脚本利用的是java语法,所有的java代码都可以被工作流解析,但所有的类必须是全路径名称(除了java.lang.*包下的类),如List 必须写成java.util.List。在工作流中内置了一些变量和函数可以进行使用,如:“__bosContext”内置变量表示服务端的context。在工作流脚本中可以直接使用定义好的流程变量,脚本执行过程中会将脚本的值自动赋值给相应的流程变量。在内置函数节点可以用来封装脚本,减轻脚本维护的复杂度和提高可重用性。
工作流中内置的一些函数
如下是一些脚本的示例:
l 根据人获取对应主负责的行政组织脚本:
首先新建一个流程变量 BOID类型 例如 orgId
String userId = "";
//获取User对象的远程控制接口
com.kingdee.eas.base.permission.IUser iUser =com.kingdee.eas.base.permission.UserFactory
.getLocalInstance(__bosContext);
com.kingdee.eas.base.permission.IUser iUser =com.kingdee.eas.base.permission.UserFactory
.getLocalInstance(__bosContext);
com.kingdee.eas.basedata.person.PersonInfo info =iUser.getUserInfo(
new com.kingdee.bos.dao.ormapping.ObjectUuidPK(
com.kingdee.bos.util.BOSUuid.read(userId))).getPerson();
if (info != null) {
String personId = info.getId().toString();
com.kingdee.eas.basedata.org.IPositionMemberiPositionMember =
com.kingdee.eas.basedata.org.PositionMemberFactory
.getLocalInstance(__bosContext);
com.kingdee.eas.basedata.org.PositionMemberInfopositionMemberInfo = iPositionMember
.getPositionMemberInfo("select
position.adminOrgUnit.id where person.id = '"+personId + "' and isPrimary = 1");
orgId =positionMemberInfo.getPosition().getAdminOrgUnit().getId();
}
l 根据组织的id获取公司的名称,然后在条件参与人中根据此进行判断
1、 增加一个流程变量adminId、companyId、companyNum。都是字符串型
2、 在新增节点的任务输出中,输出组织的ID到adminId变量中
3、 增加脚本节点,其中脚本如下:
companyId =
com.kingdee.eas.basedata.person.app.PersonToWFAdapter.getCompanyIdByAdminId(__bosContext,adminId);
com.kingdee.eas.basedata.org.INewOrgUnitFacadeiOrg =
com.kingdee.eas.basedata.org.NewOrgUnitFacadeFactory.getLocalInstance(__bosContext);
com.kingdee.eas.basedata.org.CompanyOrgUnitInfofiInfo =
(com.kingdee.eas.basedata.org.CompanyOrgUnitInfo)
iOrg.getDelegateUnit(companyId,com.kingdee.eas.basedata.org.OrgType.Company);
if (fiInfo != null) {
companyNum =fiInfo.getNumber();
}
l 判断有无直接上下级的脚本
首先定义一流程变量,类型为布尔:有直接上级
com.kingdee.bos.workflow.service.ormrpc.IEnactmentServiceservice = new
com.kingdee.bos.workflow.service.ormrpc.EnactmentService(__bosContext);
com.kingdee.bos.workflow.ProcessInstInfo[]procInstInfos =
service.getProcessInstanceByHoldedObjectId(billID.toString());
com.kingdee.bos.workflow.ProcessInstInfocurProcInst = null;
for (int i = 0, n =procInstInfos.length; i < n; i++) {
if(procInstInfos[i].getState().startsWith("open.run")) {
curProcInst =procInstInfos[i];
}
}
if (curProcInst != null) {
initUserId =curProcInst.getInitiatorId();
com.kingdee.eas.basedata.person.app.PersonToWFAdapteradapter = new
com.kingdee.eas.basedata.person.app.PersonToWFAdapter();
com.kingdee.bos.workflow.participant.Person[]persons =
adapter.getSupervisor(__bosContext, initUserId);
if (persons != null&& persons.length > 0 && persons[0] != null) {
有直接上级 = true;
} else {
有直接上级 = false;
}
}
l 委托时,判断审批人是否是部门负责人
判断审批人是否是部门负责人,如果审批人是委托任务处理人,则判断委托人是否是部门负责人
变量声明:
下述脚本使用了如下变量:
__bosContext: 系统内置变量
单据Id : 单据内码,一般由单据直接输出
归口部门: 类型为字符串,为部门id
审批人: 类型为字符串,为审批任务的处理人,在审批节点中输出
审批节点名称: 类型为字符串,为节点定义名称
是否部门负责人: 类型为布尔,为返回的结果值,用来在流程中判断
com.kingdee.bos.workflow.enactment.WfEngineengine =
com.kingdee.bos.workflow.enactment.WfEngine.getEngine(__bosContext);
com.kingdee.bos.workflow.ProcessInstInfo[]infos =
engine.getProcessInstanceByHoldedObjectId(单据Id);
if(infos!= null && infos.length>0){
ProcessControlDataKScriptAdapteradapter =
newProcessControlDataKScriptAdapter(infos[0],engine.getLocale(),engine);
String constituentUserId=adapter.getTopConstituent(审批节点名称);
if(constituentUserId !=null&& !constituentUserId.trim().equals("")){
//有委托人,判断委托人是否是部门负责人
是否部门负责人
=com.kingdee.bos.workflow.participant.ParticipantHelper.isOrgPrincipal (
__bosContext ,constituentUserId ," 归口部门) ;
}else{//没有委托人,直接判断审批人是否有直接上级
是否部门负责人
=com.kingdee.bos.workflow.participant.ParticipantHelper.isOrgPrincipal (
__bosContext ,审批人 ,归口部门) ;
}
} else{
是否部门负责人
=com.kingdee.bos.workflow.participant.ParticipantHelper.isOrgPrincipal (
__bosContext ,审批人 ,归口部门) ;
}
l 在脚本中执行SQL语句
java.lang.StringBuffersql = java.lang.new StringBuffer();
//将SQL语句保存到sql对象中
//…
java.sql.Connectioncon =
com.kingdee.bos.framework.ejb.EJBFactory.getConnection(__bosContext);
java.sql.StatementbatchStatement = con.createStatement();
batchStatement.execute(sql.toString());
com.kingdee.util.db.SQLUtils.cleanup(batchStatement,con);
com.kingdee.util.db.SQLUtils.cleanup(con);
l 将活动的参与人设为单据对应部门的负责人
场景:在单据上有个“费用的承担部门”的属性,现在要将审批活动的参与人设置为该部门的负责人。
1. 声明变量
var_principal 外部数据类型
var_orgUnitId 内码(BOID)
2. 在做业务单据时(审核节点之前)将单据上的“费用的承担部门”的ID关联到var_orgUnitId变量中 ,并在该节点的后继脚本中填入如下内容:
com.kingdee.eas.basedata.org.AdminOrgUnitInfo adminInfo = com.kingdee.eas.basedata.org.AdminOrgUnitFactory.getRemoteInstance().getAdminOrgUnit(var_orgUnitId);
if(adminInfo != null && adminInfo.getResponPosition != null)
{
com.kingdee.eas.basedata.org.IPosition iPosition = com.kingdee.eas.basedata.org.PositionFactory.getRemoteInstance();
com.kingdee.eas.basedata.person.PersonCollection pColl = iPosition.getAllPersons(adminInfo.getResponPosition.getId());
var_principal = new String[pColl.size()];
for (int i=0; i<pColl.size(); i++) {
com.kingdee.eas.basedata.person.PersonInfo pi = pColl.get(i);
var_principal[i] = pi.getId().toString();
}
}
3. 在审核节点中定义参与人,选择为参与人变量,并把var_princial添加进去。
l 根据分录信息循环发送消息给业务员
收集:脚本一
java.lang.String commonStr = data +"," + billNumber + "," + chauffeur + "," +regnumber + "," + contact + ".";
java.lang.HashMap map = newjava.lang.HashMap();
for (int i=0; i<records.size(); i++) {
//请替换成出车单的分录对象
com.kingdee.eas.fi.gl.VoucherEntryInforecord = records.get(i);
java.lang.String s =record.get("wareName") + "(" + record.get("wareNumber") + ")已发往" + record.get("customer") + ";";
java.langString op =record.("operator").getId().toString();
if (map.get(op) == null) {
map.put(op, s);
} else {
map.put(map.get(op) + s);
}
}
userList = new java.util.ArrayList();
msgList = new java.util.ArrayList();
//此段已废弃 begin
for (java.lang.Iterator i = map.getKeySet.iterator();i.hasNext();) {
Object key = i.next();
Object msg = map.get(key);
userList.add(key);
msgList.add(commonStr + msg);
}
//此段已废弃 end
修改为:
list = new java.util.ArrayList();
list.addAll(map.keySet());
for (int i=0; i<list.size(); i++) {
Object key = list.get(i);
Object msg = map.get(key);
userList.add(key);
msgList.add(commonStr + msg);
}
pos = 0;
count = userList.size();
if (count > 0) {
user = userList.get(0);
msg = msgList.get(0);
}
2.2.多UI相同实体需要触发不同的流程,条件启动流程
在EAS中经常碰到这种情形,有两套UI对应一个实体,此两个UI绑定的功能(Function)和操作(Operate)是一样。由于工作流是根据功能和操作来进行流程匹配的,这两个ui执行后都启用了同一个流程,需要在两套UI上提交的时候触发不同的工作流,如何实现?
解决办法
工作流目前支持两种方式的流程匹配方式:一种是根据Function和Operate以及用户信息来进行流程的匹配,如果两套UI使用的用户范围是不一样的,可以通过在不同的流程的第一个人工节点根据用户范围设置参与人,根据参与人来区分是要匹配那条流程。但如果两条流程使用的用户范围是一致的,此种方式不可用;第二种方式是根据流程启动条件来进行流程的匹配,通过在流程的第一个连接符上设置启动条件,可以根据一些绑定的业务单据对象的某个属性或其他内容来设置此流程启动的条件和场景。工作流系统中内置了一个__processTrigger变量,代表绑定的业务单据,可以使用此变量输出相关的业务属性来进行判断,详细的请查看如下图示:
图一.设置启动条件
图二.双击链接符,弹出设置条件界面
图三.内置变量支持打点弹出业务对象的所有属性特征
图四.最终设置条件,示例为只有当单据的number为121的时候才启动此流程,此处根据业务需求来设定
可以使用一些比较复杂的条件来做判断,只要最后返回一个boolean值即可,如下述代码:
com.kingdee.bos.dao.ormapping.ObjectUuidPK pk = new com.kingdee.bos.dao.ormapping.ObjectUuidPK(__processTrigger.getProposer().getId()); com.kingdee.bos.metadata.entity.SelectorItemCollection sic = new com.kingdee.bos.metadata.entity.SelectorItemCollection(); sic.add(new com.kingdee.bos.metadata.entity.SelectorItemInfo("id")); sic.add(new com.kingdee.bos.metadata.entity.SelectorItemInfo("name")); sic.add(new com.kingdee.bos.metadata.entity.SelectorItemInfo("employeeClassify.id")); sic.add(new com.kingdee.bos.metadata.entity.SelectorItemInfo("employeeClassify.name")); com.kingdee.eas.basedata.person.PersonInfo person = com.kingdee.eas.basedata.person.PersonFactory.getLocalInstance(__bosContext).getPersonInfo(pk,sic); return person.getEmployeeClassify().getName().equals("一般员工"); |
- 流程配置基本知识及示例
- 重要概念
- 流程变量
- 任务输入输出
- 注意事项
- 基本流程的配置示例
- 单流程
- 审批流程
- 带分支的审批流程
- 常见的流程配置需求
- 配置参与人
- 配置多级审批
- 函数节点
- 用流程变量配置条件参予人
- 工作流脚本
- JAVA脚本
- 多UI相同实体需要触发不同的流程条件启动流程
- 重要概念
1. 流程配置基本知识及示例
1.1. 重要概念
1.1.1.流程变量
流程变量是工作流引擎和业务系统的数据交互的桥梁。
工作流承载业务,驱动业务流程,但是不会执行业务。工作流中的业务执行,全部都会委托给具体的业务模块执行。那么,这些被工作流分割的业务功能,在工作流中被调用执行的时候,如何保证做操作的数据的一致性?
通过流程变量,在每一步的业务功能执行的过程中,将业务数据保存在流程变量中,那么整个流程的后续活动中,都可以引用该流程变量,来完成业务功能,保证业务数据的一致性。
例如:在凭证的审批流程中,新增凭证审批,审批的时候为什么可以正确定为到刚刚提交的那张凭证,而不是别的凭证?流程变量起到了重要的作用。在凭证新增之后,将可唯一标示凭证的ID保存到流程变量中,在审批的时候将流程变量中的值传递给凭证,就可以根据这个ID获取到一张凭证了。
流程变量在流程实例的生命周期内都是有效的。
1.1.2.任务输入输出
任务输入:在业务发生之前,有工作流传递给业务的数据。以凭证的过账为例,某个用户收到一条凭证过账的消息,双击消息处理。在双击之后、凭证的界面弹出之前,工作流会把定义的入口参数变量中的值传递给凭证,凭证根据这个值来展现特定的单据,展现特定的功能。
任务输出:在业务发生之后,由业务系统传递给工作流,需要保存在流程变量中的数据。仍以凭证过账为例,在用户操作完凭证过账之后,工作流继续流转之前,如果流程定义中定义了任务的输出,那么,就会将凭证对应的属性的数据,保存在流程变量中。已备在后续的流程活动中使用。
1.2. 注意事项
l 绘画工作流图之前一定要先将业务流整理清楚,分析业务流的特性,提取可以抽象出来公用的东西,分析是否可以进行优化等,好的业务流程可以直接映射为工作流流程。
l 利用“流程变量”的威力,建立单据和流程之间数据交换的桥梁。输入输出参数用来在流程和单据之间进行数据的传递。输入输出参数和流程变量搭建了流程和单据之间的数据联系通道。
l 流程变量赋值时需注意:变量是否在另外地方被改变,有子流程时变量关系如何匹配,对应的是否正确,每个节点对应的变量是否正确,不同的节点可能对应不同的单据id,给变量赋值时需特别细心。
l 如存在一些系统预定义功能无法满足的需求,可以采用自己开发功能,根据输入参数和输出参数来与工作流交互,如在单据中增加function,绑定到自动节点执行,或者是利用脚本节点,获取一些有用的信息输出到流程变量中在工作流中使用。还可以利用工作流的一些新增功能,比如利用函数节点,BOTP节点等来执行特殊需求。
l 参与人动态变化或根据条件变化时,可以充分利用“参与人变量”作为动态值,变量的值可以通过各种方式获取,比如脚本式(后置脚本或脚本活动)、或者任务输出属性方式等。(流程变量中可以定义类型为参与人的变量)
l 利用条件参与人设置一些动态的参与人场景。比如当某条件满足时,设置为某些参与人,当条件不满足或为另外情况时,设置为另外的参与人,通过条件参与人和参与人变量可以满足大部分复杂的参与人场景。条件参与人的参与人范围还可以做为运行期指定下一步活动的参与人范围。
l 善于利用路由节点,除了可设置模式外,还可以对流程图进行美化。
l 一些公用的业务逻辑可以单独抽取出来配置为子流程给其他流程共用,减少维护的流程数量,比如一些常用的审批流程等。
1.3. 基本流程的配置示例
1.3.1.单流程
说明:流程只有一个人工型活动,完成凭证提交的任务,流程结束。没有具体的业务含义。
以凭证提交的业务为例。流程图如下:
定义步骤:
1、 拖入开始、结束活动
2、 拖入人工型活动,用连接弧连接起来。
3、 定义人工型活动
首先,定义人工型活动的任务,选择任务
选定任务后,定制任务的输入输出。
输入参数是由任务定义带出的
根据任务输入的意义,指的是在凭证提交之前,由工作流告知凭证的数据。新建一个流程变量,绑定该输入。
这里绑定的意思是:在提交之前,工作流会将billID这个流程变量中的数据传递给业务。业务拿到这个值之后,会根据业务需要做出判断。
[说明]所有人工型任务的输入参数,全部是在定义任务的时候就定义好的。每个任务的输出参数可能不同,是由于各个不同的业务系统对于业务开始之前,所需要的数据不同导致。但是在EAS系统中,基本上任务的输入参数只有一个BOID类型的参数。这是因为一般来说,通过这样一个类型的值,就可以完全定位一个业务单据,并且拿到这个业务单据,就可以满足大部分的业务需求了。
这里,将ID属性输出,并且选定输出的流程变量是billID
凭证提交完毕后,将可以唯一标示一张凭证的ID属性保存在流程变量billID中,在后续的活动中,如果还需要操作这张凭证,就可以通过billID来唯一定位这张凭证,保证业务的一致性。
参与人定义中,分为了默认参与人和条件参与人。工作流在获取执行人的时候,首先根据条件来逐个扫描条件参与人,发现没有符合,那么会取默认参与人。
这里简单处理,选择任意人。
提交就可以匹配到该流程
到现在为止,这条简单的流程就已经定义完毕。发布。到EAS中提交凭证,然后到工作流监控中,会发现有一条流程实例,并且状态是已完成。
1.3.2.审批流程
说明:单据提交之后,经过一层审批,流程结束。
以凭证为示例。流程图如下
定义步骤:
1、 同场景1.3.1拖入活动
2、 增加一个审批活动,如图画连接弧
3、 配置提交活动。和场景1.3.1中一样选择任务,参与人也是任意人。但是任务的输出夺一项。由于在后续的消息中想展现出单据的编码,所以多输出一个单据编码到一个流程变量number中
4、 配置审批活动。为了方便测试,参与人设定为流程发起人的本人
这一部分,就是任务输入。对于现在的场景,审批凭证,那么在业务单据内码这一栏选中billID。此时billID已经在提交之后,保存了刚刚提交的凭证的ID。一旦这个审批任务发生执行,那么,在执行前,工作流会将billID这个变量中保存的值传给业务系统。那么审批时就可以唯一定位到一条业务单据。
任务输出,选择将审批结果输出到一个枚举型的流程变量 审批结果 中。
定制审批消息
流程定义完毕。发布,在EAS中执行。
提交凭证,在消息中心收到一条消息,审批,通过。然后回到凭证序时簿,察看该流程,发现,凭证的状态还是“提交”而不是“审核”。
这是因为工作流中的多极审批,只是单纯的驱动流程,做一个选择而已,不会修改业务数据。
为了能够让凭证打上审批标记,按照如下方式修改流程定义
最后的这个自动活动,就完成给凭证打审核标记的功能。
任务选择如下:
保存、发布,再到EAS中执行一下。发现审批状态打上了。
1.3.3.带分支的审批流程
说明:审批通过,则打审批状态。审批不通过,返回修改。
仍以凭证为例。流程定义如下:
定义步骤
1、 提交、审批、自动节点的设置和场景2中一样。
2、 增加一个人工型活动,修改。选择的任务和“提交”一样。但是由于单据的ID和单据的编码是新增的时候就定好的,无法修改。所以只需要定义任务输入就可以了,不需要定义任务输出。
谁提交的谁修改,参与人设置为流程发起人本人
定制修改消息
3、 编辑连接弧
首先编辑“审批”到“自动”的连接弧。
建模工具会自动根据之前的定义识别枚举,然后将枚举的值也会自动列在选择范围内。
然后编辑“审批”到“修改”的连接弧。按照如下方式设置条件
保存。流程定制完毕。发布。
[说明]业务单据一旦进入工作流,就要受到工作流的约束。例如,刚刚提交完凭证,流程执行到审批节点。这个时候工作流要求的行为是“某个人执行审批操作”。如果这个时候修改凭证,会提示:“已在工作流处理中,任务不匹配”。
1.4. 常见的流程配置需求
1.4.1.配置参与人
1.4.2.配置多级审批
管理员收到申请单后,传给多个领导。由各领导分别进行审批,审批不通过的要能够来回进行审批。直到审批通过,也即是多级审批,每级审批不通过回到相应的审批节点继续进行审批。
流程配置
面对此种问题首先想到的应该是通过流程变量来设置审批节点的标志,在每级审批节点完成后设置一个标志,标志目前走到那个审批级别,如果不通过,根据流程变量上审批标志的值直接回到此审批节点。具体配置请查看下面截图:
完整流程图
综合处审批节点后置脚本
总结:充分利用流程变量作为流程流转的条件
1.4.3.函数节点
需要重复使用某些脚本,希望能减低脚本维护的复杂度,同时提高脚本的复用率和使用效率。
解决办法
已经内置了函数节点的支持,函数节点本质上和脚本节点没有任何区别,所处理的任务和职责都是一样,但脚本节点脚本散落在流程中各个地方,维护和使用非常困难。函数节点的目的就是为了减低流程配置中脚本维护的复杂度和可重用性低的问题。具体使用请参考如下的说明:
在工具菜单 窗口->显示视图,查找选择工作流视图组->函数定义
点击确定后会出现函数定义的界面,其中已经内置了一些函数,双击选择的某个函数可以打开函数编辑界面
函数编辑界面,在此可以定义函数的输入输出以及一些描述性的说明,并可在编辑框内输入具体的代码(目前支持KScript和java代码),代码其实就是脚本。
然后定义工作流,在流程定义中增加一个函数节点。
在函数任务界面选择函数定义,会弹出函数定义选择界面,选择合适的函数即可。
在函数任务界面配置好函数的输入输出参数即可在流程中使用此函数的输出值。
如需自己定义函数,直接在函数视图中按照右键菜单提示进行操作即可。
1.4.4.用流程变量配置条件参予人
员工提交单据后,进行第一级审批,第一级审批参与人设置条件:如果是提交单据的是财务部员工,则参与人为财务部某一职员进行审批,如果不是财务部提交的单据,则提交人所在部门(归口部门)的直接上级进行审批,如果直接上级是部门负责人则上级审批完成流程就继续往下走,如果直接上级不是部门的负责人则还需要部门的负责人进行审批。
配置步骤:
首先画出流程草图,将大致的图形先画出来。
在提交单据节点输出提交人的部门到流程变量“归口部门”,并在后置脚本中根据归口部门的值设置流程变量“是否财务部”的值。
在审批节点设置条件参与人,根据流程变量 “是否财务部”来设置相关的条件参与人,并将审批人输出到流程变量“审批人”中。
在审批节点后设置一脚本节点->负责人判断,用来判断上级审批的人员是否是部门负责人。如果是则流程结束。如果不是则继续在部门内多级审批,直到部门负责人审批完成(循环过程)。负责人判断的脚本内容为:
是否部门负责人=
com.kingdee.bos.workflow.participant.ParticipantHelper.isOrgPrincipal(
__bosContext,审批人,归口部门);
其中,是否为部门负责人,审批人,归口部门为流程变量。
最终流程如下:
总结:充分利用了条件参与人与流程变量,并通过脚本来获取流程必须的信息。
2. 工作流脚本
2.1.JAVA脚本
在工作流中经常会需要使用到一些脚本来获取单据的信息或者是执行一些特殊的操作,脚本应如何写?需要注意那些地方?有没有更好的定义和使用方法?
解决方法
工作流脚本利用的是java语法,所有的java代码都可以被工作流解析,但所有的类必须是全路径名称(除了java.lang.*包下的类),如List 必须写成java.util.List。在工作流中内置了一些变量和函数可以进行使用,如:“__bosContext”内置变量表示服务端的context。在工作流脚本中可以直接使用定义好的流程变量,脚本执行过程中会将脚本的值自动赋值给相应的流程变量。在内置函数节点可以用来封装脚本,减轻脚本维护的复杂度和提高可重用性。
工作流中内置的一些函数
如下是一些脚本的示例:
l 根据人获取对应主负责的行政组织脚本:
首先新建一个流程变量 BOID类型 例如 orgId
String userId = "";
//获取User对象的远程控制接口
com.kingdee.eas.base.permission.IUser iUser =com.kingdee.eas.base.permission.UserFactory
.getLocalInstance(__bosContext);
com.kingdee.eas.base.permission.IUser iUser =com.kingdee.eas.base.permission.UserFactory
.getLocalInstance(__bosContext);
com.kingdee.eas.basedata.person.PersonInfo info =iUser.getUserInfo(
new com.kingdee.bos.dao.ormapping.ObjectUuidPK(
com.kingdee.bos.util.BOSUuid.read(userId))).getPerson();
if (info != null) {
String personId = info.getId().toString();
com.kingdee.eas.basedata.org.IPositionMemberiPositionMember =
com.kingdee.eas.basedata.org.PositionMemberFactory
.getLocalInstance(__bosContext);
com.kingdee.eas.basedata.org.PositionMemberInfopositionMemberInfo = iPositionMember
.getPositionMemberInfo("select
position.adminOrgUnit.id where person.id = '"+personId + "' and isPrimary = 1");
orgId =positionMemberInfo.getPosition().getAdminOrgUnit().getId();
}
l 根据组织的id获取公司的名称,然后在条件参与人中根据此进行判断
1、 增加一个流程变量adminId、companyId、companyNum。都是字符串型
2、 在新增节点的任务输出中,输出组织的ID到adminId变量中
3、 增加脚本节点,其中脚本如下:
companyId =
com.kingdee.eas.basedata.person.app.PersonToWFAdapter.getCompanyIdByAdminId(__bosContext,adminId);
com.kingdee.eas.basedata.org.INewOrgUnitFacadeiOrg =
com.kingdee.eas.basedata.org.NewOrgUnitFacadeFactory.getLocalInstance(__bosContext);
com.kingdee.eas.basedata.org.CompanyOrgUnitInfofiInfo =
(com.kingdee.eas.basedata.org.CompanyOrgUnitInfo)
iOrg.getDelegateUnit(companyId,com.kingdee.eas.basedata.org.OrgType.Company);
if (fiInfo != null) {
companyNum =fiInfo.getNumber();
}
l 判断有无直接上下级的脚本
首先定义一流程变量,类型为布尔:有直接上级
com.kingdee.bos.workflow.service.ormrpc.IEnactmentServiceservice = new
com.kingdee.bos.workflow.service.ormrpc.EnactmentService(__bosContext);
com.kingdee.bos.workflow.ProcessInstInfo[]procInstInfos =
service.getProcessInstanceByHoldedObjectId(billID.toString());
com.kingdee.bos.workflow.ProcessInstInfocurProcInst = null;
for (int i = 0, n =procInstInfos.length; i < n; i++) {
if(procInstInfos[i].getState().startsWith("open.run")) {
curProcInst =procInstInfos[i];
}
}
if (curProcInst != null) {
initUserId =curProcInst.getInitiatorId();
com.kingdee.eas.basedata.person.app.PersonToWFAdapteradapter = new
com.kingdee.eas.basedata.person.app.PersonToWFAdapter();
com.kingdee.bos.workflow.participant.Person[]persons =
adapter.getSupervisor(__bosContext, initUserId);
if (persons != null&& persons.length > 0 && persons[0] != null) {
有直接上级 = true;
} else {
有直接上级 = false;
}
}
l 委托时,判断审批人是否是部门负责人
判断审批人是否是部门负责人,如果审批人是委托任务处理人,则判断委托人是否是部门负责人
变量声明:
下述脚本使用了如下变量:
__bosContext: 系统内置变量
单据Id : 单据内码,一般由单据直接输出
归口部门: 类型为字符串,为部门id
审批人: 类型为字符串,为审批任务的处理人,在审批节点中输出
审批节点名称: 类型为字符串,为节点定义名称
是否部门负责人: 类型为布尔,为返回的结果值,用来在流程中判断
com.kingdee.bos.workflow.enactment.WfEngineengine =
com.kingdee.bos.workflow.enactment.WfEngine.getEngine(__bosContext);
com.kingdee.bos.workflow.ProcessInstInfo[]infos =
engine.getProcessInstanceByHoldedObjectId(单据Id);
if(infos!= null && infos.length>0){
ProcessControlDataKScriptAdapteradapter =
newProcessControlDataKScriptAdapter(infos[0],engine.getLocale(),engine);
String constituentUserId=adapter.getTopConstituent(审批节点名称);
if(constituentUserId !=null&& !constituentUserId.trim().equals("")){
//有委托人,判断委托人是否是部门负责人
是否部门负责人
=com.kingdee.bos.workflow.participant.ParticipantHelper.isOrgPrincipal (
__bosContext ,constituentUserId ," 归口部门) ;
}else{//没有委托人,直接判断审批人是否有直接上级
是否部门负责人
=com.kingdee.bos.workflow.participant.ParticipantHelper.isOrgPrincipal (
__bosContext ,审批人 ,归口部门) ;
}
} else{
是否部门负责人
=com.kingdee.bos.workflow.participant.ParticipantHelper.isOrgPrincipal (
__bosContext ,审批人 ,归口部门) ;
}
l 在脚本中执行SQL语句
java.lang.StringBuffersql = java.lang.new StringBuffer();
//将SQL语句保存到sql对象中
//…
java.sql.Connectioncon =
com.kingdee.bos.framework.ejb.EJBFactory.getConnection(__bosContext);
java.sql.StatementbatchStatement = con.createStatement();
batchStatement.execute(sql.toString());
com.kingdee.util.db.SQLUtils.cleanup(batchStatement,con);
com.kingdee.util.db.SQLUtils.cleanup(con);
l 将活动的参与人设为单据对应部门的负责人
场景:在单据上有个“费用的承担部门”的属性,现在要将审批活动的参与人设置为该部门的负责人。
1. 声明变量
var_principal 外部数据类型
var_orgUnitId 内码(BOID)
2. 在做业务单据时(审核节点之前)将单据上的“费用的承担部门”的ID关联到var_orgUnitId变量中 ,并在该节点的后继脚本中填入如下内容:
com.kingdee.eas.basedata.org.AdminOrgUnitInfo adminInfo = com.kingdee.eas.basedata.org.AdminOrgUnitFactory.getRemoteInstance().getAdminOrgUnit(var_orgUnitId);
if(adminInfo != null && adminInfo.getResponPosition != null)
{
com.kingdee.eas.basedata.org.IPosition iPosition = com.kingdee.eas.basedata.org.PositionFactory.getRemoteInstance();
com.kingdee.eas.basedata.person.PersonCollection pColl = iPosition.getAllPersons(adminInfo.getResponPosition.getId());
var_principal = new String[pColl.size()];
for (int i=0; i<pColl.size(); i++) {
com.kingdee.eas.basedata.person.PersonInfo pi = pColl.get(i);
var_principal[i] = pi.getId().toString();
}
}
3. 在审核节点中定义参与人,选择为参与人变量,并把var_princial添加进去。
l 根据分录信息循环发送消息给业务员
收集:脚本一
java.lang.String commonStr = data +"," + billNumber + "," + chauffeur + "," +regnumber + "," + contact + ".";
java.lang.HashMap map = newjava.lang.HashMap();
for (int i=0; i<records.size(); i++) {
//请替换成出车单的分录对象
com.kingdee.eas.fi.gl.VoucherEntryInforecord = records.get(i);
java.lang.String s =record.get("wareName") + "(" + record.get("wareNumber") + ")已发往" + record.get("customer") + ";";
java.langString op =record.("operator").getId().toString();
if (map.get(op) == null) {
map.put(op, s);
} else {
map.put(map.get(op) + s);
}
}
userList = new java.util.ArrayList();
msgList = new java.util.ArrayList();
//此段已废弃 begin
for (java.lang.Iterator i = map.getKeySet.iterator();i.hasNext();) {
Object key = i.next();
Object msg = map.get(key);
userList.add(key);
msgList.add(commonStr + msg);
}
//此段已废弃 end
修改为:
list = new java.util.ArrayList();
list.addAll(map.keySet());
for (int i=0; i<list.size(); i++) {
Object key = list.get(i);
Object msg = map.get(key);
userList.add(key);
msgList.add(commonStr + msg);
}
pos = 0;
count = userList.size();
if (count > 0) {
user = userList.get(0);
msg = msgList.get(0);
}
2.2.多UI相同实体需要触发不同的流程,条件启动流程
在EAS中经常碰到这种情形,有两套UI对应一个实体,此两个UI绑定的功能(Function)和操作(Operate)是一样。由于工作流是根据功能和操作来进行流程匹配的,这两个ui执行后都启用了同一个流程,需要在两套UI上提交的时候触发不同的工作流,如何实现?
解决办法
工作流目前支持两种方式的流程匹配方式:一种是根据Function和Operate以及用户信息来进行流程的匹配,如果两套UI使用的用户范围是不一样的,可以通过在不同的流程的第一个人工节点根据用户范围设置参与人,根据参与人来区分是要匹配那条流程。但如果两条流程使用的用户范围是一致的,此种方式不可用;第二种方式是根据流程启动条件来进行流程的匹配,通过在流程的第一个连接符上设置启动条件,可以根据一些绑定的业务单据对象的某个属性或其他内容来设置此流程启动的条件和场景。工作流系统中内置了一个__processTrigger变量,代表绑定的业务单据,可以使用此变量输出相关的业务属性来进行判断,详细的请查看如下图示:
图一.设置启动条件
图二.双击链接符,弹出设置条件界面
图三.内置变量支持打点弹出业务对象的所有属性特征
图四.最终设置条件,示例为只有当单据的number为121的时候才启动此流程,此处根据业务需求来设定
可以使用一些比较复杂的条件来做判断,只要最后返回一个boolean值即可,如下述代码:
com.kingdee.bos.dao.ormapping.ObjectUuidPK pk = new com.kingdee.bos.dao.ormapping.ObjectUuidPK(__processTrigger.getProposer().getId()); com.kingdee.bos.metadata.entity.SelectorItemCollection sic = new com.kingdee.bos.metadata.entity.SelectorItemCollection(); sic.add(new com.kingdee.bos.metadata.entity.SelectorItemInfo("id")); sic.add(new com.kingdee.bos.metadata.entity.SelectorItemInfo("name")); sic.add(new com.kingdee.bos.metadata.entity.SelectorItemInfo("employeeClassify.id")); sic.add(new com.kingdee.bos.metadata.entity.SelectorItemInfo("employeeClassify.name")); com.kingdee.eas.basedata.person.PersonInfo person = com.kingdee.eas.basedata.person.PersonFactory.getLocalInstance(__bosContext).getPersonInfo(pk,sic); return person.getEmployeeClassify().getName().equals("一般员工"); |
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
相关文章
- c#之MessageBox的用法和获取返回值方法[转]
c#之MessageBox的用法和获取返回值方法[转]Technorati 标签: C#,MessageBox C#中messagebox用法【函数】 <整型> MessageBox(<字符串 Text, <字符串> Title, <整型> nType,MessageBoxIcon);【函数说明】 弹出一个消息框。【语法】参数:Text <字符串…...
2024/5/5 8:03:26 - [C#][SAMPLE][CODE][Control]ListBox和CheckListBox
[示例出处]:本示例来自《C#入门经典》第三版中文版,P349-P353[示例涉及]:1、ListBox2、CheckListBox [示例代码]:2文件(其余默认)Form1.Designer.cs 1namespace WA_Lists 2{ 3 partial class Form1 4 { 5 /**//// <summary> 6 /// 必需的设计器变…...
2024/5/3 0:54:23 - 使用Spring来创建一个简单的工作流引擎
使用Spring来创建一个简单的工作流引擎http://www.pconline.com.cn/pcedu/empolder/gj/java/0509/702478.html...
2024/5/5 8:12:58 - 关于C#中使用messagebox的问题解答
对于winform中的messagebox要在C# for web form中使用是不能正常运行的了,原因是对于客户端不作什么软件安装要求而仅有ie的情况下,在客户端运行这样的web页面:页面中有调用了这个函数的一个事件过程,结果一单击这个过程,对话框却在服务端显示了而不是想象中的在客户端上显…...
2024/4/28 11:05:32 - C++ CheckListBox
实现过程CCheckListBox listbox1; listbox1.AddString("葡萄");listbox1.AddString("苹果");listbox1.AddString("桔子"); //判断你选择了哪些项目void CCheckListBoxDlg::OnButtonOk() {// TODO: Add your control notification handler cod…...
2024/4/21 8:58:29 - 我叫MT online 公会BOSS百分比、难度、BOSS技能及站位
我叫MT online 公会BOSS百分比、难度、BOSS技能及站位 副本名称 序号 进度 输出指数 BOSS技能 硬件 站位 备注祖安中 (难度★★) 掉落紫头1 小怪 100%--95% 2 血领主+小怪 95%--93% 3 血领主(单) 93%--70% 10 竖排物理攻击,自带法抗。普攻3W+,技能3W+。 卡牌选择奶量…...
2024/4/21 8:58:28 - dySE:一个 Java 搜索引擎的实现
本系列文章将逐步介绍 dySE 这个开源的Java小型搜索引擎的实现过程。该搜索引擎分为三个模块:爬虫模块、预处理模块和搜索模块。其中详细阐述了: 多线程页面爬取、正文内容提取、文本提取、分词、索引建立、快照等功能的实现。本文将重点介绍 dySE的整体结构和爬虫模块的设计与…...
2024/4/27 22:47:06 - SQL SERVER 2005 登陆18456错误的解决方法
昨天我的SQL(Microsoft SQL Server 2005 )登录不上去了,原来是出现了几个小问题,现在记录一下我的解决这几个情况的办法。(解决方法有很多种,这些只是我的解决方法,仅供参考)查找问题的过程:(注:用windows账号还是可以登录的) 第一步: 启动所有与SQL有关的服务,问…...
2024/5/5 7:15:52 - 在Vb.Net中弹出对话框的简单方法。使用Messagebox
方法很简单,就是引用 System.Windows.Forms. 然后在代码页面头部 Imports System.Windows.Forms 即可。 或者直接使用 System.Windows.Forms.Messagebox.show() 之后就能使用Messagebox对话框了。...
2024/5/5 3:27:15 - [WPF] CheckListBox的实现方式分析
实际项目中常常要实现有CheckBox列表框。但是WPF没有自带这样的一个控件,下面就用Style来实现这样的功能。而对于CheckBox列表框,又常常会有一个Select All的CheckBox来表示当前列表框的选择状态。这个功能也会被包含在下面的示例之中。效果如下图所示。对于单纯的,没有后台…...
2024/5/5 5:21:33 - 详解SQL Server连接(内连接、外连接、交叉连接)
在查询多个表时,我们经常会用“连接查询”。连接是关系数据库模型的主要特点,也是它区别于其它类型数据库管理系统的一个标志。 什么是连接查询呢? 概念:根据两个表或多个表的列之间的关系,从这些表中查询数据。 目的:实现多个表查询操作。 知道了连接查询的概念…...
2024/4/28 15:57:47 - Activiti 工作流入门
基础知识工作流: 可以认为是一系列的规范流程,让业务按照拟定的规则处理和运转,本质上是一系列逻辑相关的活动的集合。例如某校学生申请奖学金这一业务,必须按照“学生申请→辅导员审批→学生处审批→教务处审批”这一流程运转,也就是“学生申请”、“辅导员审批”、“学生…...
2024/5/5 9:23:09 - MessageBox.Show 方法使用:
MessageBoxButtons 值之一,可指定在消息框中显示哪些按钮。 MessageBoxIcon 值之一,它指定在消息框中显示哪个图 MessageBoxDefaultButton 值之一,可指定消息框中的默认按钮。 MessageBoxOptions 值之一,可指定将对消息框使用哪些显示和关联选项。若要使用默认值,请传入 0…...
2024/4/26 7:48:46 - checkListbox的单选
首先要在前面的事件里面添加this.checkedListBox3.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.checkedListBox3_ItemCheck);然后在后面cs里面写: Code 1 /**//// <summary> 2 /// checklistbox3单选 3 /// </summary>…...
2024/5/5 9:57:09 - SQL入门经典+SQL必知必会
一、了解SQL 1. 关系型数据库管理系统(RDBMS) 2. 结构化查询语言(SQL)——关系型数据库进行通信的标准语言 3. ANSI标准——可移植性和易用性 4. 连接数据库:CONNECT user@database;断开连接:DISCONNECT 5. SQL命令类型:数据定义语言:DDL——用于创建和重构数据库对象(…...
2024/5/5 11:14:44 - [热门游戏]今年“金酷”推出暗黑大作“魔界2”,邀你一起去探险。
公会名称:誓战公会公会论坛:www。92shizhan。com公会歪歪:2593魔界2.QQ群:84363971 备用群:72406710魔界2官方网站//m2。12ha。com/ 暗黑类网游《魔界2》近日确认,游戏封测的具体日期为:4月28日(周三) 随着盛大Allstar新品发布盛典的临近,作为Allstar八大明星新游之…...
2024/4/28 19:19:47 - Activiti工作流(一)之基本操作介绍
工作流的概念:工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档、信息或任务的过程自动进行,从而实现某个预期的业务目标,或者促使此目标的实现”。通俗的说,流程就是多个人…...
2024/5/5 4:20:02 - Electron-Nodejs-Addon入门
为什么80%的码农都做不了架构师?>>> 1、本次学习使用Electron的版本是1.8.0,Nodejs的版本是7.9.0,操作系统为 Win10 x64,编译器为Microsoft VC++ 14 2、安装Node模块:node-gyp node-pre-gyp nan 3、编写代码如下: //hello.cc #include <node.h> ///#…...
2024/4/22 5:13:35 - VBA中msgbox的用法小结
1、作用在消息框中显示信息,并等待用户单击按钮,可返回单击的按钮值(比如“确定”或者“取消”)。通常用作显示变量值的一种方式。2、语法MsgBox(Prompt[,Buttons][,Title][,Helpfile,Context])参数说明:(1)Prompt,必需的参数,为字符串,作为显示在消息框中的消息文本。其…...
2024/4/22 12:34:54 - SQL Server辅助插件——SQL Prompt
前言:当我们对某个程序进行维护或者完善时,必不可少的就是跟数据库或者以前开发人员写的sql语句打交道,当我们对数据库表的结构不熟悉时,修改或者编写sql语句将是一件很痛苦的时间,而且sqlserver有没有像vs等软件可以提供强大的智能提醒。这时候我们就需要一款合适的插件来…...
2024/4/21 8:58:23
最新文章
- 【ONE·基础算法 || 回溯和剪枝(暴搜/深搜)】
总言 主要内容:编程题举例,熟悉理解回溯剪枝类题型(如何画决策树,如何使用深搜进行递归,如何运用剪枝,如何在一维数组/二维数组中使用)。 文章目录 总言1、回溯和剪枝2、全排列(med…...
2024/5/5 12:09:55 - 梯度消失和梯度爆炸的一些处理方法
在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言,在此感激不尽。 权重和梯度的更新公式如下: w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...
2024/3/20 10:50:27 - Linux mount用法
在Linux系统中,系统自动挂载了以下挂载点: /: xfs文件系统,根文件系统, 所有其他文件系统的挂载点。 /sys: sysfs文件系统,提供内核对象的信息和接口。 /proc: proc文件系统,提供进程和系统信息。 /dev: devtmpfs文件系…...
2024/5/5 8:38:45 - c++类的继承方式
在 C 中,类的继承方式有三种:公有继承(public inheritance)、保护继承(protected inheritance)和私有继承(private inheritance)。这些继承方式决定了派生类对基类成员的访问权限。 …...
2024/5/3 14:42:38 - 【外汇早评】美通胀数据走低,美元调整
原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...
2024/5/4 23:54:56 - 【原油贵金属周评】原油多头拥挤,价格调整
原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...
2024/5/4 23:54:56 - 【外汇周评】靓丽非农不及疲软通胀影响
原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...
2024/5/4 23:54:56 - 【原油贵金属早评】库存继续增加,油价收跌
原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...
2024/5/4 23:55:17 - 【外汇早评】日本央行会议纪要不改日元强势
原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...
2024/5/4 23:54:56 - 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响
原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...
2024/5/4 23:55:05 - 【外汇早评】美欲与伊朗重谈协议
原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...
2024/5/4 23:54:56 - 【原油贵金属早评】波动率飙升,市场情绪动荡
原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...
2024/5/4 23:55:16 - 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试
原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...
2024/5/4 23:54:56 - 【原油贵金属早评】市场情绪继续恶化,黄金上破
原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...
2024/5/4 18:20:48 - 【外汇早评】美伊僵持,风险情绪继续升温
原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...
2024/5/4 23:54:56 - 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势
原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...
2024/5/4 23:55:17 - 氧生福地 玩美北湖(上)——为时光守候两千年
原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...
2024/5/4 23:55:06 - 氧生福地 玩美北湖(中)——永春梯田里的美与鲜
原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...
2024/5/4 23:54:56 - 氧生福地 玩美北湖(下)——奔跑吧骚年!
原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...
2024/5/4 23:55:06 - 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!
原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...
2024/5/5 8:13:33 - 「发现」铁皮石斛仙草之神奇功效用于医用面膜
原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...
2024/5/4 23:55:16 - 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者
原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...
2024/5/4 23:54:58 - 广州械字号面膜生产厂家OEM/ODM4项须知!
原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...
2024/5/4 23:55:01 - 械字号医用眼膜缓解用眼过度到底有无作用?
原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...
2024/5/4 23:54:56 - 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...
解析如下:1、长按电脑电源键直至关机,然后再按一次电源健重启电脑,按F8健进入安全模式2、安全模式下进入Windows系统桌面后,按住“winR”打开运行窗口,输入“services.msc”打开服务设置3、在服务界面,选中…...
2022/11/19 21:17:18 - 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。
%读入6幅图像(每一幅图像的大小是564*564) f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...
2022/11/19 21:17:16 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...
win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面,在等待界面中我们需要等待操作结束才能关机,虽然这比较麻烦,但是对系统进行配置和升级…...
2022/11/19 21:17:15 - 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...
有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始…...
2022/11/19 21:17:14 - win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...
置信有很多用户都跟小编一样遇到过这样的问题,电脑时发现开机屏幕显现“正在配置Windows Update,请勿关机”(如下图所示),而且还需求等大约5分钟才干进入系统。这是怎样回事呢?一切都是正常操作的,为什么开时机呈现“正…...
2022/11/19 21:17:13 - 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...
Win7系统开机启动时总是出现“配置Windows请勿关机”的提示,没过几秒后电脑自动重启,每次开机都这样无法进入系统,此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一:开机按下F8,在出现的Windows高级启动选…...
2022/11/19 21:17:12 - 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...
有不少windows10系统用户反映说碰到这样一个情况,就是电脑提示正在准备windows请勿关闭计算机,碰到这样的问题该怎么解决呢,现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法:1、2、依次…...
2022/11/19 21:17:11 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...
今天和大家分享一下win7系统重装了Win7旗舰版系统后,每次关机的时候桌面上都会显示一个“配置Windows Update的界面,提示请勿关闭计算机”,每次停留好几分钟才能正常关机,导致什么情况引起的呢?出现配置Windows Update…...
2022/11/19 21:17:10 - 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...
只能是等着,别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚,只能是考虑备份数据后重装系统了。解决来方案一:管理员运行cmd:net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...
2022/11/19 21:17:09 - 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?
原标题:电脑提示“配置Windows Update请勿关闭计算机”怎么办?win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢?一般的方…...
2022/11/19 21:17:08 - 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...
关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!关机提示 windows7 正在配…...
2022/11/19 21:17:05 - 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...
钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...
2022/11/19 21:17:05 - 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...
前几天班里有位学生电脑(windows 7系统)出问题了,具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面,长时间没反应,无法进入系统。这个问题原来帮其他同学也解决过,网上搜了不少资料&#x…...
2022/11/19 21:17:04 - 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...
本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法,并在最后教给你1种保护系统安全的好方法,一起来看看!电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中,添加了1个新功能在“磁…...
2022/11/19 21:17:03 - 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...
许多用户在长期不使用电脑的时候,开启电脑发现电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机。。.这要怎么办呢?下面小编就带着大家一起看看吧!如果能够正常进入系统,建议您暂时移…...
2022/11/19 21:17:02 - 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...
配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!配置windows update失败 还原更改 请勿关闭计算机&#x…...
2022/11/19 21:17:01 - 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...
不知道大家有没有遇到过这样的一个问题,就是我们的win7系统在关机的时候,总是喜欢显示“准备配置windows,请勿关机”这样的一个页面,没有什么大碍,但是如果一直等着的话就要两个小时甚至更久都关不了机,非常…...
2022/11/19 21:17:00 - 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...
当电脑出现正在准备配置windows请勿关闭计算机时,一般是您正对windows进行升级,但是这个要是长时间没有反应,我们不能再傻等下去了。可能是电脑出了别的问题了,来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...
2022/11/19 21:16:59 - 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...
我们使用电脑的过程中有时会遇到这种情况,当我们打开电脑之后,发现一直停留在一个界面:“配置Windows Update失败,还原更改请勿关闭计算机”,等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢࿰…...
2022/11/19 21:16:58 - 如何在iPhone上关闭“请勿打扰”
Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...
2022/11/19 21:16:57