Easyflow.NET 程式更新流程說明 開單加流程、流程中增減修改流程

對於 Easyflow 執行流程增減修改等動作中,比較有關聯的資料表有三個:

  • 表單流程異動子檔(RESDB):紀錄表單所有的流程關卡,新增刪除或更新都由此表來操作。
  • 表單流程異動明細檔(RESDC):紀錄表單流程已確定完成簽核的關卡簽核狀態。
  • 表單流程異動明細簽核檔(RESDD):紀錄表單流程簽核中的所有詳細的歷程,例如: 對同流程關卡經歷多次上呈、退件的動作,每一次的簽核結果都會被詳盡紀錄。

無意間在網路上找到「程式碼控制流程說明文件」。雖然這是ASP版本的說明文件,但是文章中講到對流程控制時所使用的物件架構,在Dot.NET版本中它有被延用下來且物件名稱都一樣。

  • rstTRFlow:「resdb」資料表物件,使用時機 流程簽核中。
  • rstTRFlowDetail:「resdc」資料表物件,使用時機 流程簽核中。
  • rstTRFlowApprove:「resdd」資料表物件,使用時機 流程簽核中。

在開單時可利用覆寫「BeforeSendNewFormAddFlow」函式,在送出來表單時手動加入新的流程關卡。※「TRFlowRESDB」類別所建立的物件,可以在開單時新增流程資訊。

		protected override void BeforeSendNewFormAddFlow(TRFlowRESDB[] xFlowData, ref bool xBlnFlowChanged)
		{
			xBlnFlowChanged = false; //不要重新解析流程
			int rows_count = MasterObj.DetailObjs[0].NewRows.Count;//取得grid有幾列資料
			xFlowData = new TRFlowRESDB[rows_count];//宣告流程物件陣列及其大小
			int resdb003=9901,index=0;//迴圈用的變數,流程關號、流程物件索引
			//送出表單時插入自訂流程使用 MasterObj.DetailObjs[0].NewRows 物件
			//DetailObjs[0]代表第一個Grid物件
			//NewRows代表尚未存入資料庫的資料
			foreach (DscRow dscRow in MasterObj.DetailObjs[0].NewRows)
			{
				if (!dscRow.IsDeleted)
				{
					xFlowData[index].resdb001 = formID; //表單代號
					xFlowData[index].resdb002 = SheetNo; //表單單號
					xFlowData[index].resdb003 = resdb003.ToString(); //關號
					xFlowData[index].resdb004 = "0010"; //支號
					xFlowData[index].resdb005 = 1; //流程角色
					xFlowData[index].resdb006 = 4; //簽核種類
					xFlowData[index].resdb007 = dscRow["empl1"].Value.ToString(); //流程角色參數1 (Grid物件中取得的員工編號值,中括號中填入"欄位名稱")
					xFlowData[index].resdb008 = ""; //流程角色參數2
					xFlowData[index].resdb009 = ""; //流程角色參數3
					xFlowData[index].resdb010 = ""; //流程角色參數4
					xFlowData[index].resdb011 = 0;  //容許簽核時間
					xFlowData[index].resdb012 = "N"; //自動ByPass?
					xFlowData[index].resdb013 = "0"; //ByPass方式
					xFlowData[index].resdb014 = "Y"; //是否強制簽核?
					xFlowData[index].resdb015 = "Y"; //是否單一簽核
					xFlowData[index].resdb016 = "N"; //可否列印?
					xFlowData[index].resdb017 = "Y"; //可否撤簽?
					xFlowData[index].resdb018 = "Y"; //可否加簽?
					xFlowData[index].resdb019 = "N"; //可否轉會?
					xFlowData[index].resdb020 = "N"; //可否轉寄?
					xFlowData[index].resdb021 = "N"; //可否新增附加檔?
					xFlowData[index].resdb022 = "N"; //可否修改附加檔?
					xFlowData[index].resdb023 = "N"; //可否刪除附加檔?
					xFlowData[index].resdb024 = "Y"; //可否閱讀附加檔?
					xFlowData[index].resdb025 = "N"; //簽核時密碼驗證?
					xFlowData[index].resdb026 = "N"; //流程是否已經解析?
					xFlowData[index].resdb027 = ""; //流程提示訊息
					xFlowData[index].resdb028 = ""; //
					xFlowData[index].resdb029 = ""; //
					resdb003++;
					index++;
				}
			}
			base.BeforeSendNewFormAddFlow(xFlowData, ref xBlnFlowChanged);
		}

