title: RDB::DataSet
author: YOSHIDA Kazuhiro
mailto: moriq@moriq.com

1. RDB::DataSet

%c:RDB::DataSet% は，行および列のデータを表すすべてのデータセットコンポーネントの基本クラスです。

1.1. super class

%c:Object%

1.1. class methods

: new : RDB::DataSet

1.1. methods

: open : nil
  データセットを開きます。

: close : nil
  データセットを閉じます。

: self[i] : RDB::Field

  %c:[]% は，データセット内で指定した項目を検索します。
  : VCL
    %c:find_field%, %c:field_by_name%

  %c:[]% を呼び出すと，指定した項目コンポーネントがデータセット内に存在するかどうかを判定できます。 %v:i% は検索する項目の名前 ( %c:String% ) またはインデックス ( %c:Fixnum% ) です。
  項目が見つかった場合は， %c:[]% は指定した項目の RDB::Field# オブジェクトを返します。それ以外の場合は， %c:nil% を返します。

: fields : RDB::Fields
  データセットのすべての非集計項目コンポーネントをリストします。

  %c:fields% は，項目コンポーネントにアクセスできるようにします。項目が実行時に動的に生成されたのであれば， %c:fields% 内での項目コンポーネントの順序は，データセットの基になるテーブル内の列の順序と同じです。データセットが静的項目を使用している場合は，項目コンポーネントの順序は設計時に項目エディタで項目を指定した順序と同じです。

  #object_view が %c:true% ならば，項目は階層的に格納されます。つまり，オブジェクト項目の子項目がすべてそのオブジェクト項目によって参照され， RDB::Fields#fields のオブジェクト項目の後でシーケンシャルに表示されません。 #object_view が %c:false% ならば，項目はシーケンシャルに格納されます ( フラットに格納されます ) 。つまり，オブジェクト項目の子項目がすべて RDB::Fields#fields にシーケンシャルに格納されます。

  %c:fields% を使った項目へのアクセスは，次のような場合に便利です。
* データセット内の一部またはすべての項目に対して処理を繰り返す
* 実行時に，そのテーブルの内部データ構造がわからない
  アプリケーションで個々の項目のデータ型がわかっている場合は， %c:fields% を使って個々の項目値を読み書きすることができます。たとえば，次の文では項目値を編集ボックスの %c:text% に割り当てます。
--ruby
edit1.text = cust_table.fields[6].to_s
# edit1.text = cust_table[6].to_s
--
  : 注意
    項目値の取り出しおよび割り当てには，持続的項目または #[] を使うのが適切な方法です。

  次の文では，編集ボックスの値を項目に割り当てます。
--ruby
cust_table.edit
cust_table.fields[6] = edit1.text
# cust_table[6] = edit1.text
cust_table.post
--
  : 注意
    #agg_fields は，すべてのデータセットの集合項目のコレクションです。したがって， #agg_fields と %c:fields% はデータセットの項目の相互に排他的なコレクションです。これら 2 つのプロパティにすべてのデータセットの項目が含まれます。

: first : nil
  データセット内の最初のレコードにカーソルを移動します。

  %c:first% を呼び出すと，データセット内の最初のレコードにカーソルを移動し，そのレコードをアクティブレコードにすることができます。 First はアクティブレコードに対するすべての変更を登録し，次の処理を実行します。
+ レコードバッファをクリアする
+ カーソルをデータセットの先頭に設定する
+ 最初のレコードを取り出し，カーソルをそのレコードに移動して，そのレコードをアクティブレコードにする
+ グリッドコントロールを埋めるためのデータなど，表示に必要な次のレコードを取り出す
+ #bof を %c:true% に設定する
+ データコントロールおよびリンクされている詳細データセットが更新できるようにレコードの変更をブロードキャストする
: last : nil
  データセット内の最後のレコードにカーソルを移動します。

  %c:last% を呼び出すと，データセット内の最後のレコードにカーソルを移動し，そのレコードをアクティブレコードにすることができます。 %c:last% はアクティブレコードに対するすべての変更を登録し，次の処理を実行します。
