Вы находитесь на странице: 1из 13

AVEVA

PML для начинающих


Предупреждение

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

Это также для начинающих специалистов, кто не знаком с программированием вообще, и для тех, кто уже умеет
выполнять базовые операции. Опытные PML-программисты возможно тоже найдут для себя несколько интересных
моментов

И конечно, этот справочник предназначен для администраторов AVEVA, специалистов, которые обязаны иметь эти
знания, чтобы выполнять свою работу на профессиональном уровне.

Этот справочник не должен быть использован как учебное руководство. Он дает только базовые представления о
том, что такое PML и простейших конструкциях языка. Специалист должен пройти учебный курс AVEVA M33,
посвященный подробному изучению свойств языка PML.

В этом справочнике не рассматривается создание пользовательских интерфейсов в виде форм, и не


рассматривается создание функций. Это будет рассмотрено в другом справочнике.

Введение
PML (Programmable Macro Language) или макроязык систем AVEVA PDMS/Marine
является встроенным языком программирования, который:
 Выполняет действия, которые пользователь выбирает с помощью интерфейса
системы. Это функции расположены в месте установки системы в папках
PMLLIB и PDMSUI и не должны подвергаться изменению пользователем. К
примеру, когда пользователь нажимает какую-либо кнопку на форме, это
значит, что будет выполнен некий PML код, связанный с этой кнопкой.
 Используется в любых пользовательских макросах или функциях, которые
могут быть разработаны любым пользователем с минимальными знаниями
программирования. Пользовательские макросы или функции, как правило
реализуют различные задачи, которые базово не включены в набор функций
системы, то есть своего рода расширение функционала для конкретных
задач. К примеру, пользователь может создать свой собственный интерфейс
в виде набора форм, специальных функций и т.д)
 Может автоматизировать практически любые действия, которые повторяются
пользователем из дня в день и занимают время (далее по тексту, такие
макросы будут называться «Быстрый Макрос или БМ)

Автор: Сергей Лебедев


AVEVA

Основные два мануала, которые описывают PML, называется Software Customisation


Guide по базовых функциях PML и Software Customisation Reference Manual по
объектам PML2, их методам и свойствам. Оба мануала входят в поставку системы.

Любой пользователь может изучить PML, так как при изучении не требуется
профессиональных знаний программирования, а только понимание следующего:
 Концепция иерархии базы данных AVEVA - Dabacon
 Типизация элементов AVEVA внутри Dabacon
 Атрибутивная составляющая элементов AVEVA, зависимости и ссылки
 Общая терминология AVEVA и наиболее часто используемые сокращения и
термины (см. Приложение 1)

Пользователь, желающий изучить и использовать PML должен иметь общие базовые


знания по системе и быть знакомым с описанными выше позициями. К примеру,
пользователь не должен смущать слов «уровень EQUI» или «уровень ZONE», или
«атрибуты» или «Пи-точки». Все эти вещи рассказываются на базовом курсе по
работе с системой. Для того, чтобы записаться на курс, свяжитесь с АВЕВА.
http://www.aveva.com/ru-RU/Contact.aspx
В дополнение необходимо понимать на общем уровне значение терминов:
переменная (variable), условный оператор (if), цикл (do). Это также будет объяснено
здесь в общих словах.

Существует две версии языка PML – PML 1 и PML2. Не вдаваясь глубоко в детали,
хотим сказать, что в отличии от PML1, PML2 является объектно-ориентированным
языком, то есть общается с элементами модели, как с объектами. В данном
справочнике, будет основной акцент сделан именно на конструкция языка PML2,
учитывая его большую актуальность и тот факт, что основной интерфейс системы
написан именно на PML2. В тоже самое время в справочнике могут встречаться
конструкции, которые принадлежат PML. Такие конструкции будут выделены
отдельно.

Для того, чтобы создавать PML программы необходимо использовать подходящий


текстовый редактор с подсветкой синтаксиса и номеров строчек. Автор использует
бесплатный редактор Notepad++

Предупреждение: Нельзя редактировать стандартные PML-файлы в папке


установки системы.

Автор: Сергей Лебедев


AVEVA

Предупреждение: Необходимо использовать систему именования макро-файлов и


переменных для удобства навигации и предотвращения конфликтов с
существующими переменными. Некоторые правила:
 Всегда используйте уникальный префикс в имени файла. Автор испольует
