カスタムセルを使って値が不正なセルの背景色に色をつけるなら、セルの更新が必要な際に呼ばれる
カスタムセルのrefresh-dataメソッドでセルの値のエラーチェックをして背景色を変えるのが簡単そう
ですがどうでしょうか
Code:
|| レコードセット
{def rs =
{RecordSet
{RecordFields
{RecordField "COL1", domain = String},
{RecordField "COL2", domain = String},
{RecordField "COL3", domain = String}
},
{RecordData COL1 = "NG", COL2 = "OK", COL3 = "OK"},
{RecordData COL1 = "OK", COL2 = "NG", COL3 = "OK"},
{RecordData COL1 = "OK", COL2 = "OK", COL3 = "NG"}
}
}
|| 入力値の有効性チェック(OKという文字列でなければ無効)
{define-proc public {is-invalid-val val:String}:bool
{return
{if val.empty? != true and
{val.to-upper-clone} != "OK"
then
true
else
false
}
}
}
|| カスタムセル
{define-class public MyCustomCell
{inherits StandardStringCell}
{constructor public {default}
{construct-super}
}
||スクロール等でセルに表示すべきデータが切り替わる場合に呼ばれる
{method public {refresh-data}:void
{super.refresh-data}
def (data:String, valid?:bool) = {self.get-formatted-data}
{if not valid? or || 値が取得できないまたは
self.selected? || 行が選択されている場合は何もしない
then
{return}
}
|| セルの値をチェック
|| 列毎にチェックメソッドを変更できるが、ここでは手抜きして
|| 全部同じチェックメソッドを呼んでいる
def invalid? =
{switch self.field.name
case "COL1" do
{is-invalid-val data}
case "COL2" do
{is-invalid-val data}
case "COL3" do
{is-invalid-val data}
else
true
}
|| チェック結果により背景色を変更
{if invalid? then
|| NG の場合は赤大文字
set self.background = "red"
set self.color = "pink"
else
|| OK の場合は通常の文字
{if not self.selected? then
{unset self.background}
{unset self.color}
}
}
}
}
{value
|| レコードグリッドを表示
{VBox
margin=2mm,
{bold OK以外の文字列を入力するとエラー},
{Fill height=2mm},
{RecordGrid
record-source = rs,
height = 3cm,
width = 10cm,
|| record-source 内のフィールドに対するカラムの自動生成を無効に設定
automatic-columns? = false,
|| 表示するカラムを明示的に生成
{RecordGridColumn "COL1", cell-spec = MyCustomCell},
{RecordGridColumn "COL2", cell-spec = MyCustomCell},
{RecordGridColumn "COL3", cell-spec = MyCustomCell}
}
}
}
どのような状況が思いつかないのですが、「エラー状態を保持~」と書かれていることから、
たとえばエラーチェックに非常に時間がかかるため、エラーチェックは入力時に一度のみ
しか行いたくないという場合のため、レコードセットに隠しフィールドを用意して、そこへ
チェック結果を保存する案も考えてみました。
チェック結果を格納するフィールドを1つにするために各フィールドのチェック結果合否を
1ビットで表現しているのでちょっと面倒になってしまいましたが・・・
Code:
|| 各フィールドの入力値チェック結果を格納する隠しフィールド名
{def flags-field-name = "flags"}
|| レコードセット
{def rs =
{RecordSet
{RecordFields
{RecordField "COL1", domain = String},
{RecordField "COL2", domain = String},
{RecordField "COL3", domain = String},
{RecordField flags-field-name, domain = int}
},
{RecordData COL1 = "NG", COL2 = "OK", COL3 = "OK", flags = 1},
{RecordData COL1 = "OK", COL2 = "NG", COL3 = "OK", flags = 2},
{RecordData COL1 = "OK", COL2 = "OK", COL3 = "NG", flags = 4}
}
}
|| チェック結果フラグから指定フィールドのチェック結果フラグを取り出すプロシージャ
{define-proc public {set-invalid-flag
invalid?:bool,
flags:int,
field-index:int
}:int
|| フィールド位置のチェック結果のビットを設定するためのビットフィールドを作成
def bit-fields = {bit-sll 0x1, field-index}
|| 既存のフラグに指定位置のビットをセットした新しいフラグを作成
def new-flags =
{if invalid? then
{bit-or flags, bit-fields}
else
{bit-and flags, {bit-not bit-fields}}
}
{return new-flags}
}
|| チェック結果フラグから指定フィールドのチェック結果フラグを取り出すプロシージャ
{define-proc public {get-invalid-flag
flags:int,
field-index:int
}:bool
|| フィールド位置のチェック結果のビットを取り出すためのマスクを作成
let bit-mask:int = {bit-sll 0x1, field-index}
||チェック結果フラグのビットフィールドから目的のフラグを取り出す
def flg:int = {bit-and flags, bit-mask}
def cell-valid? =
{if flg != 0 then
false
else
true
}
{return cell-valid?}
}
|| セルに格納されているカラムのチェック結果を取り出すプロシージャ
{define-proc public {validate-cell cell:StandardStringCell}:bool
|| セルに格納されている値のレコードセットにおけるフィールド位置を取得
def rf:#RecordField = cell.field
def field-name:String = rf.name
def rec:#Record = cell.record
def rs:#RecordSet = rec.record-set
def rfs:#RecordFields = rs.fields
def field-index:int = {rfs.get-index field-name}
|| チェック結果フラグを隠しフィールドから取得
def v-flags = {rec.get flags-field-name} asa int
||チェック結果フラグのビットフィールドから目的のフラグを取り出す
def cell-valid? = {get-invalid-flag
v-flags,
field-index
}
{return cell-valid?}
}
|| 入力値の有効性チェック(OKという文字列でなければ無効)
{define-proc public {is-invalid-val val:String}:bool
{return
{if val.empty? != true and
{val.to-upper-clone} != "OK"
then
true
else
false
}
}
}
|| カスタムセル
{define-class public MyCustomCell
{inherits StandardStringCell}
{constructor public {default}
{construct-super}
}
||スクロール等でセルに表示すべきデータが切り替わる場合に呼ばれる
{method public {refresh-data}:void
{super.refresh-data}
def (data:String, valid?:bool) = {self.get-formatted-data}
{if valid? and
not self.selected? ||行が選択されている場合は何もしない
then
|| セルの値のチェック結果を取得
def valid-cell? = {validate-cell self}
{if valid-cell? != true then
|| NG の場合は赤大文字
set self.background = "red"
set self.color = "pink"
else
|| OK の場合は通常の文字
{if not self.selected? then
{unset self.background}
{unset self.color}
}
}
}
}
}
|| セル更新時の入力値チェック用イベントハンドラ
{def rec-mod-event-handler =
{on rm:RecordModified at rs:RecordSet do
|| 更新されたフィールド名を取得
def field-name = rm.field.name
|| チェックフラグのフィールドが更新された場合はなにもしないで抜ける
{if field-name == flags-field-name then
{return}
}
|| 更新された値を取得して無効か否かをチェックする
def current-record = rm.record
def val:String = {current-record.get field-name} asa String
def invalid? = {is-invalid-val val}
|| 更新フィールドのインデックス位置を指定して、チェックフラグのフィールドへ
|| チェック結果のフラグを設定する
def rfs:#RecordFields = rs.fields
def field-index:int = {rfs.get-index field-name}
def flags = {current-record.get flags-field-name} asa int
def new-flags = {set-invalid-flag invalid?, flags, field-index}
{current-record.set flags-field-name, new-flags}
}
}
{value
|| レコードセットにセル入力値チェックのイベントハンドラをセット
{rs.add-event-handler rec-mod-event-handler}
|| レコードグリッドを表示
{VBox
margin=2mm,
{bold OK以外の文字列を入力するとエラー},
{Fill height=2mm},
{RecordGrid
record-source = rs,
height = 3cm,
width = 10cm,
|| record-source 内のフィールドに対するカラムの自動生成を無効に設定
automatic-columns? = false,
|| 表示するカラムを明示的に生成
{RecordGridColumn "COL1", cell-spec = MyCustomCell},
{RecordGridColumn "COL2", cell-spec = MyCustomCell},
{RecordGridColumn "COL3", cell-spec = MyCustomCell}
}
}
}