+ レコードバッファをクリアする
+ カーソルをデータセットの最後に設定する
+ 最後のレコードを取り出し，カーソルをそのレコードに移動してアクティブレコードにする
+ グリッドコントロールを埋めるためのデータなど，表示に必要な追加レコードを取り出す。
+ #eof を %c:true% に設定する
+ データコントロールおよびリンクされている詳細データセットが更新できるようにレコードの変更をブロードキャストする
: next : nil
  データセット内の次のレコードにカーソルを移動します。

  %c:next% を呼び出すと，データセット内の次のレコードにカーソルを移動し，そのレコードをアクティブレコードにすることができます。 %c:next% はアクティブレコードに対するすべての変更を登録し，次の処理を実行します。
+ #before_scroll のイベントハンドラを呼び出す
+ #bof および #eof を %c:false% に設定する
+ 次のレコードを取り出し，カーソルをそのレコードに移動して，そのレコードをアクティブレコードにする
+ グリッドコントロールを埋めるためのデータなど，表示に必要な追加レコードを取り出す
+ カーソルがすでにデータセット内の最後のレコードにある場合は #eof を %c:true% に設定する
+ データコントロールおよびリンクされている詳細データセットが更新できるようにレコードの変更をブロードキャストする
: prior : nil
  データセット内の前にレコードにカーソルを移動します。

  %c:prior% を呼び出すと，データセット内の前のレコードにカーソルを移動し，そのレコードをアクティブレコードにすることができます。 %c:prior% はアクティブレコードに対するすべての変更を登録し，次の処理を実行します。
+ #before_scroll のイベントハンドラを呼び出す
+ #bof および #eof を %c:false% に設定する
+ 前のレコードを取り出し，カーソルをそのレコードに移動して，そのレコードをアクティブレコードにする
+ グリッドコントロールを埋めるためのデータなど，表示に必要な追加レコードを取り出す。
+ カーソルがすでにデータセット内の最初のレコードにある場合は #bof を %c:true% に設定する
+ データコントロールおよびリンクされている詳細データセットが更新できるようにレコードの変更をブロードキャストする

: move_by(distance: Fixnum) : Fixnum
  データセット内のアクティブレコードに相対する位置にカーソルを移動します。

  %c:move_by% を呼び出すと，データセット内のアクティブレコードに相対する位置にカーソルを移動できます。 %v:distance% は移動するレコード数を示します。 %v:distance% が正の値である場合は次に進みます。 %v:distance% が負の値である場合は前に戻ります。 たとえば，次の文では， 10 レコード分前に戻ります。
--ruby
move_by(-10)
--
  %c:move_by% はアクティブレコードに対する変更をすべて登録し，次の処理を実行します。
+ #before_scroll のイベントハンドラを呼び出す
+ #bof および #eof を %c:false% に設定する
+ %v:distance% が正の値の場合は，可能ならば %v:distance% の値を 0 になるまでデクリメントしながら繰り返しそれ以降のレコードを取得し，カーソルを最後に取得したレコードに移動し，そのレコードをアクティブレコードにする。ファイルの最後を超える移動を試みると， %c:move_by% は #eof を %c:true% に設定する
+ %v:distance% が負の値の場合は，可能ならば %v:distance% の値を 0 になるまでインクリメントしながら繰り返し前にあるレコードを取得し，カーソルを最後に取得したレコードに移動し，そのレコードをアクティブレコードにする。ファイルの先頭を超える移動を試みると， %c:move_by% は #bof を %c:true% に設定する
+ データベース対応コントロールおよびリンクされているデータセットが更新されるようにレコード変更についての情報をブロードキャストする
+ 実際に移動したレコード数を返す。ほとんどの場合，返り値は %v:distance% の絶対値になる。ただし， %v:distance% 分のレコードを移動する前にファイルの先頭または最後に到達した場合は，返り値は %v:distance% の絶対値より小さい値になる
: edit : nil
  データセット内のデータを編集できるようにします。

  %c:edit% を呼び出すと，データセット内のアクティブレコードを編集可能にすることができます。 %c:edit% はデータセットの現在の状態を変更します。データセットが空ならば， %c:edit% は #insert を呼び出します。それ以外の場合は， %c:edit% は次の処理を実行します。
