[三流君] −−> [VBAで楽しく] −−> [バックナンバー一覧]
−−> No.147 テーブルをつなげないクエリーとクロス集計クエリー

テーブルをつなげないクエリーとクロス集計クエリー

メルマガ発行内容

<テーブルをつなげないクエリーとクロス集計クエリー>

どうも、三流プログラマーのKen3です。 今回は、 テーブルをつなげないクエリー と クロス集計クエリー を使用して、小細工をしてみたいと思います。 今回の、サンプルファイルは、 http://www.ken3.org/vba/lzh/vba147.lzh にdb147.mdb(Access2000版)が保存されています。 ※クエリーやデータをいじって、遊んでみてください。 ※あまり、お薦め出来ないけど、こんな方法もあるんだってことで。

/* * 1.今回のキッカケ */

VBA系の掲示板 http://www.ken3.org/cgi-bin/bbs/vba/wforum.cgi に来た質問です。 ---- 以下のようなテーブルを クエリーで横方向に展開することは出来るのでしょうしょうか? 何かいい方法があれば教えてください! よろしくお願いします。 商品 支払年月 支払回数 月額 1 商品A 200303 5 3000 2 商品B 200305 2 2000 3 商品C 200303 12 1000 ↓ 商品 200303 200304 200305 200306 200307 200308〜200402 1 商品A 3000 3000 3000 3000 3000 2 商品B 2000 2000 3 商品C 1000 1000 1000 1000 1000 1000 〜1000 -------------------------------------------------------- と もらった質問で少し考えてみました。

/* * 2.クロス集計クエリーを使いたいけど、レコードが足りない・・・ */

一番先に頭に思い浮かぶもの、 Excelだったら、分析系のピボットテーブルで行と列指定、 Accessだと、あまり使ったこと無いけどクロス集計クエリーってのがあったなぁ。 あっ、でも、 商品 支払年月 支払回数 月額 1 商品A 200303 5 3000 の1レコードから、 商品 200303 200304 200305 200306 200307 200308〜200402 1 商品A 3000 3000 3000 3000 3000 と 5つの項目は作れないか。 レコードの作りが、 商品 支払年月 月額 商品A 200303 3000 商品A 200304 3000 商品A 200305 3000 商品A 200306 3000 商品A 200307 3000 ってなっていれば、行を商品、列を支払年月のクロス集計でいいんだけど。 ワークテーブル作って、支払回数分、レコードを発生させるかな・・・ ^^^^^^^^^^^^^^^^^^^^ それが王道の処理なんだろうけど、 今回も小細工してやるぞ〜と、三流君の悪い癖が・・・ ※参考程度にしてね。

/* * 3.問題なのは、レコードが足りないってことなので、強引に増やす */

問題は、はっきりしてるんだよね。 支払回数分レコードがあれば、クロス集計クエリーが使えるんだよねキット。 支払数分、レコードを増やすかぁ・・・う〜ん。 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ まぁ、昔の人がよく言ってたり、偉そうな先輩が飲んだ時語っていると思うけど、 失敗を成功に生かす的な言葉で、 失敗は成功の元、会社によっては、失敗は成功の母とか言ってるよね。 Accessでクエリー作成していると、 2つのテーブルをつなげるリンクを忘れたりしないと思いますが、 もし、明細とマスターデータをつなげるのを忘れたら?どうなるでしょう? 隣のASPの例だけど、 http://www.ken3.org/cgi-bin/test/test073-1.asp でテストできる SQL From句にテストで2つのテーブルデータを指定(つなげない) を見ると、 Select * From T_月別売上, T_商品 と、条件無しのSQL文を発行してます。 すると、どうなるか? T_月別売上 が 8件 T_商品 が 6件 このデータ が 48件のレコードを返してきます。 T_月別売上の1件に対して、リンクしてないので商品6件分データが作成されます。 これって、明らかにミスなんだけど、今回は、そのミスを利用してみます。 ダミーのテーブルを1つ作成します。 テーブル名はDummyCnt フィールドはCNTと数値型でデータを作成して、 0〜データを入力します(0から連番で予想される最大支払回数まで作成する) ↑ダミーテーブル、データイメージ そのダミーテーブル と DATAテーブルをつなげない、 そんな欠陥クエリーを作成します。 クエリーを実行すると、DummyCntで作成したレコード数分同じデータが作成されます 商品 支払年月 支払回数 月額 CNT A1 200303 5 3000 0 A1 200303 5 3000 1 A1 200303 5 3000 2 ・ ・ A1 200303 5 3000 19 A1 200303 5 3000 20 B1 200305 4 5000 0 B1 200305 4 5000 1 とクエリーの結果が作成されます。 ※0〜20と21個のダミーデータを作成してます。 ↑ダミーテーブルとリンクしないとこんな感じです。 -【けんぞう!】--------------------------------------------------------- 月500円、タバコなら2箱、120円缶コーヒーなら4缶分の謝礼をGetするなら http://www.ken3.org/etc/500yen/ ←無料アンケート系の広告です。 『チッ、がんばって回答して月500円かよ』(お馬鹿なプログラマー:31歳) ------------------------------------------------------------------------