свои инициалы (lsa) - lsamymacro.pmlmac , чтобы сделать файлы
уникальными. Или другой пример, сокращение название компании
- xyzmymacro.pmlmac
 Хотя и необязательно, но рекомендуется использовать расширение .pmlmac
для файлов, содержащих обычные макросы.
 Начиная с версии 12.1 все PML-файлы должны быть в кодировке UTF-8

Базовые функции и определения


1.Переменные
Variables used to store values.
Variables have names.
The value that is stored can be changed but the name of the variable is fixed once it is
defined.
You choose the names and decide what is stored by each variable.
Values can have different types like Integer or String.
Values with different types should be converted to same before processing.

By analogy, the variable could be interpreted as a ‘box’ where you put something to or take something
from. And this ‘box’ has a name to clearly identify what is stored inside. And boxes with same type of
content could interact to each other.

Names of variables in PML should start with ‘!’ symbol and have meaningful name.
Examples:
!boxHeight
!boxDescription
!equipName
etc

To assign a value to variable (to put something in a ‘box’) you have to decide what
type of data it will be.
Most used types are:

 <STRING> - the value should be put within single quotes or vertical bars, could
not be used in arithmetical expressions unless converted to <REAL>

Автор: Сергей Лебедев


AVEVA

 <REAL> - any integer value, could be used I arithmetical expressions. Could not
be used in string operations unless converted to <STRING>
 <DBREF> - this is a special PDMS type pointed to an object in database with all
its attributes

There are many others but we will use this on start.

To assign value use ‘=’ and value:


!boxHeight = 1000
Here we created variable called !boxHeight and assign a value 1000 with no single quotes, as a digits so it means
variable !boxHeight will have a <REAL> type

!boxDescription = ‘This is my box’


Here we created variable called !boxDescription and assign a value ‘This is my box’ within single quotes, so it means
variable !boxDescription will have a <STRING> type

!equipName = /E1201
Here we created variable called !equipName and assign a value /E1201 with no single quotes but with a slash in front,
so it means variable !equipName will have a <DBREF> type
NB. Pointing the slash as a first symbol will automatically give to the system a signal that you try to refer to some item
with this name. So if there is no item with such name then it will be an error.

Now we have three variables of different types. So what can we do with them? Lets
review some arithmetical operations… Like it was said before only variables with type
<REAL> can be involved into these operations. All others should be converted to
<REAL> (if possible) before.

The following example will be used to find a volume (V) of a box with known different
sides (a,b,c)

The formula for calculating of box volume is:

V = a*b*c

So let do some practice using variables in PML…

Автор: Сергей Лебедев


AVEVA

Example 1. Values of variables are hardly defined in code


First, define three variable of <REAL> type. Imagine we know their values and they are
constant

!aSide = 1000
!bSide = 500
!cSide = 300

Now we have to create an arithmetical expression for calculation and result should be
stored in another variable. Normally it could be done like:

!boxVolume = !aSide * !bSide * !cSide

So we defined variable !boxVolume which will store result of calculations of several


variables
Let check it in PDMS.
Create a file called regarding your naming conventions (in my case it will
lsaPML1.pmlmac) in any folder you have access (in my case it will be
c:\temp\pmlexamples\) with following code:

!aSide = 1000
!bSide = 500
!cSide = 300

!boxVolume = !aSide * !bSide * !cSide

q var !boxVolume

Автор: Сергей Лебедев


AVEVA

The last command means to query (q) early-defined variable (var) with some name.
Result of querying will be output to PDMS’s command line.

Now try to run this. Open command line and type - $M/path_to_your_file
In my case it will be - $M/C:\temp\pmlexamples\lsaPML1.pmlmac

And look at result!

NB.By default all dimension and distance units are in mm.

NB.Nearly every variable storing non-<STRING> type of data can be converted to


<STRING>
Only digits stored as a <STRING> can be converted to <REAL>

This is your first PML program!

Example 2. Values of variables input by user


In first example, values of variables were defined within PML code as constants.
However, variables called variables because then can change their values. So in our
second example we will review how the program can interact with user let him put
values. We will use alerts for that.

Alert – is a message popping up on a screen and asking user to interact. In our case we
will use Input dialog. Let see how it works.

Imagine the situation when our volume has 2 constant sides (a,b) and one which could
vary by user input. Then our code will look like:

Автор: Сергей Лебедев


AVEVA

!aSide = 1000
!bSide = 500

!cSide = !!Alert.Input(‘Please input the C-side’,’300’)


