Скрипты на Сicode и CiVBA в помощь разработчикам

Обсуждение SCADA-систем: Citect SCADA, Vijeo Citect, CitectSCADA, CitectFacilities, PowerLogic SCADA, PowerSCADA, MX4SCADA, Desigo Insight.
Аватара пользователя
alex
Администратор
Сообщений в теме: 18
Сообщения: 1728
Зарегистрирован: 05 апр 2010, 21:58
Откуда: Москва
Благодарил (а): 45 раз
Поблагодарили: 98 раз
Контактная информация:

Скрипты на Сicode и CiVBA в помощь разработчикам

#1

Сообщение alex » 11 апр 2014, 10:01

В этой теме находятся примеры кода на стандартных для Citect-based SCADAs скриптовых языках программирования, т.е. Cicode и CiVBA, позволяющие решать различные задачи при разработке проектов, обеспечивая тем самым гибкий подход к реализации требуемого функционала.

Внимание! Тема развивается модераторами и администраторами форума.



Аватара пользователя
alex
Администратор
Сообщений в теме: 18
Сообщения: 1728
Зарегистрирован: 05 апр 2010, 21:58
Откуда: Москва
Благодарил (а): 45 раз
Поблагодарили: 98 раз
Контактная информация:

Cicode: Функции работы с битами (SetBit, GetBit, ToggleBit)

#2

Сообщение alex » 17 июн 2014, 15:39

В списке встроенных функций Сitect-based SCADAs отсутствуют часто необходимые в работе функции для манипуляции с битами. Ниже приведена реализация основных функций для этих целей на Cicode.

/*
        (с) 2014 http://www.proasutp.com

        SetBit - функция устанавливает в требуемое состояние указанный бит.

        Вход:
                iValue  - значение, в котором необходимо установить в загаданное состояние указанный бит;
                iBitNum - номер бита (0...31), который необходимо перевести в требуемое состояние;
                bState  - состояние (ноль или не ноль) в которое необходимо перевести указанный бит.
        Выход:
                Значение с приведенным в нужное состояние битом

*/


INT FUNCTION SetBit(INT iValue, INT iBitNum, INT bState)

    INT iBitMask = 0;   // маска для выделения указанного бита
    INT iBitPos = 0;    // позиция указанного бита
    INT iVal = 0;       // возвращаемое значение
   
    iBitPos = Pow (2, iBitNum);
   
    IF FALSE = bState THEN
        iBitMask = 0xFFFFFFFF BITXOR iBitPos;
        iVal = iValue BITAND iBitMask;
    ELSE
        iBitMask = iBitPos;
        iVal = iValue BITOR iBitMask;
    END
   
    RETURN  iVal;
   
END


/*
        (с) 2014 www.proasutp.com

        GetBit - функция возвращает состояние указанного бита.

        Вход:
                iValue  - значение, из которого необходимо получить состояние указанного бита;
                iBitNum - номер бита (0...31), состояние которого необходимо получить.
        Выход:
                Состояние указанного бита в переданном значении.

*/


INT FUNCTION GetBit (INT iValue, INT iBitNum)

    INT iBitMask = 0;   // маска для выделения указанного бита
    INT iVal = 0;       // возвращаемое значение
   
    iBitMask = Pow (2, iBitNum);

    IF iValue BITAND iBitMask THEN
        iVal = TRUE;
    ELSE
        iVal = FALSE;
    END
   
    RETURN iVal;
   
END


/*
        (с) 2014 www.proasutp.com

        ToggleBit - функция инвертирует состояние указанного бита.

        Вход:
                iValue  - значение, в котором необходимо инвертировать состояние указанного бита;
                iBitNum - номер бита (0...31), состояние которого необходимо инвертировать.
        Выход:
                Значение с инвертированным состоянием бита.

*/


INT FUNCTION ToggleBit(INT iValue, INT iBitNum)

    INT iBitMask = 0;   // маска для выделения указанного бита
    INT iVal = 0;       // возвращаемое значение
   
    iBitMask = Pow (2, iBitNum);
    iVal = iValue BITXOR iBitMask;
           
    RETURN iVal;
   
END



Аватара пользователя
alex
Администратор
Сообщений в теме: 18
Сообщения: 1728
Зарегистрирован: 05 апр 2010, 21:58
Откуда: Москва
Благодарил (а): 45 раз
Поблагодарили: 98 раз
Контактная информация:

Сicode: Пример вызова функций из DLL

#3

Сообщение alex » 17 июн 2014, 19:30

