MOSS多级审批工作流【Sequential+ConditionedActivityGroup版】v1.1

今年二月份,我开发了一个MOSS多级审批工作流,它实现了如下图所示的流程:



之后我在《
SharePoint多级审批工作流开发文档[Sequential]》这篇文档中详细的描述了整个开发过程并提供了项目源码下载。

其实我在匆匆的写这篇文档的时候,对MOSSWF连一知半解都谈不上。

所以为了实现审批流程中常见的动作-“回退”,我用了好几层的WhileIfElse嵌套,最终整个工作流的流程图如下:



看着这么长而且繁复的流程图就知道这是比较笨的方法了。

最近终于决定腾出一个分区安装了Windows Server 2003 MOSS,然后把这个审批工作流改了一下,现在的流程图是这样的:




清爽了很多吧?

忘记那些讨厌的While+IfElse嵌套吧,我们只需要一个活动就可以代替它们: ConditionedActivityGroup

简单的介绍一下ConditionedActivityGroup活动:

  • 可以包含多条分支;
  • 每条分支都有一个WhenCondition条件用来决定它是否可以被执行;
  • 如果不设置分支的WhenCondition条件,那么这个分支只会在第一次循环的时候执行;
  • ConditionedActivityGroupUntilCondition条件可以决定什么时候结束该活动,如果UntilCondition条件一直不满足,ConditionedActivityGroup就一直循环;
  • 如果没有设置UntilCondition条件,则ConditionedActivityGroup会一直循环直到它的分支都不再执行为止。

也可以把ConditionedActivityGroup理解为一条包含若干if语句的do…until语句。

 

修改后的工作流项目下载:ApprovalSequentialEdition_with_CAG.zip

 

最后谢谢一些朋友对《SharePoint多级审批工作流开发文档[Sequential]》这篇文档的支持,本文对其实现进行了改进,但是我必须说,审批这样的流程并不适合用顺序工作流来实现,用WF的另外一种工作流-状态机工作流会更好。

本文写给一些总喜欢在顺序工作流里实现回退的朋友。

注:于2007年8月5日更新部分代码,修正某些情况下任务的分配对象会丢失地问题.

原文发布于coding.windstyle.cn,欢迎访问、订阅并和我交流。

posted on 2007-08-01 23:08 Windie Chai 阅读(7163) 评论(32) 编辑 收藏

评论

#1楼 2007-08-01 23:36 AD[未注册用户]

刚开始接触审批工作流的时候就是从你 上一篇SharePoint多级审批工作流开发文档[Sequential版] 开始的

这次的好象改进不少
非常感谢
 回复 引用   

#2楼 2007-08-02 09:12 晴天

俺笨,俺看不懂,还在努力学习中.  回复 引用   

#3楼 2007-08-02 09:34 share[未注册用户]

果然改进了很多,坐下来忙忙学习!  回复 引用   

#4楼 2007-08-02 09:52 AA()      

大哥 你厉害啊。。  回复 引用 查看   

#5楼 2007-08-02 10:45 AA()      

大哥
你这里的

runTask == 0

runTask == 1

runTask == 2

runTask == 34
d这 0 1 2 34 都是那里来的,,好像 也没有在那里对应,,,
感觉这样 只能 走一个 流程哦,,因为 runtask 在上面已经 = 1啦。。
private void RunTask0(object sender, ConditionalEventArgs e)
{
e.Result = (runTask == 0);
}

private void RunTask1(object sender, ConditionalEventArgs e)
{
e.Result = (runTask == 1);
}

private void RunTask2(object sender, ConditionalEventArgs e)
{
e.Result = (runTask == 2);
}

private void RunTask34(object sender, ConditionalEventArgs e)
{
e.Result = (runTask == 34);
}
不明白 解释 下
 回复 引用 查看   

#6楼 2007-08-02 10:52 AA()      

还有 就是 好像 你这个 有结束的地方??
感觉
ConditionedActivityGroup 一直再循环哦。。
 回复 引用 查看   

#7楼[楼主] 2007-08-02 11:09 笑煞天      

@AA() ,
你没有在MOSS里部署测试吧?
1.仔细看我的代码.
runTask 表示该创建哪个任务,一开始是1,因为最初提交审核之后肯定是第一级审批者审批的.
第一级审批者审批过后,会将runTask 设置为2或者0(可能通过也可能驳回),以此类推.
2.仔细看这篇文章.
ConditionedActivityGroup 不会一直循环,因为我设置了它的UntilCondition为第三级的两位审批者都通过审批,所以当这个条件满足时工作流就会结束.
 回复 引用 查看   

#8楼 2007-08-02 11:20 sh37      

学习  回复 引用 查看   

