<HOME  <お願い事項  <Access2000 TOP   <Access97 TOP   <サイト内検索
  Ac2002--VBAの沼 > フィールドをレコードにする
  



フィールドをレコードにする

もうひとつ例を・・・。皆さん、テーブルを設計するとき、いろいろ悩みながら作ってらっしゃると思います。
ウチの社員の、いろいろな活動を記録する必要があるんですけどね。
そこで、こんなふうに↓、各月ごとに集計した値を入れるテーブルを作りました。

こんなふうに値を入れてます↑
また、次の年の1月の活動結果を入力するときは、もうひとつフィールドを増やして底に入れてます。

これでも、いいことはいいんですけど・・・。
「ガメラさんの今までの活動集計」を出したいとき、ちょっと面倒なんですよね。



こういう場合の「横方向の集計」は、クエリなどの中で、各フィールドの値を足し算する式を鬼のように作ってやらないとなりません。

それに、フィールドが増えたら、式を書き足さないといけません。
書き足せば答えは出ますけど、めんどくさい・・・忘れがち。
何とかならないの???

こういうテーブルの構造だと、MS-Accessのような「リレーショナルデータベース」の特性を活かせないのです。
縦方向に伸びるテーブルならば、集計もらくらくなんですけどね。なかなかこういうテーブルをシッカリ設計するのって、難しいです。

そこで・・・。
ある程度値が入っちゃってから、横に伸びてしまったテーブルを縦方向にきれいに整頓して、集計や検索しやすいテーブル構造に変えるプロシージャを作ってみましょう。
といっても、今までの内容がバッチリならば簡単ですよ。


まず、こんな感じのテーブルを作っておきます。

必ずこういうテーブルじゃないといけないかというと、そういうわけじゃないんですが・・・。
今日は練習なので、分行き掴むためにも同じようにやってみてください。

今回の処理のミソは、[1月の成績]というフィールド名が、[活動テーブル2]の[活動内容]フィールドの値になる、というところです。
なので、処理の内容としては、単にレコードを順番に読み取るだけでなく、1レコードの中の各フィールドの値とフィールド名を読み取っていく必要があります。横方向にも手を伸ばさないとならないわけです。

  [活動テーブル]のレコードを1件読み取る
      [活動テーブル]のフィールドの最後まで、処理を繰り返す
         [番号]を[番号]に代入
         [名前]に[名前を代入]
         [活動内容]に「フィールド名」を代入
         [点数]にそのフィールドの値を代入
      そのレコードの最後のフィールドまで処理が終わったら、次のレコードに移動
  [活動テーブル]のレコードがなくなるまで繰り返す

と、まあ、こんな感じになります。

フィールド名というのは、rs1というレコードセットのプロパティとして拾うことができる仕組みになっています。
配列とか、コンボボックスの列の値とかとおんなじ感覚で、

   rs1.Fields(xxx).Name

これで、「rs1の中の、xxx番目のフィールドの名前」という意味になります。

   rs1.Fields(xxx)

これで、「rs1の中の、xxx番目のフィールドの中に入力されている値」という意味になります。
つまり、またがんばってループさせて、そのテーブルの中にいくつフィールドがあるか数えて、その数に達するまで、処理を繰り返すようにすれば、横に伸びたデータを縦にすることができるわけです。

じゃ、やってみますか。
基本的なところは、まずこんな感じに書いてみました。

次に、テーブルにいくつフィールドがあるか数えます。
数えるために変数もいりますよね。

これで、[活動テーブル]にフィールドがいくつあるか、Aという変数に入ります。
試しに、変数Aの中身をこういうふうにデバッグプリントしてみると・・・。
[活動テーブル]のフィールド数が返ってきます?

14列あるわけですよね。
そしたら、14列目のフィールド名を知るためにはこうすればいいわけなんですが・・・。
じゃあ、こんなふうに↓して、14列目のフィールド名をイミディエイトウィンドウに返して試してみますと・・・。

ギャー!なにこれ!何でこんなエラーが出るの????????

落ち着いて(わたしか)。
このエラーはですね。
そんなフィールド、ありませんよ、という意味のメッセージです。何を?どういうこったよ。
14列あるうちの14番目の列を見せろといっているのに、ないだと?アホぬかせ!

・・。
これね、コンボボックスとか配列のときもそうでしたけれども、必ず 0 から始まるんですよね。
なので、一番最後の列は、

  rs1.Fields(13).Name

になるわけなんです。14列あるのに、13番目なんですよ。0番目から始まるから。
これすごくややこしいので、お薦めは最初に1引いとくやり方です。

こうしておくとわかりやすいかなぁと思います。

後は、ループを2重にしてやればOKのはず。

  外側のループは、[活動テーブル]の最後のレコードまで回すループ
      内側のループは[活動テーブル]の最後のフィールドまで回すループ

わたしはこんな感じにしてみました。
これを実行すると・・・・。

[活動テーブル2]には、↑このようにレコードが出来上がります。
できましたですか?

繰り返しテストをするときは、このテーブルのレコードを全件削除してから、プロシージャの再実行をしてくださいね。
え?なんでかって?んもーーーまだそんなこと言ってるんですか!!!どうなっても知りませんよ!!!

上の「仕上がり」を見て、もし、
   ・[ID]が2番から始まるのが気持ち悪い
   ・[点数]がところどころ空っぽになってるので、これを何とかしてを入れるようにしたい
などなどの場合は、

こんなふうに、AddNewの中を工夫していくと、いい感じだと思います。



なるべくならば、こんなコードを書かなくて済むように、用途にあったテーブル設計をしていきたいもんなんですが・・・。
たまには・・・どうしようもないときもあります。
そういうとき、こういうコードを書いて処理を通すことで、足並みをそろえる、なんてことも、やらないとならない場合があります。
なので、こうしたコードのパターンをいくつか承知しておくことも、いつか役に立つかもしれないな・・・と思いますよ。

テーブルのデータを扱うプロシージャを極めるには、やっぱりいろいろなサンプルコードに目を通すことですね。
できれば、皆さんのお仕事の内容に似た感じのデータベースを例題にしている本を探してご覧になるといいと思います。
その業界その業種独特の「データの扱い方」って、ありますもんね。



波長の合う内容の書籍を手元に一冊置かれておくと、とてもよいです。
やっぱり、コードの書き方の事例みたいなのをたくさん見ておくのが、一番応用が利くと思うんですよね。