今天早上在畫客戶的作業流程圖時,終於體認到現在Workflow在架構上的一個共同盲點--無法跨流程簽核。
從直覺上來看,不同系統之間的整合似乎不是Workflow應有的範圍,但從實務面的需求來看,Workflow往往成了各系統的啟動點,而且在簽核流程之中,似乎也會存在不同系統之間資料相互檢核的平台。舉例來說:員工想買一台電腦,採購申請單是啟動點,經過單位主管、採購部門、高階主管層層審核後同意採購,資料或先或後進入採購系統。等到貨物送來、收到發票,開票申請單又是一個啟動點,不論資料或先或後進入財會系統,但卻必須勾稽到採購系統的採購單。
問題就來了,到底要在財會系統做勾稽?還是在Workflow做?那採購系統如何更新採購狀態?有一種最簡單,也是最昂貴的作法-導入ERP。但一般ERP是沒有Workflow功能的,或只有簡單到不勘使用的簽核管理,整合的工作還是跑不掉。
另一種作法是客製MIS來做整合,因為額外導入的Workflow是不處理系統整合的。但在強調Reengineering的年代,不同作業流程中間的整合勢必無法避免,Workflow即然是處理流程的平台,理應替各個系統建立整合機制,以減少系統整合的開發工作。
看來Workflow軟體還有很大的成長空間。
2008/01/31
GridView事件執行順序@ASP.Net
在一個空白頁中置入GridView和一個Button後,當使用者按下按鈕後,各事件發生的順序如下:
Page GridView Button
------------ ------------ ------------
1 Init
2 Load
3 Load
4 RowCreated
5 RowDataBound
6 DataBound
7 Click
8 PreRender
2008/01/30
在空的GridView中顯示Header、Footer列@ASP.Net
因為GridView內建修改、刪除之功能,所以很多人利用GridView的Footer列,加入控制項,作為新增的功能。但因為GridView在沒有資料的時候,除了Empty Template外,不會顯示Header和Footer列,所以新增的功能就無效了。
有人直接利用Empty Template,加入FormView或DetailView作為新增的功能,但我覺得畫面上的不一致,容易造成使用者的困擾,執意要找出利用Footer列的方式。為此用Google找了一個晚上和早上,再加上 try 了半天,終於讓我摸索出最佳答案了。
方法是在GridView的PreRender事件中,判斷 Rows.Count 是否等於0,再執行下面這個函數。這樣利用Footer列做為新增資料的功能,就萬無一失了。
不過在執行階段時,新增資料後自動重新整理本頁時,因為GridView的DataSource還是我們虛擬的DataTable,因此不會顯示新增的記錄,故需在GridView1_Load中加入一段,改回原本的SqlDataSource。
有人直接利用Empty Template,加入FormView或DetailView作為新增的功能,但我覺得畫面上的不一致,容易造成使用者的困擾,執意要找出利用Footer列的方式。為此用Google找了一個晚上和早上,再加上 try 了半天,終於讓我摸索出最佳答案了。
方法是在GridView的PreRender事件中,判斷 Rows.Count 是否等於0,再執行下面這個函數。這樣利用Footer列做為新增資料的功能,就萬無一失了。
不過在執行階段時,新增資料後自動重新整理本頁時,因為GridView的DataSource還是我們虛擬的DataTable,因此不會顯示新增的記錄,故需在GridView1_Load中加入一段,改回原本的SqlDataSource。
public static void renderEmptyGridView(GridView EmptyGridView, string FieldNames)
{
//將GridView變成只有Header和Footer列,以及被隱藏的空白資料列
DataTable dTable = new DataTable();
char[] delimiterChars = {','};
string[] colName = FieldNames.Split(delimiterChars);
foreach (string myCol in colName)
{
DataColumn dColumn = new DataColumn(myCol.Trim());
dTable.Columns.Add(dColumn);
}
DataRow dRow = dTable.NewRow();
foreach (string myCol in colName)
{
dRow[myCol.Trim()] = DBNull.Value;
}
dTable.Rows.Add(dRow);
EmptyGridView.DataSourceID = null;
EmptyGridView.DataSource = dTable;
EmptyGridView.DataBind();
EmptyGridView.Rows[0].Visible = false;
}
protected void GridView1_PreRender(object sender, EventArgs e)
{
if (GridView1.Rows.Count == 0)
{
renderEmptyGridView(GridView1, "FLOW_UID, FLOW_CODE, FLOW_NAME, FLOW_TYPE");
}
}
protected void GridView1_Load(object sender, EventArgs e)
{
//回復原本GridView的資料連結
GridView1.DataSource = null;
GridView1.DataSourceID = "SqlDataSource1";
}
2008/01/20
DataFormatString@ASP.Net
終於進入ASP.Net領域。
在GridView中設定資料格式可用DataFormatString屬性,但需先將HtmlEncode屬性設為false才能發揮作用。
在GridView中設定資料格式可用DataFormatString屬性,但需先將HtmlEncode屬性設為false才能發揮作用。
動態增加option@Javascript
下面的語法可以增加或移除網頁中Select控制項的選取項目,對於要用AJAX動態變更選項的功能,是一個必項的工具。
function azAddOption(objID, optValue, optCaption){
//objID, optValue, optCaption
var obj = document.getElementById(objID);
var opt = new Option(optCaption, optValue );
obj.options.add(opt);
}
function azRemoveAllOptions(objID){
var obj = document.getElementById(objID);
for(var i = obj.options.length-1 ; i >= 0 ; i--) {
obj.options.remove(i);
}
}
交叉查詢語法@Oracle
用Oracle來建立交叉查詢表的語法如下:
這個語法可以將資料表:
變成這樣:
這個語法有個缺點是你必須事先知道橫向欄位的名稱及數量,如果欄位是變數就無效了。
select to_char(Applydate, 'yyyy/mm' ) As Month,
count(Decode(FormID, 'A01', SerialID, null )) AS A01,
count(Decode(FormID, 'A02', SerialID, null )) AS A02
from AFS_FLOW group by to_char(Applydate, 'yyyy/mm' )
這個語法可以將資料表:
Applydate FormID SerialID
========= ====== ========
2007/09/11 A01 T0000001
2007/09/12 A02 T0000002
2007/10/11 A01 T0000003
2007/10/12 A01 T0000004
變成這樣:
Month A01 A02
========= ====== ======
2007/09 1 1
2007/10 2 0
這個語法有個缺點是你必須事先知道橫向欄位的名稱及數量,如果欄位是變數就無效了。
如何撰寫 MSN Messenger Activity SDK @MSN
正式的 MSN Messenger Activity 必須向微軟live網站註冊後才能使用,如果只是自己寫著好玩,也可以不用註冊,但每一台電腦只能執行一個測試的 Activity ,雖然不方便,但至少有條路可以自己玩玩,而且可以和朋友對話時邀請他一起玩。
基本上寫 MSN Messenger Activity SDK 就是在寫網頁,利用html和Javascript(當然VBScript也可以,只是會用的人應該不多吧?)作出小遊戲的外觀和功能就可以了,以下就撰寫的過程說明如下:
1. 寫好一個網頁,比如<body>Hello, MSN Activity!</body>,放到網路上或本機的IIS下。
2. 從 C:\Program Files\MSN Messenger\ 找到 msgrp2p.xml 檔,這個就是告訴 MSN 測試的 Activity 的基本資料,包括網站位置和存取功能的限制。將原檔備份起來後,用筆記本打開這個xml 檔,幾個重要的tags說明如下:
<name>:Activity 的名稱,出現在MSN的工具列>執行上,會多了一項 "啟動XXXXX" 的項目。
<url>:網頁的位置,必須加上http://,如果你所寫的程式頁放在本機上,就會類似這樣
<url>http://localhost/web_test/myActivity.htm</url>
其他有一些參數,像是<SendIM>、<ReceiveIM>等,是限制小程式能否傳送訊息用的,須一併修改。
3. 將 msgrp2p.xml 檔修改並存檔後,重新啟動MSN,選擇某一個連絡人後,打開對話視窗,再從工具列>執行,就可以看到你所寫的Activity名稱了。點選後會先詢問對方是否接受,如果對方按下接受,在對話窗右邊就會跑出來一個小視窗,執行你所設計的網頁。
基本上寫 MSN Messenger Activity SDK 就是在寫網頁,利用html和Javascript(當然VBScript也可以,只是會用的人應該不多吧?)作出小遊戲的外觀和功能就可以了,以下就撰寫的過程說明如下:
1. 寫好一個網頁,比如<body>Hello, MSN Activity!</body>,放到網路上或本機的IIS下。
2. 從 C:\Program Files\MSN Messenger\ 找到 msgrp2p.xml 檔,這個就是告訴 MSN 測試的 Activity 的基本資料,包括網站位置和存取功能的限制。將原檔備份起來後,用筆記本打開這個xml 檔,幾個重要的tags說明如下:
<name>:Activity 的名稱,出現在MSN的工具列>執行上,會多了一項 "啟動XXXXX" 的項目。
<url>:網頁的位置,必須加上http://,如果你所寫的程式頁放在本機上,就會類似這樣
<url>http://localhost/web_test/myActivity.htm</url>
其他有一些參數,像是<SendIM>、<ReceiveIM>等,是限制小程式能否傳送訊息用的,須一併修改。
3. 將 msgrp2p.xml 檔修改並存檔後,重新啟動MSN,選擇某一個連絡人後,打開對話視窗,再從工具列>執行,就可以看到你所寫的Activity名稱了。點選後會先詢問對方是否接受,如果對方按下接受,在對話窗右邊就會跑出來一個小視窗,執行你所設計的網頁。
MSN Messenger Activity SDK初探@MSN
因為自己想在MSN裡玩一些花招,所以花了一些時間研究如何開發MSN的應用程式。首先找到的是這一篇文章
MSN Messenger之程式設計二三事,有清楚的說明,但對於如何寫,並沒有交待。
因此自己下載了MSN Messenger Activity SDK 來看,讀了一堆英文後還是一知半解,只好硬著頭皮寫看看,終於了解其功用。原來 MSN Messenger Activity 是讓對話中的兩個人(或更多人),可以從<檢查活動清單>來共用一個網頁程式,該網頁可以透過MSN的瀏覽器玩玩小程式、小遊戲。
這個Activity SDK中並包含了一部份MSN的功能,像是開啟MSN選項視窗、傳送訊息或檔案等。但因為使用 Activity 必須要邀請朋友參加,再等對方同意,然後才可以啟動,和我原先想到達到主動 push 訊息到使用者的MSN的目的不同,所以就沒有繼續玩下去了。
如果想知道如何撰寫 MSN Messenger Activity SDK 的程式,請看下一篇文章 如何撰寫 MSN Messenger Activity SDK @MSN 。
MSN Messenger之程式設計二三事,有清楚的說明,但對於如何寫,並沒有交待。
因此自己下載了MSN Messenger Activity SDK 來看,讀了一堆英文後還是一知半解,只好硬著頭皮寫看看,終於了解其功用。原來 MSN Messenger Activity 是讓對話中的兩個人(或更多人),可以從<檢查活動清單>來共用一個網頁程式,該網頁可以透過MSN的瀏覽器玩玩小程式、小遊戲。
這個Activity SDK中並包含了一部份MSN的功能,像是開啟MSN選項視窗、傳送訊息或檔案等。但因為使用 Activity 必須要邀請朋友參加,再等對方同意,然後才可以啟動,和我原先想到達到主動 push 訊息到使用者的MSN的目的不同,所以就沒有繼續玩下去了。
如果想知道如何撰寫 MSN Messenger Activity SDK 的程式,請看下一篇文章 如何撰寫 MSN Messenger Activity SDK @MSN 。
動態輸入框@Javascript
為了客戶的需要,在一大張報表中要能修改數值資料,所以試作了這個 function。
這個 function 可以讓表格(table)中的儲存格(td)變成輸入框(input type=text),而且使用者儲存後可以改變儲存格的值 。
用這個 網址 來測試效果。
這個 function 可以讓表格(table)中的儲存格(td)變成輸入框(input type=text),而且使用者儲存後可以改變儲存格的值 。
用這個 網址 來測試效果。
ActiveCell@VBA
VBA中的物件與指令百百種,在 excel 中寫巨集常常是寫過就忘,像是這個要讀取作用中的工作表或儲存格,就是最常用的了。
作用中的儲存格 ActiveCell
作用中的工作表 ActiveSheet
作用中的活頁簿 ActiveWorkbook
巨集所在的活頁簿 ThisWorkbook
使活頁簿變成作用中 Workbooks(1).Activate
作用中的儲存格 ActiveCell
作用中的工作表 ActiveSheet
作用中的活頁簿 ActiveWorkbook
巨集所在的活頁簿 ThisWorkbook
使活頁簿變成作用中 Workbooks(1).Activate
Julian Date轉成日期格式@Oracle
由於JDE系統將日期資料儲存為Julian Date的格式,為了方便網頁的讀取,便先用PL-SQL語法轉成日期格式。
Julian日期格式以6位整數代表一個日期,第1位為世紀,20世紀為0,21世紀為1;第2、3位為年;最後3位代表當年的第幾天。例如107003表示是21世紀的07年的第3天,亦即2007/1/3。利用PL-SQL語法轉換公式如下:
Julian日期格式以6位整數代表一個日期,第1位為世紀,20世紀為0,21世紀為1;第2、3位為年;最後3位代表當年的第幾天。例如107003表示是21世紀的07年的第3天,亦即2007/1/3。利用PL-SQL語法轉換公式如下:
TO_DATE(CONCAT((FLOOR(JULIAN_DATE/1000) + 1900),'0101'),'YYYYMMDD') + (MOD(JULIAN_DATE,1000)-1)
取得GUID@ASP
GUID全名是Globally Unique Identifier,依據微軟的說法:GUID 是一個 128 位元的整數 (16 位元組),可以在需要唯一識別項時用於所有電腦和網路。
因為重複的機率很低,可以用來當做資料庫的key值,以避免以流水號當作key值時,可以修改網址參數而偷看到別人的資料。這支程式也是從網路上找到的,年代久遠出處已經不可考了。
因為重複的機率很低,可以用來當做資料庫的key值,以避免以流水號當作key值時,可以修改網址參數而偷看到別人的資料。這支程式也是從網路上找到的,年代久遠出處已經不可考了。
Function GetGuid()
Set TypeLib = Server.CreateObject("Scriptlet.TypeLib")
tg = TypeLib.Guid GetGuid = mid(tg, 2 ,len(tg)-4)
Set TypeLib = Nothing
End Function
千分符號@Javascript
找到一個聽說是從書上抄來的 function,真的是太佩服作者的功力。
此函數可以將數值加上千分符號,以方便閱讀。但原程式只能處理字串資料,經過本人小小的修改後,如果輸入參數不是數值的話,就傳回原資料。
此函數可以將數值加上千分符號,以方便閱讀。但原程式只能處理字串資料,經過本人小小的修改後,如果輸入參數不是數值的話,就傳回原資料。
function addCommas( sValue ) {
if (! isNaN(sValue)) {
sValue = sValue.toString() ;
var sRegExp = new RegExp("(-?[0-9]+)([0-9]{3})");
while(sRegExp.test(sValue)) {
sValue = sValue.replace(sRegExp, '$1,$2');
}
}
return sValue;
}
二維陣列@Javascript
今天在網路上找到Javascript二維陣列的寫法,但實際套在程式中一直有一個「找不到 ";"」的錯誤,試了一個多小時才發現問題所在。
正確寫法如下:
錯誤寫法如下:
為了這個 var 花了一個多小時真是不值!
正確寫法如下:
var LineItem = new Array();
for(var i=1; i<=8 ; i++){
LineItem[i] = new Array();
LineItem[i][0] = i ;
LineItem[i][1] = "ITM0" + i;
LineItem[i][2] = 100*i ;
}
錯誤寫法如下:
var LineItem = new Array();
for(var i=1; i<=8 ; i++){
var LineItem[i] = new Array();
LineItem[i][0] = i ;
LineItem[i][1] = "ITM0" + i;
LineItem[i][2] = 100*i ;
}
為了這個 var 花了一個多小時真是不值!
2008/01/16
取得使用者選取之文字@Javascript
為了特殊目的,需要一支可以知道使用者在網頁中選取那段文字。在網路上找了半天(真的有半天),終於找到了,方法如下:
function getSelectedText()
{
var txt = "";
if (window.getSelection) {
txt = window.getSelection();
}
else if (document.getSelection){
txt = document.getSelection();
}
else if (document.selection){
txt = document.selection.createRange().text;
}
else { return; }
alert(txt);
}
2008/01/13
GridView 範例集@ASP.Net
以下這篇文章可以說是 GridView 的終極應用了,有興趣的人請參考。
ASP.NET 2.0 GridView 範例集
作者:黃忠成
http://www.microsoft.com/taiwan/msdn/columns/huang_jhong_cheng/ASP_NET_GridView.htm
1. 漸層光棒
2. 雙標題列
3. 標題欄合併
4. 合併儲存格
5. 主從式明細表 Master-Detail GridView
6. 下拉式明細表
7. GridView 的效能
ASP.NET 2.0 GridView 範例集
作者:黃忠成
http://www.microsoft.com/taiwan/msdn/columns/huang_jhong_cheng/ASP_NET_GridView.htm
1. 漸層光棒
2. 雙標題列
3. 標題欄合併
4. 合併儲存格
5. 主從式明細表 Master-Detail GridView
6. 下拉式明細表
7. GridView 的效能
訂閱:
文章 (Atom)