費用登記系統(開發小結)
一)項目背景
由於某公司實行新的費用制度,涉及部門的年終考核事項,考核部門需要根據各個部門的費用實際使用情況做預算,分析,統計,指標評估,作為公司降本節支的重要依據,最大限度的降低公司的運營成本。費用分攤項目應運而生,由於人力不足,一切簡單從簡,以滿足最基本的需求為目標,遵循流程簡化,界面簡潔,操作簡單為基本原則,進行小型系統開發。
二)項目需求說明
項目需求主要來源於企划部的實際工作需要,簡單介紹如下:
1)總體需要:能登記各個部門的實際發生的費用明細,具體如:商品的基本資料(名稱,規格,品牌,單價,數量,金額,承擔部門等等);招待費用,車輛派遣(車牌號,車型,司機,公里數,費用發生額等);錄入時指定特定部門或者人員,可以查詢,需要經過相關審核(部門審核,上級領導審核)。
2)費用錄入要求如下:
表1-1 費用錄入要求說明
說明:公司費用大致分為這四大類,即:日常費用,招待費用,物流日常費用(指物流部門的日常費用),商務車費用,錄入時根據此分類對應錄入系統即可。
3)費用分類資料細則說明:(部分,樣式表)
表2-2 費用分類
說明:費用分類統一編號由錄入部門決定,例如:人力資源部錄入費用編號以10開頭,財務部錄入費用編號以20開頭……等。
4)費用明細如下:
表2-3 費用明細說明
說明:錄入的時候,需要存儲,如:人力資源部登記福利費的時候需要說明是什么?婦女節,生日福利,……做查詢的時候,只需要看到福利費,以費用編號為最小單位統計依據,不再進行細分。
5)錄入和審核需求:
表 2-4 費用審核說明
說明:任何費用必須由部門領導審核,分管領導審核需要滿足一定條件,如某筆費用發生額超過規定額時,才需要上級領導審核。有些費用需要指定某部門某專員錄入,如商務車費用只能由物流事業部相關人士錄入等。
三)項目開發過程
分析相關需求,與提供相關需要的人員進行多次多次溝通,進行簡單的相關的設計。
1)邏輯分析:
哪些人屬於哪個部門,是否擁有系統的使用權限,系統的權限分哪些等級?==>人員,部門,人員與部門關系等基礎資料;可以在給人員分配部門的同時分配系統 使用權限;
哪些費用有哪些部門哪些人錄入,需要什么相關審核?==>費用明細的基礎資料,費用錄入生成相關單據,審核流水確定需要考慮部門的相關負責人等。
生成的單據的編號,新增用戶,部門的相關編號怎么產生?單據審核節點判斷?==>存儲過程,標量值函數實現。
哪些人可以查詢什么費用?==>費用的相關查詢,暫定只能普通用戶看到本部門的費用信息。
2 )數據庫設計:有邏輯分析不難得出本系統需要的基礎表及其相關存儲過程,函數。
圖 3-1 數據庫設計
詳細說明,此處略去。
3)模塊設計,如圖所示:
圖 3-2 模塊設計
相關說明:基礎資料維護(1)包括:
人員維護:新增,查詢,保存,修改,修改用戶密碼,刪除,關閉等基本功能;
部門維護:新增,查詢,保存,修改,刪除,關閉等基本功能;
人員部門維護:新增,查詢,保存,修改,刪除,關閉等基本功能;
費用項目維護:新增,查詢,保存,修改,刪除,關閉等基本功能;
費用項目登記(2)包括:
日常費用錄入:新增,保存,修改,刪除,關閉等基本功能;
招待費用錄入:新增,保存,修改,刪除,關閉等基本功能;
物流日常費用錄入:新增,保存,修改,刪除,關閉等基本功能;
商務車費用錄入:新增,保存,修改,刪除,關閉等基本功能;
特別說明:所有單據一旦被審核,均不能被修改或者刪除。
費用審核審核流程(3)包括:
部門審核:查詢,審核通過,審核不通過,退出等基本功能;
分管領導審核:查詢,審核通過,審核不通過,退出等基本功能;
總經理審核:查詢,審核通過,審核不通過,退出等基本功能;
費用查詢(4),主要用於查詢,可以看到費用明細,審核進度等,有待進一步細分,本系統只是初稿,后期會有擴充。
退出(5):退出本系統並關閉;
關於(6):計算器功能,屬於輔助功能擴展。
說明:本系統分四個角色,分別擁有不同的模塊,介紹如下:
a)管理員:權限最大,擁有系統的全部功能(1)--(6);(說明:(1)代表模塊基礎資料維護)
b)審核:擁有模塊(2)(3)(4)(5)(6);
c)錄入:擁有模塊(2)(4)(5)(6);
d)查詢:權限最小,擁有模塊(4)(5)(6);
完整設計見:FS系統開發設計(思維導圖)
4)代碼設計(略)(列幾個比較常用的,希望對初學者有所幫助)
SQL基本操作:(SQLHelper.cs)

