第224期 / June 6, 2016

研發新視界

分享到臉書!分享到維特!分享到噗浪!分享到Google+!分享到微博!轉寄友人友善列印

Microsoft Project 解析心得分享

作者/余世堯

[發表日期:2016/4/5]

前言

由於筆者工作上有與Project介接資料的需求,開始了一連串的解析動作。解析的主要對象是Microsoft Project,其中部分設計頗具巧思,值得借鏡。

資料解析

首先,透過將 MPP 檔轉存為xml,使資料轉為人工可閱讀的型態。於此,可看出一個檔案主要分為五大區段,分別是專案的基本設定、行事曆、工作任務、資源清單、任務分派。這五段是各專案基本上都會有的部分。此外,若有設定自訂欄位,則會多出一段自訂欄位的設定區段。本段落將著重於自訂欄位與任務分派兩段進行描述。

一、自訂欄位

自訂欄位的部分,Microsoft Project提供擴充數量是有限的。在設定一個新的自訂欄位時,首先要決定該欄位是屬於專案、任務還是資源的擴充欄位,其次要決定該欄位要儲存的資料性質,是屬於文字、數字還是日期、成本…等。

根據項目與資料內容這兩項設定的不同,所能擴充的自訂欄位數量也不同。例如任務-文字提供了30個自訂欄位,而任務-數字則只提供了20個自訂欄位。

在實際追蹤其資料結構前,原先以為Microsoft Project會採用固定欄位名稱的資料結構(如圖一)。因為,在設定畫面中,即使我們已重新命名,但其「文字1」的字樣也不會消失(如圖二),而且不論是否有使用到的欄位,都會在畫面上顯示出來。


《圖一》假想的資料內容



《圖二》自訂欄位設定畫面


但實際檢視並分析其xml的資料後,發現跟假設的完全不同。其xml在針對自訂欄位的結構設計如下,首先對每一個自訂欄位,其內部會給予一組獨立的 FieldID (如圖三)。之後在每一個任務/資源上,針對這個 FieldID 給予實際值(如圖四)。

特別的是,它將欄位的原始名稱與使用者自行決定的名稱分開在不同的欄位儲存。這種做法,由於原始的欄位名稱未被更改,在後續程式開發時(Ex:巨集),依然能準確地取得欄位,不用擔心名稱的變動。同時,這也避免了使用者不小心將欄位名稱修改成跟其他系統內的欄位名稱相同的困擾。


《圖三》自訂欄位 xml內容範例



《圖四》資源自訂欄位之屬性xml內容範例


此種結構設計遠比原先預想的要好。首先,在欄位的數量上沒有任何限制,要擴充多少欄位都是可行的。其次,不對未使用或未賦值的欄位進行描述,減少了文檔的大小。並且使用者任意的命名甚至修改欄位名稱,也絲毫不影響資料的串聯性。

此種資料結構,非常值得我們學習利用。故我們在實作介接系統時依然沿用的此種架構。在學習其優點的同時也保留了足夠的彈性來面對未來版本的 Microsoft Project 可能擴展其欄位數的情況。

二、任務分派

Microsoft Project 能安排每一個任務分派了哪些資源供其使用。亦可針對單一的資源分派設定其可用比例與起訖時間…等。所以這部分在XML文檔上會獨立為一段,而非包含於任務或資源中。

一項工作分派,除了其對應的任務與資源外,還包含了各任務分派的工時、可用比例、起訖時間…等資訊(如圖五)。


《圖五》任務分派xml內容範例


而其中在工時的分佈上,除了我們一般所熟知的平均分佈外,實際上還有多種不同的分佈方式(如圖六)。而在相同工時的情況下,根據分佈的方式不同,除了每天所需的工時不同外,完成工作所需的天數也可能會不同(如圖七)。


《圖六》作業分布設定畫面



《圖七》工時分布狀況表


到這邊為止,或許直覺上會猜測其設計就跟操作畫面一樣,在Assignment區段中記錄其分佈方式,再透過程式計算就可以得出各作業於每天(月/週/小時…)所分派的工作時數了。

但每個人所使用的軟硬體配備不盡相同,很難確保其在浮點數的運算會完全一致。其次,也有許多第三方所開發的 MPP reader都可以來進行 MPP 檔的讀取,而各家所讀取的結果也都相同。

除了上述的原因之外,最重要的一點則是 Microsoft Project 允許使用者針對單一的任務分派,進行人工的工時調整(如圖八)。一旦進行過人工的調整後,勢必無法透過分佈方式來動態計算出每天的工時情況。


《圖八》作業分派狀況畫面


很顯然的,文檔中絕對不只記錄了分佈方式,必定還有跟工時分佈有關的紀錄。透過實際檢視xml檔也驗證了這一點(如圖九),我們發現文檔中除了紀錄分佈方式(WorkContour)外,還記錄了經過計算後的工時分佈(TimephaseData)。


《圖九》工時分佈xml內容範例


可以特別看到其Start與Finish的屬性,其區間雖然是完整的一天,但與我們一般認知的一天起訖有所不同。這部分是因為Microsoft Project可設定每天由幾點開始工作(Ex:上午8點),而這個時間點就被認定為一天的開始與結束。

實際上該天所分派到的工時,則要參考Value這項屬性,在這邊又看到了一種獨特的表示方式,以圖九的範例而言,PT8H0M0S代表的是8小時0分0秒,而PT12H0M0S則代表的是12小時0分0秒。

當工時的分配更細的時候,TimephasedData甚至會顯示到一小時或一分鐘的工時分布情形。如圖十,就顯示了在16:00~16:12 分鐘間的工時分佈,而這12分鐘內,其所安排的工時為3分鐘。


《圖十》分鐘工時分佈xml內容範例


而正如前面所述,工時的分派允許使用者從月、週一直到時、分都可以去做安排。於介面上也是輸入如: “工作月”、 “月”、 “工作日”、 “十”…等文字,但跨語系時又可能需要顯示不同的文字,如:“mon”、 “d”、 “ed”…等。所以很顯然的,“工作日”這樣的字樣並不是直接儲存於文檔中,那 Microsoft Project 又是如何處理這種狀況的呢?

如圖十一,我們可看到其儲存了一個 DurationFormat,該欄位只儲存了一個代碼,而在實際顯示時才轉換成文字顯示。這種做法目前經常被應用在各種跨語系的程式設計上,但Microsoft Project更特別的是在輸入的處理上,不論輸入英文和中文,都能進行辨識並在內部轉換為代碼。表一為所有的代碼與中英文文字的對照。


《圖十一》工期格式xml內容範例



《表一》工期格式代碼與中英文對照表


結語

筆者在 Microsoft Project 的資料解析的過程中,雖然並沒有實質學習到程式開發的技巧,但透過理解其資料結構。有助於在介接程式設計上的資料結構設計,避免了實際運作時,發現實際資料與設想不一致導致的轉檔問題。也從中學習到了部分資料該如何設計其儲存結構,才能便於讀取或擴展。