Одной из сильных возможностей Cicode - это возможность вызова функций из системных DLLs операционной системы, а также DLLs сторонних разработчиков. Ниже пример функции проигрывания звукового файла через вызов соответствующей функции из системной DLL операционной системы. Несмотря на то, что такая функция существует в списке стандартных (это функция DspPlaySound) функций, приведенный ниже пример показывает альтернативный путь ее реализации.

/*
        (с) 2014 http://www.proasutp.com

        Функция проигрывает звуковой файл в формате .WAV.

        Вход:
                sSoundFile - полный путь к звуковому файлу;
                iPlayMode  - режим проигрывания звукового файла.
        Выход:
                Успех (TRUE)/Неуспех (FALSE) выполнения функции.

*/



INT FUNCTION PlaySound (STRING sSoundFile, INT iPlayMode)
   
    INT iHandle = 0;
    STRING sArguments = "";
    STRING sResult = "";

    IF 0 = StrLength (sSoundFile) THEN RETURN FALSE; END
   
    iHandle = DLLOpen ("WINMM.DLL", "PlaySound", "ACJJ");
   
    IF -1 = iHandle THEN RETURN FALSE; END
   
    sArguments = "^"" + sSoundFile + "^"," + "0" + "," + IntToStr (iPlayMode);
   
    sResult = DLLCall (iHandle, sArguments);
   
    IF StrToInt (sResult) THEN RETURN FALSE; END
       
    IF DLLClose (iHandle) THEN RETURN FALSE; END
   
    RETURN TRUE;
   
END



Аватара пользователя
alex
Администратор
Сообщений в теме: 18
Сообщения: 1728
Зарегистрирован: 05 апр 2010, 21:58
Откуда: Москва
Благодарил (а): 45 раз
Поблагодарили: 98 раз
Контактная информация:

Сicode: Функция создания полупрозрачных окон

#4

Сообщение alex » 19 авг 2014, 14:08

По настоящему уникальные возможности предоставляет данная функция для работы с окнами, позволяя создавать интересные визуальные эффекты основанные на манипуляции прозрачностью цветов используемых в окнах и управлением степенью их непрозрачности (использование альфа-канала).

/*
        (с) 2014 http://www.proasutp.com

        Функция устанавливает прозрачным заданный цвет и уровень непрозрачности окна.

        Вход:
                hWnd - хендл окна, если хендл окна не задан, то функция работает с текущим окном;
                iReplaceColor - цвет в RGB-кодировке (см. cicode-функцию PackedRGB), который будет прозрачным;
                iOpacity - уровень непрозрачности окна от 0 (полностью прозрачное) до 255 (полностью непрозрачное).
        Выход:
                Нет.

*/


FUNCTION SetTransparency (INT hWnd = -1,INT iReplaceColor = -1, INT iOpacity = -1)

    INT hDllGetWindowLong = 0;                 // хендл для WinAPI-функции GetWindowLong
    INT hDllSetWindowLong = 0;                 // хендл для WinAPI-функции SetWindowLong
    INT hDllSetLayeredWindowAttributes = 0;    // хендл для WinAPI-функции SetLayeredWindowAttributes

    INT GWL_EXSTYLE = -20;                     // константа WinAPI, включает новый расширенный стиль окона
    INT WS_EX_LAYERED = 0x00080000;            // константа WinAPI, включает режим многослойного окона
    INT LWA_ALPHA = 0x00000002;                // константа WinAPI, включает режим непрозрачности с заданным уровнем
    INT LWA_COLORKEY = 0x00000001;             // константа WinAPI, включает режим прозрачности заданного цвета

    INT iLWA_ALPHA = 0;                        // флаги режимов непрозрачности окна и прозрачности цвета
    INT iStyle = 0;                            // стиль окна
    STRING sWnd = "";                          // строковое представление хендла окна

    // Если хендл окна не задан, тогда получаем хендл текущего окна

    IF hWnd = -1 THEN
        hWnd = WinGetWndHnd();
    END

    // Включаем режим прозрачности цвета, если он задан
   
    IF iReplaceColor <> -1 THEN
        iLWA_ALPHA = LWA_COLORKEY;
    END

    // Включаем режим уровня непрозрачности окна, если он задан

    IF iOpacity <> -1 THEN
        iLWA_ALPHA = iLWA_ALPHA BITOR LWA_ALPHA;
    END

    // Если режим прозрачности цвета или уровень непрозрачности окна задан, то применяем его к окну

    IF (iLWA_ALPHA > 0) OR (iOpacity > 0) THEN
   
        sWnd = IntToStr(hWnd);
       
        hDllGetWindowLong = DLLOpen("user32.dll", "GetWindowLongA", "JJJ");
        hDllSetWindowLong = DLLOpen("user32.dll", "SetWindowLongA", "JJJJ");
        hDllSetLayeredWindowAttributes = DLLOpen("user32.dll", "SetLayeredWindowAttributes", "AJJJJ");

        // Включаем многослойный режим окна

        iStyle = DLLCall(hDllGetWindowLong, sWnd + "," + IntToStr(GWL_EXSTYLE));
        iStyle = iStyle BITOR WS_EX_LAYERED;
        DLLCall(hDllSetWindowLong, sWnd + "," + IntToStr(GWL_EXSTYLE) + "," + IntToStr(iStyle));
       
        // Применяем новый стиль
       
        DLLCall(hDllSetLayeredWindowAttributes, sWnd + "," + IntToStr(iReplaceColor) + "," + IntToStr(iOpacity) + "," + IntToStr(iLWA_ALPHA));
       
        DLLClose(hDllGetWindowLong);
        DLLClose(hDllSetWindowLong);
        DLLClose(hDllSetLayeredWindowAttributes);
           
    END
   
