2011年10月16日

買房策略-地段、地段、地段與房價

首先我必須說,房子是我很不瞭解的部份。
再來我必須說,我很幸運家裡有個在台北市的房子,沒有租屋付房租的壓力,
因此這篇,比較接近我以投資觀點來看買房這件事情。
這篇主要是看到了張金鶚的房產七堂課讀後感續1-----購屋的大同世界
加上之前看過的漫步華爾街後的有感而發。

因為前陣子房價很高,老媽走在路上,就會到處看房子,然後嘆息說
「以前應該在這裡買房,現在價格如何」。

然後我問我老媽,買房重點是啥,她回答了一個名人的經典說法
「買房重點有3個:地段、地段、地段」。

我聽完之後,一直覺得哪裡不大對勁,
在前陣子看過「漫步華爾街」之後,終於想明白問題在哪了......

漫步華爾街的作者在書後段提到房地產投資,作者對房地產的看法是
「他不瞭解房地產的價格如何被評估,認為房地產價格無法像公司股票比較容易量化和分析,而房地產的價格會隨著市場景氣高低波動,波動幅度會比市場景氣來得大」。
看完這段之後,我就瞭解到了一件事,
買房地段的確很重要,但實際上還是要考量到房價,一個簡單的問題:
同地段相同等級的房屋,且條件相同,
同一時間一間賣300萬,一間賣500萬,正常人會買哪間?
如果只按照「地段」作為選擇依據,
那麼300萬的房子和500萬的房子「都是值得購買的」,
可是顯然不大對,正常人都會買300萬那間而不會買500萬那間。
所以事實上,除了「地段」這項條件外,還要考慮到「價格」這個條件。

當買房條件出現了「價格」,甚至於和市場景氣出現關聯時,
那麼買房子就會和買股票、基金、黃金差不多,一樣會有價格高點和價格低點。

而股市在遇到空頭時,往往會出現一些有趣的說法,如:
「當擦鞋童都知道如何買股票時」
「當新聞版面隨處可見股市消息時」
「當某某名人說他賺了幾間房子時」
就是股市高點出現了。

那麼,如果套用到房地產呢?
如果房地產真的這麼厲害,只會漲不會跌,那美國次級房貸的問題怎麼會出現?
又如果房地產只會漲不會跌,那次級房貸後,美國房地產價格為何會破底再破底?
在回想下,前陣子台股9000點時,新聞是否經常出現買房大賺,房價大漲的新聞?
甚至可以比較一下,現在的房價和當時的房價相比有沒有差異?

所以我認為,買房只是另一種投資,
同樣要低買高賣或低買不賣,買進的時機點可能在市場景氣低點時會比較適合,
在景氣大好時,可能不適合買房,
我也認為,房價在任何時候價格不應該是相同的,
房價應該也會受到景氣影響而有房價高點跟房價低點。

2011年7月31日

OpenOffice聚會之心得分享 - 過程與範例程式、投影片下載


當天報告的投影片、範例程式:OpenOffice範例程式與投影片

年初時參加OpenOffice聚會,當時依瑪貓說,
之後OpenOffice Macro有成果,要和我們分享唷~

我當時義不容辭的同意了,於是在之後準備了這份報告。

這份報告,同時也是我到目前對OpenOffice Macro的認識與學習心得。

2011年7月8日

複委託之優點

日本發生海嘯後,我就在積極的查詢購買海外股票的方法和比較,
最後發現,目前在台灣,可以透過2種方式購買到國外股票:
1. 在海外開設股票帳戶
2. 透過國內證券公司的海外複委託購買

在經過比較後,最後我選擇使用海外複委託。

因為,用海外複委託搜尋,會發現有人在詢問海外複委託好不好,
所以這裡我大致列出我選擇的原因和海外複委託的優點和缺點。

海外複委託的缺點:
1. 手續費
我想,包括我在內所有人,
都認為海外複委託最大的缺點是「手續費
海外複委託的手續費都很貴。
以寶來證券日股交易來說,
每次交易1%計算,但最少5000日幣,
這相當於台幣1850左右(以1:2.7計算)。
其他應該也差不多,
日盛是最少5000日幣,
超過xx萬改以1%計算。

2. 人工單
除了港股、美股之外,都只有人工單,
電話呼叫很麻煩,有時候會打不進去,
詢問報價,和奇摩查到的報價會有誤差。

3. 帳戶操作麻煩
a. 沒有T+2
和台股不同,沒有T+2天,
必須帳上有足夠外幣現金(有些可以台幣交割了),
轉成外幣買完後,盛下的零碎外幣不好處理,
轉回有匯損,放著又不知道能幹嘛。
b. 轉出需要Fax+電話確認
錢從外幣帳戶轉出,需要傳真要求,
而且需要電話確認,很麻煩。

4. 限制比較多
我不用信用和融資買賣(槓桿太恐怖了),
複委託在信用買賣和融資操作,
是有限制的,印象中是不可以的。

5. 海外股票無法辦理退稅
以美股來說,美股配息先扣30%稅金,
透過複委託無法辦理退稅。

海外複委託的優點:
1. 多市場買賣
許多人推薦直接開立海外股票帳戶操作,但指的都是美股,
所以事實上,它並不是多市場,它只有美股可以操作,
只是因為美股中有全世界大部分公司的股票發行,或者ADR,
所以才說可以買到全世界公司的股票,但實際上,它還是美股,
而不會是日股、韓股、港股。
以這次日本海嘯後,我想買的日股來說,美股中的日本公司股價,
其海嘯造成的影響沒有很大,真正造成衝擊是日本股價。

2. 無銀行開戶限制
這點其實和第一點是關聯的。
要開立海外帳戶購買海外股票,必須針對單一地區開立銀行帳戶,
例如買港股要去香港銀行開戶,買美股要開立美國證券帳戶,
買日股要開立日本銀行帳戶...等。
香港和美國相對問題比較少,香港近,請假2天去玩一玩,
就能順便開好戶頭;美國可以用郵寄解決。
韓國、新加坡不清楚。
但針對日本,上網搜尋會發現,日本銀行排外性很高,
留學生都不容易找到可以開戶的銀行,何況是觀光客。

