本文說明 Genero INPUT ARRAY 指令中「暫時列(Temporary Row)」的概念,包括它的建立時機、移除條件,以及開發者如何控制其行為。
什麼是暫時列?
INPUT ARRAY 指令有一些靜默執行的有趣行為,其中包括「暫時列」的概念——系統會在需要時自動建立暫時列,並決定是否保留它。
以下幾種情境都與暫時列有關:
- 使用者意外往下移動超過原有的資料列範圍,再往回移動
- 使用者接受對話框時,游標停在空白列上
- 刪除後陣列變成空的
- 空陣列第一次獲得焦點
AUTO APPEND:暫時列的建立時機
當 AUTO APPEND 啟用(預設值)時,以下情況會自動建立暫時列:
- 使用者嘗試往下移動超過最後一列
- 在最後一列的最後一個欄位按下 TAB
- 使用者動作刪除最後一列
- 程式呼叫
DIALOG.deleteRow()或DIALOG.deleteAllRows()刪除最後一列 - DIALOG 區塊中的 INPUT ARRAY 在沒有資料列時獲得焦點
若要停用此行為,可在 INPUT ARRAY 的屬性中設定 AUTO APPEND=FALSE。若同時設定 APPEND ROW=FALSE, INSERT ROW=FALSE, DELETE ROW=FALSE, AUTO APPEND=FALSE,可建立固定列數的陣列。當 MAXCOUNT 達到上限時,也不會建立暫時列。
暫時列的移除條件
暫時列會在使用者往上移動或離開 INPUT ARRAY 時,由系統自動移除——前提是沒有任何欄位被「觸碰(touched)」過。
一個欄位被視為「touched」是指:使用者在該欄位輸入過資料,或程式透過 DISPLAY TO 模擬輸入,或呼叫 DIALOG.setFieldTouched() 方法。
需要手動處理的情境
有兩種情境需要開發者明確呼叫 DIALOG.setFieldTouched() 方法:
情境一:緩衝對話框(Buffered Dialog)搭配預設值
在 BEFORE INSERT 事件中設定欄位預設值,並用 DISPLAY TO 顯示,但希望暫時列仍能被自動移除:
BEFORE INSERT
LET arr[arr_curr()].fieldname = default_fieldname_value()
DISPLAY arr[arr_curr()].fieldname TO scr[scr_line()].fieldname
問題在於:DISPLAY TO 陳述式會讓系統將這一列標記為「touched」,導致暫時列無法被移除。
解決方式:在 DISPLAY TO 之後,明確將欄位設為未觸碰狀態:
BEFORE INSERT
LET arr[arr_curr()].fieldname = default_fieldname_value()
DISPLAY arr[arr_curr()].fieldname TO scr[scr_line()].fieldname
CALL DIALOG.setFieldTouched("fieldname", FALSE)
情境二:非緩衝對話框(UNBUFFERED Dialog)搭配 BUTTONEDIT
在非緩衝對話框中,透過 BUTTONEDIT 的動作設定欄位值:
ON ACTION zoom INFIELD fieldname
LET arr[arr_curr()].fieldname = zoom()
問題在於:非緩衝對話框沒有 DISPLAY TO 陳述式,系統可能誤判這一列為未觸碰,導致透過 BUTTONEDIT 動作填入值的暫時列被錯誤移除。
解決方式:在設定值後,明確將欄位標記為已觸碰:
ON ACTION zoom INFIELD fieldname
LET arr[arr_curr()].fieldname = zoom()
CALL DIALOG.setFieldTouched("fieldname", TRUE)
重點方法
DIALOG.setFieldTouched() 可明確控制欄位的「touched」狀態,進而決定暫時列是否應被保留。