<HOME  <お願い事項  <Access2002 TOP   <Access97 TOP   <サイト内検索
 MS-Access2000超入門部屋--重複入力のチェック方法



商品番号とか顧客番号など・・・そのテーブルの中で「主キー」として扱うコードや番号は、当然のことながらダブってはなりませんよね。
でも、人間、間違い入力とか、考えられるし・・・。
まあ、主キーにしておけば、同じ番号を2度使うことはできませんけど、なんかちょっと気の効いたエラーメッセージみたいなのを出してあげたいですよね。

今回は、「重複入力しないような仕組み」をちょっぴり考えてみようと思います。

例えば、こんなテーブルがあって・・・

こんなフォームがあって、このフォームを通じて、商品の登録をしていくとします。

この「番号」は、自動発番ではなく、あらかじめその商品に対して定められている番号を入力していく・・・ということで、考えてみます。
つまり、前に入力したことのある番号をもう一度入力する、ということは、もう既にその商品は登録すみ、ってわけなんですね。

こういう場合に、メッセージとか出したりして、注意を促そう、という仕組みを考えようかなと思います。
はっきりいって、これって具体的な操作方法としては、いろんなやり方があります。
ケースバイケースですしね。

でも、基本は、「基になっているテーブルの中で、重複しているレコードがないかどうか」を何とかして確認する、ということです。
その手段はいろいろある、というわけです。




今日は、わりとカンタンじゃないかな、と思われる方法を使ってやってみようと思います。

「フォーム上に入力されかかっている番号と同じ番号を持つレコードだけ抽出する」クエリを作って、そのクエリのレコード件数をDcount関数で数えます。
ダブってたら、「1」以上の数になるはず。ダブってなければ、ゼロのはずですよね。

じゃあ、ちょっとやってみます。

例えば・・・。なんか適当な値を[番号]欄に入力しておいて、このフォームはそっと端っこによけておきます。

クエリをデータシートビューに切り替えたりしてテストするなら、このフォームは、開いておいた方がよいですね。
だって、このフォームの中のテキストボックスの値を抽出条件にするんですから、このフォーム閉じちゃったらクエリが「?」って思っちゃいますよ。

クエリの抽出条件に、フォーム内のテキストボックスの名前を入れます。
わたしのフォームは[商品登録]という名前で、テキストボックスの名前が[番号]だったので、こんなふうになりました。
こういうのは皆さんもうお手の物ですよね。フォーム名とかテキストボックス名とか、間違えないようにしてくださいよ。


じゃあ、このクエリ、名前を付けて保存してください。
ええと、例えば、[Q_登録チェック]という名前にしたとします。

じゃあ・・・あとは、チェックするタイミングなんですけど・・・[番号]のテキストボックスに番号を入れてEnterキー押したときにしましょうか。
んじゃ、「更新後処理」というイベントに、ちょっとしたコードを書きましょう。

マクロでも同じようなことは可能ですけど、今回は、「番号が重複していたら、メッセージを出して、今入力中の新規レコードをキャンセルして白紙の状態にする」っていう感じにしようかと思います。Undoっていう命令をフォーム自身(Me)に送ってやれば、新規入力レコードや更新中のレコードの更新内容をキャンセルすることができましたよね。

コードはこんな感じかな。詳しくは、Dcount関数のヘルプ、参照してくださいね。
Me.Undoってのをやらなくてもよいのなら、マクロでもおなじことができますよ。マクロで「条件」ってできましたもんね。
Dcount関数を条件のところに書いて、アクションのところでメッセージボックスを出すようにすればよいでしょう。
この辺は、他のコーナーでもご紹介してます。「小技集」の方でも、あとでお立ち寄りくださいまし。

では、フォームビューに戻って・・・。改めて、何か番号を入れるなりなんなりして、Enterキーを押してみてください。
まあ、まだテスト段階なので、わけわかんなくなっちゃってもオッケーですよ。わけわかんなくなっちゃったらエラーメッセージとかはみんな「はいはい」と言うことを聞いておいて、一回フォームを閉じて改めて開いてから、番号の入力をしてみてください。

既にテーブルに存在する番号を入力すると、メッセージボックスが出るはずなんですけど・・・。どうでしょう?

で、OKすると、入力した番号とか、クリアされると思います。
完全ではないかもしれませんけれど、入力する人たちの様子を考えながら、こうした仕組みをちょっと組み込んでいくことによって、スムーズな入力が可能になるんじゃないかと思います。
でも、こういうのが返って邪魔臭くなっちゃうこともありますから、必ず「入力するときの様子」を考えながら作っていってくださいね。




[番号]ではなく、重複した「商品名」を入力しないようにチェックするためには・・・これはちと難しいですね。
多分、全く同じ名前の商品だってこの世には存在するだろうし、登録する人が入力し間違えてたりする場合も考えられます。
それに、「ガンキャノン」と「ガン・キャノン」は、私たちにとってみたら同じもので単に表記上ナカグロを入れているだけ、であっても、コンピュータは「違う商品」と思ってしまいます。
単純に「同じ名前の商品が存在していないかどうか」をチェックすることで、得たい結果を得ることができるのか???ということを、ちゃんと考えないといけません。え?誰がって?みなさんが考えるんですよ!あたりまえじゃありませんかっしっかりしてくださいよ!!!