3. 手續費高,但其他費用少
海外複委託雖然手續費高,
但買賣時不用其他費用(配息手續費大家都有,費用也相同,看市場),
但其他海外帳戶不同。

我同事買港股,
選擇香港匯豐銀行(應該是很多人都會選擇的,香港最大)。
香港匯豐銀行規定,帳戶內金額(聽同事說,
含股票市值)必須大於20萬港幣,
否則每個月都要收取保管費,這筆錢複委託並不需要。

美股的話,除非人到美國去開戶,否則需要匯款,
匯款需要一筆不低的手續費,
我當時計算,如果「每次買美股都匯款」,
那手續費其實接近海外複委託的美股手續費,
因此網路上都說,
一次匯入大筆金額後,再進行操作,
而像我這樣靠薪水投資的,並不合適。

另外,如果我沒記錯的話,匯款是有時差的,
好像需要2~3天,
海外複委託的操作都是台灣的銀行的外幣帳戶操作,
放錢到可以操作,大概2~3個小時即可
(這應該是證券公司帳戶資訊沒更新,
我從銀行帳戶看,是立刻就有錢)。

4. 可靠度高
這點網路上的人都提過,透過海外複委託購買可靠度比較高,
比較不怕證券公司倒閉或者股票不見,
在網路上有人提到過,他透過美國的線上證券公司買股票,
結果股票不見的事情。
針對這點,網路上的人是說,
你可以找有加入「投資人保障協會」的線上證券公司,
但問題是,當你真的發生問題時,
你要如何和投資人保障協會聯絡?要怎麼把股票拿回來?
你的操作紀錄都在線上證券公司裡,
它股票都能不見,你怎麼能保證它操作紀錄還在?
那你怎麼舉證你的股票?

基於上述原因,
我最後選擇透過海外複委託買股票,
不過對我來說,
最主要原因還是因為我要買的是日股而不是美股或港股,
但我想,未來我要購買港股或美股,我不用因此跑到香港,
或者郵寄、匯款到美國搞很久,就能直接購買了,
這應該在便利性上也會好很多。

2011年4月4日

OpenOffice Calc BASIC Macro位址、名稱轉換

在OOo Calc中寫OOo BASIC時,會遇到個問題是,
要取得Cell時,常使用getCellByPosition() Method,例如:
oCell = oSheet.getCellByPosition(0,0)
oCell.String = now 'This function returns the current date and time

這樣可以取得A1這個Cell,並修改它的內容。

