2015年12月17日 星期四

Live Writer終於復活了!

是這樣的,我一直用Blogger的blog,本來也都是徒手張貼blog,後來有人跟我說,Windows Live Writer(WLW)很好用,所以我就從善如流的用了,發現還不錯用,但好日子過了沒多久,前幾天,它突然無法登入Blogger了! 原因是,Google把登入機制改成 oAuth 2.0,但為何要改呢? 因為它們早就想改了(前情提要)。

而等到現在,是因為MS終於把WLW給open source了(參考)。

所以,Live Writer以後就由廣大的社群&善心人士共同維護了,名稱從此變為OLW(Open Live Writer)從11號等到17號,終於,善心人士釋出了新版的OLW(可以從這邊下載),所以現在你又可以用OLW登入並撰寫Blogger的文章了(如果先前有安裝,要記得移除)。

這一篇,就是用OLW寫的,對於廣大社群與善心人士的孜孜不倦,無以為報,謹以此文紀念。

SNAGHTMLeed85a1

2015年11月22日 星期日

誰管你準備好了沒?

image

我是沒甚麼看影劇節目的人,但今天在網上看到一篇文章,描述今年角逐金馬獎的宋芸樺,被主辦單位臨時邀請代替Hebe演唱<小幸運>,只猶豫了兩天,就決定上陣。上網看了一下影片,發現唱的還真不錯,但重點是,一位演員有這個勇氣和實力,很讓人敬佩。

或許,她平時就有練習,甚至,其實她打算同時朝歌手發展,但在這一個關鍵場合的良好呈現,肯定為自己未來的路擴展了更多的機會。

讓我不免回憶起,過去在擔任各種角色時,自己真的碰到很多需要硬著頭皮上的場合,大多時候表現得還可以,當然也有因為硬著頭皮上結果不是很理想的時候。但,我幾乎沒有放棄過任何一次關鍵場合上場的機會。在當開發人員的時候,常被抓去兼任PM、在當講師的時候,常常被找去做顧問服務、許多次臨時被找去代課…回想過去,其實很多工作,都是在沒有預先通知的狀況下被臨時賦予的。

這時,就是考驗平時的準備與臨場功力的時候了,在一個有充分時間準備的場合展現,多半看不出你的實力,但臨時上場的考驗,往往立刻淬鍊出你的真實程度。

過去,在職場上,很多技術人員常常跟我說,想要往顧問或是PM的角色發展,但苦無機會,其實我覺得,機會,多半都是被我們自己放棄掉的。

下一次,碰到關鍵時刻,被臨時叫上台簡報、被突然間賦予自己不擅長的任務、被緊急抓去救火,千萬別因為自己不擅長或是膽怯而說NO了。用力把握每一次展現自己的時刻,把這個場合當作一個機會,日後更多的機會自然就會主動找上你,不論在你準備好還是沒準備好的時候。

至於『準備』,就看你平時是怎麼過每一天的了。我常說:『你的時間在哪裡,你的成就就在哪裡。』

ref: http://www.setn.com/News.aspx?NewsID=107676
ref: https://www.facebook.com/sungyuhua/photos/a.441771815951334.1073741828.440923442702838/787757738019405/?type=3&theater

宋芸樺現場演唱(從1:45開始):

平時的準備就很重要:

2015年11月21日 星期六

VSTS的新功能 - 數位儀表板

2015/11月底,微軟在Connect();大會,正式公布了大幅度改版的線上TFS,也就是變了新名字的VSTS(Visual Studio Team Services,從前叫VSO)。

VSTS可視為線上版的TFS,讓開發人員可以對軟體的生命週期做非常良好的管理,是一套ALM軟體服務。翻成白話一點,就是軟體專案的統籌管理軟體。

更新後的VSTS,除了原本的版控、自動化建置、測試,以及工作項目管理之外,加上了眾人期待已久的數位儀表板功能:SNAGHTML1ab0eee5

這個討喜的功能,讓團隊以及PM/PO可以一目了然的看到整個專案的整體狀況,當然,這個儀表板是可以客製化的,有各式各樣的組件,可供專案管理人員選擇應用,您也可以為專案建立多組儀表板,分門別類的以視覺化方式來呈現所有資訊。

我們接著就來看,如何客製化這個數位儀表板。
(等等,你竟然還沒申請免費的VSTS專案管理服務? 請參考這裡。)

如果你有管理員權限,現在,進入VSTS專案之後,你會看到overview頁面上,右下角有一個『+』符號:
image
按下上圖右下角的按鈕,會出現一堆的Widget供你選擇,你可以隨意用滑鼠選擇一個或多個,佈置在預設的數位儀表板上:
image

類似像上圖這樣,可以點選幾個widget(被點選的會打勾),按下新增(add)之後,即可加入:SNAGHTML1ab0eee5

這很簡單,但重點是,這些圖表有何用途? 如果熟悉TFS/VSTS使用或和我們一樣採用Scrum開發框架的朋友們,應該很熟悉了,你可以在畫面上看到底下這些:

這些都是從library直接抓取出來的Widget,當然,你也可自行建立不同的查詢(Query),以呈現想要的結果。

例如,我們可以在work底下的Queries中,建立一個Query:

我們查詢專案中所有的Backlogs,儲存完成後,移入Shared Queries:

接著,建立一個新的Chart:
有各種圖表可以選擇,我們選擇Pie圖,並設定Group by “state” 欄位:

我們設計好圖表之後,可以透過圖表右上角的選單,把圖表釘選到數位儀表板上:

我們看看:

成功的在數位儀表板上,把Backlogs的狀態顯示出來囉。如此一來,一目了然的呈現出整個專案的狀況,老闆、客戶和PM還能說專案不夠透明嗎?

不僅如此,還有個好玩的功能,Query Tile讓你可以針對某一個數字設定紅綠燈警示看板,你可以點選Query Tile的選單:

接著,在出現的設定畫面上,你可以針對Query出的數字,設定紅燈或綠燈的條件:

完成之後,你會發現儀表板上的動態磚,底色依據我們設定的條件呈現出來:

