首页 > 代码库 > 【原创】记一次Project插件开发
【原创】记一次Project插件开发
一、开发背景
最近在使用微软的Office Project 2010 进行项目管理,看到排的满满的计划任务,一个个地被执行完毕,还是很有成就感的。其实,不光是在工作中可以使用Project进行项目进度控制,同样可以把这款软件应用在日常的生活中,比如为阅读某本书排一个计划,而任务单元就是本书的目录,当然粒度可以自己定制;也可以为健身排一个计划,每周去几次健身房、每次做多少个动作、做什么类型的动作,都可以提前排程,每完成一项就就在任务进度上狠狠地输入100%,那是多么爽的事啊。
但是,通过一段时间的使用,我发现自己有一个个性化的需求,就是习惯为各种状态的任务加上不同的背景色,这样就会很清晰直观地掌握任务的总体完成情况;还有就是很不喜欢Project自带的创建任务的方式,希望可以以自己的方式来创建任务,比如任务的资源一般是我自己的名字(大多数情况),所以我希望创建任务的时候,默认带出资源名称,再比如我喜欢用微软雅黑作为默认字体,但是每次都是设置好单个单元格后,再用格式刷去刷,很是麻烦,再比如表示任务状态的背景色,也是自己一点点用格式刷去刷的,如果不常用这个工具还好,但是总是这样难免让人反感,所以就产生了这个想法。以上就是我自己的个性化需求,如果后续有其他想法,还可以自己扩展,把懒人的风格发扬到底。在园子里也找了一些相关资料,但是和我的出发点都不是很吻合,所以废话不多说,自己动手,丰衣足食。
二、Project Object 模型
之前做过Word的插件开发,里面的各个组件(Range,Paragraph,Selection)等都是有规律可循的,大多数对象都有自己的集合,而且多个对象之间的关联比较密切,但是Project的模型让我很费解,比如里面的单元格Cell,居然不存在集合的概念(见微软官方文档),这里面比较重要的模型有以下几个:Application、Task、Cell、Resource等,当然,还有其他的比较重要的模型,只是不是很常用,在此不做说明。
Represents the active cell. (There is no collection for Cell objects.) The Cell object can be accessed only through the ActiveCell property of the Application object.
Represents a task. The Task object is a member of the Tasks collection.
Use Tasks(Index), where Index is the task index number or task name, to return a single Task object. The following example prints the name of every resource assigned to every task in the active project.
三、创建自定义任务窗口
还是先来看下自定义的创建任务窗口,效果如下:
由于我的个性化需求不是很复杂,就简单地创建了一个存储常用字段的Model,主要包括Task的常用属性,比如任务名称、工期、起止时间、资源以及完成百分比。以下是添新任务的代码段:
1 private void Create_Click(object sender, EventArgs e) 2 { 3 if (string.IsNullOrEmpty(taskName.Text)) return; 4 Project proj = Globals.ThisAddIn.Application.ActiveProject; 5 TaskModel.TaskModel taskModel = new TaskModel.TaskModel 6 { 7 TaskName = taskName.Text, 8 TaskDuring = taskDuring.Value.ToString(), 9 ResourceNames = taskResource.Text,10 Notes = taskNotes.Text11 };12 13 Application_NewProject(proj, taskModel);14 }
Application_NewProject接受一个当前的ActiveProject对象和一个TaskModel对象,代码如下:
1 private void Application_NewProject(Microsoft.Office.Interop.MSProject.Project pj, TaskModel.TaskModel taskModel) 2 { 3 object missing = Type.Missing; 4 TaskModel.TaskModel tm = taskModel; 5 Microsoft.Office.Interop.MSProject.Task newTask = pj.Tasks.Add(tm.TaskName, missing); 6 newTask.Start = DateTime.Now; 7 newTask.Duration = tm.TaskDuring; 8 newTask.ResourceNames = tm.ResourceNames.ToString(); 9 newTask.Notes = tm.Notes;10 }
新增Task是通过Project对象的Tasks属性的Add方法添加的。Task还有很多其他的属性,在此也不一一列举。
四、更清晰地展现任务进度
先看下整体的效果图:
在使用插件处理前基本是这样的
在使用插件处理后是这样的,预设好的背景色、字体、状态等。
这样一键处理后,看起来舒服多了,而且对进度的大概完成程度有一个直观的把握。相对格式刷子来说还是很方便的。
下面是部分代码:
1 /// <summary> 2 /// 根据任务状态进行背景填充的核心方法 3 /// </summary> 4 private void CallSelectTaskField() 5 { 6 foreach (Task task in Globals.ThisAddIn.Application.ActiveProject.Tasks) 7 { 8 Globals.ThisAddIn.Application.SelectTaskField(task.Index, "名称", false, 6, 0); 9 if (task.PercentComplete == 0)10 {11 CallFont32Ex(CommonData.MappingColorState(CommonData.TaskState.Ready));12 }13 else if (task.PercentComplete == 100)14 {15 CallFont32Ex(CommonData.MappingColorState(CommonData.TaskState.Complete));16 }17 else18 {19 CallFont32Ex(CommonData.MappingColorState(CommonData.TaskState.Processing));20 }21 }22 }
上面的代码中涉及到两个个核心模型,一个是Application,这是整个应用程序级别的对象,很多东西都封装在里面,包括ActiveCell、ActiveSelection、ActiveWindow以及上面代码中的ActiveProject,具体的成员请看这里;还有一个就是Task,Task模型对应的是Project中一条条的任务,它的很多成员都是动态类型(Dynamic),具体模型在这里,成员在这里。代码中从当前活动的Project中获取所有Task集合,并判断每一条Task的PercentComplete(完成百分比)属性,根据未开始、执行中和已完成几个状态来设置每一条Task背景色。开始时,我以为Task会存在一个背景色Background属性,但是并没有,而是通过选择一段Filed,然后针对该段Filed调用Font32Ex方法进行设置的。
在这个功能点上,还是遇到了很多麻烦,走了很多弯路,比如刚开始的时候,并不是采用Font32Ex方法来填充任务背景色的,而是用的TextStyle方法,这个方法的第一个参数是一个枚举,在填充背景色功能点上,只有第一个枚举生效了(其他也有,但是没有一个个尝试,枚举比较多),后来就采用录制宏的方式来解决,以下是宏代码:
1 Sub Macro1()2 ‘ 宏 Macro13 ‘ Xuhbd 在 2016年12月12日 记录的宏。4 SelectRow Row:=05 OutlineIndent6 Font32Ex CellColor:=622077 End Sub
在这段宏代码中,明显看到了Font32Ex这个方法,但是看了官方提供的文档,其中有一个参数是CellColor,要求的对象是pjColor枚举,运行后发现被填充的背景色都是黑色,无论选择什么颜色。
后来我就把pjColor直接用Color替换,居然成功了。
代码如下:
1 /// <summary> 2 /// 调用系统方法设置背景色 3 /// </summary> 4 /// <param name="bgColor"></param> 5 private void CallFont32Ex(Color bgColor) 6 { 7 object missing=Type.Missing; 8 Globals.ThisAddIn.Application.Font32Ex( 9 "微软雅黑", 9, missing, missing, 10 missing, missing, missing,11 bgColor, missing, missing);12 }
五、结语
通过完成这个Project的插件,学习了Project 模型,同时让我更加方便地使用Project,提高了积极性,如果有新的需求可以在这个基础上进行扩展,这样就形成了良性循环。在这个过程中,参考了很多的微软官方文档(而且是英文的,看来英文学习很重要啊),最后,代码已经托管到GitHub上,文中表述如果什么问题,请大家留言,我会及时更正。
Porject Addin Download
作者:悠扬的牧笛
博客地址:http://www.cnblogs.com/xhb-bky-blog/p/6155809.html
声明:本博客原创文字只代表本人工作中在某一时间内总结的观点或结论,与本人所在单位没有直接利益关系。非商业,未授权贴子请以现状保留,转载时必须保留此段声明,且在文章页面明显位置给出原文连接。
【原创】记一次Project插件开发