但getCellByPosition() Method使用的是0 Base,且X、Y都是數值
可是在Calc當中,
我們一般操作都使用A1這樣的字母+數值,且是1 Base
為了解決這個麻煩的小問題,我寫了個簡單的轉換函式,如下:
Function CellPositionToName(X As Integer, Y As Integer) As String
Dim LETTER_ARRAY As Variant
LETTER_ARRAY = Array("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","AA","AB","AC","AD","AE","AF","AG","AH","AI","AJ","AK","AL","AM","AN","AO","AP","AQ","AR","AS","AT","AU","AV","AW","AX","AY","AZ","BA","BB","BC","BD","BE","BF","BG","BH","BI","BJ","BK","BL","BM","BN","BO","BP","BQ","BR","BS","BT","BU","BV","BW","BX","BY","BZ","CA","CB","CC","CD","CE","CF","CG","CH","CI","CJ","CK","CL","CM","CN","CO","CP","CQ","CR","CS","CT","CU","CV","CW","CX","CY","CZ","DA","DB","DC","DD","DE","DF","DG","DH","DI","DJ","DK","DL","DM","DN","DO","DP","DQ","DR","DS","DT","DU","DV","DW","DX","DY","DZ","EA","EB","EC","ED","EE","EF","EG","EH","EI","EJ","EK","EL","EM","EN","EO","EP","EQ","ER","ES","ET","EU","EV","EW","EX","EY","EZ","FA","FB","FC","FD","FE","FF","FG","FH","FI","FJ","FK","FL","FM","FN","FO","FP","FQ","FR","FS","FT","FU","FV","FW","FX","FY","FZ","GA","GB","GC","GD","GE","GF","GG","GH","GI","GJ","GK","GL","GM","GN","GO","GP","GQ","GR","GS","GT","GU","GV","GW","GX","GY","GZ","HA","HB","HC","HD","HE","HF","HG","HH","HI","HJ","HK","HL","HM","HN","HO","HP","HQ","HR","HS","HT","HU","HV","HW","HX","HY","HZ","IA","IB","IC","ID","IE","IF","IG","IH","II","IJ","IK","IL","IM","IN","IO","IP","IQ","IR","IS","IT","IU","IV","IW","IX","IY","IZ","JA","JB","JC","JD","JE","JF","JG","JH","JI","JJ","JK","JL","JM","JN","JO","JP","JQ","JR","JS","JT","JU","JV","JW","JX","JY","JZ","KA","KB","KC","KD","KE","KF","KG","KH","KI","KJ","KK","KL","KM","KN","KO","KP","KQ","KR","KS","KT","KU","KV","KW","KX","KY","KZ","LA","LB","LC","LD","LE","LF","LG","LH","LI","LJ","LK","LL","LM","LN","LO","LP","LQ","LR","LS","LT","LU","LV","LW","LX","LY","LZ","MA","MB","MC","MD","ME","MF","MG","MH","MI","MJ","MK","ML","MM","MN","MO","MP","MQ","MR","MS","MT","MU","MV","MW","MX","MY","MZ","NA","NB","NC","ND","NE","NF","NG","NH","NI","NJ","NK","NL","NM","NN","NO","NP","NQ","NR","NS","NT","NU","NV","NW","NX","NY","NZ","OA","OB","OC","OD","OE","OF","OG","OH","OI","OJ","OK","OL","OM","ON","OO","OP","OQ","OR","OS","OT","OU","OV","OW","OX","OY","OZ","PA","PB","PC","PD","PE","PF","PG","PH","PI","PJ","PK","PL","PM","PN","PO","PP","PQ","PR","PS","PT","PU","PV","PW","PX","PY","PZ","QA","QB","QC","QD","QE","QF","QG","QH","QI","QJ","QK","QL","QM","QN","QO","QP","QQ","QR","QS","QT","QU","QV","QW","QX","QY","QZ","RA","RB","RC","RD","RE","RF","RG","RH","RI","RJ","RK","RL","RM","RN","RO","RP","RQ","RR","RS","RT","RU","RV","RW","RX","RY","RZ","SA","SB","SC","SD","SE","SF","SG","SH","SI","SJ","SK","SL","SM","SN","SO","SP","SQ","SR","SS","ST","SU","SV","SW","SX","SY","SZ","TA","TB","TC","TD","TE","TF","TG","TH","TI","TJ","TK","TL","TM","TN","TO","TP","TQ","TR","TS","TT","TU","TV","TW","TX","TY","TZ","UA","UB","UC","UD","UE","UF","UG","UH","UI","UJ","UK","UL","UM","UN","UO","UP","UQ","UR","US","UT","UU","UV","UW","UX","UY","UZ","VA","VB","VC","VD","VE","VF","VG","VH","VI","VJ","VK","VL","VM","VN","VO","VP","VQ","VR","VS","VT","VU","VV","VW","VX","VY","VZ","WA","WB","WC","WD","WE","WF","WG","WH","WI","WJ","WK","WL","WM","WN","WO","WP","WQ","WR","WS","WT","WU","WV","WW","WX","WY","WZ","XA","XB","XC","XD","XE","XF","XG","XH","XI","XJ","XK","XL","XM","XN","XO","XP","XQ","XR","XS","XT","XU","XV","XW","XX","XY","XZ","YA","YB","YC","YD","YE","YF","YG","YH","YI","YJ","YK","YL","YM","YN","YO","YP","YQ","YR","YS","YT","YU","YV","YW","YX","YY","YZ","ZA","ZB","ZC","ZD","ZE","ZF","ZG","ZH","ZI","ZJ","ZK","ZL","ZM","ZN","ZO","ZP","ZQ","ZR","ZS","ZT","ZU","ZV","ZW","ZX","ZY","ZZ","AAA","AAB","AAC","AAD","AAE","AAF","AAG","AAH","AAI","AAJ","AAK","AAL","AAM","AAN","AAO","AAP","AAQ","AAR","AAS","AAT","AAU","AAV","AAW","AAX","AAY","AAZ","ABA","ABB","ABC","ABD","ABE","ABF","ABG","ABH","ABI","ABJ","ABK","ABL","ABM","ABN","ABO","ABP","ABQ","ABR","ABS","ABT","ABU","ABV","ABW","ABX","ABY","ABZ","ACA","ACB","ACC","ACD","ACE","ACF","ACG","ACH","ACI","ACJ","ACK","ACL","ACM","ACN","ACO","ACP","ACQ","ACR","ACS","ACT","ACU","ACV","ACW","ACX","ACY","ACZ","ADA","ADB","ADC","ADD","ADE","ADF","ADG","ADH","ADI","ADJ","ADK","ADL","ADM","ADN","ADO","ADP","ADQ","ADR","ADS","ADT","ADU","ADV","ADW","ADX","ADY","ADZ","AEA","AEB","AEC","AED","AEE","AEF","AEG","AEH","AEI","AEJ","AEK","AEL","AEM","AEN","AEO","AEP","AEQ","AER","AES","AET","AEU","AEV","AEW","AEX","AEY","AEZ","AFA","AFB","AFC","AFD","AFE","AFF","AFG","AFH","AFI","AFJ","AFK","AFL","AFM","AFN","AFO","AFP","AFQ","AFR","AFS","AFT","AFU","AFV","AFW","AFX","AFY","AFZ","AGA","AGB","AGC","AGD","AGE","AGF","AGG","AGH","AGI","AGJ","AGK","AGL","AGM","AGN","AGO","AGP","AGQ","AGR","AGS","AGT","AGU","AGV","AGW","AGX","AGY","AGZ","AHA","AHB","AHC","AHD","AHE","AHF","AHG","AHH","AHI","AHJ","AHK","AHL","AHM","AHN","AHO","AHP","AHQ","AHR","AHS","AHT","AHU","AHV","AHW","AHX","AHY","AHZ","AIA","AIB","AIC","AID","AIE","AIF","AIG","AIH","AII","AIJ","AIK","AIL","AIM","AIN","AIO","AIP","AIQ","AIR","AIS","AIT","AIU","AIV","AIW","AIX","AIY","AIZ","AJA","AJB","AJC","AJD","AJE","AJF","AJG","AJH","AJI","AJJ","AJK","AJL","AJM","AJN","AJO","AJP","AJQ","AJR","AJS","AJT","AJU","AJV","AJW","AJX","AJY","AJZ","AKA","AKB","AKC","AKD","AKE","AKF","AKG","AKH","AKI","AKJ","AKK","AKL","AKM","AKN","AKO","AKP","AKQ","AKR","AKS","AKT","AKU","AKV","AKW","AKX","AKY","AKZ","ALA","ALB","ALC","ALD","ALE","ALF","ALG","ALH","ALI","ALJ","ALK","ALL","ALM","ALN","ALO","ALP","ALQ","ALR","ALS","ALT","ALU","ALV","ALW","ALX","ALY","ALZ","AMA","AMB","AMC","AMD","AME","AMF","AMG","AMH","AMI","AMJ")

If X < 1024 Then CellPositionToName = LETTER_ARRAY(X) + (Y + 1) Else MsgBox "Out Of Range" End If End Function

傳入X、Y 2個數值,回傳A3這樣的名稱,
因為X最大是AMJ(0~1023),因為數值並不大,
我直接定義成變數查表即可。

注意:已經自動轉換Base 0為Base 1,傳入時不用刻意加1。

2011年4月3日

007先生的交易歷程 的 讀後回文

