三流君ASPで遊ぶ、失敗する

[三流君] Top ken3.orgへ
[ASP解説] ASPの解説TOP
[ASP記事 バックナンバー] 番号順のバックナンバー
[SOHO/在宅プログラマー/派遣] 派遣のお話ほか
[...サイトマップ(総合案内へ)]




分類別ガイド
ADOで[ADO Mdb接続] ,[ADO Excel接続] ,[ADO CSV接続]

[ASP Form データのやりとりPOSTとGET]
[ASPでTextFile操作]
[ASPでVBScriptを使う]
[その他サンプル]

バックナンバー No.70 〜 No.74


No.70 2003/07/15
SQL Select DISTINCT キーワードで重複結果の出力をハジク
[ページTOPへ戻る]

<SQL Select DISTINCT キーワードで重複結果の出力をハジク>

こんにちは、三流プログラマーのKen3です。 今回は、 SQL Select DISTINCT キーワードを使用して、 重複結果の出力を取り除いてみたいと思います。

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

隣のVBA系のメルマガで、 Access サブフォームで連結 重複を弾いてメインに表示 http://www.ken3.org/backno/backno_vba22.html#106 --- >親フォームが音楽のバンド名が記載されてます。 >サブフォームには、 >そのバンドのメンバーと出身県と楽器と年齢などが記載されています。 > >そこで、親フォームには、そのバンドのメンバーの出身県が出るテキスト >ボックスがあります。 > >例えば・・・バンド名(BOOWY)−−−−−−−−−−親フォーム >      メンバー(氷室、布袋、松井、高橋)−−サブフォーム >      出身県(群馬、群馬、群馬、福島)−−−サブフォーム > >●質問1 > >で、このサブフォームに記載されている、出身県を親のフォームの >任意に作成したテキストボックスの中に「群馬、福島」とだけ表示したいのです。 > >「群馬、群馬、群馬、福島」と表示するのは、ちょっと・・・。 >群馬がだぶっているので、群馬の表示は1つとしたいのです。 --- と、データが群馬、群馬、群馬、福島と4件あって、 結果を重複を除いて、群馬、福島と2件表示したい、 そんな処理を考えてました。

/* * 2.力技とSQLを使った方法 */

はじめは、VBAのプログラマーらしく、 ループを使ってレコード全てをチェックしてました。 ^^^^^^^^^^^^^^^^^^^^^^ 'T_メンバーテーブルから出身地をバンドIDがフォームの値と一緒 strSQL = "Select 出身地 From T_メンバー " _ & " Where バンドID = " & Me![バンドID] こんな感じで、SQL文を作成して、 'レコードセットを開く rs.Open strSQL, CurrentProject.Connection, _ adOpenKeyset, adLockOptimistic レコードセットを作り、 レコードの最後までループ、 'ループ処理 str出身地 = "" '空文字で初期化 While rs.EOF = False 'いつものEOFが偽の間 'バッファの中に同じ出身地があるか場所をチェックする n = InStr(str出身地, rs.Fields("出身地")) If n = 0 Then '出身地が見つからなかったら(重複してない時) '出身地と" "スペース1つを+する str出身地 = str出身地 & rs.Fields("出身地") & " " End If rs.MoveNext '次のレコードに移動しないと、とんでもないことに(笑) Wend ループの中で、同じ出身地のチェックを行い、データの重複を取り除いてました。 SQL文で、重複を取り除くって考えると、 頭に浮かんだのが、Group By を使用して、 グループ化のレコードセットを作成する方法でした。 No.38 SQL GROUP BY句 で グループ化する http://www.ken3.org/backno/backno_asp08.html#38 で、 ログデータからURLを表示するために Set rs = db.Execute("Select URL From log GROUP BY URL") と、SQL文を指定してます。 http://www.ken3.org/cgi-bin/test/test038-1.asp を実行すると、 No. URL 1 http://www.ken3.org 2 http://www.ken3.org/ 3 http://www.ken3.org/24h/ 4 http://www.ken3.org/24h/add24h.html ・  ・  ・ とグループ化されてURLが表示されます。 同様に、GROUP BY 出身地 と グループ化して重複を取り除いてもよかったのですが、 何かないかなぁと調べていると、 SQL Select文で、 んっ? DISTINCTキーワード? ~~~~~~~~ 騙されたと思って、 Select DISTINCT 〜で、SQL文作ってみた。 'T_メンバーテーブルから出身地をバンドIDがフォームの値と一緒 strSQL = "Select DISTINCT 出身地 From T_メンバー " _ & " Where バンドID = " & Me![バンドID] と、Selectの後にキーワードを+してみます。 おっ、動きましたよ(笑)、出身地の重複がないレコードセットが返って来ました。 GROUP BY で Countなどのグループ単位の集計関数使わない時は、 Select DISTINCT で 制御するのもアリかなぁと思いました。 cnt.mdb から訪問されたURLを Set rs = db.Execute("Select DISTINCT URL From log") と、SQL文を指定してテストで取り出してみます。 http://www.ken3.org/cgi-bin/test/test070-1.asp で、テスト実行できます。 気になる処理時間は あまり変わらないかなぁ。 ※処理事態が全てのデータを見に行くからね。 -【けんぞう!】--------------------------------------------------------- 三流君の、小金稼ぎ、お小遣い稼ぎシリーズ第3弾(稼げないだろコラ!!) 参加無料:予想が当たれば一攫千金?今月はプロ野球のセパ勝敗とホームラン数 http://www.ken3.org/etc/500yen/5050.html ← 100万を当たった人数で山分け 『チッ、大穴横浜の勝利に賭けてるのに当たらない(笑)』(横浜ファン:31歳) ------------------------------------------------------------------------  ↑※7/13日の日曜日、雨で三試合中止 And 松坂の1回ノックアウト、、   大波乱、当てた人居るのかなぁ・・・雨で中止、読めなかった・・・   参加料無料なので、試合によっては一攫千金を狙えますよ。   当たっていない私が言うと説得力無いけど、みなさんは実力で稼いでください。

/* * 3.終わりの挨拶 </HTML> */

今回は、 SQL Select文で DISTINCT キーワードを使ってみたサンプルでした。 SQLって奥が深いですね・・・ SQLの魔術師はムリでも、 SQLの手品師ぐらいにはなりたいですね。 えっ、Ken3は、SQLのペテン師だろって? なんて読者の声が聞こえてこないうちに、今回は退散です。 何かの参考となれば幸いです。 素朴な疑問やリクエスト、クレームなどがあったら、 掲示板 : http://www.ken3.org/cgi-bin/bbs/asp/wforum.cgi に気軽に書き込んでください。 ASP、VBScript勉強中の三流プログラマーのKen3でした。

No.71 2003/07/22
FileSystemObjectの.DeleteFileでファイル削除
[ページTOPへ戻る]

<FileSystemObjectの.DeleteFileでファイル削除>

こんにちは、三流プログラマーのKen3です。 今回は、 指定ファイルを削除してみたいと思います。

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

テンポラリファイルの作成を、 No.69 FileSystemObjectの.GetTempName(一時ファイル名作成) http://www.ken3.org/backno/backno_asp14.html#69 で、FileSystemObjectの .GetTempNameを使用してファイル名の作成、 .CreateTextFileを使用して作成しました。 http://www.ken3.org/cgi-bin/test/test069-1.asp で、テスト可能です。 これって、ファイル作りっぱなして(笑)、 削除はFTPで2・3日に1回実行してます(笑) 今回は、ファイルの削除処理を探ってみます。

/* * 2.意外と簡単、.DeleteFile(ファイル名)でOKでした。 */