很好玩吧,專案管理,再也不是死板無效的甘特圖和Excel傳來傳去才能溝通狀況,一個數位儀表板,把一切變的視覺化,而視覺化,是有效管理的重要關鍵,還沒有申請VSTS? 沒有用TFS或VSTS管理專案? 現在還來得及。

如何申請,請看這裡

如果需要更多VSTS(VSO)的使用方式說明,可以參考這裡

2015年10月13日 星期二

程式開發是一種難以管理的創意工作?

5396691102_dd3d157676_b

從工業革命開始,工作被分成了幾種類型,為了量化生產,以供給滿足客戶大量的需求,所以生產實體產品這樣的工作,被拿到生產線上進行最佳化,目標是在最短的時間,最低的資源投入與成本耗費之下,做出一樣品質的產品。

從這個概念開始,很多管理技巧衍生出來,例如我們熟悉的SOP,我們過去常用的甘特圖,計算績效的KPI…凡此種種,都是從這種基礎概念產生的理論。

但,有一種類型的工作很難被SOP規範、很難用KPI管理、也幾乎無法被甘特圖預測,那就是創意工作,諸如,藝術品、歌曲、文章…的生產。而我得說,程式設計,其實也是其中之一,但往往被忽略的很徹底。

為何這類的創意工作不能被傳統管理工具有效管理,本質原因很簡單,因為能透過標準作業程序管理的生產行為,大多是追求著產出"完全一樣"的"實體成果",小到一顆螺絲釘,大到一台BMW汽車、在生產規劃的那一刻,其目標就是希望生產出一模一樣的東西,沒有人希望這類產品的產線在生產的時候,出來的每一個成品都有自己獨一無二的特色,如果是,哪怕只是多了一兩克重量,都會讓人難以接受。

但創意工作不是,沒有一首曲子100%完全一樣,如果有,就變成了抄襲,藝術品、創意工作所產出的成果,之所以有其價值,就是在那95%類似的元素之外,那5%的一點差異。

藝術品和創意工作,容或製作生產的流程相同、投入的資源類似,但一旦落入模仿或臨摹,其價值就一落千丈,和這市場上其他的商品不同,其差異就在於對價值的認定。

很不幸的是,電腦軟體也是如此。天下沒有兩套完全一樣的軟體,因為不需要,如果完全一樣,你copy一分就可以了。電腦"可程式化"的目的就在於面對變化,面對差異,然而麻煩的地方就在那5%的差異。這5%的差異,讓程式設計從工業工作變成了創意工作,而”人”在其中就變成了一個很大的變數。(如果完全一樣,就不會有問題,也不需要額外寫程式,就是因為不完全一樣,才需要再次撰寫程式碼)

過去20年,軟體工業一直企圖把程式設計(軟體開發)變成一個標準化的動作,我們夢想著用OOP,就可以讓一切變的組件化、好讓程式的組成變得容易。我們從工業管理生產線上學來SOP、KPI、Gantt Chart,想要用一樣的方式管理程式設計師的產出,用同樣的方式提高產量,但努力了20年,卻發現離理想越來越遠(早期軟體生命周期很長,半年才一個release,那時好像還可以應付,時至今日,過去的waterfall早已經被證明了,面對這個時代的需求完全力有未逮)。

我們從產線效法了看板方法,有效的管理工作,確保產出,但還是不能忘記,軟體開發最核心的部分其實是創意,我們確實可以依照SOP、利用各種技巧管理工作分配,但別忘了最源頭的需求,才是讓一切不同的主要因素。產線上的需求是固定的,那怕是最小量的客製化接單生產,需求在生產期間都是不變的,但軟體不是。

在這個時代,現實就是需求時刻改變,即便我們能夠在一個週期(迭代)之中固定需求,但面對真正天翻地覆的變更時,本質上我們依舊可能得拋棄某一個迭代的產出,面對變化作出反饋。

這世界上沒有一套軟體是完全一樣的,即便功能相同,但背後的目的也可能天差地遠,然而真正的災難是,企業企圖僅僅使用設計用來提高產能、確保一致性產出的管理概念,來管理一個目標是產出具有唯一性、期待不同結果、具有創意性質的軟體開發流程。
(閒話幾句,我看過無數的程式碼,method以外光鮮亮麗,往下細看method以內慘不忍睹,即便都通過unit test,即便程式運作都正確,但同樣結果的程式碼,還是有品質高低不同的差異,這些,與實體商品的生產流程根本完全不同。軟體產品絕對不能視為實體產品,他本質就是虛擬的,和一首歌、一幅畫一樣,做完,絕對不100%等於做好,做好,也不見得是完成…)

縱然,軟體開發的圭臬從早期的OOP,一路演進到現在的CI, CD, DevOps,我們依舊企圖自動化生產流程,依舊期待可以透過組合的方式產生我們要的軟件,而專案經理們採用的這些管理技巧(SOP、甘特圖、KPI),在其餘各個領域也都被驗證過且有效的被推行,但為何唯獨軟體開發領域不行? 為何唯獨軟體開發工作,在實施了這些管理工具之後,專案經理依舊必須和bug搏鬥? 依舊無法提升品質? 依舊需要面對客戶抱怨,依舊躲不開永無止盡的專案延期,依舊…依舊無法管理好每一個變更? 真的是因為PM的管理知識不足,管理工具沒用到位? 還是根本是管理方法出了問題?

相信我,每一個軟體產品都是唯一的,同樣,每一位程式設計師也是,你可以"管理"一群員工,但你只能"領導"一個團隊,傳統的管理工具僅僅可以讓你確保最低品質的產出(但如果你要的本來就是最低品質的產出,那我也無話可說),但唯有真實面對軟體開發工作與其他生產工作不同的創意特性,才能夠創造出具有價值的軟體,也才能真正發揮團隊的創意與生產力。

軟體專案管理並非真是一個難以管理的生產過程,但是用錯了方法,往往會變成一場災難。

後記:
很多專案經理和業務人員,並非軟體開發背景出身,但在軟體公司或專案工作中卻掌握了管理大權,很遺憾的,即便開發人員依稀覺得當前的管理方法有些問題,卻說不太出來(或是不想說?),導致管理人員和專案團隊中一直存在著一種很難言喻的隔閡。

