2011年7月27日 星期三
2011年7月25日 星期一
用CSV 分隔字元當格式當EDI交換檔案的注意事項
1. CSV 基本上每種程式語言幾乎都有物件直接支持這種格式的轉換, 或是一般grid 物件都會有這種格式支持, 請盡量使用物件去產生,不要自己組字串, 因為CSV 不是只有單純用逗號分開而已, 還有很多特殊狀況要處理, 例如資料本身有逗號, 雙引號, 等….
2. 換行字元也是CSV 要處理的問題之一, 一定要確認不能在產生的資料中有換行字元
3. 一樣不能處理Binary 字元
4. CSV 也像txt 一般, 需要確認檔案編碼格式 ( UTF-8 or ansi)
2. 換行字元也是CSV 要處理的問題之一, 一定要確認不能在產生的資料中有換行字元
3. 一樣不能處理Binary 字元
4. CSV 也像txt 一般, 需要確認檔案編碼格式 ( UTF-8 or ansi)
用TXT 固定位置的格式當EDI交換檔案的注意事項
1. 中文, 雙字元絕對是這種格式的致命傷, 測試溝通時一定要參入雙字元去測試,因為不同開發平台在計算單字元字串長度和雙字元字串長度實是可能會結果不同的, 一定要注意計算字串長度的計算方式雙方有共識
2. 換行字元處理, 用固定長度格式即表示不支持換行字元, 所有字串都要處理掉換行字元
3. 檔案編碼, 用txt 做資料交換的大部分都是早期開發的規格, 9 成9都是用ansi ,但不是必然的, 這點也是要注意到
4. 不能交換BINARY 格式檔案, 應該也沒人這麼離譜把Binary 字元塞在txt 檔中交換
2. 換行字元處理, 用固定長度格式即表示不支持換行字元, 所有字串都要處理掉換行字元
3. 檔案編碼, 用txt 做資料交換的大部分都是早期開發的規格, 9 成9都是用ansi ,但不是必然的, 這點也是要注意到
4. 不能交換BINARY 格式檔案, 應該也沒人這麼離譜把Binary 字元塞在txt 檔中交換
用XML 當交換格式的時候須注意的
1. 雙方編碼格式要一致, 這行 在xml 中雖然可以省略, 但是如果拿XML來做資料交換時, 這行就不能省略, 不然xml 解析器會用預設語系解析, 遇到有中文或是其他unicode 的時候就會錯誤
2. 特殊字元處理 , 所以字串欄位都需要先通過特殊字元處理
< 小於
<
> 大於 >
& &
' 單引號 '
" 雙引號 "
3. Xml 中特殊欄位 CDATA , 在這中間的文字是xml 解析器不處理的, 換句話說, 這欄位中的資料不用經過上面說的特殊字元處理, 這適合拿來交換大文字字串用, 因為用browser 開啟資料觀看時, 這部分資料的換行字元會顯示在畫面上, 相對的, 如果是用一般tag 處理的文字字串, 換行字元在browser 上顯示不出來, 但要注意用CDATA 也不是沒風險的, 如果資料內容包含 ]]> 就會錯誤了
4. 不要試圖交換binary 型別的資料, 如果一定要換這種資料, 那收/送雙方約定好用base64 decode/encode 編碼是一種處理方式
5. Xml 組好後要用browser 檢查過 , 看是否能正確顯示, 並用notepad 開啟另存新檔檢查看看編碼是否正確(是UTF-8 or ANSI)
6. 用notepad 另存UTF-8新檔產生的UTF-8 檔案, 和用程式直接產生的前面會多3碼檔案控制碼, “EF BB BF” ,這檔案控制碼在notepad 中看不到, browser 中也看不到, 用ultraEdit 以binary 型式顯示時才會發現, 做EDI 的雙方溝通debug 時一定要注意這件事, 不然有可能會出現大家都找不到錯誤的狀況, 這檔案控制碼不同編碼寫法不一樣,我只舉UTF-8 為例
7. XML 解析器共同的問題就是 大型檔案, 這邊說的大型檔案指 4mb 以上的檔案, 大部分解析器效率隨檔案大小以幾何級數曲線上升, 很多解析器到4mb 已經變很慢了, 有些甚至乾脆不支援4mb 以上的, 這點要注意, 解決方法也很簡單, 自己寫解析器把檔案拆小就可以, 因為這麼大的檔案, 通常是系統組成的, 有固定規律可拆
2. 特殊字元處理 , 所以字串欄位都需要先通過特殊字元處理
< 小於
<
> 大於 >
& &
' 單引號 '
" 雙引號 "
3. Xml 中特殊欄位 CDATA , 在這中間的文字是xml 解析器不處理的, 換句話說, 這欄位中的資料不用經過上面說的特殊字元處理, 這適合拿來交換大文字字串用, 因為用browser 開啟資料觀看時, 這部分資料的換行字元會顯示在畫面上, 相對的, 如果是用一般tag 處理的文字字串, 換行字元在browser 上顯示不出來, 但要注意用CDATA 也不是沒風險的, 如果資料內容包含 ]]> 就會錯誤了
4. 不要試圖交換binary 型別的資料, 如果一定要換這種資料, 那收/送雙方約定好用base64 decode/encode 編碼是一種處理方式
5. Xml 組好後要用browser 檢查過 , 看是否能正確顯示, 並用notepad 開啟另存新檔檢查看看編碼是否正確(是UTF-8 or ANSI)
6. 用notepad 另存UTF-8新檔產生的UTF-8 檔案, 和用程式直接產生的前面會多3碼檔案控制碼, “EF BB BF” ,這檔案控制碼在notepad 中看不到, browser 中也看不到, 用ultraEdit 以binary 型式顯示時才會發現, 做EDI 的雙方溝通debug 時一定要注意這件事, 不然有可能會出現大家都找不到錯誤的狀況, 這檔案控制碼不同編碼寫法不一樣,我只舉UTF-8 為例
7. XML 解析器共同的問題就是 大型檔案, 這邊說的大型檔案指 4mb 以上的檔案, 大部分解析器效率隨檔案大小以幾何級數曲線上升, 很多解析器到4mb 已經變很慢了, 有些甚至乾脆不支援4mb 以上的, 這點要注意, 解決方法也很簡單, 自己寫解析器把檔案拆小就可以, 因為這麼大的檔案, 通常是系統組成的, 有固定規律可拆
2011年7月22日 星期五
關於用FTP當EDI通訊工具時的注意事項
1. 交換檔案備份, 不論收或是送, 在檔案交換的時候一定要留一個備份檔, 尤其當FTP主機端是在我們掌控的時候一定要要求產生或接收後把檔案放到\BAK 路徑下, 由於FTP 在大量檔案堆在同一路徑時會造成反應很慢的問題, 所以備份檔案最好能按年月放到特定資料夾下, 這樣在EDI測試的過程或是後續追查問題的時後對雙方而言都有很大的方便性
2. 因為FTP上檔案搬來搬去會看不出來檔案產生的時間, FTP檔名在制定時最好加入時間註記, 例如 OE_OEHKS11070735_20110707153618.xml
3. FTP 檔案傳送過程有可能會和對方接收讀取檔案時間交會的話, 要注意避免讀到不完全檔案的問題, 由於檔案上傳時, 一旦開始上傳,主機端就會產生檔案, 這時剛好主機端開始接收檔案時就會讀取到空檔 .這種問題兩個簡單的解決方案, 一是錯開讀取與上傳的時間, 如果上傳時間為不特定的話, 就要採取另一個方案...產生ack 檔 , 也就是讀取指示檔
例如
OE_OEHKS11070735_20110707153618.txt 45k
OE_OEHKS11070735_20110707153618.ack 0k
這種ack檔放個空檔就可以, 對讀取檔案的程式而言, 看到ack 檔才表示這個檔案已經傳送完成可以讀取
這問題一定要注意, 不然就等於一個不定時炸彈, 不知何時就會跑出奇怪的錯誤
2. 因為FTP上檔案搬來搬去會看不出來檔案產生的時間, FTP檔名在制定時最好加入時間註記, 例如 OE_OEHKS11070735_20110707153618.xml
3. FTP 檔案傳送過程有可能會和對方接收讀取檔案時間交會的話, 要注意避免讀到不完全檔案的問題, 由於檔案上傳時, 一旦開始上傳,主機端就會產生檔案, 這時剛好主機端開始接收檔案時就會讀取到空檔 .這種問題兩個簡單的解決方案, 一是錯開讀取與上傳的時間, 如果上傳時間為不特定的話, 就要採取另一個方案...產生ack 檔 , 也就是讀取指示檔
例如
OE_OEHKS11070735_20110707153618.txt 45k
OE_OEHKS11070735_20110707153618.ack 0k
這種ack檔放個空檔就可以, 對讀取檔案的程式而言, 看到ack 檔才表示這個檔案已經傳送完成可以讀取
這問題一定要注意, 不然就等於一個不定時炸彈, 不知何時就會跑出奇怪的錯誤
2011年7月21日 星期四
程式結合excel 樞紐分析
要利用Excel 樞紐分析及樞紐分析圖的工具來接到數據可以用Excel 外接資料功能, 可以建立一個excel 樞紐分析, 但是資料來源是外部資料, 外部資料可以有機種模式 txt , excel , DB , XML ...等, excel 引用時有許多的選項, 但是我沒試出txt , xml 要如何使用因為不知怎樣的格式可以符合, 而且我希望可以直接利用cxGrid 元件匯出功能,就直接接到excel 報表, 所以採用外部資料是另一個excel 檔案的方式, 將來或許可以測試轉出為資料庫(access)的方式,這也許也是個不錯的選擇
外部資料為excel 具體方式如下, 先建立一個要分析資料用的excel A 當做資料來源, 然後建立另外一個excel B 做樞紐分析圖表, 只不過B 的資料來源是引用A, 再來的部分就比較簡單了, 利用程式把要被分析的資料匯出成A , 然後程式直接呼叫excel B 開啟就可以看到樞紐分析圖表了
沒錯,說起來挺快的, 不過這中間還有幾個問題要處理
首先, 當 B 被開啟時並不會刷新從A讀取的資料, 而是顯示最後一次使用的資料, 所以需要一個刷新資料的方式, 很顯然需要在excel 開啟的同時去執行"重新整理"這個按鈕, 這裡我想到的解決方式是用巨集去執行"重新整理"這個按鈕, 但是巨集如何在開啟時更新呢? 很簡單,只要把巨集命名為Auto_Open, 這個巨集便會在開啟時自動執行.
其次, 解決了excel B 的問題後, 還有A的問題, 由於A的資料室是每次都要重新匯出的, 匯出最快就是把A 砍掉在重新匯出另一個A, 但是由於B裡面引用資料路徑是固定寫在excel B 裡面的, 所以檔A的名稱和路徑是不能隨意變的, 這會導致同一個時間只能有一個A 存在, 也就是不能同時開啟兩個圖表B, 這目前並沒測出好的解決方式, 只能暫時這樣處理
最後,版本和自動巨集EXCEL安全性問題, 由於自動巨集需要安全性確認, 所以第一次執行時會跳出詢問訊息, 這是excel 安全管理, 這也是沒辦法的事
關於這套做法好處是, 用excel 樞紐分析當圖表工具是成本最低的, 不但很多人會製作和使用, 製作的速度也挺快的,基本上幾分鐘就能做出一個分析圖表, 隨著excel 版本不斷更新,樞紐分析圖表工具也越來越人性化, 功能越來越強大, 能夠借這工具力氣來做資料分析而不用自己去開發圖表, 感覺實在太好了
外部資料為excel 具體方式如下, 先建立一個要分析資料用的excel A 當做資料來源, 然後建立另外一個excel B 做樞紐分析圖表, 只不過B 的資料來源是引用A, 再來的部分就比較簡單了, 利用程式把要被分析的資料匯出成A , 然後程式直接呼叫excel B 開啟就可以看到樞紐分析圖表了
沒錯,說起來挺快的, 不過這中間還有幾個問題要處理
首先, 當 B 被開啟時並不會刷新從A讀取的資料, 而是顯示最後一次使用的資料, 所以需要一個刷新資料的方式, 很顯然需要在excel 開啟的同時去執行"重新整理"這個按鈕, 這裡我想到的解決方式是用巨集去執行"重新整理"這個按鈕, 但是巨集如何在開啟時更新呢? 很簡單,只要把巨集命名為Auto_Open, 這個巨集便會在開啟時自動執行.
其次, 解決了excel B 的問題後, 還有A的問題, 由於A的資料室是每次都要重新匯出的, 匯出最快就是把A 砍掉在重新匯出另一個A, 但是由於B裡面引用資料路徑是固定寫在excel B 裡面的, 所以檔A的名稱和路徑是不能隨意變的, 這會導致同一個時間只能有一個A 存在, 也就是不能同時開啟兩個圖表B, 這目前並沒測出好的解決方式, 只能暫時這樣處理
最後,版本和自動巨集EXCEL安全性問題, 由於自動巨集需要安全性確認, 所以第一次執行時會跳出詢問訊息, 這是excel 安全管理, 這也是沒辦法的事
關於這套做法好處是, 用excel 樞紐分析當圖表工具是成本最低的, 不但很多人會製作和使用, 製作的速度也挺快的,基本上幾分鐘就能做出一個分析圖表, 隨著excel 版本不斷更新,樞紐分析圖表工具也越來越人性化, 功能越來越強大, 能夠借這工具力氣來做資料分析而不用自己去開發圖表, 感覺實在太好了
2011年7月11日 星期一
oracle date format
SYSDATE
2 --◎ 可得到目前系統的時間
3
4 ex.
5 select sysdate from dual;
6
7 sysdate
8 ----------
9 20-SEP-07
10
11 常用之日期格式
12
13 日期格式 說明
14 ------------------------------------------------------------------------
15 YYYY/MM/DD -- 年/月/日
16 YYYY -- 年(4位)
17 YYY -- 年(3位)
18 YY -- 年(2位)
19 MM -- 月份
20 DD -- 日期
21 D -- 星期
22 -- 星期日 = 1 星期一 = 2 星期二 = 3
23 -- 星期三 = 4 星期四 = 5 星期五 = 6 星期六 = 7
24
25 DDD -- 一年之第幾天
26 WW -- 一年之第幾週
27 W -- 一月之第幾週
28 YYYY/MM/DD HH24:MI:SS -- 年/月/日 時(24小時制):分:秒
29 YYYY/MM/DD HH:MI:SS -- 年/月/日 時(非24小時制):分:秒
30 J -- Julian day,Bc 4712/01/01 為1
31 RR/MM/DD -- 公元2000問題
32 -- 00-49 = 下世紀;50-99 = 本世紀
33 ex.
34 select to_char(sysdate,'YYYY/MM/DD') FROM DUAL; -- 2007/09/20
35 select to_char(sysdate,'YYYY') FROM DUAL; -- 2007
36 select to_char(sysdate,'YYY') FROM DUAL; -- 007
37 select to_char(sysdate,'YY') FROM DUAL; -- 07
38 select to_char(sysdate,'MM') FROM DUAL; -- 09
39 select to_char(sysdate,'DD') FROM DUAL; -- 20
40 select to_char(sysdate,'D') FROM DUAL; -- 5
41 select to_char(sysdate,'DDD') FROM DUAL; -- 263
42 select to_char(sysdate,'WW') FROM DUAL; -- 38
43 select to_char(sysdate,'W') FROM DUAL; -- 3
44 select to_char(sysdate,'YYYY/MM/DD HH24:MI:SS') FROM DUAL; -- 2007/09/20 15:24:13
45 select to_char(sysdate,'YYYY/MM/DD HH:MI:SS') FROM DUAL; -- 2007/09/20 03:25:23
46 select to_char(sysdate,'J') FROM DUAL; -- 2454364
47 select to_char(sysdate,'RR/MM/DD') FROM DUAL; -- 07/09/20
2 --◎ 可得到目前系統的時間
3
4 ex.
5 select sysdate from dual;
6
7 sysdate
8 ----------
9 20-SEP-07
10
11 常用之日期格式
12
13 日期格式 說明
14 ------------------------------------------------------------------------
15 YYYY/MM/DD -- 年/月/日
16 YYYY -- 年(4位)
17 YYY -- 年(3位)
18 YY -- 年(2位)
19 MM -- 月份
20 DD -- 日期
21 D -- 星期
22 -- 星期日 = 1 星期一 = 2 星期二 = 3
23 -- 星期三 = 4 星期四 = 5 星期五 = 6 星期六 = 7
24
25 DDD -- 一年之第幾天
26 WW -- 一年之第幾週
27 W -- 一月之第幾週
28 YYYY/MM/DD HH24:MI:SS -- 年/月/日 時(24小時制):分:秒
29 YYYY/MM/DD HH:MI:SS -- 年/月/日 時(非24小時制):分:秒
30 J -- Julian day,Bc 4712/01/01 為1
31 RR/MM/DD -- 公元2000問題
32 -- 00-49 = 下世紀;50-99 = 本世紀
33 ex.
34 select to_char(sysdate,'YYYY/MM/DD') FROM DUAL; -- 2007/09/20
35 select to_char(sysdate,'YYYY') FROM DUAL; -- 2007
36 select to_char(sysdate,'YYY') FROM DUAL; -- 007
37 select to_char(sysdate,'YY') FROM DUAL; -- 07
38 select to_char(sysdate,'MM') FROM DUAL; -- 09
39 select to_char(sysdate,'DD') FROM DUAL; -- 20
40 select to_char(sysdate,'D') FROM DUAL; -- 5
41 select to_char(sysdate,'DDD') FROM DUAL; -- 263
42 select to_char(sysdate,'WW') FROM DUAL; -- 38
43 select to_char(sysdate,'W') FROM DUAL; -- 3
44 select to_char(sysdate,'YYYY/MM/DD HH24:MI:SS') FROM DUAL; -- 2007/09/20 15:24:13
45 select to_char(sysdate,'YYYY/MM/DD HH:MI:SS') FROM DUAL; -- 2007/09/20 03:25:23
46 select to_char(sysdate,'J') FROM DUAL; -- 2454364
47 select to_char(sysdate,'RR/MM/DD') FROM DUAL; -- 07/09/20
2011年5月27日 星期五
2011年5月20日 星期五
How do I determine if a table has a primary key
Question: How do I determine if a table has a primary key and if it has one, how do I determine what columns are in the primary key?
Answer: You can retrieve primary key information with the following SQL statement:
SELECT cols.table_name, cols.column_name, cols.position, cons.status, cons.owner
FROM all_constraints cons, all_cons_columns cols
WHERE cons.constraint_type = 'P'
AND cons.constraint_name = cols.constraint_name
AND cons.owner = cols.owner
ORDER BY cols.table_name, cols.position;
If you knew the table name that you were looking for, you could modify the SQL as follows:
SELECT cols.table_name, cols.column_name, cols.position, cons.status, cons.owner
FROM all_constraints cons, all_cons_columns cols
WHERE cols.table_name = 'TABLE_NAME'
AND cons.constraint_type = 'P'
AND cons.constraint_name = cols.constraint_name
AND cons.owner = cols.owner
ORDER BY cols.table_name, cols.position;
Answer: You can retrieve primary key information with the following SQL statement:
SELECT cols.table_name, cols.column_name, cols.position, cons.status, cons.owner
FROM all_constraints cons, all_cons_columns cols
WHERE cons.constraint_type = 'P'
AND cons.constraint_name = cols.constraint_name
AND cons.owner = cols.owner
ORDER BY cols.table_name, cols.position;
If you knew the table name that you were looking for, you could modify the SQL as follows:
SELECT cols.table_name, cols.column_name, cols.position, cons.status, cons.owner
FROM all_constraints cons, all_cons_columns cols
WHERE cols.table_name = 'TABLE_NAME'
AND cons.constraint_type = 'P'
AND cons.constraint_name = cols.constraint_name
AND cons.owner = cols.owner
ORDER BY cols.table_name, cols.position;
2011年3月22日 星期二
CR9 該死的錯誤
Crystal report 在使用 Cross-tab 的時候, 裡面統計資料可以使用 % 方式做統計 ,但使用百分比方式做統計的時後, 萬一統計資料值加總= 0 會產生問題(沒任何錯誤訊息) 就直接卡在資料筆數都跑完後的白色畫面, 資料跑不出來,也結束不了 , 這是CRYSTAL REPORT 裏面本身的function 錯誤, 不是user 撰寫的fomula 錯誤, 所以不會有任何錯誤提示或警告....
解決方式 : 把被統計的資料比如說 Amount 則寫 IF (AMOUNT) = THEN 0.00001 ELSE AMOUNT ,用一個極小值代替避過 除 0公式問題
解決方式 : 把被統計的資料比如說 Amount 則寫 IF (AMOUNT) = THEN 0.00001 ELSE AMOUNT ,用一個極小值代替避過 除 0公式問題
2011年3月1日 星期二
日期元件只顯示"星"的問題
使DevExpress日期控件正确显示
TdxGridDatePopup是DevExpress组件中日期显示的一个组件,DevExperss是一个很强大的控件,但在中文Windows中,日期控件会出现一个问
题:无论星期几都只是显示“星”字。
原因:
出现这个问题并不是DevExpress公司的程序代码有问题,只是不同的语言版本中,系统提供的日期函数中返回的格式或文字有所不同。
DevExpress公司是用ShortDayNames数组取得星期几的。
ShortDayNames: array[1..7] of string;
ShortDayNames是一个String数组,共有七个元素,分别对应星期一到七的字符串,在英文Windows中,它的值为[‘Sunday’,‘Monday’...],在中
文Windows中,它的值为[‘星期一‘,‘星期二‘...]。
DevExpress是想返回英文的第一个字母,如Sunday,返回的是S,所以她用了S := {$IFDEF
DELPHI3}WideString{$ENDIF}(ShortDayNames[J])[1]来取得,但在中文Windows中,就会返回”星“,问题就出在这里。
修改方法:
打开{Programe Files}Developer Express IncExpressInplaceEditorsDelphi 5SourcedxGrDate.pas,查找
S := {$IFDEF DELPHI3}WideString{$ENDIF}(ShortDayNames[J])[1],
然后修改为
S := {$IFDEF DELPHI3}WideString{$ENDIF}(ShortDayNames[J])[3]。
重新编译dxGrDate.pas(你可以把dxGrDate.pas加到一个Project中,重新编译你的Project,dxGrDate.pas就会重新编译),然后把相关的dxGrDate.Dcu复制到..\LIB下。
问题就会解决了。
TdxGridDatePopup是DevExpress组件中日期显示的一个组件,DevExperss是一个很强大的控件,但在中文Windows中,日期控件会出现一个问
题:无论星期几都只是显示“星”字。
原因:
出现这个问题并不是DevExpress公司的程序代码有问题,只是不同的语言版本中,系统提供的日期函数中返回的格式或文字有所不同。
DevExpress公司是用ShortDayNames数组取得星期几的。
ShortDayNames: array[1..7] of string;
ShortDayNames是一个String数组,共有七个元素,分别对应星期一到七的字符串,在英文Windows中,它的值为[‘Sunday’,‘Monday’...],在中
文Windows中,它的值为[‘星期一‘,‘星期二‘...]。
DevExpress是想返回英文的第一个字母,如Sunday,返回的是S,所以她用了S := {$IFDEF
DELPHI3}WideString{$ENDIF}(ShortDayNames[J])[1]来取得,但在中文Windows中,就会返回”星“,问题就出在这里。
修改方法:
打开{Programe Files}Developer Express IncExpressInplaceEditorsDelphi 5SourcedxGrDate.pas,查找
S := {$IFDEF DELPHI3}WideString{$ENDIF}(ShortDayNames[J])[1],
然后修改为
S := {$IFDEF DELPHI3}WideString{$ENDIF}(ShortDayNames[J])[3]。
重新编译dxGrDate.pas(你可以把dxGrDate.pas加到一个Project中,重新编译你的Project,dxGrDate.pas就会重新编译),然后把相关的dxGrDate.Dcu复制到..\LIB下。
问题就会解决了。
2010年12月10日 星期五
oracle 語法 minus 和 over
minus Oracle 查詢差異的語法 , 比較兩個資料集的差異 例如 select * from table where rownum < 75 minus ( select * from table where rownum < 65) 就可以選出 65-75 之間的資料
over 可以求總合, 使用時機有點妙 (參考文章)
http://www.cnblogs.com/liguiqing/archive/2007/11/20/966003.html
select deptno,ename,sal,
2 sum(sal) over (order by ename) 连续求和,
3 sum(sal) over () 总和, -- 此处sum(sal) over () 等同于sum(sal)
4 100*round(sal/sum(sal) over (),4) "份额(%)"
5 from emp
6 /
DEPTNO ENAME SAL 连续求和 总和 份额(%)
---------- ---------- ---------- ---------- ---------- ----------
20 ADAMS 1100 1100 29025 3.79
30 ALLEN 1600 2700 29025 5.51
30 BLAKE 2850 5550 29025 9.82
10 CLARK 2450 8000 29025 8.44
20 FORD 3000 11000 29025 10.34
30 JAMES 950 11950 29025 3.27
20 JONES 2975 14925 29025 10.25
10 KING 5000 19925 29025 17.23
30 MARTIN 1250 21175 29025 4.31
10 MILLER 1300 22475 29025 4.48
20 SCOTT 3000 25475 29025 10.34
20 SMITH 800 26275 29025 2.76
30 TURNER 1500 27775 29025 5.17
30 WARD 1250 29025 29025 4.31
over 可以求總合, 使用時機有點妙 (參考文章)
http://www.cnblogs.com/liguiqing/archive/2007/11/20/966003.html
select deptno,ename,sal,
2 sum(sal) over (order by ename) 连续求和,
3 sum(sal) over () 总和, -- 此处sum(sal) over () 等同于sum(sal)
4 100*round(sal/sum(sal) over (),4) "份额(%)"
5 from emp
6 /
DEPTNO ENAME SAL 连续求和 总和 份额(%)
---------- ---------- ---------- ---------- ---------- ----------
20 ADAMS 1100 1100 29025 3.79
30 ALLEN 1600 2700 29025 5.51
30 BLAKE 2850 5550 29025 9.82
10 CLARK 2450 8000 29025 8.44
20 FORD 3000 11000 29025 10.34
30 JAMES 950 11950 29025 3.27
20 JONES 2975 14925 29025 10.25
10 KING 5000 19925 29025 17.23
30 MARTIN 1250 21175 29025 4.31
10 MILLER 1300 22475 29025 4.48
20 SCOTT 3000 25475 29025 10.34
20 SMITH 800 26275 29025 2.76
30 TURNER 1500 27775 29025 5.17
30 WARD 1250 29025 29025 4.31
2009年10月13日 星期二
java double buffer 作法
來源
http://www.realapplets.com/tutorial/DoubleBuffering.html
讚
/* Drawing in applets is almost always done with double-buffering.
This means that drawing is first done to an offscreen image, and when all
is done, the offscreen image is drawn on the screen.
This reduces the nasty flickering applets otherwise have.
Above you see:
No Double-buffering : It flickers because everything is draw straight to the screen.
Bad double-buffering: Same as this below but without the update() method
Double Buffering: Example of this source.
*/
import java.applet.*;
import java.awt.event.*;
import java.awt.*;
public class DoubleBuffering extends Applet implements MouseMotionListener
{
// The object we will use to write with instead of the standard screen graphics
Graphics bufferGraphics;
// The image that will contain everything that has been drawn on
// bufferGraphics.
Image offscreen;
// To get the width and height of the applet.
Dimension dim;
int curX, curY;
public void init()
{
// We'll ask the width and height by this
dim = getSize();
// We'll redraw the applet eacht time the mouse has moved.
addMouseMotionListener(this);
setBackground(Color.black);
// Create an offscreen image to draw on
// Make it the size of the applet, this is just perfect larger
// size could slow it down unnecessary.
offscreen = createImage(dim.width,dim.height);
// by doing this everything that is drawn by bufferGraphics
// will be written on the offscreen image.
bufferGraphics = offscreen.getGraphics();
}
public void paint(Graphics g)
{
// Wipe off everything that has been drawn before
// Otherwise previous drawings would also be displayed.
bufferGraphics.clearRect(0,0,dim.width,dim.width);
bufferGraphics.setColor(Color.red);
bufferGraphics.drawString("Bad Double-buffered",10,10);
// draw the rect at the current mouse position
// to the offscreen image
bufferGraphics.fillRect(curX,curY,20,20);
// draw the offscreen image to the screen like a normal image.
// Since offscreen is the screen width we start at 0,0.
g.drawImage(offscreen,0,0,this);
}
// Always required for good double-buffering.
// This will cause the applet not to first wipe off
// previous drawings but to immediately repaint.
// the wiping off also causes flickering.
// Update is called automatically when repaint() is called.
public void update(Graphics g)
{
paint(g);
}
// Save the current mouse position to paint a rectangle there.
// and request a repaint()
public void mouseMoved(MouseEvent evt)
{
curX = evt.getX();
curY = evt.getY();
repaint();
}
// The necessary methods.
public void mouseDragged(MouseEvent evt)
{
}
}
/*
This is all about double-buffering. It's easy to use and recommended to use always.
There is one dangerous pitfall here, when you create an offscreen image that's very large
the applet might run slow because it takes a lot of resources and effort.
I would not recommend offscreen images larger than 500*500 when redrawn at 30FPS.
(see Threads)
*/
http://www.realapplets.com/tutorial/DoubleBuffering.html
讚
/* Drawing in applets is almost always done with double-buffering.
This means that drawing is first done to an offscreen image, and when all
is done, the offscreen image is drawn on the screen.
This reduces the nasty flickering applets otherwise have.
Above you see:
No Double-buffering : It flickers because everything is draw straight to the screen.
Bad double-buffering: Same as this below but without the update() method
Double Buffering: Example of this source.
*/
import java.applet.*;
import java.awt.event.*;
import java.awt.*;
public class DoubleBuffering extends Applet implements MouseMotionListener
{
// The object we will use to write with instead of the standard screen graphics
Graphics bufferGraphics;
// The image that will contain everything that has been drawn on
// bufferGraphics.
Image offscreen;
// To get the width and height of the applet.
Dimension dim;
int curX, curY;
public void init()
{
// We'll ask the width and height by this
dim = getSize();
// We'll redraw the applet eacht time the mouse has moved.
addMouseMotionListener(this);
setBackground(Color.black);
// Create an offscreen image to draw on
// Make it the size of the applet, this is just perfect larger
// size could slow it down unnecessary.
offscreen = createImage(dim.width,dim.height);
// by doing this everything that is drawn by bufferGraphics
// will be written on the offscreen image.
bufferGraphics = offscreen.getGraphics();
}
public void paint(Graphics g)
{
// Wipe off everything that has been drawn before
// Otherwise previous drawings would also be displayed.
bufferGraphics.clearRect(0,0,dim.width,dim.width);
bufferGraphics.setColor(Color.red);
bufferGraphics.drawString("Bad Double-buffered",10,10);
// draw the rect at the current mouse position
// to the offscreen image
bufferGraphics.fillRect(curX,curY,20,20);
// draw the offscreen image to the screen like a normal image.
// Since offscreen is the screen width we start at 0,0.
g.drawImage(offscreen,0,0,this);
}
// Always required for good double-buffering.
// This will cause the applet not to first wipe off
// previous drawings but to immediately repaint.
// the wiping off also causes flickering.
// Update is called automatically when repaint() is called.
public void update(Graphics g)
{
paint(g);
}
// Save the current mouse position to paint a rectangle there.
// and request a repaint()
public void mouseMoved(MouseEvent evt)
{
curX = evt.getX();
curY = evt.getY();
repaint();
}
// The necessary methods.
public void mouseDragged(MouseEvent evt)
{
}
}
/*
This is all about double-buffering. It's easy to use and recommended to use always.
There is one dangerous pitfall here, when you create an offscreen image that's very large
the applet might run slow because it takes a lot of resources and effort.
I would not recommend offscreen images larger than 500*500 when redrawn at 30FPS.
(see Threads)
*/
2009年10月6日 星期二
java 載入圖檔方式
import java.awt.*;
import java.awt.event.*;
import java.awt.image.renderable.ParameterBlock;
import java.io.File;
import javax.media.jai.JAI;
import javax.media.jai.PlanarImage;
import javax.media.jai.RenderedOp;
import javax.media.jai.widget.ScrollingImagePanel;
public class FileTest extends WindowContainer {
// Specify a default image in case the user fails to specify
// one at run time.
public static final String DEFAULT_FILE = "./images/glasses.jpg";
public static void main(String args[]) {
String fileName = null;
// Check for a filename in the argument.
if(args.length == 0) {
fileName = DEFAULT_FILE;
} else if(args.length == 1) {
fileName = args[0];
} else {
System.out.println("\nUsage: java " + (new FileTest()).getClass().getName() + " [file]\n");
System.exit(0);
}
new FileTest(fileName);
}
public FileTest() {}
public FileTest(String fileName) {
// Read the image from the designated path.
System.out.println("Creating operation to load image from '" + fileName + "'");
RenderedOp img = JAI.create("fileload", fileName);
// Set display name and layout.
setTitle(getClass().getName()+": "+fileName);
// Display the image.
System.out.println("Displaying image");
add(new ScrollingImagePanel(img, img.getWidth(), img.getHeight()));
pack();
show();
}
}
class WindowContainer extends Frame implements WindowListener {
public WindowContainer () {
this.addWindowListener(this);
}
public void windowClosing(WindowEvent e) {
System.exit(0);
}
public void windowOpened(WindowEvent e) {}
public void windowClosed(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowActivated(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) {}
}
jpeg 轉 bmp方法
procedure Bmp2Jpeg(const BmpFileName, JpgFileName: string);
var
Bmp: TBitmap;
Jpg: TJPEGImage;
begin
Bmp := TBitmap.Create;
Jpg := TJPEGImage.Create;
try
Bmp.LoadFromFile(BmpFileName);
Jpg.Assign(Bmp);
Jpg.SaveToFile(JpgFileName);
finally
Jpg.Free;
Bmp.Free;
end;
end;
procedure Jpeg2Bmp(const BmpFileName, JpgFileName: string);
var
Bmp: TBitmap;
Jpg: TJPEGImage;
begin
Bmp := TBitmap.Create;
Jpg := TJPEGImage.Create;
try
Jpg.LoadFromFile(JpgFileName);
Bmp.Assign(Jpg);
Bmp.SaveToFile(BmpFileName);
finally
Jpg.Free;
Bmp.Free;
end;
end;
var
Bmp: TBitmap;
Jpg: TJPEGImage;
begin
Bmp := TBitmap.Create;
Jpg := TJPEGImage.Create;
try
Bmp.LoadFromFile(BmpFileName);
Jpg.Assign(Bmp);
Jpg.SaveToFile(JpgFileName);
finally
Jpg.Free;
Bmp.Free;
end;
end;
procedure Jpeg2Bmp(const BmpFileName, JpgFileName: string);
var
Bmp: TBitmap;
Jpg: TJPEGImage;
begin
Bmp := TBitmap.Create;
Jpg := TJPEGImage.Create;
try
Jpg.LoadFromFile(JpgFileName);
Bmp.Assign(Jpg);
Bmp.SaveToFile(BmpFileName);
finally
Jpg.Free;
Bmp.Free;
end;
end;
2009年9月11日 星期五
2009年8月24日 星期一
有關function節省編譯後空間? 真的有效嗎?沒試過
http://delphi.ktop.com.tw/board.php?cid=30&fid=70&tid=99044
1.type TDataProvider=class
2.private:
3. procedure _AppendData(SKey : String; SName : String; SValue1 : integer; SValue2 : String);
4.public:
5. procedure AppendData(SKey :String; SName : String);
6. procedure AppendData(SKey : String; SName : String; SValue2 : String);
7.end;
8.
9.//implementation;
10.
11.procedure TDataProvider._AppendData(SKey : String; SName : String; SValue1 : integer; SValue2 : String);
12.begin
13.//優先處理會被省略的參數
14.//原先的函式本體
15.end;
16.
17.procedure TDataProvider.AppendData(SKey : String; SName : String);
18.begin
19.self._AppendData(SKey, SName, nil, -1, nil);
20.end;
21.
22.procedure TDataProvider.AppendData(SKey : String; SName : String; SValue2 : String);
23.
24.begin
25.self._AppendData(SKey, SName, nil, -1, SValue2);
26.end;
1.type TDataProvider=class
2.private:
3. procedure _AppendData(SKey : String; SName : String; SValue1 : integer; SValue2 : String);
4.public:
5. procedure AppendData(SKey :String; SName : String);
6. procedure AppendData(SKey : String; SName : String; SValue2 : String);
7.end;
8.
9.//implementation;
10.
11.procedure TDataProvider._AppendData(SKey : String; SName : String; SValue1 : integer; SValue2 : String);
12.begin
13.//優先處理會被省略的參數
14.//原先的函式本體
15.end;
16.
17.procedure TDataProvider.AppendData(SKey : String; SName : String);
18.begin
19.self._AppendData(SKey, SName, nil, -1, nil);
20.end;
21.
22.procedure TDataProvider.AppendData(SKey : String; SName : String; SValue2 : String);
23.
24.begin
25.self._AppendData(SKey, SName, nil, -1, SValue2);
26.end;
ShellListView 選擇的檔案
procedure TForm1.ShellListView1MouseUp(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var i:integer;
begin
for i := 0 to ShellListView1.Items.Count-1 do
begin
if ShellListView1.Items[i].Selected then
ShowMessage(ShellListView1.Folders[i].PathName); // 這就是檔案全路徑
end;
end;
2009年8月20日 星期四
測試pas檔轉html 的功能
unit uMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,StrUtils;
const VK_RTN = chr(13)+ chr(10);
type
TMain = class(TForm)
Button1: TButton;
OpenDialog1: TOpenDialog;
Memo1: TMemo;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
ColorDialog1: TColorDialog;
procedure Button1Click(Sender: TObject);
procedure Label1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TmpStyle=(mpReservedWord, mpSymbol , mpString , mpComment ,mpSpace );
TDataSec=record
DataString:String;
Style:TmpStyle;
end;
TPasFile=Class
Data,FFileName:String;
protected
ReservedWordList:TStringList;
public
function EncodeToHtml:String;
constructor Create(FileName:string);
destructor Destroy;override;
End;
var
Main: TMain;
implementation
{$R *.dfm}
procedure TMain.Button1Click(Sender: TObject);
var o:TPasFile;
s:String;
begin
s := '中文實驗<>'' '' ';
if OpenDialog1.Execute then
begin
o := TPasFile.Create(OpenDialog1.FileName);
Memo1.Lines.Clear;
Memo1.Lines.Add(o.EncodeToHtml);
Memo1.Lines.SaveToFile('C:\a.html');
Application.ProcessMessages;
winexec('explorer.exe C:\a.html',SW_SHOW );
o.Free;
end;
end;
{ TPasFile }
constructor TPasFile.Create(FileName:string);
var sl:TStringList;
begin
sl :=TStringList.Create;
FFileName :=FileName;
sl.LoadFromFile(FileName);
Data := sl.Text;
sl.Free;
ReservedWordList := TStringList.Create;
ReservedWordList.Add('constructor');
ReservedWordList.Add('destructor');
ReservedWordList.Add('begin');
ReservedWordList.Add('inherited');
ReservedWordList.Add('end');
ReservedWordList.Add('var');
ReservedWordList.Add('Integer');
ReservedWordList.Add('string');
ReservedWordList.Add('procedure');
ReservedWordList.Add('function');
ReservedWordList.Add('protected');
ReservedWordList.Add('public');
ReservedWordList.Add('if');
ReservedWordList.Add('then');
ReservedWordList.Add('While');
ReservedWordList.Add('do');
ReservedWordList.Add('for');
ReservedWordList.Add('to');
ReservedWordList.Add('in');
ReservedWordList.Add('else');
ReservedWordList.Add('override');
ReservedWordList.Add('type');
ReservedWordList.Add('record');
ReservedWordList.Add('class');
ReservedWordList.Add('implementation');
ReservedWordList.Add('private');
ReservedWordList.Add('case');
ReservedWordList.Add('of');
ReservedWordList.Add('array');
ReservedWordList.Add('unit');
ReservedWordList.Add('interface');
ReservedWordList.Text := UpperCase( ReservedWordList.Text);
end;
destructor TPasFile.Destroy;
begin
ReservedWordList.Free;
inherited;
end;
function TPasFile.EncodeToHtml: String;
var
I,oldPos: Integer;
htmlStr,sHead,sFoot:string;
oDs:TDataSec;
function GotoStr(sa:array of string):integer;
var ii,j:integer;
begin
Result := Length(Data);
for j := (i+1) to Length(Data) do
for ii := Low(sa) to High(sa) do
if data[j]=sa[ii] then
begin
Result := j ;
exit;
end;
end;
function GotoNextComm:integer;
var j:integer;
begin
Result := Length(Data);
for j := (i+1) to Length(Data) do
if (data[j]='''')and(data[j+1]<>'''') then
begin
Result := j ;
exit;
end;
end;
procedure SetDataSec(S:String;style:TmpStyle);
begin
//處理關鍵字
if ReservedWordList.IndexOf( UpperCase(s)) <> -1 then
style := mpReservedWord;
//處理 html 不能使用的字
s:= StringReplace(s,'<','<',[rfReplaceAll] );
s:= StringReplace(s,'>','>',[rfReplaceAll] );
oDs.DataString := s;
oDs.Style := style;
end;
function HtmlColorStr(Color:TColor):String;
begin
Result := format('#%.2x%.2x%.2x',[GetRValue(Color)
,GetGValue(Color),GetBValue(Color) ]);
end;
begin
i := 1;
while i < Length(Data) do
begin
oldPos := i;
case Data[i] of
' ' : SetDataSec(' ',mpSpace) ;
'{' :
begin
i := GotoStr(['}']);
SetDataSec(Copy(Data,oldPos,i - oldPos +1),mpComment );
end;
'/' :
begin
if Data[i+1]='/' then
begin
i := GotoStr( [ chr(10)]);
SetDataSec(Copy(Data,oldPos,i - oldPos +1 ),mpComment );
end
else
SetDataSec(string( data[i]),mpSymbol );
end;
':','=',';','.','[',']','(',')',',',chr(13),chr(10):
begin
SetDataSec(string( data[i]),mpSymbol );
end;
'''':
begin
i := GotoNextComm;
SetDataSec(Copy(Data,oldPos,i - oldPos +1),mpString );
end;
else
begin
i := GotoStr([' ','{','/',chr(13),chr(10),':','=',';','.','[',']','(',')',',' ]);
SetDataSec(Copy(Data,oldPos,i - oldPos ),mpString );
dec(i);
end;
end;
// <font color=#ff0000><b></b></font> 紅
// <font color=#009900></font> 綠
// <font color=#7d0000> 咖啡色
if (ods.Style = mpReservedWord) and(Main.Label1.Font.Color<>clBlack)then
htmlStr := htmlStr +'<font color='+HtmlColorStr(Main.Label1.Font.Color)+'><b>' + ods.DataString +'</b></font>'
else if (ods.Style = mpComment) and(Main.Label2.Font.Color<>clBlack) then
htmlStr := htmlStr +'<font color='+HtmlColorStr(Main.Label2.Font.Color)+'>' + ods.DataString +'</font>'
else if (ods.Style = mpSymbol)and(Main.Label3.Font.Color<>clBlack) then
htmlStr := htmlStr +'<font color='+HtmlColorStr(Main.Label3.Font.Color)+'>' + ods.DataString +'</font>'
else if (Main.Label4.Font.Color<>clBlack) then
htmlStr := htmlStr +'<font color='+HtmlColorStr(Main.Label4.Font.Color)+'>' + ods.DataString +'</font>'
else
htmlStr := htmlStr + ods.DataString;
inc(i);
end;
sHead :=
'<html>' + VK_RTN +
'<head>' + VK_RTN +
'<meta http-equiv="Content-Type" content="text/html; charset=big5">' + VK_RTN +
'<title>'+FFileName+'</title>' + VK_RTN +
'</head>' + VK_RTN +
//'<body text="#000000" bgcolor="#FFFFFF" >'+ VK_RTN +
'<pre><code>' + VK_RTN ;
sFoot := VK_RTN +
'</code></pre>' + VK_RTN +
//'</body>' + VK_RTN +
'</html>' ;
Result := sHead + htmlStr + sFoot;
end;
procedure TMain.Label1Click(Sender: TObject);
begin
if ColorDialog1.Execute then
(Sender as TLabel).Font.Color := ColorDialog1.Color;
//Memo1.Text := ColorToString( ColorDialog1.Color );
// Memo1.Text := format('#%.2x%.2x%.2x',[GetRValue(ColorDialog1.Color)
// ,GetGValue(ColorDialog1.Color),GetBValue(ColorDialog1.Color) ]);
end;
end.
2009年5月20日 星期三
搖別人視窗是不好的事
var
hand:HWND;
r:TRect;
i:integer;
begin
hand := GetForegroundWindow;
GetWindowRect(hand , r );
for i := 0 to 4 do
begin
MoveWindow(hand,r.Left,r.Top -3,r.Right-r.Left,r.Bottom-r.Top,true ); sleep(40);
MoveWindow(hand,r.Left-3,r.Top ,r.Right-r.Left,r.Bottom-r.Top,true ); sleep(40);
MoveWindow(hand,r.Left,r.Top +3,r.Right-r.Left,r.Bottom-r.Top,true ); sleep(40);
MoveWindow(hand,r.Left+3,r.Top ,r.Right-r.Left,r.Bottom-r.Top,true ); sleep(40);
end;
訂閱:
文章 (Atom)