調べてみると、意外と簡単でした。 Set objFS = Server.CreateObject("Scripting.FileSystemObject") と、 いつものように、ファイルシステムのオブジェクトを作成後、 objFS.DeleteFile(ファイル名のとパスの文字列) でOKでした。 ワイルドカード指定も可能なので、 objFS.DeleteFile("x:\zzzz\*.tmp") など、指定可能です。 http://www.ken3.org/cgi-bin/test/test071-1.asp で、テスト可能です。 Server.MapPath("work/") でworkの実フォルダーを返し、 objFS.DeleteFile(strFDIRNAME & "\*.tmp") で、*.tmpを削除してます。 <%@LANGUAGE=VBScript%> <html> <head> <title>FileSystemObject .DeleteFile(ファイル名を削除する)</title> </head> <body> <h2>FileSystemObject .DeleteFile(ファイル名を削除する)</h2> <b>FileSystemObjectの.DeleteFile</b>を使用して、ファイルを削除してみます<br> <br> .DeleteFile(削除するパスとファイル名)を使用すると、<br> ファイルを削除することができます。<br> ※*.tmp を削除したので、下記の実行結果とソースを見てください。<br> <hr> <% '*1 FileSystemObjectを生成します、、って英文、そのままジャン。 Set objFS = Server.CreateObject("Scripting.FileSystemObject") '現在のフォルダーから相対位置のworkディレクトリの名称を取り出す strFDIRNAME = Server.MapPath("work/") 'フォルダー名取得 '*2 .DeleteFileを使用して、ファイルを削除する objFS.DeleteFile(strFDIRNAME & "\*.tmp") '*.tmpを削除する Response.Write strFDIRNAME & "\*.tmp を削除しました<br>" '確認でファイルリストの表示.GetFolderで取得後、一覧表示 Response.Write strFDIRNAME & "のファイル一覧です<br>" & vbCRLF Set objDIR = objFS.GetFolder(strFDIRNAME) '.Filesコレクションにアクセスする For Each objFILE In objDIR.Files strFNAME = objFILE.Name '取り出したobjFILEの.Nameを取得 If strFNAME = strTEMPNAME Then Response.Write "<b>" Response.Write "<a href='work/" & strFNAME & "'>" Response.Write strFNAME & "</a>" & vbTab 'おまけで更新日の表示 Response.Write objFILE.DateLastModified & "<br>" & vbCRLF If strFNAME = strTEMPNAME Then Response.Write "</b>" Next %> <hr> <a href="test069-1.asp">テストのテンポラリファイルを作成する</a><br> ↑※ファイル作成後、再度テストしてみてください。<br> <br> </body> </html> -【けんぞう!】--------------------------------------------------------- 転職関係、在宅プログラマー、SOHOの広告まとめました http://www.ken3.org/etc/500yen/zaitaku.html いろいろとあるので転機の人はぜひ 『だだ、広告料稼ぎたいだけだろ、紹介料300円〜2000円の小金稼ぎ』 ギクっ、、、バレた(笑)登録料無料、匿名で探せるので在宅で小金稼ぎの人も見てね ------------------------------------------------------------------------ 

/* * 3.終わりの挨拶 </HTML> */

今回は、 ファイルの削除でした。 思ったよりも簡単だったので、私もびっくりでした。 ファイルの削除、間違えないように注意して使ってみてください。 何かの参考となれば幸いです。 ASP、VBScript勉強中の三流プログラマーのKen3でした。

No.72 2003/08/29
小計・合計の表示、大昔の方法(笑)
[ページTOPへ戻る]

<小計・合計の表示、大昔の方法(笑)>

こんにちは、三流プログラマーのKen3です。 今回は、 小計・合計の表示 を行ってみたいと思います。

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

掲示板 http://www.ken3.org/cgi-bin/bbs/asp/wforum.cgi に下記の書き込みをもらいました。 ※改行位置勝手に変更しました。 ---- 教えていただきたいことは小計の取り方です。 グループごとに縦横に小計を取って最後の行に総計を表示するようにしたいのです。 イメージとしては以下のようにしようとしています。 (うまく表示されているでしょうか?) サーバはSQLサーバで、ADOを使用しています。 使用するテーブルは2つあり、 T_商品(商品CD、商品名)とT_月別売上(商品CD、1月〜12月)です。 この2つを商品CDをキーに外部結合で結び、 T_商品にあるものを全ての月別売上を表示するようにしています。 テーブルの内容は表示できるのですが、 グループごとに小計を取って表示することができず悩んでいます。 ---------------------------------------------------------------- | 商品名 | 4月 | 5月 | 6月 | 7月 | 8月 | 9月 | 上期計 | ---------------------------------------------------------------- | A1   |  1 |  2 |  3 |  4 |  5 |  6 |   21 | ---------------------------------------------------------------- | A2   |  2 |  0 |  4 |  5 |  6 |  7 |   24 | ---------------------------------------------------------------- | A3   |  3 |  1 |  5 |  6 |  7 |  8 |   30 | ---------------------------------------------------------------- | 小計  |  6 |  3 | 12 | 15 | 18 | 21 |   75 | ---------------------------------------------------------------- | B1   |  4 |  2 |  6 |  7 |  8 |  9 |   36 | ---------------------------------------------------------------- | B2   |  5 |  3 |  7 |  8 |  9 | 10 |   42 | ---------------------------------------------------------------- | B3   |  6 |  4 |  8 |  9 | 10 | 11 |   48 | ---------------------------------------------------------------- | 小計  | 15 |  9 | 21 | 24 | 27 | 30 |  126 | ---------------------------------------------------------------- | 総計  | 42 | 24 | 66 | 78 | 90 | 102 |  402 | ---------------------------------------------------------------- 以上、内容が足りない等ありましたらご指摘ください。 よろしくお願いします。 ---- 2つのテーブルをつなげて、小計を取りたい、 そんな感じの処理ですね。

/* * 2.大昔の方法でやってみます */

さてと、いろいろと方法があるのですが、 大昔の何もRDBの知識の無い、力技の人を今日は、演じてみます。 T_月別売上テーブル 商品CD 売上4 売上5 ・ ・ 売上12 売上1 売上2 売上3 とテーブル、フィールドを作成しました。 ※年度が無いとか、気になる部分はありますが、  たぶん、年度更新処理でうまくやっていると考えて、気にしない気にしない。 ↑作成したテーブルイメージ まずは、全てのデータを表示してみます。 えっと、DBにつなげてから、Select文を書くんだっけ。 http://www.ken3.org/cgi-bin/test/test072-1.asp で、テスト可能です。 <%@LANGUAGE=VBScript%> <html> <head> <title>テストでテーブル内の全データを表示してみる</title> </head> <body> <h2>テストでテーブル内の全データを表示してみる</h2> Set rs = db.Execute("Select * From T_月別売上")<br> と、全ての項目を呼び出してみる。<br> <hr> <% 'ADO DB Connection オブジェクトを作成する、英文そのままじゃん Set db=Server.CreateObject("ADODB.Connection") '.Provider?プロバイダー?通信会社?じゃなくって 'データアクセスにはJet.OLEDB.4.0を使うことを設定 db.Provider = "Microsoft.Jet.OLEDB.4.0" '次に、接続DBの位置を渡すので、Server.MapPathで変換して渡す db.ConnectionString = Server.MapPath("db072.mdb") 'やっとデータベースを開ける db.open 'お約束のレコードセットの作成 T_月別売上から全項目(*)を指定 Set rs = db.Execute("Select * From T_月別売上") 'データの表示をテーブルで行う Response.Write "<TABLE Border='1'>" '見出しを(フィールド名を)そのまま書き込む Response.Write "<TR>" For Each fld_A In Rs.Fields 'フィールドのアイテムに対してループ Response.Write "<TH>" & fld_A.Name & "</TH>" '↑.Nameでフィールド名を表示する Next Response.Write "</TR>" 'お約束のEOFまでループは(データが無くなるまでループ)、 Do While rs.EOF = False 'レコードセットの.EOFがFalseの間 Response.Write "<TR>" '内容を表示する For Each fld_A In Rs.Fields 'フィールドのアイテムに対してループ Response.Write "<TD>" & fld_A.Value & "</TD>" '↑.Valueでフィールドの値を表示する Next Response.Write "</TR>" '次のレコードにポインタを移動する rs.MoveNext 'これを忘れると悲惨なことに、、、 Loop Response.Write "</TABLE>" 'テーブルは終わりです '開いていたレコードセットを閉じる rs.Close 'データベースも閉じようよ db.Close 'お行儀よくオブジェクトも開放しましょう(通常は自動的に解放されるけど) Set db = Nothing %> <hr> 終了です。<br> </body> </html> 普通にテーブル内容を表示してみました。 For Each fld_A In Rs.Fields 'フィールドのアイテムに対してループ Response.Write "<TD>" & fld_A.Value & "</TD>" '↑.Valueでフィールドの値を表示する Next こんな感じのループで、フィールドにアクセスする、 そんなこともできる程度に覚えて置いてください。