另一種衍生出的問題則是,在這種環境之下,開發人員久而久之,感嘆於市場狀況(或工作環境)無法改變,時不我予之下,乾脆領錢閉嘴少做錯事,慢慢消耗著僅存的開發熱情度日,不管是哪一種狀況,都很令人遺憾。

在你的團隊中,找出一個合理且有效的管理方式,讓軟體專案變成一種樂趣,讓團隊真的幫上客戶(或End-user)不論是團隊成員或PM,在日常工作中都會更有成就感,也會更熱愛你的工作。

2015年9月18日 星期五

[研討會] TechDays 2015 – Office Add-Ins

image
第三天的Office Add-Ins介紹也順利的完成囉,我後續會把影片、投影片和相關的範例逐步整理到blog上,謝謝當天留到最後的學員們,以及每一位參與學員的支持。
先前已經有整理好的幾篇blog,連結如下:
http://studyhost.blogspot.tw/search/label/Office%20Add-Ins
可提供各位先參考。

updated: 投影片位於 這裡 ,現場影片位於 這裡

2015年9月16日 星期三

[研討會] TechDays 2015

image
很高興今天在會場有機會看到許多老朋友,並且和大家分享了我們在CI/CD以及Scrum上的一些心得,場次[實現 End to End 的雲端敏捷開發流程]的投影片可由底下連結下載
希望對大家有幫助。

20150930:
[TechDays現場錄影] 今年,現場video好快就上架了,沒有來現場的朋友們,也可以聽一下我們在CI/CD這個主題上的分享囉,聽的時候千萬別怪我囉嗦,前面講了一堆有的沒的,如果你長期關注我們的FB/blog,相信你可以理解為何我們會有感而發…不論如何,謝謝大家的包容與支持。有一點小遺憾,現場的錄音把講員的聲音錄的很清楚,但卻錄不到現場學員的笑聲,現場其實充滿了歡笑和樂趣,而會後和學員們的討論,也讓我自己收穫很多,下次來現場吧,希望有機會碰到大家。
https://channel9.msdn.com/events/TechDays/TechDays-Taiwan-2015/DEV302

2015年8月29日 星期六

什麼是專業?

29-122628-64fa9554-5fa8-42b8-ac5f-ec76b211199e

前幾天,看了一篇文章,看完之後我立即在FB上分享,原因不僅僅是因為文章中描述的雖然以設計界為主體,但根本120%符合台灣軟體專案外包的現況。我本來想節錄其中讓我很感慨的幾句話,但我回頭再看一次文章,發現我不用節錄什麼,我推薦讀者整篇重頭到尾讀一遍就對了。

接著,我想說說我的感受。

最近十年,我剛好身兼文中所說的幾種工作,資訊軟體開發的教育訓練、雜誌專欄文章撰寫、書籍出版、同時也在業界接案、甚至擔任顧問,台灣軟體專案發包的低價、浮濫…等問題,跟文中說的完全一樣,我們非常明白這件事情。(因此看完之後,我沉思良久)

但如果說,我們在接案時跟其他人一樣,必須被迫用較低的價格來接案,這只說明了一件事情,就是『客戶覺得我們不夠專業』,我們不夠優秀到讓客戶願意用比別人更高的價格,來聘請我們為他服務。簡單的說,就是如此而已。

你說市場行情,沒錯,市場行情是一回事,但對於追求專業的我們來說,我們總是期許(要求)自己所做的每一項工作,都有著比他人高的品質和效率,這意味著,我們期許自己比其他同業要來的專業,果真如此,那在價格上應該要比一般"行情"要來的高一些才對。

如果客戶不願意用比市場行情高的價格,來聘請我們,那顯然該檢討的不是客戶,而是我們自己。我們是否曾在客戶面前彰顯了自己的能力? 我們是否讓客戶感受到十足的值得信任? 客戶和我們溝通的過程中,是否就能夠體會到所謂的專業? 是否與我們對談本身,對客戶來說就已經是一種收穫?

如果不是,那表示我們還必須努力。

當然,容或有一些客戶對專業沒興趣,只希望用最低的價格拿到堪用的成品,但這本來也就不是我們想要爭取的對象。

最近十年,軟體或網站開發比起過去容易非常多,隨便一個學生或是上過職訓的SOHO,都能夠拿起開發工具寫code(沒什麼好怨的,我們自己都帶過這樣的教育訓練課程,也都在台上跟學員說,你看,你看,就這樣,很簡單吧…)。

但,如果只是把程式碼寫出來,讓網站可以動,那顯然無法彰顯你的專業。

在這個業界待了五年、十年、甚至二十年,和剛畢業的學生有何差別? 當破壞行情的份子在業界用極低的價格承接專案的同時,我們能否清楚地跟客戶說明,為何我們值得比較高的報價? 軟體開發或網站設計為何不僅僅只是寫代碼? 一個優秀的系統還包含了哪些要素? (穩定性? 延展性? 安全性?) 好的專案管理該如何凸顯透明度? 為何我們可以每兩周給客戶一個Demo? 為何我們歡迎且能夠掌握需求變更? 我們如何控管 bug的生命週期,好讓軟體產品達到最好的品質管理? …

凡此種種,都不是剛從職訓單位結訓兩三年內可以掌握可以做到的,把程式寫出來是一回事,做出對客戶有用的網站或軟體,是另一回事。更不用說後續的維護、更新、以及改版或技術升級了。

專業,不一定是用最新的技術,也並非是把天花亂墜的術語天天掛在嘴邊…專業是與客戶合作,為客戶找到最適合的實施方式,讓客戶喜歡我們為他所做出的產品,更覺得與我們合作的過程不僅能夠學習,且充滿樂趣。

後記:
這篇文章寫的是軟體公司,但想想,技術人員的職場不也是如此? 什麼是專業? (絕對不只是天天學最新的技術而已,這剛畢業的年輕人也可以…) 和老闆之間的關係如何處理? 總是會碰到只出得起香蕉的老闆,而你又該如何回應? 在老闆與同事面前如何凸顯你的專業? 這也是技術人員該深思的問題。

2015年8月12日 星期三

讓團隊溝通? 比你想像的容易…

