本文說明 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」狀態,進而決定暫時列是否應被保留。

相關文件

原文:https://4js.com/ask-reuben/ig-147/  ·  有任何 Genero 技術問題或翻譯疑問,歡迎來信 support@t100.app