/* * 3.自分で上期計を計算する(笑) */

データを呼び出せたみたいなので、 さてと、次は、 | 商品名 | 4月 | 5月 | 6月 | 7月 | 8月 | 9月 | 上期計 | と、上期の合計を計算してみます。 http://www.ken3.org/cgi-bin/test/test072-2.asp で、テスト可能です。 追加したポイントは、 g_kamiki = 0 '集計用の変数を初期化する と変数を1つ作成して、初期化します。 4月〜9月のループを作ります。 For n = 4 To 9 'フィールドにフィールド名でアクセスする Response.Write "<TD>" & rs("売上" & n).Value & "</TD>" '↑"売上" & nでフィールド名売上4..売上9を作成してアクセス '自分で集計する g_kamiki = g_kamiki + rs("売上" & n).Value Next rs("売上" & n).Value と、フィールドに対して、文字列のフィールド名で参照してます。 <%@LANGUAGE=VBScript%> <html> <head> <title>上期(4〜9月)の合計を計算・表示してみる</title> </head> <body> <h2>上期(4〜9月)の合計を計算・表示してみる</h2> rs("売上" & n).Value<br> "売上" & nでフィールド名売上4..売上9を作成してアクセス<br> 自分で集計してみました。<br> g_kamiki = g_kamiki + rs("売上" & n).Value<br> <hr> <% 'ADO DB Connection オブジェクトを作成する、英文そのままじゃん Set db=Server.CreateObject("ADODB.Connection") '.Provider?プロバイダー?通信会社?じゃなくって 'データアクセスにはJet.OLEDB.4.0を使うことを設定 db.Provider = "Microsoft.Jet.OLEDB.4.0" '次に、接続DBの位置を渡すので、Server.MapPathで変換して渡す db.ConnectionString = Server.MapPath("db072.mdb") 'やっとデータベースを開ける db.open 'お約束のレコードセットの作成 T_月別売上から全項目(*)を指定 Set rs = db.Execute("Select * From T_月別売上") 'データの表示をテーブルで行う Response.Write "<TABLE Border='1'>" '見出しを表示する Response.Write "<TR>" Response.Write "<TH>商品名</TH>" For n = 4 To 9 '4月から9月と見出しを表示したいので Response.Write "<TH>" & n & "月</TH>" Next Response.Write "<TH>上期計</TH>" Response.Write "</TR>" 'お約束のEOFまでループは(データが無くなるまでループ)、 Do While rs.EOF = False 'レコードセットの.EOFがFalseの間 Response.Write "<TR>" '行を表示する Response.Write "<TD>" & rs("商品CD").Value & "</TD>" 'とりあえずコード g_kamiki = 0 '集計用の変数を初期化する For n = 4 To 9 'フィールドにフィールド名でアクセスする Response.Write "<TD>" & rs("売上" & n).Value & "</TD>" '↑"売上" & nでフィールド名売上4..売上9を作成してアクセス '自分で集計する g_kamiki = g_kamiki + rs("売上" & n).Value Next '上期の合計を表示する Response.Write "<TD>" & g_kamiki & "</TD>" Response.Write "</TR>" '次のレコードにポインタを移動する rs.MoveNext 'これを忘れると悲惨なことに、、、 Loop Response.Write "</TABLE>" 'テーブルは終わりです '開いていたレコードセットを閉じる rs.Close 'データベースも閉じようよ db.Close 'お行儀よくオブジェクトも開放しましょう(通常は自動的に解放されるけど) Set db = Nothing %> <hr> 終了です。<br> </body> </html>

/* * 4.グループの小計を自分で行う */