前一陣子到某家公司進行教育訓練,談的是專案管理與ALM。席間有位學員問到:『Scrum鼓勵溝通,但要怎樣才能夠讓成員凝聚出團隊氣氛,讓大家真的進行溝通呢?』

我很能理解這個問題,因為卓越的工程師普遍喜歡自己一個人埋頭寫code,對解決技術問題都有自己的一套想法,但要習慣性地跟其他人一起合作,有時似乎還挺困難。這位提問者是公司的主管,他嘗試過讓這些團隊成員到外面上溝通的課程、訓練團隊成員溝通的技巧,甚至把溝通這件事情當作績效指標,結果…不出你的預料,完全沒效。團隊成員好像更不喜歡講話了。

回答這個學員的問題前,我先跟這位學員說了一個我最近在一本書上(關鍵18分鐘)看到的一段故事。

書籍的作者有次造訪一座部落平原,搭乘著老舊的火車,乘車過程中,他看到有一頭雄偉的獅子 · 蹲伏在山丘頂的岩石上,看得清楚極了。
作者問列車上的管理員:『這麼巧,竟然能夠遇到獅子出來 · 這樣算是相當幸運的吧?』
『那頭獅子一向都在那裡,牠總是坐在岩石上。』對方這麼回答。
『真的? 你們用什麼辦法 · 讓牠一直待在那裡???』作者問。
管理員笑而不答。

學員們疑惑的同時,我接著說了書上的另一個故事:
『曾經有一位主管向HR顧問抱怨他們公司的接待人員不夠熱情,看到有人走進服務櫃台卻沒有表現出友善的態度。顧問實際上瞭解了狀況之後,發現根本不需要讓接待人員接受任何額外的教育訓練,也不需要複雜的績效制度,只需要把接待檯前面像是郵局櫃台一樣的那個售票窗口的玻璃移除,同時降低櫃檯的高度,服務人員的態度立即有了明顯的改善。』

真的有用? 是的,因為人們非常容易受到環境的引導和暗示。

接著,我把我們某個專案團隊的照片開給他看,並且問:有沒有發現,和一般的辦公室比起來,位子和位子之間少了什麼?SNAGHTML9cb5a72

沒錯,少了隔板。

如果你一邊鼓勵團隊溝通,一邊卻讓每一個團隊成員都坐在像是城堡一樣高度的Office Partition座位中,那溝通是不容易發生的。反之,把隔板拿掉,讓team member面對面,眼神可以隨時看到對方,如此一來,團隊成員之間的交流會自然而然的形成,不需要額外的教育訓練與獎勵制度,不需要導入績效管理。事實上,最有效的方式,就只是一個環境的改變而已。

同樣的,在實施敏捷開發的許許多多做法當中,最不需要的就是導入KPI之類的績效制度或SOP,而是透過環境來引導團隊成員,往你所需要的方向前進。

帶領人,和管理事情,是不一樣的。事情能夠管理(Manage),但人只能領導(Lead)。把人當作工具一樣管理,是工業革命時期的管理模式,不是一個適合現今這樣需要創意的腦力密集產業的有效作法。

至於那頭獅子,原因很簡單,因為那個岩石是控溫的,天氣冷的時候,園方就讓岩石溫暖一點,大熱天時,就讓岩石冰涼一點,獅子,自然就待在岩石上了…

2015年8月3日 星期一

[開發Office Add-Ins]常用API - getSelectedDataAsync(6)

談完setSelectedDataAsync之後,我們來看看getSelectedDataAsync這個API,有填入當然就有取得,getSelectedDataAsync的功能非常簡單,就是取得用戶選取範圍的資料,我們看底下的程式碼:

function getTextData() {
    //調用API填入文字
    Office.context.document.getSelectedDataAsync(Office.CoercionType.Text,
    //call back
    function (asyncResult) {
        var error = asyncResult.error;
        //如果失敗
        if (asyncResult.status == "failed") {
            //顯示失敗訊息
            app.showNotification(error.name + ": " + error.message);
        }
        else {
            //顯示成功訊息
            app.showNotification('成功取得:' + asyncResult.value);
        }
    });
}

執行的結果如下:

image

你會發現,我們透過程式碼中的『asyncResult.value』取得選取區域的文字,由於我們傳入的取回type是Office.CoercionType.Text,因此取得的結果也以純文字方式呈現。

讀者可以試試看,如果把Office.CoercionType.Text改為Office.CoercionType.Html,你回發現傳回的asyncResult.value就變成HTML格式的內容了。

如果是Excel的內容呢?

我們看底下這段程式碼:

function getTableData() {
    //調用API填入文字
    Office.context.document.getSelectedDataAsync(Office.CoercionType.Matrix,
    //call back
    function (asyncResult) {
        var error = asyncResult.error;
        //如果失敗
        if (asyncResult.status == "failed") {
            //顯示失敗訊息
            app.showNotification(error.name + ": " + error.message);
        }
        else {
            //顯示成功訊息
            app.showNotification('成功取得:' + asyncResult.value[1][2]);
        }
    });
}

由於我們傳入參數『Office.CoercionType.Matrix』以Matrix格式取得選取區域的資訊,因此,當執行上面這段程式時,結果如下:

image

當選取區域是上圖畫面中的A1-C3,則抓取到的Matrix[1][2],其內容就是『3』(矩陣起始編號為0)。

透過簡單的API,我們不僅可以寫入,也可以讀取Office文件中的資料了。

2015年8月1日 星期六

[開發Office Add-Ins]常用API - setSelectedDataAsync(5)

先前我們談到,我們在開發Office Add-Ins(特別是Task Pane與Content Add-in)時,大部分的API都從『Office.context.document…』而來,而這個從Office開頭的API,來源就是我們在html頁面上所引入的Office.js,請注意,Office.js並非一個檔案,而是一整組 office.js ,這是一大組 javaScript files的集合,如果你透過Visual Studio開發的話,可以看到專案目錄下有許多檔案:
其中的細節我們後面有機會再討論,先來看看我們常用的兩個API。getSelectedDataAsync與setSelectedDataAsync這兩個方法。
設定(填入)選取區域
我們先看setSelectedDataAsync這個方法的定義:
範例:
Office.context.document.setSelectedDataAsync(data [, options], callback);
其中data參數的可用內容如下:
參數
內容
備註
data string (Office.CoercionType.Text) Excel、 Excel Online、 PowerPoint、 PowerPoint Online、 Word,以及只Word Online
  array的陣列 (Office.CoercionType.Matrix) Excel、 Word,以及只Word Online
  TableData (Office.CoercionType.Table) Access、 Excel、 Word、 僅限Word Online
  html Word,並只Word Online
  Office Open XML 僅限Word