Here we created variable called !cSide which accept value after user put something in dialog window. 300 is a default
value.
NB. Value you put in dialog window will have type <STRING> means !cSide variable will have type <STRING> then in our
further calculation we will have to convert it to <REAL>.

Complete code will look like

!aSide = 1000
!bSide = 500
!cSide = !!Alert.Input(‘Please input the C-side’,’300’)

!boxVolume = !aSide * !bSide * !cSide.Real()

q var !boxVolume

Save this code to next macro file and run in PDMS like it was done previously with $M/

Using ‘.’ and some method we can do some operation applying it to variables of
different type. In example we used method .Real() applied to <STRING> variable to
convert it into <REAL>. Full list of methods listed in Software Customisation Reference
Guide

Feeling the magic already? To be continued 

2.IF statements
IF statement is used to let the system compare two values and by the result of
comparison we can select what to do.
Normally values of variables are compared.
<REAL> should be compared with <REAL>, <STRING> with <STRING> etc.

Автор: Сергей Лебедев


AVEVA

Result of comparison is TRUE (statement is TRUE) or FALSE (if statement is FALSE)

By analogy, remember our ‘variable-box’? Imagine that one ‘box’ contains an apple and other ‘box’
contains a peach. You want to eat an apple but you don’t know which ‘box’ stores it. You have to check.
So you put your arm into one box and IF you find an apple THEN you eat it ELSE (peach) you do nothing.

In very basic IF statement looks like:


If (comparison_expression) then
And in between you have to put PML code which will be executed if
comparison_expression is TRUE
Else
Do something else
Then close statement with
endif

Each IF should have its ENDIF!

Example 3. Do some action depends on variable value


Imagine the situation that we have to show some message to user if the value some
variable equal to 2. And another message if it is differs from 2. And we let user input
this variable

!userVariable = !!Alert.Input(‘Please input the any value’,’3’)


Here we let user input value for variable !userVariable

Now we will compare the value of the input with 2. Not forgetting to convert input to
<REAL>
If (!userVariable.Real() EQ 2) then
!!Alert.Message(‘You have input correct value’)
Else
!!Alert.Message(‘You have input incorrect value. Please put 2’)
RETURN
endif
Here we used IF statement to check if our input variable is EQual to 2. We have used EQ operator to check for equality.
If result of statement is FALSE then we un another message and quir from the program execution by using command
RETURN. We user another type of Alert – Message to output a simple message on a screen)

Complete code will look like:


!userVariable = !!Alert.Input(‘Please input the any value’,’3’)
If (!userVariable.Real() EQ 2) then
!!Alert.Message(‘You have input correct value’)
Else
!!Alert.Message(‘You have input incorrect value. Please put 2’)

Автор: Сергей Лебедев


AVEVA

RETURN
endif
Save this code to next macro file and run in PDMS like it was done previously with $M/

Operators used in comparison are:


 EQ – check for equality (all type)
 NEQ – check for non-equality (all types)
 GT – Greater Than (for <REAL>)
 GEQ – Greater or EQual (for <REAL>)
 LT – Less Than (for <REAL>)
 LEQ – Less or EQual (for <REAL>)

Quick examples of comparisons. Imagine we have two variable one is called


!realVariable which stores some <REAL> value and the other is !stringVariable which
stores some <STRING> value. And we will compare them to some values.

If (!realVariable EQ 10) then


Do something if !realVariable value is 10
Endif
If (!realVariable NEQ 10) then
Do something if !realVariable value is not 10
Endif

If (!stringVariable EQ ‘a string’) then


Do something if !stringVarialbe is ‘a string’
endif
If (!stringVariable NEQ ‘a string’) then
Do something if !stringVarialbe is not ‘a string’
endif

3.DO LOOP
DO LOOP is used to perform actions over multiple (collection) items
Usually collection is an ARRAY variable each cell of which contains some data of
particular type like ARRAY of <STRING>s or ARRAY of <REAL>s.

To define array you can use a simple construction like:


!arrayOfStrings[1] = ‘String1’
!arrayOfStrings[2] = ‘String2’
!arrayOfStrings[3] = ‘String3’
Here we have defined an array of three cells. Each cell has a value of <STRING> type

Автор: Сергей Лебедев


AVEVA

By analogy, remember our ‘variable-box’? Imagine that this ‘box’ contains 10 apples and we have to check
if all ten are fresh. We can do it by picking them up one by one and do check. DO LOOP is doing the same
– you have a collection and one by one you doing same actions on each item in collection

Very basic DO LOOP could look like:


Do !x from 1 to 10
Do here something 10 times
enddo
We have started DO LOOP which has its start from 1 index and do some actions 10
times

Each DO should have its ENDDO!

Example 4. Output 5 messages with index number one by one


Imagine the situation that we have to show 5 messages to user. On each message, you
have to show index number from our DO LOOP

--start our do loop counting from 1 till 5


Do !x from 1 to 5
!!Alert.Message(‘Next index number is ‘ + !x.String)
Enddo
Here we used output of a message with concatenation of two strings – constant string between single quotes and
variable called !x which is DO LOOP index and which is changing its value from 1 to 5 with step 1 (1 2 3 4 %)

As a result, you will get 5 messages on a screen. One by one until DO LOOP ends on 5

4.COMBINATIONS
You can now combine IF statement and DO LOOP.

Example 5. Check number from 1 to 5 and output only even values


Imagine the situation that we have to output in a message only even values from a
range. Here is a code with comments how to do it

--Let first define a constant ARRAY of digits

!digitArray[1] = 1
!digitArray[2] = 2
!digitArray[3] = 3
!digitArray[4] = 4
!digitArray[5] = 5

Автор: Сергей Лебедев


AVEVA

--Now we have an array of 5 cells. That means Size of array equal to 5.


--Now we have to pass thru each cell of arrya, check it values and if it is even – output it
--To do it we now define DO LOOP counting from 1 to ??
--TRUE! the end of DO LOOP will be a size of array (that is number of cells).

--To get the Size we will introduce another variable for storing this values can use a method called .Size() applied to
earlier defined ARRAY
--Here it is:

!digitArraySize = !digitArray.Size()

--Now start do loop:

Do !x from 1 to !digitArraySize

--To understand if the value is even or odd we have to take value and try to divide by 2
--if result of the division will contain a decimal point then value was odd otherwise it was even
--lets do it

--first make a division (remember in each iteration !x will have a next value) and this is <REAL> type

!resultOfDivision = !x / 2

--check for point. We will use MATCHWILD method which is applied to STRING object to find if there something we’d
like to find
--so we also will be converting result of division stored in previous variable to <STRING> type

!isThereAPoint = !resultOfDivision.String().Matchwild(‘*.*’)
--so previous variable will store TRUE if variable !resultOfDivision contain point and FALSE – if not

--now start IF statement to make action depends on !isThereAPoint variable’s value


--and we will be using SKIP to let DO LOOP skip current index and take next if value is odd

If (!isThereAPoint NEQ TRUE) THEN


--If its even then compose and output a message

!!Alert.Message(‘Value is ‘ + !x.String() + ‘ and its even.’)


Else
SKIP
endif

Enddo

Complete code look like


!digitArray[1] = 1
!digitArray[2] = 2
!digitArray[3] = 3
!digitArray[4] = 4
!digitArray[5] = 5

Автор: Сергей Лебедев


AVEVA

!digitArraySize = !digitArray.Size()

Do !x from 1 to !digitArraySize

!resultOfDivision = !x / 2

!isThereAPoint = !resultOfDivision.String().Matchwild('*.*')

If (!isThereAPoint NEQ TRUE) THEN


!!Alert.Message('Value is ' + !x.String() + ' and its even.')
Else
SKIP
endif

Enddo

Or we can even shorten to skip intermediate variables like


!digitArray[1] = 1
!digitArray[2] = 2
!digitArrya[3] = 3
!digitArray[4] = 4
!digitArray[5] = 5

Do !x from 1 to !digitArray.Size()

!resultOfDivision = !x / 2

!isThereAPoint = !resultOfDivision.String().Matchwild('*.*')

If (!resultOfDivision.String().Matchwild('*.*').Not()) THEN
!!Alert.Message('Value is ' + !x.String() + ' and its even.')
Else
SKIP
endif

Enddo

Or even shorter
--put number in a <STRING> then split it and get array
!stringNumber = ‘1 2 3 4 5’
!digitArray = !stringNumber.Split()

Do !x from 1 to !digitArray.Size()

Автор: Сергей Лебедев


AVEVA

!resultOfDivision = !x / 2

!isThereAPoint = !resultOfDivision.String().Matchwild('*.*')

If (!resultOfDivision.String().Matchwild('*.*').Not()) THEN
!!Alert.Message('Value is ' + !x.String() + ' and its even.')
Else
SKIP
endif

Enddo

TO BE CONTINUED…

Автор: Сергей Лебедев

Вам также может понравиться