<HOME  <お願い事項   <Access2002 TOP   <Access97 TOP   <サイト内検索
 MS-Access2000超入門部屋--自動採番の巻
   1 2 3 4 5



さて・・・。お次は、「先頭にAってアルファベットをつけて、A00000001にしたい」場合のお話です。

今度は、テキスト型のフィールド相手ですからね。簡単にはまいりません。
A00000001に1を足したって、だめでしょう。A00000001は文字ですから、最後の1も文字扱いですよね。
この「データ型による違い」をしっかり理解することが、このコーナーでの最大のポイントになりますよ。
わかりにくいかもしれませんけど、「数字だけど、数値じゃない」というこの脱線問答みたいな言葉の意味を、理解していってくださいね。

何が問題になってるかというと・・・今の、現状の処理を整理しましょう。

やってることは、DMax関数を使って、「そのテーブルのそのフィールド内の値の中で、もっとも大きいものを探す」という処理をやってるわけです。
この「大きいもの」というのが、テキスト型の場合はクセモノで、コンピュータがどう判断するか、っていうことにかかってきます。
A00000005とB00000001だったら、多分B00000001の方が大きい、と判断するんじゃないかと思います。一番左端の文字から判断していきますもんね。
複雑に考え出すときりがないので・・・とりあえず「先頭が必ずA」というケースから考えてみましょう。

やり方はいろいろ考えられると思いますが、今の考え方をそのまま使うとすると、「A00000001から00000001の部分だけ取り出して、数値にして、1を足して2として、再びA00000002という形にして、テキストボックスに代入する」という流れになるかと思います。

足し算と、再びA00000002と表示するところは特に問題ないと思いますけど、現在文字扱いを受けている00000002を、足し算できるような数値に変えるところとか、その辺が難しいですね。

テキスト型を数値型に変換したり、そういう関数もあるんですけど・・・今回は「文字でも数値でもなんでも入れられる入れ物」を一つ設けて、その中にいったん00000002を入れ、Accessにお任せでやってみようかと思います。VBAでコードを書くと、Variant型という「なんでもあり」なデータ型の入れ物を設けることができます。

Bangouという名前の入れ物を作って、その入れ物に、A00000001のうちの00000001の部分だけ取り出して入れれば、足し算させてもらえると思います。Aは取らなきゃだめですよ。そこんとこはオッケーですよね。
テキスト型のフィールドのデータから、しかるべき個所だけ文字を取り出す、という操作に適した関数がいくつかありますので、それを活用しましょう。Right関数、Mid関数、Left関数といいます。詳細はヘルプで確認してくださいね。

「A00000001のうちの00000001の部分だけ取り出す」のですから、ええと、右から、8文字分取ってくればいいのかな。じゃ、Right関数か。

A00000001だったら、右の1桁分だけ取ればいいんじゃないの?とか思ってる人、まさかおらんですよね。それじゃ、A00000010のとき、0しか取ってこないっすよ。9件目で頭打ちな処理になっちゃいます。

ついでにちょっとおしゃれして、「A00000001」じゃなくて「AAA-00000001」って出るようにしてみました。なんかそれっぽいでしょ。
今までとどこがどう違うのか、ダブルコーテーションとかハイフンとかカンマとか&とか、いろんな記号が並んでますけど、記号にもそれぞれちゃんと役割があるので、その辺じっくり観察して慣れてしまってくださいね。
何をダブルコーテーションで囲めばよいのか・・・その辺は、みなさんもうオッケーですよね。


できたら、フォームを保存し、フォームビューに切り替えましょう。
で、ウニボタンをクリックして、新規入力状態にして、「名前」の入力をして、Enterキーを押します。

相変わらず「番号」が空っぽのままですけど・・・まあ、とりあえずフォームを閉じて、テーブルAの中身を確認してみましょう。
わたしのはこんな感じに↓なりましたけど、どうでしょう?

ここまでいかがでしょう?うまくいきました?
番号振るって一口に言っても、いろいろ考えなくちゃいけないことがありますよね。でも、工夫次第で実現することです。
フォームとテーブルの仕組みをうまく利用して、正しくわかりやすく採番されるよう、検討してみてください。


さて・・・。
フォームから新規にデータの入力するとき、なぜかいつも[番号]って適すとボックスの中身はゼロか、空っぽか、どっちかでしたよね。
なんで表示されないんでしょう。
それから、[名前]のテキストボックスに何か入力してEnterキーを押すと、なぜか入力したものがなくなってテキストボックスの中身が空になってしまってたり、しませんでした?
でもって、できれば、フォームを開いたとき、1件目じゃなくて、新しく入力する状態になっててくれたら・・・とか、フォーム上のもろもろを、いくつか見てみましょう。


まず、[名前]のテキストボックスに何か入力してEnterキーを押すと、なぜか入力したものがなくなってテキストボックスの中身が空になってしまってた、というのは、正確にはこれは間違いです。データは入ってます。テキストボックスの中身が空になったのではありませんよ。
Enterキーを押すことで、次のレコード入力状態になった、ということなんです。

フォームといっても、フォーム自体にデータを持ってるわけではありませんよね。フォームという枠を通じて、実際にはテーブルAの中のデータを見ていることになるわけです。ですんで、フォーム上でEnterキーを押すということは、次のテキストボックス、次のテキストボックス、と、カーソルが次々移動して(といってもこのフォームにはテキストボックス2個しかないけど)、そして・・・。