基本上setSelectedDataAsync的功能就是將特定的文字或物件,填入當前用戶在文件當中的選取區域。 例如,底下這段很簡單的程式碼,可將特定文字填入文件當中: // 從目前文件選取範圍讀取資料,並且顯示通知
function FillText() {
    //調用API填入文字
    Office.context.document.setSelectedDataAsync("測試填入文字",
    //call back
    function (asyncResult) {
        var error = asyncResult.error;
        //如果失敗
        if (asyncResult.status == "failed") {
            //顯示失敗訊息
            app.showNotification(error.name + ": " + error.message);
        }
        else {
            //顯示成功訊息
            app.showNotification('成功!');
        }
    });
}
按下Button之後,執行結果如下: SNAGHTML10a16bd7 當然,可以填入的不僅僅是文字而已,試試看底下這段程式碼: function FillTable() {
    //調用API填入文字
    Office.context.document.setSelectedDataAsync([['張三', '李四', '王五'], ['A', 'B', 'C'], ['123', '456', '789']],
    //call back
    function (asyncResult) {
        var error = asyncResult.error;
        //如果失敗
        if (asyncResult.status == "failed") {
            //顯示失敗訊息
            app.showNotification(error.name + ": " + error.message);
        }
        else {
            //顯示成功訊息
            app.showNotification('成功!');
        }
    });
}
執行的結果如下: SNAGHTML10a139da 你會發現,setSelectedDataAsync除可以填入文字之外,如果你填入陣列類型的資料,在Word當中則會變成表格,在Excel當中自然就是直接變成儲存格內容了: image
非常簡單的API,是吧? 我們後面再來看我們用過多次的getSelectedDataAsync。










[開發Office Add-Ins] Task Pane Add-Ins專案內容(4)

不管你是透過NAPA 或是Visual Studio來開發Office Add-Ins,建構出的Task Pane Add-Ins專案,在App Body的部分,結構都是底下這樣:

clip_image002

我們前面曾經提過,進入點Home.html是從manifest檔案那邊設定的,你當然可以改變這個設定。

整個App都是透過HTML與JavaScript撰寫,我們先來看Home.html部分。

Home.html

我們開啟Home.html,你會發現頁面結構如下:

clip_image004

你會發現主畫面<Body>標記裡面被兩個<div>區分,分別是content-header,以及content-main。(上圖)

content-header的部分是標題,呈現出來向是底下的『歡迎』部分:

clip_image006

而content-main則是上圖除了藍色的歡迎區塊以外的其他內容。一般來說我們把App主程式放在content-main當中。

前面說過,這個Home.html是app的進入點,是在Manifest當中設置的,當然,你也可以在專案中新增一個或多個HTML Page,我會建議你直接在Visual Studio當中複製Home.html即可:

clip_image008當然,複製完後你要修改一下檔名(例如Page2.html)。接著,我們來修改一下Home.html的內容:

clip_image010

我們加上了一行程式碼:

<button onclick="javascript: location.href = 'Page2.html';">跳到Page2</button>

你會發現,主頁面上多了一個Button,並且,點選之後會跳到另一個Page2.html:

clip_image002[6]

這沒什麼,就是網頁的基本行為,對於常寫JavaScript的開發人員來,就是家常便飯一般。

不過,從這邊你就看的出來,我們的Task Pane Add-Ins,基本上就是一個Html page,而上面可以運行JavaScript,必要時我們可以撰寫多個html,透過JavaScript在多個頁面中切換。

Home.js

緊接著,我們來看看Home.js這個檔案,從Home.html的頁面上我們發現,這是該Page所引入的唯一一個直屬javascript file(另外兩個是office.js與App.js)。

該檔案內容如下:

clip_image004[7]

沒了,就這樣,簡單到不行。

其中第一個部分,是在Document Ready時,做一個hook按鈕『get-data-from-selection』的Click事件的動作:

當按鈕『get-data-from-selection』被按下,則getDataFromSelection會被觸發。

而getDataFromSelection的內容是:

留意getSelectedDataAsync這個Method,它是由Office.context.document.而來的,依照慣例,微軟掛上『Async』字尾的Method,都是非同步的API,因此一定會有一個call back函式,上面例子中,就是後面的這一段function:

function (result) {
    if (result.status === Office.AsyncResultStatus.Succeeded) {
        app.showNotification('選取的文字為:', '"' + result.value + '"');
    } else {
        app.showNotification('錯誤:', result.error.message);
    }
}

getSelectedDataAsync這個Method,是取得當前文件上的被選取區段,取得之後,就調用上面這個function,將取得的物件以result這個名稱傳入,傳入後,可由result.status判斷剛才的動作是否成功,如果成功,則把取得的用戶選取區域的內容(result.value)顯示出來:

app.showNotification('選取的文字為:', '"' + result.value + '"')

程式碼就這樣而已,很單純。

上面的『app.showNotification』,是在add-in的下方呈現出一個訊息顯示區塊,有這區塊可用,是app.js的功勞:

clip_image002[8]

1-1-1 App.js

如果我們開啟App.js,不難發現其中的內容,就是幫我們建構一塊訊息顯示區域,並提供API讓我們可以藉以調用,顯示出訊息:

clip_image004[9]

上面這一段code中的app.initialize,則是在home.js當中被叫用的:

clip_image006[6]

到這邊為止,您應該已經很瞭解整個Task Pane Add-Ins的架構了,後面,我們要來看幾個常見的API。

2015年7月29日 星期三

[開發Office Add-Ins] 關於Office Add-Ins的類型與架構(3)

要討論Office Add-Ins的架構之前,我們得先知道它目前有哪些類型,如不論你用NAPA或是VS,都可以透過開發工具建立底下三種Office Add-Ins其中之一,分別是:

1. Task Pane Apps
2. Content Apps
3. Mail Apps

分別說明如後。

Task Pane Apps

這種類型的App可在Word, Excel, Porint, Project…等環境中使用,可以說是最廣泛的應用程式類型,主要UI出現在畫面的右方,我們剛才開發的第一個App就是屬於這種類型:

clip_image002[8]

Task Pane Add-Ins可以跟Office文件互動,讀取、填入文件當中的文字或表格,也可以更進一步的抓取文件當中用戶選取的區域,甚至進行該區域的綁定,一但選取區域有所變動時,我們的App可以得知該事件,並透過JavaScript配合Restful API進行進一步的一些後續動作。

Content App

Content App最大的差異,是UI主體是崁入在Office文件當中的:

clip_image004

當然,Content App也是透過JavaScript撰寫,由於這類型的App主要是崁入在Office文件當中,因此最常用的功能與形式,是擴充Office文件原本無法實現的功能。(利如上圖中的地圖,是依照Excel中的數字即時繪製出來的)

Content App跟Task Pane App一樣,可以讀寫Office文件中的內容,我們可以透過Content App,將這些資訊當作參數,調用Content App中的Restful API,計算出我們要的結果,並呈現在Office文件中。(另一個典型的例子,就是股市或匯率即時查詢)

Mail App

第三種是Mail App,是配合Outlook的Add-Ins,這種類型的App和前兩種截然不同,它不只有一個主UI,而是兩個,分別叫做Compose Form和Read Form。

底下是Read Form的介面:

clip_image006

顧名思義,Compose Form是出現在用戶撰寫Email和Appointment的時候使用,而Read Form則是在用戶讀取Email和Appointment的時候使用。

沒錯,Mail App不僅可以與email配合,也可以與Appointment配合,這讓Mail App變得相對複雜,它有兩種使用情境(Email和Appointment),分別又有兩種操作介面(Compose Form與Read Form)。

它可以做什麼功能? 配合email,它可以讀取或寫入郵件的主旨、收件人、副本收件人,它可以讀寫郵件內文,可以設定約會的地點。

我甚至拿這個技術來做了一個請假簽核系統,讓用戶可以開啟email填寫幾個欄位就自動產生請假單,讓收到價單的主管不用點開email,就,就可以直接簽核。

總括一句,Mail App應用層面非常廣大。

在瞭解了Office Add-Ins的類型之後,我們接著來看架構。

Office Add-Ins架構

我們先來看Office Add-Ins的專案架構,Office Add-Ins就專案架構來說,可以分成兩大塊,一個是manifest file,另一個是WebPages:

clip_image002

App manifest用來描述App本身的資訊,例如版號、支援的Office Application類型(Word, Excel…還是都支援?),需要跟用戶索取的權限,開發廠商名稱…等,如果透過Visual Studio,可以在底下畫面中查看與設定:

image003

本質上它是一個.xml格式的檔案,當然Visual Studio幫我們設計了一個編輯介面(上圖)。這個檔案也是您將此App上架到Office Store的時候,需要上傳給Microsoft檢查的檔案。

除了這個檔案之外,另一個部分是WebPages,WebPages基本上就是一堆網頁,前面我們用NAPA時候提到過的Home.html,就是其中之一,本質上,這是一個ASP.NET網站。所以你會看到,不管透過NAPA或是Visual Studio,Office Add-Ins專案建立起來,其結構就是底下這樣的兩個Visual Studio Projects:

clip_image006

上圖下半部的第二個Project,就是WebPages,因此,對照下圖,你可以可以更清楚Office Add-Ins專案的架構:

clip_image008

一個manifest.xml檔案,用來描述App,而另一個WebPages,則是整個App的主體。

Project專案結構

在瞭解了專案的架構之後,我們更靠近一點,來看看專案的結構,主要是WebPages這部分。

你不難發現,所謂的WebPages,基本上就是一個ASP.NET Web專案,但沒有WebForm或MVC的架構,基本上只是一堆html和javaScript而已。但不要忘了,它終究是一個ASP.NET專案,因此這個專案運行時,還是運行在一個IIS服務器上,並且也有web.config,正因為如此,你甚至可以在專案裡加上加上WebAPI或Controllers。

Office Add-Ins的特色(與功能)之一,就是可以透過Restful API抓取外部的資料,並且與Office文件互動,底下是一個典型的例子:

clip_image010

你會看到我們撰寫的Office App抓取到文件中的地址,並且判斷出郵遞區號,在Word裡面當然是沒有郵遞區號資料的,因此我們的App透過呼叫遠端的WebAPI,來取得該地址所對應的可能郵遞區號。

這就是一個典型的例子,在App當中,我們不僅僅具有HTML以及可以與Office Application互動的JavaScript,我們可以撰寫WebAPI,讓JavaScript來呼叫,進而達成我們需要的效果。

而這部分,當然就是撰寫在先前提到的第二個(ASP.NET)專案當中的。

clip_image011

所以簡單的說,第一個專案是manifest file,用來描述、指向app body,第二個專案是ASP.NET也就是app的body了。在這個專案當中,我們可以撰寫前端JavaScript指令碼和HTML,也可以撰寫供前端呼叫的WebAPI(當然你也可以用非.net技術來開發,諸如PHP, JSP…etc)

好,在說明了Office Add-Ins的專案架構之後,我們後面要接著看專案的內容了。

[開發Office Add-Ins] 回頭談談Office這玩意兒 (2)

前一篇我們介紹了如何在幾分鐘內建立一個Office Add-Ins,這一篇,我們回過頭來談一談,為何有Office Add-Ins這玩意兒。

首先,在我成長(也是台灣經濟快速成長)的那個年代,我幾乎可以武斷地說,所有使用個人電腦的用戶,都曾經用過Microsoft Office,甚至有許多使用者,打開電腦的目的,根本就只是使用Office軟體。當然,自從網際網路開始盛行之後,這一切變得有些不同。

