还是没有做PPT的灵感,总结下前段时间做的VISIO好了。
网上VISIO的资料那个少啊,姐艰辛地做了一个星期啊一个星期,中间还夹杂着PMP道德题的高强度训练,和各种“不知道为啥那么难,为啥怎么做准确率都不高,难道我道德真的不及格吗”的自我怀疑
// 网上本来就很少的资料,还带了n多术语,作为半个visio小白,研究了半天,成果如下:
//
visio文件叫document(PMP说没归档的叫file,归了档的叫document,偷偷地纠结为啥我才刚open都没save之前的visio也叫document……),用来画图的地方叫window,放图形的地方叫模具窗口,图形当然就叫模具了。
//做的是话路线,关键路径用红底标出,程序太长,不利于总结,就简写了。
//至今没搞懂怎么获取一个动态连接线两端的图形index,所以算法改成:
//
1、从数据库获取一个网络路径,用最早开始最晚开始时间(ES,LS)标出关键路径的节点。算ES的时候可以顺手标X值(图形画在哪里,靠(x,y)坐标定位,我用固定间隔画),唯一的起点排第一,直接后继第二,后继的后继们第3……,如果发现某点是某X值更大的点的后继,则改掉这点的ES值和X值。由于X固定间隔,很容易看出来哪些图形是站在同一列的,两层循环,for从最小的X到最大的X,for网络路线的DataTable,相同X值的图形用固定的Y增量填入不同的Y值。
// 2、两个循环找出哪个关键路径上的点的后继也在关键路径上,这些点准备用红底标出。
//
3、开始按(x,y)坐标drop图形,如果有红底标记,则涂红色,顺手将图形的index值放进datatable。drop完图形之后,在自己和后继之间drop连接线,如果有红底标记,则线需要涂红。
//--------正文来了---------
// 1.打开一个VISIO,增加一个application,有两种方法
MsVisio.InvisibleAppClass VsApp=new
Microsoft.Office.Interop.Visio.InvisibleAppClass(); //VISIO不可见,我稀饭用这种
MsVisio.Application VisApp=new
Microsoft.Office.Interop.Visio.Application(); //这样定义的VISIO是可见滴,就open了之后可以在托盘上找到他
MsVisio.Document
VsDoc=VsApp.Documents.Open(path+filename+".vsd"); //打开VISIO,路径由纯路径+文件名+vsd后缀组成。
// 2.停靠模具窗口“UML 活动”(用的是UML活动里的图形,因为画的是路线图,还要标出关键路径)
short flags=(short)MsVisio.VisOpenSaveArgs.visOpenDocked;
MsVisio.Documents VsDocs=VsApp.Documents;
MsVisio.Document VsStencil=VsDocs.OpenEx("UMLACT_M.VSS",flags);
//这个是模具窗口,不知道模具窗口名字的话在visio做个宏,然后直接ctrl C V 过来就行了。
// 3.定义当前页
MsVisio.Page VsPage=VsApp.ActivePage;
//4.定义我用到的4种图形的类型,同样,不知道名字的画到visio宏ctrlCV
MsVisio.Master MasterAS=VsStencil.Masters.get_ItemU(@"Action
State"); //活动
MsVisio.Master MasterBegin=VsStencil.Masters.get_ItemU(@"Initial
State"); //起点符
MsVisio.Master MasterEnd=VsStencil.Masters.get_ItemU(@"Finial
State"); //终止符
MsVisio.Master MasterCF = VsStencil.Masters.get_ItemU(@"Control
Flow"); //动态连接线
//5.画节点
MsVisio.Shape sp; //声明某一图形,跟int x是同类意思
if (如果是活动节点)
{
sp=VsPage.Drop(MasterAS,X值,Y值);
sp.Text=某string; // 我写的是 名称+活动时长+时长单位
if (如果有红底标记)
sp.get_CellsU("FillForegnd").Formula="RGB(255,153,204)"; //底色用浅红色,所以G值和B值都没有为0
}
else if (如果是起点)
sp=VsPage.Drop(MasterBegin,X值,Y值);
else //终点
sp=VsPage.Drop(MasterEnd,X值,Y值);
// 6.画动态连接线
MsVisio.Shape CnnShape;
MsVisio.Cell BeginXCell; MsVisio.Cell
EndXCell; //用来确定连接线连在图形的上下左右,不同图形的值还不一样,麻烦,还是得去CtrlCV visio宏
MsVisio.Shape BeginShape; MsVisio.Shape EndShape;
//画线
if (节点后继非空,则需要画线)
{
// 定义连接线从哪个点连到哪个点
BeginShape=VsPage.Shapes[BeginId]; //
BeginId=自己的图形index,之前画图形的时候存的图形Index有用了
EndShape=VsPage.Shapes[EndId]; //
EndId=后继的图形index
CnnShape=VsPage.Drop(MasterCF,0,0); //这个时候不用管你的线drop在哪里,随便写个xy值就行了
if(有红底标记)
Cnnshape.get_CellsU("LineColor").Formula="RGB(255,0,0)"
; //红色
// 设置连接起点
//
据推测,Shape.get_CellsSRC()中间的数值表示连接在左右前后
BeginXCell=CnnShape.get_CellsU("BeginX");
// 若起始shape是起始符,连接点在右边
if (BeginXCell.NameU.Contains("Initial
State"))
BeginXCell.GlueTo(VsPage.Shapes[BeginId].get_CellsSRC(7,2,0));
// 若起始shape是活动,连接点在右
else if(BeginShape.NameU.Contains("Action
State"))
BeginXCell.GlueTo(VsPage.Shapes[BeginId].get_CellsSRC(7,3,0));
//设置连接终点
EndXCell=CnnShape.get_CellsU("EndX");
//活动shape,连接点在左
if
(EndShape.NameU.Contains("Action State"))
EndXCell.GlueTo(VsPage.Shapes[EndId].get_CellsSRC(7,2,0));
//结束shape,连接点在左
if
(EndShape.NameU.Contains("Final State"))
EndXCell.GlueTo(VsPage.Shapes[EndId].get_CellsSRC(7,0,0));
}