END



Аватара пользователя
alex
Администратор
Сообщений в теме: 18
Сообщения: 1728
Зарегистрирован: 05 апр 2010, 21:58
Откуда: Москва
Благодарил (а): 45 раз
Поблагодарили: 98 раз
Контактная информация:

Сicode: Динамическое формирование подсказки (tooltip) для графических объектов

#5

Сообщение alex » 19 июн 2015, 14:03

Часто встречается задача в режиме исполнения (в режиме runtime), при наведении указателя мышки на тот или иной графический объект Vijeo Citect, получать некоторую информацию по объекту, которая формируется динамически, т.е. по ходу работы системы диспетчеризации и которую нельзя сформировать статически, т.е. на стадии конфигурирования. Ниже приведен скрипт, который показывает один из вариантов реализации данной возможности.

/*
        (c) 2015 http://www.proasutp.com

        Динамическое формирование подсказки для графических объектов Vijeo Citect

        Вход:
        Нет
        Выход:
                Нет

*/


MODULE INT MOUSE_MOVE_EVENT = 0; // идентификатор события перемещения указателя мыши

// Устанавливаем свой обработчик на событие перемещения мыши

PUBLIC INT FUNCTION SetMyMouseMoveEventHandler()
   
    INT res = 0;
   
    res = OnEvent (MOUSE_MOVE_EVENT, SetToolTipForGObjectAtMousePoint);
   
    RETURN res;
   
END

// Собственно сам обработчик события, устанавливающий свойство tooltip в нужное значение

PRIVATE INT FUNCTION SetToolTipForGObjectAtMousePoint()
   
    INT x = 0, y = 0, an = 0;
    STRING tooltip = "";
   
    DspGetMouse(x, y);
    an = DspGetAnFromPoint(x, y);
   
    IF (an <> 0) THEN
        //Здесь должны быть функция, которая формирует строку подсказки (tooltip)
    tooltip = MakeToolTipString ();
    DspSetTip (an, tooltip );
    END
       
    RETURN 0;
   
END

// Функция, которая по определенным правилам формирует строку подсказки (tooltip)

PRIVATE STRING FUNCTION MakeToolTipString ()

    RETURN "http://forum.proasutp.com";

END



Аватара пользователя
alex
Администратор
Сообщений в теме: 18
Сообщения: 1728
Зарегистрирован: 05 апр 2010, 21:58
Откуда: Москва
Благодарил (а): 45 раз
Поблагодарили: 98 раз
Контактная информация:

Сicode: Использование сигнальных функций для работы с задачами

#6

Сообщение alex » 09 сен 2015, 14:18

Как известно Vijeo Citect славиться среди остальных SCADA систем помимо всего прочего (и что его собственно сильно выделяет среди остальных) своими "низкоуровневыми" возможностями, включая работу с такими системными вещами как потоки, очереди, RPC-сообщения, объекты синхронизации (критические секции и семафоры) и т.д. Это многих может пугать, но для профессионалов это поле для сильных решений. Среди всех функций в разделе Task Functions существуют такие функции как TaskSetSignal и TaskGetSignal. Из встроенной помощи не совсем ясно как их использовать. Собственно о них и речь ниже...