本來在找匯率表之類的,就找到這個有趣的Blog
007先生看來年紀跟我差不多,不是同年就是小個1~2歲,
整個Blog看下來後,我認為007先生實際的以金錢去做了個實驗,
實驗證明了,程式交易並不是神,
僅僅依靠程式交易搭配特定演算法就要套利,
結果就是直接被市場KO,
我後來想了想,覺得007先生這麼做,並以日記形式寫成Blog,
應該可以作為不錯的反向教材,
而在倒數第二篇文章中,因為007先生的不甘心,
提到「一定是哪裡出了問題」,
因此我把我這段時間的想法寫成回文,
這段回文,算是目前我對交易市場和程式交易的想法。


沒做過外匯,只有最近(算前陣子)台幣升值時有換一些美金玩玩。
我是看到「我知道必定是哪裡出了錯...」這句話,才想回應的。

我對程式交易有興趣,但我只打算用程式交易做股市中長期(月為單位、長期持有定存股),代替人工下單(上班沒時間)。
我目前認為,除非遇到系統風險或異常超跌,否則在交易市場要套利,應該很難和大戶或法人玩。

我目前認為,程式交易會失敗有幾個關鍵因素:
1. 常見的程式交易,都是用EasyLanguage去寫的,你仔細想一下,事實上它能做到的條件很死板,它的條件幾乎都是軟體寫好提供的,感覺有點像是說,給你玩個沒規則的遊戲,但只給你幾個條件去搭配判斷,這聽起來就很受限,只要我知道你能夠使用的條件,我想贏你的機會應該很大

2. 目前沒有任何聖杯,可以保證獲利,沒有任何條件套用在金融市場是百分百正確的,我們透過一連串無法保證的條件去判斷,並期望它要有6成勝率,那可能用亂數感覺還快些

3. 去年發生過一次美股異常交易的事件有上新聞,大家都知道,有人說可能是高頻交易引發的連鎖效應,我查了高頻交易,才知道國外很多大型投資公司用高頻交易套利,它們利用電腦,以「每秒400次成交」的速度,高速的進行買跟賣,利用利差來套利,甚至我認為,能以此掌握最短期的市場變化,在設備、環境、程式、資金大小、消息面都不對等的情況,我不認為我的程式有辦法跟這樣的程式作對

4. 程式是人寫的,換言之,它只能代替人去按照特定模式交易,既然你我都沒找到一個勝率達6成的模式,又怎麼能要求程式能有6成勝率?

最後,我想我可以把最近幾個月的想法說一下,我認為,憑空希望能透過投機的方式來獲利,不如注意系統風險的發生。
你買了這麼多書,相信有提到一點,交易市場會有系統性風險跟非系統性風險,系統性風險不可預期,且影響巨大,像金融風暴、次級房貸...等。
事實上你稍微注意一下會發現,當遇到系統風險時,該投資標的很有機會跌到非常不錯的價格,只要不破產,此時買入並長期持有(預期至少1~2年),那麼我認為績效應該都不會太差。
你前面常提到,有錢人一開始也是從無到有的,這點我認同,但不完全認同,一些人它可能父母有庇蔭,一開始就有一筆不少的資金,當他剛好遇到某個系統風險時,大膽的投入,運氣不好可能破產,但此時只要沒破產,勝率很高,且因為資金大,獲得的獲利非常可觀,原因是,在交易市場,你玩了這麼久就知道,它的獲利是以%數計算的,他有資金,又在系統風險最低點投入,上來時,那種以%數計算的獲利非常驚人。
最後,我們生在台灣,天生就不平等,你想想,我們辛辛苦苦一個月不過3,4萬,一個月有辦法也不過存2萬,美國人薪資是我們的2~3倍,扣除開銷和稅金,還是比我們多很多,他們的資金水平和我們不是同一個水平,對賠率的容忍度比我們高,這是沒辦法的事,但好消息是,跟對岸或東南亞國家相比,薪資水準、物價水平我們又好一些。

OpenOffice BASIC Macro資料庫操作-2

在上集中,我們完成了現在要使用的資料庫,
接著我們就可以透過OpenOffice BASIC來操作剛剛產生的資料庫。

在OOo BASIC中要操作資料庫,整個過程需要6個動作:
  1. 連結DataSource
  2. 取得查詢
  3. 連結SQL伺服器
  4. 從查詢中取得SQL Code,並查詢SQL伺服器
  5. 查詢完成,取出查詢結果
  6. 關閉SQL伺服器連線

整個程式碼如下:
Sub Main

REM 連結 DataSource
Dim DatabaseContext As Object
Dim DataSource As Object
DatabaseContext = createUnoService("com.sun.star.sdb.DatabaseContext")
DataSource = DatabaseContext.getByName("OOoTEST")

REM 取得查詢
Dim QueryDefinitions As Object
QueryDefinitions = DataSource.getQueryDefinitions()
QueryDefinition = QueryDefinitions("ProductQuery")

REM 連結SQL伺服器
Dim InteractionHandler As Object
Dim Connection As Object
InteractionHandler = createUnoService("com.sun.star.task.InteractionHandler")
Connection = DataSource.ConnectWithCompletion(InteractionHandler)

REM 從查詢中取得SQL Code,並查詢SQL伺服器
Dim Statement As Object
Statement = Connection.createStatement()
ResultSet = Statement.executeQuery(QueryDefinition.Command)

REM 查詢完成,取出查詢結果
Dim DATA_ID As String
Dim DATA_NAME As String
Dim DATA_PRICE As String
If Not IsNull(ResultSet) Then
While ResultSet.next
DATA_ID = ResultSet.getString(1)
DATA_NAME = ResultSet.getString(2)
DATA_PRICE = ResultSet.getString(3)
MsgBox "ID:"+ DATA_ID + " 名稱:" + DATA_NAME + " 價格:" + DATA_PRICE
Wend
End If

REM 關閉SQL伺服器連線
Connection.Close()
End Sub


