2008年3月9日日曜日

FileMaker と Access の入力フォームにおける操作モデルの違い

FileMaker、Access ともにデータを入力するためのフォームをお手軽に作成できる。 FileMaker に慣れていると、 Access のフォームにおいて、微妙な挙動の違いに気がつく。

 

FileMaker の入力フォーム

FileMaker は、フォームの入力に際して、「新規レコード」を作成しなくてはいけない。(フォームを作成して、はじめてフォームが表示されるときには、「新規レコード」が一つ作成された状態になっている。)

20080309fm1

 

そのため、「レコード削除」をして、すべてのデータを削除した状態でフォームに入力しようとすると、「新規レコード」を作成するように促される。

080309-003

 

つまり、「フォームにおける入力する場」と、「レコードの存否」が対応している。

 

Access のフォーム

これに対して、Access のフォームは FileMaker の動作とは異なる。以下のフォームは、対応するテーブルにデータが全く入力されていない状態である。

080309-007

 

メニューを見ても、レコードの削除はできない。よって、テーブルにデータはない。

080309-008

 

ここで FileMaker との違いが浮き彫りになる。 FileMaker と同じつもりで、「新規レコードを作成する」に相当する「新しいレコード」を選択しよう思っても選択できない。

080309-009

 

しかし、不思議なことに、フォームにデータを入力しようとすると、データを入力することが可能だ。そして、入力をしたと同時に、上記の「レコードの削除」と「新しいレコード」の選択ができるようになる。

つまり、Access においては、FileMaker の「フォームにおける入力する」が、フォームを開くと同時に自動的に生成されていると類推することができる。ただし、その「場」は全く性質が異なる。フィールドへ入力しただけでは、テーブルにデータは反映されない。意識的に「レコードの保存」を行うか、または、「次のレコードへ移動する」か、「フォームを閉じる」とテーブルに反映される。 FileMaker のように、新規レコードを作成したときにレコードが保存されるのに比べると複雑に感じる。

Access では、フォームに入力しただけでは、データは登録されない。「フォームに入力する場」はあるけれど、テーブルからは独立しているようなものと言えばよいのかな。

 
オートナンバー型

例えば、オートナンバー型のフィールドがあった場合、オートナンバー型以外のフィールドへの入力がされたときになって、はじめてオートナンバーが生成される。

 

面倒になること

例えば、以下のように、あるフォームに新しいレコードを作成するときに、同時にそのデータに対応する他のデータを作成したいということがあったとする。

  1. レコードを作成する
  2. 特定のルールによって、上記に対応するデータを作成する

FileMaker においては、新規レコードを作成する処理において、同時にデータを作成する処理を加えればよいはずである。これに対して、Access ではデータを生成するタイミングに気をつけなくてはならない。

 

例えば、新規ボタンを押さなければ、フィールドに入力できないように VBA でコントロールする。新規ボタンを押したときに、レコードを保存し、それと同時に対応するデータを作成。そして、作成したデータを再度フォームに読み込むという手続きをとる必要がある。

手順をまとめると...

  1. ユーザがフォームを表示させる。
  2. システムは、フォームのフィールドを操作できないようにする。
  3. ユーザは、「新規ボタン」を押す。
  4. システムは、フォームに対応したレコードをテーブルに保存する。同時に、そのレコードに対応した他のテーブルのデータを生成し、テーブルに保存する。フォームの内容をリフレッシュすることによって、ユーザにデータを提示。その後、フォームのフィールドを操作できるようにする。
  5. ユーザはデータを入力する。

 

新規レコードの作成においては、フォームの .NewRecord で、テーブルに反映されてないフォームの内容であることを確認した場合、フィールドのロックを解除してデータの生成。そうでない場合は、「新しいレコード」を作成してからロックを解除して、データの生成をする。

 

うーん 、なんかややこしい。方法が間違ってるのかな... ^^;

2コメント:

匿名 さんのコメント...

???
accessはもっと簡単な方法があるのに…。
たとえば、サブフォームとか。VBAも不要だし。VBAだとしてもイベントドリブン型はユーザー側に選択肢が増えていいんじゃないですか?
だからって別にaccessを勧めるわけでもないですが。

jutememo さんのコメント...

詳しくは書かなかったのですが、上記はサブフォームを使った場合の話です。ちょっと昔のことなのでうろ覚えなのですが ^^; 親デーブル A とそれを参照する子テーブル B があるとします。テーブル A のデータの入力に対してフォーム F を作成し、テーブル B に対するサブフォームを フォーム F に含めす。ここでフォーム F においてデータを新規作成するとき、同時に対応するテーブル B に対して、予めテーブル R において表現してある特定のルールに基いてデータが作成されるという条件があるとします。ただし、フォーム F において新規データが作成されるとき、テーブル A に書き込むフィールドには全く値が割当てられず、サブフォームに対応するテーブル B にのみデータが書き込まれます。この場合、テーブル A の主キーである id フィールドがあるとして、それをオートナンバー型にしてしまうと、フォーム F におけるデータの新規作成時に作成されるテーブル B のデータは、参照整合性違反によって入力できません。なぜならフォーム F を開いて新規データを入力しようとするだけでは、そのフォームに対応するテーブル A のデータがないためです。
フィールドをテーブルと連動しないようにしておいて、トランザクションを用いてデータを保存するというが一番良いと思いますが、それをすると色々とコードを記述しなくてはいけなくて、Access のようにサクッと作るツールのメリットが失われてしまうと思いました。データの入力自体もエラーがでたら作成した新規データを削除するという運用で十分なレベルでしたので、トランザクションは用いないことにしたのです。
話を元に戻しまして、このようにデータを新規作成するとき、初期状態として、親テーブルにはそのエンティティを識別するための id のみが入力されており、かつ、子テーブルには親テーブルのエンティティに対応したデータが必要とされるとき、上記のような制御が必要となってくると考えました。
で、こういった場合、具体的に「もっと簡単な方法がある」とはどういった感じにすればいいでしょうか?