+ #check_browse_mode を呼び出して，未処理の変更があればそれを前のレコードに登録する
+ #before_edit イベントハンドラを呼び出す
+ レコードを取り出す
+ データセットの状態を %c:DS_EDIT% にして，アプリケーションまたはユーザーがレコード内の項目を変更できるようにする
+ 関連付けられているコントロールに状態の変更をブロードキャストする
+ #after_edit イベントハンドラを呼び出す
  編集が終了したら #post を呼ぶことで変更されたレコードがデータベースに書き込まれます。

: post : nil
  変更されたレコードをデータベースに書き込む仮想メソッドです。

  RDB::DataSet# オブジェクトは変更されたレコードをデータベースに書き込む仮想メソッドを実装します。 #edit ， #insert ， #append などのようにデータセットの状態を変更したり， #first ， #last ， #next ， #prior などのようにあるレコードから別のレコードへ移動するデータセットメソッドは，自動的に %c:post% を呼び出します。 RDB::DataSet# のすべての下位オブジェクトは，データベースへレコードを書き込むために %c:post% を再宣言して実装します。

: append : nil
  データセットの最後に新しい空のレコードを追加します。

  %c:append% は，次の手順でレコードを追加します。
+ データセットの最後で新しい空のレコードを開く
+ アクティブレコードを新しいレコードに設定する
  %c:append% を呼び出した後，アプリケーションはユーザーがそのレコードの項目にデータを入力できるようにし，次に，変更内容を #post ( または #apply_updates ，キャッシュアップデートが有効な場合 ) を使ってデータベースに登録することができます。新たに追加されたレコードは，次のいずれかの方法でデータベースに登録されます。
* インデックスの付いた Paradox および dBASE テーブルの場合，レコードはインデックスに基づいたデータセット内の位置に挿入される
* インデックスの付いていない Paradox および dBASE テーブルの場合，レコードはデータセット内の最後に追加される
* SQL データベースの場合，追加されたレコードの物理位置は実装によって異なる。インデックス付きテーブルの場合，インデックスが新しいレコードの情報で更新される

: insert : nil
  新しい空のレコードをデータセットに挿入します。

  %c:insert% を呼び出すと，次の手順でレコードを挿入します
+ データセット内で新しい空のレコードを開く
+ アクティブレコードを新しいレコードに設定する
  %c:insert% を呼び出した後，アプリケーションはユーザーがそのレコードの項目にデータを入力できるようにし，次に， #post ( または #apply_updates ，キャッシュアップデートが有効な場合 ) を使って変更内容をデータベースに登録することができます。新たに挿入されたレコードは，次のいずれかの方法でデータベースに登録されます。
* 一次インデックスの付いた Paradox テーブルの場合，レコードはインデックスに基づいたデータセット内の位置に挿入される
* 一次インデックスの付いていない Paradox テーブルの場合，レコードはデータセット内の現在のカーソル位置に挿入される
* dBASE ， FoxPro ，および Access テーブルの場合，レコードはデータセットの最後に物理的に追加される。インデックスがアクティブになった場合，新しいレコードがインデックスに関連した位置に表示されることもあるが，レコードは実際にはテーブルの最後に格納されている
* SQL データベースの場合，追加先の物理位置は実装によって異なる。インデックスの付いたテーブルの場合，インデックスが新しいレコードの情報で更新される

: delete : nil
  アクティブレコードを削除し，カーソルを次のレコードに移動します。

  %c:delete% を呼び出すと，アクティブレコードをデータベースから削除できます。データセットがアクティブでない場合は， %c:delete% は例外を生成します。それ以外の場合は， %c:delete% は次の処理を実行します。
+ データセットが空でないことを確認する ( 空の場合は例外が生成される )
+ #check_browse_mode を呼び出して，未処理の変更があればそれを前のレコードに登録する
+ #before_delete イベントハンドラを呼び出す
+ レコードを削除する
+ レコードに割り当てられていたバッファを解放する
+ データセットを %c:DS_BROWSE% モードに設定する
+ データセットを同期し直してカーソルを次の削除されていないレコードに置く
+ #after_delete イベントハンドラを呼び出す
+ #after_scroll イベントハンドラを呼び出す

