




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
VBOPC控件設計說明文檔裝配與檢測自動化事業部如何建立OPC服務器與PLC的S7連接以及如何使用VB版OPC控件的說明書1軟硬件環境1(1軟件環境:1,Windows2000或WindowXP操作系統2)SIMATICNETPCSOFTWAREV6.2及授權3)STEP7V5.3+SP3或以上版本及授權4,VisualBasic6.0編程軟件注:以上軟件安裝順序無要求。1.2硬件:1)CP1613或普通10/100自適應以太網卡2)普通網線3,PS307(6ES7307-1EA00-0AA0)4)CPU315-2DP(6ES7315-2AG10-0EX0)5)CP343-1Lean,6GK7343-1CX10-0XE0,2(OPC服務器配臵2.1配臵PC站的硬件機架,當SIMATICNET軟件成功安裝后~在PC機桌面上可看到StationConfigurator的快捷圖標~同時在任務欄(Taskbar)中也會有StationConfigurationEditor的圖標。圖1:StationConfigurator桌面快捷圖標雙擊StationConfigurationEditor圖標~打開配臵窗口1裝配與檢測自動化事業部圖2StationConfigurationEditor配臵窗口1)在1#槽中插入OPCServer圖3:添加OPCServer2)在3#槽中插入IE-General,插入IEGeneral后~即彈出其屬性對話框。2裝配與檢測自動化事業部圖4:添加IE-General3)點擊NetworkProperties~進行網卡參數配臵,如IP地址~子網掩碼等。圖5:配置IE-General屬性3裝配與檢測自動化事業部圖6配臵網絡屬性圖7配臵Internet屬性4)當網卡配臵完成后~點擊StationConfigurationEditor中的“StationName”按鈕~指定PC站的名稱~這里命名為ethernetopc。點擊“OK”確認即完成了PC站的硬件組態。4裝配與檢測自動化事業部圖8:命名PC站名稱2(2配臵控制臺,ConfigurationConsole,的使用與設臵1)配臵控制臺,ConfigurationConsole,是組態設臵和診斷的核心工具~用于PC硬件組件和PC應用程序的組態和診斷。2)正確完成PC站的硬件組態后~打開配臵控制臺~在控制臺檢測到OPC服務器的配臵后~就可以看到所用以太網卡的模式已從PGmode切換到Configurationmode,插槽號,Index,也自動指向3。如下圖。1.5裝配與檢測自動化事業部圖9配臵控制臺,ConfigurationConsole,3)在AccessPoints設定窗口中~將S7ONLINE指向PCinternal(local)。此設定是為PC站組態的下載做準備。圖10:PCStation配置控制臺AccessPoint2(3在STEP7中組態PCStation1)打開SIMATICManager~通過File->New創建一個新項目。通過Insert->Station->SimaticPcStation插入一個PC站。圖11在STEP7中插入PCStation6裝配與檢測自動化事業部2)在硬件組態中~從硬件目錄窗口選擇與已安裝的Simaticnet軟件版本相符的硬件插入到與在StationConfigurationEditor配臵的PC硬件機架相對應的插槽中。圖12配臵PCStation3)分配普通以太網絡參數點擊IEGeneral屬性對話框中Properties按鈕打開以太網接口參數設臵對話框,按要求設臵以太網卡的IP地址和相應的子網掩碼。IP地址應與實際硬件所設以太網卡IP地址一致。并用New按鈕建立一個ethernet網絡。確認所有組態參數~完成網卡設臵。7裝配與檢測自動化事業部圖13在PCStation中配臵IE-General屬性4)完成PC站組件設臵后~按下編譯存盤按鈕確定且存儲當前組態配臵5)插入一個S7300站,通過Insert->Station->Simatic300Station,在相應的槽中插入,電源模塊、CPU、cp343,1等~并cp343,1的屬性窗口中配臵ip地址~子網掩碼等參數~完成硬件組態.圖14配臵S7-300站6)編譯無誤后~點擊“ConfigureNetwork”按鈕~進入NetPro配臵窗口。7)在NetPro網絡配臵中~用鼠標選擇OPCServer后在連接表第一行鼠標右鍵插入一個新的連接或通過“Insert>NewConnection”也可建立一個新連接。8裝配與檢測自動化事業部圖15在NetPro網絡配臵中加入一個新連接如果在同一STEP7項目中~所要連接的PLC站已經組態完成~即PLC以太網通訊處理器,CP343-1orCP443-1,網絡已經使能~在選擇“InsertNewConnection”后~連接會自動創建。圖16S7連接屬性8)確認所有配臵后~已建好的S7連接就會顯示在連接列表中。點擊編譯存盤按9裝配與檢測自動化事業部鈕或選擇Network>SaveandCompile~如得到Noerror的編譯結果~則正確組態完成。這里編譯結果信息非常重要~如果有警告信息,Warning,顯示在編譯結果對話框中~這僅僅是一條信息。但如果有錯誤信息,errorMessage,~說明組態不正確~是不能下載到PCStation中的。圖17組態編譯存盤2(4完成PC站組態后~即可在NetPro窗口點擊功能按鈕欄中下載按鈕將組態下載到PC站中。需注意的是~下載過程中會刪除已有相關組件的數據~新的組態數據將被下載到PC機。點擊OK執行下載。下載完成后~可以打開StationConfigurationEditor窗口Conn一欄一定要有連接圖標~檢查組件狀態。下圖為正確狀態顯示畫面。OPCServer插槽此項說明連接激活。10裝配與檢測自動化事業部圖18PCStation運行狀態3(OPC控件說明OPC(OLEforProcessControl—用于過程控制的對象連接與嵌入)是一套以微軟對象連接與嵌入OLE、組件對象模型COM、分布式組件對象模型DCOM(DistributedCOM)技術為基礎~基于Windows操作平臺~為工業應用程序之間提供高效的信息集成和交互功能的組件對象模型接口標準。OPC實際上是提供了一種機制~通過這種機制~系統能夠以服務器/客戶端標準方式從服務器獲取數據并將其傳遞給任何客戶應用程序。這樣~只要生產商開發一套遵循OPC規范的服務器與數據進行通信~其他任何客戶應用程序便能通過服務器訪問設備。OPC服務器有兩類接口:定制接口和自動化接口。定制接口為C++程序服務~自動化接口為VB這一類可使用自動化對象的程序服務。定制接口是服務商必須提供的~而自動化接口則是可選的~不過OPC基金會提供了一個叫做“自動化包裝器”的動態連接庫~用于在兩者間轉換。OPC數據存取規范規定的基本對象有三類:服務器(server)、組(group)和數據項(item)。服務器對象包含服務器的所有信息~也是組對象的容器~一個服務器對應于一個OPCserver~即一種設備的驅動程序。組對象除了包含它自身信息外~還負責管理數據項。每一個數據項代表到數據源的一個連接~但它沒有提供外部接口~客戶端程序無法對數據項直接進行操作~應用程序必須依靠數據項的容器組對象來對它進行操作。該控件的主要屬性有OPCServerName、OPCGroupName、OPCBufferSize、OpcLinkStatus、OPCstartAddress~其中~OPCServerName用于配臵服務器(server)名稱,OPCGroupName用于配臵組(group)名稱,OPCstartAddress用于配臵連接到控件的PLC變量的起始地址,OPCBufferSize用于配臵PLC變量的長度,OpcLinkStatus用于顯示OPC控件的連接狀態~連接正?!珓t該參數為0~若該參數不為0~則連接出現問題~在該情況下~可通過編程先11裝配與檢測自動化事業部調用OPCDisconnect,,斷開與OPC服務器的連接~再調用OPCLink,,重新連接OPC服務器。該控件的方法主要有OPCLink,,、OPCGetData,ByrefData,,asVarriant~ByvalLenasInteger,、OPCSentData,ByrefData,,asVarriant~ByvalLenasInteger,、OPCDisconnect,,~其中~OPCLink用于連接服務器(server)添加組,GROUP,和數據項(ITEM),OPCGetData,ByrefData,,asVarriant~ByvalLenasInteger,用于讀取OPC服務器的數據~數組Data用于接受數據~Len指定數據長度,OPCSentData,ByrefData,,asVarriant~ByvalLenasInteger,用于向OPC服務器發送數據~數組Data用于存放被發送的數據~Len指定數據長度,OPCDisconnect,,用于斷開與OPC服務器的連接。4(OPC控件使用舉例4(1添加控件在VB環境中~按“工程”的子菜單“控件…”后~彈出對話框圖19添加工程部件對話框12裝配與檢測自動化事業部圖20添加Opclinker控件點擊瀏覽按鈕在添加ACTIVEX控件窗口中找到C:\WINNT\SYSTWM32下的OPCLINKER.OCX文件~點擊打開~后點擊部件窗口中的確定按鈕~即加入控件。加入后效果如下圖所示:13裝配與檢測自動化事業部圖21添加控件后的效果4(2應用例程:PrivateSubCommand1_Click()Dimrecv(9)AsVariantOPCLinker1.OpcGetDatarecv,8Text1.Text=CStr(recv(1))Text2.Text=CStr(recv(2))Text3.Text=CStr(recv(3))Text4.Text=CStr(recv(4))Text5.Text=CStr(recv(5))Text6.Text=CStr(recv(6))Text7.Text=CStr(recv(7))Text8.Text=CStr(recv(8))EndSubPrivateSubCommand2_Click()Dimsent(9)AsVariantsent(1)=Val(Text1.Text)sent(2)=Val(Text2.Text)sent(3)=Val(Text3.Text)sent(4)=Val(Text4.Text)sent(5)=Val(Text5.Text)sent(6)=Val(Text6.Text)sent(7)=Val(Text7.Text)sent(8)=Val(Text8.Text)OPCLinker1.OpcSendDatasent,8EndSubPrivateSubForm_Load()OPCLinker1.LinkEnble=TrueOPCLinker1.OpcLinkEndSub附錄1:網絡文章《ActiveX控件的創建》,web地址:www_xiameng_net.htm,作者:互聯網文章來源:互聯網點擊數:1097更新時間:2005-10-1414裝配與檢測自動化事業部1,概述ActiveX是一個Microsoft的術語~它指的是一組包括控件~DLL和ActiveX文檔的組件~它通常是以動態鏈接庫的形式存在,因此必須在一個叫容器的獨立執行軟件中運行。這樣的容器包括Authorware、Delphi~VisualBasic~VisualC,,~InternetExplorer和Access等等。ActiveX控件數據輸入和函數功能執行都必須通過容器~因此ActiveX控件和容器都必須支持一些特定的接口協議。根據Microsoft相應的規格標準~ActiveX控件應具備如下的性能機制。屬性和方法:ActiveX控件必須提供屬性的名稱、方法的名稱及參數,通過這項機制容器可以存取和改變ActiveX控件的屬性參數。事件:ActiveX控件由這項機制通知容器在ActiveX控件中發生的事件~比如屬性參數的改變~用戶按下鼠標左鍵等。存儲:容器由這項機制通知ActiveX控件存儲和提取有關信息數據等。ActiveX控件只要在Windows的Registry數據庫中注冊后~就可以像其他Windows應用程序一樣發揮各自的功能。ActiveX控件是一個模塊化的靈活對象,如果某個應用程序或網頁需要增加一項特殊的功能~無須重寫整個程序~只要靈活地插入一個具有此項功能的ActiveX控件即可實現。ActiveX的優勢還在于它的動態可交互性~用戶可以動態地在使用過程中~通過改變它的屬性和參數~在應用程序中實現自己的特殊要求。也許有的讀者會問:目前在市面上可以找到各種各樣現成的ActiveX控件~還有沒有必要自己創建ActiveX控件呢,關于這個問題很容易解釋~現有的控件種類是很多~功能也比較齊全~問題是有許多時候會遇到這種情況:使用現成的控件雖能完成任務~但自己需要的一些特性,屬性、事件或方法,該控件卻沒有提供~還需要自己手工寫代碼來實現~而這些特性偏偏在自己的應用系統中又經常會用到~為了避免大量的重復勞動~一勞永逸的辦法就是在創建自己的ActiveX控件。目前可以使用VisualBasic或其它開發工具創建ActiveX控件。無論按照哪種標準~VisualBasic都是計算機歷史上最為成功的,同時也是最流行的,編程語言~其中最令人興奮的特性就是可以創建用戶自己的控件并可以像其他控件一樣應用于支持ActiveX控件技術的應用程序中。下面通過一個具體實例來闡述如何在VisualBasic6.0,中文企業版,下進行ActiveX控件創建。2,創建ActiveX控件的步驟15裝配與檢測自動化事業部使用VisualBasic編程語言編寫過應用程序的用戶~一定非常熟悉諸如TextBox、Label和Data等控件。要利用這些控件~可以將它們繪制在窗體中~通過屬性~方法和事件控制它們的行為。當用戶創建自己的ActiveX控件時~除了確定屬性、方法和事件以外~用戶是在創建一個相似的對象。當創建了自己的ActiveX控件以后~就可以在其他VisualBasic工程中使用它~就像使用TextBox控件一樣??梢栽谀苁褂肁ctiveX控件的任何應用程序或開發工具,包括其他VisualBasic工程、Authorware或者MicrosoftInternetExplorer,中使用自己的控件。在VisualBasic中創建一個ActiveX控件不同于創建一個StandardEXE應用程序。因此當創建一個新控件時~一般應遵循的步驟是:,1,確定控件將要提供的功能。因為ActiveX控件類似于一個獨立的對象~所以需要明確這個對象的目的~希望它在屏幕上有什么樣的外觀,使用此控件時~需要什么屬性、方法以及事件用于應用程序中,,2,設計控件的外觀。,3,設計控件的接口~即屬性、事件和方法。,4,創建由控件工程和測試工程組成的工程組。,5,通過把控件和或代碼添加到UserControl對象中來實現控件的外觀。,6,實現控件的接口和功能。,7,編譯控件部件,.ocx文件,。下面按照上述步驟建立一個可直接顯示數據庫內容的DataListView控件。3,具體實現方法,1,確定DataListView控件的功能標準的ListView控件在顯示數據庫記錄時還存在一些不足~如必須編寫大量的代碼等~DataListView通過在ListView的基礎上添加部分功能而彌補了ListView的不足~因此它除了本身固有的屬性、方法和事件外~添加了如下成員:?DataServerName屬性--確定所操作的數據庫服務器。?DataBaseName屬性--確定所操作的數據庫。?AdministratorName屬性--確定操作數據庫的管理員名稱。?PasswordName屬性--確定操作數據庫的管理員口令。?ShowDataBase方法--顯示Select命令所執行的數據庫操作結果。?ErrorDataBase事件--當遇到錯誤的數據庫操作時引發該事件。,2,設計控件的外觀DataListView由于僅包含一個ListView控件~所以其外觀沒有太多需要考慮的問題。16裝配與檢測自動化事業部如果要創建的控件是多個控件構成~或新控件不包括任何現存控件即完全從頭開始創建一個全新的控件的話~則外觀問題是一個很重要的問題。,3,設計控件的接口~即屬性、事件和方法對ListView控件所作的改進是為了讓ListView控件支持數據庫的內容顯示,以便在所有能支持ActiveX控件的應用程序中使用。通過添加用戶自己的屬性DataServername、DataBaseName、AdministratorName、PasseordName和方法ShowDataBase等可以實現這項功能。DataListView的其他屬性、事件和方法都和標準ListView一樣。,4,創建由控件工程和測試工程組成的工程組?啟動一個新的ActiveX控件工程。?按下CTRL+T組合鍵或者選擇【工程】|【部件】菜單選項~顯示【部件】對話框~在【控件】選擇框中選擇MicrosoftWindowsCommonControls6.0。?選擇【工程】|【引用】菜單選項~顯示【引用】對話框~在【可用的引用】選擇框中選擇MicrosoftActiveXDataObjects2.0Library。?在UserControl窗口中添加一ListView控件~ListView控件的左上角位臵為0~0。?設臵ActiveX工程和UserControl控件屬性值~如下表所示。條目設臵工程類型ActiveX控件工程名稱DataLV工程描述通過ADO~使得ListView控件能夠直接操作數據庫UserControl的Name屬性DataListViewUserControl的Public屬性True?保存這個工程。?選擇【文件】|【添加工程】菜單選項。然后添加一個標準EXE工程。建立該工程的目的是為了在創建ActiveX控件時不斷地進行測試。此時已建立了一個由控件工程和測試工程組成的工程組~下面就可以正式開始創建DataListView控件。,5,實現控件的外觀確定控件外觀的方式取決于當前控件的創建模型。如果要創建一個用戶繪制控件~那么必須自己在UserControl_Paint事件過程編寫代碼來完成所有的繪制工作~同時還需要確定何時繪制控件~以便在需要的時候調用UserControl的Refresh方法來產生Paint事件。如果是改進一個現有控件~那么只需正確地將組成控件放臵在UserControl上即可。由于DataListView控件僅包含ListView一個組成控件~那么只需簡單地在17裝配與檢測自動化事業部UserControl1上繪出一個標準ListView控件~控件名為缺省的ListView1~即可完成外觀繪制工作。為了在使用控件時~使ListView控件和自己繪制的空間相匹配~必須建立UserControl的Resize事件過程。Resize事件過程的代碼如下:PrivateSubUserControl_Resize()ListView1.Left=0ListView1.Top=0ListView1.Width=UserControl.WidthListView1.Height=UserControl.HeightEndSub僅四行代碼的Resize事件過程是簡單控件的用戶界面的所有必須的代碼~其目的是使ListView控件和UserControl對象有相同的尺寸。,6,實現控件的接口和功能這是整個創建過程中最核心、最重要也是最復雜的步驟。對于創建控件的每一屬性、事件和方法均需逐一實現。?創建DataServerName屬性要創建DataServerName屬性值~首先需要添加一個在內部存貯屬性值的局部變量。要做到這一點~在UserControl對象的GenaralDeclarations通用聲明語句中創建此變量。如下所示:Dimm_DataServerNameAsString接著需要創建稱為DataServerName的新屬性~可以通過手工輸入Get和Let過程~或者選擇【工具】|【添加過程】|【類型】創建這個新屬性。DataServerName屬性的代碼相當容易理解。當臵DataServerName屬性的值時~PropertyGet過程僅將局部變量的存貯內容取出來。當設臵DataServerName屬性值時~PropertyLet過程將為局部變量賦予一個有效值。以下是兩個Property過程的代碼:PublicPropertyGetDataServername()AsStringDataServername=m_DataServerNameEndPropertyPublicPropertyLetDataServername(ByValNew_DataServerNameAsString)m_DataServerName=New_DataServerNamePropertyChanged"DataServerName"EndProperty18裝配與檢測自動化事業部需要注意的是在PropertyLet過程中~有一個PropertyChanged方法~它的功能是通知容器,可以理解為存放所有屬性的單元,屬性值已變更~需產生一個WriteProperties事件~來保存新屬性值。事實上不僅在PropertyLet過程需要調用PropertyChanged方法~在UserControl的代碼模塊中無論何時改變了ActiveX控件的某個屬性值~均需調用該過程,以保存屬性的變化。注意PropertyDataServerName方法的用法~此方法與ReadProperties和WriteProperties事件在一起使用。此時需要使用用戶控件的InitProperties事件指定此屬性的初始值:PrivateSubUserControl_InitProperties()m_DataServerName=m_def_DataServerNameEndSub即使用戶沒有設臵初始值~這些代碼也會確保設臵了一個初始值。至于DataBaseName、AdministratorName、PasseordName屬性的創建過程跟DataServername屬性的創建過程完全一樣~這里就不再重復敘述。?使用PropertyBag對象用戶還需要為WriteProperties和ReadProperties事件創建代碼,從而保護DataServername、DataBaseName、AdministratorName、PasseordName屬性在設計階段的屬性值。這兩個事件都使用PropertyBag對象保存和檢索DataServername、DataBaseName、AdministratorName、PasseordName屬性的值。PropertyBag對象能夠保持DataServername、DataBaseName、AdministratorName、PasseordName的設計值。具體實現代碼如下:PrivateSubUserControl_ReadProperties(PropBagAsPropertyBag)m_DataServerName=PropBag.ReadProperty("DataServerName",m_def_DataServerName)m_DataBaseName=PropBag.ReadProperty("DataBaseName",m_def_DataBaseName)m_AdministratorName=PropBag.ReadProperty("AdministratorName",m_def_AdministratorName)m_PasswordName=PropBag.ReadProperty("PasswordName",m_def_PasswordName)EndSubPrivateSubUserControl_WriteProperties(PropBagAsPropertyBag)CallPropBag.WriteProperty("DataServerName",m_DataServerName,19裝配與檢測自動化事業部m_def_DataServerName)CallPropBag.WriteProperty("DataBaseName",m_DataBaseName,m_def_DataBaseName)CallPropBag.WriteProperty("AdministratorName",m_AdministratorName,m_def_AdministratorName)CallPropBag.WriteProperty("PasswordName",m_PasswordName,m_def_PasswordName)EndSub由于這兩個過程是針對"容器"對象的~因此所有屬性值的保存和讀取都通過這兩個過程來實現~而不是每個屬性都需要單獨的兩個過程。其中~PropertyBag就是"容器對象"的名稱。WriteProperty方法有三個參數:第一個字符串標識需要保存的屬性~第二個參數是需要保存的值~最后的參數是屬性的缺省值。ReadProperty方法需要兩個參數:一個字符串用來保存屬性的名稱~另一個為缺省值。在窗體上繪制ActiveX控件的那一刻~就會開始執行ActiveX控件的代碼。在控件設計過程中~將DataServername、DataBaseName、AdministratorName、PasseordName屬性的默認值設臵為:Constm_def_DataServerName="lyc"Constm_def_DataBaseName="pubs"Constm_def_AdministratorName="sa"Constm_def_PasswordName=""當然~也可以在程序運行時多次修改它。控件的正常行為是當程序終止時恢復其默認值~這樣增加了保持屬性的兩種獨立狀態的要求。簡言之~如果在設計階段改變了一個屬性值~那么控件必須得到這個新值~而不是使用默認值。相反~如果在程序運行時改變屬性值~那么當返回設計狀態時~控件必須檢索此屬性值。PropertyBag對象允許ActiveX控件存貯有關它自己的屬性值~使它能執行這個動作。PropertyChanged方法會通知用戶已經改變了一個屬性。通過了解程序的狀態以及是否調用了PropertyChanged方法~VB就可以激發WriteProperties和ReadProperties事件。?為ShowDataBase方法編寫代碼ShowDataBase方法實現在ListView控件中顯示Select命令所執行的數據庫操作結果。在其具體實現過程中采用了ADO,ActiveXDataObjects,的數據存取方法。ADO的主要特點是使用更加容易~訪問速度更快,而對磁盤和存儲容量的要求更小,ADO支持建立各種客戶20裝配與檢測自動化事業部/服務器模式與基于Web的應用程序~具有遠程數據服務RDS,RemoteDataService,的特性~通過RDS能夠在一次往返中將服務器端的數據傳送到客戶端的應用程序或Web頁面中~并在客戶端對數據進行處理后~立即更新服務器端的數據。采用ADO所基于的OLEDB技術~可以對電子郵件、文本文件、數據表格等各類數據通過統一的接口API接口進行存取~是遠程數據存取的一個主要發展方向。ShowDataBase方法具有一個字符串參數~但無任何返回值~具體代碼如下所示:PublicSubshowdatabase(ssqlAsString)DimAdoDatabaseAsNewADODB.ConnectionDimAdoTableAsNewADODB.RecordsetDimscnnAsStringDimresponseAsStringDimIAsIntegerOnErrorGoToerrorhandlescnn="Provider=SQLOLEDB;DataSource="&Trim(m_DataServerName)&";InitialCatalog="&Trim(m_DataBaseName)&";UserId="&Trim(m_AdministratorName)&";Password="&Trim(m_PasswordName)&";"AdoDatabase.OpenscnnAdoTable.CursorType=adOpenKeysetAdoTable.LockType=adLockOptimisticAdoTable.CursorLocation=adUseClientAdoTable.Openssql,AdoDatabase,,,adCmdTextIfAdoTable.BOFAndAdoTable.EOFThenresponse=MsgBox("沒有符合條件的記錄::",vbOKOnly+vbInformation,"數據庫控件")AdoTable.CloseSetAdotable=NothingAdoDatabase.CloseSetAdoDataBase=NothingExitSubEndIfListView1.ColumnHeaders.ClearListView1.ListItems.ClearDimclmXAsColumnHeaderForI=0ToAdoTable.Fields.Count-1SetclmX=ListView1.ColumnHeaders.Add()WithclmX.Text=AdoTable.Fields(I).NameEndWithNextDimitmXAsListItemAdoTable.MoveFirst21裝配與檢測自動化事業部DoWhileNotAdoTable.EOFSetitmX=ListView1.ListItems.Add()WithitmXIfIsNull(AdoTable.Fields(0).Value)Then.Text="NULL"Else.Text=AdoTable.Fields(0).ValueEndIfEndWithForI=1ToAdoTable.Fields.Count-1IfIsNull(AdoTable.Fields(I).Value)ThenitmX.SubItems(I)="NULL"ElseitmX.SubItems(I)=AdoTable.Fields(I).ValueEndIfNextAdoTable.MoveNextLoopListView1.View=lvwReportAdoTable.CloseSetAdotable=NothingAdoDatabase.CloseSetAdoDataBase=NothingExitSuberrorhandle:RaiseEventErrordatabaseEndSub當對數據庫的操作發生錯誤后~除了不能正常顯示以外~還應通知宿主程序用戶。可以通過創建一個叫做Errordatabase的事件實現上述功能。要創建這個事件~把下述代碼添加到UserControl對象的GeneralDeclarations段中。PublicEventErrordatabase()此事件的工作像其他控件的事件一樣。使用控件的用戶可以將代碼放到這個事件中~用戶要做的唯一的事情就是用RaiseEvent方法激發此事件。,7,編譯控件部件,.ocx文件,?,F在已經完成了DataListView控件的創建工作~為了在DataLV工程外也可以使用該控件~只需將DataLV工程編譯.ocx控件部件即可。22裝配與檢測自動化事業部在【工程組】窗口單擊【DataLV】以選擇該工程~在【文件】菜單上單擊【生成DataLV.ocx】~在【生成工程】對話框中選擇控件存放的目錄后~單擊【確定】即可創建.ocx文件。一旦生成了.ocx文件的控件~就可以象使用其它控件一樣來隨心所欲地使用它了。4,結束語ActiveX技術可以靈活、高效的實現可交互、重入、重用、完全分布式、與語言無關的各種應用。隨著ActiveX技術的發展~ActiveX控件在應用程序中的作用將會顯得越來越重要~那么創建一個功能完善、具有自己特色的ActiveX控件就非常具有現實意義。只要掌握了創建ActiveX控件的基本方法~就不難創建自定制的可在各種應用領域使用的ActiveX控件。但是~ActiveX技術也有一些明顯缺點~ActiveX技術依賴于Windows平臺~對廣泛應用的UNIX平臺目前仍不兼容~另外ActiveX在許多方面的性能還較弱~ActiveX技術仍需要不斷完善和發展。附錄2:網絡文章《OPC異步客戶程序》,1,建立新工程或項目~在“工程”菜單下選擇“引用”~如圖5-3所示。只有引用OPCDAAuoto.DLL后~在程序中才能創建服務器對象~然后進行一系列的操作。,2,在彈出的引用窗口里單擊“瀏覽(B)…”按鈕~彈出添加引用窗口~選擇OPCDAAuoto.DLL文件。,3,在引用窗口里的OPCAutomation2.0前面打鉤~按“確定”按鈕。,4,定義全局變量~這樣可以在窗體的任何方法的代碼內應用。變量類型應該指定為對象型。這些對象最好在窗體的通用部分聲明加上“OptionExplicit”語句~表示模塊里的所有變量都需要顯式聲明。由于OPC自動化接口的數組的索引要求必須從1開始~而系統默認是從0開始~為了避免錯誤最好在代碼的最初加上“OptionBase1”語句。為了使對象可以處理事件~必須將objTestGrp和objServer的聲明中加上“WithEvents”語句~表示聲明的對象可以響應事件。OptionExplicitOptionBase1DimWithEventsobjServerAsOPCServerDimobjGroupsAsOPCGroupsDimWithEventsobjTestGrpAsOPCGroupDimobjItemsAsOPCItems,5,連接OPC服務器和建立OPC組考慮到代碼的可反復使用性~采用子程序進行編程。SubConnect(strProgIDAsString,OptionalstrNodeAsString)IfobjServerIsNothingThen23裝配與檢測自動化事業部'建立一個OPC服務器對象SetobjServer=NewOPCServerEndIf服務器狀態ServerState屬性一共有OPCRunning、OPCFailed、OPCNoconfig、OPCSuspended、OPCTest和OPCDisconnected六個值~分別表示正在運行、失敗、沒有配臵、暫停、測試和沒有連接六種OPC服務器當前的狀態。如果OPC服務器沒有連接~我們才執行objServer.ConnectstrProgID,strNode語句。strProgID就是ProgID~strNode就是用于遠程通信的IP地址。IfobjServer.ServerState=OPCDisconnectedThen'連接OPC服務器objServer.ConnectstrProgID,strNodeEndIf在VisualBasic中~通過執行一個Set操作實現調用其它接口的方法。IfobjGroupsIsNothingThen'建立一個OPC組集合SetobjGroups=objServer.OPCGroupsEndIfIfobjTestGrpIsNothingThen'添加一個OPC組SetobjTestGrp=objGroups.Add("Group")EndIfEndSub,6,添加OPC標簽對服務器進行訪問前~必須先在OPC組里添加要訪問的OPC標簽。OPC客戶端程序要按照用戶指定的標簽或者從組態文件里讀取需要添加的OPC標簽。SubAddItem()DimstrItemIDs(17)AsStringDimlClientHandles(17)AsLongDimlErrors()AsLongDimIAsIntegerIfobjTestGrpIsNothingThenExitSubEndIfIfNotobjItemsIsNothingThenIfobjItems.Count>0ThenExitSubEndIfEndIf'設臵組活動狀態。只有處于活動狀態的OPC才進行定期的數據更新。非活動狀態的OPC組~除了在接到顯然的數據讀寫要求外~并不收集任何數據。IfmnuSubscribtion.Checked=TrueThenobjTestGrp.IsActive=True24裝配與檢測自動化事業部ElseobjTestGrp.IsActive=FalseEndIf'啟動組異步通知。進行訂閱的OPC組可以自動收到從服務器送來的數據變化通知。objTestGrp.IsSubscribed=True'建立OPC項集合SetobjItems=objTestGrp.OPCItems'生成從TAG1到TAG17的項標識符ForI=1To17strItemIDs(I)="Server.Group.TAG"&IlClientHandles(I)=INext'添加OPC項CallobjItems.AddItems(17,strItemIDs,lClientHandles,lServerHandles,lErrors)EndSub,7,異步讀取代碼的實現在定時器事件內進行執行AsyncRead子程序的讀取代碼~而在讀取完成事件處理返回的數據訪問結果。SubAsyncRead()DimlErrors()AsLongIfobjTestGrpIsNothingThenExitSubEndIfIfobjTestGrp.OPCItems.Count>0Then'異步讀取lTransID_Rd=lTransID_Rd+1objTestGrp.AsyncRead17,lServerHandles,lErrors,lTransID_Rd,lCancelID_RdEndIfEndSubPrivateSubobjTestGrp_AsyncReadComplete(_ByValTransactionIDAsLong,ByValNumItemsAsLong,_ClientHandles()AsLong,ItemValues()AsVariant,_Qualities()AsLong,TimeStamps()AsDate,Errors()AsLong)……Sub,8,在按鈕中執行AsyncWrite子程序~完成異步寫的操作。SubAsyncWrite(nIndexAsInteger,ByRefvtItemValues()AsVariant,_ByReflErrors()AsLong)DimlHandle(1)AsLongIfobjTestGrpIsNothingThenExitSub25裝配與檢測自動化事業部EndIfIfobjTestGrp.OPCItems.Count>0ThenlHandle(1)=lServerHandles(nIndex)'異步寫入lTransID_Wt=lTransID_Wt+1objTestGrp.AsyncWrite1,lHandle(),vtItemValues,_lErrors,lTransID_Wt,lCancelID_WtEndIfEndSub,9,斷開OPC服務器連接著OPC服務器的OPC客戶應用程序~在退出前必須斷開和OPC服務器的連接。因為OPC服務器并不知道OPC客戶應用程序的退出。如果不先斷開連接~那么OPC服務器使用的計算機資源就不會被釋放。如果這樣的問題反復發生~久而久之~連續運轉的自動控制系統可能會計算機資源漸漸枯竭從而發生嚴重問題~可以顯式地把它設臵為“Nothing”。SubDisconnect()DimlErrors()AsLongIfNotobjItemsIsNothingThenIfobjItems.Count>0ThenobjItems.Remove17,lServerHandles,lErrors'清除OPC項EndIfSetobjItems=NothingEndIfIfNotobjTestGrpIsNothingThenobjGroups.Remove"Group"'清除OPC組SetobjTestGrp=NothingEndIfIfNotobjGroupsIsNothingThenSetobjGroups=NothingEndIfIfNotobjServerIsNothingThenIfobjServer.ServerState<>OPCDisconnectedThenobjServer.Disconnect'斷開OPC服務器.EndIfSetobjServer=NothingEndIfEndSub附錄3:OPC客戶程序,VB篇——同步,來源網絡建立如下窗體:引用如下:26裝配與檢測自動化事業部代碼如下:OptionExplicitDimWithEventsServerObjAsOPCServerDimWithEventsGroupObjAsOPCGroupDimItemObjAsOPCItemPrivateSubCommand_Start_Click()DimOutTextAsStringOnErrorGoToErrorHandlerCommand_Start.Enabled=FalseCommand_Read.Enabled=TrueCommand_Write.Enabled=TrueCommand_Exit.Enabled=TrueOutText="連接OPC服務器"SetServerObj=NewOPCServerServerObj.Connect("XXXSERVER")'XXXSERVER為某OPC服務器名稱OutText="添加組"SetGroupObj=ServerObj.OPCGroups.Add("Group")OutText="AddinganItemtothegroup"SetItemObj=GroupObj.OPCItems.AddItem("XXXITEM",1)'XXXITEM為添加的ITEM名稱ExitSubErrorHandler:'如果出現異?!珓t報出錯誤。MsgBoxErr.Description+Chr(13)+_OutText,vbCritical,"ERROR"EndSubPrivateSubCommand_Read_Click()'同步讀DimOutTextAsStringDimmyValueAsVariantDimmyQualityAsVariant27裝配與檢測自動化事業部DimmyTimeStampAsVariantOnErrorGoToErrorHandlerOutText="讀ITEM值"ItemObj.ReadOPCDevice,myValue,myQuality,myTimeStampEdit_ReadVal=myValueEdit_ReadQu=GetQualityText(myQuality)Edit_ReadTS=myTimeStampExitSubErrorHandler:MsgBoxErr.Description+Chr(13)+_OutText,vbCritical,"ERROR"EndSubPrivateSubCommand_Write_Click()'同步寫DimOutTextAsStringDimServerhandles(1)AsLongDimMyValues(1)AsVariantDimMyErrors()AsLongOutText="寫值"OnErrorGoToErrorHandlerServerhandles(1)=ItemObj.ServerHandleMyValues(1)=Edit_WriteValGroupObj.SyncWrite1,Serverhandles,MyValues,MyErrorsEdit_WriteRes=ServerObj.GetErrorString(MyErrors(1))ExitSubErrorHandler:MsgBoxErr.Description+Chr(13)+_OutText,vbCritical,"ERROR"EndSub28裝配與檢測自動化事業部PrivateSubCommand_Exit_Click()'停止~刪除ITEM,刪除GROUP~刪除SERVER。DimOutTextAsStringOnErrorGoToErrorHandlerCommand_Start.Enabled=TrueCommand_Read.Enabled=FalseCommand_Write.Enabled=FalseCommand_Exit.Enabled=FalseOutText="刪除對象"SetItemObj=NothingServerObj.OPCGroups.RemoveAllSetGroupObj=NothingServerObj.DisconnectSetServerObj=NothingExitSubErrorHandler:MsgBoxErr.Description+Chr(13)+_OutText,vbCritical,"ERROR"EndSubPrivateFunctionGetQualityText(Quality)AsStringSelectCaseQualityCase0:GetQualityText="BAD"Case64:GetQualityText="UNCERTAIN"Case192:GetQualityText="GOOD"Case8:GetQualityText="NOT_CONNECTED"Case13:GetQualityText="DEVICE_FAILURE"Case16:GetQualityText="SENSOR_FAILURE"Case20:GetQualityText="LAST_KNOWN"Case24:GetQualityText="COMM_FAILURE"Case28:GetQualityText="OUT_OF_SERVICE"Case132:GetQualityText="LAST_USABLE"Case144:GetQualityText="SENSOR_CAL"Case148:GetQualityText="EGU_EXCEEDED"29裝配與檢測自動化事業部Case152:GetQualityText="SUB_NORMAL"Case216:GetQualityText="LOCAL_OVERRIDE"CaseElse:GetQualityText="UNKNOWNERROR"EndSelectEndFunction控件程序清單:OptionExplicitOptionBase1PrivateMyOPCServerAsOPCServerPrivateWithEventsMyOPCGroupAsOPCGroupPrivateMyOPCItems(32767)AsOPCItemPrivateItemsAsOPCItemConstm_def_OpcServerName="OPC.SimaticNET"Constm_def_OpcGroupName="Group"Constm_def_OpcStartAddress="MB0"Constm_def_OpcBufferSize=16'Constm_def_OpcBufStartAddr=0Constm_def_OpcLinkStatus=0Constm_def_LinkEnble=FalseConstm_def_ConnectionType="S7CONNECTION_1"Dimm_OpcServerNameAsStringDimm_OpcGroupNameAsStringDimm_OpcStartAddressAsStringDimm_OpcBufferSizeAsIntegerDimm_LinkEnbleAsBoolean'Dimm_OpcBufStartAddrAsIntegerDimm_OpcLinkStatusAsIntegerDimm_ConnectionTypeAsString'PublicEventOpcDataExchage()PublicPropertyGetOpcServerName()AsVariantOpcServerName=m_OpcServerNameEndProperty30裝配與檢測自動化事業部PublicPropertyLetOpcServerName(ByValvNewValueAsVariant)m_OpcServerName=vNewValuePropertyChanged"OpcServerName"EndPropertyPrivateSubUserControl_InitProperties()m_OpcServerName=m_def_OpcServerNamem_OpcGroupName=m_def_OpcGroupNamem_OpcStartAddress=m_def_OpcStartAddressm_OpcBufferSize=m_def_OpcBufferSizem_LinkEnble=m_def_LinkEnble'm_OpcBufStartAddr=m_def_OpcBufStartAddrm_OpcLinkStatus=m_def_OpcLinkStatusm_ConnectionType=m_def_ConnectionTypeEndSubPublicPropertyGetOpcGroupName()AsVariantOpcGroupName=m_OpcGroupNameEndPropertyPublicPropertyLetOpcGroupName(ByValvNewGroupValueAsVariant)m_OpcGroupName=vNewGroupValuePropertyChanged"OpcGroupName"EndPropertyPrivateSubUserControl_Paint()UserControl.Height=675UserControl.Width=825EndSubPrivateSubUserControl_ReadProperties(PropBagAsPropertyBag)m_OpcServerName=PropBag.ReadProperty("OpcServerName",m_def_OpcServerName)m_OpcGroupName=PropBag.ReadProperty("OpcGroupName",m_def_OpcGroupName)m_OpcStartAddress=PropBag.ReadProperty("OpcStartAddress",m_def_OpcStartAddress)m_OpcBufferSize=PropBag.ReadProperty("OpcBufferSize",m_def_OpcBufferSize)m_LinkEnble=PropBag.ReadProperty("LinkEnble",m_def_LinkEnble)'m_OpcBufStartAddr=PropBag.ReadProperty("OpcBufStartAddr",31裝配與檢測自動化事業部m_def_OpcBufStartAddr)m_OpcLinkStatus=PropBag.ReadProperty("OpcLinkStatus",m_def_OpcLinkStatus)m_ConnectionType=PropBag.ReadProperty("ConnectionType",m_def_ConnectionType)EndSubPrivateSubUserControl_WriteProperties(PropBagAsPropertyBag)CallPropBag.WriteProperty("OpcServerName",m_OpcServerName,m_def_OpcServerName)CallPropBag.WriteProperty("OpcGroupName",m_OpcGroupName,m_def_OpcGroupName)CallPropBag.WriteProperty("OpcStartAddress",m_OpcStartAddress,m_def_OpcStartAddress)CallPropBag.WriteProperty("OpcBufferSize",m_OpcBufferSize,m_def_OpcBufferSize)CallPropBag.WriteProperty("LinkEnble",m_LinkEnble,m_def_LinkEnble)'CallPropBag.WriteProperty("OpcBufStartAddr",m_OpcBufStartAddr,m_def_OpcBufStartAddr)CallPropBag.WriteProperty("OpcLinkStatus",m_OpcLinkStatus,m_def_OpcLinkStatus)CallPropBag.WriteProperty("ConnectionType",m_ConnectionType,m_def_ConnectionType)EndSubPublicPropertyGetOpcStartAddress()AsVariantOpcStartAddress=m_OpcStartAddressEndPropertyPublicPropertyLetOpcStartAddress(ByValvNewAddressAsVariant)m_OpcStartAddress=vNewAddressPropertyChanged"OpcStartAddress"EndPropertyPublicPropertyGetOpcBufferSize()AsIntegerOpcBufferSize=m_OpcBufferSizeEndPropertyPublicPropertyLetOpcBufferSize(ByValvNewDataLenAsInteger)m_OpcBufferSize=vNewDataLenPropertyChanged"OpcBufferSize"EndProperty32裝配與檢測自動化事業部PublicPropertyGetLinkEnble()AsBooleanLinkEnble=m_LinkEnbleEndPropertyPublicPropertyLetLinkEnble(ByValvEnbleAsBoolean)m_LinkEnble=vEnblePropertyChanged"LinkEnble"EndPropertyPublicSubOpcLink()DimItemName(32767)AsStringDimSHandles(32767)AsLong'parametervalueDimValues()AsVariant'returnvalueDimErrors()AsLong'returnvalueDimQualAsVariant'returnvalueDimTSAsVariant'returnvalueDimiAsIntegerDimItemName1,BufferType,strAddrIndexNoDot,strAddrIndexDotAsStringDimstrAddress,strAddressConverted,strAddrIndexAsStringDimCharInputAsStringDimAddrStrTotalLen,BufferTypeLen,AddrIndexLenAsIntegerDimiStep0,iStep1,iStep2,iAddrIndex,iIndexDotPosAsIntegerDimIsBitTypeAsBooleanDimstrIndexIntPart,strIndexDecPartAsStringDimiIndexIntPart,iIndexDecPartAsIntegerDimstrDBNo,strDBBufType,strVarTypeAsStringDimstrItemName(32767)AsStringDimCountAsIntegerCount=1IsBitType=False'm_OpcStartAddress=Text1.Text'獲得OPC起始地址字符AddrStrTotalLen=Len(m_OpcStartAddress)'獲得OPC起始地址字符長度'------------------獲得寄存器類型字符------------------------'ForiStep2=1ToAddrStrTotalLenCharInput=Mid(m_OpcStartAddress,iStep2,1)If((Asc(CharInput)>=65AndAsc(CharInput)<=90)Or(Asc(CharInput)>=97AndAsc(CharInput)<=122))ThenBufferType=BufferType+CharInputElse33裝配與檢測自動化事業部BufferTypeLen=iStep2-1ExitForEndIfNextiStep2BufferType=UCase(BufferType)'寄存器類型字符變大寫'----------------------獲得地址數據字符---------------------'ForiStep0=AddrStrTotalLenTo1Step-1CharInput=Mid(m_OpcStartAddress,iStep0,1)If((Asc(CharInput)>=48AndAsc(CharInput)<=57)OrAsc(CharInput)=46)ThenstrAddrIndexDot=CharInput+strAddrIndexDotElseAddrIndexLen=AddrStrTotalLen-iStep0ExitForEndIfNextiStep0ForiStep1=1ToAddrIndexLenCharInput=Mid(strAddrIndexDot,iStep1,1)If((Asc(CharInput)>=48AndAsc(CharInput)<=57))ThenstrAddrIndexNoDot=strAddrIndexNoDot+CharInputElseIsBitType=TrueEndIfNextiStep1IfIsBitType=TrueTheniIndexDecPart=Val(Right(strAddrIndexNoDot,1))
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年甘肅省武威市-嘉峪關市-臨夏州中考歷史試題(含答案)
- 工業園區的物流配送規劃優化實踐分享
- 工業廢水處理技術與工藝研究
- 工業控制系統中智能傳感器的應用
- 工業機器人結構設計與應用
- 工業自動化中新材料的作用
- 工業自動化中電池技術的運用
- 工業視頻監控中的智能識別技術應用
- 工業節能與余熱回收利用
- 工業生產與環保的和諧共生
- 第九屆全國大學生化學實驗邀請賽筆試試題
- 熱管理技術詳述
- 推薦《史蒂夫·喬布斯傳》
- 應急演練評估表、評價表、評審表(模板)
- 系統集成項目總體服務方案
- CRH2動車組制動系統常見故障及處理方法
- 國開《色彩》形考任務第1-4章及答案
- 2004浙S1、S2、S3砌磚化糞池
- 熱電廠管道防腐保溫施工方案
- 骨髓穿刺術培訓教案
- 《供應鏈管理》期末考試復習題庫(含答案)
評論
0/150
提交評論