/* * 4.増えたデータを調整する */

商品 支払年月 支払回数 月額 CNT A1 200303 5 3000 0 A1 200303 5 3000 1 A1 200303 5 3000 2 こんな、欠陥データ作られても、困るんだよね。 固定でn件データが増えても使えないでしょ? ほしいイメージは、 ^^^^^^^^^^^^^^^^^^ 商品 支払年月 支払回数 月額 商品A 200303 5 3000 だったら、 商品 支払年月 月額 商品A 200303 3000 商品A 200304 3000 商品A 200305 3000 商品A 200306 3000 商品A 200307 3000 の 5件なんだよ。 ~~~~ ですよね、 そこで、演算フィールドを作成して、それに近いデータを作ります。 ^^^^^^^^^^^^^^^^^^^^^^ まずは、200303,200304,200305,200306,200307と、月数を増やしたいので、 基準の200303の文字列を日付型にCdate変換してから、 DateAddでCNT月後を計算してみます。 支払中: DateAdd("m",[CNT],CDate(Left([支払年月],4) & "/" & Mid([支払年月],5,2) & "/01")) と、計算式を作成して、支払中フィールドを作成しました。 すると、 支払年月にCNTを+したフィールドが作成されます。 商品 支払年月 支払回数 月額 CNT 支払中 A1 200303 5 3000 0 2003/03/01 ←03月+CNTで3月 A1 200303 5 3000 1 2003/04/01 03月+CNTで4月 A1 200303 5 3000 2 2003/05/01 03月+CNTで5月 A1 200303 5 3000 3 2003/06/01 03月+CNTで6月 A1 200303 5 3000 4 2003/07/01 03月+CNTで7月(5回ここで終了したい) A1 200303 5 3000 5 2003/08/01 03月+CNTで8月(いらないのに) A1 200303 5 3000 6 2003/09/01 03月+CNTで9月(いらない) となり、1ヶ月単位でCNTの値を利用して変化させてます。 次は、支払回数が5回なら、5個のデータにして必要・不必要を区別したい。 ホントはレコードを増やさないのがベストだけど、 FLGとフラグ項目を作成して、CNTが支払回数以内ならON(支払い中)とフラグを付けます FLG: IIf([cnt]<[支払回数],"ON","") と、演算フィールドを作成しました。 商品 支払年月 支払回数 月額 CNT 支払中 FLG A1 200303 5 3000 0 2003/03/01 ON 03月+CNTで3月 A1 200303 5 3000 1 2003/04/01 ON 03月+CNTで4月 A1 200303 5 3000 2 2003/05/01 ON 03月+CNTで5月 A1 200303 5 3000 3 2003/06/01 ON 03月+CNTで6月 A1 200303 5 3000 4 2003/07/01 ON 03月+CNTで7月(5回終了) A1 200303 5 3000 5 2003/08/01 (""の空白) A1 200303 5 3000 6 2003/09/01 (""の空白) と、クエリーの結果データが作成されました ↑2つの演算フィールドを追加する