上期の横計を自分で計算できたので、 今度はグループの頭が変更になった時の、縦計(小計、総合計)を計算してみます。 基本構想は、 集計用の配列を取り、1つ1つ集計する、 グループのコード、頭の1桁が変わったら、 とループを作成してみる。 '月別の小計・総合計を保存する配列を作成する Dim sum_group(12) 'グループ合計 Dim sum_all(12) '総合計 Dim sum_code 'グループ化のコード '総合計エリア、グループ合計を初期化する For n = 1 To 12 sum_group(n) = 0 sum_all(n) = 0 Next 'グループ化のコードを初期化する sum_code = Left(rs("商品CD").Value , 1) '先頭レコードの商品コード1桁目 'お約束のEOFまでループは(データが無くなるまでループ)、 Do While rs.EOF = False 'レコードセットの.EOFがFalseの間 Response.Write "<TR>" '行を表示する Response.Write "<TD>" & rs("商品CD").Value & "</TD>" 'とりあえずコード g_kamiki = 0 '集計用の変数を初期化する For n = 4 To 9 'フィールドにフィールド名でアクセスする Response.Write "<TD>" & rs("売上" & n).Value & "</TD>" '↑"売上" & nでフィールド名売上4..売上9を作成してアクセス '自分で上期を集計する g_kamiki = g_kamiki + rs("売上" & n).Value '月別、グループ、総合計を計算する sum_group(n) = sum_group(n) + rs("売上" & n).Value 'グループ sum_all(n) = sum_all(n) + rs("売上" & n).Value '総合計 Next '上期の合計を表示する Response.Write "<TD>" & g_kamiki & "</TD>" Response.Write "</TR>" '次のレコードにポインタを移動する rs.MoveNext 'これを忘れると悲惨なことに、、、 'グループコードが変わったかチェックする If sum_code <> Left(rs("商品CD").Value , 1) Then '小計を表示する Response.Write "<TR bgcolor=#FFE0FF>" '行を表示する Response.Write "<TD>小計</TD>" g_kamiki = 0 '小計の上期集計用の変数を初期化する For n = 4 To 9 '4〜9月 Response.Write "<TD>" & sum_group(n) & "</TD>" 'n月の値を表示 g_kamiki = g_kamiki + sum_group(n) '小計の上期のタメに計算 Next Response.Write "<TD>" & g_kamiki & "</TD>" '小計の上期計を表示 Response.Write "</TR>" '行の終わり '次のグループになるので、配列とCODEを初期化する sum_code = Left(rs("商品CD").Value , 1) '次のコードを代入 For n = 4 To 9 '小計値を初期化する sum_group(n) = 0 Next End If Loop ポイントは ^^^^^^^^^^ sum_code = Left(rs("商品CD").Value , 1) '先頭レコードの商品コード1桁目 と頭で、商品コードを代入しておきます。 A1ならAが入ります。 集計は普通に、明細の4月〜9月の表示の中で、 For n = 4 To 9 'フィールドにフィールド名でアクセスする Response.Write "<TD>" & rs("売上" & n).Value & "</TD>" ・     ・ '月別、グループ、総合計を計算する sum_group(n) = sum_group(n) + rs("売上" & n).Value 'グループ sum_all(n) = sum_all(n) + rs("売上" & n).Value '総合計 と、 n月分は、n月の配列に+してます。 あとは、グループのコードが変わったら、 小計を出力して、次のグループのタメにデータをクリア ^^^^^^^^^^^^^^ 'グループコードが変わったかチェックする If sum_code <> Left(rs("商品CD").Value , 1) Then '小計を表示する      ・ ・ '次のグループになるので、配列とCODEを初期化する sum_code = Left(rs("商品CD").Value , 1) '次のコードを代入 For n = 4 To 9 '小計値を初期化する sum_group(n) = 0 Next End If の繰り返しを行います。 まぁ、楽勝かなぁと思ったら、 72: rs.MoveNext 'これを忘れると悲惨なことに、、、 73: 'グループコードが変わったかチェックする 74: If sum_code <> Left(rs("商品CD").Value , 1) Then ADODB.Field エラー '800a0bcd' BOF と EOF のいずれかが True になっているか、または現在のレコードが削除されています。 要求された操作には、現在のレコードが必要です。 /cgi-bin/test/test072-3.asp, 行 74 あらら、なんだぁ?74行目? そっか、rs.MoveNext で、EOFまで行っているからか・・・ 条件を rs.EOF = True Or sum_code <> Left(rs("商品CD").Value , 1) と、先にEOFか?きいてみます。 あれ、だめかぁ・・・ 流れを変えるか、、、 If rs.EOF = True Or sum_code <> Left(rs("商品CD").Value , 1) でチェックできないので、 商品コードのチェック処理をループの頭に回し、 Eof後(レコードが終了後) 最後の項目の小計を出力する流れに変えました。 http://www.ken3.org/cgi-bin/test/test072-3.asp で、テスト可能です。 <%@LANGUAGE=VBScript%> <html> <head> <title>小計(グループ)を計算・表示してみる</title> </head> <body> <h2>小計(グループ)を計算・表示してみる</h2> <hr> <% 'ADO DB Connection オブジェクトを作成する、英文そのままじゃん Set db=Server.CreateObject("ADODB.Connection") '.Provider?プロバイダー?通信会社?じゃなくって 'データアクセスにはJet.OLEDB.4.0を使うことを設定 db.Provider = "Microsoft.Jet.OLEDB.4.0" '次に、接続DBの位置を渡すので、Server.MapPathで変換して渡す db.ConnectionString = Server.MapPath("db072.mdb") 'やっとデータベースを開ける db.open 'お約束のレコードセットの作成 'T_月別売上から全項目(*)を指定、Order Byで商品コード順にする Set rs = db.Execute("Select * From T_月別売上 Order By 商品CD") 'データの表示をテーブルで行う Response.Write "<TABLE Border='1'>" '見出しを表示する Response.Write "<TR bgcolor=#E0FFFF>" Response.Write "<TH>商品名</TH>" For n = 4 To 9 '4月から9月と見出しを表示したいので Response.Write "<TH>" & n & "月</TH>" Next Response.Write "<TH>上期計</TH>" Response.Write "</TR>" '月別の小計・総合計を保存する配列を作成する Dim sum_group(12) 'グループ合計 Dim sum_all(12) '総合計 Dim sum_code 'グループ化のコード '総合計エリア、グループ合計を初期化する For n = 1 To 12 sum_group(n) = 0 sum_all(n) = 0 Next 'グループ化のコードを初期化する sum_code = Left(rs("商品CD").Value , 1) '先頭レコードの商品コード1桁目 'お約束のEOFまでループは(データが無くなるまでループ)、 Do While rs.EOF = False 'レコードセットの.EOFがFalseの間 'グループコードが変わったかチェックする If sum_code <> Left(rs("商品CD").Value , 1) Then '小計を表示する Response.Write "<TR bgcolor=#FFE0FF>" '行を表示する Response.Write "<TD>小計</TD>" g_kamiki = 0 '小計の上期集計用の変数を初期化する For n = 4 To 9 '4〜9月 Response.Write "<TD>" & sum_group(n) & "</TD>" 'n月の値を表示 g_kamiki = g_kamiki + sum_group(n) '小計の上期のタメに計算 Next Response.Write "<TD>" & g_kamiki & "</TD>" '小計の上期計を表示 Response.Write "</TR>" '行の終わり '次のグループになるので、配列とCODEを初期化する sum_code = Left(rs("商品CD").Value , 1) '次のコードを代入 For n = 4 To 9 '小計値を初期化する sum_group(n) = 0 Next End If Response.Write "<TR>" '行を表示する Response.Write "<TD>" & rs("商品CD").Value & "</TD>" 'とりあえずコード g_kamiki = 0 '集計用の変数を初期化する For n = 4 To 9 'フィールドにフィールド名でアクセスする Response.Write "<TD>" & rs("売上" & n).Value & "</TD>" '↑"売上" & nでフィールド名売上4..売上9を作成してアクセス '自分で上期を集計する g_kamiki = g_kamiki + rs("売上" & n).Value '月別、グループ、総合計を計算する sum_group(n) = sum_group(n) + rs("売上" & n).Value 'グループ sum_all(n) = sum_all(n) + rs("売上" & n).Value '総合計 Next '上期の合計を表示する Response.Write "<TD>" & g_kamiki & "</TD>" Response.Write "</TR>" '次のレコードにポインタを移動する rs.MoveNext 'これを忘れると悲惨なことに、、、 Loop 'ループを抜けたら、最後の小計を表示する '小計を表示する Response.Write "<TR bgcolor=#FFE0FF>" '行を表示する Response.Write "<TD>小計</TD>" g_kamiki = 0 '小計の上期集計用の変数を初期化する For n = 4 To 9 '4〜9月 Response.Write "<TD>" & sum_group(n) & "</TD>" 'n月の値を表示 g_kamiki = g_kamiki + sum_group(n) '小計の上期のタメに計算 Next Response.Write "<TD>" & g_kamiki & "</TD>" '小計の上期計を表示 Response.Write "</TR>" '行の終わり '総合計の表示(計算した総合計を表示する) Response.Write "<TR bgcolor=#FFFFE0>" '行を表示する Response.Write "<TD>総合計</TD>" g_kamiki = 0 '総合計の上期集計用の変数を初期化する For n = 4 To 9 '4〜9月の値を表示する Response.Write "<TD>" & sum_all(n) & "</TD>" 'n月の値を表示 g_kamiki = g_kamiki + sum_all(n) '総合計の上期のタメに計算 Next Response.Write "<TD>" & g_kamiki & "</TD>" '小計の上期計を表示 Response.Write "</TR>" '行の終わり Response.Write "</TABLE>" 'テーブルは終わりです '開いていたレコードセットを閉じる rs.Close 'データベースも閉じようよ db.Close 'お行儀よくオブジェクトも開放しましょう(通常は自動的に解放されるけど) Set db = Nothing %> <hr> 終了です。<br> </body> </html>

/* * 5.商品名を1つ1つ自分で取ってくる・・・ */

さて、なんとか、小計、総合計まで、表示しました。 A1,A2,B1,B2とコードから商品名を取得してみたいと思います。 ※普通はテーブルをつなげるんだけど、  今回は、RDBの特徴を知らない設定でやってみます。 T_商品 テーブル 商品CD 商品名 のフィールドを作成します。 商品CD 商品名 A1 コーラ A2 オレンジ A3 りんご B1 スーパードライ B2 モルツ B3 黒ラベル ↑作成したテーブルイメージ 商品コードを受け取って、商品名を返すFunction関数を作成してみます。
Function get_sname(strCODE)

  strSQL = "Select 商品名 From T_商品 Where 商品CD='" & strCODE & "'"
  Set rs_master = db.Execute(strSQL) 'SQL文の発行

  If rs_master.EOF = True Then 'データ無し?
     get_sname = strCODE & "はエラーです"
  Else
     get_sname = rs_master("商品名").Value
  End If

  rs_Master.Close         'クローズ
  Set rs_master = Nothing 'と開放で後始末・・・