Сicode: Использование сигнальных функций для работы с задачами
Основное назначение данных функций это передача задачам так называемых сигналов. В качестве сигналов выступают целочисленные значения. Как интерпретировать переданное конкретное целочисленное значение лежит уже на логике, которую закладывает сам разработчик. Это хороший механизм для общения между разными задачами (которые работают в отдельных потоках) в многозадачной среде. В Vijeo Citect существует для этих целей две функции TaskSetSignal и TaskGetSignal, которые позволяют соответственно установить и прочитать значение сигнала (т.е. целочисленное значение) для конкретной задачи.
Пример использования данных функций можно посмотреть в теме: Управление задачами Vijeo Citect 7.40.



Аватара пользователя
alex
Администратор
Сообщений в теме: 18
Сообщения: 1728
Зарегистрирован: 05 апр 2010, 21:58
Откуда: Москва
Благодарил (а): 45 раз
Поблагодарили: 98 раз
Контактная информация:

Cicode: Организация строковых массивов неограниченного размера

#7

Сообщение alex » 28 ноя 2015, 21:34

Как известно, стандартно, в Cicode существует ряд ограничений, таких как запрет на локальные массивы в функциях или невозможность вернуть из функций несколько значений. Ниже Cicode, который позволяет обойти эти ограничения и добавить возможности сортировки строк...

// Table.ci
// v1.02
// Функции для использования очередей (queues) в качестве строковых массивов неограниченной длины.
// Это позволяет передавать такой "массив" между функциями или же каждый экземпляр одной и той же функции
// может работать с разными такими "массивами".
// По умолчанию, очереди могут иметь только 256 элементов. Увеличить длину очереди можно с помощью
// параметра [Code]Queue в Citect.ini, или же установить значение этого параметра в -1, что
// позволяет иметь очередь неограниченной длины.

// Константы модуля
INT cQueCreate = 1;
INT cQueFindNumber = 2;
INT cQueRemove = 8;
INT cQueFindElement = 16;
INT cErrCicode = -1;


// Переменные модуля
INT mhCompareString = -1;


// Создать таблицу и вернуть ее хэндл.
//
// Указание уникального описания, позволяет быстрее найти эту таблицу в окне Kernel.
// Параметр sDescription необязателен.

INT FUNCTION TableCreate(STRING sDescription = "TableQueue")
    RETURN QueOpen(sDescription, cQueCreate);
END

// Закрыть указанную таблицу с уничтожением всех данных в ней. Функция должны быть вызвана
// для освобождения памяти, когда таблица больше не нужна.

FUNCTION TableClose(INT hTable)
    QueClose(hTable);
END


// Записать значение в элемент таблицы.
//
// hTable        Хэндл таблицы возвращенный функцией TableCreate().
// nElement      Номер элемента для записи (любое целое значение).
// sValue        Текст или числовое значение для записи (до 255 символов).
// bQuickAppend  TRUE   Добавляет элемент без проверки на его существованием.
//               FALSE  Перезаписывает элемент если он существует (по умолчанию).
//
// Возвращает 0 при успехе или код ошибки.
//
// Примечание: Режим добавления элементов является более быстрым, поэтому его можно
// использовать для начального заполнения таблицы. Данный режим
// позволяет сохранять несколько значений для одного и того же номера элемента.

INT FUNCTION TableSet(INT hTable, INT nElement, STRING sValue, INT bQuickAppend = FALSE)
   
    STRING sFound = "";

    IF (bQuickAppend = FALSE) THEN
        QuePeek(hTable, nElement, sFound, cQueFindNumber + cQueRemove);
    END
   
    RETURN QueWrite(hTable, nElement, sValue);
   
END


// Прочитать значение элемента из таблицы.
//
// hTable    Хэндл таблицы возвращенный функцией TableCreate().
// nElement  Номер элемента, значение которого необходимо прочитать (любое целое значение).
//
// Возвращает значение элемента. Если элемент не существует, возвращается пустая строка ""
// и генерируется ошибка Cicode

STRING FUNCTION TableGet(INT hTable, INT nElement)
   
    INT nError = 0;
    STRING sValue = "";

    nError = QuePeek(hTable, nElement, sValue, cQueFindNumber);

    IF nError <> 0 THEN
        ErrSetHw(cErrCicode, nError);
    END

    RETURN sValue;

END

// Возвращает количество элементов в таблице.

INT FUNCTION TableLength(INT hTable)
    RETURN QueLength(hTable);
END

// Удаляет последний (самый новый) элемент из очереди и возвращает целое значение
// Эмуляция стека последний пришел/первый вышел

