2010年8月1日

[Excel 技巧] 善用資料剖析來調整資料格式 (以 MS Excel 2007 為例)

上週要調整以 Joomla 為基礎的資產管理系統中的資料格式,把原本的「保固期間」欄位改成「保固期間(起)」和「保固期間(迄)」兩個欄位,以方便將日期作為搜尋條件來過濾資料。從實際的資料來說,是要把一筆「93.3.26~94.3.25」的資料拆成「2004-03-26」和「2005-03-25」兩筆資料 (配合 Fabrik 套件的 Date 格式,改為 YYYY-MM-DD (ISO格式)),那麼該怎麼做呢?

由於 Joomla 的資料是存在 MySQL 中,本來想說直接在 MySQL 中以 SQL 處理字串格式就好,但是要一口氣把「93.3.26~94.3.25」的資料拆成「2004-03-26」和「2005-03-25」是頗麻煩的,而且我對 MySQL 又不熟,所以最後還是改用 Excel 來完成啦!

用 Excel 的好處是可以先編輯資料,等到所有資料都確認無誤以後再匯入到 MySQL 中。以這次的需求而言,需要先新增「起始年」、「起始月」、「起始日」、「截止年」、「截止月」、「截止日」等,如下:



接下來只要把這些欄位的內容處理好 (例如補零、年份要 +1911、確認格式是否正確等),之後,再組合成最後所需的 YYYY-MM-DD 格式,然後把新增的 temp 欄位刪除就好啦!

但是一打開 Excel,想要自己動手用內建 function 硬幹的壞毛病又發作了,最後發現雖然可以做的出來,但由於缺少了「split」這個重要的 function,實作起來相當麻煩,公式也會搞的很複雜,以開始年為例,我的公式如下:


( =IF(OR(ISBLANK(A2), EXACT(A2, "N/A")), "", SUBSTITUTE(MID(A2, 1, 3), ".", "")+1911) )

首先要判斷 A2 欄位的值若為空或者 N/A 就不處理,確定有資料以後再用 MID 取出所需的年、月、日等字串。為了要正確取出民國 100 年,還必需要先多取一位 (可能會多取到一個「.」,例如「98.」),而多取了一位以後又要用 SUBSTITUTE 這個名字落落長的 function 來把多取的「.」給刪除掉,非常的麻煩!

雖然很麻煩,但是最後我還是把各欄位的公式都實作出來了,如下:
  • Start Year: =IF(OR(ISBLANK(A2), EXACT(A2, "N/A")), "", SUBSTITUTE(MID(A2, 1, 3), ".", "")+1911)
  • Start Month (TMP): =IF(OR(ISBLANK(A2),EXACT(A2,"N/A")),"",SUBSTITUTE(MID(A2,4,2),".",""))
  • Start Day (TMP): =IF(OR(ISBLANK(A2),EXACT(A2,"N/A")),"",SUBSTITUTE(MID(A2, FIND(".", A2, 4)+1, 2), "~", ""))
  • Start Month: =IF(OR(ISBLANK(A2),EXACT(A2,"N/A")),"",REPT(0, 2-LEN(N2))&N2)
  • Start Day: =IF(OR(ISBLANK(A2),EXACT(A2,"N/A")),"",REPT(0, 2-LEN(O2))&O2)
  • End Year: =IF(OR(ISBLANK(A2),EXACT(A2,"N/A")),"", SUBSTITUTE(MID(A2, FIND("~", A2)+1, 3), ".", "")+1911)
  • End Month (TMP): =IF(OR(ISBLANK(A2),EXACT(A2,"N/A")),"",SUBSTITUTE(MID(A2, FIND("~", A2)+4, 2), ".", ""))
  • End Day (TMP): =IF(OR(ISBLANK(A2),EXACT(A2,"N/A")),"",SUBSTITUTE(RIGHT(A2, 2), ".", ""))
  • End Month: =IF(OR(ISBLANK(A2),EXACT(A2,"N/A")),"",REPT(0, 2-LEN(S2))&S2)
  • End Day: =IF(OR(ISBLANK(A2),EXACT(A2,"N/A")),"",REPT(0, 2-LEN(T2))&T2)
完整的 Excel 範例檔可在這裡下載。

這次學到的技巧主要是「如何補零」,例如「3 -> 03」,作法請參考 Padding out a cell with leading zeros (leading zero 是關鍵字,中文或許可翻為「前導零」?)。

把公式實作出來,並且做完資料格式調整後,總是覺得不太對,Excel 沒有內建 split function 未免也太麻煩了,於是又找了一些資料 (例如這篇:How to Split a Column of Data in MS Excel ),這才發現 Excel 是把「分割字串」這個強大的功能放在「資料」-->「資料剖析」裡面阿!(其實以前好像用過的,但因為少用就忘記它的存在了 Orz)

