1.系統主要涉及以下幾個表
問卷項目表(Q_Naire) 問卷題目表(Q_Problem) 題目類型表(Q_ProblmeType)
題目選項表(Q_Options) 調查結果表(Q_Answer) 參與用戶表(Q_User)

2.涉及的存儲過程
pNextID 獲取實體表主鍵ID
sp_NaireAnswer 將問卷調查的結果寫入結果表(通過WebService方法調用)
sp_NaireImport 通過導入的問卷數據生成問卷項目(根據Q_Naire_Import表中的問卷數據分別寫入Q_Naire、Q_Problem、Q_Options中生成問卷)
sp_NaireResult 問卷調查結果數據集
3.系統實現方式
后台:主要是通過后台維護的問卷數據,根據問卷項目編號獲取問卷題目以及題目類型
然后根據題目類型在后台生成相應的控件,后台控件生成通過Asp.Net實現
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data.SqlClient; using System.Data; namespace QuestionnaireSurveySystem { public partial class Naire : System.Web.UI.Page { /// <summary> /// 問卷編號 /// </summary> public string nid = string.Empty; /// <summary> /// 用戶編號 /// </summary> public string uid = string.Empty; /// <summary> /// 數據庫連接字符串 /// </summary> private string constr = ConfigHelper.GetConfigString("System.ConnectionString"); protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { try { if (Request.Params["uid"].ToString() != null && Request.Params["uid"].ToString().Trim() != "") { uid = Request.Params["uid"].ToString(); } if (Request.Params["nid"].ToString() != null && Request.Params["nid"].ToString().Trim() != "") { nid = Request.Params["nid"].ToString(); //綁定題目 BindNaire(nid); } } catch { Response.Redirect("Error.html"); } } } /// <summary> /// 動態生成問卷表單 /// </summary> /// <param name="id">問卷項目編號</param> private void BindNaire(string id) { SqlConnection con = new SqlConnection(constr); con.Open(); DataTable dt = new DataTable(); DataTable dt2 = new DataTable(); SqlDataAdapter sda = new SqlDataAdapter("SELECT b.ID AS Nid,b.Title,b.Descr,a.ID AS Pid,a.Title,d.TypeName,c.ID AS Oid,c.OptionValue FROM dbo.Q_Problem a LEFT JOIN dbo.Q_Naire b ON a.Nid=b.ID LEFT JOIN dbo.Q_Options c ON a.ID=c.Pid LEFT JOIN dbo.Q_ProblmeType d ON a.Tid=d.ID WHERE b.ID=" + id + "", con); sda.Fill(dt); SqlDataAdapter sda2 = new SqlDataAdapter("SELECT a.ID as Pid,a.Title,a.Nid,a.Tid,b.TypeName,b.Descr FROM dbo.Q_Problem a LEFT JOIN dbo.Q_ProblmeType b ON a.Tid=b.ID WHERE a.Nid=" + id + " ORDER BY a.Tid ASC", con); sda2.Fill(dt2); lbltitle.Text = dt.Rows[0]["Title"].ToString(); lbldescr.Text = dt.Rows[0]["Descr"].ToString(); int sid = 1;//單選題序號 int mid = 1;//多選題序號 int aid = 1;//問答題序號 if (dt2.Rows.Count > 0) { foreach (DataRow dr in dt2.Rows) { switch (dr["TypeName"].ToString()) { case "單選題": Label lbl = new Label(); lbl.Text = sid.ToString() + "、" + dr["Title"].ToString(); RadioButtonList rbl = new RadioButtonList(); rbl.ID = dr["Pid"].ToString(); DataRow[] drs = dt.Select("Pid=" + dr["Pid"] + ""); foreach (DataRow drc in drs) { ListItem li1 = new ListItem(); li1.Text = drc["OptionValue"].ToString(); li1.Value = drc["Oid"].ToString(); rbl.Items.Add(li1); } if (sid == 1) { Label lblss = new Label(); lblss.Text = "單選題"; lblss.Font.Bold = true; this.Panel1.Controls.Add(lblss); this.Panel1.Controls.Add(new LiteralControl("<br/>")); } this.Panel1.Controls.Add(lbl); this.Panel1.Controls.Add(new LiteralControl("<br/>")); this.Panel1.Controls.Add(rbl); this.Panel1.Controls.Add(new LiteralControl("<br/>")); sid = sid + 1; break; case "多選題": Label lbl2 = new Label(); lbl2.Text = mid.ToString() + "、" + dr["Title"].ToString(); CheckBoxList cbl = new CheckBoxList(); cbl.ID = dr["Pid"].ToString(); DataRow[] drs2 = dt.Select("Pid=" + dr["Pid"] + ""); foreach (DataRow drc in drs2) { ListItem li2 = new ListItem(); li2.Text = drc["OptionValue"].ToString(); li2.Value = drc["Oid"].ToString(); cbl.Items.Add(li2); } if (mid == 1) { Label lblms = new Label(); lblms.Text = "多選題"; lblms.Font.Bold = true; this.Panel1.Controls.Add(lblms); this.Panel1.Controls.Add(new LiteralControl("<br/>")); } this.Panel1.Controls.Add(lbl2); this.Panel1.Controls.Add(new LiteralControl("<br/>")); this.Panel1.Controls.Add(cbl); this.Panel1.Controls.Add(new LiteralControl("<br/>")); mid = mid + 1; break; case "問答題": Label lbl3 = new Label(); lbl3.Text = aid.ToString() + "、" + dr["Title"].ToString(); TextBox txb = new TextBox(); txb.ID = dr["Pid"].ToString(); txb.TextMode = TextBoxMode.MultiLine; txb.Width = Unit.Pixel(600); txb.Height = Unit.Pixel(50); if (aid == 1) { Label lblas = new Label(); lblas.Text = "問答題"; lblas.Font.Bold = true; this.Panel1.Controls.Add(lblas); this.Panel1.Controls.Add(new LiteralControl("<br/>")); } this.Panel1.Controls.Add(lbl3); this.Panel1.Controls.Add(new LiteralControl("<br/>")); this.Panel1.Controls.Add(txb); this.Panel1.Controls.Add(new LiteralControl("<br/>")); aid = aid + 1; break; } } } //關閉連接 釋放資源 con.Close(); Dispose(); } } }
前台:通過JavaScript方法獲取用戶選擇項,作為參數傳遞給后台WebService方法,然后調用存儲過程將問卷結果寫入數據庫
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Naire.aspx.cs" Inherits="QuestionnaireSurveySystem.Naire" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <script type="text/javascript"> //獲取問卷填寫內容 function GetRadioValue() { var p = document.getElementsByTagName("input"); var v = ""; for (var i = 0; i < p.length; i++) { if (p[i].checked) { v = v + p[i].name.split('$')[0] + "." + p[i].value + ","; } } var t = document.getElementsByTagName("textarea"); for (var i = 0; i < t.length; i++) { /*處理輸入中的"."*/ v = v + t[i].id + "." + t[i].value.toString().split('.').join('') + ","; } v = v.substring(0, v.length - 1); return v; } //判斷是否填寫完整 function CheckSelect() { /* 在使用indexOf方法前,執行一下下面的js, 原理就是如果發現數組沒有indexOf方法,會添加上這個方法 */ if (!Array.prototype.indexOf) { Array.prototype.indexOf = function (elt /*, from*/) { var len = this.length >>> 0; var from = Number(arguments[1]) || 0; from = (from < 0) ? Math.ceil(from) : Math.floor(from); if (from < 0) from += len; for (; from < len; from++) { if (from in this && this[from] === elt) return from; } return -1; }; } /* */ var ok = false;//完成標志 var no = new Array();//應完成項 var nn = new Array();//已完成項 var s = document.getElementsByTagName('input');//選擇項 for (var i = 0; i < s.length; i++) { var n = s[i].name.split('$')[0].toString(); if (no.indexOf(n) < 0 && s[i].type == "radio") { no.push(n) } if (no.indexOf(n) < 0 && s[i].type == "checkbox") { no.push(n) } if (s[i].checked && nn.indexOf(n) < 0 && s[i].type == "radio") { nn.push(n); } if (s[i].checked && nn.indexOf(n) < 0 && s[i].type == "checkbox") { nn.push(n); } } var t = document.getElementsByTagName("textarea"); for (var i = 0; i < t.length; i++) { var m = t[i].name.split('$')[0]; if (no.indexOf(m) < 0) { no.push(n) } if (t[i].value != null && t[i].value != "") { nn.push(n) } } if (nn.length < no.length) { ok = false; } else { ok = true; } return ok; } //將填寫內容寫入數據庫 function Insert() { var ok = CheckSelect(); if (ok) { var r = GetRadioValue(); if (r != "") { var f=Select(); if(f) { var uid=<%=uid %>; var nid=<%=nid %>; var URL = "Server/NaireService.asmx/RecordResult" var Params = "uid=" + uid + "&nid="+nid+"&val=" + r + ""; //傳給WebService的參數 var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); xmlhttp.Open("POST", URL, false); //用POST方法 xmlhttp.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xmlhttp.SetRequestHeader("Content-Length", Params.length); xmlhttp.send(Params); if (xmlhttp.Status == 200) { //200代表成功 alert("提交成功,謝謝您的參與和支持!"); //刷新頁面 location.reload(); } } else{ alert("您已經完成問卷,不用重復提交!"); } } else { alert("內容不可為空!"); } } else { alert("所有調查項完成后才可以提交,請檢查!"); } } function Select() { var uid=<%=uid %>; var nid=<%=nid %>; var URL = "Server/NaireService.asmx/IsHasCarry"; var Params = "uid=" + uid + "&nid="+nid+""; //傳給WebService的參數 var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); xmlhttp.Open("POST", URL, false); //用POST方法 xmlhttp.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xmlhttp.SetRequestHeader("Content-Length", Params.length); xmlhttp.send(Params); if (xmlhttp.Status == 200) { //200代表成功 var res = xmlhttp.responseXML; //得到WebService傳回的結果 var strJSON = res.childNodes[1].text; var obj = eval("(" + strJSON + ")"); //轉換后的JSON對象 if(obj){return false; } else{return true; } } else{return false; } } </script> <style id="style1" type="text/css"> body { background-color: #9ECBE8 } </style> </head> <body> <form id="form1" runat="server"> <table width="100%"> <tr> <td style="width: 25%"> </td> <td align="center" style="font-size: larger; font-weight: bold"> <asp:Label ID="lbltitle" runat="server"></asp:Label> </td> <td style="width: 25%"> </td> </tr> <tr> <td style="width: 25%"> </td> <td align="left" class=""> <asp:Label ID="lbldescr" runat="server"></asp:Label> </td> <td style="width: 25%"> </td> </tr> <tr> <td style="width: 25%"> </td> <td> <hr style="border: 1px dotted #036" /> </td> <td style="width: 25%"> </td> </tr> <tr> <td style="width: 25%"> </td> <td align="left"> <asp:Panel ID="Panel1" runat="server"> </asp:Panel> </td> <td style="width: 25%"> </td> </tr> <tr> <td style="width: 25%"> </td> <td> <hr style="border: 1px dotted #036" /> </td> <td style="width: 25%"> </td> </tr> <tr> <td style="width: 25%"> </td> <td align="left"> <input type="button" value="提交" onclick="Insert()" /> <input type="button" value="重置" onclick="javascript:location.reload()" /> </td> <td style="width: 25%"> </td> </tr> </table> </form> </body> </html>
WebService代碼
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Services; using System.Data.SqlClient; using System.Data; namespace QuestionnaireSurveySystem.Server { /// <summary> /// NaireService 的摘要說明 /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] // 若要允許使用 ASP.NET AJAX 從腳本中調用此 Web 服務,請取消對下行的注釋。 [System.Web.Script.Services.ScriptService] public class NaireService : System.Web.Services.WebService { //[WebMethod] //public string HelloWorld() //{ // return "Hello World"; //} private string constr = ConfigHelper.GetConfigString("System.ConnectionString"); /// <summary> /// 判斷用戶是否有進行問卷 /// </summary> /// <param name="uid"></param> /// <param name="nid"></param> /// <returns></returns> [WebMethod(Description = "判斷用戶是否有進行問卷")] public bool IsHasCarry(string uid, string nid) { SqlConnection con = new SqlConnection(constr); con.Open(); DataTable dt = new DataTable(); SqlDataAdapter sda = new SqlDataAdapter("SELECT ID FROM Q_Answer WHERE Uid=" + uid + " AND Nid=" + nid + "", con); sda.Fill(dt); con.Close(); if (dt.Rows.Count > 0) { return true; } else { return false; } } /// <summary> /// 將問卷調查的結果寫入數據庫 /// </summary> /// <param name="uid">用戶編號</param> /// <param name="nid">項目編號</param> /// <param name="val">結果字符串</param> /// <returns></returns> [WebMethod(Description = "將問卷調查的結果寫入數據庫")] public int RecordResult(string uid, string nid, string val) { SqlConnection con = new SqlConnection(constr); con.Open(); SqlCommand cmd = new SqlCommand("exec sp_NaireAnswer " + uid + "," + nid + ",'" + val + "'", con); int i = cmd.ExecuteNonQuery(); con.Close(); return i; } } }
結束語:
時間關系,只是作了簡單的問卷展示頁面,其他維護性頁面都沒有做。直接在后台數據庫處理的。有興趣的朋友可以完善下。寫的很粗糙,歡迎大神拍磚。
補一張效果圖