: locate(key_field, key_value, options) : boolean

  %c:locate% は，指定したレコードをデータセット内で検索し，そのレコードをアクティブレコードにします。%c:DataSet% の下位クラス（ Table#, Query# ）で使えます。

  : key_field
    検索したい項目名
  : key_value
    検索したい値
  : options : Array of Fixnum (TLocateOptions)
    : LO_CASE_INSENSITIVE
      大文字小文字の区別なし
    : LO_PARTIAL_KEY
      部分一致

  * 利用可能なインデックスがあればそれを使って高速に検索します。

: locate_ex(key_field, key_value) : Boolean

  基本的には locate# と同じですが、部分一致で見つかるまでキーを縮小します。ただし 10 回試みて見つからない場合には %c:false% を返します。

  * rdb.rb による拡張仕様です。

1.1. properties

: state : Fixnum (DataSetState)
  データセットの現在の操作モード

  %c:state% を調べると，データセットの現在の操作モードを判定できます。 %c:state% はデータセット内のデータについてどんな操作 ( たとえば，既存レコードの編集や新しいレコードの挿入など ) を行うことができるかを表します。アプリケーションがデータを処理するのにつれて，データセットの状態は常に変化します。

  データセットを開くと， %c:state% は %c:DS_INACTIVE% から %c:DS_BROWSE% へと変更されます。アプリケーションは #edit を呼び出してデータセットの状態を %c:DS_EDIT% に変えたり， #insert を呼び出してデータセットの状態を %c:DS_INSERT% に変えたりすることができます。データセットが Table# オブジェクトの場合は，アプリケーションは #set_key または #set_range を呼び出して，データセットの状態を %c:DS_SET_KEY% に変えることができます。

  編集，挿入，削除，変更を登録したり取り消したりすると， %c:state% は現在の状態から %c:DS_BROWSE% へと変わります。データセットを閉じると，現在の状態から %c:DS_INACTIVE% へと変わります。

  %c:DS_CALC_FIELDS% ， %c:DS_FILTER% ， %c:DS_NEW_VALUE% ， %c:DS_OLD_VALUE% ， %c:DS_CUR_VALUE% など，一部の状態は，アプリケーションから直接見たり，設定したりすることはできません。これらの状態は， #on_calc_field および #on_filter_record イベントが発生したとき，またはアプリケーションが特定の項目プロパティにアクセスしたときに自動的に設定されます。

: bof? : Boolean
  カーソルがデータセットの最初のレコードにあるかどうか

  %c:bof% ( ファイルの先頭 ) を参照すると，カーソルがデータセットの最初のレコードにあるかどうかを判別できます。 %c:bof% が %c:true% ならば，カーソルはデータセットの最初の行にあります。 %c:bof% が %c:true% になるのは，アプリケーションが以下の処理を行ったときです。
* データセットを開いた直後
* データセットの #first を呼び出した
* データセットの #prior を呼び出したが，失敗した ( カーソルがすでにデータセットの最初の行にあったため )
* 空の範囲またはデータセットに対して #set_range を呼び出した
  その他の場合 %c:bof% はすべて %c:false% です。

: eof? : Boolean
  カーソルがデータセットの最後のレコードにあるかどうか

  %c:eof% ( ファイルの最後 ) を参照すると，カーソルがデータセットの最後のレコードにあるかどうかを判別できます。 %c:eof% が %c:true% ならば，カーソルは確実にデータセットの最後の行にあります。 %c:eof% が %c:true% になるのは，アプリケーションが以下の処理を行ったときです。
* 空のデータセットを開いた
* データセットの #last を呼び出した
* データセットの #next を呼び出したが，失敗した ( カーソルがすでにデータセットの最後の行にあったため )
* 空の範囲またはデータセットに対して #set_range を呼び出した
  その他の場合 %c:eof% はすべて %c:false% です。

  : 参考
    %c:eof% と %c:bof% がいずれも %c:true% ならば，データセットまたは範囲は空です。

: active : Boolean
  データセットが開いているかどうかを示します。

  active は，データセットとデータベース内のデータとの接続を判定したり設定したりできます。

  active が false ならば，データセットは閉じられており，データセットはデータベースからデータを読み出したり，データベースにデータを書き込んだりすることはできません。

  active が true ならば，データベースからデータを読み出したり，データベースにデータを書き込んだりすることができます。

  active を true に設定すると，以下の処理を行うことができます。