而在流程簽核中則以覆寫「BeforeApprove」、「AfterApprove」這兩個函式來處理流程關卡的新增、刪除、修改。在這兩個函式中就可以使用 RstTRFlow、RstTRFlowApprove、RstTRFlowDetail 這三個物件來操作他們所對應的表單資料。

#region 簽核前處理
		protected override void BeforeApprove(PublicUTIL.DBProcessor processor)
		{
			base.BeforeApprove(processor);
			//取得單身欄位資料
			string sql_command = @"select empl1 from [EFNETDB].[dbo].[test2_2] where test2_2001='{0}' and test2_2002='{1}' ";
			sql_command = String.Format(sql_command, this.formID, this.SheetNo);
			SqlDataAdapter my_adapter = processor.getDataAdapter(sql_command);
			DataTable my_table= new DataTable();
			my_adapter.Fill(my_table);

			if (AryFlowProperty.SerialSignResult == "2") //同意
			{
				//如果關號是0010,則手動塞流程
				if (this.FlowNo == "0010")
				{
					foreach (DataRow my_resdd_row in RstTRFlowApprove.Tables[0].Select("resdd003 like '2%'"))
					{
						my_resdd_row.Delete();
					}
					foreach (DataRow my_resdc_row in RstTRFlowDetail.Tables[0].Select("resdc003 like '2%'"))
					{
						my_resdc_row.Delete();
					}
					foreach (DataRow my_resdb_row in RstTRFlow.Tables[0].Select("resdb003 like '2%'"))
					{
						my_resdb_row.Delete();
					}

					int resdb003=20;
					foreach( DataRow my_row in my_table.Rows )
					{
						DataRow my_datarow = RstTRFlow.Tables[0].NewRow();//流程資料表建立一新的資料列
						//開始設定資料列相關資資料
						my_datarow["resdb001"] = formID;
						my_datarow["resdb002"] = SheetNo;
						my_datarow["resdb003"] = resdb003.ToString()+DateTime.Now.Second.ToString("00");
						my_datarow["resdb004"] = "0010"; //支號
						my_datarow["resdb005"] = 1; //流程角色
						my_datarow["resdb006"] = 4; //簽核種類
						my_datarow["resdb007"] = my_row["empl1"].ToString(); //流程角色參數1 (Grid物件中取得的員工編號值,中括號中填入"欄位名稱")
						my_datarow["resdb008"] = ""; //流程角色參數2
						my_datarow["resdb009"] = ""; //流程角色參數3
						my_datarow["resdb010"] = ""; //流程角色參數4
						my_datarow["resdb011"] = 0;  //容許簽核時間
						my_datarow["resdb012"] = "N"; //自動ByPass?
						my_datarow["resdb013"] = "0"; //ByPass方式
						my_datarow["resdb014"] = "Y"; //是否強制簽核?
						my_datarow["resdb015"] = "Y"; //是否單一簽核
						my_datarow["resdb016"] = "N"; //可否列印?
						my_datarow["resdb017"] = "Y"; //可否撤簽?
						my_datarow["resdb018"] = "Y"; //可否加簽?
						my_datarow["resdb019"] = "N"; //可否轉會?
						my_datarow["resdb020"] = "N"; //可否轉寄?
						my_datarow["resdb021"] = "N"; //可否新增附加檔?
						my_datarow["resdb022"] = "N"; //可否修改附加檔?
						my_datarow["resdb023"] = "N"; //可否刪除附加檔?
						my_datarow["resdb024"] = "Y"; //可否閱讀附加檔?
						my_datarow["resdb025"] = "N"; //簽核時密碼驗證?
						my_datarow["resdb026"] = "N"; //流程是否已經解析?
						my_datarow["resdb027"] = ""; //流程提示訊息
						my_datarow["resdb028"] = ""; //
						my_datarow["resdb029"] = ""; //
						RstTRFlow.Tables[0].Rows.Add(my_datarow);//將資料列插入流程資料表中
						resdb003++;
					}
				}
			}
		}
