柳孔明,趙波,張一平
(中國人民解放軍95806部隊,北京100076)
“全軍各級要強化練兵備戰(zhàn)鮮明導向,堅定不移把軍事訓練擺在戰(zhàn)略位置、作為中心工作,抓住不放,抓出成效?!毙履暌潦迹醒胲娢e行2018年開訓動員大會,習主席向全軍發(fā)布了訓令,全軍各級掀起了體能訓練的熱潮。由于體能訓練考核科目涉及較多,且考核成績按照人員類別、性別、年齡段有不同的考核科目,且給出了不同的成績計算標準,這就給工作人員根據成績計算出各科目的得分,并最終給出綜合評價結果帶來較大的困難。如果采取人工方式通過Excel表進行匯集統(tǒng)計計算,再依照模板填寫到Word文檔中去,會花費大量人力物力,并且效率低下,增加了出錯的概率,會影響領導對考核成績的信息的及時把握、分析和判斷。
對軍人體能訓練考核中人工計算成績中存在的現實問題,通過設計和開發(fā)專門的信息系統(tǒng)可以輕松解決。本文基于通過自動匹配成績區(qū)間來計算考核分數的基本思路,采用DevExpress界面開發(fā)控件庫,利用C#語言開發(fā)了軍人體能考核成績計算系統(tǒng),并進行了大量的測試,在實際應用中極大提高了計算效率和正確率。本文將對系統(tǒng)軟件的設計與開發(fā)的關鍵技術進行簡要闡述。
軍人體能考核成績計算系統(tǒng)旨在利用計算機技術實現軍人體能訓練考核成績計算信息化、標準化,減輕重復繁重的工作負擔,同時達到體能標準查詢、按照成績計算得分及評價、按照模板進行結果輸出等簡單易操作性。進行系統(tǒng)設計時,考慮到成績數據中有些符號如分鐘(′)、秒(″)在錄入過程中可能由于中英文字符難以區(qū)分等因素造成輸入不規(guī)范,程序中采取最大兼容方式規(guī)避了可能出現的問題。系統(tǒng)主要實現了考核成績的導入、得分與評價計算、數據按照模板的導出等主要功能。
系統(tǒng)建立了體型標準表(T_TX)、體脂標準表(T_TZ)、引體向上標準表(T_YTXS)、仰臥起坐標準表(T_YWQZ)、曲臂懸垂標準表(T_QBXC)、俯臥撐標準表(T_FWC)、蛇形跑標準表(T_SX2)、3000 米跑標準表(T_3000)、成績統(tǒng)計表(T_SCORE)等。系統(tǒng)中涉及的數據表較多,由于篇幅限制,這里只給出體型標準表(T_TX)簡約數據表結構(主要字段信息),如表1所示。
表1 體型標準表(T_TX)簡約數據表結構
軍人體能考核成績計算系統(tǒng)是典型的信息系統(tǒng),系統(tǒng)采用C/S架構,以C#作為系統(tǒng)的程序設計語言,以Visual Studio 2013為系統(tǒng)集成開發(fā)平臺,系統(tǒng)數據庫采用Microsoft Office Access。Microsoft公司的Access是一個桌面關系型數據庫管理系統(tǒng),能夠制作窗體和報表,并且能夠與Excel進行數據交換。Access適合開發(fā)小型數據庫應用系統(tǒng)。該系統(tǒng)采用Access 2000進行開發(fā)。
系統(tǒng)的設計采取軟件工程中“自下而上”的方法,實現各個業(yè)務功能。系統(tǒng)開發(fā)主要包括后臺數據庫的建立和維護以及前端應用程序的開發(fā)兩個方面,對于前者要求建立起數據一致性和完整性強、數據安全性好的庫。而對于后者則要求應用程序功能完備,易使用等特點。
(1)Excel數據的導入
因為使用Excel來操作數據很方便,在數據登記時采用Excel登記數據可以給用戶帶來很多方便,因此為了便于數據流轉需要,我們需要提供一個入口給用戶導入所需要的數據。
C#操作Excel的傳統(tǒng)方式主要有以下幾種方式:①采用OleDB讀取Excel文件,把Excel文件當做一個數據源來進行數據的讀取操作;②通過引用COM組件Microsoft.Office.Interop.Excel.dll讀?。虎蹖xcel文件轉化成CSV文件,利用文件流的方式讀取。但是上述方法都較為過時,并且或者操作比較繁瑣,或者對組件版本依賴性較強,客戶機通用性差。這里采用NPOI動態(tài)庫進行開發(fā),NPOI是開源的POI項目.NET版,可以用來讀寫Excel等Office文檔,在處理Excel文件方面,NPOI可以同時兼容*.xls和*.xlsx格式,具有開源免費、不依賴Office組件、簡單方面、性能穩(wěn)定等優(yōu)點。程序中的關鍵代碼如下:private void ReadExcelData()
{
FileStream fs=null;
NPOI.SS.UserModel.IWorkbook workbook=null;
ISheet sheet=null;
var filePath=openFileDialog.FileName;
ExcelPath=filePath;
try
{
//讀取文件的sheet頁
using(fs=File.OpenRead(filePath))
{
if(filePath.IndexOf(".xlsx")>0)//Excel 2007版本
workbook=new XSSFWorkbook(fs);
else if(filePath.IndexOf(".xls")>0)//Excel 2003版本
workbook=new HSSFWorkbook(fs);
((DevExpress.XtraEditors.Repository.RepositoryItemComboBox)
this.barEditItem1.Edit).Items.Clear();
if(workbook!=null)
{
object dafaultSheet="";
for(int i=0;i { sheet=workbook.GetSheetAt(i);//循環(huán)讀取每個 sheet頁面 ((DevExpress.XtraEditors.Repository.RepositoryItemComboBox)this.barEditItem1.Edit).Items.Add(sheet.SheetName);//加載各個sheet表的名稱到下拉框中供選擇 if(i==0) dafaultSheet=sheet.SheetName; } if(workbook.NumberOfSheets==1)//如果只有一個sheet頁,則默認加載數據 this.barEditItem1.EditValue=dafaultSheet; else//如果有多個頁面,則提示用戶從下拉框中選擇需要加載的數據源 MessageBox.Show("請在下拉框中選擇需要計算的Sheet表單,并提交計算!"); } } } } (2)LINQ to SQL技術實現根據考核成績計算分數 使用LINQ to SQL技術,主要由以下幾個優(yōu)點:一是把查詢語法直接融入C#語言,關鍵詞高亮顯示,支持類型檢查,允許使用debugger調試,便于程序開發(fā);二是把之前復雜的查詢工作封裝起來,語法更加清晰易懂,可讀性較高;三是通過LINQ查詢內存數據,避免了多次與數據庫的連接延遲,極大提升了程序的執(zhí)行效率。 需要特別指出的是,在計算過程中針對考核成績大于100分的分數按照各考核項目的給出的處理方法做了處理;針對考核成績下限,按照不同類別的人員進行了成績歸零處理。以仰臥起坐分數計算為例,程序中的關鍵代碼如下: private void CalculateScore() { ...(省略部分代碼) //// 2.2 計算仰臥起坐分數 var result2=from b in dt_YWQZ.AsEnumerable() where b.Field where b.Field //where a.Field select b; double max_YWQZ=0;string score_YWQZ="0"; foreach(var item in result2) { if(p.YWQZ continue; else if (max_YWQZ < Convert.ToDouble(item["V_NUM"])) { max_YWQZ=Convert.ToDouble(item["V_NUM"]); score_YWQZ=item["SCORE"].ToString(); } //MessageBox.Show(item["ID"].ToString()+"******"+item["V_NUM"].ToString());// } this.gridView1.SetRowCellValue(i,"仰臥起坐分數",score_YWQZ); //如果超出100分 if(score_YWQZ=="100") { this.gridView1.SetRowCellValue(i,"仰臥起坐分數",(100+Math.Floor((p.YWQZ-max_YWQZ)/2)).ToString()); } else if(Convert.ToDouble(score_YWQZ)<65)//按照人員類別計算不及格人員分數 { if(p.RYLB=="一類") this.gridView1.SetRowCellValue(i,"仰臥起坐分數","0"); else if(p.RYLB=="二類"&&Convert.ToDouble(score_YWQZ)<60) this.gridView1.SetRowCellValue(i,"仰臥起坐分數","0"); else if(p.RYLB=="三類"&&Convert.ToDouble(score_YWQZ)<55) this.gridView1.SetRowCellValue(i,"仰臥起坐分數","0"); } ...(省略部分代碼) } (3)考核分數表的輸出 通過Aspose.Words類庫,利用Word模板實現靜態(tài)的創(chuàng)建和填充Word文檔(即:通過Bookmark書簽填充文檔內容),可以不依賴Word組件的安裝,方便地實現數據按照既定模板的導出功能。這需要事先制作好成績輸出的Word模板,并在模板中添加相應的書簽標記。這里按照模板要求,做了各個表格位置的標簽,有xh1-xh10(對應各行的序號),…,zp1-zp10(對應各行的總評)。特別需要指出的是,由于需要計算的人數不同,而在標準輸出模板中每頁最多可以輸出10人成績,這里采用了按照10人一組(最后不滿10人的為一組)輸出成為一個單獨文檔,再將各個文檔合并成一個文檔的方法實現。同時,為了輸出數據的標準化,系統(tǒng)設置了數據的輸出標準統(tǒng)一格式,增添了數據可讀性。程序中的關鍵代碼如下: private static void CreateDocumentByBookmark(string template?Path,string targetPath) { string templatePath=Application.StartupPath+@"模板.docx";//模板文件 string savePath=null;//最終生成的文件(如果是多個文件的話 需要合成) SaveFileDialog saveFileDialog1=new SaveFileDialog(); saveFileDialog1.Filter="Word文檔(*.docx)|*.docx"; saveFileDialog1.RestoreDirectory=true; if(saveFileDialog1.ShowDialog()==DialogResult.OK)//選擇輸出的文件名稱和路徑 { savePath=saveFileDialog1.FileName;//輸出的文件名 //創(chuàng)建word文檔 if(File.Exists(templatePath)) { int docCount=(int)Math.Ceiling(this.gridView1.Row?Count/10.0);//計算需要拆分的word數量 for(int j=0;j { //加載word模板文件 Aspose.Words.Document doc=new Aspose.Words.Document(templatePath); Aspose.Words.DocumentBuilder builder=new As?pose.Words.DocumentBuilder(doc); if(j { for(int i=0;i<10;i++) //按照每行的書簽逐個表格添加數據 { //1序號 string bookmarkName="xh"+(i+1).ToString();//計算出需要填寫的書簽名 builder.MoveToBookmark(bookmarkName);//通過移動光標到指定的書簽名,寫入內容 builder.Write((j*10+i+1).ToString());//將相應的內容填寫到指定的標簽位置 //2姓名 …此處省略相似代碼 } } else { //將數據逐行加入到文檔中 寫標簽 for(int i=0;i { //按照每行的書簽逐個表格添加數據 //1序號 string bookmarkName="xh"+(i+1).ToString(); builder.MoveToBookmark(bookmarkName);builder.Write((j*10+i+1).ToString()); //2姓名 ……此處省略相似代碼 } } //添加表頭單位信息 string headmarkName="dm"; builder.MoveToBookmark(headmarkName); builder.Write((this.barEditItem2.EditValue.ToString())); doc.Save(Application.StartupPath+"\temp\"+j.ToString()+".docx",Aspose.Words.SaveFormat.Docx);//文檔的保存,每10行保存為1個單獨word文檔 } //進行多個文檔的合成最終輸出文檔 Aspose.Words.Document docx=new Aspose.Words.Document(); docx.RemoveAllChildren(); for(int i=0;i { string fp=Application.StartupPath+"\temp\"+i.ToString()+".docx"; FileStream fs=new FileStream(fp,FileMode.Open); Aspose.Words.Document doc=new Aspose.Words.Document(fs); docx.AppendDocument(doc,Aspose.Words.Import?FormatMode.UseDestinationStyles); fs.Dispose();fs.Close(); } docx.Save(savePath, Aspose.Words.SaveFormat.Docx);//保存合成結果 } } } 系統(tǒng)運行的界面效果如圖1所示,其中黃色背景的列為要導入(或輸入)的數據列,屬公共考核科目或個人信息內容;紅色背景列為男軍人專有考核項目;綠色背景列為女軍人專有考核項目;無背景列為系統(tǒng)計算并自動填充的考核分數列;藍色背景列為最終得分統(tǒng)計及總評結果列。結果顯示非常直觀。 圖1 成績計算功能主界面 圖2為系統(tǒng)計算結果按照預定模板輸出的登記表。 圖3為體型標準數據查看界面,界面采用了Dev?Express控件,可以方便的實現數據的按列分組,按關鍵字進行查詢篩選等功能。 本文針對軍人體能考核成績計算過程中存在的實際困難,詳細分析系統(tǒng)所需關鍵技術,利用計算機技術和數據庫技術,設計并實現了軍人體能考核成績計算系統(tǒng),并對系統(tǒng)進行了詳細測試。系統(tǒng)目前已經順利運行,切實滿足了單位的實際需要,提高了考核成績的及計算輸出效率和正確率,極大降低了人工作業(yè)難度,可以在廣大軍警院校及部隊推廣使用。 圖2 計算結果輸出表3 系統(tǒng)運行效果
4 結語