INT FUNCTION TablePopInt(INT hTable)
   
    INT nValue = 0;
    STRING sUnused = "";

    nValue = QueLength(hTable) - 1;
    QuePeek(hTable, nValue, sUnused, cQueFindElement + cQueRemove);
    RETURN nValue;

END


// Удаляет последний (самый новый) элемент из очереди и возвращает строковое значение
// p.s. эмуляция стека последний пришел/первый вышел.

STRING FUNCTION TablePopString(INT hTable)
   
    INT nElement = 0;
    STRING sValue = "";

    nElement = QueLength(hTable) - 1;
    QuePeek(hTable, nElement, sValue, cQueFindElement + cQueRemove);
    RETURN sValue;

END
 
// Сортировка строк таблицы по алгоритму быстрой сортировки.
// Не английские буквы и символы по умолчанию будут отсортированы в соответствии
// с региональными настройками Windows.
// Если установить аргумент bInternational в FALSE, то производительность сортировки
// увеличиться. Более подробно можно посмотреть статью Q3750 базы знаний.

FUNCTION TableSort(INT hTable, INT nFirst, INT nLast, INT bInternational = TRUE)

    INT cQuickAppend = 1;
    INT i = 0;
    STRING sUnused = "";
    INT hStack = TableCreate("TableSortStack");

    TableSet(hStack, nFirst, sUnused, cQuickAppend);
    TableSet(hStack, nLast, sUnused, cQuickAppend);

    WHILE (TableLength(hStack) > 0) DO
        nLast = TablePopInt(hStack);
        nFirst = TablePopInt(hStack);
            IF (nFirst < nLast) THEN
                i = Partition(hTable, nFirst, nLast, bInternational);
                IF (i - nFirst > nLast - i) THEN
                    TableSet(hStack, nFirst, sUnused, cQuickAppend);
                    TableSet(hStack, i - 1, sUnused, cQuickAppend);
                    TableSet(hStack, i + 1, sUnused, cQuickAppend);
                    TableSet(hStack, nLast, sUnused, cQuickAppend);
                ELSE
                    TableSet(hStack, i + 1, sUnused, cQuickAppend);
                    TableSet(hStack, nLast, sUnused, cQuickAppend);
                    TableSet(hStack, nFirst, sUnused, cQuickAppend);
                    TableSet(hStack, i - 1, sUnused, cQuickAppend);
                END
            END
        END

    TableClose(hStack);
   
END

// Вспомогательная функция для функции сортировки TableSort().

PRIVATE INT FUNCTION Partition(INT hTable, INT nFirst, INT nLast, INT bInternational)

    INT cCompareEqual = 2;
    INT cCompareGreater = 3;
    STRING sTemp = "";
    STRING sPivot = "";
    INT iUp = 0;
    INT iDown = 0;

    sPivot = TableGet(hTable, nFirst);
    iUp = nFirst; iDown = nLast;

    WHILE (iUp < iDown) DO
        IF (bInternational = TRUE) THEN
            WHILE ((StrCompare(TableGet(hTable, iUp), sPivot) <= cCompareEqual) AND (iUp < nLast)) DO
                iUp = iUp + 1;
            END

            WHILE (StrCompare(TableGet(hTable, iDown), sPivot) = cCompareGreater) DO
                iDown = iDown - 1;
            END
        ELSE
            WHILE ((TableGet(hTable, iUp) <= sPivot) AND (iUp < nLast)) DO
                iUp = iUp + 1;
            END
           
            WHILE (TableGet(hTable, iDown) > sPivot) DO
                iDown = iDown - 1;
            END
        END

        IF (iUp < iDown) THEN
            sTemp = TableGet(hTable, iUp);
            TableSet(hTable, iUp, TableGet(hTable, iDown));
            TableSet(hTable, iDown, sTemp);
        END
    END

    sTemp = TableGet(hTable, nFirst);
    TableSet(hTable, nFirst, TableGet(hTable, iDown));
    TableSet(hTable, iDown, sTemp);
    RETURN iDown;
   
END


// Вспомогательная функция для функции сортировки TableSort().
// Сравнивает две строки используя региональные настройки Windows.
//
// iMode - режим сортировки (по умолчанию = 0)
//       0x1     Игнорировать регистр букв
//       0x2     Игнорировать непробельные буквы
//       0x4     Игнорировать символы
//       0x1000  Рассматривать знаки пунктуации как символы
//       0x10000 Считать одинаковыми буквы Хирагана и Катакана
//
// Возвращаемое значение:
//       0 ошибка сравнения
//       1 string1 < string2
//       2 string1 = string2
//       3 string1 > string2
//
// Примечание: Для нормальной работы функции требуется Vijeo Citect версии 6.10 и выше. См. статью базы знаний Q3750.