ちょっとわかりにくいですけど、上の図で行くならば、エゾジカの入力の後、Enterキーを押すと、ピンクのやじるしのところにカーソルが移動することになりますよね。
この行は、新規入力行で、まだ何の入力もしてない空白行です。エゾジカを入力した後、Enterキーを押すと、ここが、フォームを通じて表示されるのです。

フォームのプロパティの中に、「Tabキー移動」というのがあります。デフォルトは多分「すべてのレコード」になっていて、これはEnterキーを押したときの動きも同様です。なので、フォームで、入力しようがしまいがEnterキーとかTabキーを押すと、次のレコード次のレコードと、どんどんめくれていくわけです。単票形式のフォームなので、一見「入力したのにテキストボックスの中身が空になった!」みたいに見えるってわけです。

このプロパティを「カレントレコード」にすれば、Enterキーを押しても、次のレコードに移動しなくなります。同じレコードの中で、つまりエゾジカならエゾジカのレコードがフォームに表示された状態で、カーソルだけぴょこぴょこ動くってことになります。

この方が都合がよい場合もあると思いますし、Enterキーがんがん押して次のレコードに移動していく方が何かと便利、ということもあると思います。まあ、ケースバイケースってことで、上のプロパティで調節するのだということ、確認しておいてください。

んじゃー今日はせっかくなので(なにが)、「カレントレコード」にしておきましょうか。テキストボックス2個しかないし、入力が必要なのはそのうち1個だけですから、移動しない方がよさそうですよね。


次にー・・・。
フォーム開いたとき、「新規レコード入力」状態にしたい、っていうのは、これはいろいろやり方があると思います。

「このフォームを通じて新規入力しかしない」ということなら、↑フォームのプロパティの「データ入力用」を「はい」にすれば、このフォームからは新規入力しかできなくなります。

前に入力したレコードとかは、このフォームを通じては、見えないってことです。
このフォームから、って意味ですよ。テーブルからレコードがなくなるとか見えなくなるとか、そういうことじゃないです。フォームとテーブル、時として分けて考えるようにしてくださいね。フォームAはテーブルAのレコードとつながりを持ちますけど、オブジェクトっていう点では、それぞれ独立した固体ですからね。

では、以前入力したレコードについても、参照したいし、でもフォーム開いて一番最初は新規入力状態、っていう場合は、うーん、そうですねぇ。フォームを開くときのイベントで、新規レコードにレコード移動、ってのがいいんじゃないでしょうかね。

フォームの「開くとき」っていうイベントプロパティで、新規レコードに移動するようアクションとってみましょう。
すでに、Form_AfterInsertっていうプロシージャ作ってますんで、その下あたりに、Form_Openっていうプロシージャができる形になると思います。こちらの方はとりあえず一行だけ。。。

マクロの、「レコード移動」っていうアクションをVBAで書いたら↑こうなります。
マクロ作ってもいいんですけど、たった一行で済みますし、ひとつのフォームに関するもろもろの動きは1箇所にまとまって書いてあった方があとあとわかりやすいかなーと思ったもんで。

じゃ、フォームを保存して閉じましょう。
で、改めて、フォームAを開きます。

ちょっとわかりにくいですが、多分「新規入力状態」になってるんじゃないでしょうか。
まー、もうここまできたら、[番号]のテキストボックスにカーソルが入らないようにしといた方がよさそうですよね。[名前]の入力だけすればいいようにしちゃいましょうか。
[番号]のテキストボックスの↓「使用可能」「編集ロック」を、それぞれ「いいえ」「はい」に変更しましょう。

ついでにテキストボックスの色も、↓透明にでもしておけば、入力しなくてもよいということが入力者に伝わりそうですよね。


さて、ここまでのところ、いかがでしょう。うまくいってますか??
では・・・「なぜ名前の入力をしても、番号は空欄のままなんでしょう」という点ですが・・・。
まず、みなさんのフォーム、名前の入力をしても、番号の欄、表示されてないですよね。表示されてる人はそれでいいんですけど、わたしのは番号の欄、最初はゼロって出てたんですけど、テキスト型にしてからゼロすらも出なくなっちゃったんですよ。これは、なんでですかね?

これはですね。
今、番号を自動的に採番する仕組みを、「フォームに新規レコードが挿入された後(After_Insert)」に動くようにしてるからです。そうしましたよね??もう一度おさらいしておいてくださいね。
つまり、「名前」の入力をして、Enterキーとか押したり、新規レコード入力のためのウニボタンをクリックした後、次のレコードに移動したときに、自動的に番号がつくのです。正確にはAfter_Insertっていうプロシージャが動くのです。
なので、番号はついてるんですけど、ついた瞬間にわたしたちの目には「新規入力行」が表示されるので、何番がついたのか見ることはできないわけですね。

つまり、↓この図で行くと、ピンクの矢印の先にカーソルが移動したときに、「アリクイ」にAAA-00000011という番号がつくのです。番号はついてますけど、そのときは既にピンクの矢印の先の行がフォーム上表示されてるわけで、アリクイの行はひとつ前のレコードになっちゃってるわけですね。