練習3:納品書作成データベース(3)
前のページで作ったクエリを基にして、いよいよ「サブフォーム」を作成します。
サブフォームの作り方には、前回やったような 「フォームウィザードを利用して作る方法」 の他に、今回挑戦する 「親フォームと子フォームを別々に手作りし、手作業で埋め込む方法」 があります。Access2007になって、ナビゲーションウィンドウが左端に常に出ている状態になったことなどから、今回挑戦するこの方法も、なかなか侮れなくなりました。もしかしたら、「コッチの方法のほうが、わかりやすいわ」 という方も多いかもしれません。
ではでは、例によってゆっくりゆっくり、ひとつひとつ丁寧に進めてまいりましょう。
親フォームを作る
「Q_納品」を基にして、新規にフォームを作成しましょう。
と、いう展開になったら、どういう操作をすればいいか・・・もうばっちりですよね。
図1:「Q_納品」を基にフォームを作る、と言われたら?
フォームができました。
このままでも使えないことはないんですが、デザインをもうちょっと整えたいところです。
ポイントとしては、
■フォームヘッダー部分: ”Q_納品書”じゃなくて・・・
■テキストボックスの大きさや位置を調整したい
図2:このままでもいいんだけどね
デザインビューに切り替えて、細かいところを調整していきましょう。
切り替えは、左上の「表示」で切り替えても、右下の小さなボタンで切り替えても、どっちでもいいですよ。
図3:どっちでも切り替えられるぞ
まず、フォームヘッダー部分にあるラベルの内容を、クエリの名前ではなく、このフォームに見合った文言に変えましょう。「納品書」でいいんじゃないでしょうか。
それから、フォームヘッダー部分を少し狭めましょう。
右図を参考にしていただきながら、フォームヘッダーの境界線にマウスポインタを当て、上方向にそっとドラッグしてください。
図4:まず、ヘッダー部分の調整
次に、各テキストボックスの大きさや位置を、個々に調整したいので、コントロールレイアウトを解除します。
右図の順序でコントロールレイアウトを解除してください。
図5:わんつーすりー、と
テキストボックスの位置、サイズを調整します。
お任せしますんで、よく見かける納品書をイメージしながら配置してください。
といっても、このフォームをそのまま印刷するわけじゃないので、とにかく ”入力しやすそうな配置” をイメージしていただければいいかな、と思います。
図6:どういう順番で入力する?
さらに、今回は、このフォームの中に別のフォームを埋め込むので、フォームをもうちょっと広げておきましょう。
右図のように、フォームの下部分をそっとドラッグして広げましょう。
フォームは「セクション」と呼ばれる部分の組み合わせで構成されてるんです。このフォームは、
■フォームヘッダーセクション(上の青い部分)
■詳細セクション(メインとなる部分)
■フォームフッターセクション
(折りたたまれていて非表示になっている)
の3つのセクションで構成されてますよ。フォームの中をじっくり観察してみてくださいね。
通常はあんまり「セクション」という言葉自体は使いませんが、市販の書籍などではときどき出てくるかも。ついでに覚えておいたほうがいいかもしれないですね。
図7:広げよう、詳細セクションを
私は、「通信欄」は、下の方に配置しました。
で、真ん中の部分に、後ほど作成するフォームを埋め込む予定です。
まだ、なんだか、「どうなっちゃうの?」って感じですが・・・とにかく先に進みましょう。
図8:びろーん
このフォームに名前をつけて保存します。
「納品書フォーム」とかつけておいてください。名前はお任せします。後でワケわからなくならなければOKです。
図9:名前をつけるアル
フォームビューに切り替えます。
ちょいと、入力テストのようなことをやっておきましょう。
図10:フォームビュー!!
「伝票番号」に適当な数字を入力し、「会社番号」を入力します。
クエリ作ったときにやったことと同じことですね。
会社名、出ます?
ここまでの作業、OKですか?フォームのデザインを調整するところは、もう皆さん、慣れたもんですよね。
あと、クエリによるテーブル同士の結びつきや、会社番号を入力したら会社名が出る、ってとこの仕組みも、特に問題ないですよね。
じゃあ、もう一歩進んだお話をしても、混乱したりしないですよね。それでは・・・
「伝票番号を自動的に採番(付ける、振る)する」ということをやりましょう。
具体的には、そういう「イベント」を作ります。イベントはマクロかVBAで作成するんですが、マクロは前回ちょっとやったので、今日はVBAに挑戦しましょう。
図11:会社名、出るよね?
伝票番号を自動的に振る処理を作る (コードビルダ)
右図の順番で、フォーム全体のプロパティを出します。
フォーム全体に関する操作をするときは、フォーム右上の四角い部分(フォームセレクタ、と呼びます)をクリックしますよ。右図のマルイチ番の部分ですね。
図12:フォームセレクタとはどれ?
今回作成する 「伝票番号を自動的に採番する」 といったイベントを作るには、 「いつ」「何を」「どうする」 の3つを、あらかじめしっかり考えておく必要があります。
漠然と「伝票番号を自動的にぱって付けたいんだけどどうすればいいの?」と願っているだけでは、おそらく完成しません。
「何を」と「どうする」がごちゃ混ぜのときもありますが、「いつ」だけは明確にしておいたほうがいいでしょう。
今日は、操作手順をお話しするところに重点を置きますので、「いつ」「何を」「どうする」は、私が考えた通りにやってください。イベントを作る操作に慣れてきたら、ご自分で考えてみてくださいね。
で、今回はというと・・・
いつ? → 「新しいレコードを新規に追加入力するとき」
何を(に)→ 「伝票番号テキストボックスに」
どうする → 「納品テーブルの伝票番号の中で一番大きな番号に1を足した数を入れる」
です。まず、この三つを、じっくり噛み締めて理解しておいて下さい。
プロパティシートの「イベント」タブをクリックし、「挿入前処理」というイベントを探してください。
見つかったらクリックして選択し、さらに、右端に表示されたビルドボタンをクリックします。
これが、「いつ」です。
要は、イベントの一覧の中から、処理を実行するタイミングとして良さげなものを選ぶ、ってことですね。
今日は、「レコードを新規に追加するとき」なので、「挿入前処理」がいいでしょう。「挿入後処理」ってのもありますが、伝票番号は主キーにしているので空っぽは厳禁。レコードを追加して一番最初に付いたほうがよさそう。
図13:いつ?
コードビルダを選びます。マクロを作るならマクロビルダですが、今日はVBAで処理を作りますので、コードビルダを使います。
図14:コードビルダ
なんか妙な画面が出てきましたね。Accessのウィンドウとは別に、Microsoft Visual Basic・・・というタイトルのウィンドウが開きました。これが、VBAを入力するための専用画面です。
図15:Visual Basic Editorとか呼んでた時代もあったけど
Private Sub から End Sub までの間に、「伝票番号を自動的に振る」という処理を書き込みます。
Form_BeforeInsert というのが、「挿入前処理」 っていう意味ですね。Form_BeforeInsertという名前のプロシージャを作成している、ということになってるんですよ。いつの間にか。まあ、そういうことは気にせず、続けましょう。
図16:真ん中にカーソルがあるでしょ?
少しずつ入力していきますので、途中で無意識に勢いあまってEnterキーを押したり、他のとこクリックしたりしないでくださいね。
まず、右図のように、左辺を入力します。
Me!伝票番号= 記号は半角ですよ。
図17:記号は半角だぞ。それと、まだ途中だからEnterキーとか押すなよ
続けて右辺を入力します。
記号は全部、半角ですよ。
図18:dmaxってのは関数の一種だ。
dmax("伝票番号","納品テーブル")
dmaxとは、定義域関数という種類の関数の一種で、「納品テーブルというところの中にある伝票番号というものの中で、一番大きな値を調べてきて知らせろ」 という意味合いになります。maxってのは、最大って意味ですもんね。
そう。ご名答。dmin っていう関数もあるんですよ。こちらは最小値を調べるときに使います。でも、dmaxのほうが良く使うかな・・・でぃーまっくすって読む人が多いですね。dminはでぃーみにまむ、でぃーみむ、かな。
他にも、dsum、davg、dcountなどがあるよ。だいたい、どんな意味合いか検討が付くんじゃないかしら。ふふふ。
ここまで入力して一区切り。他の行にカーソルを移動させたり、あるいはEnterキーを押してみましょう。
関数名が大文字混じりになったり、ちょっとスペースが空いたりしましたよね。右図のようになれば成功です。
図19:赤字になったりしたら、エラーだよ。どっか違うんだきっと。
仕上げに、この関数によって調べてきた最大値に、1を足します。これで、今まで使われていない伝票番号を作り出すことができるって寸法です。
図20:イチを足すのを忘れんなよ
■■■(ここからは、オマケです。気持ちにゆとりのある人は挑戦してみてください。■■■
ここで、ごくごくわずかな、1パーセントにも満たないかもしれない「例外」について考えます。
もし、「納品テーブル」の中身が、0レコードだったらどうなるんでしょう。まだテーブルを作ったばかりで、テストデータも入れてなくて、0件だった場合・・・。要は、「伝票番号の最大値」を探したいのに、「伝票番号」自体がまだひとつもない状態です。DMax関数は答えを探し出すことができない、ということになります。
該当する値が見つからなかった場合、DMax関数は Null という答えを出してきます。Nullとは、「値の無い状態」「空欄」のことで、0ではないんです。Nullに1を足すことはできないんです・・・。つまり、この処理はエラーになってしまいます。
これを避けるための方法はふたつ。ひとつは、「納品テーブル」にダミーでも何でもいいのでとにかく最低でも1レコード、必ず入れておきます。まあ、安全パイですね。
もうひとつの方法は、これからやりますよ。「もし納品テーブルのレコード件数が0だったら」 という条件をつけるんです。
マクロでも似たようなことやりましたよね。VBAで「もしも・・・だったら」って、どうするのかといいますと・・・
(余裕のある人はトライ)まず、条件式を入力します。右図のように、すぐ上に一行、式を入力しましょう。
図21:メモ帳なんかと同じ感覚で、Enterキーで改行して一行空けてみよう
if dcount("伝票番号","納品テーブル")>0 then
大文字小文字は後で自動的に変わりますので、全部小文字で入力するんでOKです。むしろ、全部小文字で入力しておいたほうが、ちゃんと式として認識されたかどうか、大文字に変わる箇所があるか否かでわかるので、ちょっとしたスペルチェックにもなってお奨めです。
記号は全部半角ですよ。私たちは、英語圏の人たちよりちょっぴり、こういうツールを使いこなすのに労力が要るんですよね。
そしてdcount関数。納品テーブルのレコード件数を調べます。数えるのは「伝票番号」以外のフィールドでも何でもいいんですが、「伝票番号」は主キーですんで、絶対値が入ってますからね。主キーを数えるのがいいかなーと思いますよ。こういうときは。
つまりこれで、「納品テーブルのレコード件数が0じゃなかったら」という意味になりますね。マイナスってことはあり得ないので、ゼロ以上、って考え方でよいと思います。
(余裕のある人はトライ、の続き)次に、それ以外、という処理の分岐を作ります。それ以外、ってことは、レコード件数がゼロのとき、ってことですね。
ゼロ件のときは、伝票番号はイチから振っていいんじゃないかと思うんで、1 を代入しましょう。1は半角の数字ですよ。当たり前だけど。
図22:いふ、ざん、えるす、えんどいふ
(余裕のある人はトライ、は、ここまで)これで完成です。条件ごとの処理を見やすくするために、右図のように行頭位置をずらすみたいなこと、よくやりますよ。
これは決まりではないので、行頭位置が揃ってても問題はないです。好みですね。
行の一番左端にカーソルをおいてTABキーを押すと揃えやすいのでお奨めです。
図23:気持ちの問題だけどね。見やすいかどうかなんて。
この段階では保存などは特にしなくてもいいんで、このウィンドウを閉じましょう。
まあ、保存してもいいんですが。。。今やっている操作は、フォームのプロパティの一部の操作ですから、フォームに戻ってから上書き保存すれば十分ですからね。
図24:閉じて、フォームの操作に戻るぞ
フォームに戻ったら、フォームビューに切り替えてちょっとした入力テストをやってみましょう。
さっき入力したレコードが残っているなら、新規にレコードを追加します。フォーム下部分の移動ボタンをクリックして新規入力行に移動しましょう。
私は、さっき、テスト入力するとき、「伝票番号」に1って入力したのですが、皆さんの中には1以外の数字を入力した方もいらっしゃると思います。その辺も少々、ポイントになりますよ。
私の場合、「納品テーブル」の「伝票番号」の最大値は、今のところ、1 です。と、すると・・・?
図25:新しく一件、レコードを追加するなら?
「伝票番号」は入力せず、「会社番号」を入力します。
そうすると、「伝票番号」が自動的に振られるはず。
私は、「納品テーブル」の「伝票番号」の最大値が 1 でしたから、1に1が足されて、今回自動的に振られた番号は 2 ってことになりました。
皆さんはどうですか?
テストが終わったら、このフォームは閉じておきましょう。
図26:番号が付いたぜ
「伝票番号」は「納品テーブル」の主キーですから、常に異なる番号が付かなければなりません。なので、今回は、もっともシンプルだと思われる「最大値に1を足す」というやり方を採用しました。
もちろん、100を足して100番ずつ飛び飛び番号をつけてもいいし、999999から1ずつ減らしていく、とか、仕組みや目的がはっきりすれば、やり方もいろいろ考えられそうですよね。
そう。忘れないでくださいよ。目的は、「毎レコード、異なる伝票番号を振る」というところにあるんです。
今回は、「1を足す」というシンプルな方法を実践していただくために、「伝票番号」を数値型にしました。テキスト型では、足し算ができませんからね。うーん、ちょっと違うな。そのままでは足し算ができない、ってところですかね。
つまり、「伝票番号を、001、002・・・って付けたい」とか、「A-001、A-002というふうに、記号や英文字も含めたい」という場合は、当然、「伝票番号」のデータ型をテキスト型にしないとならないわけで、そうなると、単純な足し算だけでなく、もうちょっといろいろやら無いといけないわけです。
でも、全ての基本は、今日やった「最大値に1を足す」ってやり方です。このイベント作成で「難しい、ぜんぜんわかんない」だと、残念ながら「A-001、A-002というふうに・・・」も、まだ無理ではないか・・と言わざるを得ません。自動採番の基本は「最大値に1を足す」なので、ぜひ、今日やった内容に手ごたえを感じてください。
このページのまとめなど
- サブフォームは、フォームウィザードでなくても、手作りでもできる。まずは、親フォーム子フォームをそれぞれ作るところから。
- 親フォームのどの位置に子フォームを埋め込むかイメージして、スペースを作っておこう。
- 自動採番の第一歩は、「最大値に1を足す」。DMax関数やDCount関数など、定義域関数をうまく活用しよう。
- いきなり複雑な処理を望まず、シンプルな処理をひととおり作ってみよう。マクロやVBAによるイベント作りの基本ですぞ。
作成日:2009-1-27