PRIVATE INT FUNCTION StrCompare(STRING sString1, STRING sString2, INT iMode = 0)

    INT cLocaleSystemDefault = 0x400, cNullTerminated = -1;

    IF (mhCompareString = -1) THEN
        mhCompareString = DLLOpen("kernel32", "CompareStringA", "JJJCJCJ");
    END

    RETURN DLLCallEx(mhCompareString, cLocaleSystemDefault, iMode, sString1, cNullTerminated, sString2, cNullTerminated);
   
END



Аватара пользователя
alex
Администратор
Сообщений в теме: 18
Сообщения: 1728
Зарегистрирован: 05 апр 2010, 21:58
Откуда: Москва
Благодарил (а): 45 раз
Поблагодарили: 98 раз
Контактная информация:

Re: Cicode: Пример использования .NET сборок в Cicode

#8

Сообщение alex » 29 ноя 2015, 09:11

Не так давно, а конкретно с версии Vijeo Citect 2015, в Cicode добавлена поддержка вызова методов из .NET сборок, как этот функционал использовать смотрите ниже, на примере вызова метода
Send
Чтобы увидеть ссылку зарегистрируйтесь или войдите под своим логином.
из сборки System.

/*
        (c) 2015 http://www.proasutp.com

        Пример использования .NET сборок в Cicode на примере реализации функции отправки электронного сообщения (email)

        Вход:
            sTo - электронный адрес того, кому отправляется сообщение (например, admin@mail.ru)
            sSubject - тема сообщения
            sMessage - текст сообщения
            sFrom - электронный адрес того, от имени кого отправляется сообщение (например, user@yandex.ru)
            sSMTPServer - адрес SMTP сервера отправителя (например, smtp.yandex.ru)
            iSMTPServerPort - порт SMTP сервера отправителя (например, 25)
            sPassword - пароль, который используется для отправки сообщений через SMTP сервера
           
        Выход:
                Возвращается код ошибки выполнения функции, 0 - успех, не ноль - код ошибки.
*/


INT FUNCTION SendEmail (STRING sTo, STRING sSubject, STRING sMessage, STRING sFrom, STRING sSMTPServer, INT iSMTPServerPort, STRING sPassword)

    STRING sPath = "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\Profile\Client\System.dll";
   
    OBJECT hCredentialsProxy;
    OBJECT hSMTPClientProxy;

    INT iError = 0;
   
    hSMTPClientProxy = DllClassCreate (sPath, "SmtpClient", sSMTPServer);
   
    IF DllClassIsValid (hSMTPClientProxy) THEN
       
        DllClassSetProperty (hSMTPClientProxy, "Port", iSMTPServerPort);
        DllClassSetProperty (hSMTPClientProxy, "UseDefaultCredentials", 0);
        hCredentialsProxy = DllClassCreate (sPath, "NetworkCredential", sFrom, sPassword);
       
        IF DllClassIsValid (hCredentialsProxy) THEN
       
            DllClassSetProperty (hSMTPClientProxy, "Credentials", hCredentialsProxy);
            DllClassSetProperty (hSMTPClientProxy, "EnableSsl", 1);
            DllClassCallMethod (hSMTPClientProxy, "Send", sFrom, sTo, sSubject, sMessage);
            iError = IsError ();
           
        END
   
    END
   
    DllClassDispose (hSMTPClientProxy);
   
    RETURN iError;

END

Примечание: При разработке .Net-сборок и их использовании в проектах Citect SCADA есть нюансы, которые можно узнать из топика Шифровка дешифровка/пароля.



Аватара пользователя
alex
Администратор
Сообщений в теме: 18
Сообщения: 1728
Зарегистрирован: 05 апр 2010, 21:58
Откуда: Москва
Благодарил (а): 45 раз
Поблагодарили: 98 раз
Контактная информация:

Cicode: Объединение двух байт в слово и двух слов в двойное слово

#9

Сообщение alex » 29 ноя 2015, 10:15

Так сложилось, что среди функций Cicode есть функции, которые позволяют получать младшие и старшие части 16-битного слова или 32-битного двойного слова, но нет функций позволяющих объединить два байта в слово или два слова в двойное слово, к этому добавляется еще то, что отсутствуют такие типы переменных как байт и слово. Ниже две функции, которые позволяют устранить данные пробелы...

