There are two ways to add records to Audit with a script, one is to write with the InserAuditEntryNew function, and the other is to generate an alarm message of the type "Operator Input Message", which is logged to Audit.
The TargetName column in the Audit record is the action content, and the Reason column is the operator's comment. The content of the record generated by using the InserAuditEntryNew function in the TargetName column defaults to VBScripting Runtime or CScripting Runtime, and the operation content can only be recorded at the Reason column, which is inconsistent with the form of other records and the effect is not good, so the InserAuditEntryNew function is not used here.
The second method is to establish an alarm message in the "Operator Input Message" under "System, No Confirmation" in the alarm record, and when this message is triggered, the message will be logged not only to the alarm database, but also to the Audit database. Trigger alarm messages can be triggered with variables or scripts. Use script triggering to pass parameters to the message, that is, write values to text blocks such as @1%s@.
WinCC defaults to an operator input message numbered 12508141, defined as shown below, which is used to record the change of the new value and the old value.
12508141 the content of the message does not fully meet the requirements of the Audit message record, create a message numbered 12508142. In a project, it is possible to control multiple devices with WinCC, define the text block @10%s@ the role is to record which device the operation is aimed at, and the text block @7% s@ record what operation was performed. Some projects do not use the Audit trail component, but use the database of alarm records to record the audit trail, so you can fill in the @10% s@ in the error point column, which is easy to filter when viewing using the alarm control. The message is defined as follows:
Use a C script to generate operator messages
WinCC supports both C and VB scripts, and the GCreateMyOperationMsg() function is provided in the C script to generate operator messages.
Function prototype:
int GCreateMyOperationMsg( DWORD dwFlags, DWORD dwMsgNum, char* lpszPictureName, char* lpszObjectName, DWORD dwMyTextID, double doValueOld, double doValueNew, char* pszComment)
Parameter:
- dwFlags, which specifies how comments are generated, with the following constant values, which can be used or operate "|" Input:
constant | value | description |
FLAG_COMMENT_PARAMETER | 0x00000001 | Text is entered directly as a message at run time, without its own comment dialog. A pointer to a comment cannot equal "NULL". |
FLAG_COMMENT_DIALOG | 0x00000003 | A comment dialog box appears, and the entered comment is transferred to the message |
FLAG_TEXTID_PARAMETER | 0x00000100 | Provides a text ID from the text library to insert the text into the procedure value of the message. |
- dwMsgNum, this parameter is the message number, which triggers the numbered message. Messages must be of type Operator Input Message and cannot use other types of messages.
- lpszPictureName, which is not used in the function and has no effect.
- lpszObjectName, which is written to the text block @1%s@ and the szInstance property, which is equivalent to the text block @10%s@.
- dwMyTextID, this parameter is the text library ID, the value will be written to the value @8%g@. If the dwFlags parameter is FLAG_TEXTID_PARAMETER, the text of that ID in the text library is written to the text block @8%s@.
- doValueOld, this parameter is the old value of the variable, the value will be written to the value @2%g@, and in the audit, it will be written to the OldValue column.
- doValueNew, this parameter is the new value of the variable, the value will be written to the value @3%g@, and in the audit, it will be written to the NewValue column.
- pszComment, this parameter is a comment string, if the dwFlags parameter is FLAG_COMMENT_PARAMETER, the string will be written to the comment of the alarm and written to the Reason column of Audit.
Return value:
value | description |
Function execution completes without any errors | |
-101 | Messages cannot be edited |
-201 | When calling the "MSRTGetComment()" feature an error is thrown |
-301 | When calling the "MSRTCreateMsgInstanceWithComment()" feature an error is thrown |
The GCreateMyOperationMsg() function does not use the text block @7% in the message text generated by the GCreateMyOperationMsg(s@) function, we refer to the GCreateMyOperationMsg function to modify and recreate an operator message function GCreateMyOperationMsg2(), the function value is replaced by the lpszMsg parameter lpszPictureName parameter, The value of the lpszMsg parameter is written to the text block @7%s@. The GCreateMyOperationMsg2() function is used with 12508142 messages.
Function prototype:
int GCreateMyOperationMsg2( DWORD dwFlags, DWORD dwMsgNum, char* lpszMsg, char* lpszObjectName, DWORD dwMyTextID, double doValueOld, double doValueNew, char* pszComment)
Parameter:
- lpszMsg, this parameter logs the operation message, which is written to the text block @7%s@.
- The other parameters are consistent with the GCreateMyOperationMsg() function.
Function code:
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 script operator message function secondary encapsulation
In places where electronic signatures are not required and operation messages are recorded, for easier use, the function is subpackaged as the function CreateMyOpMsg().
Function prototype:
int CreateMyOpMsg(char* lpszMsg, char* lpszdevice)
Parameter:
- lpszMsg, this parameter logs the operation message, written to the text block @7%s@.
- lpszdevice, which is the device name, is written to the text block @10%s@.
Return value:
value | description |
Function execution completes without any errors | |
-101 | Messages cannot be edited |
-201 | When calling the "MSRTGetComment()" feature an error is thrown |
-301 | When calling the "MSRTCreateMsgInstanceWithComment()" feature an error is thrown |
Function code:
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 } |
Generate operator messages with VB scripts
The script to create an operator message using VB script is as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 'Create operator message 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 |
Note: Operator messages generated with VBS do not have the computer name in the alarm record.
VB script operator message function secondary encapsulation
In places where electronic signatures are not required and operation messages are recorded, for easier use, the function is subpackaged as the function CreateMyOpMsg().
Function prototype:
Function CreateMyOpMsg(inputMsg, device)
Parameter:
- inputMsg, this parameter records the operation message and writes it to the text block @7%s@.
- device, which is the device name, is written to the text block @10%s@.
Return value:
not
Function code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Function CreateMyOpMsg(inputMsg, device) 'Create operator message 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 |
How to generate an electronic signature
C scripts execute electronic signatures
Function prototype:
int EsigDialog(const char * inputMsg, const char * device)
Parameter:
- inputMsg, which is the description string of the operation, is written to the text block @7%s@.
- device, which is the device name, is written to the text block @10%s@.
Return value:
value | description |
-1 | Function execution encountered an error |
1 | The electronic signature is passed |
2 | The user canceled the electronic signature |
3 | Three failed electronic signatures |
Note:
This function depends on the function GCreateMyOperationMsg2()
Function code:
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) { Gets the user name and computer name 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 = ""; If you joined a domain, enter the domain name here int nRet = 0; char szBuf[1024]=""; char myComm[1024]=""; char userComm[1024]=""; VARIANT vtComment; __object* EsigDlg; /*--- determine whether the user is logged in ---*/ if (strlen(userName) == 0) { MessageBox(NULL, "User is not logged in, please log in before executing!") ","Error",MB_SYSTEMMODAL| MB_OK); return -1; } /*--- Electronic signature---*/ EsigDlg = __object_create("CCESigDlg.ESIG"); if (! EsigDlg) { printf("Failed to create Picture Object\n"); return -1; } EsigDlg->forcecomment = FALSE; Non-mandatory comments nRet = EsigDlg->ShowDialog(userName,displayedUser,Domain,GetLanguage(),&vtComment); __object_delete(EsigDlg); /*--- extract comments---*/ sprintf(userComm,"%ls",vtComment.u.bstrVal); VariantClear(&vtComment); /*--- merge comments---*/ /* 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; } |
The C script executes an electronic signature and writes the new value of the variable:
Function prototype:
int TagNewValueES(const char *winccTagName,double newValue, const char *description, const char *device)
Parameter:
- winccTagName, this parameter is the name of the WinCC variable, which is concatenated with the parameter description and written into the text block @7%s@.
- newValue, the parameter is a new value to be written, can only be a numeric value, does not support strings, and is written to the value block @3%g@.
- description, this parameter is the variable description, explain the meaning of the variable, and the parameter winccTagName is stitched and written into the text block @7%s@.
- device, which is the device name, is written to the text block @10%s@.
Return value:
value | description |
-1 | Function execution encountered an error |
1 | The electronic signature is passed |
2 | The user canceled the electronic signature |
3 | Three failed electronic signatures |
Note:
This function depends on the function GCreateMyOperationMsg2()
Function code:
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) { Gets the user name and computer name 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 = "" // If the domain is joined, fill in the domain name here int nRet = 0; char szBuf[1024]=""; char myComm[1024]=""; char userComm[1024]=""; char tagDescription[1024]=""; double oldValue; VARIANT vtComment; __object* EsigDlg; /*--- determine whether the user is logged in ---*/ if (strlen(userName) == 0) { MessageBox(NULL, "User is not logged in, please log in before executing!", "Error", MB_SYSTEMMODAL| MB_OK); return -1; } /*--- Electronic signature---*/ EsigDlg = __object_create("CCESigDlg.ESIG"); if (! EsigDlg) { printf("Failed to create Picture Object\n"); return -1; } EsigDlg->forcecomment = FALSE; Non-mandatory comments nRet = EsigDlg->ShowDialog(userName,displayedUser,Domain,GetLanguage(),&vtComment); __object_delete(EsigDlg); /*--- extract comments---*/ sprintf(userComm,"%ls",vtComment.u.bstrVal); VariantClear(&vtComment); /*--- merge comments---*/ /* 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: Get the old value //strcpy(oldValue,GetTagChar(winccTagName)); oldValue = GetTagDouble(winccTagName); //Return-Type: double Write the new value //SetTagChar(winccTagName,newValue); SetTagDouble(winccTagName,newValue); //Return-Type: BOOL Create an operator message //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 scripts perform electronic signatures
Function prototype:
Function EsigDialog(inputMsg, device)
Parameter:
- inputMsg, which is the description string of the operation, is written to the text block @7%s@.
- device, which is the device name, is written to the text block @10%s@.
Return value:
value | description |
-1 | Function execution encountered an error |
1 | The electronic signature is passed |
2 | The user canceled the electronic signature |
3 | Three failed electronic signatures |
Function code:
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) 'Get the user name and computer name 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 "User is not logged in, please log in before executing" EsigDialog = -1 Exit Function End If 'Electronic signature Dim myEsig Dim myComment Dim userComment Dim ret Set myEsig = CreateObject("CCEsigDlg.ESIG") 'Comments are not mandatory 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 'User successfully authenticated 'Call InsertAuditEntryNew("", "", myComment, 0) 'Create operator message 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 'The user closed the dialog box using the 'Cancel' button. Case 3 'User failed 3 authentications. End Select EsigDialog = right End Function |
The VB script performs an electronic signature and writes the new value
Function prototype:
Function TagNewValueES(WinccTagName,NewValue,description,device)
Parameter:
- winccTagName, this parameter is the name of the WinCC variable, which is concatenated with the parameter description and written into the text block @7%s@.
- newValue, the parameter is a new value to be written, can only be a numeric value, does not support strings, and is written to the value block @3%g@.
- description, this parameter is the variable description, explain the meaning of the variable, and the parameter winccTagName is stitched and written into the text block @7%s@.
- device, which is the device name, is written to the text block @10%s@.
Return value:
value | description |
-1 | Function execution encountered an error |
1 | The electronic signature is passed |
2 | The user canceled the electronic signature |
3 | Three failed electronic signatures |
Function code:
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) 'Get the user name and computer name 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 "User is not logged in, please log in before executing" TagNewValueES = -1 Exit function End If 'Electronic signature Dim myEsig Dim myComment Dim userComment Dim ret Set myEsig = CreateObject("CCEsigDlg.ESIG") 'Comments are not mandatory 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 'User successfully authenticated 'Get the old value of the variable dim OldValue, WinCCTag Set WinCCTag = HMIRuntime.Tags(WinccTagName) OldValue = WinCCTag.read ' Write a new value to the variable WinCCTag.Write NewValue If WinCCTag.LastError <> 0 Then Msgbox WinCCTag.ErrorDescription TagNewValueES = -1 Exit Function End If 'Create operator message dim myAlarm set myAlarm = HMIRuntime.Alarms(12508141) '@10%s@: @7%s@ @102%s@ New=@3%g@ @8%s@ Old = @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's old value myAlarm.ProcessValues(3) = NewValue's new value myAlarm.ProcessValues(7) = WinccTagName & " "&description ' variable name + variable description myAlarm.ProcessValues(10) = device's device name MyAlarm.Create 'InsertAuditEntryNew(OldValue, NewValue, myComment, 0) Case 2 'The user closed the dialog box using the 'Cancel' button. Case 3 'User failed 3 authentications. End Select TagNewValueES = right End Function |
Copyright statement: This article was originally published in Blog Park, the author is Xingmo The copyright of this article belongs to the author and Blog Park, welcome to reprint, but without the consent of the author must retain this statement, and give the original text link in a conspicuous position on the article page, otherwise it will be regarded as infringement.
Original address https://www.cnblogs.com/yada/p/11597846.html