#endregion

		protected override void AfterApprove()
		{
			base.AfterApprove();
		}

p.s:以上的程式碼片段僅為測試說明用,實際上可能未能符合流程關卡新增刪除相關資料表依存邏輯。

Easyflow.NET 如何在簽核中加入新的流程關卡

這次要在表單簽核流程中由程式判斷手動塞入新的流程關卡。所用的變數和先前開單塞流程中使用的是不一樣,至於為什麼不能用開單中所使用的變數我也不知道為何。相同的這次還是由雙檔表單的子單身中紀錄的人員作為塞入的流程關卡來作為操作範例。

一、取得紀錄 Grid 單身中人員的員工編號是使用 Easyflow 物件中內建的方法processor.getDataAdapter(sql_command) 直接由資料庫中抓取資料並填入 DataTable 物件的變數之中。在取得人員資料後就可以利用迴圈,將流程塞入表單流程異動子檔資料表中。

二、插入流程 於流程中使用表單流程資料表物件的方法「RstTRFlow.Tables[0].Add(my_datarow)」加入新的流程關卡。在這之前先必須藉由 「RstTRFlow.Tables[0].NewRow()」物件方法新增一個「DataRow」資料列件件(流程關卡資料列),再將這資料列物件的「key-value」資料補齊(設定方法如陣列元素給值那樣)。