接著我們分段來解說每個部份:
1. 連結 DataSource
在OpenOffice中,所有要被Calc使用的資料庫都需要先被「註冊」,
在建立資料庫時,預設都會自動幫你把它註冊到OpenOffice當中,
回憶一下,如下圖:
當我們將資料庫註冊到OpenOffice後,
我們就可以將它當成DataSource進行連結,
這裡要注意到,註冊的名稱可以和DataBase名稱不同,
要以「註冊名稱」為「DataSource名稱」,
不過預設,兩者名稱相同。

在這裡,我們指定DataSource為剛剛建立好的資料庫OOoTEST
分段程式碼如下:
Dim DatabaseContext As Object
Dim DataSource As Object
DatabaseContext = createUnoService("com.sun.star.sdb.DatabaseContext")
DataSource = DatabaseContext.getByName("OOoTEST")

我們先定義DatabaseContext和DataSource這兩個變數,
接著建立DatabaseContext服務
透過DatabaseContext服務來取得OOoTEST這個DataSource

延伸:
這裡有個延伸的程式碼可以參考,如下:
Dim DatabaseContext As Object
Dim DataSource As Object
DatabaseContext = createUnoService("com.sun.star.sdb.DatabaseContext")
Names = DatabaseContext.getElementNames()
For I = 0 To UBound(Names())
MsgBox Names(I)
Next I

我們可以透過這段程式碼,將所有註冊的資料庫全部列出。

2. 取得查詢
取得DataSource後,還記得剛剛我們在OOo Base裡面,
有建立好一個叫做ProductQuery的查詢項目。
接著,我們取得這個查詢,分段程式碼如下:
Dim QueryDefinitions As Object
QueryDefinitions = DataSource.getQueryDefinitions()
QueryDefinition = QueryDefinitions("ProductQuery")

定義QueryDefinitions這個變數,
透過DataSource的getQueryDefinitions() Method,
我們取得全部的Query,
並從裡面取出我們要使用的Query - ProductQuery

延伸:
如果我們不清楚有哪些Query,希望透過Macro動態查詢,如下:
Dim QueryDefinitions As Object
QueryDefinitions = DataSource.getQueryDefinitions()
REM 顯示所有查詢
For I = 0 To QueryDefinitions.Count() - 1
QueryDefinition = QueryDefinitions(I)
MsgBox QueryDefinition.Name
Next I

我們可以用這段程式碼,將所有已經儲存的Query全部列出。

如果我們想要用Macro建立新的Query,我們可以使用下面的程式碼:
Dim QueryDefinitions As Object
QueryDefinitions = DataSource.getQueryDefinitions()
QueryDefinition = createUnoService("com.sun.star.sdb.QueryDefinition")
QueryDefinition.Command = "SELECT Name FROM ProductTable"
QueryDefinitions.insertByName("OurNewQuery", QueryDefinition)

透過這段程式碼,我們可以建立一個新的Query叫做OurNewQuery
這個Query的SQL Code為「SELECT Name FROM ProductTable」。

3. 連結SQL伺服器
再來我們要正式連結SQL伺服器,分段程式碼如下:
Dim InteractionHandler As Object
Dim Connection As Object
InteractionHandler = createUnoService("com.sun.star.task.InteractionHandler")
Connection = DataSource.ConnectWithCompletion(InteractionHandler)

這裡我們要建立InteractionHandler服務
接著使用DataSource的ConnectWithCompletion()來連結SQL伺服器

4. 從查詢中取得SQL Code,並查詢SQL伺服器
SQL伺服器連結完成後,我們要查詢SQL伺服器,如下:
Dim Statement As Object
Statement = Connection.createStatement()
ResultSet = Statement.executeQuery(QueryDefinition.Command)

我們先定義Statement變數
接著透過Statement的executeQuery()查詢SQL伺服器

這邊注意到,事實上executeQuery()使用的是SQL Code,
因此我們要透過QueryDefinition.Command
將剛剛我們取得的Query - ProductQuery內的SQL Code取出。

延伸:
因為executeQuery()使用的是SQL Code,
因此我們可以不透過Query,直接用SQL Code進行資料庫的查詢,
程式碼如下:
Dim Statement As Object
Statement = Connection.createStatement()
ResultSet = Statement.executeQuery("SELECT Name FROM ProductTable")

5. 查詢完成,取出查詢結果
如果資料庫是INSERT或者UPDATE的操作,不需要取得資料,
那麼這個步驟是完全不需要的,這個步驟只有在查詢資料,
需要從資料庫中取得資料才需要。

分段程式碼如下:
Dim DATA_ID As String
Dim DATA_NAME As String
Dim DATA_PRICE As String
If Not IsNull(ResultSet) Then
While ResultSet.next
DATA_ID = ResultSet.getString(1)
DATA_NAME = ResultSet.getString(2)
DATA_PRICE = ResultSet.getString(3)
MsgBox "ID:"+ DATA_ID + " 名稱:" + DATA_NAME + " 價格:" + DATA_PRICE
Wend
End If

這裡很簡單,在前面步驟4的最後,
我們透過executeQuery()查詢資料庫後,
結果會儲存在變數ResultSet當中,
這裡我們先檢查ResultSet,確定它是有東西的,
接著使用ResultSet.next取出每條結果,
再來我們使用ResultSet.getString(1)取出第1個欄位資料
使用ResultSet.getString(2)取出第2個欄位資料,
利用MsgBox將資料用訊息視窗顯示出來

6. 關閉SQL伺服器連線
最後,我們要有好習慣,將SQL伺服器斷線,分段程式碼如下:
Connection.Close()
到這裡,整個資料庫的查詢全部完成。

這裡延續前面的慣例,可以出個作業,
這裡我們完整的取得了資料庫的資料,
那要如何填入OpenOffice的Calc呢?

OpenOffice BASIC Macro資料庫操作-1(資料庫建立)

要操作資料,或者進行歷史資料處理,資料庫的操作都是不可避免的,
在前面入門課題結束了,我們就開始直奔主題,而第一個po的心得,
就是頗有難度,但在資料處理上很重要的,資料庫操作,這裡是操作讀取,
但寫過資料庫程式的都知道,讀取比寫入麻煩,會讀取,要會寫入都不難。
因為篇幅可能會比較長,我分上下兩集介紹,上集是建立資料庫。