* #before_open を呼び出す。
* データセットの状態を DS_BROWSE に設定する。
* データセットを open する。
* #after_open を呼び出す。

  データセットを open するときにエラーが発生した場合，データセットの状態は DS_INACTIVE に設定され，データセットは閉じます。

  アプリケーションは，データベースのステータスに影響を及ぼす他のプロパティや，アプリケーションでデータを表示するコントロールを変更する前に， active を false に設定する必要があります。

  : 注意
    open メソッドを呼び出すと active は true に設定され， close メソッドを呼び出すと active は false に設定されます。

: auto_calc_fields : Boolean
  auto_calc_fields は， calc_fields event の発生を制御します。

  auto_calc_fields を設定すると，データセット処理中に計算項目を更新するために，いつ calc_fields event が発生するかを制御できます。計算項目は値をアクティブレコード内の 1 つまたは複数の項目の値から派生させ，場合によってはその値に追加処理を行う項目です。

  auto_calc_fields が true ならば ( デフォルト ) ， calc_fields event は次の場合に発生します。
* データセットが開いた。
* データセットの状態が DS_EDIT になった。
* フォーカスが 1 つの可視コントロールから別の可視コントロールへ，またはデータベース対応グリッドの 1 つの列から別の列へ移り，レコードに変更が加えられた。
* データベースからレコードを取り出した。

  アプリケーションがユーザーによるデータの変更を許可している場合は， calc_fields event は頻繁に発生します。

  そのような場合には， auto_calc_fields を false に設定すれば， #on_calc_fields が呼び出される回数を少なくすることができます。

  auto_calc_fields が false ならば，レコード内の個々の項目に変更が加えられたときに #on_calc_fields は呼び出されません。

: auto_refresh : Boolean
  サーバーによって生成された項目値が自動的に再フェッチされるかを指定します。 auto_refresh が false( デフォルト ) の場合，レコードがポストされたときに自動インクリメント項目およびデフォルト値を含む項目に対してサーバーが作成する値は，データセットによって自動的に再フェッチされません。かわりに，アプリケーションは，データセットの #refresh を呼び出してこれらの項目値を更新する必要があります。

  auto_refresh が true の場合，これらの項目値は， #refresh を明示的に呼び出さずに自動的に更新できます。

  : 注意
    データベースドライバによっては，どの項目が自動インクリメント項目か，またはどの項目がデフォルト値を含むかを判断できません。このような場合には，更新する必要があるすべての項目の auto_generate_value を設定して，この情報を提供する必要があります。同様に，データセットが問い合わせまたはストアドプロシージャを表す場合にも，項目コンポーネントの auto_generate_value を設定する必要があります。

: cached_updates :

: database_name :

: default_index :

: filter :

: filter_options :

: filtered :

: object_view :

: session_name :

: update_mode :

1.1. event handlers

: after_cancel

: after_close

: after_delete

: after_edit

: after_insert

: after_open

: after_post

: after_scroll

: before_cancel

: before_close

: before_delete

: before_edit

: before_insert

: before_open

: before_post

: before_scroll

: on_calc_fields

: on_delete_error(action, e) : action
  アプリケーションがレコードを削除しようとして例外が生成されたときに発生します。

  %c:on_delete_error% イベントハンドラを記述すると，アプリケーションがレコードを削除しようとして失敗したときに発生する例外を処理することができます。 %c:DataSet% はレコードの削除に失敗したデータセットです。 %v:e% は，例外エラーメッセージが入ったデータベースエラーオブジェクトです。これによりアプリケーションはエラーメッセージを表示できるようになります。 %v:action% はこのデータセットがエラーにどのように応答するかを示します。

  %c:on_delete_error% が呼び出されたときは， %v:action% は必ず %c:DA_FAIL% に設定されています。エラーハンドラが自分を呼び出したエラー状態を訂正できる場合は， %v:action% を %c:DA_RETRY% に設定してからハンドラを終了します。 %v:action% が %c:DA_RETRY% のときは，削除処理が再試行されます。エラー状況が訂正できない場合， %v:action% を %c:DA_FAIL% ではなく %c:DA_ABORT% に設定すれば，エラーメッセージが表示されないようにすることもできます ( 必要な場合 ) 。

: on_edit_error

: on_filter_record

: on_new_record

: on_post_error