微軟在很早以前,就曾經把Office定位成一個平台,而非只是一套軟體。平台,與軟體有何不同? 軟體有著特定的功能,為使用者完成特定的工作;但『平台』,則是一個基礎,一個舞台,讓用戶(或開發人員)可以基於這個平台,持續在上面擴展與發揮。微軟這個Idea,可以說成功,也可以說不成功。其中的細節我們先不談,但不論如何,Microsoft Office持續稱霸著企業應用多年,一直到今天。

然而,挑戰一直都在,曾幾何時,大家打開平板和手機的頻率,開始逐漸超過PC,才沒多久的時間,平板上的應用App,已經不僅僅是超過,而是讓PC上的軟體感到強烈的威脅。

一家企業,要能夠成功不容易,要能夠持續成功,更可以說是難上加難,難的部份不僅僅只是持續創新、不單單只靠執行和效率,更多時候,是必須忘記背後,自己把過去的成功親手掐死,然後你才能夠面對一個新的世代,走向一個嶄新的未來。

微軟,就常幹這種事情。

薩提亞·納德拉(SatyaNadella),在2014年2月就任微軟CEO時,說道:『我們這個行業不尊重傳統,只尊重創新』。

不要覺得訝異,持續成功了三十多年的微軟,不只一次打掉重練,讓自己(的產品)破碎,然後重新開始。網際網路大勢所趨時如是、Java改變開發人員時如是,而今面對行動裝置大軍挑戰的現在,也是。

首先,微軟面對Google一系列線上Office(可以在瀏覽器中執行的類Word, Excel軟體)的挑戰,開始也跟著推出可以在瀏覽器裡面執行的Word, Excel, PowerPoint,當然,用戶可以在瀏覽器裡面編輯,並且直接把檔案儲存到Onedrive雲端空間。不僅如此,也跟用戶端的Office軟體充分整合,檔案可以下載編輯,甚至從用戶端桌面版本的Office軟體中直接編輯雲端的檔案。

接著,因應SaaS(軟體暨服務)的雲端應用程式概念,微軟推出了Office 365,這是一個整合的方案,讓訂購的用戶,可以以租用的方式,使用Office,每個月最多只要幾百元,你可以有近乎無限的Onedrive空間,可以使用整套線上Office(諸如Word Online, Excel Online),然後,你也同時具備了用戶端桌面版本Office的使用授權,只消用同樣的Office 365帳號登入,你就可以執行網路上免費下載的整套Office軟體。

不僅僅如此,Office 365還包含了雲端版本的Exchange Service、SharePoint Service,讓O365的用戶可以不需要自行搭建伺服器,即可享有整套SharePoint與Exchange的功能。全部都包含在每個月幾百元的費用當中,這,也未免太豐富了吧?

還沒完,隨著行動裝置的盛行,微軟知道iOS(iPad, iPhone)以及android的用戶非常多,短時間內Windows平板與手機不太可能超越,因此,行動裝置的市場不可忽視,在這個前提之下,微軟面對現實,做出令對手難以忽視的出擊。

微軟直接把行動裝置版本的Office軟體免費提供給iPad, iPhone, 以及Android用戶,從2015年開始,各種平台上的使用者,都可以下載Office來使用,而針對具有O365帳號的用戶,更是全功能免費開放。

甚至,Office開始有了自己的市集,稱為Office Store,開發人員可已將自己撰寫的App,發佈到市集上,讓各種平台上的Office的用戶購買使用,以便擴充Office本身沒有的功能。(例如筆者就撰寫了一個台灣郵遞區號查詢的App,讓Word, Excel的用戶,可以直接在編寫文件時,查詢或檢核郵遞區號。)

至此,Office再也不單單只是一套辦公室當中廣泛使用的軟體,且變成了一套跨平台、有全球數十億用戶的生態系統與平台。整套Office不僅可以在PC、MAC上使用,也可以在Web(Online)、iOS、Android、Windows Device上使用。

開發人員、MIS或IT人員,可以透過JavaScript程式碼的開發,輕易地擴充Office的功能。

是的,不只是用過去微軟自己家的VBA語言,而是採用標準的JavaScript與jQuery,微軟在這個領域也革了自己的命,為了讓更多的開發人員投入,微軟一改過去撰寫Office Add-Ins的習慣,建立了一個全新的架構,讓熟悉JavaScript與Web開發的技術人員,也可以直接開發Office Add-Ins。

這樣還不夠,前面說到,微軟的O365方案還有SharePoint與Exchange,這兩套微軟重要的企業應用產品,一個是企業的資訊入口網站,另一個是重要的電子郵件、會議預約、以及企業通訊平台,當然也不能置身事外。微軟開放了透過JavaScript與Restful API,讓開發人員用更簡單的方式,直接撰寫SharePoint Add-Ins,將一切更完美的整合在一起。

不僅如此,開發人員寫出來的SharePoint Add-Ins,依舊可以上架到Office Store市集,讓全球所有的Office 365用戶付費下載使用,現在,你已經可以在市集上,看到SAP、SalesFoce,等各種與SharePoint、Offce整合的App在Office Store上,讓Office、SharePoint輕易整合SalesFoce與SAP等企業應用相關功能。

這一個時代,我們正目睹著從傳統的桌面應用程式,大舉轉向為SaaS(軟體及服務)的年代,而微軟正顛覆著自己過去獲利與成功的方式,率先朝這個新的方向前進。今天,不管你是獨立的開發人員、是企業中的IT、MIS,是軟體的開發廠商(ISV),對於微軟以及全球市場正在經歷的這項改變,您勢必將無法忽視。

2015年7月26日 星期日

[開發Office Add-Ins] 從NAPA開始 (1)

Office Add-Ins,是Office 2013開始,嶄新的增益集套件開發方式,用的語言不再是VBA(但VBA依舊可以用,別擔心),而是Web開發人員熟悉的的HTML與JavaScript。

你可以透過開發Office Add-Ins,擴充Office Word, Excel , PowerPoint…的功能,可以將開發好的增益集上架到Office Store(市集),或是佈署到企業內的App Catalog上,供同仁使用。更重要的是,透過這個架構開發的App,是可以在Office Web/Desktop/Mobile各種版本上跨平台使用的,亦即,你在iPad上的Word裡,同樣可以使用這種新的增益集。

