還是沒有做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));
}