#9楼 2007-08-02 16:27 AA()      

哈哈 失败,,,,
我没有认真看,,,嘿嘿,,
我在 wwf里面测试 拉一下,,感觉不错。

ConditionedActivityGroup 只有每个条件都结束的时候 才结束,,
只要有一个 还在,,他就不结束。。。
 回复 引用 查看   

#10楼[楼主] 2007-08-02 23:11 笑煞天      

@AA() ,
对!就是这样,比我从前用一堆IfElse+While强多啦,呵呵.
 回复 引用 查看   

#11楼 2007-08-17 15:06 Burnett      

其实就是用switch代替了若干的if判断。呵呵
其实你的第一版虽然复杂,但是对于初学者来说,还是很好的。
 回复 引用 查看   

#12楼[楼主] 2007-08-17 17:12 笑煞天      

@Burnett ,
谢谢,个人感觉,MS还是应该继续改进MOSS工作流的开发方式,VS2008中方便了不少,但还是有些麻烦,尤其是InfoPath表单的设置.
 回复 引用 查看   

#13楼 2007-08-24 08:55 xilang[未注册用户]

怎么无法通过啊,能否给详细解释以下啊!初学者的苦难。  回复 引用   

#14楼 2007-08-24 09:51 笑煞天

@xilang,
如果是初学者,请先不厌其烦的读读这篇文章http://www.cnblogs.com/xiaoshatian/archive/2007/02/26/657181.aspx
 回复 引用   

#15楼 2007-08-27 01:06 pccai

hi,照着做了遍,总是在此workflowProperties.InitiationData出错,只好加了个判断:
private void onWorkflowActivated_Invoked(object sender, ExternalDataEventArgs e)
{
workflowId = workflowProperties.WorkflowId;

//定义任务的名称
approveItemTitle = "请审批 " + workflowProperties.Item.DisplayName;
rejectItemTitle = workflowProperties.Item.DisplayName + " 被退回,请审批。";

//反序列化workflowProperties.InitiationData以得到初始窗体的实例
XmlSerializer xs = new XmlSerializer(typeof(Init));
if (workflowProperties.InitiationData != null)
{
XmlTextReader xtr = new XmlTextReader(new System.IO.StringReader(workflowProperties.InitiationData));
Init init = (Init)xs.Deserialize(xtr);

//将初始窗体的信息赋给Task0
task0_Properties.Title = rejectItemTitle;
task0_Properties.AssignedTo = workflowProperties.Originator;
task0_Properties.ExtendedProperties["comments"] = init.comments;

//设置Task1的标题和分配对象
task1_Properties.Title = approveItemTitle;
task1_Properties.AssignedTo = init.contact[0].AccountId;
}
else
{
//将初始窗体的信息赋给Task0
task0_Properties.Title = rejectItemTitle;
task0_Properties.AssignedTo = workflowProperties.Originator;
task0_Properties.ExtendedProperties["comments"] = "comments:";

//设置Task1的标题和分配对象
task1_Properties.Title = approveItemTitle;
task1_Properties.AssignedTo = "contososrv\\pccai";
}
}
导致这种原因不知如何更好的解决,其实最后把“新建项目是启动工作流”选项去掉,手动的启动,直接走/_layouts/IniWrkflIP.aspx...就可避免!不知晓伟有何其它好法,具体的描述我顺便贴到我的空间上,这个评论格式不好调哦,呵呵。。。。如果有时间的话!tks.
 回复 引用   

#16楼 2007-09-05 17:18 Armslave      

在工作流设计器中,有的activity上有一把小锁,干什么用的啊,怎么去掉啊~!  回复 引用 查看   

#17楼[楼主] 2007-09-06 09:40 笑煞天      

@Armslave
一般来说,小锁图标表示这是个复合活动,它的内部还有一些子活动,但是不可以直接进行操作,就像上图中的CAG活动,小锁图标附近应该会有一个按钮,点击之后就可以展开复合活动,然后就可以操作它的子活动了.
 回复 引用 查看   

#18楼 2007-11-21 10:01 张海洋[未注册用户]

搂主,我现使用2007,现在想开发个工作流,每个部门对应的上级不一样,需要判断员工属于那个部门然后提交给部门领导,审批后在提交给总监审批,单在DESIGER中我简单设置了,没有实现,请协助帮忙,如方便可会我mail:或电话:13141238032谢  回复 引用   

#19楼 2007-11-21 11:03 佳君[未注册用户]

此工作流确实不错,就是没有权限设置,任何审批者都能审批,容易管理混乱!请高手指点,怎样改进,达到有权限的审批工作,只有被指定的审批者,才能够审批工作.
谢谢指点!
 回复 引用   