開始工作前,首先需要個資料庫,在這裡我們使用OpenOffice Base的資料庫來操作。

1.建立資料庫,並存檔為OOoTEST.odb放置於桌面



2. 建立Table、輸入資料



3. 建立查詢,查詢ProductTable內全部項目


如果偏好直接用SQL Code,也可以用下列SQL Code直接建立:
SELECT "ID", "Name", "Price" FROM "ProductTable";

4. 至此,資料庫和查詢建立完成,可以開始透過Macro操作了

2011年3月19日

日本祈福與福島核災

日本這次發生誇張的地震和歷史性的海嘯,在慶幸不是台灣的同時,
祝福他們,希望他們能夠早日重建完成,我相信強大的日本,
絕對可以在短時間內重建,恢復如常。

這次,我繼四川地震、八八風災後,第三次捐款,
同樣捐助了3000元台幣,雖然不算太多,但以我目前的收入來說,
是3日所得,算是我能力所及的,因為我最近比較忙碌,
經常加班,恐怕沒辦法有力出力,錢,大概也只能出這些,
希望大家都能幫忙,讓日本能更快得回覆原來生活。

至於福島的核災,現在很多媒體報導的很誇張,
我實在不想點名,但有些新聞台報導的實在太離譜了,
記得第二天某新聞台的報導,
一邊說原能會說輻射線對台灣沒影響,風向也不對,
但另一邊打跑馬說輻射線晚上就會來台灣,這實在是......

在到達第4天時,某新聞台晚上的新聞評論,
幾個名嘴一邊說反應爐已經破洞了,一邊說水不夠,
一邊說他們拿水桶衝過去潑水,
這看得我笑到眼淚都噴出來了,這也太扯了......

我認為,日本核電廠的問題算嚴重,
但並沒有嚴重到會發生核子爆炸,也不會發生核子爆炸,
事實上,他們第一時間反應爐就停機了,
核子反應第一時間就降到最低了,所以不會核爆,
但因為核子反應「不會完全停止」,因此需要持續水循環作降溫,
而供水設備沒電、故障,才引發後續問題。

到了現在第6天,事實上狀況「漸趨穩定」了,
從新聞來看,他問題的背景是:
遭遇地震+海嘯時
1號、2號、3號反應爐機組運作中
4號、5號、6號停機歲修中(全世界核電廠的反應爐機組,運作1年半都要歲修一次)

所以4、5、6正常來說,反應爐是不應該有問題的。
所以4號失火,第一時間日本官防長官(台灣的行政院長)說正在瞭解情況,
因為不應該有問題,而之後的瞭解是,「廢燃料棒儲存槽失火」。

到今天(2011-03-19)原能會發佈的狀況是:
1號反應爐機組,反應爐圍阻體正常,冷卻水(海水)有進入,勉強可控制
2號反應爐機組,反應爐圍阻體「可能受損」,冷卻水無法進入,無法控制
3號反應爐機組,反應爐圍阻體「可能受損」,冷卻水無法進入,無法控制
4號「廢燃料棒儲存槽」「可能受損」,冷卻水無法進入,無法控制
5號「廢燃料棒儲存槽」原本水位降低,柴油發電機已能正常動作,冷卻水循環已經正常
6號「廢燃料棒儲存槽」和5號相同,柴油發電機已能正常動作,冷卻水循環已經正常

所以現在要注意的是:
1. 4號儲存槽是否有受損,這關係到輻射線是否外洩?
4號儲存槽的冷卻水循環何時能恢復?
2. 2號跟3號的反應爐圍阻體到底受損多嚴重,是變形還是破洞?
因為這關係到輻射線外洩的嚴重程度
3. 2號跟3號的冷卻水循環,或者外部海水注入,何時可以完成?

這3個點才是目前要關注的,這3個點,也才是輻射線外洩程度的關鍵問題。
至於爆炸,目前我認為再發生爆炸的機會不大,核爆的可能性更低,
而輻射線外洩,是「已經洩了」,但「洩漏程度」是目前的問題點。

至於台灣,我認為台灣的核電廠安全係數比福島的高一些,
就原能會的新聞來看,台灣核電廠的選址地形、備援機制都要比日本福島的好很多,
同樣的災難發生在台灣,可能不至於讓核電廠出問題,
但我認為,台灣的核電廠未必會出現和日本一樣的災難,
卻可能因為其他災難造成其他問題,因此我認為,加固或增加安全機制有必要性,
但因此反核我就不認同了。

最後,我的結論是,在為日本祈福,有錢出錢有力出力的同時,
對於核能的問題,還是應該理性一點看待,不應該被一些怪怪的媒體報導左右,
然後搞得認為世界末日或者福島要核彈爆炸了,
以冷靜的腦袋,儘可能的瞭解資訊,讓自己不要驚慌,應該是這時候比較適合做的事。

OpenOffice巨集參考資料

繼上篇的UNO架構介紹和上上偏的簡單範例後,
相信已經有能力寫個HelloWorld的Macro(巨集;之後都會直接用Macro表示)了,
但記得我在很多年前寫過,要學習一個新的程式語言,需要知道幾個部份:
1. Main結構
2. 程式語法
3. API或Class Reference

從上上篇的範例看完,以及上篇的UNO解說,
我相信1和2大概都能掌握了,接著是3的部份,而這篇,
就是列出一些我在寫OpenOffice時,參考的網站、文件。

書:
我在學習OpenOffice Macro時,第一個找的是書,但很不幸的,
中文書是完全沒有的(正體、簡體),
我找到的一本值得的書是:

這本書基本上不錯,但仍舊有缺點,它細節的部份很多都略過了,
所以看起來也會有一知半解的感覺。

文件:
針對OpenOffice Macro的基本概念和語法教學,寫得最好的我認為是:
這個算是Oracle(前Sun)提供的官方教學文件,
針對OpenOffice的BASIC Macro寫得非常詳盡,
事實上,我認為前面介紹的書,有一些是從這裡面Copy出來的。
雖然文件是介紹StarOffice的BASIC,
但事實上,
OpenOffice的BASIC和StarOffice的BASIC在語法上幾乎是一樣的。

