楊 柯,孔繁虹
(同濟大學電氣工程系,上海 201804)
城市軌道交通管理系統,又稱列車自動監控系統(ATS),它主要實現對列車運行的監督和控制,輔助行車調度人員對全線列車進行管理,對提高運輸效率和保障行車安全起到極其重要的作用。它分為幾大部分:車站設備信號控制,時刻表管理,車次號追蹤,進路控制,列車運行圖和列車運行調整(ATR)。其中列車時刻表是ATS系統中運營管理的基礎,列車的車次號追蹤需要從時刻表中查找車次;列車運行圖的編制需要時刻表為基礎;列車在運行過程中,依據時刻表來控制速度;在列車偏離時刻表運行的情況下,調度員還需要通過修正時刻表,來實現對列車的自動調整運行。所以本文主要介紹列車時刻表與數據庫的通信技術。由于調度中心要與列車實時通信,并能及時地對列車收發指令,故對數據庫接口要求提出了很高的要求。本文介紹MFC中的ADO技術,可迅速地操作數據庫,并不需要安裝驅動,簡單方便,適合于大型調度服務器端的數據庫中。
ATS的時刻表通常安裝在控制中心的計算機上,由時刻表編輯員根據客流量和線路的狀況來提供多套不同情況下使用的運行圖,并存在ATS數據庫中。該軟件的主要功能描述如下:
(1)用戶界面:可以看到列車車次號,時刻表,車站等信息。并能實時反映出當前列車的運行情況。
(2)數據庫:ATS監控系統需要處理大量的數據,比如時刻表就分為計劃時刻表和在線時刻表等,所以就要采取實時穩定可靠并能處理較大數據量的數據庫,本文用SQL Server 2005作為數據存儲工具,采用ADO技術,通過該接口用軟件實現對數據庫訪問,可有效管理系統中數據。
軟件應該滿足以下幾個目標:
(1)列車調度員應該通過輸入用戶名和密碼登錄ATS調度系統。
(2)對車站的管理,可以增加,刪除該線路上的車站信息。
(3)對列車的管理,實現加車,減車,修改列車時刻表等信息。
上面幾個目標實現后,就可以根據數據庫已有的時刻表來編制列車的計劃運行圖。
開放數據庫互連(ODBC)是Microsoft引進的一種早期數據庫接口技術,它用包含在DLL內的驅動程序完成任務。它提供了一組對數據庫訪問的標準API(應用程序編程接口),這些API利用SQL來完成其大部分任務。但其訪問速度慢,并且需要安裝驅動,且只能用于關系數據庫,不適用于對象數據庫。
DAO(數據訪問對象)是微軟第一個面向對象的數據庫接口,它封裝了Access的Jet函數,因此對Access的執行效率比較高,但對SQL等非MDB數據庫得執行效率較低,因此不適用于列車監控系統。
OLE DB是微軟的戰略性的通向不同的數據源的低級應用程序接口。OLE DB不僅包括微軟資助的標準數據接口開放數據庫連通性(ODBC)的結構化問題語言(SQL)能力,還具有面向其他非SQL數據類型的通路。它的對象包括數據源對象、階段對象、命令對象和行組對象。但它使用時需加入很多代碼,使用起來比較復雜。
微軟的ADO(ActiveX Data Objects)是一個用于存取數據源的COM組件。它提供了編程語言和統一數據訪問方式OLE DB的一個中間層。允許開發人員編寫訪問數據的代碼而不用關心數據庫是如何實現的,而只用關心到數據庫的連接。它是使用簡單,讀寫速度快,又更加靈活的對象模型。適合用在城市軌道交通數據庫中。
ADO主要數據對象
Connection對象
-Connection對象用于建立與數據庫的連接。通過連接可從應用程序訪問數據源。它保存諸如指針類型、連接字符串、查詢超時、連接超時和缺省數據庫這樣的連接信息。Command對象
-Command對象定義了將對數據源執行的指定命令。Command對象可以在數據庫中添加、刪除或更新數據、或者在表中進行數據查詢。返回的結果保存在Recordset對象中。Recordset對象
-Recordset對象表示的是來自基本表或命令執行結果的記錄全集。任何時候,Recordset對象所指的當前記錄均為集合內的單個記錄。使用ADO時,通過Recordset對象可對幾乎所有數據進行操作。所有Recordset對象均使用記錄(行)和字段(列)進行構造。在一個Connection對象上,可以同時打開多個Recordset。
由于數據庫是存放在SQL 2005中,需要先在SQL中建立數據庫train,然后向里面添加多個表,分別存放車站信息,列車時刻表信息和用戶信息等。如圖1所示,是列車時刻表信息的結構,設置列車ID為主鍵,不能為空。
在VC2005中建立一個基于對話框的MFC應用程序time,并添加相關菜單,如車站信息管理,時刻表添加、刪除、修改,退出系統等。不同的菜單命令都有一個對話框與之對應,然后向個對話框中添加靜態控件、編輯控件、TAB控件、按鈕控件和列表框控件等。為了使表中的字段與編輯控件對應,編輯控件應與控制變量綁定。下面介紹ADO技術的在VC中的應用。
(1)為了便于方便的使用ADO,該程序中對ADO封裝到了一個類中,命名為ADOConn,后面的編程可直接調用該類使用ADO,避免重復寫代碼。在使用ADO之前,應在該類的頭文件中加入以下代碼:
#import"C:Program FilesCommon FilesSystemadomsado15.dll"no_namespacerename("EOF","adoEOF")rename("BOF","adoBOF")
此指令,告訴編譯器把指令的動態庫文件引入到程序中去,為了避免與其他地方定義的EOF沖突,使用rename指令將EOF重新命名。
(2)在頭文件定義幾個函數,如 void OnInit ADOConn()用來初始化連接數據庫,_RecordsetPtr&GetRecordSet(_bstr_t bstrSQL)來執行查詢,BOOL ExecuteSQL(_bstr_t bstrSQL)來執行SQL語句。
(3)在調用ADO時候需要初始化OLE/COM環境,在OnInitADOCon中用::CoInitialize(NULL)來實現,在最后關閉記錄集連接時還要用::CoUninitialize()來釋放環境。另外為了能捕捉到程序的錯誤信息,還需要捕捉異常,具體代碼是:
catch(_com_error e)
{
AfxMessageBox(e.Description());}
(4)創建Connection對象,并設置字符串與數據庫連接,如本例代碼為:
_bstr_tstrConnect="Provider=SQLOLEDB.1;
DataSource=WWW;UserID=sa;Password=sa;Initial Catalog=train";
其中,DataSource為計算機名,對本機可直接用 127.0.0.1代替;User ID和 Password分別是SQL的登錄名和密碼,Initial Catalog是數據庫名稱。
(5)創建記錄集對象m_pRecordset.CreateInstance(__uuidof(Recordset)),然后取得表中的記錄,代碼

