2011年9月10日 星期六

背景讀取 DataWindow 的方法

很多時候,DataWindow 的設計目的在於監視列表的資料,尤其是會自動定期更新的列表。

譬如說,我有一個紀錄狀態的 Table ,裡面紀錄的狀態一直在改變,

因此,我會需要一個 DataWindow 定時的去 Retrieve 這些紀錄資料,並將它顯示到畫面上,

讓管理人員可以一目了然。

當然,你會說這有什麼困難?用一個 DataWindow 加上 Timer 就可以解決啦!

但如果,這些資料多到螢幕容納不下時會發生什麼事?

如果你設定必需2秒更新一次又會怎麼樣?

事實是,當管理人員下拉(Scroll)該 DataWindow 以便檢視下方被遮住的資料時,

由於 Retrieve 的關係,所以畫面又跳回第一筆 Row 啦!!!

管理人員會落入不勝其擾的拉下又跳回、拉下又跳回的無間地獄了。

也許加大 Timer 間隔是個方法,不過對於資料的即時性就大打折扣了,

尤其是特別重要的資料更是如此,例如即時股票的變化.....

所以需要一點小技巧來達成這樣的運作模式,利用下面的程式碼技巧可以避開 DataWindow 的顯示畫面 reflash 動作:


DataStore lds_src
Long ll_row , ll_rcount
Integer li_col , li_ccount

//建立一個資料倉儲並使之與資料視窗的來源物件相同
lds_src = Create DataStore
lds_src.DataObject = dw_1.DataStore
lds_src.SetTransObject(SQLCA)

//由資料倉儲來讀取資料
lds_src.Retrieve()
ll_rcount = lds_src.RowCount()
li_ccount = integer(dw_1.Object.DataWindow.Column.Count)
for ll_row = 1 to ll_rcount
  for li_col = 1 to li_ccount
    //複製資料蓋掉畫面上的資料
    dw_1.Object.Data[ll_row , li_col] = lds_src.Object.Data[ll_row , li_col]
  next
next
//移除畫面上多餘的資料(如果有的話)
if ll_row <= dw_1.RowCount() then
  do while dw_1.RowCount() > lds_src.RowCount()
    dw_1.DeleteRow(dw_1.RowCount())
  loop
end if

Destroy lds_src

這段程式碼放在讀取的 function 裡面執行,

當然為了提高效率,你可以把淡藍色的部份放在該 window 的 open 事件裡面,
只是 lds_src 就必須定義在 Instance 變數區內以方便呼叫使用,
而粉色的部份就放到 window 的 close 事件去處理就好了。


6 個回應:

分岔路 提到...

大大您好:
小弟在datawindow中設定where 條件式使用in+參數
但是參數不論是ls_a="'"+'123'+"'"+','+"'"+'456'+"'"
或是 ls_a ='123'+','+'456'
或是使用陣列皆出現錯誤
請問各位大大參數內容應該為何才對呢?
謝謝
小弟的mail
cherng32@gmail.com

WILDOX 提到...

哈羅 分岔路

關於您的問題,我已經貼在
http://radio-idea.blogspot.com/2012/03/datawindow.html
這一篇裡面,請你看看

分岔路 提到...

Re: 分岔路 <639196460171365801>
我瞭解了~謝謝大大~

分岔路 提到...

WILDOX您好:
小弟想請問一下TriggerEvent 與EventTrigger有何不同?我瞭解EventTrigger在使用的時候需要傳入event的數,但何時要用TriggerEvent或EventTrigger?小弟不是很清楚,不知可否請大大您撥空解答一下?
謝謝

WILDOX 提到...

Re: 分岔路 <5149345324783134328>
使用Event Trigger的方式是像呼叫函式般觸發它
所以呼叫方式像是:
event EventName(argument1,argument2)
當然上面的方法適用所有event(系統/自訂)
但是如果你要使用triggerevent('EventName')
這個方法就得注意要觸發的event必須是enumerated型態,也就是該event必須配有event id(pbm_eventname)才可以使用這方法,Help 原文有提到:
A value of the TrigEvent enumerated data type that identifies a PowerBuilder event (for example, Clicked!, Modified!, or DoubleClicked!) or a string whose value is the name of an event. The event must be a valid event for objectname and a script must exist for the event in objectname.

WILDOX 提到...

Re: 分岔路 <5149345324783134328>
這個主要是因為pbm_event類型的傳遞參數是帶有default值的,如果是自訂的event就不能帶任何傳遞參數