試用了以後很快的發現,利用這功能只要不到 10 分鐘就可以把上面那一大堆公式要做的事情做完了,而且過程相當的直覺,可以節省非常多的時間阿!

實作的步驟如下:

步驟一:首先選取要分析的資料(A欄),再點選「資料」-->「資料剖析」



步驟二:在「原始資料類型」中採用預設值:分隔符號(D),之後按下一步



步驟三:此時先進行第一次分割,把「分隔符號」設定為「~」,以區隔開始日期和截止日期。此時可在下面「預覽分欄結果」視窗中先檢視是否將字串如預期的拆開,在第三行可看出的確有正確將「99.1.2」和「100.1.1」拆開 (免去了用公式要多取一位,之後再用 SUBSTITUTE 把多取的一位刪除的大麻煩)



步驟四:接下來可設定「欄位的資料格式」(此時用預設值「一般」即可),最重要的是「目標儲存格」,在此例中,以「~」作為分隔符號會將 1 欄拆成 2 欄,因此要選一個可容納兩欄的空間,假如 Excel 中的原始資料長這樣:



那麼就應該要選擇「K欄」($K:$K) 作為目標儲存格:





步驟五:確定目標儲存格已設定為 K 欄後,按一下「完成」按鈕即可



此時資料會正確被分為兩欄:



步驟六:接下來只要按照上述步驟,分別把 K 欄和 L 欄以「.」作為分隔符號再拆出 3 欄 (起始/截止年、月、日),再用前面提過的小技巧來補零,最後把年、月、日組合成 YYYY-MM-DD 的格式就可以了!這個作法比起直接用公式硬幹真的是太直覺,而且方便太多啦!

希望這篇簡短的紀錄對有須要的人會有幫助,也希望以後自己不要再忘記 Excel 這個簡單好用的工具啦!

2010年7月13日

[可能解法] Red Hat 4 開機時卡在啟動網路介面

上禮拜有台 IBM X3850 Server 硬碟掛掉 (跑 Red Hat 4),必須停機更換,沒想到重開機的時候會卡在「bringing up interface bond0 ...」的地方,造成每次重開機居然要花費將近 20 分鐘 (見鬼了,又不是 mainframe ...=.=),經過一番努力,終於發現一個可能的問題。

Linux 的網路相關設定檔案的存放位置在 /etc/sysconfig/network-scripts 目錄下,通常會看到 ifcfg-bond0 (bonding 介面)、ifcfg-eth0 (第一張網路卡)、ifcfg-eth1 (第二張網路卡) 等等,結果在這台 Server 上除了 ifcfg-eth0 以外,居然多了一個 ifcfg-etho (英文字母 o),檔案內容跟 ifcfg-eth0 完全一模一樣!結果我把 ifcfg-etho 檔案給移到另一個目錄下,再重開機後就恢復正常了!

後來為了重現這個問題,我在 Red Hat 5 上面故意用「cp ifcfg-eth0 ifcfg-etho」指令來產生一個多餘的檔案,再重新開機,結果!開機過程非常之順利 Orz  大概不用 5 秒鐘就略過有問題的 ifcfg-etho 設定檔,並且在螢幕上顯示「Usage ...」的警告文字 (用 runlevel 5 開機的話要自己點「詳細資訊...」按鈕才看的到),很容易猜到問題在哪裡。

於是我開始猜想是不是因為 Red Hat 4 比較**老實**,遇到有問題的設定檔還會一直執意要進行設定,retry N 次以後才會自動放棄?於是我又灌了一個 Red Hat 4 的 VM 來測試 (用 CD 灌的!相當復古!),結果即使我產生 ifcfg-ethxx、ifcfg-ethx99 等內容和 ifcfg-eth0 相同的亂七八糟設定檔,重開機還是不會卡住呀!Orz

雖然最後沒辦法完美的重現這個問題,但是本來就不應該有 ifcfg-etho 這種設定檔的,總之這種不應該出現的東西砍掉就對啦!