圖1 Time數據表結構
如下:
m_pRecordset →Open (bstrSQL,m_pConnection.GetInterfacePtr (),adOpenDynamic,adLockOptimistic,adCmdText);
(6)執行SQL命令,connection對象的Execute方法是:
(_bstr_t CommandText,VARIANT*RecordsAffected,long Options)
m_pConnection->Execute(bstrSQL,NULL,adCmdText)
其中,CommandText是命令字符串,通常是SQL命令,RecordsAffected是操作完成后所影響的行 數 ,Options表 示 CommandText的 類 型,adCmdText文本令,adCmdTable表名,adCmdProc是存儲過程,adCmdUnknown-未知。
ATS系統的數據庫管理是整個列車行車調度的關鍵,其車次號的變更,加減列車,時刻表偏移等措施無一不與數據庫有很大關系。下面介紹程序的實現步驟:
(1)先對數據庫中的每個表創建一個類,如時刻表創建類CShike,并把一些相關的SQL命令如insert、update、delete命令封裝在類中,方便后面直接調用。
(2)新建一個對話框Dialogin,添加編輯框等控件來輸入用戶名密碼,并對編輯框添加變量與表對應。之后再主對話框的OnInitDialog函數中加入以下代碼:CDialogin gin;
if(gin.DoModal()!=IDOK)
OnOK();
這樣程序運行時就會先出現登陸框,輸入用戶名密碼后方能進入主界面(見圖2)。

圖2 程序主界面
狀態欄中mr就是當前登陸的用戶名。
(3)以時刻表管理為例,新建對話框并插入相關控件,這里為了方便維護信息和查詢,用了TAB控件分頁,單擊TAB的時刻信息按鈕顯示列表框并直接從數據庫表中讀取時刻表信息并顯示。單擊信息刪除按鈕顯示編輯框等控件,調度員可以在這里對時刻表的相關信息進行維護,比如添加、修改、刪除等。下面就相關代碼做介紹。
在CShikedlg的OnInitDialog函數中加入以下代碼實現TAB按鈕名稱:
TC_ITEM tci;
tci.mask=TCIF_TEXT;
tci.pszText="時刻信息";m_tab.InsertItem(0,&tci);tci.pszText="信息刪除";m_tab.InsertItem(1,&tci)。
之后InsertColumn初始化列表框控件,之后調用ADO類并執行SQL命令,再向列表框控件插入數據,比如表中字段為trainID,代碼就是:
m.list.SetItemText(0,0,(char*)(_bstr_t)m_AdoConn.m_pRecordset->GetCollect("TrainID")); 其中 m_list是列表框的成員變量。
TAB的分頁機制可用OnTcnSelchangeTab1和OnTcnSelchangingTab1與SetCurTab函數來實現,比如編輯框和列表框的代碼如下:
void CShikedlg::SetCurTab(UINT m_index){
m_tab.SetCurSel(m_index);
if(m_index==0)
{
GetDlgItem(IDC_LIST1)->ShowWindow(SW_HIDE);GetDlgItem(IDC_EDIT1)->ShowWindow(SW_SHOW);}
else{
GetDlgItem(IDC_EDIT1)->ShowWindow(SW_HIDE);GetDlgItem(IDC_LIST1)->ShowWindow(SW_SHOW);
}}
程序運行后的時刻表信息如圖3所示。
通過程序的運行結果可知,ADO可以快速實現對數據庫的操作,整個過程不需要安裝任何驅動,在VC中直接使用ADO代碼即可實現,簡單方便。本文使用MFC開發程序,其強大的集成環境可簡化加快應用程序的開發,采用ADO技術實現數據庫管理之后,就可以利用已有的數據來繪制列車的計劃運行圖,MFC提供的繪圖類CDC非常方便,利用函數move to,line to結合相關算法可直接繪制出運行圖;從而更好地實現ATS的行車調度。
[1]宋坤,李偉明,劉銳寧.Visual C++數據庫系統開發案例精選[M].北京:人民郵電出版社,2006:311-360.
[2]顏志軍.Visual C++數據庫通用模塊及典型系統開發實例[M].北京:電子工業出版,2006:17-134.
[3]趙麗紅,劉海,王春曉.基于MFC和ADO技術的電網數據庫系統[J].測控技術,2010,29(8).
[4]劉曉娟,張雁鵬,湯自安.城市軌道交通智能控制系統[M].北京:中國鐵道出版社,2008:105-118.
[5]SERBANGHENEA,Application Tool for Experiments on SQLServer 2005 Transactions[J].WSEASTransactions on Computers,2007,6(2).

圖3 程序運行后的時刻表信息