#20楼 2007-11-22 09:05 Armslave      

http://www.cnblogs.com/xiaoshatian/archive/2007/08/21/863388.html@佳君
 回复 引用 查看   

#21楼 2007-11-22 09:53 佳君[未注册用户]

Armslave ,多谢指点!  回复 引用   

#22楼 2007-11-22 10:56 佳君[未注册用户]

"在属性面板中将createTask的SpecialPermissions属性绑定到新的specialPermissions对象",这句话不理解,不知道怎么设SpecialPermissions属性,设什么值,新的specialPermissions对象在哪里设置,请多多指教,谢谢!  回复 引用   

#23楼[楼主] 2007-11-23 14:12 笑煞天      

@佳君
你引用的这段话已经说的很明白了,任务全线的分配和和创建任务一起进行的。
创建任务需要createTask活动吧?这个活动有一个SpecialPermissions属性,可以绑定到你代码中的变量,那么将其绑定到一个新的变量即可。可以在绑定时选择绑定到已有的变量或者新的变量。
当然,如果你绑定到新的变量,设计器会自动创建一个变量,如果你没有对它赋值,它就是默认值,关于如何赋值,我想这篇文章已经讲的很清楚了:
http://www.cnblogs.com/xiaoshatian/archive/2007/08/21/863388.html
 回复 引用 查看   

#24楼 2007-11-25 19:39 佳君[未注册用户]

谢谢楼主!我基础比较差!非常感谢楼主对小弟的问题进行回复!  回复 引用   

#25楼 2008-05-26 17:42 萍萍[未注册用户]

“CAG的子活动是并行执行的,我们也可以将CAG活动可以看作是对活动本身和它的子活动都附加了条件的Parallel活动.

请问是这样吗?如果是这样,那么,审批是有一定的顺序的,也就是第一集级审批通过后才能进行第二级审批,而CAG的子活动是并行执行的,这不是矛盾了吗?
 回复 引用   

#26楼[楼主] 2008-05-27 10:07 Windie Chai(笑煞天)      

@萍萍
“每条分支都有一个WhenCondition条件用来决定它是否可以被执行”,所以你要设置WhenCondition来避免它在你不想要的时候执行。
 回复 引用 查看   

#27楼 2008-05-29 11:03 萍萍[未注册用户]

谢谢你的解惑。这么一来,每到审批过程中的一个环节,每条分支的WhenCondition条件都要有个对应的判断,譬如task4在审批没到达task4之前它都不能执行,也就是说要考虑到审批在task1,task2对应的状态时不能执行,当然这个例子中它的条件判断逻辑比较简单,runTask == 34,但它毕竟要考虑之前所有的情况,当业务流程很复杂的时候,这个判断逻辑可能就不是很好写了。其实,这时应该由工作流来控制的流程变成了由逻辑条件来控制了,不知道我说的对不对,只是这么猜想的,期待你的回答,^_^。
不过你文章最后说
“但是我必须说,审批这样的流程并不适合用顺序工作流来实现,用WF的另外一种工作流-状态机工作流会更好。”
我赞同你的观点,但不知道我说的算不算是这个不适合的理由呢 吼吼
 回复 引用   

#28楼[楼主] 2008-05-30 13:14 Windie Chai(笑煞天)      

@萍萍
对,顺序工作流只适合于简单的、没有过多循环的流程,如果你的流程牵扯到多个用户或多种条件判断,那么,用状态机工作流最合适了。
 回复 引用 查看   

#29楼 2008-05-30 16:55 萍萍[未注册用户]

LZ反应真是迅速,要是地震局能像LZ这样就好了  回复 引用   

#30楼 2008-06-19 15:46 jam[未注册用户]

当我在送审者和第一级审批者之间循环了几次后(即第一级审批者不通过,送审者又再次送审),出现任务的标题变成了空(无标题),分配对象也变成了空,这两种情况不是同时出现,这是怎么回事呢?  回复 引用   

#31楼 2010-03-21 13:30 chb      

onWorkflowActivated_Invoked中
XmlTextReader xtr = new XmlTextReader(new
System.IO.StringReader(workflowProperties.InitiationData));
这句有错啊!InitiationData提示为null,抛出异常了!
 回复 引用 查看   

导航

公告


 

版权声明

本Blog言论均以“现状”提供,没有任何担保,也没有授予任何权利,如需转载,请注明出处。
昵称:Windie Chai
园龄:5年3个月
荣誉:推荐博客
粉丝:86
关注:17

统计

搜索

 

常用链接

我的标签

随笔分类

随笔档案

出版社

专家博客

积分与排名

最新评论

阅读排行榜

评论排行榜