(最後只能猜測,Red Hat 在 Server 上的運作跟在一般的商用 NB / VM 模擬出來的環境還是會有差異,可能在 Server 上會有更嚴謹的程序,例如發現名稱錯誤的設定檔還是要盡力設法完成設定,不能直接忽略等等 ... 但這畢竟還是猜測,手上也沒有 Server 可以灌 Red Hat 4 來當測試機,所以真正的原因還是個謎 ... >"<)


另外補充-1:可惜 Blogger 介面不支援 Consolas 字型,不然要分辨數字0和英文字母o就方便多啦!(話說 Office 2007 好像有內建) Red Hat 開機到 runlevel 5 以後,在 GUI 介面下叫出的 terminal 也不容易分辨數字0和英文字母o,但是在 runlevel 3 下就看得很清楚了。

另外補充-2:如果有設定 NTP 校時,Red Hat 在開機的時候就會試圖跟 time server 溝通,此時若不接上網路線,可能也會因此卡住好幾分鐘。(類似 DNS 設定錯誤,會造成開機使啟動 sendmail 卡住好幾分鐘的狀況)

2010年7月12日

AWStats 重新分析特定時段 log 的方法

最近手上維護的 AWStats 網站出了一點問題,連續幾天的分析報表一片空白,因此花點時間研究了如何讓 AWStats 重新分析特定時段 log 的方法。

我主要參考的是:Neo's Blog - awstats 加入/重新計算分析某時段的方法,但是一開始嘗試多次都沒有成功。

最後我發現,若目前系統時間是 2010-07,則存放統計資料的資料夾中會出現 awstats062010.yoursite.txt & awstats072010.yoursite.txt (要知道 AWStats 產出的統計資料檔放在哪個目錄,請參考 AWStats config 檔中的 DirData 參數),

此時若欲重新分析 2010-06 的資料,必須先把 awstats072010.yoursite.txt 檔案移到 DirData 之外,否則將 Neo's Blog - awstats 加入/重新計算分析某時段的方法 一文中所說的第 4 步執行完畢後,雖然可正確看到 AWStats 的 output ( Found XXX new qualified records ... 等等),但 awstats062010.yoursite.txt 檔案還是不會被更新!

會注意到這個問題,是因為我改完  awstats062010.yoursite.txt 中的 LastLine、LastTime、LastUpdated 的值以後,跑完 awstats.pl 之後只有 awstats072010.yoursite.txt 檔案的最後更新時間有改變,看來 awstats.pl 根本沒有去讀 awstats062010.yoursite.txt 這個檔案!

在第 3 步和第 4 步之間加入「把當月的統計資料檔移出 DirData 目錄」這個動作,並執行完第 4 步的重新分析後,要記得把當月的統計資料檔 (awstats072010.yoursite.txt) 搬回 DirData 目錄,否則當月的統計報表會變成一片空白哦~


同場加映:Hourly, daily, (and yearly?) reporting period support debuts,daily report 的實作蠻簡單的,下一步是思考如何製作 weekly report。

2010年7月5日

HP-UX 的 ntp client 設定方式

前陣子測試在 HP-UX 上設定 ntp client 成功了,步驟如下(參考關於HP-UX「ntpq:read:can't assign requested address」問題):

  1. 採用root 身份登入
  2. 編輯設定檔netdaemons(# vi /etc/rc.config.d/netdaemons),將 XNTPD 設定為 1
    export XNTPD=1
  3. 編輯設定檔 ntp.conf (# vi  /etc/ntp.conf,要以chmod調整檔案權限),加入下列兩行server 10.xx.xx.xx  #  Primary Time Server
    server 10.yy.yy.yy  #  Secondary Time Server
  4. 啟動 NTP 服務.(# /sbin/init.d/xntpd start)(可下 ps -ef | grep ntp 來驗證 ntp process 是否有在運作)
  5. 檢查是否正常運作(約10分後) (# /usr/sbin/ntpq -p)
若有出現 “*” 於某列前,表示 ntp 服務正常運作,否則 ntp 服務即無正常運作。

一開始參考的是 HP 官網的線上說明文件:Chapter 4 Configuring NTP,在 Getting Started with NTP 章節中,要特別注意的是不要設定 /etc/rc.config.d/netdaemons 中的 NTPDATE_SERVER 參數!

NTPDATE_SERVER 參數設下去之後 ntp client 就不work了,執行 ntpq -p 指令會發生以下錯誤:

[myServer]:/etc#ntpq -p
No association ID's returned


參考資料:
  1. 鳥哥的 Linux 私房菜 - NTP 時間伺服器
  2. 台大網際網路時間伺服器說明
  3. HP Online Documentation: Chapter 4 Configuring NTP

[心得] 參加中央氣象局局慶心得

昨天坎尼和 Tim 中午相約吃完飯,想說來去參加一下氣象局局慶活動
其實兩人是對傳說中的地球展示系統(Science On a Sphere)有興趣!
20100704983
但到了現場才發現,好多蘿利和正太小弟弟小妹妹跑來跑去啊~
展示系統又需要排隊,demo 其實已經進行一半了,兩人就跑去亂晃

接著坎尼發現可以在樓下偷偷拍照…
20100704982 

展示系統是以四個方位的投影機,投在圓球體上
控制器則是用 Wii Remote 做成
不過到這邊坎尼心想,都用 Wii Remote 了
怎麼在指出地點的時候,另一手還拿出雷射筆哩…

20100704985

以展示來講,目前的系統已經 ok 了
有靜態投影片加上互動的感覺
(但所謂的互動,也就僅止於轉轉地球…)
20100704988 

但在應用上,坎尼覺得氣象局可以結合即時訊息
把即時的天氣雲圖、氣溫、雨量、地震等資訊,投到畫面上去
Wii Remote 也可以增加一些點選事件,和即時訊息互動等功能

今天 (7/5) 還有一天的展示,有興趣的朋友可以到氣象局逛逛
以下是熱心網友放在 Youtube 的系統 demo

最後要吐槽一下,坎尼和 Tim 在 B1 排隊排的很累
demo 完要散場才發現,其實可以從1樓直接進去…

然後兩個人還在交通部氣象局門口違反交通規則

2010年6月24日

[DOTNET] 利用 System.Globalization 提供的各種曆法類別取得特別的日期

今天來介紹各種 DotNET 提供的客製化曆法吧

I. 客製化曆法簡介

首先來看一下 System.Globalization namespace
各種曆法類別的命名為 xxxCalendar

比方講 PersianCalendar 為波斯曆
另外還有 TaiwanCalendar、JapaneseCalendar、KoreanCalendar …等

使用方法很簡單,大多是建立 xxxCalendar 類別實體之後
再叫用 .GetYear、.GetMonth、.GetDayOfMonth 方法
以下就用台灣曆和台灣農曆來簡單示範一下用法

II. 實戰

首先,先建立一個要轉換曆法的日期
建立 TaiwanCalendar 類別
由於台灣曆和西元曆的月日相同,這邊只顯示相異的民國年
TC01 再建立 TaiwanLunisolarCalendar 來取得農曆的日期
看一下日期的轉換結果
TC02
民國年當然可以確定是正確的
但農曆呢? 坎尼找到了這個 網站
2010/04/24 在農曆中的確是 3/11,得證!
TC03 
TaiwanLunisolarCalendar 還可以取得天干和地支
有興趣的讀者可以試試

III. 小結

若是要在自己的系統中顯示各地不同的曆法
建議可以先到 System.Globalization 裡找找
或許會有意外的發現

也有提供泰國的佛教曆,給有可能用到的人作參考

2010年6月22日

[ASPNET] 在 FormView 中使用 WebUserControl 可能會導致 Visual Studio 罷工

標題好長,不過真的有這回事嗎?

起先是坎尼的同學問有沒有碰過類似的問題
坎尼一開始也是很莫名,但發現 Visual Studio 跑他的程式就會掛
經過一陣推敲及實驗之後,總算是發現了肇事的主因

I. 問題描述

首先是怎麼個停擺法呢?

當在 FormView 中放入有問題的 WebUserControl 時
用 DesignMode 進入 FormView 的 EditTemplates 編輯模式
會看到 WebUserControl 不停的閃爍,接著 IDE 就會停擺在那邊

(註:IDE = Integrated Development Environment,本篇指 Visual Studio)

若運氣好,在發生問題之前就將游標移到 FormView 以外的位置
可以用快速鍵 Ctrl + PgUp/PgDn 切換成 Source Mode
運氣不好,大概就要叫 Task Manager 出來結束它的生命

先來看一下問題發生的影片 (請自行放大影片

影片中第一次打開 EditTemplates 時是沒有問題的
所以標題才會用 "可能" 而非 "絕對"

II. 問題解決

就在坎尼看著同學的 Code 百思不得其解時
想說再依樣畫葫蘆自己造一個一樣的 sample 來試試
咦?! 實驗結果很正常!!!

但當把坎尼同學寫的 FormView 內容 Code 直接貼到新建的 FormView 時,它又開始不停閃爍,這難道就是傳說中的鬼打牆?

接著坎尼眉頭一皺,發覺同學的 Code 裡有不對勁的地方
該不會是 WebUserControl ID 是用中文命名的關係吧?

測試結果證明:還真的就是這個原因!!!
但一般的 Controls 用中文命名都沒問題,只有 UserControl 會

原本坎尼以為所有容器型的 Template 編輯模式都會發生此情況
嗯,坎尼又猜錯了,只有 FormView 才會……

目前測試 VS2008 和 VWD2010Express 都有此情形
更之前的 VS2005 坎尼手邊沒有,無法測試
歡迎有心提供測試結果的讀者留言 ^^

III. 小結


這問題一直沒人發現 (坎尼 Google 不到)
大概是大家不怎麼用中文命名,或是沒在用 FormView 吧?
雖然 Visual Studio 為支援 unicode 的 IDE
但使用上除了文字屬性以外,還是盡量以英數字為主吧 :P

第一次錄影片,有點手忙腳亂,還請多多包涵 :D

Google Spreadsheet 裡用規則運算式

最近因為工作關係,遇到要用 Google Form 及 Google Sheet 所以研究了 Google Sheet 裡的一些 function 怎麼用 首先,分享一下如何在 Google Sheet 裡用規則運算 :D