End Function
こんな感じで、商品コードを受け取り、 マスターを一回一回、読み込んでます。 マスターに無いデータを読むと(該当無しのSQLを作成すると) get_sname = rs_master("商品名").Value の代入文で、 ADODB.Field エラー '800a0bcd' BOF と EOF のいずれかが True になっているか、 または現在のレコードが削除されています。 要求された操作には、現在のレコードが必要です。 なんてエラーだったので、 rs_master.Countなんてやったら、 下記のようなエラーも出しつつ(笑) Microsoft VBScript 実行時エラー エラー '800a01b6' オブジェクトでサポートされていないプロパティまたはメソッドです。 : 'rs_master.Count' /cgi-bin/test/test072-4.asp, 行 144 If rs_master.EOF = True Then 'データ無し? で判断してます。 商品名表示を組み込んだ実行は、 http://www.ken3.org/cgi-bin/test/test072-4.asp で、テスト可能です。 Response.Write "<TR>" '行を表示する 'マスターから商品名を読み込む Response.Write "<TD>" & get_sname(rs("商品CD").Value) & "</TD>" と メインの処理から呼び出してます。 <%@LANGUAGE=VBScript%> <html> <head> <title>商品名をマスターから読み込んでみた</title> </head> <body> <h2>商品名をマスターから読み込んでみた</h2> <hr> <% 'ADO DB Connection オブジェクトを作成する、英文そのままじゃん Set db=Server.CreateObject("ADODB.Connection") '.Provider?プロバイダー?通信会社?じゃなくって 'データアクセスにはJet.OLEDB.4.0を使うことを設定 db.Provider = "Microsoft.Jet.OLEDB.4.0" '次に、接続DBの位置を渡すので、Server.MapPathで変換して渡す db.ConnectionString = Server.MapPath("db072.mdb") 'やっとデータベースを開ける db.open 'お約束のレコードセットの作成 'T_月別売上から全項目(*)を指定、Order Byで商品コード順にする Set rs = db.Execute("Select * From T_月別売上 Order By 商品CD") 'データの表示をテーブルで行う Response.Write "<TABLE Border='1'>" '見出しを表示する Response.Write "<TR bgcolor=#E0FFFF>" Response.Write "<TH>商品名</TH>" For n = 4 To 9 '4月から9月と見出しを表示したいので Response.Write "<TH>" & n & "月</TH>" Next Response.Write "<TH>上期計</TH>" Response.Write "</TR>" '月別の小計・総合計を保存する配列を作成する Dim sum_group(12) 'グループ合計 Dim sum_all(12) '総合計 Dim sum_code 'グループ化のコード '総合計エリア、グループ合計を初期化する For n = 1 To 12 sum_group(n) = 0 sum_all(n) = 0 Next 'グループ化のコードを初期化する sum_code = Left(rs("商品CD").Value , 1) '先頭レコードの商品コード1桁目 'お約束のEOFまでループは(データが無くなるまでループ)、 Do While rs.EOF = False 'レコードセットの.EOFがFalseの間 'グループコードが変わったかチェックする If sum_code <> Left(rs("商品CD").Value , 1) Then '小計を表示する Response.Write "<TR bgcolor=#FFE0FF>" '行を表示する Response.Write "<TD>小計</TD>" g_kamiki = 0 '小計の上期集計用の変数を初期化する For n = 4 To 9 '4〜9月 Response.Write "<TD>" & sum_group(n) & "</TD>" 'n月の値を表示 g_kamiki = g_kamiki + sum_group(n) '小計の上期のタメに計算 Next Response.Write "<TD>" & g_kamiki & "</TD>" '小計の上期計を表示 Response.Write "</TR>" '行の終わり '次のグループになるので、配列とCODEを初期化する sum_code = Left(rs("商品CD").Value , 1) '次のコードを代入 For n = 4 To 9 '小計値を初期化する sum_group(n) = 0 Next End If Response.Write "<TR>" '行を表示する 'マスターから商品名を読み込む Response.Write "<TD>" & get_sname(rs("商品CD").Value) & "</TD>" g_kamiki = 0 '集計用の変数を初期化する For n = 4 To 9 'フィールドにフィールド名でアクセスする Response.Write "<TD>" & rs("売上" & n).Value & "</TD>" '↑"売上" & nでフィールド名売上4..売上9を作成してアクセス '自分で上期を集計する g_kamiki = g_kamiki + rs("売上" & n).Value '月別、グループ、総合計を計算する sum_group(n) = sum_group(n) + rs("売上" & n).Value 'グループ sum_all(n) = sum_all(n) + rs("売上" & n).Value '総合計 Next '上期の合計を表示する Response.Write "<TD>" & g_kamiki & "</TD>" Response.Write "</TR>" '次のレコードにポインタを移動する rs.MoveNext 'これを忘れると悲惨なことに、、、 Loop 'ループを抜けたら、最後の小計を表示する '小計を表示する Response.Write "<TR bgcolor=#FFE0FF>" '行を表示する Response.Write "<TD>小計</TD>" g_kamiki = 0 '小計の上期集計用の変数を初期化する For n = 4 To 9 '4〜9月 Response.Write "<TD>" & sum_group(n) & "</TD>" 'n月の値を表示 g_kamiki = g_kamiki + sum_group(n) '小計の上期のタメに計算 Next Response.Write "<TD>" & g_kamiki & "</TD>" '小計の上期計を表示 Response.Write "</TR>" '行の終わり '総合計の表示(計算した総合計を表示する) Response.Write "<TR bgcolor=#FFFFE0>" '行を表示する Response.Write "<TD>総合計</TD>" g_kamiki = 0 '総合計の上期集計用の変数を初期化する For n = 4 To 9 '4〜9月の値を表示する Response.Write "<TD>" & sum_all(n) & "</TD>" 'n月の値を表示 g_kamiki = g_kamiki + sum_all(n) '総合計の上期のタメに計算 Next Response.Write "<TD>" & g_kamiki & "</TD>" '小計の上期計を表示 Response.Write "</TR>" '行の終わり Response.Write "</TABLE>" 'テーブルは終わりです '開いていたレコードセットを閉じる rs.Close 'データベースも閉じようよ db.Close 'お行儀よくオブジェクトも開放しましょう(通常は自動的に解放されるけど) Set db = Nothing %> <hr> 終了です。<br> </body> </html> <% '商品コードを受け取り、商品名を返す関数を作成する
Function get_sname(strCODE)

  strSQL = "Select 商品名 From T_商品 Where 商品CD='" & strCODE & "'"
  Set rs_master = db.Execute(strSQL) 'SQL文の発行

  If rs_master.EOF = True Then 'データ無し?
     get_sname = strCODE & "はエラーです"
  Else
     get_sname = rs_master("商品名").Value
  End If

  rs_Master.Close         'クローズ
  Set rs_master = Nothing 'と開放で後始末・・・

End Function
%>
-【けんぞう!】--------------------------------------------------------- 転職関係、在宅プログラマー、SOHOの広告まとめました http://www.ken3.org/etc/500yen/zaitaku.html いろいろとあるので転機の人はぜひ 『だだ、広告料稼ぎたいだけだろ、紹介料300円〜2000円の小金稼ぎ』 ギクっ、、、バレた(笑)登録料無料、匿名で探せるので在宅で小金稼ぎの人も見てね ------------------------------------------------------------------------ 

/* * 6.終わりの挨拶 </HTML> */

今回は、 小計・総合系を自分で計算して、表示してみました。 原始的な方法だと、なんて長いソースなんだ・・・ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ってことは、次回は近代的な方法?の解説なの? たいした解説、予定してないけど、 予定では、今風の書き方、処理方法を次回、載せたいですね。 今回の方法、なんか変だけど、何かの参考となれば幸いです。 ASP、VBScript勉強中の三流プログラマーのKen3でした。

No.73 2003/08/30
テーブルをつなげて商品名を取得する方法
[ページTOPへ戻る]

<テーブルをつなげて商品名を取得する方法>

こんにちは、三流プログラマーのKen3です。 前回は、リレーションを知らない?な人が作った(三流プログラマーの私(笑)) 小計・合計の表示プログラムでした。 今回は、チョットだけ進化させて、テーブルをつなげて見たいと思います。

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

前回の、商品名表示を組み込んだ表 http://www.ken3.org/cgi-bin/test/test072-4.asp で、商品マスターから商品名を検索して、表示させました。 '商品コードを受け取り、商品名を返す関数を作成する
Function get_sname(strCODE)

  strSQL = "Select 商品名 From T_商品 Where 商品CD='" & strCODE & "'"
  Set rs_master = db.Execute(strSQL) 'SQL文の発行

  If rs_master.EOF = True Then 'データ無し?
     get_sname = strCODE & "はエラーです"
  Else
     get_sname = rs_master("商品名").Value
  End If

  rs_Master.Close         'クローズ
  Set rs_master = Nothing 'と開放で後始末・・・

End Function
データテーブルを商品CD順にして、 'お約束のレコードセットの作成 'T_月別売上から全項目(*)を指定、Order Byで商品コード順にする Set rs = db.Execute("Select * From T_月別売上 Order By 商品CD") とSQL文を発行、レコードセットを作成。 ループの中で、 'マスターから商品名を読み込む Response.Write "<TD>" & get_sname(rs("商品CD").Value) & "</TD>" なんて感じで、作成した関数でマスターテーブルを読み込んでました。 流行のRDB(リレーショナルデータベース)を知らない作りをしてみました。 今回は、テーブルをつなげてみたいと思います。

/* * 2.テーブルを単純につなげる */

