- Обязательно представиться на русском языке кириллицей (заполнить поле "Имя").
- Фиктивные имена мы не приветствуем. Ивановых и Пупкиных здесь уже достаточно.
- Не писать свой вопрос в первую попавшуюся тему - вместо этого создать новую тему.
- За поиск, предложение и обсуждение пиратского ПО и средств взлома - бан без предупреждения.
- Рекламу и частные объявления "куплю/продам/есть халтура" мы не размещаем ни на каких условиях.
- Перед тем как что-то написать - читать здесь и здесь, а студентам - обязательно здесь.
- Не надо писать в ЛС администраторам свои технические вопросы. Администраторы форума отлично знают как работает форум, а не все-все контроллеры, о которых тут пишут.
[Нужна помощь] WinCC 7. Лог действий оператора.
-
- завсегдатай
- Сообщения: 524
- Зарегистрирован: 05 окт 2009, 11:51
- Имя: Тихомиров Дмитрий Викторович
- Страна: Россия
- город/регион: Москва
- Благодарил (а): 17 раз
- Поблагодарили: 20 раз
[Нужна помощь] WinCC 7. Лог действий оператора.
Коллеги, добрый день!
Может ли кто-нибудь показать как интегрировать скрипт логирования действий оператора в WinCC 7.
Сам скрипт и описание тут: http://dfpd.siemens.ru/forum/viewtopic. ... erationMsg
Описание создаваемых сообщений там тоже есть.
Проблема в моем низком уровне знаний WinCC. Может кто-нибудь расписать как это правильно сделать или подключиться по удаленке и потыкать меня мышью в монитор? Готов эти знания после получения выложить мануалом сюда.
Может ли кто-нибудь показать как интегрировать скрипт логирования действий оператора в WinCC 7.
Сам скрипт и описание тут: http://dfpd.siemens.ru/forum/viewtopic. ... erationMsg
Описание создаваемых сообщений там тоже есть.
Проблема в моем низком уровне знаний WinCC. Может кто-нибудь расписать как это правильно сделать или подключиться по удаленке и потыкать меня мышью в монитор? Готов эти знания после получения выложить мануалом сюда.
-
- частый гость
- Сообщения: 409
- Зарегистрирован: 20 ноя 2012, 13:45
- Имя: :.О.N.Ф
- Страна: Россия
- Благодарил (а): 3 раза
- Поблагодарили: 7 раз
[Нужна помощь] WinCC 7. Лог действий оператора.
А в чём именно вопрос? Смотрите, функция n_GCreateMyOperationMsg, из первого листинга, создаёт пользовательское сообщение. По сути просто обвязка для винсисёвой GCreateMyOperationMsg. На любое событие, которое нужно логировать, вешается скрипт (в свойствах объекта в Graphics Designer'e, вторая вкладка), в котором помимо самих действий вызывается эта функция со всеми нужными параметрами (из не совсем неочевидного там только код сообщения, который передаётся вторым аргументом "DWORD dwMsgNum", винсисёвые заморочки - нужно предварительно насоздавать в AlarmLogging'e шаблоны сообщений, последний скриншот в том посте). Собственно, второй и третий листинги - как раз те скрипты на событие с примерами вызова этой функции.
«Сразу видно внимание к каждой мелочи, неиспорченным не осталось ничто».
-
- завсегдатай
- Сообщения: 524
- Зарегистрирован: 05 окт 2009, 11:51
- Имя: Тихомиров Дмитрий Викторович
- Страна: Россия
- город/регион: Москва
- Благодарил (а): 17 раз
- Поблагодарили: 20 раз
[Нужна помощь] WinCC 7. Лог действий оператора.
Так вопросов два, по большому счету:
1. Куда положить сам скрипт (который обвязка)?
2. Как связать значения из скрипта с текстом сообщения в WinCC 7.3? Там совершенно другое окно свойств и как привязывать к нему параметры, непонятно. Ну и сам формат параметров хотелось бы понять. Хоть где почитать про это?
1. Куда положить сам скрипт (который обвязка)?
2. Как связать значения из скрипта с текстом сообщения в WinCC 7.3? Там совершенно другое окно свойств и как привязывать к нему параметры, непонятно. Ну и сам формат параметров хотелось бы понять. Хоть где почитать про это?
-
- частый гость
- Сообщения: 409
- Зарегистрирован: 20 ноя 2012, 13:45
- Имя: :.О.N.Ф
- Страна: Россия
- Благодарил (а): 3 раза
- Поблагодарили: 7 раз
[Нужна помощь] WinCC 7. Лог действий оператора.
Соврал, обвязка не для GCreateMyOperationMsg, а для MSRTCreateMsgInstanceWithComment. Собственно, всё интересное про неё можно почерпнуть из хелпа к ODK.
1. Скрипт положить в ProjectFolder\Library (можно во вложенный каталог, например ProjectFolder\Library\OperationLogging). Запустить C-Sript Editor из WinCC Explorer'a, не открывая никакие скрипты в меню выбрать Options > Regenerate Header, потом Options > Compile All Functions. Слева в дереве появится скрипт: Project Functions > n_GCreateMyOperationMsg (или Project Functions > OperationLogging > n_GCreateMyOperationMsg - если во вложенный каталог положили).
2. WinCC Explorer > Alarm Logging - создаёте тексты сообщений в Message Blocks. Класс и тип влияют на их отображение/поведение (фильтрация, удержание аларма при уходе аварийного состояния и т.п., всё как везде). Вместо, например, 1%s или 2%d берётся строковое или числовое значение (%s, %d и т.п. работают как в printf'е) с соответствующим индексом из массива mtTextValue структуры MSG_RTDATA_INSTANCECOMMENT_STRUCT, которая передаётся в ф-ю MSRTCreateMsgInstanceWithComment (ещё подробнее почитать можно, опять же, в мануале на ODK). В случае конкретно этой функции смотрите под каким индексом что будет в блоке INITIALIZATION PROCESS VALUE BLOCKS 1..10 Не знаю, как модераторы отнесутся к ссылкам на вражеские ресурсы и неточтобысовсемужлегальныематериалы, которые там выложены, поэтому - на запрос "wincc odk скачать" в гугле вторая ссылка :)
1. Скрипт положить в ProjectFolder\Library (можно во вложенный каталог, например ProjectFolder\Library\OperationLogging). Запустить C-Sript Editor из WinCC Explorer'a, не открывая никакие скрипты в меню выбрать Options > Regenerate Header, потом Options > Compile All Functions. Слева в дереве появится скрипт: Project Functions > n_GCreateMyOperationMsg (или Project Functions > OperationLogging > n_GCreateMyOperationMsg - если во вложенный каталог положили).
2. WinCC Explorer > Alarm Logging - создаёте тексты сообщений в Message Blocks. Класс и тип влияют на их отображение/поведение (фильтрация, удержание аларма при уходе аварийного состояния и т.п., всё как везде). Вместо, например, 1%s или 2%d берётся строковое или числовое значение (%s, %d и т.п. работают как в printf'е) с соответствующим индексом из массива mtTextValue структуры MSG_RTDATA_INSTANCECOMMENT_STRUCT, которая передаётся в ф-ю MSRTCreateMsgInstanceWithComment (ещё подробнее почитать можно, опять же, в мануале на ODK). В случае конкретно этой функции смотрите под каким индексом что будет в блоке INITIALIZATION PROCESS VALUE BLOCKS 1..10 Не знаю, как модераторы отнесутся к ссылкам на вражеские ресурсы и неточтобысовсемужлегальныематериалы, которые там выложены, поэтому - на запрос "wincc odk скачать" в гугле вторая ссылка :)
Тут не подскажу, 7.3 в глаза не видел Не думаю, что там радикально переделали. Ищите Events. В версиях попроще оно должно выглядеть как-то так http://s52.radikal.ru/i137/1305/94/b712ccb9fb71.jpg , если тут 7.3, то там оно не сильно отличается вроде бы
«Сразу видно внимание к каждой мелочи, неиспорченным не осталось ничто».
-
- завсегдатай
- Сообщения: 524
- Зарегистрирован: 05 окт 2009, 11:51
- Имя: Тихомиров Дмитрий Викторович
- Страна: Россия
- город/регион: Москва
- Благодарил (а): 17 раз
- Поблагодарили: 20 раз
[Нужна помощь] WinCC 7. Лог действий оператора.
Спасибо, вечером буду копать! А ссылки - 100% не приветствуются, тут где-то правила форума были. Я, врать не буду, их не читал, но прения нескольколетней давности на этот счет помню.
-
- завсегдатай
- Сообщения: 524
- Зарегистрирован: 05 окт 2009, 11:51
- Имя: Тихомиров Дмитрий Викторович
- Страна: Россия
- город/регион: Москва
- Благодарил (а): 17 раз
- Поблагодарили: 20 раз
[Нужна помощь] WinCC 7. Лог действий оператора.
Перечитал внимательнее. Не, про куда скрипты вставить - это я знаю, там всё по-старому. Пункт 2 - про сообщения. Сама программа управления сообщениями выглядит по-другому. В том числе вот этого окошка больше нет:
Вместо него сбоку панель со свойствами, в которых вот такой вкладки вообще нет.
А у меня просто вообще нет понимания как задаются какие-то динамические параметры в сообщениях.
-
- частый гость
- Сообщения: 409
- Зарегистрирован: 20 ноя 2012, 13:45
- Имя: :.О.N.Ф
- Страна: Россия
- Благодарил (а): 3 раза
- Поблагодарили: 7 раз
[Нужна помощь] WinCC 7. Лог действий оператора.
эм первый раз это окно вижу) В 7.2 это выглядит вот так:
В 7.3 не знаю, ничего подсказать не могу. Возможно, они что-то сильно поменяли.
В 7.3 не знаю, ничего подсказать не могу. Возможно, они что-то сильно поменяли.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
«Сразу видно внимание к каждой мелочи, неиспорченным не осталось ничто».
-
- завсегдатай
- Сообщения: 524
- Зарегистрирован: 05 окт 2009, 11:51
- Имя: Тихомиров Дмитрий Викторович
- Страна: Россия
- город/регион: Москва
- Благодарил (а): 17 раз
- Поблагодарили: 20 раз
[Нужна помощь] WinCC 7. Лог действий оператора.
Всё. Разобрался. Чуть попозже выложу что и как, с копией исходной функции (пусть лучше в двух местах лежит, так спокойнее и надежнее). Типа мануала для нубов навроде меня :)
-
- завсегдатай
- Сообщения: 524
- Зарегистрирован: 05 окт 2009, 11:51
- Имя: Тихомиров Дмитрий Викторович
- Страна: Россия
- город/регион: Москва
- Благодарил (а): 17 раз
- Поблагодарили: 20 раз
[Нужна помощь] WinCC 7. Лог действий оператора.
Итак, саммари:
Взято отсюда: http://dfpd.siemens.ru/forum/viewtopic. ... erationMsg
Скрипт добавляется, как писал выше Exactamente, или копируется текст в новый Action script и аналогично компиляется.
Код функции:
Пример на OnClick объекта:
Аналогично на событие Input Value текстового поля (только автор там еще модифицированную функцию указал - править нужно, но идея понятна:
Текстовые сообщения формируются, с @1%s@ по @9%s@, где формируется 1%s по правилам языка С. (Внимание, в данной функции 3 и 4 параметры - с литерой d, а не s, т.к. числа). Текст сообщения для теста и понимания что кладется в какую переменную:
Большая часть параметров - обычные тексты, но в примерах к событиям автор показал как туда подставить различные параметры объектов.
Взято отсюда: http://dfpd.siemens.ru/forum/viewtopic. ... erationMsg
Скрипт добавляется, как писал выше Exactamente, или копируется текст в новый Action script и аналогично компиляется.
Код функции:
Код: Выделить всё
/* Автор: LexUS
Добавляет сообщение о действии оператора
DWORD dwFlags - FLAG_COMMENT_PARAMETER 0x00000001 - комментарий вводится напрямую при возникновении сообщения о действии оператора
FLAG_COMMENT_DIALOG 0x00000003 - вызывается диалог добавления комментария при возникновении сообщения о действии оператора
DWORD dwMsgNum - номер сообщения в Alarm Logging
char* lpszPictureName - имя формы с которой производится ввод информации
char* lpszObjectName - имя объекта в котором производится ввод информации
char* lpszTagName - имя тэга
char* lpszObjectName1 - наименование датчика, объекта
char* lpszActionName - действие
double doValueOld - предыдущее значение lpszTagName
double doValueNew - новое значение lpszTagName
char* pszComment - комментарий
*/
#pragma code ("kernel32.dll")
void GetLocalTime( LPSYSTEMTIME lpSystemTime);
BOOL GetComputerNameA(LPSTR Computername, LPDWORD size);
#pragma code()
#include "apdefap.h"
#define FLAG_COMMENT_PARAMETER 0x00000001
#define FLAG_COMMENT_DIALOG 0x00000003
//#define FLAG_TEXTID_PARAMETER 0x00000100
int n_GCreateMyOperationMsg( DWORD dwFlags, DWORD dwMsgNum, char* lpszPictureName, char* lpszObjectName, char* lpszTagName, char* lpszObjectName1, char* lpszActionName, float doValueOld, float 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* szCurrentUser = NULL;
char * pszServerPrefix = NULL;
// char* pszPrefix; // to define the type of WinCC project
// char* lpszParent;
char szTmp[256] = ""; // for diagnosis output
printf("Start n_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 = 0x03FF; // text values 1 .. 10 used for textblocks 1 .. 10
MsgRTData.wTextValueUsed = 0x03FF; // text values 1 .. 10 used for textblocks 1 .. 10
MsgCreateEx.dwFlags = MSG_FLAG_TEXTVALUES;
MsgRTData.dwFlags = MSG_FLAG_COMMENT | MSG_FLAG_TEXTVALUES;
MsgCreateEx.dwMsgState = MSG_STATE_COME;
MsgRTData.dwMsgState = MSG_STATE_COME;
//======================================
// INITIALIZATION PROCESS VALUE BLOCKS 1..10
//======================================
GetComputerNameA(szComputerName, &dwBufSize);
// sprintf(szTmp, "Computername = %s \r\n", szComputerName);
strncpy ( MsgCreateEx.mtTextValue[0].szText, szComputerName, sizeof (MsgCreateEx.mtTextValue[0].szText) - 1); // Computer Name
// printf("Start n_GCreateMyOperationMsg \r\n");
szCurrentUser = GetTagChar("@local::@CurrentUser");
strncpy ( MsgCreateEx.mtTextValue[1].szText, szCurrentUser, sizeof (MsgCreateEx.mtTextValue[1].szText) - 1); // Current User Name
MsgCreateEx.wPValueUsed = (WORD)(MsgCreateEx.wPValueUsed | 0x000C);
MsgCreateEx.dPValue[2] = doValueOld; // old value
MsgCreateEx.dPValue[3] = doValueNew; // new value
strncpy ( MsgCreateEx.mtTextValue[4].szText, lpszPictureName, sizeof (MsgCreateEx.mtTextValue[4].szText) - 1); // lpszPictureName
strncpy ( MsgCreateEx.mtTextValue[5].szText, lpszObjectName, sizeof (MsgCreateEx.mtTextValue[5].szText) - 1); // lpszObjectName
strncpy ( MsgCreateEx.mtTextValue[6].szText, lpszTagName, sizeof (MsgCreateEx.mtTextValue[6].szText) - 1); // lpszTagName
strncpy ( MsgCreateEx.mtTextValue[7].szText, lpszActionName, sizeof (MsgCreateEx.mtTextValue[7].szText) - 1); // lpszActionName
strncpy ( MsgCreateEx.mtTextValue[8].szText, lpszObjectName1, sizeof (MsgCreateEx.mtTextValue[8].szText) - 1); // lpszObjectName1
//======================================
//======================================
// 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("n_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;
//======================================
//======================================
// CREATE MESSAGE
//======================================
bOK = MSRTCreateMsgInstanceWithComment(dwServiceID, &MsgCreateEx, &scError) ;
if ( TRUE == bOK)
{
if (FLAG_COMMENT_DIALOG == (dwFlags & FLAG_COMMENT_DIALOG) )
{
BOOL bOkay;
HWND hWnd = FindWindow(NULL, "WinCC-Runtime - ");
memset(&scError,0,sizeof(scError));
bOkay= MSRTDialogComment (hWnd, &MsgRTData, &scError);
if (TRUE == bOkay)
{
MSG_COMMENT_STRUCT mComment;
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: n_GCreateMyOperationMsg() - Error at MSRTGetComment() szErrorText="%s" error2=%d\r\n", scError.szErrorText, scError.dwError2);
iRet = -201;
}
}
}
if(bOK == FALSE)
{
printf ("#E301: n_GCreateMyOperationMsg() - Error at MSRTCreateMsgInstanceWithComment() szErrorText="%s"\r\n", scError.szErrorText);
iRet = -301;
}
//======================================
//======================================
// STOP_MESSAGE_SERVICE
//======================================
bOK= MSRTStopMsgService( dwServiceID, &scError);
printf("End n_GCreateMyOperationMsg \r\n");
return (iRet);
}
Код: Выделить всё
#include "apdefap.h"
void OnLButtonDown(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName, UINT nFlags, int x, int y)
{
// WINCC:TAGNAME_SECTION_START
// syntax: #define TagNameInAction "DMTagName"
// next TagID : 1
#define TAG_1 "Main/Total/allPlatesDel.Clr_L1"
// WINCC:TAGNAME_SECTION_END
// WINCC:PICNAME_SECTION_START
// syntax: #define PicNameInAction "PictureName"
// next PicID : 1
// WINCC:PICNAME_SECTION_END
HWND Handle=NULL;
Handle=FindWindow("PDLRTisAliveAndWaitsForYou","WinCC-Runtime - ");
if (MessageBox(Handle," Очистить все листы? ","Очистка всех листов из ССМ",MB_YESNO|MB_ICONWARNING|MB_SYSTEMMODAL|MB_SETFOREGROUND)==6){
// n_GCreateMyOperationMsg( DWORD dwFlags, DWORD dwMsgNum, char* lpszPictureName, char* lpszObjectName, char* lpszTagName, char* lpszObjectName1, char* lpszActionName, float doValueOld, float doValueNew, char* pszComment )
n_GCreateMyOperationMsg( 0x00000001, 1009, lpszPictureName, lpszObjectName, TAG_1, GetPropChar(lpszPictureName, lpszObjectName, "ToolTipText"), "", 0, 1, "");
// MessageBox(Handle," Готово ","Лист удален",MB_OK|MB_ICONINFORMATION|MB_SYSTEMMODAL|MB_SETFOREGROUND);
SetTagBit(TAG_1, 1);
}
}
Код: Выделить всё
#include "apdefap.h"
void OnPropertyChanged(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName, char* value)
{
// WINCC:TAGNAME_SECTION_START
// syntax: #define TagNameInAction "DMTagName"
#define v_str_length 4
// next TagID : 1
// WINCC:TAGNAME_SECTION_END
// WINCC:PICNAME_SECTION_START
// syntax: #define PicNameInAction "PictureName"
// next PicID : 1
// WINCC:PICNAME_SECTION_END
LINKINFO pLink;
char v_str[v_str_length+1] = "";
if (PDLRTGetLink (0, lpszPictureName, lpszObjectName, "OutputValue", &pLink, NULL, NULL, NULL)) {
strncpy(v_str, value, v_str_length);
SetTagChar(pLink.szLinkName, v_str); //Return-Type: BOOL
n_GCreateMyOperationMsg_str( 0x00000001, 1004, lpszPictureName, lpszObjectName, pLink.szLinkName, GetPropChar(lpszPictureName, lpszObjectName, "ToolTipText"), "",GetPropChar(lpszPictureName, lpszObjectName, "OutputValue"), GetPropChar(lpszPictureName, lpszObjectName, "InputValue"), "");
}
}
Код: Выделить всё
@1%s@, @2%s@, @3%d@, @4%d@, @5%s@, @6%s@, @7%s@, @8%s@, @9%s@
-
- завсегдатай
- Сообщения: 524
- Зарегистрирован: 05 окт 2009, 11:51
- Имя: Тихомиров Дмитрий Викторович
- Страна: Россия
- город/регион: Москва
- Благодарил (а): 17 раз
- Поблагодарили: 20 раз
[Нужна помощь] WinCC 7. Лог действий оператора.
Вообще, как я понимаю, мануал больше для нубов, ибо скрипт берет сообщение, внешние тексты и пихает одно в другое. Но для тех, кто не знает С - это магия какая-то. :(
-
- здесь недавно
- Сообщения: 16
- Зарегистрирован: 14 апр 2016, 22:47
- Имя: Юлдашев Феликс Маратович
- Страна: Россия
- город/регион: Москва
-
- осмотрелся
- Сообщения: 192
- Зарегистрирован: 16 дек 2011, 15:13
- Имя: Алексей
- Страна: Россия
- Благодарил (а): 65 раз
- Поблагодарили: 46 раз
[Нужна помощь] WinCC 7. Лог действий оператора.
Я тоже какое-то время "заморачивался" на C с этой функцией, но потом во всех последующих проектах делал на VBS:
например, при нажатии кнопки вызывается вот такая функция:
AlarmId - номер сконфигурированного в AlarmLogging сообщения, text - нужный текст сообщения (например, "Подана команда "ОТКРЫТЬ"")
например, при нажатии кнопки вызывается вот такая функция:
Код: Выделить всё
Function CreateAlarm(AlarmId, text)
Const hmiAlarmStateCome = 1
Dim user, Alarm
user = HMIRuntime.Tags("@CurrentUser").Read
Set Alarm = HMIRuntime.Alarms(AlarmId)
Alarm.ProcessValues(5).Value = "" & text
Alarm.ProcessValues(4).Value = "" & user
Alarm.State = hmiAlarmStateCome
Alarm.UserName = user
Alarm.Create
End Function
У вас нет необходимых прав для просмотра вложений в этом сообщении.