用脚本向Audit中添加记录有两种方法,一种方法是用InserAuditEntryNew函数写入,另一种方法是生成属于“操作员输入消息”类型的报警消息,该报警消息会记录到Audit中。
Audit记录中的TargetName列是操作内容,Reason列是操作员的注释。使用InserAuditEntryNew函数生成的记录在TargetName列的内容默认为VBScripting Runtime或CScripting Runtime,而操作内容只能记录在Reason列处,这与其他记录的形式不一致,效果不好,因此在此不使用InserAuditEntryNew函数。
第二种方法,在报警记录的“系统,无确认”下的“操作员输入消息”中建立报警消息,当这条消息触发后,消息不仅会记录到报警数据库,也会记录到Audit数据库。触发报警消息可以用变量触发,也可以用脚本触发。使用脚本触发可以给消息传递参数,即向@1%s@等文本块中写入值。
WinCC中默认有一条编号为12508141的操作员输入消息,定义如下图,该消息用于记录新值旧值的更改。
12508141消息的内容不完全符合Audit消息记录的需要,新建一条编号为12508142消息。项目中可能会用WinCC控制多台设备,定义文本块@10%s@的作用是记录该操作针对哪台设备,文本块@7%s@记录执行了什么操作。有些项目中不使用Audit trail组件,而是用报警记录的数据库记录审计追踪,因此可在错误点列填上@10%s@,使用报警控件查看时便于筛选。该消息定义如下:
使用C脚本生成操作员消息
WinCC支持C和VB两种脚本,C脚本中提供了GCreateMyOperationMsg()函数生成操作员消息。
函数原型:
int GCreateMyOperationMsg( DWORD dwFlags, DWORD dwMsgNum, char* lpszPictureName, char* lpszObjectName, DWORD dwMyTextID, double doValueOld, double doValueNew, char* pszComment)
参数:
- dwFlags,该参数指定如何生成注释,可用以下常量值,值可以用或运算“|”输入:
常数 | 值 | 描述 |
FLAG_COMMENT_PARAMETER | 0x00000001 | 文本在运行时直接作为消息输入,没有自己的注释对话框。对注释的指针不能等于“NULL”。 |
FLAG_COMMENT_DIALOG | 0x00000003 | 出现一个注释对话框,输入的注释被转移到消息中 |
FLAG_TEXTID_PARAMETER | 0x00000100 | 提供文本库中的一个文本ID,将文本插入到消息的过程值中。 |
- dwMsgNum,该参数为消息编号,触发该编号的消息。消息必须属于“操作员输入消息”类型,不可使用其他类型的消息。
- lpszPictureName,该参数未在函数中使用,不起任何作用。
- lpszObjectName,该参数会写入到文本块@1%s@中和szInstance属性中,szInstance属性等同于文本块@10%s@。
- dwMyTextID,该参数是文本库ID,值会被写入到值@8%g@中。如果dwFlags参数为FLAG_TEXTID_PARAMETER,会将文本库中该ID的文本写入到文本块@8%s@中。
- doValueOld,该参数是变量旧值,值会被写入到值@2%g@中,在audit中会写入到OldValue列中。
- doValueNew,该参数是变量新值,值会被写入到值@3%g@中,在audit中会写入到NewValue列中。
- pszComment,该参数是注释字符串,如果dwFlags参数为FLAG_COMMENT_PARAMETER,该字符串会写入到报警的注释中,写入到Audit的Reason列。
返回值:
值 | 描述 |
0 | 函数执行完成没有任何错误 |
-101 | 消息不能被编辑 |
-201 | 当调用"MSRTGetComment()"特征引发一个错误 |
-301 | 当调用"MSRTCreateMsgInstanceWithComment()"特征引发一个错误 |
GCreateMyOperationMsg()函数生成的消息文本中未使用文本块@7%s@,我们参考GCreateMyOperationMsg函数进行修改,重新创建一个操作员消息函数GCreateMyOperationMsg2(),该函数值用lpszMsg参数代替lpszPictureName参数,lpszMsg参数的值被写入文本块@7%s@中。GCreateMyOperationMsg2()函数配合12508142消息使用。
函数原型:
int GCreateMyOperationMsg2( DWORD dwFlags, DWORD dwMsgNum, char* lpszMsg, char* lpszObjectName, DWORD dwMyTextID, double doValueOld, double doValueNew, char* pszComment)
参数:
- lpszMsg,该参数记录操作消息,会写入文本块@7%s@中。
- 其他参数与GCreateMyOperationMsg()函数一致。
函数代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | #pragma code ("kernel32.dll") void GetLocalTime( LPSYSTEMTIME lpSystemTime); BOOL GetComputerNameA(LPSTR Computername, LPDWORD size); VOID Sleep(DWORD dwMilliseconds); //RQ:1072746 #pragma code() #define FLAG_COMMENT_PARAMETER 0x00000001 #define FLAG_COMMENT_DIALOG 0x00000003 #define FLAG_TEXTID_PARAMETER 0x00000100 int GCreateMyOperationMsg2( DWORD dwFlags, DWORD dwMsgNum, char* lpszMsg, char* lpszObjectName, DWORD dwMyTextID, double doValueOld, double doValueNew, char* pszComment ) { MSG_RTDATA_INSTANCECOMMENT_STRUCT MsgCreateEx; MSG_RTDATA_STRUCT MsgRTData; // for comment dialog CMN_ERROR scError; int iRet= FALSE; DWORD dwServiceID = 0; BOOL bOK; SYSTEMTIME time; DWORD dwBufSize = 256; char szComputerName[256] = ""; char szSource[256] = ""; char szMyText[MSG_MAX_TB_CONTENT + 1] = ""; char szTmp[256] = ""; // for diagnosis output char* pszPrefix; // to define the type of WinCC project char* lpszCurrentUser; char* lpszParent; char * pszServerPrefix; //RQ:1072746 begin DWORD dwMaxCheckTime = 5000; // max time to wait 5000ms=5sec. DWORD dwStepCheckTime = 500; // start stepping waittime with 500ms DWORD dwReduceStepTime = 100; // reduce the steptime here by 100ms DWORD dwActWaitedTime = 0; DWORD dwInx = 0; //RQ:1072746 end printf("Start GCreateMyOperationMsg \r\n"); //====================================== // INIT_MESSAGE_STRUCT //====================================== memset(&MsgCreateEx,0,sizeof(MsgCreateEx)); memset(&MsgRTData,0,sizeof(MsgRTData)); memset(&scError,0,sizeof(scError)); GetLocalTime(&time); MsgCreateEx.stMsgTime = time; MsgRTData.stMsgTime = time; MsgCreateEx.dwMsgNr = dwMsgNum; MsgRTData.dwMsgNr = dwMsgNum; MsgCreateEx.wPValueUsed = (WORD)(0x0000 ); // no real process value used MsgRTData.wPValueUsed = (WORD)(0x0000 ); MsgCreateEx.wTextValueUsed = 0x001F; // text values 1 .. 5 used for textblocks 1 .. 5 MsgRTData.wTextValueUsed = 0x001F; // text values 1 .. 5 used for textblocks 1 .. 5 MsgCreateEx.dwFlags = MSG_FLAG_TEXTVALUES; MsgRTData.dwFlags = MSG_FLAG_COMMENT | MSG_FLAG_TEXTVALUES; MsgCreateEx.dwMsgState = MSG_STATE_COME; MsgRTData.dwMsgState = MSG_STATE_COME; GetComputerNameA(szComputerName, &dwBufSize); sprintf(szTmp, "Computername = %s \r\n", szComputerName); printf(szTmp); strncpy(MsgCreateEx.szComputerName, szComputerName, sizeof(MsgCreateEx.szComputerName) -1); lpszCurrentUser = GetTagChar("@NOP::@CurrentUser"); if (NULL != lpszCurrentUser ) { strncpy( MsgCreateEx.szUser, lpszCurrentUser, sizeof (MsgCreateEx.szUser) - 1); } if ( dwFlags & FLAG_TEXTID_PARAMETER) { MsgCreateEx.dPValue[7] = dwMyTextID; // TextID MsgCreateEx.wPValueUsed = 0x0080; // for process value 8 } MsgCreateEx.wPValueUsed = (WORD)(MsgCreateEx.wPValueUsed | 0x0006); MsgCreateEx.dPValue[1] = doValueOld; // old value MsgCreateEx.dPValue[2] = doValueNew; // new value //====================================== // START_MESSAGE_SERVICE //====================================== memset(&scError,0,sizeof(scError)); // GetServerPrefix to determine MC or Server GetServerTagPrefix(&pszServerPrefix, NULL, NULL); //Return-Type: void if (NULL == pszServerPrefix) { printf("Serverapplication or Single Client\r\n"); bOK = MSRTStartMsgService( &dwServiceID, NULL, NULL, 0, NULL, &scError ); // activate service } else { printf("MultiClient with Prefix : %s\r\n",pszServerPrefix); //Return - Type :char* bOK = MSRTStartMsgServiceMC( &dwServiceID, NULL, NULL, 0, NULL,pszServerPrefix, &scError ); // activate service } if (bOK == FALSE) { printf("GCreateMyOperationMsg() - Unable to start message service! \r\n"); sprintf(szTmp, " Error1 = 0x%0x, Errortext = %s \r\n", scError.dwError1, scError.szErrorText); printf(szTmp); return (-101); } //====================================== //====================================== // PARSE PARAMETERS //====================================== if ( ( dwFlags & FLAG_COMMENT_PARAMETER ) && ( NULL != pszComment ) ) { strncpy(MsgCreateEx.szComment, pszComment, sizeof (MsgCreateEx.szComment) - 1); MsgCreateEx.dwFlags |= MSG_FLAG_COMMENT; } if ( dwFlags & FLAG_COMMENT_DIALOG ) MsgCreateEx.dwFlags |= MSG_FLAG_COMMENT; if (lpszObjectName!= NULL) // = tagname { strncpy (szSource, lpszObjectName, sizeof (lpszObjectName) - 1); strncpy ( MsgCreateEx.szInstance, lpszObjectName, sizeof (MsgCreateEx.szInstance) - 1); strncpy ( MsgCreateEx.mtTextValue[0].szText, lpszObjectName, sizeof (MsgCreateEx.mtTextValue[1].szText) - 1); } if ( szMyText != NULL) { strncpy ( MsgCreateEx.mtTextValue[1].szText, szMyText , sizeof (MsgCreateEx.mtTextValue[1].szText) - 1); } if ( lpszMsg != NULL) { strncpy ( MsgCreateEx.mtTextValue[6].szText, lpszMsg , sizeof (MsgCreateEx.mtTextValue[6].szText) - 1); } //====================================== //====================================== // CREATE MESSAGE //====================================== bOK = MSRTCreateMsgInstanceWithComment(dwServiceID, &MsgCreateEx, &scError) ; if ( TRUE == bOK) { if (FLAG_COMMENT_DIALOG == (dwFlags & FLAG_COMMENT_DIALOG) ) { BOOL bOkay; HWND hWnd = FindWindow("PDLRTisAliveAndWaitsForYou", NULL); //RQ:1072746 begin MSG_COMMENT_STRUCT mComment; sprintf( mComment.szUser, MsgCreateEx.szUser, sizeof(mComment.szUser) - 1 ); for (dwInx = 1; dwActWaitedTime < dwMaxCheckTime; dwInx++) { memset(&scError,0,sizeof(scError)); mComment.dwMsgNr = dwMsgNum; mComment.stTime = time; bOkay = MSRTGetComment (dwServiceID, &mComment, &scError); if (TRUE == bOkay) { break; } else { Sleep(dwStepCheckTime); printf("#W401: GCreateMyOperationMsg(): pre MSRTGetComment() performance warning: waited=%ld / step=%ld/ round=%ld\r\n", dwActWaitedTime+dwStepCheckTime, dwStepCheckTime, dwInx); } dwActWaitedTime += dwStepCheckTime; if (100 < dwStepCheckTime) { dwStepCheckTime -=dwReduceStepTime; } } //RQ:1072746 memset(&scError,0,sizeof(scError)); bOkay= MSRTDialogComment (hWnd, &MsgRTData, &scError); if (TRUE == bOkay) { //MSG_COMMENT_STRUCT mComment; //RQ:1072746 mComment.dwMsgNr = dwMsgNum; mComment.stTime = time; sprintf( mComment.szUser, MsgCreateEx.szUser, sizeof(mComment.szUser) - 1 ); memset(&scError,0,sizeof(scError)); bOkay = MSRTGetComment (dwServiceID, &mComment, &scError); if (TRUE == bOkay) { strncpy(MsgCreateEx.szComment, mComment.szText, sizeof (MsgCreateEx.szComment) - 1); } } else { printf("#E201: GCreateMyOperationMsg() - Error at MSRTGetComment() szErrorText=\"%s\" error2=%d\r\n", scError.szErrorText, scError.dwError2); iRet = -201; } } } if(bOK == FALSE) { printf ("#E301: GCreateMyOperationMsg() - Error at MSRTCreateMsgInstanceWithComment() szErrorText=\"%s\"\r\n", scError.szErrorText); iRet = -301; } //====================================== //====================================== // STOP_MESSAGE_SERVICE //====================================== bOK= MSRTStopMsgService( dwServiceID, &scError); printf("End GCreateMyOperationMsg \r\n"); return (iRet); } |
C脚本操作员消息函数二次封装
在不要电子签名只需记录操作消息的地方,为了更方便使用,对函数进行二次封装为函数CreateMyOpMsg()。
函数原型:
int CreateMyOpMsg(char* lpszMsg, char* lpszdevice)
参数:
- lpszMsg,该参数记录操作消息,写入文本块@7%s@中。
- lpszdevice,该参数为设备名,写入到文本块@10%s@中。
返回值:
值 | 描述 |
0 | 函数执行完成没有任何错误 |
-101 | 消息不能被编辑 |
-201 | 当调用"MSRTGetComment()"特征引发一个错误 |
-301 | 当调用"MSRTCreateMsgInstanceWithComment()"特征引发一个错误 |
函数代码:
1 2 3 4 5 6 7 | #include "apdefap.h" int CreateMyOpMsg(char* lpszMsg, char* lpszdevice) { char userComm[1024]=""; return GCreateMyOperationMsg2(0x00000001 ,12508142 , lpszMsg, lpszdevice, 0, 0 , 0 , userComm); //Return-Type: long int } |
用VB脚本生成操作员消息
使用VB脚本创建操作员消息的脚本如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | '创建操作员消息 dim myAlarm Set myAlarm = HMIRuntime.Alarms(12508142) MyAlarm.State = 5 '-------------------------- 'State Alarm Log Status '1 Came In '2 Went Out '5 Came in and comment '6 Gone and comment '-------------------------- myAlarm.Comment = userComment myAlarm.UserName = userName myAlarm.ProcessValues(10) = Device myAlarm.ProcessValues(7) = Msg MyAlarm.Create |
注意:使用VBS生成的操作员消息,在报警记录中没有计算机名。
VB脚本操作员消息函数二次封装
在不要电子签名只需记录操作消息的地方,为了更方便使用,对函数进行二次封装为函数CreateMyOpMsg()。
函数原型:
Function CreateMyOpMsg(inputMsg, device)
参数:
- inputMsg,该参数记录操作消息,写入文本块@7%s@中。
- device,该参数为设备名,写入到文本块@10%s@中。
返回值:
无
函数代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Function CreateMyOpMsg(inputMsg, device) '创建操作员消息 dim myAlarm Set myAlarm = HMIRuntime.Alarms(12508142) MyAlarm.State = 5 '-------------------------- 'State Alarm Log Status '1 Came In '2 Went Out '5 Came in and comment '6 Gone and comment '-------------------------- myAlarm.Comment = userComment myAlarm.UserName = userName myAlarm.ProcessValues(10) = Device myAlarm.ProcessValues(7) = inputMsg MyAlarm.Create End Function |
如何生成电子签名
C脚本执行电子签名
函数原型:
int EsigDialog(const char * inputMsg, const char * device)
参数:
- inputMsg,该参数为执行该操作的描述字符串,写入到文本块@7%s@中。
- device,该参数为设备名,写入到文本块@10%s@中。
返回值:
值 | 描述 |
-1 | 函数执行遇到错误 |
1 | 电子签名通过 |
2 | 用户取消了电子签名 |
3 | 三次电子签名未通过 |
注意:
该函数依赖函数GCreateMyOperationMsg2()
函数代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | #include "apdefap.h" int EsigDialog(const char * inputMsg, const char * device) { //获取用户名和计算机名 char *userName = GetTagChar("@NOP::@CurrentUser"); //Return-Type: char* char *displayedUser = GetTagChar("@NOP::@CurrentUserName"); //Return-Type: char* char *computerName = GetTagChar("@NOP::@LocalMachineName"); //Return-Type: char* char *Domain = ""; //如果加入了域,在此填写域名 int nRet = 0; char szBuf[1024]=""; char myComm[1024]=""; char userComm[1024]=""; VARIANT vtComment; __object* EsigDlg; /*---判断用户是否登录---*/ if (strlen(userName) == 0) { MessageBox(NULL,"用户未登录,请登录后再执行!","Error",MB_SYSTEMMODAL|MB_OK); return -1; } /*---电子签名---*/ EsigDlg = __object_create("CCESigDlg.ESIG"); if (!EsigDlg) { printf("Failed to create Picture Object\n"); return -1; } EsigDlg->forcecomment = FALSE; //非强制注释 nRet = EsigDlg->ShowDialog(userName,displayedUser,Domain,GetLanguage(),&vtComment); __object_delete(EsigDlg); /*---提取注释---*/ sprintf(userComm,"%ls",vtComment.u.bstrVal); VariantClear(&vtComment); /*---合并注释---*/ /* if (strlen(inputMsg)>0 && strlen(userComm)>0) { sprintf(myComm,"%s:%s", inputMsg, userComm); } else if (strlen(inputMsg)>0) { sprintf(myComm,"%s", inputMsg); } else if (strlen(userComm)>0) { sprintf(myComm,"%s", userComm); } */ switch(nRet) { case 1: //InsertAuditEntryNew("","",myComm,0,szBuf); GCreateMyOperationMsg2(0x00000001, 12508142, inputMsg, device, 0, 0, 0, userComm); //Return-Type: long int break; case 2: break; case 3: break; } return nRet; } |
C脚本执行电子签名并写入变量新值:
函数原型:
int TagNewValueES(const char *winccTagName,double newValue, const char *description, const char *device)
参数:
- winccTagName,该参数为WinCC变量名,与参数description拼接后写入到文本块@7%s@中。
- newValue,该参数为要写入的新值,只能为数值,不支持字符串,写入到数值块@3%g@中。
- description,该参数为变量描述,说明该变量的含义,与参数winccTagName拼接后写入到文本块@7%s@中。
- device,该参数为设备名,写入到文本块@10%s@中。
返回值:
值 | 描述 |
-1 | 函数执行遇到错误 |
1 | 电子签名通过 |
2 | 用户取消了电子签名 |
3 | 三次电子签名未通过 |
注意:
该函数依赖函数GCreateMyOperationMsg2()
函数代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | #include "apdefap.h" int TagNewValueES(const char *winccTagName,double newValue, const char *description, const char *device) { //获取用户名和计算机名 char *userName = GetTagChar("@NOP::@CurrentUser"); //Return-Type: char* char *displayedUser = GetTagChar("@NOP::@CurrentUserName"); //Return-Type: char* char *computerName = GetTagChar("@NOP::@LocalMachineName"); //Return-Type: char* char *Domain = "" //如果加入了域,在此填写域名 int nRet = 0; char szBuf[1024]=""; char myComm[1024]=""; char userComm[1024]=""; char tagDescription[1024]=""; double oldValue; VARIANT vtComment; __object* EsigDlg; /*---判断用户是否登录---*/ if (strlen(userName) == 0) { MessageBox(NULL,"用户未登陆,请登陆后再执行!","Error",MB_SYSTEMMODAL|MB_OK); return -1; } /*---电子签名---*/ EsigDlg = __object_create("CCESigDlg.ESIG"); if (!EsigDlg) { printf("Failed to create Picture Object\n"); return -1; } EsigDlg->forcecomment = FALSE; //非强制注释 nRet = EsigDlg->ShowDialog(userName,displayedUser,Domain,GetLanguage(),&vtComment); __object_delete(EsigDlg); /*---提取注释---*/ sprintf(userComm,"%ls",vtComment.u.bstrVal); VariantClear(&vtComment); /*---合并注释---*/ /* if (strlen(description)>0 && strlen(userComm)>0) { sprintf(myComm,"%s:%s", description, userComm); } else if (strlen(description)>0) { sprintf(myComm,"%s", description); } else if (strlen(userComm)>0) { sprintf(myComm,"%s", userComm); } */ switch(nRet) { case 1: //获取旧值 //strcpy(oldValue,GetTagChar(winccTagName)); oldValue = GetTagDouble(winccTagName); //Return-Type: double //写入新值 //SetTagChar(winccTagName,newValue); SetTagDouble(winccTagName,newValue); //Return-Type: BOOL //创建操作员消息 //InsertAuditEntryNew(oldValue,newValue,myComm,0,szBuf); sprintf(tagDescription,"%s %s", winccTagName, description); GCreateMyOperationMsg2(0x00000001 ,12508141 , tagDescription, device, 0, oldValue , newValue , userComm); //Return-Type: long int break; case 2: break; case 3: break; } return nRet; } |
VB脚本执行电子签名
函数原型:
Function EsigDialog(inputMsg, device)
参数:
- inputMsg,该参数为执行该操作的描述字符串,写入到文本块@7%s@中。
- device,该参数为设备名,写入到文本块@10%s@中。
返回值:
值 | 描述 |
-1 | 函数执行遇到错误 |
1 | 电子签名通过 |
2 | 用户取消了电子签名 |
3 | 三次电子签名未通过 |
函数代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | Function EsigDialog(inputMsg, device) '获取用户名和计算机名 Dim userName, displayedUser, Domain, computerName userName = HMIRuntime.Tags("@NOP::@CurrentUser").Read displayedUser = HMIRuntime.Tags("@NOP::@CurrentUserName").Read computerName = HMIRuntime.Tags("@NOP::@LocalMachineName").Read Domain = "" If userName = "" Then Msgbox "用户未登陆,请登陆后再执行" EsigDialog = -1 Exit Function End If '电子签名 Dim myEsig Dim myComment Dim userComment Dim ret Set myEsig = CreateObject("CCEsigDlg.ESIG") '不强制注释 myEsig.forcecomment = False ret = myEsig.showDialog(userName,displayedUser,Domain, HMIRuntime.Language, userComment) ' If Trim(inputMsg)<>"" And Trim(userComment)<>"" Then ' myComment = inputMsg&":"&userComment ' Elseif Trim(inputMsg)<>"" Then ' myComment = inputMsg ' Elseif Trim(userComment)<>"" Then ' myComment = userComment ' Else ' myComment = "" ' End If Select Case ret Case 1 '用户成功获得验证 'Call InsertAuditEntryNew("", "", myComment, 0) '创建操作员消息 dim myAlarm Set myAlarm = HMIRuntime.Alarms(12508142) MyAlarm.State = 5 '-------------------------- 'State Alarm Log Status '1 Came In '2 Went Out '5 Came in and comment '6 Gone and comment '-------------------------- myAlarm.Comment = userComment myAlarm.UserName = userName myAlarm.ProcessValues(10) = device myAlarm.ProcessValues(7) = inputMsg MyAlarm.Create Case 2 '用户使用“取消”按钮关闭了对话框。 Case 3 '用户 3 次验证均失败。 End Select EsigDialog = ret End Function |
VB脚本执行电子签名并写入新值
函数原型:
Function TagNewValueES(WinccTagName,NewValue,description,device)
参数:
- winccTagName,该参数为WinCC变量名,与参数description拼接后写入到文本块@7%s@中。
- newValue,该参数为要写入的新值,只能为数值,不支持字符串,写入到数值块@3%g@中。
- description,该参数为变量描述,说明该变量的含义,与参数winccTagName拼接后写入到文本块@7%s@中。
- device,该参数为设备名,写入到文本块@10%s@中。
返回值:
值 | 描述 |
-1 | 函数执行遇到错误 |
1 | 电子签名通过 |
2 | 用户取消了电子签名 |
3 | 三次电子签名未通过 |
函数代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | Function TagNewValueES(WinccTagName,NewValue,description,device) '获取用户名和计算机名 Dim userName, displayedUser, Domain, computerName userName = HMIRuntime.Tags("@NOP::@CurrentUser").Read displayedUser = HMIRuntime.Tags("@NOP::@CurrentUserName").Read computerName = HMIRuntime.Tags("@NOP::@LocalMachineName").Read Domain = "" If userName = "" Then Msgbox "用户未登陆,请登陆后再执行" TagNewValueES = -1 Exit function End If '电子签名 Dim myEsig Dim myComment Dim userComment Dim ret Set myEsig = CreateObject("CCEsigDlg.ESIG") '不强制注释 myEsig.forcecomment = False ret = myEsig.showDialog(userName,displayedUser, Domain, HMIRuntime.Language, userComment) ' If Trim(description)<>"" And Trim(userComment)<>"" Then ' myComment = description&":"&userComment ' Elseif Trim(description)<>"" Then ' myComment = description ' Elseif Trim(userComment)<>"" Then ' myComment = userComment ' Else ' myComment = "" ' End If Select Case ret Case 1 '用户成功获得验证 '获取变量旧值 dim OldValue, WinCCTag Set WinCCTag = HMIRuntime.Tags(WinccTagName) OldValue = WinCCTag.read '给变量写入新值 WinCCTag.Write NewValue If WinCCTag.LastError <> 0 Then Msgbox WinCCTag.ErrorDescription TagNewValueES = -1 Exit Function End If '创建操作员消息 dim myAlarm set myAlarm = HMIRuntime.Alarms(12508141) '@10%s@: @7%s@ @102%s@ 新=@3%g@ @8%s@ 旧=@2%g@ @8%s@' MyAlarm.State = 5 '-------------------------- 'State Alarm Log Status '1 Came In '2 Went Out '5 Came in and comment '6 Gone and comment '-------------------------- myAlarm.Comment = userComment myAlarm.UserName = userName myAlarm.ProcessValues(2) = OldValue'旧值 myAlarm.ProcessValues(3) = NewValue'新值 myAlarm.ProcessValues(7) = WinccTagName &" "&description '变量名+变量描述 myAlarm.ProcessValues(10) = device'设备名 MyAlarm.Create 'InsertAuditEntryNew(OldValue, NewValue, myComment, 0) Case 2 '用户使用“取消”按钮关闭了对话框。 Case 3 '用户 3 次验证均失败。 End Select TagNewValueES = ret End Function |
版权声明:本文原创发表于博客园,作者为星墨 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明, 且在文章页面明显位置给出原文连接,否则视为侵权。
原文地址
https://www.cnblogs.com/yada/p/11597846.html