何の条件も無しにSQLでテーブルを2つ使用してみます。 ^^^^^^^^^^^^^^^^ T_月別売上 テーブル 商品CD 売上4 売上5 ・ ・ 売上12 売上1 売上2 売上3 ↑作成したテーブルイメージ T_商品 テーブル 商品CD 商品名 ↑作成したテーブルイメージ なにも条件を指定しないで、2つのテーブルをFrom句に書いてみました。 Set rs = db.Execute("Select * From T_月別売上, T_商品") と、SQL文でレコードセットを作成してみた さて、どうなるでしょう? http://www.ken3.org/cgi-bin/test/test073-1.asp でテスト結果をみると、 T_月別売上.商品CD A1 に対して、同じデータが6行作成され、 T_商品.商品CDがA1,A2,A3,B1,B2,B3となってます T_月別売上.商品CD A2も同様に6行データが作成されてます。 あらら、A1はA1同士つなげた商品名がほしいのにね・・・ Select * From T_月別売上, T_商品 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ だと、2つのテーブルの内容をセレクトしてくれるけど、 作成されたレコードセットのイメージはかなり違うなぁ・・・ <%@LANGUAGE=VBScript%> <html> <head> <title>テストで2つのテーブルデータを指定</title> </head> <body> <h2>テストで2つのテーブルデータを指定</h2> なにも条件を指定しないで、2つのテーブルをFrom句に書いてみました。<br> Set rs = db.Execute("Select * From T_月別売上, T_商品")<br> と、SQL文でレコードセットを作成してみた<br> <hr> <% 'ADO DB Connection オブジェクトを作成する、英文そのままじゃん Set db=Server.CreateObject("ADODB.Connection") 'データアクセスにはJet.OLEDB.4.0を使うことを設定 db.Provider = "Microsoft.Jet.OLEDB.4.0" '次に、接続DBの位置を渡すので、Server.MapPathで変換して渡す db.ConnectionString = Server.MapPath("db072.mdb") db.open 'やっとデータベースを開ける 'お約束のレコードセットの作成 T_月別売上,T_商品を指定 Set rs = db.Execute("Select * From T_月別売上, T_商品") 'データの表示をテーブルで行う Response.Write "<TABLE Border='1'>" '見出しを(フィールド名を)そのまま書き込む Response.Write "<TR>" For Each fld_A In Rs.Fields 'フィールドのアイテムに対してループ Response.Write "<TH>" & fld_A.Name & "</TH>" '↑.Nameでフィールド名を表示する Next Response.Write "</TR>" 'お約束のEOFまでループは(データが無くなるまでループ)、 Do While rs.EOF = False 'レコードセットの.EOFがFalseの間 Response.Write "<TR>" '内容を表示する For Each fld_A In Rs.Fields 'フィールドのアイテムに対してループ Response.Write "<TD>" & fld_A.Value & "</TD>" '↑.Valueでフィールドの値を表示する Next Response.Write "</TR>" '次のレコードにポインタを移動する rs.MoveNext 'これを忘れると悲惨なことに、、、 Loop Response.Write "</TABLE>" 'テーブルは終わりです rs.Close '開いていたレコードセットを閉じる db.Close 'データベースも閉じようよ Set db = Nothing 'お行儀よくオブジェクトも開放しましょう %> <hr> 終了です。<br> </body> </html>

/* * 3.商品コードが一致したデータにする */

商品コードで結合してないからだろボケ・・なんて読者の声を聞きつつ、 商品コードが一致するデータとWhere条件を付けてみます。 ポイントは、特に無く、 Select * From T_月別売上, T_商品 Where T_月別売上.商品CD = T_商品.商品CD とSQL文を作成してます。 テーブル名.フィールド名 と ドット(ピリオド)で区切って、 T_月別売上.商品CD はT_月別売上テーブルの商品CDフィールド をあらわすぐらいかなぁ。 http://www.ken3.org/cgi-bin/test/test073-2.asp が、T_月別売上.商品CD = T_商品.商品CDで一致させたデータです。 <%@LANGUAGE=VBScript%> <html> <head> <title>2つのテーブルを商品コードでつなげる</title> </head> <body> <h2>2つのテーブルを商品コードでつなげる</h2> 条件を指定して、2つのテーブルをつなげてみます。<br> Select * From T_月別売上, T_商品<br> Where T_月別売上.商品CD = T_商品.商品CD<br> と<br> 商品コードでつなげる条件を書いてみました。<br> <hr> <% 'ADO DB Connection オブジェクトを作成する、英文そのままじゃん Set db=Server.CreateObject("ADODB.Connection") 'データアクセスにはJet.OLEDB.4.0を使うことを設定 db.Provider = "Microsoft.Jet.OLEDB.4.0" '次に、接続DBの位置を渡すので、Server.MapPathで変換して渡す db.ConnectionString = Server.MapPath("db072.mdb") db.open 'やっとデータベースを開ける 'お約束のレコードセットの作成 T_月別売上,T_商品を指定 '結合の条件 T_月別売上.商品CD = T_商品.商品CD を指定 strSQL = "Select * From T_月別売上, T_商品" strSQL = strSQL & " Where T_月別売上.商品CD = T_商品.商品CD" Set rs = db.Execute(strSQL) 'SQL発行、レコードセットを作成 'データの表示をテーブルで行う Response.Write "<TABLE Border='1'>" '見出しを(フィールド名を)そのまま書き込む Response.Write "<TR>" For Each fld_A In Rs.Fields 'フィールドのアイテムに対してループ Response.Write "<TH>" & fld_A.Name & "</TH>" '↑.Nameでフィールド名を表示する Next Response.Write "</TR>" 'お約束のEOFまでループは(データが無くなるまでループ)、 Do While rs.EOF = False 'レコードセットの.EOFがFalseの間 Response.Write "<TR>" '内容を表示する For Each fld_A In Rs.Fields 'フィールドのアイテムに対してループ Response.Write "<TD>" & fld_A.Value & "</TD>" '↑.Valueでフィールドの値を表示する Next Response.Write "</TR>" '次のレコードにポインタを移動する rs.MoveNext 'これを忘れると悲惨なことに、、、 Loop Response.Write "</TABLE>" 'テーブルは終わりです rs.Close '開いていたレコードセットを閉じる db.Close 'データベースも閉じようよ Set db = Nothing 'お行儀よくオブジェクトも開放しましょう %> <hr> 終了です。<br> </body> </html> -- 余談 -- 一流読者の心の声? SELECT T_月別売上.*, T_商品.* FROM T_月別売上 INNER JOIN T_商品 ON T_月別売上.商品CD = T_商品.商品CD; と INNER JOIN でつなげろって? まぁまぁ、あせらないでくださいよ・・・・

/* * 4.SQL文を変えてみた */