では・・・入力した「文字列」を含んだ商品名をリストアップするような仕組みを考えてみましょうか。
今度は白紙に戻さず、「こういう商品が既に入力されているけれど、今入力しようとしている商品とは別のものなのかしら?」って、たずねるような感じで考えようかな。

では、こんな感じのクエリを作りましょう。
Like *は、書き方が若干難しいですけど、みなさんもう大丈夫ですよね。
がんばって挑戦してみてください。



で、このクエリを基にしたフォームを作ります。表形式のフォームでいいですね。
まあ、クエリを開くだけでも、データシートビューの形でも十分見やすいんですけど、ついでですからちょっとおしゃれしましょう。
フォームウィザードやオートフォームを使うと、このクエリを実行することになりますから、なんかパラメータの入力画面が出てきますけど、それは、商品登録のフォームが開いていない場合のことですね。これ、みなさん、ちゃんと理解なさってますよね???

適当にテキストボックス等々、大きさを調節してください。
新規に入力するフォームじゃないので、フォームのデータプロパティで「追加の許可」をいいえにしておくといいかもしれません。

で、「名前」のテキストボックスの「更新後処理」で、同じようにDcount関数を使ったチェックをします。



今度はさらに一工夫して・・・

If文を2重にして、ボタンがふたつあるメッセージボックスを使ってみました。
メッセージボックスって、いろんな種類があるんで、If文とうまく組み合わせて使うことで、いろんな処理を作っていくことができますよね。
で、さっき作った表形式のフォームを開くようにします。

実験です。
番号欄には、今まで使ったことのない番号を入力し(そうすればこの時点ではまだエラーにならないですよね)、[名前]欄に、既に入力したことのある名前を入力してみます。すると・・・。

メッセージボックス、出ます?

「はい」の方をクリックすると、表が出てきて、「ジム」という文字列を含む商品名を持つレコードを一覧にしてくれます。




余談ですが、「入力の途中、フォーム上でチェックする」のではなくて、ひととおり入力し終わって、後で、テーブルの中のデータの重複をチェックしたいのであれば、「集計クエリ」が一役買ってくれると思います。

クエリのデザイン画面出、Σボタンをクリックすると、「集計クエリ」というタイプのクエリになることはご存知ですよね。

グリッド上に選んでいるフィールドで、同じ値を持つものだけまとめて、そのグループでのいろいろな集計ができるようになります。
なので、この手のクエリの場合は、余分なフィールドは選びません。今回のような場合、必要になるのは、「ダブってる値」を検査したいフィールドだけ、です。
「名前」ですね。
例えば、商品番号とか、値段まで選んじゃうと、多分、商品番号は別の番号がついてるはずですよね。だから、「違うグループ」になっちゃって、まとまってはくれません。
値段も、全く同じ値段を入力していれば別ですけど、違う値段を入力してたとしたら、同じ名前の商品でも「違うもの」と扱われちゃいます。

で、ふつうは、「名前」だけでいいのですが、今回は、「同じ名前をもつ値が、いくつずつあるか」を調べますので、もう一列、なんでもいいので適当にフィールドを選んで、そっちを「カウント」とります。まあ、[名前]を2列並べるのが一番わかりやすいかもしれませんね。

と、こうなります。ほとんどの商品がダブらず入力されてるので、ほとんどの商品が「カウント 1」です。

「名前のカウント」の列が、2とか3になってる商品は、ダブって違う商品番号で2回3回入力しちゃった商品、ということになります。

じゃあ、この列の抽出条件に「1より大きい数のレコードだけ」と指定してやれば・・・。

ダブって2回以上入力されてる「商品の名前」だけ、拾うことができますね。
このクエリはいちおう「確認用」です。同じ名前をもつレコードを束ねてますから、この画面から直接レコードの削除とか書き換えはできません。今表示しているのは「明細」じゃありませんからね。こういうとこは皆さん、大丈夫ですよね。

同じ商品名だけど違うメーカーの商品、とか、いろいろあると思いますので、ここからさきは、人間が目で判断して考えていくところだと思います。
こういったクエリで、重複がないかどうか時々調べて、メンテナンスしていく・・・なんていうことも、時には必要な作業かな、って思うんです。




商品名とか顧客名のチェックはホントに難しいです。
できるだけ、「顧客番号」などの番号を振ってコード化して、誰が入力しても混乱のないようにしていくべきだと思います。
そして、ときどき、テーブルの中身を、人間が人間の目で見て、ダブっていると思わしきレコードは除外していくとか、何らかの形で人の手を加えていく必要は、絶対あると思うんです。コンピュータにはね、人間のような、状況に応じた判断は、できないですよね。

チェックの方法、チェックのタイミングの基本構造はこんな感じだと思います。
あとは、クエリの中での抽出条件などを工夫してやることによって、もう少し複雑なチェックをすることができるんじゃないでしょうか。
いろいろ工夫できそうですね。



(オシマイ)