掌握“高级工作流开发”的前题是能熟练的使用“智能窗体开发”和“表单工作流开发”。高级工作流其实也可以叫做窗体工作流,是因为它不再是用HTML或者WORD模版这样的呈现方式来进行流转审批,他的界面和操作都是复杂多变的窗体呈现出来的。
●回顾表单工作流的开发
首先来回顾一下“表单工作流开发”的操作思路:设计表单模版→建立数据表→建立流程图→在流程图中绑定对应的数据表和表单模版。
表单工作流按照以上步骤设置好后可以直接运行,运行的时候系统会自动生成一个列表界面,如下图:
(图一)
这个界面是系统根据绑定的数据表自动生成的,上面有处理流程、开始新流程、删除数据、查看数据、查看流程图、查看流转历史等等功能按钮,当我们点击开始新流程的时候,就可以看到根据设置的表单模版自动生成的一个界面,如下图:
(图二)
在这个界面中有保存文档、下一步、流程图、流转历史等等功能按钮,当我们填写完内容后点击下一步那么这次的申请就会按照设置好的流程图流转审批,后续的每个步骤都会打开图二,进行相应的处理。
说这些的目的就是为了说明我们高级工作流的工作模式也和表单工作流类似,不同的地方在于如图一、图二的两个界面需要我们自己用窗体来构建,以及对流程的控制需要我们自己写代码控制,这无疑是非常灵活的,所以高级工作流是用来弥补表单工作流无法完成的一些需求。
●构建空白高级工作流
根据表单工作流程的思路,我们来构建一个空白的高级工作流,也就是窗体里面任何智能部件,只是构建一个窗体的流程。
1)新建一个高级工作流的流程图(操作步骤:工作流管理→新增工作流→选择高级工作流→下一步)。
2)构建流程图,如下图:
在高级工作流中,所有步骤的节点都叫做任务节点,所以高级工作流的节点比较少,就是开始节点、结束节点、条件节点、分支节点、和任务节点共5个节点。
同表单工作流的模式一样,每一个节点在处理的时候都会打开一个窗体,可以是同一个窗体,也可以是不同的窗体,这里我们每个节点打开的都是同一个窗体,打开窗体的设置如下图:
dim form1 = 创建智能窗体("7e19e9bc-ba24-45df-b1af-642d54023964")
form1.ShowDialog()
如上图所示把所有任务节点的执行代码都填写完成后,我们进行下一个操作:构建窗体,一般情况需要构建2个窗体(列表窗体、编辑窗体),列表窗体的功能类似表单工作流中的列表窗体,编辑窗体类似表单工作流中带模版的那个窗体,用于编辑数据、审核等操作。
3)新建的列表窗体的设置如下:
dim form1 = 创建窗体("7e19e9bc-ba24-45df-b1af-642d54023964")
form1.SetParam("Tag","ADD")
'这里还可以设置其他变量
form1.ShowDialog()
call("刷新")
因为我们创建的是一个空白高级工作流,所以列表窗体中没有使用任何智能部件,只有功能按钮,下面是其他功能按钮的截图:
dim form1 = 创建窗体("7e19e9bc-ba24-45df-b1af-642d54023964")
form1.SetParam("Tag","EDIT")
'这里还可以设置其他变量
form1.ShowDialog()
call("刷新")
(修改申请)
dim form1 = 创建窗体("7e19e9bc-ba24-45df-b1af-642d54023964")
form1.SetParam("Tag","SELECT")
'这里还可以设置其他变量
form1.ShowDialog()
call("刷新")
(查看申请)
ShowFlowChart("68db1e87c84f446ca4506d8766a6391b","关键值")
(查看流程图)
ShowFlowList("关键值")
(查看流转历史)
4)新建编辑窗体的设置如下(以下放截图的顺序是根据操作顺序和代码执行顺序放图):
'当前任务节点ID
dim nodeId=""
'标识变量,表示是新增、修改、查看
dim tag=""
if isnull(me.Flow) then
'如果me.Flow为空表示从窗体打开本窗体,获取传入的Tag值
tag=me.GetParam("Tag")
else
'如果me.Flow不为空表示从流程中打开本窗体,获取打开本窗体的流程的任务节点ID
nodeId=Flow.TaskNode.Id
end if
'任务节点ID:填写申请
dim nodeId1="669bf826-8cb2-4a40-98a2-63c31de957a5"
'任务节点ID:部长审批
dim nodeId2="4e8e20fe-f876-43b8-8110-d85628c90526"
'任务节点ID:总经理审批
dim nodeId3="20906754-2979-4df7-a792-8d0fc481fa35"
'条件节点ID:合计金额大于5000
dim tjNodeId1="af5cd411-486a-4363-8a99-c9902566a922"
'如果是新增物资采购申请时
if tag="ADD" then
'控制功能按钮是否可用
Me.SetFunctionEnabled("退回",False)
Me.SetFunctionEnabled("中止",False)
Me.SetFunctionEnabled("查看流转历史",False)
'这里添加自定义代码
end if
'如果是修改物资采购申请时
if tag="EDIT" then
'控制功能按钮是否可用
Me.SetFunctionEnabled("退回",False)
Me.SetFunctionEnabled("中止",False)
Me.SetFunctionEnabled("查看流转历史",False)
'这里添加自定义代码
end if
'如果是查看物资采购申请时
if tag="SELECT" then
'控制功能按钮是否可见
Me.SetFunctionVisible("存草稿",False)
Me.SetFunctionVisible("提交",False)
Me.SetFunctionVisible("退回",False)
Me.SetFunctionVisible("中止",False)
'这里添加自定义代码
end if
'如果是退回到申请人修改时
if nodeId=nodeId1 then
'控制功能按钮是否可用
Me.SetFunctionEnabled("退回",False)
Me.SetFunctionEnabled("中止",False)
'这里添加自定义代码
end if
'如果是部长审批时
if nodeId=nodeId2 then
'控制功能按钮是否可见
Me.SetFunctionVisible("存草稿",False)
'这里添加自定义代码
end if
'如果是总经理审批时
if nodeId=nodeId3 then
'控制功能按钮是否可见
Me.SetFunctionVisible("存草稿",False)
'这里添加自定义代码
end if
(加载事件-1/3)
(加载事件-2/3)
(加载事件-3/3)
加载事件中,可以在对应步骤填写相关代码来对数据进行操作。
if isnull(me.Flow) then
'启动流程并设置流程关键值
me.StartFlow("68db1e87c84f446ca4506d8766a6391b","关键值")
'设置标题
Flow.DocumentTitle=""
'设置描述
Flow.DocumentSummary=""
Flow.GoNextNode()
else
Flow.GoNextNode()
end if
(提交功能按钮)
如果要对数据的效验请在启动流程前进行效验。
if ShowQuestion("确定退回吗?") then
Flow.GoBack()
me.Close()
end if
(退回功能按钮)
if ShowQuestion("确定中止吗?") then
Flow.Break()
me.Close()
end if
(中止功能按钮)
if isnull(me.Flow) then
ShowFlowChart("关键值")
else
ShowFlowChart(Flow.FlowKeyValue)
end if
(查看流程图功能按钮)
if isnull(me.Flow) then
ShowFlowList("关键值")
else
ShowFlowList(Flow.FlowKeyValue)
end if
(查看流转历史功能按钮)
dim e1 = Me.GetEventArgs()
'如果是新增物资申请时
if tag="ADD" then
'这里添加自定义代码
end if
'如果是修改物资申请时
if tag="EDIT" then
'这里添加自定义代码
end if
'如果是退回申请人修改时
if e1.NodeId=nodeId1 then
'这里添加自定义代码
end if
'如果是部长审批时
if e1.NodeId=nodeId2 then
'这里添加自定义代码
end if
'关闭窗体
me.Close()
(进入下一步完成事件)
'如果是部长审批时
if nodeId=nodeId2 then
'这里添加自定义代码
end if
'如果是总经理审批时
if nodeId=nodeId3 then
'这里添加自定义代码
end if
'关闭窗体
me.Close()
(流程结束事件)
dim e1 = Me.GetEventArgs()
'判断合计金额大于5000
if e1.NodeId=tjNodeId1 then
'自定义判断条件
e1.ReturnValue=true
end if
(条件节点运算事件)
5)到这里高级工作流已经设置完成,运行的效果如下图:
可以看到窗体的中没有任何内容,是因为我们没有在窗体里面添加部件,但是高级工作流程我们已经构建完成了,如果再在窗体中添加相应的部件,在列表窗体和编辑窗体相应的地方添加相关的处理代码,如编辑窗体的加载事件中刷新数据、提交功能中把数据的关键值设置到流程关键值中、在不同的步骤对数据不同的处理,在进入下一步完成时更改流程状态并保存数据,在流程结束时更改流程状态并保存数据。如列表窗体中根据状态控制各个功能按钮是否可用等,那么整个高级工作流就完成了。
●总结高级工作流的注意事项
1)在编辑窗体中获取数据关键值时要分清楚何时可以用Flow.KeyValue,何时要用自定义传入的变量。
2)启动流程时一定要设置流程关键值,该关键值在平台中都是唯一的,一般使用GUID。并且该关键值是用来在不同步骤中获取数据,或者处理数据的一个值。
3)效验数据的代码无特殊情况时一定要写在提交功能按钮的启动流程(Me.StartFlow())或者下一步(Flow.GoNextNode())代码的前面。
4)保存数据的代码无特殊情况时一定要写在进入下一步完成事件里。
5)注意流程图中有哪些任务节点可能直接流向结束节点,那么要注意这些任务节点就可能直接跳过“进入下一步完成”事件。当一个任务节点要执行“流程结束”事件时,就不会执行“进入下一步完成”事件,一般这些任务节点都是最后的任务节点。