內容連載
頁數 1/2
Chapter 01
我的BILLG審查初體驗
2006年1月16日,星期五
古早時期,Excel有一個很糟糕的無名程式語言,我們稱之為「Excel巨集」。這是個功能嚴重失調的程式語言:沒有變數(數值只能放工作表儲存格裡)、沒有局部變數,也沒有副程式。簡言之,這語言幾乎完全無法維護。它倒是具備「Goto」之類的高階功能,不過,用在Goto的標記,實際上是看不到的。
這東西唯一值得稱道之處,就是跟Lotus巨集語言相比,還不錯。畢竟後者只不過是把一連串按鍵序列,用字串形式儲存到工作表儲存格裡而已。
我從1991年6月17日開始,以產品經理的身分進入微軟的Excel團隊工作。我應該要解決這個問題,而解決方法據說得牽涉到Basic程式語言。
Basic?我呸!
我花了一些時間和各個開發團隊協調。當時剛出來的Visual Basic 1.0相當的酷。此外,有個代號MacroMan的計劃正在進行中,但是方向錯誤;還有一個Silver計劃要開發物件導向Basic。Silver團隊被告知Excel要使用他們的產品。而Silver的行銷經理Bob Wyman(沒錯,就是那位BobWyman)的產品只有一個行銷對象──就是我。
MacroMan計畫正如我所說的方向錯誤,雖然費了一些工夫遊說,不過,還是停掉了這計劃。而Excel團隊也說服Basic團隊,我們真正要的是某種針對Excel的Visual Basic。而我設法讓Basic添加了四個小功能。我讓他們添加Variant(一種可以容納任何其他型別的合併資料型別),否則就必須用switch敘述,才能把工作表儲存格的內容存到變數內。我還要他們加了延後連結(late binding),也就是後來名為COM Automation的IDispatch功能。因為依照Silver的原始設計,使用者必須深入理解型別系統,但會去寫巨集程式的人根本不會想管這些東西。此外,我還加入兩個好用的小語法功能:由csh偷來的For Each以及取自Pascal的With。
然後我坐下來寫Excel Basic規格,一份長達數百頁的龐大文件。我覺得完成時應該是500頁(「瀑布開發法1」,你竊笑著說。是的,請閉嘴!)。
當時我們有一個名為「BillG審查」的會議。基本上,每個主要的重大功能都得由Bill Gates審查。有人叫我準備一份規格書,送到他的辦公室以備審查用。基本上,印一份規格書出來就要用掉一令(500張)雷射印表紙。
我趕緊把規格書印出來,再送到他的辦公室。
當天稍晚有段空檔,於是我開始思考,想想Basic的日期和時間函數是否能滿足Excel裡的所有的需求。在現代程式設計環境中,日期大多存成實數。整數部分是由過去某個指定日期(稱作起算日;epoch)起算的天數。今天(2006年6月16日)在Excel裡會存成38884,也就是把1900年1月1日當作1起算的天數。
2 譯註:傳統軟體工程把軟體開發分為很多階段,前一階段完成才進入下一階段,就是多段式的瀑布一階一階的流下來。
我開始逐一檢查Basic和Excel裡各個日期和時間函數,並加以測試,然後我注意到Visual Basic文件有個奇怪的地方:Basic的起算日是1899年12月31日,而非1900年1月1日,但是基於某種原因,今天的日期在Excel和Basic裡的值卻是相同的。咦?我想該找一個資深到能記得始末的Excel開發者。Ed Fries應該會知道答案。
「噢,」他告訴我。「檢查1900年2月28日的值。」
「59,」我說。
「現在試試3月1日。」
「61!」
「60怎麼了?」Ed問。
「1900年2月29號是閏年!可以被4整除!」
「猜得好,不過沒有獎品。」Ed說,然後讓我自己想了一會。哎呀。我再想了一下。能被100整除的不是閏年,除非同時能被400整除。所以1900年並不是閏年。
「這是Excel的蟲!」我叫道。
「呃,並不算是!」Ed說。「這是不得已的,因為我們要匯入Lotus 123的工作表。」
「所以這是Lotus 123的蟲囉?」
「是的,不過可能是故意的。Lotus必須限制在640 K內,而這並不是很大的記憶體。如果忽略1900年,只要檢查最右邊2個bit為0,就能知道某年是否閏年。這種寫法既快又容易。Lotus的傢伙可能認為,已經是過去的這兩個月有錯並不打緊;但Basic那裡的人似乎對這兩個月很在意,所以把起算日往前移一天。」
「啊啊啊!」我大叫。然後就轉去研究選項對話框裡為什麼有個叫「1904年日期系統」的選項。
第二天就是重大的BillG審查。