版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
/OPC客户端的自动化实现OPC是建立在COM,DCOM的基础商的,因此绝大多数语言都可以很好的进行开发.在Net中开发客户端有以下几种方式:(1)
使用OPCNetAPI,需要用到OPCNetAPI.dll,.dll(2)
使用自动化接口,需要用到OPCDAAuto.dll(3)
使用自定义接口,需要用到多个Wrapper:OpcRcw。Ae。dll,OpcRcw。Batch.dll,n.dll,OpcRcw.Da.dll,OpcRcw。Dx.dll,OpcRcw。Hda。dll,OpcRcw.Sec.dll以上开发方式所需的动态链接库可以从OPC基金会()的网站上下载,一些下载项目可能需要注册,或成为基金会的成员。不同的方式有各自的有缺点,请参见…本文使用自动化接口,VB.Net语言进行开发,开发项目是无线射频(RFID)卡方面的应用,典型的如公交车,或公司考勤使用的刷卡机.需要注意的是自动化接口存在一个“不是问题”的问题,数组下标是以1开始的,而不是传统计算机开发上的以0开始.不知道设计者头脑是怎么想(有人知道吗?);这可能会给一些语言的开发造成问题(有人碰到吗,没有你就是幸运的)需求:OPCDAAuto。dll或该Dll的Interop(一)
:客户端开发流程OPC客户端的开发主要遵循下图所示的开发流程,下面就从以下几个开发步骤进行说明
ﻫ
(二)
:枚举OPC服务器列表枚举服务器主要是通过OPCServer接口的GetOPCServers方法来实现的,该方法会返回OPC服务器数组(以1为下界,上面已有说明),以下是代码段'枚举OPC服务器列表PrivateSubForm1_Load(ByValsenderAsSystem。Object,ByValeAsSystem。EventArgs)HandlesMyBase.LoadTryGlobalOPCServer=NewOPCAutomation。OPCServerClass()DimServerListAsObject=GlobalOPCServer。GetOPCServersForindexAsShort=LBound(ServerList)ToUBound(ServerList)’加入控件列表中,注意这里使用LBound和UBoundcbbServerList。Items.Add(ServerList(index))NextIfcbbServerList.Items.Count>0ThencbbServerList.SelectedIndex=0EndIfResetControlStatus()'设置控件状态GlobalOPCServer=NothingCatchExAsExceptionMessageBox.Show("ListOPCserversfailed:"+Ex。Message,"OPCSample",MessageBoxButtons。OK)EndTryEndSub(三)
:连接OPC服务器自动化接口中连接到服务器是使用connect方法PublicOverridableSubConnect(ByValProgIDAsString,OptionalByValNodeAsObject=Nothing)ProgID指服务器的ProgID,Node代表网络节点,如果是本机则放空即可。连接到服务器后,以下属性需要特别注意:OPCServer.StartTime:服务器的启动时间OPCServer。CurrentTime:服务器的当前时间,各个客户端可以通过这个属性值完成一些同步的操作OPCGroups.DefaultGroupIsActive:以后添加的Group是否默认激活OPCGroups。DefaultGroupDeadBand:Group的默认死区,变化量超过死区后将会触发DataChange事件,合理的设置该值可以提高程序性能OPCGroups.Count:下属组(Group)的数量OPCGroups.DefaultGroupLocalID:组(Group)的默认通信区域编号,如1024OPCGroups.DefaultGroupUpdateRate:组(Group)的默认刷新率,该属性也比较重要OPCGroups。DefaultGroupTimeBias:组(Group)的默认时间偏差(四)
:添加组(Group)和项(Item)添加组和项需要用到Groups.Add和Items。AddItem方法,以下是原型:FunctionAdd(OptionalByValNameAsObject=Nothing)AsOPCAutomation。OPCGroupFunctionAddItem(ByValItemIDAsString,ByValClientHandleAsInteger)AsOPCAutomation.OPCItem 组也有两个重要的属性 Group.UpdateRate:刷新率,该属性通Groups的UpdateRate意义一样,如果这个值有设置,则以这个值为准 Group。IsSubscribed:是否使用订阅功能 以下是代码段ﻩ'连接到指定的OPC服务器PrivateSubbtnConnectServer_Click(ByValsenderAsSystem.Object,ByValeAsSystem.EventArgs)HandlesbtnConnectServer.ClickIfcbbServerList.Text<>""ThenConnectedOPCServer=NewOPCAutomation.OPCServerClass()TryConnectedOPCServer.Connect(cbbServerList.Text)'设置组集合的默认属性ConnectedOPCServer。OPCGroups。DefaultGroupIsActive=TrueConnectedOPCServer.OPCGroups.DefaultGroupDeadband=0'添加组ConnectedGroup=ConnectedOPCServer.OPCGroups。Add()ConnectedGroup。UpdateRate=3*1000'刷新虑,用于下面的DataChange事件ConnectedGroup.IsSubscribed=True'使用订阅功能'添加项GlobalOPCItems(0)=ConnectedGroup.OPCItems.AddItem("Reader_Device.OpenCard",0)GlobalOPCItems(1)=ConnectedGroup.OPCItems。AddItem("Reader_Device.CloseCard”,1)GlobalOPCItems(2)=ConnectedGroup.OPCItems.AddItem("ReaderdNO”,2)RefreshServerStatus()'刷新服务器状态CatchexAsExceptionConnectedOPCServer=NothingMessageBox。Show("OPCserverconnectfailed:”+ex。Message,"OPCSample”,MessageBoxButtons.OK)EndTryResetControlStatus()EndIfEndSub(五)
:读写操作与事件控制读写操作包括同步和异步两种操作方式,以下是这几个方法的原型:Group的同步读事件SubSyncRead(ByValSourceAsShort,ByValNumItemsAsInteger,ByRefServerHandlesAsSystem。Array,ByRefValuesAsSystem。Array,ByRefErrorsAsSystem.Array,OptionalByRefQualitiesAsObject=Nothing,OptionalByRefTimeStampsAsObject=Nothing)
Group的同步写事件SubSyncWrite(ByValNumItemsAsInteger,ByRefServerHandlesAsSystem.Array,ByRefValuesAsSystem.Array,ByRefErrorsAsSystem。Array)
Group的异步读事件SubAsyncRead(ByValNumItemsAsInteger,ByRefServerHandlesAsSystem.Array,ByRefErrorsAsSystem。Array,ByValTransactionIDAsInteger,ByRefCancelIDAsInteger)
Group的异步写事件SubAsyncWrite(ByValNumItemsAsInteger,ByRefServerHandlesAsSystem.Array,ByRefValuesAsSystem。Array,ByRefErrorsAsSystem.Array,ByValTransactionIDAsInteger,ByRefCancelIDAsInteger)如果使用异步的读写操作,那么还需要实现Group中的ReadComplete和WriteComplete两个事件PublicEventAsyncReadComplete(ByValTransactionIDAsInteger,ByValNumItemsAsInteger,ByRefClientHandlesAsSystem。Array,ByRefItemValuesAsSystem.Array,ByRefQualitiesAsSystem。Array,ByRefTimeStampsAsSystem.Array,ByRefErrorsAsSystem.Array)
PublicEventAsyncWriteComplete(ByValTransactionIDAsInteger,ByValNumItemsAsInteger,ByRefClientHandlesAsSystem.Array,ByRefErrorsAsSystem.Array)其他相关的重要事件包括:Group数据变化时的通知事件PublicEventDataChange(ByValTransactionIDAsInteger,ByValNumItemsAsInteger,ByRefClientHandlesAsSystem.Array,ByRefItemValuesAsSystem。Array,ByRefQualitiesAsSystem.Array,ByRefTimeStampsAsSystem.Array)
Group的异步取消事件PublicEventAsyncCancelComplete(ByValCancelIDAsInteger)
Server(服务器)关闭通知事件PublicEventServerShutDown(ByValReasonAsString)
以下是这些实现的代码段'读取卡片指定的块号的值PrivateSubbtnReadCard_Click(ByValsenderAsSystem。Object,ByValeAsSystem.EventArgs)IfNot(ConnectedGroupIsNothing)ThenTry’获取块号DimBlockNoAsShort=CByte(ReadBlockNo.Text)’如果要获取数据的块所对应的项还没有创建,就创建它IfGlobalOPCBlockItems(BlockNo)IsNothingThenGlobalOPCBlockItems(BlockNo)=ConnectedGroup.OPCItems。AddItem("Reader_Device.Block"&CStr(BlockNo),200+BlockNo)EndIf'准备参数数组DimServerResultsAsSystem。ArrayDimServerErrorsAsSystem。ArrayDimServerHandles(1)AsIntegerServerHandles(1)=GlobalOPCBlockItems(BlockNo).ServerHandle’读取值ConnectedGroup.SyncRead(OPCAutomation.OPCDataSource.OPCDevice,1,ServerHandles,ServerResults,ServerErrors)IfServerErrors(1)<>0ThenMsgBox("ReadCardFailed:"&ServerErrors(1))ElsetxtReadBlockNo.Text=ServerResults(1)EndIfCatchexAsExceptionMessageBox.Show("OPCserverReadCardfailed:"+ex.Message,"OPCSample",MessageBoxButtons.OK)EndTryEndIfEndSub
’写卡片指定块的值PrivateSubbtnWriteCard_Click(ByValsenderAsSystem.Object,ByValeAsSystem。EventArgs)IfNot(ConnectedGroupIsNothing)ThenTry'获取块号DimBlockNoAsShort=CByte(WriteBlockNo.Text)'如果要写入数据的块所对应的项还没有创建,就创建它IfGlobalOPCBlockItems(BlockNo)IsNothingThenGlobalOPCBlockItems(BlockNo)=ConnectedGroup.OPCItems.AddItem(”Reader_Device.Block"&CStr(BlockNo),200+BlockNo)EndIf'准备参数数组DimServerValues(1)AsObjectDimServerErrorsAsArrayDimServerHandles(1)AsIntegerServerHandles(1)=GlobalOPCBlockItems(BlockNo).ServerHandleServerValues(1)=txtWriteBlockNo。Text’写入值ConnectedGroup。SyncWrite(1,ServerHandles,ServerValues,ServerErrors)IfServerErrors(1)〈>0ThenMsgBox(”WriteCardFailed:"&ServerErrors(1))ElseMsgBox(”WriteCardSucceed")EndIfCatchexAsExceptionMessageBox。Show("OPCserverWriteCardfailed:"+ex.Message,”OPCSample”,MessageBoxButtons。OK)EndTryEndIfEndSub(六)
:断开服务器断开服务器只要使用OPCServer的Disconnect方法几个,以下是代码段:'断开到指定OPC服务器的连接PrivateSubbtnDisconnectServer_Click(ByValsenderAsSystem.Object,ByValeAsSystem.EventArgs)HandlesbtnDisconnectServer.ClickIfNot(ConnectedOPCServerIsNothing)ThenTryConnectedOPCServer。Disconnect()CatchexAsExceptionMessageBox.Show(”OPCserverdisconnectfailed:”+ex。Message,”OPCSample”,MessageBoxButtons.OK)FinallyConnectedOPCServer=NothingResetControlStatus()EndTryEndIfEndSub(七)
:相关链接非常好的一个OPC技术网站OPC基金会网址国内的一个比较好的OPC网站(八):全部源码Imports
System.Runtime。InteropServicesﻫPublic
Class
Form1ﻫ
Dim
GlobalOPCServer
As
OPCAutomation。OPCServerClass
Dim
WithEvents
ConnectedOPCServer
As
OPCAutomation。OPCServerClass
Dim
WithEvents
ConnectedGroup
As
OPCAutomation.OPCGroupClass
ﻫ
Dim
GlobalOPCItems(4)
As
OPCAutomation。OPCItem
Dim
GlobalOPCBlockItems(64)
As
OPCAutomation.OPCItem
ﻫﻫ
'枚举OPC服务器列表ﻫ
Private
Sub
Form1_Load(ByVal
sender
As
System。Object,
ByVal
e
As
System。EventArgs)
Handles
MyBase。Load
Tryﻫ
GlobalOPCServer
=
New
OPCAutomation。OPCServerClass()
Dim
ServerList
As
Object
=
GlobalOPCServer.GetOPCServersﻫ
For
index
As
Short
=
LBound(ServerList)
To
UBound(ServerList)
’加入控件列表中,注意这里使用LBound和UBound
cbbServerList.Items.Add(ServerList(index))
Next
If
cbbServerList.Items。Count
>
0
Then
cbbServerList.SelectedIndex
=
0ﻫ
End
If
ResetControlStatus()
'设置控件状态
GlobalOPCServer
=
Nothingﻫ
Catch
Ex
As
Exception
MessageBox。Show("List
OPC
servers
failed:
”
+
Ex.Message,
"OPCSample”,
MessageBoxButtons.OK)ﻫ
End
Tryﻫ
End
Subﻫ
’连接到指定的OPC服务器ﻫ
Private
Sub
btnConnectServer_Click(ByVal
sender
As
System.Object,
ByVal
e
As
System.EventArgs)
Handles
btnConnectServer。Clickﻫ
If
cbbServerList。Text
<〉
""
Thenﻫ
ConnectedOPCServer
=
New
OPCAutomation.OPCServerClass()ﻫ
Tryﻫ
ConnectedOPCServer。Connect(cbbServerList。Text)ﻫ
’设置组集合的默认属性
ConnectedOPCServer。OPCGroups.DefaultGroupIsActive
=
Trueﻫ
ConnectedOPCServer.OPCGroups.DefaultGroupDeadband
=
0ﻫ
’添加组
ConnectedGroup
=
ConnectedOPCServer。OPCGroups.Add()
ConnectedGroup.UpdateRate
=
3
*
1000
'刷新虑,用于下面的DataChange事件ﻫ
ConnectedGroup.IsSubscribed
=
True
'使用订阅功能ﻫ
'添加项
GlobalOPCItems(0)
=
ConnectedGroup.OPCItems.AddItem("Reader_Device。OpenCard",
0)ﻫ
GlobalOPCItems(1)
=
ConnectedGroup.OPCItems.AddItem("Reader_Device。CloseCard”,
1)
GlobalOPCItems(2)
=
ConnectedGroup.OPCItems。AddItem("ReaderdNO",
2)ﻫ
RefreshServerStatus()
’刷新服务器状态ﻫ
Catch
ex
As
Exceptionﻫ
ConnectedOPCServer
=
Nothing
MessageBox.Show("OPC
server
connect
failed
:
"
+
ex.Message,
”OPCSample",
MessageBoxButtons.OK)
End
Try
ResetControlStatus()
End
If
End
Subﻫ
’服务器断开事件通知
Private
Sub
OnServerShutDown(ByVal
Reason
As
String)
Handles
ConnectedOPCServer。ServerShutDownﻫ
btnDisconnectServer_Click(Nothing,
New
EventArgs())ﻫ
End
Sub
ﻫ
Private
Sub
OnGroupDataChange(ByVal
TransactionID
As
Integer,
ByVal
NumItems
As
Integer,
ByRef
ClientHandles
As
System。Array,
ByRef
ItemValues
As
System.Array,
ByRef
Qualities
As
System.Array,
ByRef
TimeStamps
As
System.Array)
Handles
ConnectedGroup.DataChangeﻫ
For
i
As
Integer
=
1
To
NumItems
If
Qualities(i)
=
OPCAutomation。OPCQuality.OPCQualityGood
Thenﻫ
Select
Case
ClientHandles(i)
Case
2ﻫ
txtCardNo.Text
=
CStr(ItemValues(i))
Case
200
'测试7张卡片
txtValueBlock0.Text
=
CStr(ItemValues(i))
Case
201
txtValueBlock1。Text
=
CStr(ItemValues(i))
Case
202ﻫ
txtValueBlock2。Text
=
CStr(ItemValues(i))
Case
203
txtValueBlock3.Text
=
CStr(ItemValues(i))
Case
204ﻫ
txtValueBlock4.Text
=
CStr(ItemValues(i))ﻫ
Case
205
txtValueBlock5.Text
=
CStr(ItemValues(i))
Case
206ﻫ
txtValueBlock6。Text
=
CStr(ItemValues(i))ﻫ
Case
207
txtValueBlock7。Text
=
CStr(ItemValues(i))
Case
Elseﻫ
End
Select
ﻫ
End
If
Next
End
Sub
ﻫﻫ
’断开到指定OPC服务器的连接ﻫ
Private
Sub
btnDisconnectServer_Click(ByVal
sender
As
System.Object,
ByVal
e
As
System.EventArgs)
Handles
btnDisconnectServer.Clickﻫ
If
Not
(ConnectedOPCServer
Is
Nothing)
Thenﻫ
Tryﻫ
ConnectedOPCServer.Disconnect()ﻫ
Catch
ex
As
Exception
MessageBox.Show("OPC
server
disconnect
failed:
"
+
ex.Message,
”OPCSample",
MessageBoxButtons.OK)
Finallyﻫ
ConnectedOPCServer
=
Nothingﻫ
ResetControlStatus()ﻫ
End
Tryﻫ
End
Ifﻫ
End
Sub
ﻫ
’开卡,并返回卡号
Private
Sub
btnOpenCard_Click(ByVal
sender
As
System.Object,
ByVal
e
As
System.EventArgs)ﻫ
If
ConnectedGroup
IsNot
Nothing
Then
Tryﻫ
'准备参数数组
Dim
ServerHandles(1)
As
Integer
Dim
ServerValues(1)
As
Object
Dim
ServerErrors
As
System。Arrayﻫ
ServerHandles(1)
=
GlobalOPCItems(0)。ServerHandleﻫ
ServerValues(1)
=
1
'写入值,用于执行OpenCard的操作ﻫ
ConnectedGroup.SyncWrite(1,
ServerHandles,
ServerValues,
ServerErrors)
If
ServerErrors(1)
<>
0
Then
MsgBox("OpenCardError:
”
&
ServerErrors(1))
End
If
ServerHandles(1)
=
GlobalOPCItems(2).ServerHandleﻫ
Dim
ServerResult
As
System。Array
'读取卡号ﻫ
ConnectedGroup.SyncRead(OPCAutomation.OPCDataSource.OPCDevice,
1,
ServerHandles,
ServerResult,
ServerErrors)ﻫ
If
ServerErrors(1)
〈>
0
Thenﻫ
MsgBox("ReadCardNoError:
”
&
ServerErrors(1))ﻫ
Elseﻫ
txtCardNo。Text
=
ServerResult(1)ﻫ
End
If
Catch
ex
As
Exception
MessageBox.Show("OPC
server
Open
Card
failed:
”
+
ex。Message,
”OPCSample",
MessageBoxButtons.OK)
End
Try
ResetControlStatus()
End
Ifﻫ
End
Subﻫﻫ
'读取卡片指定的块号的值
Private
Sub
btnReadCard_Click(ByVal
sender
As
System.Object,
ByVal
e
As
System.EventArgs)ﻫ
If
Not
(ConnectedGroup
Is
Nothing)
Thenﻫ
Try
'获取块号
Dim
BlockNo
As
Short
=
CByte(ReadBlockNo。Text)
'如果要获取数据的块所对应的项还没有创建,就创建它
If
GlobalOPCBlockItems(BlockNo)
Is
Nothing
Thenﻫ
GlobalOPCBlockItems(BlockNo)
=
ConnectedGroup.OPCItems.AddItem(”Reader_Device.Block"
&
CStr(BlockNo),
200
+
BlockNo)
End
If
'准备参数数组
Dim
ServerResults
As
System.Arrayﻫ
Dim
ServerErrors
As
System.Arrayﻫ
Dim
ServerHandles(1)
As
Integerﻫ
ServerHandles(1)
=
GlobalOPCBlockItems(BlockNo).ServerHandle
’读取值
ConnectedGroup。SyncRead(OPCAutomation.OPCDataSource.OPCDevice,
1,
ServerHandles,
ServerResults,
ServerErrors)ﻫ
If
ServerErrors(1)
〈>
0
Thenﻫ
MsgBox("Read
Card
Failed:"
&
ServerErrors(1))
Elseﻫ
txtReadBlockNo.Text
=
ServerResults(1)
End
Ifﻫ
Catch
ex
As
Exceptionﻫ
MessageBox.Show(”OPC
server
Read
Card
failed:
"
+
ex.Message,
"OPCSample”,
MessageBoxButtons.OK)ﻫ
End
Try
End
If
End
Subﻫﻫ
’写卡片指定块的值ﻫ
Private
Sub
btnWriteCard_Click(ByVal
sender
As
System。Object,
ByVal
e
As
System.EventArgs)ﻫ
If
Not
(ConnectedGroup
Is
Nothing)
Then
Try
’获取块号
Dim
BlockNo
As
Short
=
CByte(WriteBlockNo.Text)ﻫ
’如果要写入数据的块所对应的项还没有创建,就创建它ﻫ
If
GlobalOPCBlockItems(BlockNo)
Is
Nothing
Thenﻫ
GlobalOPCBlockItems(BlockNo)
=
ConnectedGroup。OPCItems.AddItem(”Reader_Device.Block”
&
CStr(BlockNo),
200
+
BlockNo)ﻫ
End
If
’准备参数数组
Dim
ServerValues(1)
As
Objectﻫ
Dim
ServerErrors
As
Array
Dim
ServerHandles(1)
As
Integer
ServerHandles(1)
=
GlobalOPCBlockItems(BlockNo)。ServerHandle
ServerValues(1)
=
txtWriteBlockNo。Text
’写入值ﻫ
ConnectedGroup.SyncWrite(1,
ServerHandles,
ServerValues,
ServerErrors)ﻫ
If
ServerErrors(1)
<〉
0
Thenﻫ
MsgBox(”Write
Card
Failed:"
&
ServerErrors(1))ﻫ
Else
MsgBox("Write
Card
Succeed”)ﻫ
End
Ifﻫ
Catch
ex
As
Exceptionﻫ
MessageBox.Show(”OPC
server
Write
Card
failed:
"
+
ex.Message,
”OPCSample”,
MessageBoxButtons。OK)
End
Tryﻫ
End
If
End
Sub
'重设控件状态
Private
Sub
ResetControlStatus()ﻫ
If
ConnectedOPCServer
Is
Nothing
Thenﻫ
btnConnectServer.Enabled
=
True
btnDisconnectServer.Enabled
=
False
btnReadCard.Enabled
=
False
btnWriteCard。Enabled
=
Falseﻫ
btnOpenCard。Enabled
=
Falseﻫ
btnCloseCard.Enabled
=
False
ReadBlockNo.Value
=
0ﻫ
WriteBlockNo.Value
=
0
txtReadBlockNo.Text
=
”"
txtWriteBlockNo.Text
=
”0000000000”
txtCardNo.Text
=
""
ﻫ
txtSrvStartTime.Text
=
""
txtSrvCurrTime.Text
=
”"
txtSrvGroupCount。Text
=
""ﻫ
txtSrvGroupDeadBand.Text
=
""
txtSrvGroupDefActive。Text
=
""ﻫ
txtSrvGroupLocalID。Text
=
”"ﻫ
txtSrvGroupTimeBias.Text
=
""
txtSrvRequestRate.Text
=
""ﻫ
Else
btnConnectServer.Enabled
=
Falseﻫ
btnDisconnectServer.Enabled
=
Trueﻫ
If
txtCardNo.Text
=
””
Then
btnReadCard。Enabled
=
False
btnWriteCard.Enabled
=
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 煤矿安全承诺书集锦七篇
- 2024年铁路轨枕垫合作协议书
- 娄底市涟源市2024年数学四下期末调研模拟试题含解析
- 六盘水市2024届数学四下期末检测模拟试题含解析
- 2024年单晶生产炉项目合作计划书
- 陵水黎族自治县2024年数学四下期末质量检测试题含解析
- 2024年商超货架项目合作计划书
- 2024年紫外线强度观测仪器项目建议书
- 临潭县2024年四年级数学第二学期期末监测试题含解析
- 2024年氢氧化亚镍项目发展计划
- 模拟联合国介绍-课件
- 个人所得税课程设计
- 【培训】统编高中语文教材使用建议
- ICU床旁交接班清单
- 2020年AMC8真题及答案(中文版)
- 2023年清华大学考博英语真题及答案详解
- 国家自然科学基金标书写作课件
- 表单:纳税人办税授权委托书
- 英语泛读教程2(王守仁)答案
- 《Google-Cash》快速致富手册(中文版)
- 律师手稿:公司常年法律顾问报价单模板
评论
0/150
提交评论