在這一篇文章當中,我們將陸續開始為讀者介紹如何開發Office Add-Ins(App for Office),一開始,我們選擇用最簡單的工具,NAPA。

NAPA本身是一個網站,一個Web應用程式,其實也是一個SharePoint App。NAPA提供了一套很簡便的操作介面,讓開發人員可以快速地建構出Office Add-Ins。

在開始之前,您必須申請一個NAPA帳號。可以透過底下這個網址申請:

https://www.napacloudapp.com/

請留意,你要使用NAPA,必須先有一個Microsoft Account,所謂的Microsoft Account也就是過去的Live ID,基本上就是Outlook.com或是hotmail.com的帳號,如果沒有,可以到底下網址申請一個:

https://signup.live.com/

申請完成並登入之後,可進到https://www.napacloudapp.com/ ,會看到底下畫面:

image004

點選Get Started,會要求你使用Microsoft Account登入,如果你已經登入,會看到底下畫面:

 image005

因為NAPA是一個網站,我們可以透過NAPA這個網站來寫程式,而NAPA需要存取您的OneDrive及相關資訊以便於存放與測試您寫的程式,因此您必須選擇Yes。

選擇了Yes之後,會看到底下畫面:

image

這樣您就可以透過NAPA來建立應用程式了。你可以建立一個最基本的Office Add-Ins,我們可以選擇Task Pane Add-In:

image

按下Create之後,你會看到底下畫面:

image018

在這個畫面當中,你會發現一進來看到的是Home.html,這是Task Pane Add-In應用程式的首頁(主UI),你可以點選Home.js,則會切換到:

image019

這是Home.html的主頁面邏輯,身分就等於過去我們在asp.net的code behind的感覺[1]。你會發現,撰寫Office Add-Ins的主要程式語言就是JavaScript(其中大多的語法都是jQuery),只要你熟悉Web開發,就可以開發Office Add-Ins。

除此之外,比較重要的還有app.js,不過關於應用程式架構與內容的部分,我們在後面再介紹。我們先看設定的部分,請點選底下這個工具鈕:

image020

你會發現其實剛才我們提到的頁面進入點,是從這邊(上圖Start Page)設定的。

請接著切換到Run:

 image021

你會發現畫面右方變成了你的應用程式運行方式的選項,在筆者撰寫本文的時候,只有第一個選項可以選擇。這設定的意思是,你選擇在Excel Web App當中來測試這個應用程式。

注意,這是指測試階段。當正式階段時,你的Task Pane Add-Ins是可以在Desktop/Web/Mobile版本的Word, Excel, PowerPoint…等環境執行的。

NAPA令人側目的原因之一,不僅僅是你可以透過它在純Web環境上面寫程式(使用時還有完整的IntelliSense),除此之外,你的source code直接存放在你自己的OneDrive裡面,連測試環境都是你自己的Excel Online應用程式。

你可以在NAPA環境當中,按下下圖中的執行圖式:

image

你會發現NAPA正幫你把這個程式碼上傳到你的OneDrive,並且試著開起你的Excel Online來運行:

image023

正常上傳完畢之後,你會發現Excel Online被打開了,你的Task Pane App就出現在Excel Online右方(這是Task Pane Add-In的顯示位置):

image024

由於它需要你的授權,請按下Start:

image025

您會發現App的主畫面Home.html出現了:

image026

由於Excel Online需要你授權才能編輯文件,所以請從選單中選擇Edit in Excel Online:

image027

接著,你就可以編輯Excel了,我們嘗試在儲存格中填入一些文字,然後按下主畫面當中的get data from selection鈕:

image028

你會發現我們透過NAPA撰寫的javaScript,抓取到了Excel裡面的儲存格內容,並且把資料顯示在上圖右下方的Notification訊息區塊。

這段JavaScript的程式碼是:

    function getDataFromSelection() {
        Office.context.document.getSelectedDataAsync(Office.CoercionType.Text,
            function (result) {
                if (result.status === Office.AsyncResultStatus.Succeeded) {
                    app.showNotification('The selected text is:', '"' + result.value + '"');
                } else {
                    app.showNotification('Error:', result.error.message);
                }
            }
        );
    }

我們後面再來慢慢解釋這段程式碼,讀者先別心急。不過你可以很明確地發現,我們只需要透過JavaScript,就可以存取Excel中編輯文件的資料。

NAPA固然已經是一個非常不錯的開發工具,但是,如果我們想更進一步的編輯複雜的程式碼,甚至在測試執行時候設定中斷點,那Visual Studio依舊是你的不二選擇。

你可以從NAPA當中,按下底下這個按鈕,即可把整個專案下載到Visual Studio當中執行:

image

點選後,如果出現底下畫面,請選擇你要下載的(慣用的)程式語言:

image030

選定後,你會發現瀏覽器自動下載一個程式,請選擇執行:

image031

接著,系統會開起Visual Studio:

image032

你會發現,開啟的專案就是剛才我們透過NAPA編輯的專案。

你會發現,在Visual Studio當中,依舊可以按下F5執行整個專案,如果你需要,甚至可以在JavaScript中設定中斷點,程式碼執行到該斷點還真的會中斷。

會不會好奇,如果你在Visual Studio當中,按下F5,程式會運行在哪兒呢?

沒錯,就是Desktop版本的Excel:

image033

而透過用戶端的Visual Studio來開發與測試,還有一個好處,就是可以設定更多的測試環境,你可以開啟專案中的manifest檔案,然後選擇Activation:

image034

你會發現畫面中可以選擇該App可運行的Office應用程式環境,當你選擇了Word之後,會發現這個App,在Visual Studio中按下F5測試時,開起的就從Excel改為Word了:

image035

但有趣的是,在程式碼完全不改變的狀況下,該App依舊可以運行,且跟在Excel中運行的狀況幾乎一樣,按下task pane視窗中的按鈕,底下呈現出了用戶在word當中選擇的文字。

有沒有發現,不論是透過NAPA或是Visual Studio,你都可以輕易地建立Office Add-Ins應用程式,是不是很方便呢?

後面,我們將會繼續介紹Office Add-Ins的開發,與程式碼的撰寫。

 


[1] 沒聽過code behind? 算了, never mind。