/*
        (c) 2015 http://www.proasutp.com

        Функция объединяет два младших слова (младшие 16 бит) iHighPart и iLowPart в двойное слово (32 бит)  
*/


INT FUNCTION Combine2Int16bitTo1Int32bit (INT iHighPart, INT iLowPart)
   
    RETURN (LowWord (iHighPart) * Pow (2,16)) + LowWord (iLowPart);

END

/*
        (c) 2015 http://www.proasutp.com

        Функция объединяет два младших байта (младшие 8 бит) iHighPart и iLowPart в слово (16 бит)
*/


INT FUNCTION Combine2Int8bitTo1Int16bit (INT iHighPart, INT iLowPart)
   
    RETURN (LowByte (iHighPart) * Pow (2,8)) + LowByte (iLowPart);

END



Аватара пользователя
alex
Администратор
Сообщений в теме: 18
Сообщения: 1728
Зарегистрирован: 05 апр 2010, 21:58
Откуда: Москва
Благодарил (а): 45 раз
Поблагодарили: 98 раз
Контактная информация:

Cicode: Набор фунцкий для преобразования типов даты и времени между Unity Pro и Vijeo Citect

#10

Сообщение alex » 11 дек 2015, 13:27

/*
    (C) 2015 http://www.proasutp.com

    DataAndTimeConversion.ci - набор функций для преобразования типов даты и времени между Unity Pro и Vijeo Citect
*/


/*
    (C) 2015 http://www.proasutp.com
   
    ConvDateToStr - преобразование даты в формате DATE Unity Pro в строку формата дд.мм.гггг

    Вход:
            nDate - значение даты в формате DATE Unity Pro (дата в DATE представлена в
                    BCD-формате (старшие 16 бит - год, следующие 8 бит, следующие 8 бит - месяц
                    следующие 8 бит - день, младшие 8 бит не используются)
    Выход:
            Дата в формате дд.мм.гггг

*/


STRING FUNCTION ConvDateToStrExt (INT nDate)

    STRING sTemp = "";

    sTemp = HexToStr (nDate, 8);
   
    RETURN StrRight (sTemp, 2) + "." + StrMid (sTemp, 4, 2) + "." + StrLeft (sTemp, 4);

END

/*
    (C) 2015 http://www.proasutp.com
   
    ConvDateToStr - преобразование даты в формате DATE Unity Pro в строку формата дд.мм.гг

    Вход:
            nDate - значение даты в формате DATE Unity Pro (дата в DATE представлена в
                    BCD-формате (старшие 16 бит - год, следующие 8 бит, следующие 8 бит - месяц
                    следующие 8 бит - день, младшие 8 бит не используются)
    Выход:
            Дата в формате дд.мм.гг

*/


STRING FUNCTION ConvDateToStr (INT nDate)

    STRING sTemp = "";

    sTemp = HexToStr (nDate, 8);
   
    RETURN StrRight (sTemp, 2) + "." + StrMid (sTemp, 4, 2) + "." + StrMid (sTemp, 2, 2);
   
END

/*
    (C) 2015 http://www.proasutp.com
   
    ConvStrToDateExt - преобразование даты в формате дд.мм.гггг в формат DATE Unity Pro

    Вход:
            sDate - значение даты в формате дд.мм.гггг
    Выход:
            Дата в BCD-формате (старшие 16 бит - год, следующие 8 бит, следующие 8 бит - месяц
            следующие 8 бит - день, младшие 8 бит не используются)
*/


INT FUNCTION ConvStrToDateExt (STRING sDate)

    RETURN StrToHex (StrRight (sDate, 4) + StrMid (sDate, 3, 2) + StrLeft (sDate, 2));

END

/*
    (C) 2015 http://www.proasutp.com
   
    ConvStrToDate - преобразование даты в формате дд.мм.гг в формат DATE Unity Pro
   
    Вход:
            sDate - значение даты в формате дд.мм.гг
    Выход:
            Дата в BCD-формате (старшие 16 бит - год, следующие 8 бит, следующие 8 бит - месяц
            следующие 8 бит - день, младшие 8 бит не используются)
*/


INT FUNCTION ConvStrToDate (STRING sDate)

    RETURN StrToHex ("20" + StrRight (sDate, 2) + StrMid (sDate, 3, 2) + StrLeft (sDate, 2));
   
END

