laitimes

How to write an audit trail

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.

How to write an audit trail

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@.

How to write an audit trail

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.

How to write an audit trail

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:

How to write an audit trail

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