/* * 5.データがそろったので、クロス集計クエリーを作成する */

作成したクエリーのFLGがONのデータをクロス集計すれば、 目的のクエリーを作ることが出来そうです。 ※クエリーを2つ使ってしまいますが。 クエリーの種類をクロス集計クエリーにして、 行:商品 列:支払中(作成した演算フィールドを使用) 値:月額 where条件:FLG=ONのデータ で、作成すると、なんとかできそうです。 ↑作成イメージ -【けんぞう!】--------------------------------------------------------- ASPが利用可能なレンタルサーバーをお探しのアナタ、 http://www.ken3.org/asp/server.html ← けんぞうも使っているサーバーの紹介 『おっIISでbasp21でメール送信、mdbも使えるよ』(三流PG:31歳) ------------------------------------------------------------------------ 

/* * 6.終わりの挨拶 */

今回は、 つなげないクエリーでデータを増やし クロス集計クエリーを使用して、行列で集計したデータを作成してみました。 半ば強引に作成したので、データ量が多かったりすると、 集計に時間がかかったりするので、 判断しながら使ってみてください。 何か読者の心に残れば、うれしいです。 *私の独り言をうまく消化してくださいね。 いつも失敗?の負け組のKen3でした。 ~~~~~~~(↑オイオイ)


ページフッター

ここまで、読んでいただきどうもです。ここから下は、三流君のホームページの紹介・案内です
目的の情報が見つかったか?少々心配しつつ、、、

種類別のリンク や 広告など

気になったジャンル↓を選択してください。

人気記事(来場者が多いTOP3):
[VBAでIE,WebBrowserを操作]・・・VBAでIE,WebBrowserを操作する サンプルです
[Access から Excel 連携 CreateObject("Excel.Application")]・・・AccessからExcelを操作したりデータの書き出しなどです
[VBAでOutlookの操作 CreateObject("Outlook.Application" )]・・・VBAからOutlookを使い、メール関係を処理するサンプルです
↑上記3つみたいなCreateObjectで他のアプリケーションを操作するサンプルが人気です。

Excel関係:
[Excel UserFormを操作する]・・・エクセルでユーザーフォームを作成して入力などを行ってます
[ExcelからAccessを操作する]・・・ExcelからAccessのマクロを起動してみました、
[Excel関係 関数、その他]・・・その他Excel関係です

Access関係:
[Access UserForm/サブフォーム 操作]・・・アクセスでフォームを使ったサンプルです
[Access レポート操作]・・・レポートを操作してみました
[Access クエリーやその他関数]・・・あまりまとまってませんが、スポット的な単体関数の解説です

その他:VBAの共通関数やテキストファイルの操作など
[VBAでテキストファイル(TextFile)の操作]・・・普通のテキストファイルを使ったサンプルです
[VBA 標準関数関係とその他解説]・・・その他、グダグタ解説してます

開発時の操作: [F1を押してHELPを見る]/ [Debug.Print と イミディエイトウインドウ]/ [実行時エラーでデバッグ]/ [ウォッチ式とSTOP]/ [参照設定を行う]

仕様書(設計書?) XXXX書類: [基本設計書や要求仕様書]/ [テスト仕様書 テストデータ]/ [バグ票]/ [関数仕様書]/ [流れは 入力・処理・出力]

※↑文章の味付けが変わっていて、お口に合うかわかりませんが。。。
※※読んで、気分を悪くされたらスミマセン。

Blogとリンク:[三流君の作業日記]/ [VBAやASPのサンプルコード]/ 広告-[通販人気商品の足跡]



[三流君(TOP ken3.org へ戻る)] / [VBA系TOPへ] / [VBA系バックナンバー目次へ移動]