<HOME  <お願い事項   <Access2002 TOP   <Access97 TOP   <サイト内検索
 MS-Access2000超入門部屋--基本操作をさらに考える
   >00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 



さて・・・。では、次に・・・。
ここまでの感じでも、十分実用に耐えられるフォームになってると思うんですが、今回最大の難関と思しき「行番号の自動採番」に挑戦してみようと思います。

ああ、でも別に、そんなに難しくはないですよ。
難しいと申し上げたのは、他に意味があるんです。

とりあえず、いろいろやってみますので、興味ある方は挑戦してみてください。

自動で番号をふるやり方は、伝票番号を作るときやりましたよね。あの方法、使えるんじゃないかな?って思った方も多いと思います。
やってみましょう。

えーと、サブフォームの方に、新しいレコードが追加されたとき、ってことでいいでしょうか。

「挿入前処理」がいいかもしれないですね。

コードビルダを使って、「更新前処理」にイベントを作ります。

で、こんな感じのイベントを作ってみます。
DMax関数を使って、売上明細商品テーブルの行番号の中で一番大きな値に、1を足して、新しい行番号にするってわけです。

これでいけるかな???


ありー・・・・。
なんでいきなり「4」とかつくの・・・?????

よーくテーブル思い起こしてみてください。
確かに、フォーム上ではこれでいいのかもしれないですけど、DMaxというのは、テーブルやクエリーの中を直接見に行く関数です。したがって、左の図で行くところの赤い枠内で、一番大きな数字に対して1を足し算するわけですね・・・。

うーん、これじゃだめか・・・。

少なくとも、「同じ伝票番号の中で、最も大きな数字に1を足す」って構造にしないと・・・。

やってやろうじゃありませんか!ねえ!


ちょっと複雑になりますよ。DMax関数、ヘルプでもういちど見ておいて下さい。

構造は・・・。

DMax("フィールド名","テーブルまたはクエリー名","なんか特別な条件式とかあれば")

ピンクのとこは省略可能な引数です。今まで省略してたとこを使うのです。ここに、「同じ伝票番号の中で」って条件をつけるんです。
これが、難しいかもわかんないですが・・・。

ダブルコーテーションのつけ方が難しいかもわかんないですが、ヨーク見るとちゃんとルールがあるんですよ。謎解きみたいな感じですが・・・。

Me![行番号] = DMax("行番号", "売上明細商品", "伝票番号=" & Forms!売上明細![伝票番号]) + 1

ピンク色の部分が問題の個所ですが・・・まず、ダブルコーテーションで囲んでるものと囲んでないものがあることに注目してください。
そして、基本的にはすべてダブルコーテーションで囲むものだということも。

囲んでいないところは何か???と、よく見ると、Forms!売上明細![伝票番号]と、いうのはつまり、フォーム上の伝票番号のテキストボックスのことですよね。

しかも、今この処理をしているときはカーソル、というか処理の対象はサブフォーム上にあるので、くっついてるといってもメインのフォームは外野なんです。
なので、Me!は使えない。だからForms!と、まどろっこしい方の書き方をしています。

本来ならば、"伝票番号= Forms!売上明細![伝票番号]"でよいはずなのです。

でも、これだと、Accessはアホだから「伝票番号がForms!売上明細![伝票番号]のものだね〜」と思い込んでしまいます。実際の伝票番号が2544であっても、Forms!売上明細・・・と入力されているレコードを探します。そんな入力、逆立ちしたって入力されないですよね。とりあえず、Fなんて文字が伝票番号欄に入ってくることはありえません。ありえませんよね。伝票番号って数字ですよね。

そう。"伝票番号= Forms!売上明細![伝票番号]"だと、「Forms!売上明細![伝票番号]」という伝票番号を探してしまいます。

Forms!・・・という書き方は、実在するテキストボックス名などを、変数っぽく表している書き方なので、こういう関数や式の中で書き込むときは、この書き方そのものが関数にわたってもしょうがないんです。だから、ダブルコーテーションの外に出します。

"伝票番号="  Forms!売上明細![伝票番号]

