Thread Rating:
  • 391 Vote(s) - 2.76 Average
  • 1
  • 2
  • 3
  • 4
  • 5
セル単位での色指定
05-31-2013, 12:46 AM,
#2
RE: セル単位での色指定
カスタムセルを使って値が不正なセルの背景色に色をつけるなら、セルの更新が必要な際に呼ばれる
カスタムセルの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}
        }
    }
}
Reply


Messages In This Thread
セル単位での色指定 - by umemura - 05-28-2013, 03:56 PM
RE: セル単位での色指定 - by dyoshida - 05-31-2013, 12:46 AM
RE: セル単位での色指定 - by umemura - 05-31-2013, 10:49 AM
RE: セル単位での色指定 - by dyoshida - 05-31-2013, 12:38 PM
RE: セル単位での色指定 - by michaeljee - 06-13-2013, 01:43 PM
RE: セル単位での色指定 - by umemura - 06-17-2013, 07:57 PM
RE: セル単位での色指定 - by umemura - 10-28-2013, 01:11 PM
Forum Jump:


Users browsing this thread:
1 Guest(s)

MyBB SQL Error

MyBB has experienced an internal SQL error and cannot continue.

SQL Error:
1017 - Can't find file: 'mybb_threadviews' (errno: 2)
Query:
INSERT INTO mybb_threadviews (tid) VALUES('905')