[三流君] −−>
[ASPで遊ぶ、失敗する] −−>
[バックナンバー一覧]
−−> No.044 MDBを使ったアンケート集計を作る
MDBを使ったアンケート集計を作る
本文(発行内容)
<MDBを使ったアンケート集計を作る>
こんにちは、三流プログラマーのKen3です。
今回は、
MDBファイルへアンケートの集計結果を貯めてみたいと思います
何かの参考となれば幸いです。
/*
* 1.やりたいこと
*/
発行しているメルマガの評価を5段階で集計したいと思います。
種類(ASP,VBA,愚痴,コンビニ)
と
発行した発行No別に、
5 満足(参考になった)
4 まぁまぁ(一部参考になった)
3 普通(どちらとも言えない)
2 なんかなぁ(期待と違った)
1 不満(読んで損した気分)
の投票数を管理したいと思います。
また、簡単な連続投票の防止機能を付けてみたいと思います。
(投票されたIPアドレスを記録して、連続投票の防止)
/*
* 2.仕様
*/
テーブル仕様
~~~~~~~~~~~~
データはDBへ保存管理します。
db044.mdb (Access2000で作成したDB)
へADO,SQLでアクセスします。
テーブル名 ans
フィールドは、
ID オートナンバー
KUBUN テキスト型
MNO 数値型
A5 数値型
A4 数値型
A3 数値型
A2 数値型
A1 数値型
IP テキスト型
WriteTime 日付型
で、投票数をカウントアップしていきます(詳細は取らないで累積加算します)
入力仕様
~~~~~~~~
データをURLに載せた形式で受取ります。(METHOD="GET")
受取り項目は
KUBUN=ASPなどの区分
NO=10 XX号
A=5〜1の評価
の3項目を受取ります。
出力仕様
~~~~~~~~
データを受取ったら、累積加算します。
加算後の結果とアンケートありがとうのメッセージを表示します。
主な処理の流れは、
~~~~~~~~~~~~~~~~~~
パラメータのチェック Aが1〜5の間か?
重複登録のチェック And 初回の時はレコードを新規作成
累積加算を行う
結果の表示
です。
/*
* 3.まずはパラメータのチェック
*/
エラーのパターンを洗い出すと、
エラー条件は、
KUBUN が 無し(スペース)
NO が無し Or 0の時
A か 1〜5以外の時(範囲外の時)
です。
正常パターンテスト用
http://www.ken3.org/cgi-bin/test/test044-1.asp?KUBUN=ASP&NO=44&A=5
http://www.ken3.org/cgi-bin/test/test044-1.asp?KUBUN=ASP&NO=44&A=4
http://www.ken3.org/cgi-bin/test/test044-1.asp?KUBUN=ASP&NO=44&A=3
http://www.ken3.org/cgi-bin/test/test044-1.asp?KUBUN=ASP&NO=44&A=2
http://www.ken3.org/cgi-bin/test/test044-1.asp?KUBUN=ASP&NO=44&A=1
エラーテスト用
http://www.ken3.org/cgi-bin/test/test044-1.asp?NO=44&A=1 区分無し
http://www.ken3.org/cgi-bin/test/test044-1.asp?KUBUN=ASP&A=2 NO無し
http://www.ken3.org/cgi-bin/test/test044-1.asp?KUBUN=ASP&NO=44 評価無し
http://www.ken3.org/cgi-bin/test/test044-1.asp?KUBUN=ASP&NO=44&A=6 評価範囲外
でテスト可能です。
<%@LANGUAGE=VBScript%>
<html>
<head>
<title>パラメータをチェックする</title>
</head>
<body>
<h2>パラメータをチェックする</h2>
test044-1.asp<br>
<hr>
エラー条件は、<br>
KUBUN が 無し(スペース)<br>
NO が無し Or 0の時<br>
A か 1〜5以外の時(範囲外の時)<br>
<hr>
<%
'値の代入
KUBUN = Request.QueryString("KUBUN")
NO = Request.QueryString("NO")
A = Request.QueryString("A")
'テストで値を表示
Response.Write "<Font Color='BLUE'>受取った値は</Font><BR>"
'For Each で Request.QueryStringの値を取出す
For Each RQ In Request.QueryString
Response.Write RQ & "=" '名称表示
Response.Write Request.QueryString(RQ) & "<BR>" '値の表示
Next
'パラメータのチェックを行う
ret = errchk() 'チェック用の関数を呼ぶ
If ret = -1 Then 'エラーか?
Response.Write "<Font Color='red'>"
Response.Write "受取ったパラメータが異常です"
Response.Write "</Font>"
Else '正常時
Response.Write "パラメータは正常です"
End If
%>
<hr>
</body>
</html>
<% '外側に関数を書いてます(どこでもいいんだけど)
Function errchk() 'パラメータのエラーをチェックします 0:正常 -1:エラー
errchk = 0 'エラーを無しにする(初期値で代入)
'KUBUN が 無し(スペース)
If Len(KUBUN) = 0 Then errchk = -1
'NO が無し Or 0の時
If Len(NO) = 0 Then errchk = -1
If CInt(NO) = 0 Then errchk = -1
'A か 1〜5以外の時(範囲外の時)
If A < 1 Or 5 < A Then errchk = -1
End Function |
%>
処理の解説
~~~~~~~~~~
'値の代入
KUBUN = Request.QueryString("KUBUN")
NO = Request.QueryString("NO")
A = Request.QueryString("A")
GETでデータを受取るので、.QueryStringで値を取出します。
'テストで値を表示
Response.Write "<Font Color='BLUE'>受取った値は</Font><BR>"
'For Each で Request.QueryStringの値を取出す
For Each RQ In Request.QueryString
Response.Write RQ & "=" '名称表示
Response.Write Request.QueryString(RQ) & "<BR>" '値の表示
Next
確認の意味で、受取ったパラメータを表示してます。
'パラメータのチェックを行う
ret = errchk() 'チェック用の関数を呼ぶ
とチェックの関数を呼んでます
(チェック処理を関数にまとめました)
If ret = -1 Then 'エラーか?
Response.Write "<Font Color='red'>"
Response.Write "受取ったパラメータが異常です"
Response.Write "</Font>"
Else '正常時
Response.Write "パラメータは正常です"
End If
リターン値を見て、結果を判断してます。
肝心のチェック処理は、各エラーパターンに対して、チェックを行い、
エラーの時はリターン値に-1をセットしてます。
Function errchk() 'パラメータのエラーをチェックします 0:正常 -1:エラー
errchk = 0 'エラーを無しにする(初期値で代入)
'KUBUN が 無し(スペース)
If Len(KUBUN) = 0 Then errchk = -1
'NO が無し Or 0の時
If Len(NO) = 0 Then errchk = -1
If CInt(NO) = 0 Then errchk = -1
'A か 1〜5以外の時(範囲外の時)
If A < 1 Or 5 < A Then errchk = -1
End Function |
/*
* 4.連続登録のチェック と データ加算
*/
次は、連続登録のチェックと初回の時はレコードを作成です。
KUBUNとMNOを条件にして、
ansテーブルからデータを読み込みます。
該当データ無しの時(新規レコード時)、データ0のレコードを作成します
データが読めた時は、IPアドレスを比べて、同じ時はエラーを返します。
Function cntDATA() '連続登録のチェックとデータ加算 0:正常 -1:エラー
'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("db044.mdb")
'やっとデータベースを開ける
db.open
'検索するSQLを作成する
strSQL = "Select * From ans "
strSQL = strSQL & "Where KUBUN = '" & KUBUN & "' And MNO = " & NO
'オマケで画面にデータ表示
Response.Write "<hr>発行する(した)SQL文は<br><B><font color='green'>"
Response.Write strSQL & "</font></B><br>です<hr>"
Set rs = db.Execute(strSQL) 'SQL文を発行してレコードセットを作成
If rs.EOF = True Then 'データが見つからなかった時
strINSSQL = "INSERT INTO ans (KUBUN, MNO) VALUES ("
strINSSQL = strINSSQL & "'" & KUBUN & "'" '区分
strINSSQL = strINSSQL & ", " & NO & ")" 'NO
'オマケで画面にデータ表示
Response.Write "<hr>発行する(した)SQL INSERT文は<br><B><font color='green'>"
Response.Write strINSSQL & "</font></B><br>です<hr>"
'SQL INSERT文を発行
db.Execute(strINSSQL)
Else 'データ在りの時
'前回のIPアドレスと同じかチェックする
If rs("IP") = Request.ServerVariables("REMOTE_ADDR") Then
cntDATA = -1 'エラーにする
rs.Close
Exit Function '関数を途中で抜ける
End If
End If
rs.Close 'レコードセットを閉じる
'UPDATEのSQL文を作成する
strUSQL = "UPDATE ans Set " 'ansテーブルを更新
strUSQL = strUSQL & "IP = '" & Request.ServerVariables("REMOTE_ADDR") & "'"
strUSQL = strUSQL & ", WriteTime = #" & Now & "#"
strUSQL = strUSQL & ", A" & A & " = A" & A & " + 1" 'カウントアップ
strUSQL = strUSQL & " Where KUBUN = '" & KUBUN & "' And MNO = " & NO '条件
'オマケで画面にデータ表示
Response.Write "<hr>発行する(した)SQL UPDATE文は<br><B><font color='green'>"
Response.Write strUSQL & "</font></B><br>です<hr>"
'SQL文を発行
db.Execute(strUSQL)
'更新結果を読み直す
Set rs = db.Execute(strSQL) 'SQL文を発行してレコードセットを作成
Response.Write "更新結果<br>"
Response.Write "KUBUN=<b>" & rs("KUBUN") & "</b><br>"
Response.Write "MNO=<b>" & rs("MNO") & "</b><br>"
Response.Write "A5=<b>" & rs("A5") & "</b><br>"
Response.Write "A4=<b>" & rs("A4") & "</b><br>"
Response.Write "A3=<b>" & rs("A3") & "</b><br>"
Response.Write "A2=<b>" & rs("A2") & "</b><br>"
Response.Write "A1=<b>" & rs("A1") & "</b><br>"
Response.Write "IP=<b>" & rs("IP") & "</b><br>"
Response.Write "WriteTime=<b>" & rs("WriteTime") & "</b><br>"
'リターン値をセットして関数終了
cntDATA = 0 '正常終了
End Function |
ポイント解説
~~~~~~~~~~~~
http://www.ken3.org/cgi-bin/test/test044-2.asp?KUBUN=ASP&NO=6&A=2
を貰ったら、
'検索するSQLを作成する
strSQL = "Select * From ans "
strSQL = strSQL & "Where KUBUN = '" & KUBUN & "' And MNO = " & NO
で、
Select * From ans Where KUBUN = 'ASP' And MNO = 6
とSQL文を発行します。
If rs.EOF = True Then 'データが見つからなかった時
もしデータが見つからなかったら、
初めての投票なので、区分とNOでレコードを作ります(作りたいです)
strINSSQL = "INSERT INTO ans (KUBUN, MNO) VALUES ("
strINSSQL = strINSSQL & "'" & KUBUN & "'" '区分
strINSSQL = strINSSQL & ", " & NO & ")" 'NO
で、
INSERT INTO ans (KUBUN, MNO) VALUES ('ASP', 6)
とSQL INSERT文を作成して、レコードを作ります。
Else 'データ在りの時
は、
読みこんだレコードの前回IPが現在のアドレスと一緒かチェックします。
'前回のIPアドレスと同じかチェックする
If rs("IP") = Request.ServerVariables("REMOTE_ADDR") Then
cntDATA = -1 'エラーにする
rs.Close
Exit Function '関数を途中で抜ける
End If
End If
rs.Close 'レコードセットを閉じる
ここまでで、IPアドレスが同じ時は関数を抜け、
初投票の時はデータレコードが作成されました。
次は、
・投票されたAをカウントアップ
・投票者のIPアドレスをセット
・投票時間のセットです
SQLのUPDATE文更新処理で行ってみようと思います。
'UPDATEのSQL文を作成する
strUSQL = "UPDATE ans Set " 'ansテーブルを更新
strUSQL = strUSQL & "IP = '" & Request.ServerVariables("REMOTE_ADDR") & "'"
strUSQL = strUSQL & ", WriteTime = #" & Now & "#"
strUSQL = strUSQL & ", A" & A & " = A" & A & " + 1" 'カウントアップ
strUSQL = strUSQL & " Where KUBUN = '" & KUBUN & "' And MNO = " & NO '条件
で
UPDATE ans Set
IP = '203.182.79.243',
WriteTime = #2003/04/04 23:47:35#,
A2 = A2 + 1
Where KUBUN = 'ASP' And MNO = 6
とUPDATEのSQL文を作成しました。
ここの一番のポイントが、
A2 = A2 + 1
^^^^^^^^^^^^^
の更新方法です。
このように項目(フィールド)を使った計算を書くことが出来ます。
KUBUN と MNOで初めにレコードを読み、
レコードが無い時は、レコードを作る、
在った時は前回のIPアドレスと比べる。
重複チェックと新規のレコード作成が終了しているので、
UPDATE文で、投票された項目を+1して、
同時に、IPアドレスと時刻を更新しました。
なんか複雑ですが、流れはほぼ一直線なので、
一歩一歩見て下さい。
/*
* 4.終わりの挨拶
*/
今回は、DBを使ったカウント処理でした。
ポイントの
A2 = A2 + 1の更新SQL
と
新規レコードの追加
そこだけ押さえてください
カウント処理の参考になれば幸いです。
素朴な疑問あったら、気軽に、
メール、掲示板に書き込んでくださいね。
掲示板 : http://www.ken3.org/asp/bbs-asp.html
ASP、VBScript勉強中の三流プログラマーのKen3でした。
----------------------------------
関連項目(ただのバックナンバー紹介)
----------------------------------
[No.41 POST(Request.Form)/GET(Request.QueryString) で 送られてきた値を表示する]
http://www.ken3.org/backno/backno_asp09.html#41
のGET(Request.QueryString) を参考に
[No.27 SQL INSERT INTO文でデータの追加]
http://www.ken3.org/backno/backno_asp06.html#27
のSQL INSERT INTO文作成方法
[No.33 SQL UPDATE文でデータを更新する]
http://www.ken3.org/backno/backno_asp07.html#33
のSQL UPDATE文
フィードバック
ASP系の→[掲示板]←を覗く、質問を書き込む
評価・感想
三流君の主なリンク先
[アクセスランキング]
[サイトマップ]
[リンク先・相互リンク先など]
Ken3の日記(weblog) --
[広告・副収入系]
[プログラマー業務の愚痴]
[VBA系の話題]
[ASP系の話題]
[コンビニ系ネタ]
[その他]
その他 宣伝広告