函式「BeforeApprove」程式碼範例(完整檔案範例 TEST2.aspx.cs

	#region 簽核前處理
    protected override void BeforeApprove(PublicUTIL.DBProcessor processor)
    {
        base.BeforeApprove(processor);
        //取得單身欄位資料
        string sql_command = @"select empl1 from [EFNETDB].[dbo].[test2_2] where test2_2001='{0}' and test2_2002='{1}' ";
        sql_command = String.Format(sql_command, this.formID, this.SheetNo);
        SqlDataAdapter my_adapter = processor.getDataAdapter(sql_command);
        DataTable my_table= new DataTable();
        my_adapter.Fill(my_table);

        if (AryFlowProperty.SerialSignResult == "2") //同意
        {
            //如果關號是0010,則手動塞流程
            if (this.FlowNo == "0010")
            {
                int resdb003=9901;
                foreach( DataRow my_row in my_table.Rows )
                {
                        DataRow my_datarow = RstTRFlow.Tables[0].NewRow();//流程資料表建立一新的資料列
                        //開始設定資料列相關資資料
                        my_datarow["resdb001"] = formID;
                        my_datarow["resdb002"] = SheetNo;
                        my_datarow["resdb003"] = resdb003;
                        my_datarow["resdb004"] = "0010"; //支號
                        my_datarow["resdb005"] = 1; //流程角色
                        my_datarow["resdb006"] = 4; //簽核種類
                        my_datarow["resdb007"] = my_row["empl1"].ToString(); //流程角色參數1 (Grid物件中取得的員工編號值,中括號中填入"欄位名稱")
                        my_datarow["resdb008"] = ""; //流程角色參數2
                        my_datarow["resdb009"] = ""; //流程角色參數3
                        my_datarow["resdb010"] = ""; //流程角色參數4
                        my_datarow["resdb011"] = 0;  //容許簽核時間
                        my_datarow["resdb012"] = "N"; //自動ByPass?
                        my_datarow["resdb013"] = "0"; //ByPass方式
                        my_datarow["resdb014"] = "Y"; //是否強制簽核?
                        my_datarow["resdb015"] = "Y"; //是否單一簽核
                        my_datarow["resdb016"] = "N"; //可否列印?
                        my_datarow["resdb017"] = "Y"; //可否撤簽?
                        my_datarow["resdb018"] = "Y"; //可否加簽?
                        my_datarow["resdb019"] = "N"; //可否轉會?
                        my_datarow["resdb020"] = "N"; //可否轉寄?
                        my_datarow["resdb021"] = "N"; //可否新增附加檔?
                        my_datarow["resdb022"] = "N"; //可否修改附加檔?
                        my_datarow["resdb023"] = "N"; //可否刪除附加檔?
                        my_datarow["resdb024"] = "Y"; //可否閱讀附加檔?
                        my_datarow["resdb025"] = "N"; //簽核時密碼驗證?
                        my_datarow["resdb026"] = "N"; //流程是否已經解析?
                        my_datarow["resdb027"] = ""; //流程提示訊息
                        my_datarow["resdb028"] = ""; //
                        my_datarow["resdb029"] = ""; //
                        RstTRFlow.Tables[0].Rows.Add(my_datarow);//將資料列插入流程資料表中
                        resdb003++;
                }
            }
        }
    }
 #endregion

執行步驟說明:

程式碼 BeforeApprove 範例片段,利用這個函式在指定的關卡完成審核動作前加入新的流程關卡。

建立一張測試表單,加入兩位員工於單身中。

表單送出後,流程解析為兩關。

在第二關流程畫面中,解析流程已有新的流程加入。

第三關流程解析畫面

最後表單完成簽核

Easyflow.NET 表單送出時,依Grid中的員工編號做為手動塞流程的關卡

由雙檔架構表單的單身(Grid)所儲存的員工編號欄位值,來當作程式手動塞流程的員工編號值(流程參數1的值)。此次的重點在於知道Grid的物件是什麼及如何從Grid物件中取得指定欄位的值。

表單後端程式碼完整範例「TEST2.aspx.cs」
範例程式碼片段:

protected override void BeforeSendNewFormAddFlow(TRFlowRESDB[] xFlowData, ref bool xBlnFlowChanged)
{
	xBlnFlowChanged = false; //不要重新解析流程
	int rows_count = MasterObj.DetailObjs[0].NewRows.Count;//取得grid有幾列資料
	xFlowData = new TRFlowRESDB[rows_count];//宣告流程物件陣列及其大小
	int resdb003=9901,index=0;//迴圈用的變數,流程關號、流程物件索引
	//送出表單時插入自訂流程使用 MasterObj.DetailObjs[0].NewRows 物件
	//DetailObjs[0]代表第一個Grid物件(第一個子單身)
	//NewRows代表尚未存入資料庫的資料
	foreach (DscRow dscRow in MasterObj.DetailObjs[0].NewRows)
	{
		if (!dscRow.IsDeleted)
		{
			xFlowData[index].resdb001 = formID; //表單代號
			xFlowData[index].resdb002 = SheetNo; //表單單號
			xFlowData[index].resdb003 = resdb003.ToString(); //關號
			xFlowData[index].resdb004 = "0010"; //支號
			xFlowData[index].resdb005 = 1; //流程角色
			xFlowData[index].resdb006 = 4; //簽核種類
			xFlowData[index].resdb007 = dscRow["empl1"].Value.ToString(); //流程角色參數1 (Grid物件中取得的員工編號值,中括號中填入"欄位名稱")
			xFlowData[index].resdb008 = ""; //流程角色參數2
			xFlowData[index].resdb009 = ""; //流程角色參數3
			xFlowData[index].resdb010 = ""; //流程角色參數4
			xFlowData[index].resdb011 = 0;  //容許簽核時間
			xFlowData[index].resdb012 = "N"; //自動ByPass?
			xFlowData[index].resdb013 = "0"; //ByPass方式
			xFlowData[index].resdb014 = "Y"; //是否強制簽核?
			xFlowData[index].resdb015 = "Y"; //是否單一簽核
			xFlowData[index].resdb016 = "N"; //可否列印?
			xFlowData[index].resdb017 = "Y"; //可否撤簽?
			xFlowData[index].resdb018 = "Y"; //可否加簽?
			xFlowData[index].resdb019 = "N"; //可否轉會?
			xFlowData[index].resdb020 = "N"; //可否轉寄?
			xFlowData[index].resdb021 = "N"; //可否新增附加檔?
			xFlowData[index].resdb022 = "N"; //可否修改附加檔?
			xFlowData[index].resdb023 = "N"; //可否刪除附加檔?
			xFlowData[index].resdb024 = "Y"; //可否閱讀附加檔?
			xFlowData[index].resdb025 = "N"; //簽核時密碼驗證?
			xFlowData[index].resdb026 = "N"; //流程是否已經解析?
			xFlowData[index].resdb027 = ""; //流程提示訊息
			xFlowData[index].resdb028 = ""; //
			xFlowData[index].resdb029 = ""; //
			resdb003++;
			index++;
		}
	}
	base.BeforeSendNewFormAddFlow(xFlowData, ref xBlnFlowChanged);
}

流程角色及流程角色參數設定參考

範例說明:
新增一個雙檔的表單,其中單頭只有一個 Textbox 輸入框,然後用 Grid 物件建立單身而單身也僅有放一個DSC內建的員工選單。(注意:被加入單身的人員會變成表單流程的關卡)

原始的流程設置,只有一個關卡(直屬主管)。

修改表單後端的程式碼,複寫函式「BeforeSendNewFormAddFlow」。這樣做可以在表單送出前經由程式修改的內容,將所選取的人員做為關卡插入於原始流程關卡之後。「BeforeSendNewFormAddFlow」函式預設是不會出現在後端程式碼的檔案中,我們需要手動將這段函式的程式碼區塊放到表單類別裏。

修改完成之後,重新開啟測試表單。將人員選擇加入單身之中,接著按下表單送出按鈕。此時表單流程顯示就會出現我們剛剛所加入人員的流程關卡。

EasyFlow.NET 在表單設計階段中刪除不需要的資料欄位

在表單設計階段中刪除用不到的資料欄位,需要到「EFNETDB」資料庫中找到名為「EFormWizardField」的資料表,然後在資料表中找出對將應表單欄位的資料列將之刪除即可。表單代號及欄位代號兩個主Key可讓我們找到想要刪除的資料欄位。(修改此資料表欄位還可以變更資料欄位的資料屬性)

刪除電子表單精靈的欄位資料列之後,還要需要將電子表單對應的資料儲存Table裏把剛剛刪除掉的欄位給移除

除了上面刪除相對應的資料列之外,還需要利用電子表單設計精靈快速的將該表單重新設計一遍(一直按著下一步直到結束修改),如此就能產生新的表單程式檔案不至於在開啟表單時出現錯誤。

Easyflow.net ISO模組 使用自訂頁面顯示ISO文件一覽表

歷經兩個禮拜大家勤奮的打單(新增ISO文件申請單)後,已經將公司現行的ISO相關文件, 都提交到Easyflow的ISO文管中心,並且已發佈成功。

因為公司ISO架構會在不同的ISO形態下,有引用相同ISO文件的問題。所以在建立所謂的Easyflow’s ISO文件資料三階層(型態、階層、類別)的架構下,須注意以下三點: 繼續閱讀

Easyflow.NET 進階表單程式設計心得之MIMJ

什麼是MIMJ這可以分成兩個部份來看,一個是MI當然另一個就是MJ啦。MI主要的功能為開窗帶值,而MJ的功用就是當MI帶值回來造成欄位值變動時(不一定要MI開窗帶值,只要欄位值有變動就會觸發),進行後端驗証的動作並回傳一個值。
繼續閱讀

EasyFlow.Net 如何修改表單類別

【問題】已修改了表單的類別,但左邊的樹狀為何沒有改有改變?

【解答】

  1. 請至 系統管理工具 >> 程式選單建立 修改 “上層資料匣編號", 查詢時請用 進階 資料匣代號 查詢 程式代號。
  2. 同時也到 流程基本設定 >> 表單性質維護作業 查看表單類別是否已修正為修改後的表單類別。
  3. 最後看看左邊的選單是表單是否換了類別了。