/*
    (C) 2015 http://www.proasutp.com
   
    ConvTimeToStrExt - преобразование времени в формате TIME Unity Pro в строку с миллисекундами

    Вход:
            nTime - значение времени в формате TIME Unity Pro (в миллисекундах)
    Выход:
            Время в формате чч:мм:сс:ммм
*/


STRING FUNCTION ConvTimeToStrExt (INT nTime)

    INT hours = 0, mins = 0, secs = 0, msecs = 0, temp = 0;

    hours = nTIME / 3600000;                // Часы
    temp = nTIME - (hours * 3600000);
    Mins = temp / 60000;                    // Минуты
    secs = (temp - (mins * 60000)) / 1000;  // Секунды
    msecs = nTIME MOD 1000;                 // Тысячные
   
    RETURN IntToStr (hours) + ":" + StrRight ("0" + IntToStr (mins), 2) + ":" + StrRight ("0" + IntToStr (secs), 2) + "." + StrRight ("00" + IntToStr (msecs), 3);

END

/*
    (C) 2015 http://www.proasutp.com
   
    ConvTimeToStr - преобразование времени в формате TIME Unity Pro в строку без миллисекунд

    Вход:
            nTime - значение времени в формате TIME Unity Pro (в миллисекундах)
    Выход:
            Время в формате чч:мм:сс
*/


STRING FUNCTION ConvTimeToStr (INT nTime)

    INT hours = 0, mins = 0, secs = 0, temp = 0;

    hours = nTime / 3600000;                // Часы
    temp = nTime - (hours * 3600000);
    Mins = temp / 60000;                    // Минуты
    secs = (temp - (mins * 60000)) / 1000;  // Секунды
   
    RETURN IntToStr (hours) + ":" + StrRight ("0" + IntToStr (mins), 2) + ":" + StrRight ("0" + IntToStr(secs), 2)

END

/*
    (C) 2015 http://www.proasutp.com
   
    ConvStrToTimeExt - преобразование строки со временем в формате чч:мм:сс:ммм в расширенный формат типа TIME Unity Pro

    Входа:
            sTime - значение времени в формате чч:мм:сс.ммм
    Выход:
            Время в формате TIME Unity Pro в миллисекундах
*/


INT FUNCTION ConvStrToTimeExt (STRING sTime)

    RETURN StrToInt (StrLeft (sTime, 2)) * 3600000 + StrToInt (StrMid (sTime, 3, 2)) * 60000 + StrToInt (StrMid (sTime, 6, 2)) * 1000 + StrToInt (StrRight (sTime, 3));

END

/*
    (C) 2015 http://www.proasutp.com

    ConvStrToTime - преобразование строки со временем в формате чч:мм:сс в нормальный формат TIME Unity Pro

    Вход:
            sTime - значение времени в формате чч:мм:сс.
    Выход:
            Время в формате TIME Unity Pro в миллисекундах
*/


INT FUNCTION ConvStrToTime (STRING sTime)

    RETURN StrToInt (StrLeft (sTime, 2)) * 3600000 + StrToInt (StrMid (sTime, 3, 2)) * 60000 + StrToInt (StrRight (sTime, 2)) * 1000;

END

/*
    (C) 2015 http://www.proasutp.com

    ConvTODToStr - преобразование времени в формате TOD (Time of Day) Unity Pro в строку
   
    Вход:
            lTOD - значение времени в формате TOD Unity Pro

    Выход:
            Время в формате чч:мм:сс
*/


STRING FUNCTION ConvTODToStr (INT nTOD)

    STRING sTemp;

    sTemp = HexToStr(nTOD, 8);
   
    RETURN StrLeft (sTemp,2) + ":" + StrMid (sTemp, 2, 2) + ":" + StrMid (sTemp, 4, 2);

END

/*
    (C) 2015 http://www.proasutp.com

    ConvStrToTOD - преобразование строкового представления времени в формат TOD (Time of Day) Unity Pro

    Вход:
            sTOD - значение времени в формате чч:мм:сс.
    Выход:
            Время в BCD-формате (часы (старшие 8 бит), минуты (следующие 8 бит),
            секунды (следующие 8 бит), остальные младшие 8 бит не используются)
*/


INT FUNCTION ConvStrToTOD (STRING sTOD)

    RETURN StrToHex (StrLeft (sTOD,2) + StrMid (sTOD, 3, 2) + StrRight (sTOD,2) + "00");

END




Если эта тема может быть полезна другим, поделитесь ссылкой:

Вернуться в «Citect SCADA, Vijeo Citect, CitectSCADA, CitectFacilities, PowerLogic SCADA, PowerSCADA, MX4SCADA, Desigo Insight»