網頁:
 針對OpenOffice BASIC,OpenOffice網站的教學當然不能錯過:
OpenOffice.org BASIC Programming Guide

這個教學頁面有提供簡體中文的翻譯,如下:
OpenOffice.org BASIC 編程指南
這個教學頁面我認為部份內容寫得還ok,
但它幾乎沒有圖片,解說內容也很少,看得很模糊,
看完之後,感覺上還是甚麼都沒看懂,
但基本上,有比沒有好,還是一個值得參考的教學頁面。

OpenOffice.org Developer's Guide
這個同樣是OpenOffice wiki內的教學頁面,
它的特點是,它介紹了OpenOffice內多種語言的開發,
包括OOo BASIC、Java、C++...等,
但如果前面的BASIC Programming Guide是有比沒有好的話,
這個頁面就實在是不怎麼樣,每個篇幅看下來,
反應就是,只有2句話我能看懂甚麼... :(
但,憑著它有多個語言的描述,勉強可以參考參考。

The OpenOffice.org API Project
OpenOffice.org Global Index A
OpenOffice.org Module star
這3個網頁是OpenOffice API內的頁面,
它們其實是同一串網頁的東西,
它們其實就是UNO的API Reference,
第2個網頁是將所有Service、Method、Properties全部以字母排列,
然後列出來。

第3個網頁則是以Module Name來排列描述的樹狀頁面。

第1個網頁則是它們的首頁,
如果知道Module、Method、Property的名稱,
首頁提供了很難用的搜尋引擎可以直接尋找。

我認為這幾個API Reference的頁面非常重要,
它提供了OpenOffice能夠使用的所有API的說明,
也非常有價值,但它寫得很爛,遠比Java在使用的API Reference爛得多,
我不瞭解,明明有Java的API Reference這麼好得樣板,
為啥還要作成這種鬼樣子。

Calc Functions listed by category
這同樣是OpenOffice wiki的網頁,但內容非常不錯,
我們回到最初提過的,我們這麼辛苦的學習OOo Macro,
就是為了使用它的Calc幫助我們運算和資料整理,
Calc裡面最強大的莫過於它的許多「function」,
這些function能幫助我們進行數學、財經...等運算,
透過Macro,我們還是要知道這些function怎麼用,
這個頁面,就是列出了所有Calc的function,
並有簡單的解說和Example教我們怎麼使用它。

The OpenOffice.org Wiki
因為前面的推薦頁面中,很多個都來自OpenOffice的wiki,
因此,還是把它的首頁列出來推薦,
這個可以算是前面幾個教學頁面的目錄。
不過因為它是針對OpenOffice的wiki,
而不是專門針對OpenOffice開發,
所以大部分的教學都還是針對OpenOffice的操作進行說明和教學。

OpenOffice Help:
沒看錯,就是OpenOffice的Help,
和前面的Calc Functions listed by category類似,
OpenOffice的Help能夠提供我們Calc Function的使用說明,
還有一部分BASIC的解說,包括OOo BASIC的資料型態,
運算符號和方式...等。
OpenOffice的Help最方便的地方在於,它可以直接搜尋,
雖然命中率有點低,但相對來說,還是比較方便的。

範例程式:
要使用OpenOffice的Macro,通常需要安裝OpenOffice SDK,SDK安裝好後,除了相關的Library外,還提供了一些範例和說明,
路徑在:
OpenOffice.org 3\Basis\sdk\examples

這裡必須要提一下,它的範例,我個人覺得有些複雜難懂。

論壇:
Macros and UNO API(OpenOffice Forum)
壓箱寶一定要放在最後面。
因為OpenOffice的Macro開發實在是文件稀少,
很多人都有相關的疑問,因此它的Forum真的是很熱鬧,
裡面有幾個國外的高手,看起來從很早前就在用OOo Macro了,
不少相關的解說和文章都相當的有用,直接提供了Code。
事實上,我看了前面的API Reference,
還是沒辦法獨立的根據API Reference寫出OOo的BASIC程式,
需要到Forum裡面查看看有沒有人有寫過並po文,
交互參考後才寫得出來,由此可知這個Forum的強大。

到這裡,我認為OpenOffice Macro入門所需的知識應該已經夠了,
下一篇開始,我會將這段時間的研究後得到的一些技巧性的程式段po出來,
一些是來自於論壇的Code的改寫,一些則是翻翻找找後拼湊出來的,
還請期待。

OpenOffice Macro API(UNO)架構說明

承接前一篇,在知道了簡單的開發環境和程式流程後,
這篇簡單的介紹OpenOffice Macro的API的架構,
瞭解架構後,可以比較容易瞭解API怎麼使用。

要接觸OpenOffice BASIC前,
我原本認為它的BASIC語法應該會跟VBA差不多,
學習下去後才發現,它跟VBA完全不同,類似的只有基本語法,
但API的使用,操作完全不同,基本上沒辦法無痛,
一定要下去瞭解UNO才有辦法使用。

OOo(OpenOffice.org簡稱)的Macro支援很多套程式語言,
包括:BASIC、Java、Java Script、C++、Java BeanShell Script

它們的核心,都是呼叫OOo提供的一整套API,
這套API被稱為UNO(Universal Network Objects),
透過UNO,上述所有語言都能呼叫和操作OpenOffice,
好處是跨語言,壞處是,就算只是想學BASIC,也得瞭解UNO。

如果先前學的是Java,要瞭解UNO很容易,UNO不愧是Sun設計的,
很有Java的概念。

一般來說,常見的UNO概念圖如下:

這裡我不得不說,我第一次看得時候,看一眼就沒興趣了,
但事實上它只是描述了一個簡單的架構。

UNO(Universal Network Objects),我猜測,
也許是為了要設計一個能跨平台使用的溝通模式,
又因為是Sun,所以以Java的物件導向為架構,用網路來實做,
我想用網路而不用其他溝通機制的原因,
應該是因為網路是各平台都有,
而且在UNIX、Linux的環境,他是很基本又常見的溝通機制,
也因為這樣,取名為Universal Network Objects。

簡單的說,它跟Java的物件導向概念雷同,它們的類比如下:
UNO ServiceJava Class
UNO PropertiesJava Object Properties
UNO MethodJava Object Method

簡單的說,它是以Java的物件導向為基本概念,
所有的Java Class在UNO上,都稱為Service
每個Service都有自己的Properties和Method

要使用Service,則和使用Java Object有些許不同,類比如下:
UNO:
Dim oDesk as Object
oDesk = createUnoService ("com.sun.star.frame.Desktop")


Java:
Object oDesk;
oDesk = new com.sun.star.frame.Desktop();


這樣應該很清楚,差異在於,要定義物件時,使用
Dim <名稱> as <物件名稱>

要實體化時(UNO下應該說是建立Service),使用
<名稱> = createUnoService("com.sun.star.frame.Desktop")

這樣描述,應該就能清楚的瞭解UNO的Service概念,
而要使用UNO Service也很容易,同樣以上面的oDesk為例子,
可以如下使用:
Dim oDoc as Object
oDoc = oDesk.loadComponentFromUrl("private:factory/scalc", "_blank",0,Array ())


在這裡,loadComponentFromUrl()就是com.sun.star.frame.DesktopMethod
使用上和Java的語法差不多。

要定義或修改Properties也很容易,類似如下:
oCell.String = "我的第一個Input"

這樣就能修改oCellString這個Property
並將內容改為"我的第一個Input"



最後,同樣出個簡單的問題,答案很好找,
卻在使用時頭一個會遇到疑問。
在Java中,每個Object幾乎都有相對應的Object名稱,
例如:
JFrame f = new javax.swing.JFrame();

像是JFrame f裡面的JFrame。

那類比到UNO Service時,這個建立後的Service,
是否也有獨立的名稱?
如果有,那會是甚麼?
如果沒有,那又會是甚麼?

補充:
漏了一個部份.....
我們回到前面常見的UNO概念圖,圖上在Service的外圍,
有一個ModuleService包裹住,Module是甚麼?
這也是很簡單的概念,同樣取自Java,類比如下:
UNO ModuleJava Package

實際上,和Java的Class一樣,OpenOffice的Service根據不同的用途,
會被包裹在不同的Module裡面,例如:
javax.swing.JFrame

我們可以知道JFrame屬於javax.swing這個Package,同樣的,在UNO中
com.sun.star.frame.Desktop

Desktop就是屬於com.sun.star.frame這個Package

2011年2月28日

OpenOffice Calc巨集最簡範例

很久很久沒更新了,主要是工作忙碌,一個個bug接著來,一直處於很忙碌狀態。

從上次po文說要開發Stock程式後沒多久,
我開始轉移方向到OpenOffice巨集的學習,
原因是,Stock程式的前段、後段都完成了
(前段,透過AutoIT控制證券軟體後,DDE取得即時資料;後段,透過AutoIT控制證券軟體或網頁下單),
而最關鍵的行為判斷(也就是演算法)的開發一直沒有很好得構想,
我的期望是,能夠有個簡易但富有彈性的開發環境可以進行演算法開發和評估,
但Java要開發這樣的程式,實在是不大方便,要作所謂的回測(用歷史資料測試效果)也沒辦法,
曾經考慮過整個用Java寫,也考慮過修改OpenSource的看盤軟軟體,
但感覺效果都很差,複雜度都很高,最後回頭看Excel,
考慮到Linux,因此決定改以OpenOffice為中心,連結先前開發的前段和後段,
以OpenOffice的Calc來開發和測試演算法的部份,
這部份在今天有很大的突破,以後再說。

這裡這篇,我寫上OpenOffice Calc的簡單巨集開發,算是熱身,
之後再陸續貼些在使用不錯的Macro。

環境:Windows or Linux 均可
OpenOffice版本:3.2.1(新版亦可)

1. 開啟OpenOffice Calc後,點選
工具巨集組織巨集OpenOffice Basic

2. 選取要編輯的巨集(Macro)檔案
我的巨集StandardModule1Main編輯

3. 巨集(Macro)編輯視窗簡介

4. 輸入程式碼
在剛剛看到的Sub Main和Sub之間輸入如下程式碼:
Sub Main
Dim oDoc As Object
Dim oSheet As Object
Dim oCell as Object

REM 新建一個試算表檔案
oDoc = starDeskTop.loadComponentFromUrl ("private:factory/scalc", "_blank",0,Array ())
REM 開啟目前的試算表視窗
REM oDoc = StarDesktop.CurrentComponent

REM 建立新試算表分頁
REM http://docs.sun.com/app/docs/doc/819-0439/faail?l=en&a=view
oSheet = oDoc.createInstance("com.sun.star.sheet.Spreadsheet")
oDoc.Sheets.insertByName("Stock1", oSheet)
REM 取得試算表分頁
oSheet = oDoc.Sheets.getByName("Stock1")
REM 取得第幾個試算表分頁
REM oSheet = oDoc.Sheets(0)

oCell = oSheet.getCellByPosition (0,0)
oCell.String = "我的第一個Input"
End Sub


如下圖:

5. 執行
將游標移到「Sub Main」,接著點擊「執行」按鈕

6. 執行結果
執行後,會發現新開了一個新的Calc試算表視窗,如下圖:

這個新的試算表視窗,就是透過剛剛的巨集(Macro)程式建立的,
而其中可以注意到,它會多一個叫做「Stock1」的試算表分頁,
這也是剛剛巨集(Macro)程式產生的。

接著我們點擊切換到Stock1分頁,如下圖:

我們可以發現,在「A1」這個 Cell 當中,會顯示「我的第一個Input」,
BINGO,這也是我們剛剛寫在巨集(Macro)裡面的程式碼。

至此,我們整個巨集(Macro)的開發流程就很確定了。

接著,可以出個作業自己玩玩看,
用單步執行的方式,把剛剛的巨集(Macro)程式執行一次,
搭配程式碼的註解來看看,可以對整個程式內容更有感覺。