1:项目前提:上海市排水公司积水点监测系统升级,现有DDE服务,那只能通过DDECLIENT去访问了。客户又是要求B/S系统,这次又是放弃C/S系统进行开发.现在:整个项目使用 "设备" - DDESERVER - DDEClient - 中间件 - WEB 这样一个架构.(该项目已通过城投公司领导的汇报确认)
2:特点,主要完成DdeClient,与中间件服务业务功能.而中间件的服务主要是将数据提供给B/S
DDE思路:通过Advise动态交换DDE服务上的数据,通过POKE向DDE服务写数据,用于反控与参数设置!
注意:DDE API需要用户调用API自己封装,点NET并不提供DDE的开发模块!
3:内部运行的图,可参考“OPC的开发”,http://blog.csdn.net/zerodj/archive/2006/01/25/588289.aspx
4:DDE得到数据后,使用特定的公式转换出实际需要显示的数据!
5:DDE上Advise的事件
private static void MyClient_Advise(object sender, DdeClient.AdviseEventArgs args)
{
string sPrmValue = System.Text.Encoding.ASCII.GetString(args.Data).Replace(System.Environment.NewLine, "");
string sPrmName = args.Item;
string sWhere = "PENAME = '" + sPrmName.Replace("'","''") + "'";
DataRow[] dRows = null;
lock(ddeParams.PARAMSINFO) //动态内存数据表
{
dRows = ddeParams.PARAMSINFO.Select(sWhere);
}
if(dRows == null)return;
lock(dRows)
{
foreach(DataRow dRow in dRows)
{
#region 如果是积水点的液位数据,需要转换陪率
//如果是积水点的液位数据,需要转换陪率
if(Convert.ToInt32(dRow["BWaterPOS"]) == 1)
{
//得到积水点编号
string sPSID = dRow[ddeParams.PARAMSINFO.PS_IDColumn].ToString();
sWhere = "PS_ID = " + sPSID;
DataRow[] StaRows = ddeParams.STATIONINFO.Select(sWhere);
//取得陪率
if(StaRows.Length == 0)continue;
DataRow StaRow = StaRows[0];
float fScale = 1;
float fMinVAL = 0; //最小工程量
if(StaRow["STASCALE"] != System.DBNull.Value)fScale = Convert.ToSingle(StaRow["STASCALE"]);
if(StaRow["MINVAL"] != System.DBNull.Value)fMinVAL = Convert.ToSingle(StaRow["MINVAL"]);
if(Convert.ToInt32(dRow["BSCALE"]) == 1) //转换陪率
sPrmValue = (Convert.ToSingle(sPrmValue) * fScale - fMinVAL).ToString("f2");
else
sPrmValue = Convert.ToSingle(sPrmValue).ToString("f2");
}
#endregion
#region 比较是否发生警告
//得到警告范围
bool bHappendWarn = false; //是否发生警告
if(Convert.ToInt32(dRow["BALM"])==1)
{
if(!dRow.IsNull(ddeParams.PARAMSINFO.HIALMColumn) && !dRow.IsNull(ddeParams.PARAMSINFO.LOALMColumn))
{
try
{
float fHI = Convert.ToSingle(dRow["HIALM"]);
float fLW = Convert.ToSingle(dRow["LOALM"]);
float dPrmValue = Convert.ToSingle(sPrmValue);
if(fHI != fLW)
{
if(Convert.ToDouble(sPrmValue) !=0 )
{
if(dPrmValue >= fHI || dPrmValue <= fLW)
{
//报警的值
int iPSID = Convert.ToInt32(dRow["PS_ID"]);
string sPKID = dRow["PKID"].ToString(); //参数关键字
WriteWarnValue(iPSID,sPrmValue,sPKID);
bHappendWarn = true; //已经发生Warnning
}
else
bHappendWarn = false; //没有发生Warnning
}
}
else
{
if(dPrmValue != fHI)
{
//报警的值
int iPSID = Convert.ToInt32(dRow["PS_ID"]);
string sPKID = dRow["PKID"].ToString(); //参数关键字
WriteWarnValue(iPSID,sPrmValue,sPKID); //记录警告值
bHappendWarn = true; //已经发生Warnning
}
else
bHappendWarn = false; //没有发生Warnning
}
}
catch(Exception ex)
{
//Debug.WriteLine(ex.Message);
dClient.ErrLog.WriteMessage("有无产生报警时,数据比较,发生错误:"+ex.Message,true);
}
}
}
#endregion
//更新积水点实时数据
dRow[ddeParams.PARAMSINFO.PsValueColumn] = sPrmValue;
//更新警告标志
if(bHappendWarn)
dRow[ddeParams.PARAMSINFO.HappendWarnColumn] = 1;
else
dRow[ddeParams.PARAMSINFO.HappendWarnColumn] = 0;
}
}
//Debug.WriteLine(args.Item + "/t" +System.Text.Encoding.ASCII.GetString(args.Data).Replace("/r/n", ""));
//Debug.WriteLine("");
//历史记录调用存储,放到ORACLE表SCADA_DATA中
try
{
OracleCommand oraCmd = new OracleCommand();
oraCmd.CommandText = "jsdHIS"; //需读者自己开发JAVA存储过程或PL/SQL存储过程,此处的是JAVA存储过程
oraCmd.CommandType = CommandType.StoredProcedure;
oraCmd.Connection = oraConn;
oraCmd.ExecuteNonQuery();
oraCmd.Dispose();
}
catch(Exception ex)
{
//Debug.WriteLine(ex.Message);
dClient.ErrLog.WriteMessage("调用JAVA存储过程,发生错误:"+ex.Message,true); //记录错误日志,读者自己完成
}
}
6:界面图参考(以下GUI上的上的数据,将根据DDE上的数据实时更新)