でも、これではエラーになります。"伝票番号="Forms!売上明細![伝票番号]が分断されちゃってるからです。

なので、このふたつを半角の&でつなぎます。

ね、ちゃんと法則があるでしょう?この法則、理解できるようになると、関数とか式を書くときすごく楽ですよ。
関数に関しては実際には、Accessのバージョンによって多少書き方が変わることもありますから、必ずヘルプを見ること。そしていろいろ書いて試してみること。このふたつは必須ですけどね。


ありー・・・。
なんも付けてくれないなぁ・・・なんでじゃ???????

よく考えてみればそうですよね・・・。
まだ、サブフォームの中には「2544と同じ伝票番号のレコード」が1件しかなくて、その1件に行番号をこれからつけようとしてるんだから、「2544と同じ伝票番号を持つレコードの中で最も大きな値」自体がないんですよね。まだ・・・。
ないから、DMax関数は、なんも答えを出してないはずなんです。
なんもないから、なんも出してないんですね・・・。

ってぇことは!「2544と同じ伝票番号のレコードが1件もなかったら行番号は1、それ以外だったら最大値に1を足した数」っていう具合にしないとならないんですね。
あーーーーーめんどっちーーーーー!!!!!

で、下のようになります。If文を使って分岐させます。If文はどういう時使うものか、だいたい皆さんご存知ですよね。

If DCount("行番号", "売上明細商品", "伝票番号=" & Forms!売上明細![伝票番号]) = 0 Then

 
Me![行番号] = 1

Else

 
Me![行番号] = DMax("行番号", "売上明細商品", "伝票番号=" & Forms!売上明細![伝票番号]) + 1

End If

もし○が×だったら。。。という条件判断の部分。
今回は、売上明細商品テーブルの中で伝票番号がメインのフォームの方の伝票番号と同じモノの行番号の数が(簡単に言っちゃうとレコード件数がって感じでしょうか)ゼロだったら、ということですね。

条件判断の結果がYESのときやること。今回は、行番号に1を代入します。

条件判断の結果がNOのときやること。今回はDMax関数を使って新しい行番号を作ります。

と、いう感じですね。


と、今度はどうでしょう。
商品番号選んだとき、行番号がつきます???

わはは〜すっげー大変でしょ。もちろん、もっと簡単な方法もあるとは思いますが、とりあえずココで意識してもらいたいのは

「"前の番号"って考え方はない」っていうことです。

これって最初にお話しましたよね。

だいたい察していただいてる方もあると思うんですけど、Accessに限らず、データベースって呼ばれるものは、「レコード単位」の処理をします。
レコードはひとつひとつ独立しているのです。

なんか表のような形をして、レコードが固まってくっついて存在しているみたいに思えてしまいますけど、物理的にはくっついてるわけじゃないんですよ。だから、1件データ入力したからといって「テーブルの保存」とかやんなくても、ただ入力すれば1件データが入る。Excelとか表計算ソフトは、表全体でひとつのデータを表しますけど、データベースってモノはたいがい、レコード単位で考えます。
だから、「このフォームの、一つ前の行番号」っていう情報を、容易には引き出せないんです。

最初に「難しい」と申し上げたのはこういうことなんです。操作が難しいわけじゃなくて、レコード単位の処理、ってところをうまく理解するのが、もしかしたらよくわからんぞ、っていう方もいらっしゃるんじゃないかと・・・。特に表計算ソフトになれちゃってる方は、「Accessって使いにくい、なんか不便」って思うかもしれないですね。

だから、Excelと同じように使おうとしても無理が出るんですよ。わたしはExcelとAccessを比較して同じように使おうとするのには反対です。うまく使い分けるために比較するのはよいことだと思いますが、ヘンにExcelと比較しても何にもならないですよ。だったらExcel使えばいい。

Accessでのデータの仕組み、構造を理解しようとしないで、ただExcelと同じように使おうとするなら、Accessはたいして便利でもないし、返って使いにくいと思う。Accessを活用するなら、「データベース」たるデータの仕組みを少し理解して取り組んでいってくださいね。Excelにもデータベース機能がありますけど、Excelはデータベースじゃないですからね。