2つのテーブルを商品コードでつなげたレコードセットを作成して処理しました Select * From T_月別売上, T_商品 Where T_月別売上.商品CD = T_商品.商品CD Order By T_月別売上.商品CD と、SQLを発行するように修正しました。 すると、 57: 'グループ化のコードを初期化する 58: sum_code = Left(rs("商品CD").Value , 1) '先頭レコードの商品コード1桁目 ADODB.Recordset エラー '800a0cc1' 要求された名前、または序数に対応する項目がコレクションで見つかりません。 /cgi-bin/test/test073-3.asp, 行 58 えっ、58行目?エラー? あっ、rs("商品CD")って、 T_月別売上.商品CD なのか T_商品.商品CD か、わからないのかぁ。 rs("商品CD").Value を rs("T_月別売上.商品CD").Value に変更するか。 http://www.ken3.org/cgi-bin/test/test073-3.asp で、下記の作成したプログラムのテストが出来ます。 <%@LANGUAGE=VBScript%> <html> <head> <title>マスターとつなげて商品名を表示してみた</title> </head> <body> <!-- Ken3 --><!-- #include file="info.inc" --> <h2>マスターとつなげて商品名を表示してみた</h2> 2つのテーブルを商品コードでつなげたレコードセットを作成して処理しました<br> Select * From T_月別売上, T_商品<br> Where T_月別売上.商品CD = T_商品.商品CD<br> Order By T_月別売上.商品CD<br> <hr> <% 'ADO DB Connection オブジェクトを作成する、英文そのままじゃん Set db=Server.CreateObject("ADODB.Connection") '.Provider?プロバイダー?通信会社?じゃなくって 'データアクセスにはJet.OLEDB.4.0を使うことを設定 db.Provider = "Microsoft.Jet.OLEDB.4.0" '次に、接続DBの位置を渡すので、Server.MapPathで変換して渡す db.ConnectionString = Server.MapPath("db072.mdb") 'やっとデータベースを開ける db.open 'お約束のレコードセットの作成 T_月別売上,T_商品を指定 '結合の条件 T_月別売上.商品CD = T_商品.商品CD を指定 strSQL = "Select * From T_月別売上, T_商品" strSQL = strSQL & " Where T_月別売上.商品CD = T_商品.商品CD" strSQL = strSQL & " Order By T_月別売上.商品CD" Set rs = db.Execute(strSQL) 'SQL発行、レコードセットを作成 'データの表示をテーブルで行う Response.Write "<TABLE Border='1'>" '見出しを表示する Response.Write "<TR bgcolor=#E0FFFF>" Response.Write "<TH>商品名</TH>" For n = 4 To 9 '4月から9月と見出しを表示したいので Response.Write "<TH>" & n & "月</TH>" Next Response.Write "<TH>上期計</TH>" Response.Write "</TR>" '月別の小計・総合計を保存する配列を作成する Dim sum_group(12) 'グループ合計 Dim sum_all(12) '総合計 Dim sum_code 'グループ化のコード '総合計エリア、グループ合計を初期化する For n = 1 To 12 sum_group(n) = 0 sum_all(n) = 0 Next 'グループ化のコードを初期化する sum_code = Left(rs("T_月別売上.商品CD").Value , 1) '商品コード1桁目 'お約束のEOFまでループは(データが無くなるまでループ)、 Do While rs.EOF = False 'レコードセットの.EOFがFalseの間 'グループコードが変わったかチェックする If sum_code <> Left(rs("T_月別売上.商品CD").Value , 1) Then '小計を表示する Response.Write "<TR bgcolor=#FFE0FF>" '行を表示する Response.Write "<TD>小計</TD>" g_kamiki = 0 '小計の上期集計用の変数を初期化する For n = 4 To 9 '4〜9月 Response.Write "<TD>" & sum_group(n) & "</TD>" 'n月の値を表示 g_kamiki = g_kamiki + sum_group(n) '小計の上期のタメに計算 Next Response.Write "<TD>" & g_kamiki & "</TD>" '小計の上期計を表示 Response.Write "</TR>" '行の終わり '次のグループになるので、配列とCODEを初期化する sum_code = Left(rs("T_月別売上.商品CD").Value , 1) '次のコードを代入 For n = 4 To 9 '小計値を初期化する sum_group(n) = 0 Next End If Response.Write "<TR>" '行を表示する 'マスターから商品名を読み込む Response.Write "<TD>" & rs("商品名").Value & "</TD>" g_kamiki = 0 '集計用の変数を初期化する For n = 4 To 9 'フィールドにフィールド名でアクセスする Response.Write "<TD>" & rs("売上" & n).Value & "</TD>" '↑"売上" & nでフィールド名売上4..売上9を作成してアクセス '自分で上期を集計する g_kamiki = g_kamiki + rs("売上" & n).Value '月別、グループ、総合計を計算する sum_group(n) = sum_group(n) + rs("売上" & n).Value 'グループ sum_all(n) = sum_all(n) + rs("売上" & n).Value '総合計 Next '上期の合計を表示する Response.Write "<TD>" & g_kamiki & "</TD>" Response.Write "</TR>" '次のレコードにポインタを移動する rs.MoveNext 'これを忘れると悲惨なことに、、、 Loop 'ループを抜けたら、最後の小計を表示する '小計を表示する Response.Write "<TR bgcolor=#FFE0FF>" '行を表示する Response.Write "<TD>小計</TD>" g_kamiki = 0 '小計の上期集計用の変数を初期化する For n = 4 To 9 '4〜9月 Response.Write "<TD>" & sum_group(n) & "</TD>" 'n月の値を表示 g_kamiki = g_kamiki + sum_group(n) '小計の上期のタメに計算 Next Response.Write "<TD>" & g_kamiki & "</TD>" '小計の上期計を表示 Response.Write "</TR>" '行の終わり '総合計の表示(計算した総合計を表示する) Response.Write "<TR bgcolor=#FFFFE0>" '行を表示する Response.Write "<TD>総合計</TD>" g_kamiki = 0 '総合計の上期集計用の変数を初期化する For n = 4 To 9 '4〜9月の値を表示する Response.Write "<TD>" & sum_all(n) & "</TD>" 'n月の値を表示 g_kamiki = g_kamiki + sum_all(n) '総合計の上期のタメに計算 Next Response.Write "<TD>" & g_kamiki & "</TD>" '小計の上期計を表示 Response.Write "</TR>" '行の終わり Response.Write "</TABLE>" 'テーブルは終わりです '開いていたレコードセットを閉じる rs.Close 'データベースも閉じようよ db.Close 'お行儀よくオブジェクトも開放しましょう(通常は自動的に解放されるけど) Set db = Nothing %> <hr> 終了です。<br> </body> </html> -【けんぞう!】--------------------------------------------------------- 月500円、タバコなら2箱、120円缶コーヒーなら4缶分の謝礼をGetするなら http://www.ken3.org/etc/500yen/ ←無料アンケート系の広告です。 『チッ、がんばって回答して月500円かよ』(お馬鹿なプログラマー:31歳) ------------------------------------------------------------------------ 

/* * 5.終わりの挨拶 </HTML> */

今回は、 テーブルをつなげて、商品名付のレコードセットを作成して、 使用してみました。 自分でマスターを読み込むより、SQLでつなげたほうが簡単だったでしょ? 今回の解説でもSQLまだまだなんだけど、 何かの参考となれば幸いです。 ASP、VBScript勉強中の三流プログラマーのKen3でした。

No.74 2003/08/31
演算フィールドを作成する
[ページTOPへ戻る]

<演算フィールドを作成する>

こんにちは、三流プログラマーのKen3です。 小計・合計の表示プログラムで、 上期の合計をループで計算させてました。 今回は、チョットだけ進化させて、 SQL内で計算してみたいと思います。

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

前回までの、商品名表示を組み込んだ表 http://www.ken3.org/cgi-bin/test/test072-4.asp で、商品マスターから商品名を検索して、表示させました。 この表で、4月から9月の上期の合計を計算表示してます。 計算方法は、フィールドをループで計算してました。 g_kamiki = 0 '集計用の変数を初期化する For n = 4 To 9 'フィールドにフィールド名でアクセスする Response.Write "<TD>" & rs("売上" & n).Value & "</TD>" '↑"売上" & nでフィールド名売上4..売上9を作成してアクセス '自分で上期を集計する g_kamiki = g_kamiki + rs("売上" & n).Value Next まぁ、これも間違いじゃないんだけど。

/* * 2.演算フィールドって何? */