1 using System; 2 using System.Data; 3 using System.Xml; 4 using System.Data.SqlClient; 5 using System.Collections; 6 using System.Configuration; 7 using System.Collections.Generic; 8 using System.Data.Common; 9 using System.Windows.Forms; 10
11 namespace BLL 12 { 13 /// <summary>
14 /// 數據訪問抽象基礎類 15 /// </summary>
16 public abstract class SqlHelper 17 { 18 private static string conn = ConfigurationManager.ConnectionStrings["ExpensionDBC"].ConnectionString.ToString(); 19 public SqlHelper() 20 { 21 } 22 #region 公用方法
23 /// <summary>
24 /// 判斷是否存在某表的某個字段 25 /// </summary>
26 /// <param name="tableName">表名稱</param>
27 /// <param name="columnName">列名稱</param>
28 /// <returns>是否存在</returns>
29 public static bool ColumnExists(string tableName, string columnName) 30 { 31 string sql = "select count(1) as cnt from syscolumns where [id]=object_id('" + tableName + "') and [name]='" + columnName + "'"; 32 object res = GetSingle(sql); 33 if (res == null) 34 { 35 return false; 36 } 37 return Convert.ToInt32(res) > 0; 38 } 39 /// <summary>
40 /// 取得最大編號+1 41 /// </summary>
42 /// <param name="FieldName">字段</param>
43 /// <param name="TableName">表名</param>
44 /// <returns>最大編號+1</returns>
45 public static int GetMaxID(string FieldName, string TableName) 46 { 47 string strsql = "select max(" + FieldName + ")+1 from " + TableName; 48 object obj = SqlHelper.GetSingle(strsql); 49 if (obj == null) 50 { 51 return 1; 52 } 53 else
54 { 55 return int.Parse(obj.ToString()); 56 } 57 } 58 /// <summary>
59 /// 查詢有無結果 60 /// </summary>
61 /// <param name="strSql">查詢語句</param>
62 /// <returns>結果空否</returns>
63 public static bool Exists(string strSql) 64 { 65 object obj = SqlHelper.GetSingle(strSql); 66 int cmdresult; 67 if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))) 68 { 69 cmdresult = 0; 70 } 71 else
72 { 73 cmdresult = int.Parse(obj.ToString()); 74 } 75 if (cmdresult == 0) 76 { 77 return false; 78 } 79 else
80 { 81 return true; 82 } 83 } 84 /// <summary>
85 /// 表是否存在 86 /// </summary>
87 /// <param name="TableName">表</param>
88 /// <returns>存在否</returns>
89 public static bool TabExists(string TableName) 90 { 91 string strsql = "select count(*) from sysobjects where id = object_id(N'[" + TableName + "]') and OBJECTPROPERTY(id, N'IsUserTable') = 1"; 92 object obj = SqlHelper.GetSingle(strsql); 93 int cmdresult; 94 if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))) 95 { 96 cmdresult = 0; 97 } 98 else
99 { 100 cmdresult = int.Parse(obj.ToString()); 101 } 102 if (cmdresult == 0) 103 { 104 return false; 105 } 106 else
107 { 108 return true; 109 } 110 } 111 /// <summary>
112 /// 查詢有無結果,帶參數 113 /// </summary>
114 /// <param name="strSql">查詢語句</param>
115 /// <param name="cmdParms">參數</param>
116 /// <returns>結果空否</returns>
117 public static bool Exists(string strSql, params SqlParameter[] cmdParms) 118 { 119 object obj = SqlHelper.GetSingle(strSql, cmdParms); 120 int cmdresult; 121 if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))) 122 { 123 cmdresult = 0; 124 } 125 else
126 { 127 cmdresult = int.Parse(obj.ToString()); 128 } 129 if (cmdresult == 0) 130 { 131 return false; 132 } 133 else
134 { 135 return true; 136 } 137 } 138 #endregion
139
140 #region 執行簡單SQL語句
141 /// <summary>
142 /// 執行SQL語句,返回影響的記錄數 143 /// </summary>
144 /// <param name="SQLString">SQL語句</param>
145 /// <returns>影響的記錄數</returns>
146 public static int ExecuteSql(string SQLString) 147 { 148 using (SqlConnection connection = new SqlConnection(conn)) 149 { 150 using (SqlCommand cmd = new SqlCommand(SQLString, connection)) 151 { 152 try
153 { 154 connection.Open(); 155 int rows = cmd.ExecuteNonQuery(); 156 return rows; 157 } 158 catch (System.Data.SqlClient.SqlException e) 159 { 160 connection.Close(); 161 throw e; 162 } 163 } 164 } 165 } 166 /// <summary>
167 /// 執行SQL語句等待時間 168 /// </summary>
169 /// <param name="SQLString">查詢語句</param>
170 /// <param name="Times">時間</param>
171 /// <returns>影響的記錄數</returns>
172 public static int ExecuteSqlByTime(string SQLString, int Times) 173 { 174 using (SqlConnection connection = new SqlConnection(conn)) 175 { 176 using (SqlCommand cmd = new SqlCommand(SQLString, connection)) 177 { 178 try
179 { 180 connection.Open(); 181 cmd.CommandTimeout = Times; 182 int rows = cmd.ExecuteNonQuery(); 183 return rows; 184 } 185 catch (System.Data.SqlClient.SqlException e) 186 { 187 connection.Close(); 188 throw e; 189 } 190 } 191 } 192 } 193 /// <summary>
194 /// 執行多條SQL語句,實現數據庫事務。 195 /// </summary>
196 /// <param name="SQLStringList">多條SQL語句</param>
197 public static int ExecuteSqlTran(List<String> SQLStringList) 198 { 199 using (SqlConnection con = new SqlConnection(conn)) 200 { 201 con.Open(); 202 SqlCommand cmd = new SqlCommand(); 203 cmd.Connection = con; 204 SqlTransaction tx = con.BeginTransaction(); 205 cmd.Transaction = tx; 206 try
207 { 208 int count = 0; 209 for (int n = 0; n < SQLStringList.Count; n++) 210 { 211 string strsql = SQLStringList[n]; 212 if (strsql.Trim().Length > 1) 213 { 214 cmd.CommandText = strsql; 215 count += cmd.ExecuteNonQuery(); 216 } 217 } 218 tx.Commit(); 219 return count; 220 } 221 catch
222 { 223 tx.Rollback(); 224 return 0; 225 } 226 } 227 } 228 /// <summary>
229 /// 執行帶一個存儲過程參數的的SQL語句。 230 /// </summary>
231 /// <param name="SQLString">SQL語句</param>
232 /// <param name="content">參數內容,比如一個字段是格式復雜的文章,有特殊符號,可以通過這個方式添加</param>
233 /// <returns>影響的記錄數</returns>
234 public static int ExecuteSql(string SQLString, string content) 235 { 236 using (SqlConnection connection = new SqlConnection(conn)) 237 { 238 SqlCommand cmd = new SqlCommand(SQLString, connection); 239 System.Data.SqlClient.SqlParameter myParameter = new System.Data.SqlClient.SqlParameter("@content", SqlDbType.NText); 240 myParameter.Value = content; 241 cmd.Parameters.Add(myParameter); 242 try
243 { 244 connection.Open(); 245 int rows = cmd.ExecuteNonQuery(); 246 return rows; 247 } 248 catch (System.Data.SqlClient.SqlException e) 249 { 250 throw e; 251 } 252 finally
253 { 254 cmd.Dispose(); 255 connection.Close(); 256 } 257 } 258 } 259 /// <summary>
260 /// 執行帶一個存儲過程參數的的SQL語句。 261 /// </summary>
262 /// <param name="SQLString">SQL語句</param>
263 /// <param name="content">參數內容,比如一個字段是格式復雜的文章,有特殊符號,可以通過這個方式添加</param>
264 /// <returns>影響的記錄數</returns>
265 public static object ExecuteSqlGet(string SQLString, string content) 266 { 267 using (SqlConnection connection = new SqlConnection(conn)) 268 { 269 SqlCommand cmd = new SqlCommand(SQLString, connection); 270 System.Data.SqlClient.SqlParameter myParameter = new System.Data.SqlClient.SqlParameter("@content", SqlDbType.NText); 271 myParameter.Value = content; 272 cmd.Parameters.Add(myParameter); 273 try
274 { 275 connection.Open(); 276 object obj = cmd.ExecuteScalar(); 277 if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))) 278 { 279 return null; 280 } 281 else
282 { 283 return obj; 284 } 285 } 286 catch (System.Data.SqlClient.SqlException e) 287 { 288 throw e; 289 } 290 finally
291 { 292 cmd.Dispose(); 293 connection.Close(); 294 } 295 } 296 } 297 /// <summary>
298 /// 向數據庫里插入圖像格式的字段(和上面情況類似的另一種實例) 299 /// </summary>
300 /// <param name="strSQL">SQL語句</param>
301 /// <param name="fs">圖像字節,數據庫的字段類型為image的情況</param>
302 /// <returns>影響的記錄數</returns>
303 public static int ExecuteSqlInsertImg(string strSQL, byte[] fs) 304 { 305 using (SqlConnection connection = new SqlConnection(conn)) 306 { 307 SqlCommand cmd = new SqlCommand(strSQL, connection); 308 System.Data.SqlClient.SqlParameter myParameter = new System.Data.SqlClient.SqlParameter("@fs", SqlDbType.Image); 309 myParameter.Value = fs; 310 cmd.Parameters.Add(myParameter); 311 try
312 { 313 connection.Open(); 314 int rows = cmd.ExecuteNonQuery(); 315 return rows; 316 } 317 catch (System.Data.SqlClient.SqlException e) 318 { 319 throw e; 320 } 321 finally
322 { 323 cmd.Dispose(); 324 connection.Close(); 325 } 326 } 327 } 328 /// <summary>
329 /// 執行一條計算查詢結果語句,返回查詢結果(object)。 330 /// </summary>
331 /// <param name="SQLString">計算查詢結果語句</param>
332 /// <returns>查詢結果(object)</returns>
333 public static object GetSingle(string SQLString) 334 { 335 using (SqlConnection connection = new SqlConnection(conn)) 336 { 337 using (SqlCommand cmd = new SqlCommand(SQLString, connection)) 338 { 339 try
340 { 341 connection.Open(); 342 object obj = cmd.ExecuteScalar(); 343 if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))) 344 { 345 return null; 346 } 347 else
348 { 349 return obj; 350 } 351 } 352 catch (System.Data.SqlClient.SqlException e) 353 { 354 connection.Close(); 355 throw e; 356 } 357 } 358 } 359 } 360 public static object GetSingle(string SQLString, int Times) 361 { 362 using (SqlConnection connection = new SqlConnection(conn)) 363 { 364 using (SqlCommand cmd = new SqlCommand(SQLString, connection)) 365 { 366 try
367 { 368 connection.Open(); 369 cmd.CommandTimeout = Times; 370 object obj = cmd.ExecuteScalar(); 371 if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))) 372 { 373 return null; 374 } 375 else
376 { 377 return obj; 378 } 379 } 380 catch (System.Data.SqlClient.SqlException e) 381 { 382 connection.Close(); 383 throw e; 384 } 385 finally
386 { 387 cmd.Dispose(); 388 connection.Close(); 389 } 390 } 391 } 392 } 393 /// <summary>
394 /// 執行查詢語句,返回SqlDataReader ( 注意:調用該方法后,一定要對SqlDataReader進行Close ) 395 /// </summary>
396 /// <param name="strSQL">查詢語句</param>
397 /// <returns>SqlDataReader</returns>
398 public static SqlDataReader ExecuteReader(string strSQL) 399 { 400 SqlConnection connection = new SqlConnection(conn); 401 SqlCommand cmd = new SqlCommand(strSQL, connection); 402 try
403 { 404 connection.Open(); 405 SqlDataReader myReader = cmd.ExecuteReader(CommandBehavior.CloseConnection); 406 return myReader; 407 } 408 catch (System.Data.SqlClient.SqlException e) 409 { 410 throw e; 411 } 412
413 } 414 /// <summary>
415 /// 執行查詢語句,返回DataSet 416 /// </summary>
417 /// <param name="SQLString">查詢語句</param>
418 /// <returns>DataSet</returns>
419 public static DataSet Query(string SQLString) 420 { 421 using (SqlConnection connection = new SqlConnection(conn)) 422 { 423 DataSet ds = new DataSet(); 424 try
425 { 426 connection.Open(); 427 SqlDataAdapter command = new SqlDataAdapter(SQLString, connection); 428 command.Fill(ds, "ds"); 429 } 430 catch (System.Data.SqlClient.SqlException ex) 431 { 432 throw new Exception(ex.Message); 433 } 434 return ds; 435 } 436 } 437 public static DataSet Query(string SQLString, int Times) 438 { 439 using (SqlConnection connection = new SqlConnection(conn)) 440 { 441 DataSet ds = new DataSet(); 442 try
443 { 444 connection.Open(); 445 SqlDataAdapter command = new SqlDataAdapter(SQLString, connection); 446 command.SelectCommand.CommandTimeout = Times; 447 command.Fill(ds, "ds"); 448 } 449 catch (System.Data.SqlClient.SqlException ex) 450 { 451 throw new Exception(ex.Message); 452 } 453 finally
454 { 455
456 connection.Close(); 457 } 458 return ds; 459 } 460 } 461 #endregion
462
463 #region 執行帶參數的SQL語句
464 /// <summary>
465 /// 執行SQL語句,返回影響的記錄數 466 /// </summary>
467 /// <param name="SQLString">SQL語句</param>
468 /// <returns>影響的記錄數</returns>
469 public static int ExecuteSql(string SQLString, params SqlParameter[] cmdParms) 470 { 471 using (SqlConnection connection = new SqlConnection(conn)) 472 { 473 using (SqlCommand cmd = new SqlCommand()) 474 { 475 try
476 { 477 PrepareCommand(cmd, connection, null, SQLString, cmdParms); 478 int rows = cmd.ExecuteNonQuery(); 479 cmd.Parameters.Clear(); 480 return rows; 481 } 482 catch (System.Data.SqlClient.SqlException e) 483 { 484 throw e; 485 } 486 finally
487 { 488 cmd.Dispose(); 489 connection.Close(); 490 } 491 } 492 } 493 } 494 /// <summary>
495 /// 執行多條SQL語句,實現數據庫事務。 496 /// </summary>
497 /// <param name="SQLStringList">SQL語句的哈希表(key為sql語句,value是該語句的SqlParameter[])</param>
498 public static void ExecuteSqlTran(Hashtable SQLStringList) 499 { 500 using (SqlConnection con = new SqlConnection(conn)) 501 { 502 con.Open(); 503 using (SqlTransaction trans = con.BeginTransaction()) 504 { 505 SqlCommand cmd = new SqlCommand(); 506 try
507 { 508 //循環
509 foreach (DictionaryEntry myDE in SQLStringList) 510 { 511 string cmdText = myDE.Key.ToString(); 512 SqlParameter[] cmdParms = (SqlParameter[])myDE.Value; 513 PrepareCommand(cmd, con, trans, cmdText, cmdParms); 514 int val = cmd.ExecuteNonQuery(); 515 cmd.Parameters.Clear(); 516 } 517 trans.Commit(); 518 } 519 catch
520 { 521 trans.Rollback(); 522 throw; 523 } 524 } 525 } 526 } 527 /// <summary>
528 /// 執行多條SQL語句,實現數據庫事務。 529 /// </summary>
530 /// <param name="SQLStringList">SQL語句的哈希表(key為sql語句,value是該語句的SqlParameter[])</param>
531 public static int ExecuteSqlTran(System.Collections.Generic.List<CommandInfo> cmdList) 532 { 533 using (SqlConnection con = new SqlConnection(conn)) 534 { 535 con.Open(); 536 using (SqlTransaction trans = con.BeginTransaction()) 537 { 538 SqlCommand cmd = new SqlCommand(); 539 try
540 { 541 int count = 0; 542 //循環
543 foreach (CommandInfo myDE in cmdList) 544 { 545 string cmdText = myDE.CommandText; 546 SqlParameter[] cmdParms = (SqlParameter[])myDE.Parameters; 547 PrepareCommand(cmd, con, trans, cmdText, cmdParms); 548
549 if (myDE.EffentNextType == EffentNextType.WhenHaveContine || myDE.EffentNextType == EffentNextType.WhenNoHaveContine) 550 { 551 if (myDE.CommandText.ToLower().IndexOf("count(") == -1) 552 { 553 trans.Rollback(); 554 return 0; 555 } 556
557 object obj = cmd.ExecuteScalar(); 558 bool isHave = false; 559 if (obj == null && obj == DBNull.Value) 560 { 561 isHave = false; 562 } 563 isHave = Convert.ToInt32(obj) > 0; 564
565 if (myDE.EffentNextType == EffentNextType.WhenHaveContine && !isHave) 566 { 567 trans.Rollback(); 568 return 0; 569 } 570 if (myDE.EffentNextType == EffentNextType.WhenNoHaveContine && isHave) 571 { 572 trans.Rollback(); 573 return 0; 574 } 575 continue; 576 } 577 int val = cmd.ExecuteNonQuery(); 578 count += val; 579 if (myDE.EffentNextType == EffentNextType.ExcuteEffectRows && val == 0) 580 { 581 trans.Rollback(); 582 return 0; 583 } 584 cmd.Parameters.Clear(); 585 } 586 trans.Commit(); 587 return count; 588 } 589 catch
590 { 591 trans.Rollback(); 592 throw; 593 } 594 } 595 } 596 } 597 /// <summary>
598 /// 執行多條SQL語句,實現數據庫事務。 599 /// </summary>
600 /// <param name="SQLStringList">SQL語句的哈希表(key為sql語句,value是該語句的SqlParameter[])</param>
601 public static void ExecuteSqlTranWithIndentity(System.Collections.Generic.List<CommandInfo> SQLStringList) 602 { 603 using (SqlConnection con = new SqlConnection(conn)) 604 { 605 con.Open(); 606 using (SqlTransaction trans = con.BeginTransaction()) 607 { 608 SqlCommand cmd = new SqlCommand(); 609 try
610 { 611 int indentity = 0; 612 //循環
613 foreach (CommandInfo myDE in SQLStringList) 614 { 615 string cmdText = myDE.CommandText; 616 SqlParameter[] cmdParms = (SqlParameter[])myDE.Parameters; 617 foreach (SqlParameter q in cmdParms) 618 { 619 if (q.Direction == ParameterDirection.InputOutput) 620 { 621 q.Value = indentity; 622 } 623 } 624 PrepareCommand(cmd, con, trans, cmdText, cmdParms); 625 int val = cmd.ExecuteNonQuery(); 626 foreach (SqlParameter q in cmdParms) 627 { 628 if (q.Direction == ParameterDirection.Output) 629 { 630 indentity = Convert.ToInt32(q.Value); 631 } 632 } 633 cmd.Parameters.Clear(); 634 } 635 trans.Commit(); 636 } 637 catch
638 { 639 trans.Rollback(); 640 throw; 641 } 642 } 643 } 644 } 645 /// <summary>
646 /// 執行多條SQL語句,實現數據庫事務。 647 /// </summary>
648 /// <param name="SQLStringList">SQL語句的哈希表(key為sql語句,value是該語句的SqlParameter[])</param>
649 public static void ExecuteSqlTranWithIndentity(Hashtable SQLStringList) 650 { 651 using (SqlConnection con = new SqlConnection(conn)) 652 { 653 con.Open(); 654 using (SqlTransaction trans = con.BeginTransaction()) 655 { 656 SqlCommand cmd = new SqlCommand(); 657 try
658 { 659 int indentity = 0; 660 //循環
661 foreach (DictionaryEntry myDE in SQLStringList) 662 { 663 string cmdText = myDE.Key.ToString(); 664 SqlParameter[] cmdParms = (SqlParameter[])myDE.Value; 665 foreach (SqlParameter q in cmdParms) 666 { 667 if (q.Direction == ParameterDirection.InputOutput) 668 { 669 q.Value = indentity; 670 } 671 } 672 PrepareCommand(cmd, con, trans, cmdText, cmdParms); 673 int val = cmd.ExecuteNonQuery(); 674 foreach (SqlParameter q in cmdParms) 675 { 676 if (q.Direction == ParameterDirection.Output) 677 { 678 indentity = Convert.ToInt32(q.Value); 679 } 680 } 681 cmd.Parameters.Clear(); 682 } 683 trans.Commit(); 684 } 685 catch
686 { 687 trans.Rollback(); 688 throw; 689 } 690 finally
691 { 692 cmd.Dispose(); 693 con.Close(); 694 } 695
696 } 697 } 698 } 699 /// <summary>
700 /// 執行一條計算查詢結果語句,返回查詢結果(object)。 701 /// </summary>
702 /// <param name="SQLString">計算查詢結果語句</param>
703 /// <returns>查詢結果(object)</returns>
704 public static object GetSingle(string SQLString, params SqlParameter[] cmdParms) 705 { 706 using (SqlConnection connection = new SqlConnection(conn)) 707 { 708 using (SqlCommand cmd = new SqlCommand()) 709 { 710 try
711 { 712 PrepareCommand(cmd, connection, null, SQLString, cmdParms); 713 object obj = cmd.ExecuteScalar(); 714 cmd.Parameters.Clear(); 715 if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))) 716 { 717 return null; 718 } 719 else
720 { 721 return obj; 722 } 723 } 724 catch (System.Data.SqlClient.SqlException e) 725 { 726 throw e; 727 } 728 finally
729 { 730 cmd.Dispose(); 731 connection.Close(); 732 } 733 } 734 } 735 } 736 /// <summary>
737 /// 執行查詢語句,返回SqlDataReader ( 注意:調用該方法后,一定要對SqlDataReader進行Close ) 738 /// </summary>
739 /// <param name="strSQL">查詢語句</param>
740 /// <returns>SqlDataReader</returns>
741 public static SqlDataReader ExecuteReader(string SQLString, params SqlParameter[] cmdParms) 742 { 743 SqlConnection connection = new SqlConnection(conn); 744 SqlCommand cmd = new SqlCommand(); 745 try
746 { 747 PrepareCommand(cmd, connection, null, SQLString, cmdParms); 748 SqlDataReader myReader = cmd.ExecuteReader(CommandBehavior.CloseConnection); 749 cmd.Parameters.Clear(); 750 return myReader; 751 } 752 catch (System.Data.SqlClient.SqlException e) 753 { 754 throw e; 755 } 756 finally
757 { 758 cmd.Dispose(); 759 connection.Close(); 760 } 761
762 } 763 /// <summary>
764 /// 執行查詢語句,返回DataSet 765 /// </summary>
766 /// <param name="SQLString">查詢語句</param>
767 /// <returns>DataSet</returns>
768 public static DataSet Query(string SQLString, params SqlParameter[] cmdParms) 769 { 770 using (SqlConnection connection = new SqlConnection(conn)) 771 { 772 SqlCommand cmd = new SqlCommand(); 773 PrepareCommand(cmd, connection, null, SQLString, cmdParms); 774 using (SqlDataAdapter da = new SqlDataAdapter(cmd)) 775 { 776 DataSet ds = new DataSet(); 777 try
778 { 779 da.Fill(ds, "ds"); 780 cmd.Parameters.Clear(); 781 } 782 catch (System.Data.SqlClient.SqlException ex) 783 { 784 throw new Exception(ex.Message); 785 } 786 finally
787 { 788 cmd.Dispose(); 789 connection.Close(); 790 } 791 return ds; 792 } 793 } 794 } 795 /// <summary>
796 /// 填充參數 797 /// </summary>
798 /// <param name="cmd">cmd命令</param>
799 /// <param name="conn">連接字符串</param>
800 /// <param name="trans">T_SQL事務</param>
801 /// <param name="cmdText">命令內容</param>
802 /// <param name="cmdParms">參數數組</param>
803 private static void PrepareCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction trans, string cmdText, SqlParameter[] cmdParms) 804 { 805 if (conn.State != ConnectionState.Open) 806 conn.Open(); 807 cmd.Connection = conn; 808 cmd.CommandText = cmdText; 809 if (trans != null) 810 cmd.Transaction = trans; 811 cmd.CommandType = CommandType.Text;//cmdType;
812 if (cmdParms != null) 813 { 814
815
816 foreach (SqlParameter parameter in cmdParms) 817 { 818 if ((parameter.Direction == ParameterDirection.InputOutput || parameter.Direction == ParameterDirection.Input) &&
819 (parameter.Value == null)) 820 { 821 parameter.Value = DBNull.Value; 822 } 823 cmd.Parameters.Add(parameter); 824 } 825 } 826 } 827 #endregion
828
829 #region 存儲過程操作
830 /// <summary>
831 /// 執行存儲過程,返回SqlDataReader ( 注意:調用該方法后,一定要對SqlDataReader進行Close ) 832 /// </summary>
833 /// <param name="storedProcName">存儲過程名</param>
834 /// <param name="parameters">存儲過程參數</param>
835 /// <returns>SqlDataReader</returns>
836 public static SqlDataReader RunProcedure(string storedProcName, IDataParameter[] parameters) 837 { 838 SqlConnection connection = new SqlConnection(conn); 839 SqlDataReader returnReader; 840 connection.Open(); 841 SqlCommand command = BuildQueryCommand(connection, storedProcName, parameters); 842 command.CommandType = CommandType.StoredProcedure; 843 returnReader = command.ExecuteReader(CommandBehavior.CloseConnection); 844 return returnReader; 845 } 846 /// <summary>
847 /// 執行存儲過程 848 /// </summary>
849 /// <param name="storedProcName">存儲過程名</param>
850 /// <param name="parameters">存儲過程參數</param>
851 /// <param name="tableName">DataSet結果中的表名</param>
852 /// <returns>DataSet</returns>
853 public static DataSet RunProcedure(string storedProcName, IDataParameter[] parameters, string tableName) 854 { 855 using (SqlConnection connection = new SqlConnection(conn)) 856 { 857 DataSet dataSet = new DataSet(); 858 connection.Open(); 859 SqlDataAdapter sqlDA = new SqlDataAdapter(); 860 sqlDA.SelectCommand = BuildQueryCommand(connection, storedProcName, parameters); 861 sqlDA.Fill(dataSet, tableName); 862 connection.Close(); 863 return dataSet; 864 } 865 } 866 public static DataSet RunProcedure(string storedProcName, IDataParameter[] parameters, string tableName, int Times) 867 { 868 using (SqlConnection connection = new SqlConnection(conn)) 869 { 870 DataSet dataSet = new DataSet(); 871 connection.Open(); 872 SqlDataAdapter sqlDA = new SqlDataAdapter(); 873 sqlDA.SelectCommand = BuildQueryCommand(connection, storedProcName, parameters); 874 sqlDA.SelectCommand.CommandTimeout = Times; 875 sqlDA.Fill(dataSet, tableName); 876 connection.Close(); 877 return dataSet; 878 } 879 } 880 /// <summary>
881 /// 構建 SqlCommand 對象(用來返回一個結果集,而不是一個整數值) 882 /// </summary>
883 /// <param name="connection">數據庫連接</param>
884 /// <param name="storedProcName">存儲過程名</param>
885 /// <param name="parameters">存儲過程參數</param>
886 /// <returns>SqlCommand</returns>
887 private static SqlCommand BuildQueryCommand(SqlConnection connection, string storedProcName, IDataParameter[] parameters) 888 { 889 SqlCommand command = new SqlCommand(storedProcName, connection); 890 command.CommandType = CommandType.StoredProcedure; 891 foreach (SqlParameter parameter in parameters) 892 { 893 if (parameter != null) 894 { 895 // 檢查未分配值的輸出參數,將其分配以DBNull.Value.
896 if ((parameter.Direction == ParameterDirection.InputOutput || parameter.Direction == ParameterDirection.Input) &&
897 (parameter.Value == null)) 898 { 899 parameter.Value = DBNull.Value; 900 } 901 command.Parameters.Add(parameter); 902 } 903 } 904
905 return command; 906 } 907 /// <summary>
908 /// 執行存儲過程,返回影響的行數 909 /// </summary>
910 /// <param name="storedProcName">存儲過程名</param>
911 /// <param name="parameters">存儲過程參數</param>
912 /// <param name="rowsAffected">影響的行數</param>
913 /// <returns></returns>
914 public static int RunProcedure(string storedProcName, IDataParameter[] parameters, out int rowsAffected) 915 { 916 using (SqlConnection connection = new SqlConnection(conn)) 917 { 918 int result; 919 connection.Open(); 920 SqlCommand command = BuildIntCommand(connection, storedProcName, parameters); 921 rowsAffected = command.ExecuteNonQuery(); 922 result = (int)command.Parameters["ReturnValue"].Value; 923 connection.Close(); 924 return result; 925 } 926 } 927 /// <summary>
928 /// 執行存儲過程,返回存儲過程返回值 929 /// </summary>
930 /// <param name="storedProcName">存儲過程名</param>
931 /// <param name="parameters">存儲過程參數</param>
932 /// <param name="rowsAffected">影響的行數</param>
933 /// <returns></returns>
934 public static string RunProcedureOut(string storedProcName, IDataParameter[] parameters) 935 { 936 string rowsAffected; 937 using (SqlConnection connection = new SqlConnection(conn)) 938 { 939 connection.Open(); 940 SqlCommand command = BuildIntCommand(connection, storedProcName, parameters); 941 command.ExecuteNonQuery(); 942 rowsAffected = command.Parameters["ReturnValue"].Value.ToString(); 943 //MessageBox.Show(rowsAffected + "\n" + parameters[0].Value.ToString() + "\n" 944 // + parameters[1].Value.ToString() + "\n" + parameters[2].Value.ToString());//測試
945 connection.Close(); 946 return rowsAffected; 947 } 948 } 949 /// <summary>
950 /// 創建 SqlCommand 對象實例(用來返回一個整數值) 951 /// </summary>
952 /// <param name="storedProcName">存儲過程名</param>
953 /// <param name="parameters">存儲過程參數</param>
954 /// <returns>SqlCommand 對象實例</returns>
955 private static SqlCommand BuildIntCommand(SqlConnection connection, string storedProcName, IDataParameter[] parameters) 956 { 957 SqlCommand command = BuildQueryCommand(connection, storedProcName, parameters); 958 command.Parameters.Add(new SqlParameter("ReturnValue", 959 SqlDbType.Int, 4, ParameterDirection.ReturnValue, 960 false, 0, 0, string.Empty, DataRowVersion.Default, null)); 961 return command; 962 } 963 /// <summary>
964 /// 事務處理 965 /// </summary>
966 /// <param name="SQLStringList">SQL命令(數組)</param>
967 public void ExecuteSqlTran(ArrayList SQLStringList) 968 { 969 using (SqlConnection connection = new SqlConnection(conn)) 970 { 971 connection.Open(); 972 DbTransaction dbtran = connection.BeginTransaction(); 973 try
974 { 975 for (int n = 0; n < SQLStringList.Count; n++) 976 { 977 string strsql = SQLStringList[n].ToString(); 978 if (strsql.Trim().Length > 1) 979 { 980 DbCommand dbCommand = connection.CreateCommand(); 981 dbCommand.CommandText = strsql; 982 dbCommand.Transaction = dbtran; 983 int val = dbCommand.ExecuteNonQuery(); 984 } 985 } 986 dbtran.Commit(); 987 } 988 catch (Exception ex) 989 { 990 dbtran.Rollback(); 991 throw ex; 992 } 993 finally
994 { 995 connection.Close(); 996 } 997 } 998 } 999 #endregion
1000 } 1001 }
EXEel導出功能:(untCommon.cs)

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Windows.Forms; 6
7 namespace BLL 8 { 9 public class untCommon 10 { 11 /// <summary>
12 /// 消息對話框 13 /// </summary>
14 /// <param name="txt">文本</param>
15 /// <param name="title">標題</param>
16 public void InfoMsg(string txt) 17 { 18
19 MessageBox.Show(txt, "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Information); 20 } 21 /// <summary>
22 /// 錯誤對話框 23 /// </summary>
24 /// <param name="txt">文本</param>
25 /// <param name="title">標題</param>
26 public void ErrorMsg(string txt) 27 { 28
29 MessageBox.Show(txt," 錯誤提示", MessageBoxButtons.OK, MessageBoxIcon.Error); 30
31 } 32 /// <summary>
33 /// 問題對話框 34 /// </summary>
35 /// <param name="txt">文本</param>
36 /// <param name="title">標題</param>
37 public bool QuestionMsg(string txt) 38 { 39
40 if (MessageBox.Show(txt, "確認請求", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) 41 { 42 return true; 43 } 44 else
45 { 46 return false; 47 } 48
49 } 50 /// <summary>
51 /// 將datagridview中的數據導出到excel中 52 /// </summary>
53 /// <param name="view">datagridview</param>
54 public void ToExel(DataGridView view) 55 { 56 untCommon ut = new untCommon(); 57 if (view.Rows.Count == 0) 58 { 59 ut.InfoMsg("表格中沒有數據,不能導出空表"); 60 return; 61 } 62
63 //建立Excel對象
64 Excel.Application excel = new Excel.Application(); 65 excel.Application.Workbooks.Add(true); 66 excel.Visible = true; 67 //生成字段名稱
68 for (int i = 0; i < view.ColumnCount; i++) 69 { 70
71 excel.Cells[1, i + 1] = view.Columns[i].HeaderText; 72 } 73 //填充數據
74 for (int row = 0; row <= view.RowCount - 1; row++) 75 { 76 for (int column = 0; column < view.ColumnCount; column++) 77 { 78
79 if (view[column, row].ValueType == typeof(string)) 80 { 81 excel.Cells[row + 2, column + 1] = "'" + view[column, row].Value.ToString(); 82 } 83 else
84 { 85 excel.Cells[row + 2, column + 1] = view[column, row].Value.ToString(); 86 } 87 } 88 } 89 } 90 } 91 }
treeNode相關用法(這是本次寫代碼的一次重要收獲):

1 private void getBm(TreeNode treenode) 2 { 3 treenode.Text = "組織機構 "; 4 treenode.NodeFont = new Font("楷體", 14, FontStyle.Underline | FontStyle.Bold); 5 DataSet ds = new DataSet(); 6 jc_bmdoc bm = new jc_bmdoc(); 7 ds = bm.getList(" and beactive='是'"); 8 DataTable dt=ds.Tables[0]; 9 for (int i = 0; i < dt.Rows.Count; i++) 10 { 11 treenode.Nodes.Add(dt.Rows[i][2].ToString().Trim()); 12 } 13 } 14 private void hr_Bmzhygw_Load(object sender, EventArgs e) 15 { 16 this.tvBM.LabelEdit = true; 17 TreeNode node = new TreeNode(); 18 getBm(node); 19 tvBM.Nodes.Add(node); 20 tvBM.ExpandAll(); 21 } 22
23 private void tvBM_AfterSelect(object sender, TreeViewEventArgs e) 24 { 25 jc_bmzhygx bmzg = new jc_bmzhygx(); 26 DataSet ds = new DataSet(); 27 dvZhiydoc.DataSource = null; 28 ds = bmzg.getList(e.Node.Text.ToString().Trim(),1); 29 //MessageBox.Show(e.Node.Text);//獲取選擇中節點的內容
30 dvZhiydoc.DataSource = ds.Tables[0]; 31 }
獲得漢字的助記碼:(SQL標量值函數)

1 USE [ExpensionDB]
2 GO
3 /****** Object: UserDefinedFunction [dbo].[fun_getZjm] Script Date: 04/20/2014 22:28:02 ******/
4 SET ANSI_NULLS ON
5 GO
6 SET QUOTED_IDENTIFIER ON
7 GO
8
9 ------------------------------------------------
10 --作者:zhangbc
11 --時間:2014-03-19
12 --功能:獲取漢字拼音首字母
13 ------------------------------------------------
14 ALTER function [dbo].[fun_getZjm](@str nvarchar(4000)) 15 returns nvarchar(4000) 16 as
17 begin
18 declare @word nchar(1),@PY nvarchar(4000) 19 set @PY=''
20 while len(@str)>0
21 begin
22 set @word=left(@str,1) 23 --如果非漢字字符,返回原字符
24 set @PY=@PY+(case when unicode(@word) between 19968 and 19968+20901
25 then (select top 1 PY from ( 26 select 'A' as PY,N'驁' as word 27 union all select 'B',N'簿'
28 union all select 'C',N'錯'
29 union all select 'D',N'鵽'
30 union all select 'E',N'樲'
31 union all select 'F',N'鰒'
32 union all select 'G',N'腂'
33 union all select 'H',N'夻'
34 union all select 'J',N'攈'
35 union all select 'K',N'穒'
36 union all select 'L',N'鱳'
37 union all select 'M',N'旀'
38 union all select 'N',N'桛'
39 union all select 'O',N'漚'
40 union all select 'P',N'曝'
41 union all select 'Q',N'囕'
42 union all select 'R',N'鶸'
43 union all select 'S',N'蜶'
44 union all select 'T',N'籜'
45 union all select 'W',N'鶩'
46 union all select 'X',N'鑂'
47 union all select 'Y',N'韻'
48 union all select 'Z',N'咗'
49 ) T 50 where word>=@word collate Chinese_PRC_CS_AS_KS_WS 51 order by PY ASC) else @word end) 52 set @str=right(@str,len(@str)-1) 53 end
54 return @PY
55 end
單據錄入功能(事務處理,這是本次寫代碼的又一次重要收獲):

1 private void djSave_Click(object sender, EventArgs e) 2 { 3 using (System.Transactions.TransactionScope TranSop 4 = new System.Transactions.TransactionScope())//開始事務
5 { 6 try
7 { 8 getDjhz(); 9 try
10 { 11 for (int i = 0; i < dvRcfy.Rows.Count - 1; i++) 12 { 13 #region
14 djmx.djbh = djhz.djbh; 15 djmx.dj_sort = dvRcfy.Rows[i].Cells["dj_sort"].Value.ToString(); 16 djmx.fylx = ""; 17 djmx.is_zx = "否"; 18 try
19 { 20 djmx.fybh = dvRcfy.Rows[i].Cells["fybh"].Value.ToString(); 21 } 22 catch
23 { 24 ut.InfoMsg("費用編號不能為空!"); 25 return; 26 } 27 try
28 { 29 djmx.fymch = dvRcfy.Rows[i].Cells["fymch"].Value.ToString(); 30 } 31 catch
32 { 33 ut.InfoMsg(dvRcfy.Rows[i].Cells["fymch"].Value.ToString() + "費用名稱不能為空!"); 34 return; 35 } 36 try
37 { 38 djmx.shpgg = dvRcfy.Rows[i].Cells["shpgg"].Value.ToString(); 39 } 40 catch
41 { 42 ut.InfoMsg("規格不能為空!"); 43 return; 44 } 45 try
46 { 47 djmx.zrbm = dvRcfy.Rows[i].Cells["zrbm"].Value.ToString(); 48 } 49 catch
50 { 51 ut.InfoMsg("費用承擔部門不能為空!"); 52 return; 53 } 54 if ((decimal)dvRcfy.Rows[i].Cells["dj"].Value == 0) 55 { 56 ut.InfoMsg("單價不能為0!"); 57 return; 58 } 59 else
60 { 61 djmx.dj = (decimal)dvRcfy.Rows[i].Cells["dj"].Value; 62 } 63 if ((decimal)dvRcfy.Rows[i].Cells["shl"].Value == 0) 64 { 65 ut.InfoMsg("數量不能為0!"); 66 return; 67 } 68 else
69 { 70 djmx.shl = (decimal)dvRcfy.Rows[i].Cells["shl"].Value; 71 } 72 djmx.je = (decimal)dvRcfy.Rows[i].Cells["je"].Value; 73 try
74 { 75 djmx.pinp = dvRcfy.Rows[i].Cells["pinp"].Value.ToString(); 76 } 77 catch
78 { 79 djmx.pinp = ""; 80 } 81 djmx.chph = ""; 82 djmx.chex = ""; 83 djmx.yongt = ""; 84 djmx.days = 0; 85 djmx.distance = 0; 86 djmx.chlr = ""; 87 djmx.gangw = ""; 88 try
89 { 90 djmx.beizhu = dvRcfy.Rows[i].Cells["beizhu"].Value.ToString(); 91 } 92 catch
93 { 94 djmx.beizhu = ""; 95 } 96 #endregion
97 dj_mx.Insert(djmx); 98 } 99 if(djhz.app_bm==""||djhz.shenqr==""||djhz.lyr=="") 100 { 101 ut.InfoMsg("抬頭不能有空項!"); 102 return; 103 } 104 if (dvRcfy.Rows.Count <= 1 || dj_hz.Insert(djhz) == 0) 105 { 106 ut.InfoMsg("保存失敗!"); 107 return; 108 } 109 dj_hz.Insert(djhz); 110 ut.InfoMsg("保存成功!"); 111 } 112 catch (Exception ex) 113 { 114 ut.ErrorMsg("新增失敗,請檢查!" + ex.ToString()); 115 } 116 TranSop.Complete(); 117 } 118 catch (Exception ex) 119 { 120 MessageBox.Show("錯誤原因:\n"+ex.ToString()); 121 TranSop.Dispose(); 122 } 123 } 124 clear(); 125 }
四)項目成果演示
1)系統登錄界面:
圖 4-1 登陸Flash界面
圖 4-2 登陸界面
系統主界面相關:
圖 4-2 人員部門維護
圖 4-4 單據錄入界面
圖 4-5 單據審核
圖 4-6 費用查詢
五)項目補充說明
本小系統基本達到預定目標,新手上路,歷時將近一個月,收獲頗多,后期將有許多需求都很在此基礎擴展,但仍有很多有待改進之處,歡迎大師指正,不甚感激!完整demo及其代碼不便分享,敬請諒解!