通常、下記のようなテーブルがあったら、 T_月別売上 テーブル 商品CD 売上4 売上5 ・ ・ 売上12 売上1 売上2 売上3 ↑作成したテーブルイメージ Select * From T_月別売上 なんて感じのSQL文を作成して、データを取り出します。 http://www.ken3.org/cgi-bin/test/test072-1.asp 上記で、テストしているのが、 Set rs = db.Execute("Select * From T_月別売上") でレコードセットを作成して、 For Each fld_A In Rs.Fields 'フィールドのアイテムに対してループ Response.Write "<TD>" & fld_A.Value & "</TD>" '↑.Valueでフィールドの値を表示する Next フィールドの全ての項目を呼び出し表示してます。 このフィールドに対して、演算した/フィールドを使った式を作ることが出来ます。 だから何?えっと、 下記のテストデータがあります。 商品CD 売上4 売上5 ... 売上1 売上2 売上3 A1 1 2 ..... A2 2 3 ..... 商品コードの1桁目をグループコードした時に、 下記のSQL文を書きます。 Select Left([商品CD], 1) AS GroupCD, * From T_月別売上 ポイントは、 Left([商品CD], 1) AS GroupCD として、Left関数を使用して、1文字とり出し、 AS GroupCDで演算結果のフィールド名はGroupCDと指定しました。 Select Left([商品CD], 1) AS GroupCD, * と,のあとの*で、テーブル内のフィールド全てを取り出してます。 百聞は一見になので、下記を実行してみてください。 http://www.ken3.org/cgi-bin/test/test074-1.asp ↑左端に、GroupCDの項目が表示されていると思います。 SQL文しか変わっていないけど、下記がソースです。 <%@LANGUAGE=VBScript%> <html> <head> <title>演算フィールドの作成テスト</title> </head> <body> <h2>演算フィールドの作成テスト</h2> 商品CDの一桁目を(左から1文字を)GroupCDにする。<br> strSQL = "Select Left([商品CD], 1) AS GroupCD, * From T_月別売上"<br> Set rs = db.Execute(strSQL)<br> と、演算フィールドとして、<br> <b>Left([商品CD], 1) AS GroupCD</b>を作成する。<br> <hr> <% 'ADO DB Connection オブジェクトを作成する、英文そのままじゃん Set db=Server.CreateObject("ADODB.Connection") 'データアクセスにはJet.OLEDB.4.0を使うことを設定 db.Provider = "Microsoft.Jet.OLEDB.4.0" '次に、接続DBの位置を渡すので、Server.MapPathで変換して渡す db.ConnectionString = Server.MapPath("db072.mdb") db.open 'データベースを開く '商品CDの一桁目を(左から1文字を)GroupCDにする strSQL = "Select Left([商品CD], 1) AS GroupCD, * From T_月別売上" Set rs = db.Execute(strSQL) 'データの表示をテーブルで行う Response.Write "<TABLE Border='1'>" '見出しを(フィールド名を)そのまま書き込む Response.Write "<TR>" For Each fld_A In Rs.Fields 'フィールドのアイテムに対してループ Response.Write "<TH>" & fld_A.Name & "</TH>" '↑.Nameでフィールド名を表示する Next Response.Write "</TR>" 'お約束のEOFまでループは(データが無くなるまでループ)、 Do While rs.EOF = False 'レコードセットの.EOFがFalseの間 Response.Write "<TR>" '内容を表示する For Each fld_A In Rs.Fields 'フィールドのアイテムに対してループ Response.Write "<TD>" & fld_A.Value & "</TD>" '↑.Valueでフィールドの値を表示する Next Response.Write "</TR>" '次のレコードにポインタを移動する rs.MoveNext 'これを忘れると悲惨なことに、、、 Loop Response.Write "</TABLE>" 'テーブルは終わりです '後始末 rs.Close '開いていたレコードセットを閉じる db.Close 'データベースも閉じようよ Set db = Nothing 'お行儀よくオブジェクトも開放しましょう %> <hr> 終了です。<br> </body> </html>

/* * 3.上期の合計を計算する */

簡単に計算することが出来ましたね。 演算フィールド、なんとなく、わかりましたか? 今度は、上期と下期の合計を計算してみます。 項目を+(加算)して上期計にする。 Select Left([商品CD], 1) AS GroupCD, T_月別売上.* ,([売上4]+[売上5]+[売上6]+[売上7]+[売上8]+[売上9]) AS 上期計 ,([売上10]+[売上11]+[売上12]+[売上1]+[売上2]+[売上3]) AS 下期計 >From T_月別売上 Set rs = db.Execute(strSQL) と、演算フィールドとして、上期計と下期計を作成しました。 http://www.ken3.org/cgi-bin/test/test074-2.asp で、テスト実行できます。 -【けんぞう!】--------------------------------------------------------- 番外編:在宅プログラマー↓↓派遣登録した時の笑い話です(実話です) http://www.ken3.org/etc/500yen/zaitaku.html ※おっ、と思ったら覗きに来てくださいね。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ----------------------------------------------------------------------- 

/* * 4.終わりの挨拶 </HTML> */

Left等の関数を使って、フィールドの編集結果を新たなフィールドにする。 ([売上4]+[売上5]+[売上6]+[売上7]+[売上8]+[売上9]) AS 上期計 と単純に計算を行って、フィールドを作成する。 そんなことが簡単に可能、そんなイメージがわきましたか? 自分で計算する ^^^^^^^^^^^^^^ g_kamiki = 0 '集計用の変数を初期化する For n = 4 To 9 'フィールドにフィールド名でアクセスする Response.Write "<TD>" & rs("売上" & n).Value & "</TD>" '↑"売上" & nでフィールド名売上4..売上9を作成してアクセス '自分で上期を集計する g_kamiki = g_kamiki + rs("売上" & n).Value Next SQLに演算フィールドを作る ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Select T_月別売上.*,([売上4]+[売上5]+[売上6]+[売上7]+[売上8]+[売上9]) AS 上期計 From T_月別売上 アナタは、自分で計算するorSQLに式を書いて置く、 どちらが好みですか? これで、横の計算は、SQLだけでもなんとかなりそうですね。 ---------------------------------------------------------------- | 商品名 | 4月 | 5月 | 6月 | 7月 | 8月 | 9月 | 上期計 | ---------------------------------------------------------------- | A1   |  1 |  2 |  3 |  4 |  5 |  6 |   21 | | A2   |  2 |  0 |  4 |  5 |  6 |  7 |   24 | | A3   |  3 |  1 |  5 |  6 |  7 |  8 |   30 | ---------------------------------------------------------------- | 小計  |  6 |  3 | 12 | 15 | 18 | 21 |   75 | ---------------------------------------------------------------- あとは、 縦の小計を簡単にしたいですよね・・・ 今回の解説でもSQL系まだまだなんだけど、 何かの参考となれば幸いです。 ASP、VBScript勉強中の三流プログラマーのKen3でした。



ページフッター リンクや広告、質問送信など

三流解説を読んでいただき、どうもです。ここから下は、三流君宛のメッセージ送信や 三流君のホームページの紹介・案内です
目的の情報が見つかったか?少々心配しつつ、、、※質問や感想は、気軽に送ってくださいね。

まぁ、基本はデータの受け取りかなぁ。
・[Form等を使用したデータのやり取り]・・・ASPと言っても、HTMLの入力フォームからデータを受け取ります。POSTやGETでやりとりを押さえますか。

次は、データの入出力 で ADOを使った(ADOで接続) と SQLの解説を少々
・[ADOでMdbファイルを使う]・・・MDBと接続して、簡単な追加・更新・削除を行った。
・[ADOでExcelと接続してみた]・・・.xlsと接続してSQLを使ってみた。
・[ADOでCSVと接続してみた]・・・.CSV テキストを読み出した。※更新・削除はできません

DBが使えるので、あまり使用しないけど、普通のテキストファイル処理
・[テキストファイル処理]・・・ファイルを開いて、書き込む。1行読み込みなどを軽く

VBScriptでFormat関数が無いなど、微妙にVBAと違うけど
[VBScript関数関係の説明]・・・少し、処理を書いてみた。
[その他処理サンプル]・・・あまり良いサンプル作れなかったけど。。。
何かの参考となれば幸いです。

ニガテな環境設定系など
[Win2003 Server に IIS を Setup]・・・ポイントの無い、ほぼ一本道解説だけど。
[IIS 仮想ディレクトの作成とASP動作TEST]・・・Web拡張でASPを有効にしただけです。

Blog:[三流君の作業日記]/ [サンプルコードのゴミ箱]/ 広告-[通販人気商品の足跡]

質問や要望など メッセージを送る(三流君に連絡する)

質問や要望など連絡方法でお互い確認が取りやすく、便利なのが掲示板なのですが、私の対応のまずさから不定期で荒れてしまい、掲示板は現在封鎖中です。(反省しなきゃ)
感想や質問・要望・苦情など 三流君へメッセージを送る。
時間的余裕のある要望・質問・苦情の場合は、下記のフォームからメッセージを送ることができます。

あなたのお名前(ニックネーム):さん
返信は?: 不用(HP更新を待つ) , E-mail→ アドレス:に返事をもらいたい



(感想や質問・要望 メッセージはHPで記事に載せることがあります。)


急ぎで連絡がほしい、そんな時は:[三流君連絡先アドレス]を見て連絡してください。



[三流君(TOP ken3.org へ戻る)] / [ASPで遊ぶ、失敗する] / [ASP記事 バックナンバー目次]