3.19. Methods on User-Defined Object Types

Response:
AVEVA PDMS Programmable Macro Language manual
  2016 v.1. Page 24/178  define function !!AnyType(!Argument is ANY)
  Type = !Argument.pmlobjectType()
  if ( !Type EQ 'STRING' ) then
    - - do something with a STRING
  elseif ( !Type EQ 'REAL' ) then
    - - do something with a REAL
  elseif ( !Type EQ 'DBREF' ) then
    - - do something with a DB Reference
  else
    - - do something with all other types or give a n error
  endif
endfunction
 A PML Procedure is a PML Function that does not re turn a result. A function is defined as
a procedure by omitting the data type at the end of  the define function statement:

define function !!Area( !Length is REAL, !Width is REAL, !Result is REAL)
  !Result = !Length * !Width
endfunction

Here we are using an output argument, !Result, to r eturn the result rather than using a
function return value. The arguments to the !!Area procedure can be set as follows, and then
the procedure invoked with the call command.

!SurfaceArea = REAL()
!Partlength = 7
!PartWidth = 6
call !!Area(!PartLength, !PartWidth, !SurfaceArea)

There will be an error if you attempt to assign the  result of a PML Procedure because there
is no return value to assign. So, for example you c an say:

call !!Area(!PartLength, !PartWidth, !SurfaceArea)
!Answer = !SurfaceArea

But you cannot say:

!Answer = !!Area(!PartLength, !PartWidth, !SurfaceA rea)
$* WRONG

The ( ) parentheses after the name of a procedure o r function must always be present even
for procedures that do not need arguments:

define function !!Initialize()
  !TotalWeight = 0
  !!MaxWeight = 0
endfunction
call !!Initialize()

Although the call keyword is strictly speaking opti onal, its use is recommended with
procedures.

Note:  As well as procedures, you can invoke a PML Functi on that has a return value using
call, in which case the function result value is di scarded.


Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 26/178 define method . Life() ! This.Answer = 42 Endmethod  A method may return a result in just the same way a s a PML Function using the returnCommand. Set a member of the object using! This.mem bername.  Define method. Answer() IS REAL Return! This.Answer Endmethod  Define method. Answer( ! Value Is REAL) ! This.Answer =! Value Endmethod  These methods might be used in the following way:! Marvin = object LIFE() -- The method . Life() was called automatically ! Number = ! Marvin.Answer() --! Number is set to the value 42 ! Marvin.Answer(40) ! Number = ! Marvin.Answer() --! Number now has the value 40  Warning: When you create a new objeCt type, or chan ge an existing definition, you Must load the definition by giving the command:  Pml reload object _name_ Two or more methods on an object may share the sam e name providing they have Different arguments. This is called method overload ing.PML will invoke the method with the Arguments which match the method call. It is common practice:  • To use a method with the same name as a member and one argument of the same Type to set the member's value. For example:  ! Marvin.Answer(65)  •To use a method of the same name as a member retur ning a value of the same type But with no arguments to get the member's value. Fo r example:  ! Number = ! Marvin.Answer() When an object is created, it is possible to suppl y arguments that are passed by PML to aConstructor method with matching arguments instead of the default constructor method:  ! Marvin = object LIFE(40)  This would invoke a method:  Define method. Life(! Value IS REAL)


3.23. Invoking a Method from Another Method

Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 27/178 3.22. Overloading with ANY As with PML Functions, the type of a methOd argume nt may be specified as ANY. Yew Method overloading is being used, PML will invoke t he method with a matching set of Explicitly typed arguments in preference to calling a method with arguments of type ANY, Irrespective of the order the methodsAppeared in t he object definition file:  Define method. SetValue(! Argument Is ANY) Define method. SetValue(! Argument Is REAL)  Then: ! SomeObject.SetValue(100) will invoke the method with the REAL argument, but ! SomeObject.SetValue('Priceless' )Will invoke the method with the ANY argument. Within a method! This.Methodname() refers to anoth er method on the same object. So Our second LIFE constructor method, the one with an argument, could be defined as:  Define method. Life(! Value IS REAL)! This.Answer(! Value) Endmethod Whenever you add a new method to an object, you ne ed to tell PML to re-read the object Definition, by giving the command:  Pml reload object life  It is not necessary to use this command if you are simply editing an existing method(Although you will have to use it if you edit a for m definition file, and change the default Constructor method, described in Form Definition Fi le.) In PML 2, forms are a type of global variable. Thi s means that a form cannot have the Same name as aNy other global variable or any other form. Note that a form definition is also The definition of an object, so a form cannot have the same name as any other object type.


Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 28/178 4. ARRAYs in PML An ARRAY variable can contain many values, each of which is called an array element. YearArray is created automatically by creating one o f its array elements.  ! Array = Array()  This is an empty variable but it has been defined a s an array. Adding elements to the array:  Type 1 ! Array[1] = 'BOB'! Array[2] = 45! Array[10] = !! C E Type 2! Array.Append('BOB')! Array.Append(45)! Array.Appe nd(!! CE)  Type 1 adds string values into exact position of a rray element (1,2 and 10). Type2 add String values to the end of lists (11,12,13). To ch eck array list query:  Q var! Array <ARRAY> [1] <STRING> 'BOB'[2] <REAL> 45 [10] <DBREF> 'KELLY' [11] <STRING> 'BOB' [12] <REAL> 'GEORGE' [13] <DBREF> 'KELLY'  To check exact array member query:  Q var! Array[1] <STRING> 'BOB'  Note: How array elements are referred to by means of a s ubscript expression in [ ] squareBrackets and that there must be no space between th e end of the array name and the Subscript. Array elements are accessed in the same way when using the value in an Expression:  ! Average = ( ! Sample[1] +! Sample[2] +! Sample[3] ) / 3 )  The individualUal elements of an array variable can be set independently and in any order. Thus You can set! X[1] and ! X[10] without setting any of the intervening elements! X[2] to! X[9]. In Other words PML arrays are allowed to be 'sparse' a nd to have gaps between the subscriptNumbers which have values set. Negative subscripts are no longer permitted. An array Subscript of zero is allowed but you are advised ag ainst using it as many of the array Facilities ignore array element zero. An array subs cript may be an expression of anyComplexity provided it evaluates to a positive REAL result and may even include a call to a PML Function:  ! Value = ! MyArray[! A + (! B * !! MyFunction() ) + ! C ]  PML Arrays may be heterogeneous. That is to say the elements of a PML array do not haveTo be all of the same type. Array elements may even be user-defined objects. Values to be Concatenated are automatically converted to STRING by the '&' operator. Type the following Onto the command line: Non-existent array elements - after the last set element of the arrayAnd the non-existent elements in the gaps of a spar se array - are all UNDEFINED: the Function Undefined() will return TRUE and the funct ion Defined() will return FALSE for all These subscripts.


Response:
AVEVA PDMS Programmable Macro Language manual
  2016 v.1. Page 29/178  4.1. Array methods
 Array methods are built-in functions for performin g a variety of operations on the array.
These methods are invoked with a dot following the array name. The method name must be
followed by ( ) parentheses - even if the function has no arguments. Array methods :

• !Array.Size()
• !Array.Clear()
• !Array.RemoveFrom(x,y)
• !Array.Append()
• !Array.Delete() or !Array[N].Delete()
• !Array.Split()
• !Array.Width()
• !Array.Sort()
• !Array.Inver()
• !Array.SortUnique()
• !Array.Unique()

Note:  Always use an array method, if one is available, i n preference to constructing a do
loop as it is far more efficient.

!Nelements = !MyArray.Size()
This method sets !Nelements to the number of elemen ts currently in the array. Its returns a
REAL result which can be assigned to another variab le.

!MyArray.Clear()
This is an example of a method which modifies the a rray by deleting all the array elements
but produces no-result value, so there is nothing t o assign to another variable.

!NewArray = !OldArray.RemoveFrom(5,10)
This is an example of a method result which modifie s the array by removing 10 elements,
starting at element 5. NewArray value is a new arra y containing the 10 removed elements. If
not required, the result can be simply discarded by  invoking the method as a command and
not assigning the result to a variable: !OldArray.RemoveFrom(5,10)

!Result.Append(!NewValue)
To set a new element at the end of an existing arra y without needing to know which
elements are already set, use the Append() method. The new array element to be created is
determined automatically by adding 1 to the highest  existing index for the array !Result. The
data are stored in !Result[1] if the array does not  yet contain any elements. The array !Result
must exist before you can call this method. If nece ssary you can create an empty array (with
no elements) beforehand: !Result = ARRAY() .If !Res ult exists already as a simple variable,
you will get an error and the command is ignored.

!MyArray[N].Delete()
To destroy an array element use the Delete() method . The deleted array element would test
as UNDEFINED. Note that the array continues to exis t even when you have deleted all its
elements. Deleting the entire array, together with any existing array elements, use the Delete
method on the array itself: !MyArray.Delete()

!ArrayOfFields = !Line.split()
You can split a text string into its component fiel ds and store each field in a separate array
element using a text string’s Split() method. This can be useful after reading a record from a
file into a variable. By default, the delimiter is any white-space character (tab, space or


Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 30/178 newline): ! Line = '123 456 789' The white-space is treated as a special case since Consecutive white-spaces are treated as a single deLimit and white-spaces at the start or Finish of the string are ignored. The result is to create the array-variable! ArrayOfFields (if it Does not already exist) with the element! FIELDS[1] set to '123', ! FIELDS[2] set to '456', and ! FIELDS[3] set to '789'.To specify a different del imiter, specify the required (single) Character as the argument to the Split() method:  ! Line = '123 ,456 ,,789' ! ArrayOfFields = ! Line.split(',') In this example, comma is used as the delimiter. ! A rrayOfFields is created if it does notAlready exist with the element! FIELDS[1] set to '1 23', ! FIELDS[2] set to '456', ! FIELDS[3] Created but set to zero length, and! FIELDS[4] set to '789'. Note that in this case, unlike the White-space delimiter, consecutive occurrences of t he comma define empty elements.Note: The only way to set the special white-space delimit er is by default; that is, by not specifying Any delimiter as an argument to the Split() method. If a space is specified explicitly as the Delimiter (as ' '), it will behave in the same way as comma in this example.You can combine An array-append method with a text-string Split() m ethod in a single command to append the Fields of a text string to the end of an existing a rray variable, thus: ! ArrayOfFields.AppendArray(! Line.Split())  ! Width = ! List.width() ThE length of the longest element in an array can b e a useful thing to know, for example When you are outputting the values in table form. Y ou can do this using the Width() method. For example, in the array! LIST: ! LIST[1]'One'! LIST[2]'Two'! LIST[3]'Three'The command: ! Width = ! List.width() would set to! Width to the v alue 5, the length of the longest element in ! LIST, which is 'Three'. Note: If the array contain ed elements that were not strings, these are Ignored when calculating the maximum width. ! MyArray.Sort() & ! MyArray.Sort(). Invert() The simplest way of sorting an array is to use the Sort() method: ! MyArray.Sort() This is a No-result method that modifies the array by perform ing a sort in-situ. The sort is into Ascending order and will be aN ASCII sort on an arr ay of STRING elements and a NUMERIC Sort on an array of REAL values. The Sort() method returns the array itself as a list result, so It is possible to follow the call to the Sort() met hod immediately with a call to the Invert() MEthod, which will return a descending sort: ! MyArr ay.Sort(). Invert(). An alternative Approach is an indirect sort using the method Sorte dIndices() which returns a REAL array Representing new index positions for the array elem ents in their sorted positions:! NewPositions = ! MyArray.SortedIndices() The array can be sorted by applying the new Index values using the ReIndex() method: ! MyArray.R eIndex(! NewPositions) More important, The index values in! NewPositions can be used to so rt other arrays as well. To use some simple examples, imagine we had the arr ay! Animals that contained: [1] Wombat [2] Kangaroo [3] Gnu [4] Aardvark [5] An telope  The command: ! Animals.Sort ()  Would move the array elements so that they now appe ared in the following order:[1] Aardvark [2] Antelope [3] Gnu [4] Kangaroo [5] Wombat  The command: ! Animals.Invert () invert the sort to the following order: [1] Antelope [2] Aardvark [3] Gnu [4] Kangaroo [5] Wombat


4.3. Subtotaling Arrays with the VAR Command

Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 31/178 4.2. Sorting Arrays using the VAR Command These facilities were dSigned to work with arrays of STRINGS. Where a multi-level sort Is required it is still necessary to use the older facilities of the VAR command to perform the Comes out. Using a different example, look at the arrays! Because,! Colour and! Year:  VAR! Index SORT!Because CIASCII! Colour! Year NUMERIC  Sorting Option Effect CIASCII Sorts in ascending case-independent alphabe tic order. DESCENDING Sorts in alphabetic in reverse order CIASCII DESCENDING Sorts in descending case-indepen dent alphabetic order. NUMERIC Forces an ascending numerical sort on numbe rs held as strings. NUMERIC DESCENDING Forces a descending numerical so rt on numbers held as strings.  You can also modify the array to eliminate empty or repeated elements:  UNIQUE - Eliminates instances of duplicated data.For exa mple:  VAR! Unique SORT Index! Because CIASCII! Colour! Year N UMERIC  NOUNSET NOEMPTY - Eliminates rows that contain only UNSET values.  VAR! Index SORT NOUNSET! Because CIASCII! Colour! Year NUMERIC  To sort these arrays and identify the last oCcurren ce of each group of the same car type, use The LASTINGROUP option:  VAR! Index SORT! Because LASTINGROUP! Group Suppose we had sorted the array! Car and another ar ray! Value using the command:  VAR! Index SORT! Because! Value LASTINGROUP! Group We can then generate an array of subtotals for each type of car with the following command:  VAR! Totals SUBTOTAL! Values! Index! Group  VAR! Variable SUBTOTAL - This will sum value strings that contain values with or without Unit qualifiers. Unit qUalifiers within the strings will be ignored. This is to allow REPORTER to Still operate with unit qualified value strings tha t may have been introduced by other VAR or $! Variable commands.  VAR! Variable EVALUATE - Will return string variables andArrays of unit qualified values if The evaluation generates quantities with physical d imensions. VAR! D EVAL (DIAM) for all CYLI - sets! D to a set of strings such as '90cm' ' 60cm' etc. - when cm are the current length Units). The unit will be the current working unit.VAR! Variable ATTRIBUTE This sets the variable to a string that contains t he value AND The unit qualifier for attributes with of a physica l quantity VAR! X XLEN sets! X to '46cm' if Current units are cm) The unit will be the current working unit.


Response:
AVEVA PDMS Programmable Macro Language manual
  2016 v.1. Page 31/178  4.2. Sorting Arrays using the VAR Command
 These facilities were designed to work with arrays  of STRINGS. Where a multi-level sort
is required it is still necessary to use the older facilities of the VAR command to perform the
sort. Using a different example, look at the arrays  !Car, !Colour and !Year:

VAR !Index SORT !Car CIASCII !Colour !Year NUMERIC

 Sorting   Option Effect
CIASCII Sorts in ascending case-independent alphabe tic order.
DESCENDING Sorts in alphabetic in reverse order
CIASCII DESCENDING Sorts in descending case-indepen dent alphabetic order.
NUMERIC Forces an ascending numerical sort on numbe rs held as strings.
NUMERIC DESCENDING Forces a descending numerical so rt on numbers held as strings.

You can also modify the array to eliminate empty or  repeated elements:

UNIQUE  - Eliminates instances of duplicated data. For exa mple:

VAR !Index SORT UNIQUE !Car CIASCII !Colour !Year N UMERIC

NOUNSET NOEMPTY  - Eliminates rows that contain only UNSET values.

VAR !Index SORT NOUNSET !Car CIASCII !Colour !Year NUMERIC

To sort these arrays and identify the last occurren ce of each group of the same car type, use
the LASTINGROUP  option:

VAR !Index SORT !Car LASTINGROUP !Group
Suppose we had sorted the array !Car and another ar ray !Value using the command:

VAR !Index SORT !Car !Value LASTINGROUP !Group

We can then generate an array of subtotals for each  type of car with the following command:

VAR !Totals SUBTOTAL !Values !Index !Group

VAR !variable SUBTOTAL  - This will sum value strings that contain values with or without
unit qualifiers. Unit qualifiers within the strings  will be ignored. This is to allow REPORTER to
still operate with unit qualified value strings tha t may have been introduced by other VAR or
$!variable commands.

VAR !variable EVALUATE  - Will return string variables and arrays of unit qualified values if
the evaluation generates quantities with physical d imensions. VAR !D EVAL (DIAM) for all
CYLI - sets !D to a set of strings such as '90cm' ' 60cm' etc. - when cm are the current length
units). The unit will be the current working unit.

VAR !variable ATTRIBUTE  This sets the variable to a string that contains t he value AND
the unit qualifier for attributes with of a physica l quantity VAR !X XLEN sets !X to '46cm' if
current units are cm) The unit will be the current working unit.


Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 33/178 Expression search criteria applied to collection eq uates to "with (GTYP eq 'BEAM')" ! Expression = object EXPRESSION() ! expression.expression('GTYP eq ''BEAM''') Define Collection ! Collection = object COLLECTION() ! Collection.scope(! Scope)! collection.addType(! elementType) ! Collection.filter(! Expression) !! sectionPML2 = ! Collection.results()  Example 2:  PML 1 collection  Var! myColl collect ALL (VALV INST) WITH (spec of s pref eq /INST ) FOR /TUB_PRUEBA /Tuberias_para_aplicacionesPML 2 Collection  ! myColl = !! CollectAllFor('VALV INST', 'spec of spr ef eq /INST', /TUB_PRUEBA /Tuberias_para_aplicaciones ! Coll = object COLLECTION() ! Coll.type('<gtype>') ! Coll.scope(<dbref>) ! Coll.filter(<expression>) ! Coll.initialize() ! ListOfItems = !Coll.results()  Note: Remember that this returns an array of DBREFS and not STRINGS  Example 3:  PML 1 collection  Var! Test coll all pipe with matchw (purp,'*yourpur pose*') within vol ce 1000 Var! Test1 eval name for all from! Test ! Dat = 'c:/temp/excel.Csv' ! Output = object file (! Dat) ! Output.writefile ('WRITE',! Test1) ! Output.close() Syscom 'c:/temp/excel.csv&'  Example 4:  PML 2 collection  ! Coll = object COLLECTION() ! coll.type('TRFAIL') ! Coll.scope(! Trinco) ! Coll.filter( object EXPRESSION('OWNER eq TRMLST') )! Coll.initialize() ! Scope = ! Coll.results()  -- Create an array of list names (for the dropdown) ! listNames = object ARRAY() ! listNames.append('ExampleList') ! listNames.append('AnotherList') -- Create a corresponding list of numbers (the RTEX T in the dropdown)


Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 34/178! listNumbers = object ARRAY()! listNumbers.append('1') ! listNumbers.append('2')  -- Create an array of strings for contents of the f irst list (names or refnos) ! listContents = object ARRAY() ! listContents.append('/P-MA') ! listContents.append('/P-GA') ! listContents.append('/P-16B')-- Add the array of contents to a global variable !! Cdlist1 = object ARRAY() !! Cdlist1.appendarray(! listContents)  -- Repeat for a second list (optional) ! listContents = object ARRAY() ! listContents.append('/E-13') ! listContents.append('/S-13') !listContents.append('/P-16B') !! Cdlist2 = object ARRAY() !! Cdlist2.appendarray(! listContents)  -- Update the form with the DTEXT and RTEXT !! cdcList.name.dText = ! listNames !! cdcList.name.rText = ! listNumbers  -- Store the names in a global variable!! cdList = ! listNames  Example 5:  PML 2 collection  ! E = !! CollectAllFor('SCTN','', !! This ) ! E = !! CollectAllFor('PIPE','Pspec eq |/A3|', world ) ! E = object COLLECT() ! E.classes = 'ALL' ! E.types = 'sctn' ! Tmp = !! Collect(! E)  Note: There are more options, like!E.expression - this lets you add an expression to the Object, etc. The easiest way to see the options I t hink is to create the object then query it.  ! E = object COLLECT() Q var! E ! A = Object Collection() ! a.scope(/VALIDELY) ! a.type('TYPE') Example 6:  Conditions:  Type: TEE Stype: RDTE (reducing tee in our DB) Bore: DN100 Cbore: DN50 (bore of tee connection) Spec: /SOME_SPEC


Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 35/178 PML 1 collection  Var! Tees coll all SPCO with ((GTYPE of catref eq ' TEE') and (STYPE eq 'RDTE' and PARAM1 of Catref eq 100)) for /SOME_SPEC  Note: What you get is anArray of specifications matchin g criteria. In this case this would be All reducing tees in catalog. You still don't know how to select the tee with correct reduced DN.  PML 2 collection  ! Elbows = !! collectallfor(|ELBO|,|gtype of catref i nset('ELBO') AND stype inset('PPBA') AND P1BORE eq 50mm|,!! This)  ! Directory = object file (|C:\FOLDER|) ! dirFiles = ! Directory.files() -- Query! dirFiles: Q var! dirFiles  -- If you want to get only the filenames: ! fileList = object array() Do! I clues!dirFiles ! File = ! dirFiles[! I].entry() ! fileList.append(! File) Enddo  Q var! fileList ! Project = CURRENT PROJECT ! MyProj = ! Project.code() $p $p Project: $! MyProj $p ! xTab = | |  Var! Pipes collect all (PIPE) ! Asz = ArraySize(! Pipes) $P Array size: $!Asz  ! Output = object ARRAY() ! xRec = |'PIPE| & |$! xTab| & |ZONE| & |$! xTab| & |P SPEC| & |$! xTab| & |ISPEC| & |$! xTab| & |:STATUS'| ! Output.append($! xRec) Var! Names evaluate (name) for all from! Pipes ! NewPositions = ! names.SortedIndices() ! Names.Sort()  Var! Zones evaluate (name of zone) for all from! Pi pes Var! Pspes evaluate (pspe) for all from! Pipes Var! Ispes evaluate (ispe) for all from! Pipes Var! Stats evaluate (:status) for all from! Pipes  ! zones.ReIndex(! NewPositions) ! pspes.ReIndex(!NewPositions) ! ispes.ReIndex(! NewPositions) ! stats.ReIndex(! NewPositions)


Response: AVEVA PDMS Programmable Macro Language manual2016 v.1. Page 36/178 do! Pipe index! Pipes ! Record =! Names[! Pipe] & |$! xTab| & ! Zones[! Pipe ] & |$! xTab| & ! Pspes[! Pipe] & |$! xTab| & ! Ispes[! Pipe] & |$! xTab| & ! Stats[! Pip e] ! Output.append(! Record) Enddo  ! File = object FILE('%PDMSuser%\$!MyProj_PipeList.t xt') ! file.writefile('OVERWRITE',! Output) $p $p Macro finished  Resulting sample output of PML report (623 records): PIPE ZONE PSPEC ISPEC :STATUS /1"-D173015-11180-H4-0001 /PIP-17000-71 /11180-H4 = 0/0 1 /1"-R172002-11085-R /PIP-17000-FLARE /11180-H4 =0/0 1/1"-R17200X-11085-R /PIP-17000-FLARE /11180-H4 =0/0 1 /10"-B172001-11380-H1-0001-1 /PIP-17000-FLARE /1138 0-H1 =0/0 1 /10"-B172002-11380-H1-0001-1 /PIP-17000-FLARE /1138 0-H1 =0/0 1 /10"-B172035-11380-H1-0001 /PIP-17000-FLARE /11380- H1 =0/0 1 /10"-B172036-11380-H1-0001 /PIP-17000-FLARE /11380- H1 =0/0 1 PML 2 array sorting ! Project = CURRENT PROJECT ! MyProj = ! Project.code()  $p $p Project: $! MyProj $p  ! TwldX = |*| ! xTab = | | ! Output = object ARRAY() ! xRec = |'PIPE| & |$! xTab| & |ZONE| & |$!xTab| & |P SPEC| & |$! xTab| & |ISPEC| & |$! xTab| & |:STATUS'| ! Output.append($! xRec)  ! Collect = object COLLECTION() ! Collect.scope(WORLD) ! Collect.type('PIPE') ! Collect.expression(object EXPRESSION('SUBSTR(NAME, 1,1) eq |/|') )  ! Pipes = ! Collect.Results() ! Names = object ARRAY() Do! Pipe values! Pipes ! Names.append(! Pipe.name) Enddo  ! Clues = ! Names.sortedindices() ! Pipes.reindex(! Indices)  ! Zones = ARRAY() ! PSpecs = ARRAY() ! ISpecs = ARRAY() ! udaSTATUS = ARRAY()  ! I = 1 Do! Pipe values!Pipes -- $p $! Pipe.name ! Zones.append(! Pipe.owner.name) -- q var! Zones ! PSpecs.append(! Pipe.pspec.name)


Response:
AVEVA PDMS Programmable Macro Language manual
  2016 v.1. Page 36/178  do !Pipe index !Pipes
  !record = !names[!Pipe] & |$!xTab| & !zones[!Pipe ] & |$!xTab| & !pspes[!Pipe] &
  |$!xTab| & !ispes[!Pipe] & |$!xTab| & !stats[!Pip e]
  !output.append(!record)
Enddo

!file = object FILE('%PDMSuser%\$!MyProj_PipeList.t xt')
!file.writefile('OVERWRITE',!output)
$p
$p Macro finished

Resulting sample output of PML report (623 records) :
PIPE ZONE PSPEC ISPEC :STATUS
/1"-D173015-11180-H4-0001 /PIP-17000-71 /11180-H4 = 0/0 1
/1"-R172002-11085-R /PIP-17000-FLARE /11180-H4 =0/0  1
/1"-R17200X-11085-R /PIP-17000-FLARE /11180-H4 =0/0  1
/10"-B172001-11380-H1-0001-1 /PIP-17000-FLARE /1138 0-H1 =0/0 1
/10"-B172002-11380-H1-0001-1 /PIP-17000-FLARE /1138 0-H1 =0/0 1
/10"-B172035-11380-H1-0001 /PIP-17000-FLARE /11380- H1 =0/0 1
/10"-B172036-11380-H1-0001 /PIP-17000-FLARE /11380- H1 =0/0 1
PML 2 array sorting
!Project = CURRENT PROJECT
!MyProj = !Project.code()

$p
$p Project: $!MyProj
$p

!TwldX = |*|
!xTab = | |
!output = object ARRAY()
!xRec = |'PIPE| & |$!xTab| & |ZONE| & |$!xTab| & |P SPEC| & |$!xTab| & |ISPEC| & |$!xTab| &
|:STATUS'|
!output.append($!xRec)

!Collect = object COLLECTION()
!Collect.scope(WORLD)
!Collect.type('PIPE')
!Collect.expression(object EXPRESSION('SUBSTR(NAME, 1,1) eq |/|') )

!Pipes = !Collect.results()
!Names = object ARRAY()
do !Pipe values !Pipes
  !Names.append(!Pipe.name)
Enddo

!Indices = !Names.sortedindices()
!Pipes.reindex(!Indices)

!Zones = ARRAY()
!PSpecs = ARRAY()
!ISpecs = ARRAY()
!udaSTATUS = ARRAY()

!i = 1
do !Pipe values !Pipes
  -- $p $!Pipe.name
  !Zones.append(!Pipe.owner.name)
  -- q var !Zones
  !PSpecs.append(!Pipe.pspec.name)


6.1. Functions, Macros and Object Definitions

Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 38/178 6. PML general futures Functions and Macros are PML Files that contain st ored sequences of commands. The PML FileIs invoked whenever this sequence of comma nds is required. The PML file may Also include control logic which alters the order i n which the commands are carried out and Special commands for handling errors. PML Files are normally created using a text editor.PML Functions and methods on objects (including for ms) are the recommended way of Storing command sequences because:  • There is a check that they have been called with t he right type of arguments. • Arguments can return values. • A PML Function oR method can return a result of an y type.  Most new AppWare code is written as methods on obj ects. PML Macros are explained in Macros as they are the basis of the older AppWare c ode. PML Macros are normally stored in A directory under the PDMSUI search-path.PML Funct ions are automatically loaded from a Directory under the PMLLIB search-path. Comments are additional text included in a PML Fil e for the benefit of someone reading The PML code. The PML processor ignores comments an d so they do not affect the way theCode executes. For a simple one line comment, begin the line with - - (two dashes) or $* (Dollar and asterisk).  - - This is a new-style PML comment - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $* The following lines calculate the new angleYou can also use $* to add an inline comment to any line of PML. A comment may extend Over several lines provided it is enclosed in the e scape sequences: $( and $) $( A comment containing Skip if (! X EQ! Y) More than one line $) At any point wiThin a PML File a return command wi ll stop further execution of the file and Return to the calling PML File, if there is one:  If ( count EQ 0 ) then Return Endif  For clarity, return can be used as the final line o f a PML Macro. However, the use of thisCommand is not essential and there will be no error if it is not used. Note: This is a different Use of return from the command used to set return v alues of variables. Everything written in PML, including keywords such as if, do and else means the sameThing in upper or lower case. The exception is text enclosed between quotes or vertical bars, Which is used exactly as it is typed. Throughout th is document you will see examples of PML Code using a mixture of upper and lower case for re adability.


Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 39/178 6.5. Abbreviations Many commands have a minimumAbbreviation which ca n be used in place of the full Command. For readability it is recommended that you use the full form of the command — Note that it is not less efficient than using the a bbreviation. PML keywords such as if, else And do have no abbreviations.The $ character has a special meaning in PML. It i s an escape character, which means That together with the character which follows it a re treated as a special instruction to PML. The pair of characters beginning with $ is known as an escape sequence.$P is a commonly Encountered example, which is used to output a mess age to the screen: $P This text will be output to the screen  A number of other escape sequences will be described ed later in this manual. The important Point to note here that if yOr need the dollar char acter itself as part of a command, you will Need to double it ($$). As the last character on a line, $ means that the next line is a Continuation line. For example: $P This is an example of a much longer message that will be $ output to the screen$! The PML variable following the! (Gold!!) Is expa nded as a string by using its own . STRING() Method.  Note: Real values are automatically expanded with any un it qualify appended if the value is A physical quantity. This is useful on $P lines oR converting real values to strings in Commands. $newline command continues on next line w ithout being automatically closed.  $M/filename execute a text file as a sequence of co mmands or an input macro. Named Using its filename or pathname.  The Dollar $ symbol and its meanings$M = Runs a macro in pdms $! = Evaluate a variable $. = Terminates a macro $S = Defines a synonym $G = Defines a global synonym $S- = Turns synonyms off $S+ = Turns synonyms On $QS = Query's the synonyms $H = Help $Q = Another syntax help $P = PRints a line to your command line $$ = Adds a $ symbol $D = Default argument value  To turn the pml trace on and off I use  $R<n> $R0 = Turn trace Off $R6 = Turn trace On $R1 = Tracing to shell window (default) $R2 = Tracing to requests window $R4 = Tracing of only input lines executed $R8 = Tracing of all input lines $R16 = Tracing without $ expression (Default off) $R32 = Tracing includes line numbers $R64 = Tracing of macro/function changes $R100 = General Debugging $R102 = capture trace in ALPHA LOGText strings must be enclosed in either single quo tes, or apostrophes, or vertical bars: ('Apostrophes' or |vertical bars| ). The apostrophe s and vertical bars are known as delimiters. Take great care to avoid unmatched delimiters as th is can lead to many lines of PML codeBeing included as part of the text string, and so l ost.


Response:
AVEVA PDMS Programmable Macro Language manual
  2016 v.1. Page 39/178  6.5. Abbreviations
 Many commands have a minimum abbreviation which ca n be used in place of the full
command. For readability it is recommended that you  use the full form of the command —
note that it is not less efficient than using the a bbreviation. PML keywords such as if, else
and do have no abbreviations.
 The $ character has a special meaning in PML. It i s an escape character, which means
that together with the character which follows it a re treated as a special instruction to PML.
The pair of characters beginning with $ is known as  an escape sequence. $P is a commonly
encountered example, which is used to output a mess age to the screen:
$P This text will be output to the screen

 A number of other escape sequences will be describ ed later in this manual. The important
point to note here that if you need the dollar char acter itself as part of a command, you will
need to double it ($$). As the last character on a line, $ means that the next line is a
continuation line. For example:
$P This is an example of a much longer message that  will be $ output to the screen

$! The PML variable following the ! (or !!) is expa nded as a string by using its own .STRING()
method.

Note:  Real values are automatically expanded with any un it qualifier appended if the value is
a physical quantity. This is useful on $P lines or converting real values to strings in
commands. $newline command continues on next line w ithout being automatically closed.

$M/filename execute a text file as a sequence of co mmands or an input macro. Named
using its filename or pathname.

The Dollar $ symbol and its meanings

$M = Runs a macro in pdms
$! = Evaluate a variable
$. = Terminates a macro
$S = Defines a synonym
$G = Defines a global synonym
$S- = Turns synonyms off
$S+ = Turns synonyms On $QS = Query’s the synonyms
$H = Help
$Q = Another syntax help
$P = Prints a line to your command line
$$ = Adds a $ symbol
$D = Default argument value

To turn the pml trace on and off I use

$R<n>
$R0 = Turn trace Off
$R6 = Turn trace On
$R1 = Tracing to shell window (default)
$R2 = Tracing to requests window
$R4 = Tracing of only input lines executed
$R8 = Tracing of all input lines $R16 = Tracing without $ expression
(default off)
$R32 = Tracing includes line numbers
$R64 = Tracing of macro/function changes
$R100 = General Debugging
$R102 = capture trace in ALPHA LOG
 Text strings must be enclosed in either single quo tes, or apostrophes, or vertical bars:
('apostrophes' or |vertical bars| ). The apostrophe s and vertical bars are known as delimiters.
Take great care to avoid unmatched delimiters as th is can lead to many lines of PML code
being included as part of the text string, and so l ost.


Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 41/178 7. PML Control logicThere are four types of construct for implementing control logic within a PML Function or Macro. These are: • The if construct for conditional execution of comm ands. • The do command for looping and the associated brea k and skip. • The golabel for jumping to a line with a label.• The handle construct for dealing with errors. The full form of an if-construct is as follows:  If (! Word EQ 'Peanuts' OR! Word EQ 'Crisps') then ! Snacks = ! Snacks + 1 ! Meal = FALSE Elseif (! Word EQ 'Soup') then ! Starters = ! Starters + 1! Meal = TRUE Elseif (! Word EQ 'Fruit' Gold! Word EQ 'IceCream' ) t hen ! Puddings = ! Puddings + 1 ! Meal = TRUE Else ! MainCourse =! MainCourse + 1 ! Meal = TRUE Endif  Each BOOLEAN expression, such as (! Word EQ 'Soup') , is examined in turn to seeWhether it is TRUE or FALSE. As soon as an expressi on that is TRUE is encountered, the Following block of commands is executed. Once a blo ck of commands has been executed, Everything else up to the endif is ignored. The els e command is optional. If it is included, youCan be sure that exactly one command block within t he if-construct will be executed. The Elseif commands are also optional. Once one of the elseif expressions has been found to be TRUE, any remaining elseif commands are ignored. Th us the simplest form of the if-Construct is:  If (! Number LT 0 ) then ! Negative = TRUE Endif  You may not concatenate the commands into one line, so the following expressions are not If (! TrueValue OR! UnsetValue) If (! FalseValue AND! UnsetValue) Don't know! UnsetValue if thE value is not required to determine the outcome of the expression. The same is true for PML Functions which have retur ned an error.  Any if-construct may contain further if ... elseif ... endif constructs:  If (! Number LT 0) then ! Negative = TRUEIf (! Number EQ -1 ) then ! OnlyJustNegative = TRUE Endif Endif It is particularly helpful with nested if construct s to indent the code so that the logic is clear.


7.1.3. BOOLEAN Expressions and if Statements

Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 42/178 7.1.2. IF, THEN, ELSEIF and ELSE Statements An IF construct can beExtended by adding addition al conditions. This is done by adding Either ELSEIF or ELSE to it. When an IF construct i s encountered, PML will evaluate its Condition. If the condition is FALSE, PDMS will loo k to the next ELSEIF condition. Once a ConditiOn is found to be TRUE, that code will be ru n that proportional of the code and the IF Construct is complete. If an ELSE condition is adde d, this portion of code will only be run if The other conditions are never met. This is a way o f ensuring some code is always run.If ($1 EQ 0) THEN $p Your value is zero Elseif ($1 LT 0) THEN $p Your value is less than zero Else $p Your value is Greater than zero Endif  The ELSEIF and ELSE commands are optional, but ther e can only be one ELSE command In an IF construct.New expressions based on the operators such as EQ and GT give a BOOLEAN result That can be used directly in a PML2 if test: If (! NewValue - 1 GT 0) then  The expression can be a simple variable provided it is a BOOLEAN type variable: ! Success =! NewValue GT 0If (! Success) then The expression could be a user-defined PML Function provided it returns a BOOLEAN Result: if (!! MyFunction() ) then  Note: The BOOLEAN constants TRUE, FALSE, YES and NO and t heir single-letter abbreviations Not enclosed in quoTes return BOOLEAN results and s o can be used directly in expressions. For example:  Code Result Type If ( TRUE ) BOOLEAN If ( FALSE ) If ( T ) BOOLEAN If ( F ) If ( YES ) BOOLEAN If ( NO ) If ( Y ) BOOLEAN If ( N )  The following do not retUrn BOOLEAN values and are therefore invalid:  Code Result Type If ( 1 ) REAL If ( 0 ) If ( 'TRUE' ) STRING If ( 'FALSE' ) If ( 'T' ) STRING If ( 'F' ) Variable = 1 REAL If ($Variable)


Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 43/178 For upward compatibility with PML1, STRING variable s set to 'TRUE', 'FALSE', 'YES' or 'NO' or their singlE-letter abbreviations can be us ed in an if-test as long as they are Evaluated with a preceding $. For example:  Code Result Type Variable = 'TRUE' STRING If ($Variable)  There is a built-in PML Method and a function for c onverting a value to BOOLEAN:! MyString = 'TRUE' If (! MyString.Boolean() ) then  The Boolean conversion is as follows:  Code Result REAL zero FALSE $* All other positive and negative REAL values TRUE STRING 'FALSE, 'F', 'NO' and 'N' FALSE STRING 'false, 'f', 'no' and 'n' FALSESTRING 'TRUE', 'T', 'YES' AND 'Y' TRUE STRING 'true', 't', 'yes' and 'y' TRUE IF TRUE will return a value of the type defined by the second and third arguments. If the Initial Boolean expression is true, the result of t he first expression is returned.If false, the Result of the second expression is returned. Both t he second and third arguments are fully Evaluated regardless of the value of the Boolean. T his is because the function is evaluated Using reverse polish procedure (as is the case of t he expression design).This allows the IF Statement to be nest able with any of the arguments to IF capable of including other IF Functions.  If logical1 expression is set to true, then value o f typeX1expression is returned If logical1 Expression is set to false, then vAlue of typeX1 ex pression is returned typeX1 and typeX2 Are two arguments of the same type which may be:  Logical Logical Array Real Real Array ID ID Array Text Position Direction For upward compatibility with PML1, STRING variable es set to 'TRUE', 'FALSE', 'YES' or'NO' or their single letter abbreviations can be us ed in an if test as long as they are Evaluated with a preceding $. For example:  If ($Variable) where Variable = 'TRUE' STRING OK


7.2.1. Stopping a DO loop: break and breakif

Response:
AVEVA PDMS Programmable Macro Language manual
  2016 v.1. Page 43/178  For upward compatibility with PML1, STRING variable s set to ‘TRUE’, ‘FALSE’, ‘YES’ or
‘NO’ or their single-letter abbreviations can be us ed in an if-test as long as they are
evaluated with a preceding $. For example:

Code Result Type
Variable = ‘TRUE‘ STRING
if ($Variable)

There is a built-in PML Method and a function for c onverting a value to BOOLEAN:

!MyString = ‘TRUE’
if (!MyString.Boolean() ) then

The Boolean conversion is as follows:

Code Result
REAL zero FALSE
$* All other positive and negative REAL values TRUE
STRING ‘FALSE, ‘F’, ‘NO’ and ‘N’ FALSE
STRING ‘false, ‘f’, ‘no’ and ‘n’ FALSE
STRING ‘TRUE’, ‘T’, ‘YES’ AND ‘Y’ TRUE
STRING ‘true’, ‘t’, ‘yes’ and ‘y’ TRUE
 IF TRUE will return a value of the type defined by  the second and third arguments. If the
initial Boolean expression is true, the result of t he first expression is returned. If false, the
result of the second expression is returned. Both t he second and third arguments are fully
evaluated regardless of the value of the Boolean. T his is because the function is evaluated
using reverse polish procedure (as is the case of t he expression design). This allows the IF
statement to be nest able with any of the arguments  to IF capable of including other IF
functions.

If logical1 expression is set to true, then value o f typeX1expression is returned  If logical1
expression is set to false, then value of typeX1 ex pression is returned typeX1 and typeX2
are two arguments of the same type which may be:

Logical
Logical Array
Real
Real Array
ID
ID Array
Text
Position
Direction
 For upward compatibility with PML1, STRING variabl es set to ‘TRUE’, ‘FALSE’, ‘YES’ or
‘NO’ or their single letter abbreviations can be us ed in an if test as long as they are
evaluated with a preceding $. For example:

if ($Variable) where Variable = ‘TRUE’ STRING OK


Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 45/178 do! X ! Number = ! Sample[! X] If ((INT(!Number/2) NE (! Number/2)) then Skip Endif ! Result = ! Result +! Number Enddo  The skip if command can sometimes be more convenien t:  Do! X ! Number = ! Sample[! X] Skip if (INT(! Number/2) NE (! Number/2)) ! Result = ! Result +! Number EnddoYou can nest do-loops one inside the other. The co unter for each loop must have a Different name.  Do! X to 10 Do! Y ! Z = ! X +! Y Break if (! Y GT 5) Enddo Enddo  The inner-most loop goes through all the values of! Y before the outer loop moves on to theSecond value of! X. Note that the break (or skip) c ommand acts just on the loop containing it - in this case the inner-most loop. DO Index and DO Values are ways of looping through arrays. This is an effective method For controlling the values used for the loops.Typi cally values are collected into an ARRAY Variable then looped through using the following:  Do! X values! ARRAY ! X takes each ARRAY element (! X is an element!!!) Enddo  Do! X index! ARRAY ! X takes a number from 1 to! ARRAY size (! X is a number!!!) Enddo Type out the following as an example of looping thr ough an ARRAY of values.  VAR! Zones COLL ALL ZONES FOR SITE VAR! Names EVAL NAME FOR ALL FROM! Zones Q var! Names  Do! X VALUES! Names Q var! X Enddo  Do! X INDEX! Names Q var!Names[! X] Enddo


Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 46/178 7.2.6. DO Values with Arrays of Objects Imagine that we have already defined an object typ e EMPLOYEE which contains a Member of type STRING. We create an array of EMPLOY EE objects and set the Name Member of each of each object.  ! MyEmployees[1] = object EMPLOYEE()! MyEmployees[2] = object EMPLOYEE() ! MyEmployees[3] = object EMPLOYEE() ! MyEmployees[1]. Name = 'James' ! MyEmployees[2]. Name = 'Joe' ! MyEmployees[3]. Name = 'Mike'  We then wish to create a new array containing just the employees' names.  ! Names = ARRAY()Do! Person VALUES! MyEmployees ! Names.Append(! Person.Name) Enddo  Each time round the do-loop, the do-variable become s an object of the appropriate type, Even if the array is a heterogeneous mixture of obj ects. The golabel command in PML allowYou to jump to a line with a matching label name  LABEL /FRED : : GOLABEL /FRED  The label name /FRED has a maximum length of 16 characters , excluding the / slash Which must be present. The next line to be executed will be the line following LABEL /FRED,Which could be before or after the GOLABEL command. Do! A Do! B to 3 ! C = ! A * ! B Golabel /finished if (! C GT 100) ! Total = ! Total +! C Enddo Enddo Label /finished $P Total is $! Total  If the expression! C GT 100 is TRUE there wIll be a jump to LABEL /FINISHED and PML Execution will continue with the line  $P Total is $! Total  If the expression is FALSE , PML execution will continue with the line:  ! Total = ! Total +! C


Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 47/178 7.3.2. Illegal Jumping The following is an illegal jump into a nested do b lock. It is however allowed to jump out ofA nested block to a line in an enclosing block.  Golabel /illegaL Do! Count to 5 ! Total = ! Total +! Count Label /illegal Enddo An error condition can occur because a command cou ld not complete successfully or Because of a mistake in a PML Macro or function.Th e presence of an error normally has Three effects:  • An Alert box appears which the user must acknowled ge • An error message is output together with a trace b ack of any calling macros or Functions. • Any currently running PML Macros and functions are abandoned.This example of an error is caused by an attempt to use a PML Variable that does not exist:  (46,28) ERROR - Variable FRED not defined  The 46 is the module or program section which identified the error and is the error code itself Is 28 . If thE input line had been typed interactively th at is the end of the story. However, if the Input line was part of a PML Macro or function the error may optionally be handled. An error arising during the processing of a PML Ma cro or function does not immediatelyGive rise to an error message - this depends on the next line of input. Provided the next Command processed by PML is a matching handle comma nd, the error is not output and the Commands within the matching handleblock are proces sed instead. Elsehandle blocks mayOptionally also be present - if the handle block do es not match the error one elsehandle will Be processed - if it matches the error:  $* a command causes Error(46, 28) Handle (46, 27) $* handle block - not processed this time Elsehandle (46, 28)$* The commands in this matching handle block are processed Next Elsehandle ANY $* An ANY Handle Block is processed for any error s. In this position it would handle errors Other than (46, 27) and (46,28) Elsehandle NONE $* A NONE Handle BloCk is processed only if there were no errors Endhandle  $* This line is processed after the handle block.  If (46,27) matches the error, PML processes the com mands in that handle block instead of Outputting an error. Processing of the current PML MAcro or function continues at the line After the endhandle command.


Response:
AVEVA PDMS Programmable Macro Language manual
  2016 v.1. Page 47/178  7.3.2. Illegal Jumping
The following is an illegal jump into a nested do b lock. It is however permitted to jump out of
a nested block to a line in an enclosing block.

golabel /illegaL
do !Count to 5
  !Total = !Total + !Count
  label /illegal
enddo
 An error condition can occur because a command cou ld not complete successfully or
because of a mistake in a PML Macro or function. Th e presence of an error normally has
three effects:

• An Alert box appears which the user must acknowled ge
• An error message is output together with a trace b ack of any calling macros or
functions.
• Any currently running PML Macros and functions are  abandoned.

This example of an error is caused by an attempt to  use a PML Variable that does not exist:

(46,28) ERROR - Variable FRED not defined

The 46  is the module or program section which identified the error and is the error code itself
is 28 . If the input line had been typed interactively th at is the end of the story. However, if the
input line was part of a PML Macro or function the error may optionally be handled.
 An error arising during the processing of a PML Ma cro or function does not immediately
give rise to an error message - this depends on the  next line of input. Provided the next
command processed by PML is a matching handle comma nd, the error is not output and the
commands within the matching handleblock are proces sed instead. Elsehandle blocks may
optionally also be present - if the handle block do es not match the error one elsehandle will
be processed - if it matches the error:

$* a command causes Error(46, 28)
handle (46, 27)
  $* handle block - not processed this time
elsehandle (46, 28)
  $* The commands in this matching handle block are  processed
  next
elsehandle ANY
  $* An ANY Handle Block is processed for any error s. In this position it would handle errors
other than (46, 27) and (46,28)
elsehandle NONE
  $* A NONE Handle Block is processed only if there  were no errors
Endhandle

$* This line is processed after the handle block.

If (46,27) matches the error, PML processes the com mands in that handle block instead of
outputting an error. Processing of the current PML Macro or function continues at the line
after the endhandle command.


Response: AVEVA PDMS Programmable Macro Language manual2016 v.1. Page 49/178 return error  You can also re-instate the error but suppress the alert using the command: Return error noalert  To generate a new error (or replace an error with y our own error) plus an optional message, Use one of the followingReturn error 1 Return error 1 'Your error message' Return error 1 NOALERT  To handle such an error there is a special form of the handle command:  Handle 1 PML code to handle a user-defined error number Endhandle Reading and writing files isGreatly simplified by using the FILE object. This chapter Describes the methods most frequently used for read ing and writing. Methods are also Provided for moving, copying and deleting files and extracting information such as the Pathname of a file,Its size data and time last mod ified. A FILE object may refer to a directory Rather than a file and methods are provided for nav igating around the directory structure. For A complete list of the methods available, refer to the Software Customization ReferenceManual. A file object is created by invoking the FILE cons tructor with the name of the file as its Argument. For example:  ! MyFile = object FILE ('c:\users\bob\list.txt') ! MyFile = object FILE (/net/usr/bob/list') ! MyFile = object FILE ('%PDMSUSER%\bob\list.Txt')  At this stage, the file may or may not exist — cre ating the FILE object does not open or Access the file in any way. This example reads pair s of numbers from file data, adds them Together and writes the answers to file RESULTS.  ! Input = object FILE('DATA')! Input.Open('READ') ! Output = object FILE('RESULTS') ! Output.Open('WRITE') C ! Line = ! Input.ReadRecord() If (! Line.set()) then ! Array = ! Line.Split() ! Total = ! Array[1]. Real() +! Array[2]. Real() ! Output.WriteRecord( ! Total.String() )Else Estate car Endif Enddo ! Output.Close() ! Input.Close()


Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 50/178 7.5.2. Reading from Files When reading a file one line at a time using the R eadRecord() method you must open the File first with the Open('READ') method and close i t afterwards with the Close() method. Each line read from the file wilL be returned as a STRING until the end of the file is reached, When you will get an UNSET STRING returned. The UNS ET string can be detected using The STRING object's Set() method (or Unset()) When you open a file for writing, the file will be created if it does not already exist.If you Use Open('WRITE') and the file already exists, the user will be shown an alert asking Whether the file can be overwritten. Alternatively you may specify OVERWRITE, to force Overwriting of a file if it already exists or APPEN D if you want to add to the end of a file if itAlready exists. You will obtain much quicker performance if you re ad or write an entire array in a single Operation. In particular you are recommended to use the ReadFile() method which returns The whole file as an array of strings, opening and closing the file automatically:! Input = object FILE('DATA') ! Output = object FILE('RESULTS') ! Lines = ! Input.ReadFile() ! ResultArray = ARRAY() Do! Line VALUES! Lines ! Numbers = ! Line.Split() ! Total = ! Numbers[1]. Real() +! Numbers[2]. Real() ! ResultArray.Append( ! Total.String() )Enddo ! Output.WriteFile('WRITE', ! ResultArray)  Note: With the ReadFile() method you may optionally specify the maximum number r of Lines you are prepared to read and an error is rais ed if this number is exceeded. If not Specified, a limit of 10000 is imposed.Errors will mainly be encountered when an attempt is made to open a file that does not Exist, has been mistyped or to which you do not hav e access. Anticipated errors may be Dealt with in a handle command following use of the Open() method. The errors mostCommonly encountered include the following:  (160,7) Argument to method is incorrect (160,9) File does not exist (160,36) Unable to read file record, file is not op en (160,37) Unable to write file record, file is not o pen (160,44) File exists, userDoes not want to overwri te it (160,47) File length has exceeded N lines (41,319) Cannot access file (Privileges insufficien t)


Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 51/178 8. Macros Macros are command sequences that are stored in te xt files. To access a macro file and Input the command sequence to your program, you run the macro. The file is scanned line-By-line, with exactly the same effect as if you wer e typing the lines in from a keyboard. Macro files may include synonyms and user-defined v ariables. They may also act on data Which you define when you give the command to run t he macro (parameterized macros).Macros are permanent records which may be called fr om within any working session of a Program. A macro file can be given any name that conforms t o the naming conventions of the Operating system. The suffix .mac is often used to indicate that the filename is that of aMacro, but this is optional. The process of reading the contents of a macro file as program Input is known as running the macro . The program does not discriminate between input From the GUI, the keyboard, or a macro file. To run a macro, enter: $M filenameWhere filename is the pathname of the macro file. The filename may optionally be preceded By a slash (/) character. If you give only the name of the file, the program will look for it in the Directory from which you executed the program. An e rror meSsage will be output if the file Cannot be found and opened for reading. It is often convenient to write a macro in a gener alized form, using parameters to Represent dimensions, part numbers etc., and to ass ign specific values to those parameters Only when the macro is to be run.In the simplest c ase, parameters are allocated positions in The command lines as macro arguments by inserting e scape codes of the form $n where n is An integer in the range 1 to 9. These arguments are then specified as part of the command To run the macro.They follow the macro name, with spaces separating the individual Arguments. For example, if a macro named beam.mac i ncludes the command line  NEW BOX XLEN $1 YLEN $2 ZLEN $3  Then the macro call $M/BEAM.MAC 5000 200 300 will run the macro and will set the lengthsDefined as $1, $2, $3 to 5000, 200 and 300 respecti vely. Arguments may be either values or Text, but note that a space in a text string will b e interpreted as a separator between two Different arguments. Apostrophes in text arguments are treated as parts of the arguments,Not as separators between them. For example, if a d demonstration macro arg.mac includes The lines: $P First Argument is $1 $P Second Argument is $2 $P Third Argument is $3  And is called by the command $M arg.mac 'Arg1a Arg1b' 'Arg2' 'Arg3'  The resulting output will beFirst Argument is 'Arg1a' Second Argument is 'Arg1b' Third Argument is 'Arg2'  Whereas the intended output was First Argument is 'Arg1a Arg1b' Second Argument is 'Arg2' Third Argument is 'Arg3'


8.2. Using Macros and Functions Together

Response:
AVEVA PDMS Programmable Macro Language manual
  2016 v.1. Page 51/178  8. Macros
 Macros are command sequences that are stored in te xt files. To access a macro file and
input the command sequence to your program, you run the macro. The file is scanned line-
by-line, with exactly the same effect as if you wer e typing the lines in from a keyboard.
Macro files may include synonyms and user-defined v ariables. They may also act on data
which you define when you give the command to run t he macro (parameterized macros).
Macros are permanent records which may be called fr om within any working session of a
program.
 A macro file can be given any name that conforms t o the naming conventions of the
operating system. The suffix .mac is often used to indicate that the filename is that  of a
macro, but this is optional. The process of reading  the contents of a macro file as program
input is known as running the macro . The program does not discriminate between input
from the GUI, the keyboard, or a macro file. To run  a macro, enter: $M filename

where filename is the pathname of the macro file. The filename may  optionally be preceded
by a slash (/) character. If you give only the name  of the file, the program will look for it in the
directory from which you executed the program. An e rror message will be output if the file
cannot be found and opened for reading.
 It is often convenient to write a macro in a gener alized form, using parameters to
represent dimensions, part numbers etc., and to ass ign specific values to those parameters
only when the macro is to be run. In the simplest c ase, parameters are allocated positions in
the command lines as macro arguments by inserting e scape codes of the form $n where n is
an integer in the range 1 to 9. These arguments are  then specified as part of the command
to run the macro. They follow the macro name, with spaces separating the individual
arguments. For example, if a macro named beam.mac i ncludes the command line

NEW BOX XLEN $1 YLEN $2 ZLEN $3

then the macro call $M/BEAM.MAC 5000 200 300 will run the macro and will set the lengths
defined as $1, $2, $3 to 5000, 200 and 300 respecti vely. Arguments may be either values or
text, but note that a space in a text string will b e interpreted as a separator between two
different arguments. Apostrophes in text arguments are treated as parts of the arguments,
not as separators between them. For example, if a d emonstration macro arg.mac includes
the lines:
$P First Argument is $1
$P Second Argument is $2
$P Third Argument is $3

and is called by the command $M arg.mac ’Arg1a Arg1b’ ’Arg2’ ’Arg3’

the resulting output will be
First Argument is ’Arg1a’
Second Argument is ’Arg1b’
Third Argument is ’Arg2’

whereas the intended output was
First Argument is ’Arg1a Arg1b’
Second Argument is ’Arg2’
Third Argument is ’Arg3’


Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 53/178 8.4. PML 1 Hierarchy All PML1 Macros are in a directory structure point ed at by the variable PDMSUI. The PDMSUI environment variable Set PDMSUI=C:\AVEVA\plant\PDMS12.0.2\pdmsui  Picture Nr.2. - PML1 File hierarchy Standard AVEVA environment variable are set in a b at files called EVAR.bat in the Executable directory. All PML1 macros and forms ar e called using synonyms For example The macros and forms associated with piping are cal led using the synonym CALLP:$S CALLP=$M/%PDMSUI%/DES/PIPE/$s1 CALLP MPIPE  Note: This is why if all synonyms are killed that PDMS w ill no longer work properly.  It is normal practice to create a parallel hierarch y to contain any new or modified PML. These modifications canThen be called by modifying the PDMSUI variable to point at a multi Path. This can be done by putting a new file path i n front of the %PDMSUI% definition. This Will update the PDMSUI environment variable to incl ude the specified file path. Set PDMSUI=c:\pmltraining\PDMSUI %pdmsui%  The new file path should go in front of %PDMSUI% so this area is checked first for content. Once content is found, other locations will not be searched. This modification should be Done after the PDMSUI environment variable has been defined.This can be done at the Bottom of the EVAR.bat file or in the PDMS.bat file (after the line which calls evar.bat). The Environment variables can be checked with PDMS by u sing the q evar syntax q evar PDMSUI Or q evar 'SAM000' . The PMLLIB environmentNt variable points to a PML2 di rectory structure. Set PMLLIB= C:\AVEVA\plant\PDMS12.0.2\pmllib  Picture Nr.3. - PML2 File hierarchy There are 3 new file extensions .pmlfnc for Functi ons, .pmlfrm for Forms and .pmlobj for Objects, with these extensiOns the files will be lo aded by PDMS automatically when the Program is started. Functions are loaded by PDMS an d are run by typing the following !! Mymac(). This runs file mymac.pmlfnc. Forms are d isplayed by typing Show!! Myform or !! Myform.show()ObjEcts have to be assigned to a var iable before they can be used i.e.! X = Object MyObject() It is normal practice to create a parallel hierarc hy to contain any new or modified PML. These modifications can then be called by modifying the PMLLIB variable to point at a multi


Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 54/178 path. This canBe done by putting a new file path i n front of the %PMLLIB% definition. This Will update the PMLLIB environment variable to incl ude the specified file path.  Set pmllib=c:\pmltraining\PMLLIB %pmllib%  The new file path should go in front of %PMLLIB% s o this area is checked first for Happy. Once content is found, other locations wil l not be searched. This modification should Be done after the PMLLIB environment variable has b een defined. This can be done at the Bottom of the EVAR.bat file or in the PDMS.Bat file (after the line which calls evar.bat). In AVEVA products environment variables can be checked using the q evar syntax i.e. q evar Pmllib. Edit the Evar.bat file to include multi paths for PDMSUI and PMLLIB. These settings Should be made at the bottom of the evar.Bat file  Set pdmsui=c:\pmltraining\pdmsui %pdmsui% Set pmllib=c:\pmltraining\pmllib %pmllib%  The setting of the variable can be checked in AVEV A Plant Design (PDMS) using the Following commands: q evar pdmsui and q evar pmllib . If a pmllib file is c once items haveBeen loaded by PDMS, it needs to be reloaded. This can be done by typing either pml Reload form!! NAME or pml reload object NAME If a new file is to pmllib, the files can be Remapped so PDMS knows where it is located. This is done by typing pml rehash onto theCommand line. This will update the first file locat ion in the search path. To update all search Paths, type pml rehash all . An object is a PML grouping of information. It may have MEMBERS (used to hold data) And METHODS (used to complete an action).Once assi gned to a variable, that variable Becomes an instance of that object. This means that variable will behave as the object Definition. While it is possible to create user-def ined objects (discussed later), PDMS is Supplied with a large number of built-in objects.A full list of these can be found in the PDMS Software Customization Reference Manual. For exampl e, type! Pos = object position() onto The command line. Query the variable and check the results against the members of a Position object listed in the reference manual.When working with built-in objects, there may also be BUILT-IN METHODS (object Dependents). These methods have been defined to com plete certain actions applicable to Object. For example, type the following into the co mmand line:  ! Value = |56| !Result = ! Value * 2  This example will have caused an error as a string cannot be used in an expression like This. To avoid the error, refer to the STRING objec t in the Reference Manual and find the .Real() method. This method translates the variableE from a STRING to a REAL so that it can Be used in the expression. The! Value remains a str ing, but! Results now becomes a REAL E.g.  ! Value = |56| ! Result = ! Value.real() * 2


Response:
AVEVA PDMS Programmable Macro Language manual
  2016 v.1. Page 54/178  path. This can be done by putting a new file path i n front of the %PMLLIB% definition. This
will update the PMLLIB environment variable to incl ude the specified file path.

Set pmllib=c:\pmltraining\PMLLIB %pmllib%

 The new file path should go in front of %PMLLIB% s o this area is checked first for
content. Once content is found, other locations wil l not be searched. This modification should
be done after the PMLLIB environment variable has b een defined. This can be done at the
bottom of the EVAR.bat file or in the PDMS.bat file  (after the line which calls evar.bat). In
AVEVA products environment variables can be checked  using the q evar syntax i.e. q evar
pmllib.
 Edit the Evar.bat file to include multi paths for PDMSUI and PMLLIB. These settings
should be made at the bottom of the evar.bat file

Set pdmsui=c:\pmltraining\pdmsui %pdmsui%
Set pmllib=c:\pmltraining\pmllib %pmllib%

 The setting of the variable can be checked in AVEV A Plant Design (PDMS) using the
following commands: q evar pdmsui and q evar pmllib . If a pmllib file is c once items have
been loaded by PDMS, it needs to be reloaded. This can be done by typing either pml
reload form !!NAME  or pml reload object NAME  If a new file is to pmllib, the files can be
remapped so PDMS knows where it is located. This is  done by typing pml rehash  onto the
command line. This will update the first file locat ion in the search path. To update all search
paths, type pml rehash all .
 An object is a PML grouping of information. It may  have MEMBERS (used to hold data)
and METHODS (used to complete an action). Once assi gned to a variable, that variable
becomes an instance of that object. This means that  variable will behave as the object
definition. While it is possible to create user-def ined objects (discussed later), PDMS is
supplied with a large number of built-in objects. A  full list of these can be found in the PDMS
Software Customization Reference Manual. For exampl e, type !pos = object position() onto
the command line. Query the variable and check the results against the members of a
position object listed in the reference manual.
 When working with built-in objects, there may also  be BUILT-IN METHODS (object
dependents). These methods have been defined to com plete certain actions applicable to
object. For example, type the following into the co mmand line:

!value = |56|
!result = !value * 2

 This example will have caused an error as a string  cannot be used in an expression like
this. To avoid the error, refer to the STRING objec t in the Reference Manual and find the
.real() method. This method translates the variable  from a STRING to a REAL so that it can
be used in the expression. The !value remains a str ing, but !results now becomes a REAL
e.g.

!value = |56|
!result = !value.real() * 2


Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 56/178! Easting = !! CE.Href.Cpar[1] Cata parameter member (attribute) of a DBREF objec t. If the!! CE object member is an object with built-in metho ds, these methods can also be called:  ! PosWRTValve = !! CE.Hpos.WRT(ZONE) POSITION object w.r.t the owning ZONE  This process can also be reversed allowing the sett ing of attributes for the CE. This meansThat it is possible to record the current value of an attribute, modify and reassign back to the CE. For example, type out the following onto the co mmand line:  ! Pos = !! CE.Pos Q POS ! Pos.Up = 2000 !! CE.Pos = ! Pos Q POS  These lines will have moved the CE up by 2000.Try this example again with some other Attributes. Functions are new style macros which are pre-loade d by PDMS and can be called Directly. For example, to call the function called FuncName.pmlfnc, type!! FuncName() onto The command line. A function is defined within a .P mlfnc file stored within the PMLLIB file Path. For an example of a function, type the follow ing into a new file and save it as  c:\pmltraining\pmllib\functions\NameCE.pmlfnc. Define function!! NameCE() ! This = !! CE.fullname $p $! This EndfunctionTo run this function, type!! NameCE() onto the comm and line. You will notice the full name is Printed below it. This is an example of a NON-RETUR N function with NO ARGUMENTS. Yew The function can be given arguments which are then assigned to variables with the function.If a variable is returned, this means that the func tion can be assigned to another variable or As part of a calculation. Type out the following, a nd save it as  c:\pmltraining\pmllib\functions\Area.pmlfnc: Define function!! Area(! Radius is REAL) is REAL! CircleArea = ! Radius.Power(2) * 3.142 Return! CircleArea Endfunction  As this function is an example of a RETURN function with an ARGUEMENT, it can be used As part of an expression. The returned value is bas ed the functions argument and its type(REAL in this case ).   ! Height = 64 ! CylinderVolume = !! Area(2.3) *! Height Q var! CylinderVolume  As indicated by the !!, functions are global. This means that once defined, they can be called By any form or method within PDMS minimizing repeti tive code.


Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 57/178 9. Using PML in AVEVA Products Most of this maNual describes how to use PML 2 to create and customize Forms and Menus. This chapter describes how to use PML within AVEVA products. Note that for tasks Such as defining Rules and Report Templates, you ar e restricted to the PML 1 expressions PackageDescribed in the Software Customization Reference Manual, and it is also Sometimes necessary to use the VAR command. It is sometimes necessary to arrange text in multi ple columns. The COMPOSE facility of The VAR command will help you do this. For examPle, if we create the following text string:  ! A = 'The quick brown fox jumped over the lazy dogs'  To compose the text we might use the following comm and:  VAR! Table COMPOSE |$! A| WIDTH 11 C SPACES 2 |$! A| WIDTH 15 R  This would give the following output:Index Value [1] The quick The quick brown' [2] brown fox jumped over' [3] jumped over the lazy dogs' [4] the lazy ' [5] dogs '  COMPOSE always returns an array with at least one element. The number of array Elements depends on the length ofThe text strings supplied and the width of each column. Notice that all of the STRING array elements are sp ace-padded to the same length. Following the COMPOSE keyword is a list of column d definitions. For each column, there is a Text string, such as |$!A| which evaluates to a tex t string, followed by the column layout Keywords in any order: Keyword Effect WIDTH n Specifies the space-padded width of this column. If not specified the width Of the column will be the length of the input strin g. SPACES n Specifies the number spaces between this and the ne xt column. L LEFT Specifies text is to be aligned along the left edge of the column. R RIGHT Specifies text aligned along the right edge of the column C CENTRE Specifies justification in the center of the column .DELIMITER ' ' This can optionally be used to specify an alternati ve delimiter at which to Break the input. By default the text will be split at a white-space character such as space Which may be removed from the output text. If the d elimiter is specified as an empty string,The text will be split at the column edge whatever the content. The following are used to pass the name of a varia ble into PDMS as part of a stored Expression so that the value is taken when PDMS pro cesses the stored expression rather Than PML extracTing the value at the time the line is read:  VVALUE( ! X ) VTEXT(! AString ) VLOGICAL( ! Boolean)


Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 58/178 9.3. Using PML in PDMS The following facilities are only applicable to PDM S. A special global variable!! CE has been provided w hich always refers to the current Element in the database.!! CE can be used to obtain the DB reference of the current Element:  ! Item = !! THIS  !! CE is of type DBREF so the new variable! Item wil l also be of type DBREF. The dot Notation can be used to access attributes and pseud o-attributes of a database element:! Bore = ! Item.bore  This form of access can also be used directly on th e !! CE variable:  ! Owner = !! CE.owner  It is also possible to follow references between DB elements using this mechanism:  ! Rating = !! CE.cref.pspec.rating  Assigning a new reference to the!! CE variable make s the new reference the current element By navigating to it in the database:  !! THIS =!! CE.owner  P-points are accessed using the P-point number like an array subscript. For example, to Access the direction of P-point[1]:  ! Dir = !! CE.Pdirection[1] $*! Dir is a DIRECTION ob ject  To access the position of P-point[3]:  ! Pos = !! CE.Pposition[3] $*! Pos is a POSITION obje ct  A NULREF is treated as UNSET, so a NULREF can be te sted for in two ways:  If (! MyDBRef EQ NULREF ) thenIf ( UNSET( ! MyDBRef ) ) then  There is also the function BADREF which will detect whether a database reference is unset Or invalid (i.e. impossible to navigate to):  If (BADREF(! MyDBRef ) ) then . . .  Note: Use full-length names for attributesAs listed in the Appendix for compatibility with Future releases. You can assign a new value to aDBREF attribute, en suring that the type of the new value Matches the type of the attribute  !! CE.Built = TRUE


9.3.3. Accessing Information About a Session

Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 59/178 You can still assign an attribute value in this way even if the PML DBREF is not the current Element':  ! A = !! THIS !! THIS =!! CE.Owner ! A.Built = TRUE  You can even assign a PML object, such as POSITION, where this corresponds to the typeOf the attribute:  Note that where the type of an attribute is a PML o bject, it is not possible to set an object Member value, such as the up value of a POSITION, d irectly - this must be done in two Internships:  ! Pos = !! CE.Position ! Pos.Up = 2000 !!CE.Position =! Pos A number of special commands have been provided to set a PML Variable with Information about the current session. The commands are:  Current Session, Sessions, Projects, Teams, Users, MDBs, DBs  These commands can be used as in the following exam ple.The SESSION object has a Method that returns name of the MDB in the current session. Hence:  ! C = current session ! CurrentMDB = ! C.MDB()  This will set! CurrentMDB to the name of the curren t MDB. Using the facilities described here you can createAn expression and have it evaluated for all Elements which satisfy particular selection criteri a. The results of the expression are then Placed in a named array. The command syntax is:  VAR! Array EVALUATE (Expression) FOR select COUNTVA R! Counter Where: ! Array is the name of the array that will be created to c ontain the results of (expression) for All the elements selected within select. (Expression) is the expression that will be carried out for all the elements that match the Select criteria.Select is the selection criteria (see above, and the rele vant Reference Manual for your Product for details of selection criteria) COUNTVAR is an optional command which allows you to record how often the expression is Calculated in Counter , whichIs increased by one e ach time the expression is evaluated.  You can append the results of such an evaluation to an existing array using the APPEND Keyword. For example: VAR! BOXES APPEND EVALUATE ( XLEN*YLEN ) FOR ALL BOXES will add the values calculationAted from the express ssion for all BOXES to the (already Existing) array BOXES. You can also overwrite eleme nts in the array by specifying the first Index in the array which you want to be overwritten . The specified index, and the indexes Following it,Will be overwritten by the results of the evaluation. For example:


9.3.5. RAW keyword When setting Variables with VAR

Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 60/178 VAR! BOXES[99] EVALUATE ( XLEN*YLEN ) FOR ALL BOXES  Will place the result of the first evaluation for t he selected elements at index 99, overwriting Any existing item,And the following results in the subsequent array elements. Programs that use the Forms and Menus interface (e .g. the DESIGN, DRAFT and ISODRAFT modules) strip out line feeds and compress consecutive spaces to a single Space before text strings are assigned to array var iables.If this is not the effect you want, You can suppress this automatic editing by includin g the RAW keyword into the variable- Setting command line for these programs. The syntax for setting array variable elements to Unedited text strings is  VAR! VarName RAW ...  Where ... represents any of the standard VAR syntax f or setting variables. The Undo and Redo functionality has been exposed t o PML so you can create your own Set of undoable events. There are several ways PDMS adds entries to the undo system: • Using the MARKDB / ENDMARKDB commands. The syntax is as follows: MARKDB 'Text' • where text is an optional description to be includ ed with the mark. This causes a mark To be made in the database and an entry made in the undo stack. You should makeYour database changes, and then use the command END MARKDB • By creating a PML undoable object and adding it to the undo stack. See the Software Customization Reference Manual for a fuller descript tion of this object. You should Create an undoable objeCt, set up the undo and redo execution strings, and then Call the method add() to mark the database and add the undoable to the undo Stack. Make your database changes, and then call th e method end Undoable(). • Automatically whenever a model element iS moved us ing graphical interaction Techniques in Model Editor. Additionally you may re gister to be informed whenever An undo or redo operation has taken place, using th e PML PostEvents object. See The Software Customization Reference Manual for a fUller description of this object.  After an undoable has been removed from the stack a nd its state recovered then the user Supplied method on the PostEvents object is called, and will be passed the description text That was associated with the undoable object.


Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 61/178 10. Copies and References Assignment using = , the assignMent operator, usua lly does what you would expect, but a Detailed explanation of how the different data type s are handled may be helpful. Assignment always makes a copy of the right-hand-s ide to replace what is on the left- Hand side. The following command copies!Y into! X:  ! X = ! Y  If, for example, ! Y is an array, this command will duplicate the entire array making a copy of Each of the array elements. The same is true if! Y is an OBJECT. The technical term for this Is deep copy. Following this copy! X[1] = 'New Value'Will change! X[1] but leave the original array! Y u nchanged. !! Form and!! Form.Gadget are both PML references. A fter the command:  ! X = !! Form.Gadget  ! X is now a new reference, but the gadget itself ha s not been copied. Both PML Variables Now refer to the same gadget.! X.val = 'New Value' !! Form.Gadget = 'New Value'  Will both have the same effect and will assign a ne w value original gadget. You can think of a Reference as another name for the same object or va riable. !! CE is a DB reference. Following the command:! X = !! THIS  ! X is now a new reference to the same DB element, b ut the element itself has not been Copied.  ! Value = ! X.Attribute  Will now return an attribute of the current element . When the current element changes, !! THIS Will point to a new DB element.In this example, ! X will not be changed but remains as a Reference to the previous current element. Because!! CE is special,  !! THIS =! X  Will navigate to a new current element provided! X is another DB reference. In this example The command would nAvigate to the previous current element.  Where! Y is an array or object: ! X = ! Y


Response: AVEVA PDMS Programmable Macro Language manual2016 v.1. Page 62/178 will make a deep copy of! Y. However, if any of the array elements is a reference (e.g. to a Gadget or DB element), a copy is made of the reference, but not of the object it refers to. In Other words a deep copy stops copying when it reach ed a reference.A function argument is a PML reference to a value or object outside the function. In effect The argument is another name for the original PML V ariable. If we define a PML Function Such as the following:  Define function!! ChangeIt (! Argument is STRING)! Argument = 'New Value' $P! Argument $P!! Global Var Endfunction  Then invoke the function like this:  !! GlobalVar = 'Old Value' !! ChangeIt (!! GlobalVar)  The values printed for! Argument and!! GlobalVar wi ll both be 'NewValue'. Warning: Be veryCareful about changing function arguments. It is a powerful feature capable of causing Unexpected results. Passing a constant as a function argument, such as a STRING in quotes, means the Argument is read only and cannot be assigned a new value. So if we define a functionDefine function!! ChangeString( ! Argument is STRING ) ! Argument = 'New Value' Endfunction  The following will change the value of ! S:  ! S = 'Old Value' !! ChangeString ( ! S )  However, the following will result in a PML error m essage because the value passed to theFunction as an argument is a CONSTANT STRING value which cannot be modified.  !! ChangeString ( 'OldValue' ) $* WRONG A form or gadget value passed as a function argume nt is read only so cannot be Assigned a new value. If you wish to change the val ueOf a gadget passed as an argument, Pass the gadget itself as an argument, not its valu e:  Define function!! ChangeValue( ! Argument is GADGET) ! Argument.val = 'NewValue' Endfunction PDMS Database Attribute are read only, and so they cannot be given new values byAssigning to them.


Response:
AVEVA PDMS Programmable Macro Language manual
  2016 v.1. Page 62/178  will make a deep copy of !Y. However, if any of the  array elements is a reference (e.g. to a
gadget or DB element), a copy is made of the refere nce, but not of the object it refers to. In
other words a deep copy stops copying when it reach ed a reference.
 A function argument is a PML reference to a value or object outside the function. In effect
the argument is another name for the original PML V ariable. If we define a PML Function
such as the following:

define function !!ChangeIt ( !Argument is STRING)
  !Argument = 'New Value'
  $P !Argument
  $P !!Global Var
Endfunction

Then invoke the function like this:

!!GlobalVar = ‘Old Value’
!!ChangeIt (!!GlobalVar)

The values printed for !Argument and !!GlobalVar wi ll both be 'NewValue'. Warning: Be very
careful about changing function arguments. It is a powerful feature capable of causing
unexpected results.
Passing a constant as a function argument, such as a STRING in quotes, means the
argument is read only and cannot be assigned a new value. So if we define a function

define function !!ChangeString( !Argument is STRING )
  !Argument = 'New Value'
Endfunction

The following will change the value of !S:

!S = ‘Old Value’
!!ChangeString ( !S )

However, the following will result in a PML error m essage because the value passed to the
function as an argument is a CONSTANT STRING value which cannot be modified.

!!ChangeString ( 'OldValue' ) $* WRONG
 A form or gadget value passed as a function argume nt is read only so cannot be
assigned a new value. If you wish to change the val ue of a gadget passed as an argument,
pass the gadget itself as an argument, not its valu e:

define function !!ChangeValue( !Argument is GADGET)
  !Argument.val = 'NewValue'
endfunction
 PDMS Database Attribute are read only, and so they  cannot be given new values by
assigning to them.


Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 64/178 • UTF32BE UTF32 big-endian • ISO • LATIN1 ISO8859-1 • LATIN2 ISO8859-2• LATIN5 ISO8859-5 Cyrillic • Windows code page • CP932 Japanese shift-JIS • CP936 Simplified Chinese GBK • CP949 Korean • CP950 Traditional Chinese Big5 • CP1250 Central European • CP1251 Cyrillic • CP1252 LATIN1 + some extras (beware) • For backWards compatibility with legacy PDMS Proje cts • JAPANESE Japanese shift-JIS • CHINESE Simplified Chinese (EUC) • KOREAN Korean (EUC) • TCHINESE Traditional Chinese (used in Taiwan for e example) (EUC) PDMS provides a file transcoding utility transc.exE which users may find useful, particularly For moving files between PDMS12.1 and previous PDMS versions. Transc is a command line Application to transcode files from one encoding to another, and can also be used to add or Remove the BOM from existing UTF8 (or UTF16) files.The basic syntax is:  Transc -encoding> <input-file> -encoding> <output-f ile>  See Transc - text file transcoding utility.doc for more details. The major design decision for the Unicode conversi on of PDMS was to use (32bit) Unicode Scalar (US) iNstead of ASCII codes as it's integer character representation (holding Strings, with up to 4 bytes to represent 1 characte r. The section below describes a few Important properties of Unicode Scalars and the UTF 8 format.  Character. Unicode assumes tHat the 32 bit range wi ll cope uniquely with all the world's Character sets. Codes. To be able to clearly distinguish the number of cha racters held and the number of bytes Needed to represent them - as they cannot be assume d to be the same. Either direction.Search in either direction, and every first byte yi elds the number of bytes in the character. /, &, space, ~ etc.) then subsequent bytes of the c haracter are never ASCII bytes. So when You've found an ASCII byte it is a genuine characte r and not part of another character.


11.3. Diagnostic Messages From Within PML Files

Response: AVEVA PDMS Programmable Macro Language manual2016 v.1. Page 65/178 11.2. PML Tracing If a PML File does not appear to be running in the way you expect the easiest thing to do Is to turn on PML Tracing with the command:  PML TRACE ON  With PML Tracing switched on, each of the PML lines executed is output to the parentWindow together with its line number. Additional tr acing messages tell you when you have Begun to process a new PML File and when it has fin ished. To turn off tracing type:  PML TRACE OFF  These commands can also be put into a PML File on a temporary basis.You can also turn PML tracing on by setting the Environment Variable PMLTRACE to ON before you start the Program. For more precise control of PML tracing yo u can use the $R command. $R100 is The equivalent of PML TRACE ON and $R0 is the same as PML TRACE OFF.Type the Command $HR for online help on how to use the $R co mmand. It is often useful to output a line to the screen from within a running PML File to indicate That the execution of the program has reached a par ticular stage. Use the $P command: $P! Total is: $! Total and! Maximum is: $! Maximum  Note: The use of $ to convert the value of a variable to a STRING. The alpha-log is a file containing a record of all the commands processed together with Any text output and error messages. To startRecord ing use one of the following commands:  Alpha log /filename $* to open a new file Alpha log /filename OVERWRITE $* to replace an exis ting file Alpha log /filename APPEND $* to add to an existing file  To finish recording and close the file use:Alpha log END The alpha-log does not include standard PML tracin g from the command PML TRACE ON. For PML tracing to be included in the alpha-log , PML tracing should be directed to the Alpha-window. For example, to obtain standard PML t racing in the alpha-log use theCommand:  $R102  Refer to the online help given by $HR for other opt ions. If you cannot find out what is going wrong by mean s of PML trace output or writing out the Values of PML Variables, you may suspend a running PML File at a particular point byIncluding the command:


Response: AVEVA PDMS Programmable Macro Language manual 2016 v.1. Page 66/178 $MYou  Can then query the valuesOf any PML Variables of i nterest and even change the values of Some PML Variables. To resume processing of the sus pended PML File type into the Command line:  $M+  Use these facilities only for debugging and do not leave these commands in a finished PMLFile.  Note: These facilities do not apply to PML Functions or m ethods. A variety of queries are available to help diagnos e problems. Typically you might type These queries into the command line while a PML Fi le is suspended. Alternatively you couldInclude any of these commands temporarily within a PML File. If you are interested in the name of the currently running PML File and the other PML Files from which the current file was invoked use t he command:  $QM The table below gives some usefuL commands for que rying PML Variables.  Command Effect Q var! LocalName Queries the value of a specific local variable, u se the command. Q var LOCAL Queries the values of all local variables. Q var!! GlobalName Queries the value of a specific global variable.Q var GLOBAL Queries the values of all global variables Q var! MyArray[1] Queries the value of a specific element of an arr ay. Q var! MyArray Queries the values of all elements of an array. Q var! MyArray.Size() Queries the number of elements currently in an ar ray.When you are typing commands into a macro or into a command line, you may not Remember exactly what arguments are available or wh at other commands are related. You Will find full details in the appropriate Reference Manuals to the module, but you can also askThe command processor what sort of command or comma nds it is expecting next by typing: $Q  This will produce a list of every valid command wor d or argument type that you may enter Next. The list may be long and could include every valid command for the module that youAre in. The $Q facility is also useful to establish what is allowed as the next component of a Command. Type the beginning of the command sequence followed by $Q.


Response:
AVEVA PDMS Programmable Macro Language manual
  2016 v.1. Page 66/178  $MYou

can then query the values of any PML Variables of i nterest and even change the values of
some PML Variables. To resume processing of the sus pended PML File type into the
command line:

$M+

Use these facilities only for debugging and do not leave these commands in a finished PML
File.

Note:
These facilities do not apply to PML Functions or m ethods.
 A variety of queries are available to help diagnos e problems. Typically you might type
these queries into the command line whilst a PML Fi le is suspended. Alternatively you could
include any of these commands temporarily within a PML File.
 If you are interested in the name of the currently  running PML File and the other PML
Files from which the current file was invoked use t he command:

$QM
 The table below gives some useful commands for que rying PML Variables.

Command   Effect
q var !LocalName   Queries the value of a specific local variable, u se the command.
q var LOCAL   Queries the values of all local variables.
q var !!GlobalName   Queries the value of a specific global variable.
q var GLOBAL   Queries the values of all global variables
q var !MyArray[1]   Queries the value of a specific element of an arr ay.
q var !MyArray   Queries the values of all elements of an array.
q var !MyArray.Size()   Queries the number of elements currently in an ar ray.
 When you are typing commands into a macro or into a command line, you may not
remember exactly what arguments are available or wh at other commands are related. You
will find full details in the appropriate Reference  Manuals to the module, but you can also ask
the command processor what sort of command or comma nds it is expecting next by typing:
$Q

This will produce a list of every valid command wor d or argument type that you may enter
next. The list may be long and could include every valid command for the module that you
are in. The $Q facility is also useful to establish  what is allowed as the next component of a
command. Type the beginning of the command sequence  followed by $Q.


Response:
AVEVA PDMS Programmable Macro Language manual
  2016 v.1. Page 67/178  12. Upgrading from PML1 to PML2
• PML 1-First version of PML including loops, if sta tements, string handling , labels.
• Is faster with simple single line definition and s ingle execution,
• Returns array of strings of the references,
• The scope can include volumetric limits (within …) ,
• To obtain a value in PML 1 must be preceded with $ , var !value ($!number),
• PML1 must be still used when an expression is used  as an argument to a command
and must be enclosed in () brackets,
• PML 1 macros are in PDMSUI folder,
• PML 2-Object oriented language builds on PML 1 and  extends the facilities to be like
other object based languages (VB, Smalltalk)
• Is slower and initially more lines of code to set up the collection is necessary,
• Returns array of database references and
• Collection can be used as the scope of a collectio n,
• Can be used with the TABLE object,
• Can’t use volumes to limit the scope,
• To obtain a value in PML 2 is used =, !value = !nu mber,
• PML2 may be of any complexity, may contain PML fun ctions and methods and form
gadget values, !value = !!MyFunction(!arg) * !!Form .Gadget.Val /
!MyArray.Method(),
• PML2 may consist operators and operands (+,-,*,/,G T,AND,OR,&,EQ…),
• PML 2 macros are in PMLLIB,
• Variable Types - STRING, REAL, BOOLEAN and ARRAY,
• Built in methods for commonly used actions,
• User Defined Object Types,
• PML Search PATH (%PMLLIB%),
• Dynamic Loading of Forms, Functions and Objects,
• New Aid objects for geometric modelling,
• $Wn - Will Break the GUI Software
• Numbered Variables - Are no longer available
• Macros - Avoid Mixing with PML Functions
• Global Variables for results - Use Function “Retur n”
• $M- $M+ $MK - Only for debugging, not LIVE code
• $R+ $R- - Withdrawn, (PML TRACE ON/OFF)
• Synonyms - Not permitted in PML Functions but work s in macros,
• VAR Syntax - Use “=“ Where possible
• VAR Name READ - Use ALERT object or Form
• Expressions in () - Brackets not needed after “=“
• !VALUE = NAME - Use !VALUE = !!CE
• $ - Use variables without $
• Don’t Quote variables - With no $, quotes not need ed
• @ cursor functions - Use Event Driven Graphics
• !ARRAY[-ve] - Not allowed in PML2
• !ARRAY[0] - Not advised to use at PML2
• Dots “.” In Names - New meaning at PML2
• Form EDIT  - syntax Use direct setting


Response:
AVEVA PDMS Programmable Macro Language manual
  2016 v.1. Page 68/178  12.2. Important differences
Only Algebraic expressions are allowed, (No reverse -polish notations after “=“ sign)

Creating numeric variable with “=“ creates a REAL

Some PML1 macros using the “=“ will now create vari ables of the wrong type.

VAR !name value will now create a STRING value.

DO variables are now REAL rather than STRING

If “=“ has been used in existing PML code and probl ems are found, re-write the code using
PML2 technology, or revert to PML1 VAR technology.

Conversion utility “eq2var” (Currently runs through  an “awk” script)

DO variables in PML2 are automatically deleted to e nsure that they can be created, This can
upset other variables if of the same name.

On exit DO variables remain REAL; previously they w ould have been STRING +1 if loop ran
to completion.

Variable in “do values” is deleted on exit.

DO from to are required to be REAL, Existing macros  are unaffected by this ($)

Change variable names to avoid DO variables

Check DO expressions, re-write as necessary

Results of an expression in IF must be TRUE or FALS E.

An error will occur where ZERO=FALSE

e.g.                                     if ($value) then - - (PML1)
will have to be either       if ($value EQ 1) then
                                  or if ( BOOLEAN($value)) then

Most common occurrence
PML1  if ( match ($!String1,$!String2)) then
PML2  if ( match ($!String1,$!String2) GT 0 ) then

Check Form and Global Variable Names

Forms are now GLOBAL variables, and cannot have the  same names as a Global Variable.

Form and Gadget Names Must be Unique and Start with  a Letter

Forms & Menus enforces the rule that gadget names m ust start with a letter, and must be
unique, (Gadget names can be re-used in different f orms).

New Forms & Menus Error Messages.

No longer possible to use setup form from within .I NIT macro.


Response:
AVEVA PDMS Programmable Macro Language manual
  2016 v.1. Page 69/178
Gadgets that are outside the form are now ERRORS.

More than one OK,CANCEL or HELP will generate an er ror.

Var list & do list are restricted to LIST gadgets, for TEXTPANES & SELECTOR gadgets use
var pane,selector & do selector

DOT in variable, Form and Gadget Names Is now used as separator between a Form or
Object name and the name of one of its members or f unctions.

!Array.size()
var !String ‘comment’
!Old.Name = ‘!String’

could now use:
!Size = $!<Old.name>.length()
or
!Size = $!Old.name$N.length()

Negative Array Subscript is now an Error.
Array subscripts MUST now be positive or zero, Zero  is permitted but many of the array
methods ignore the zero’th element. Macros which ma ke use of negative array subscripts
will need to be revised.

$MKn & $MK-n Withdrawn.

These commands may have had a role when macros were  run directly from a terminal, but
are incompatible with form-driven software.

Macros will have to be re-written.

Synonyms are NOT Available in PML Functions but are  still available in Macros.

= in PDMS10 is not compatible with = in PDMS11

Components in Function to the Right of “=“

Existing “var” code is not affected.

Add brackets if PML1 code has none.

To convert to “text” add “$”

!X = 32 , !Y = 52
!Z = !X + !Y Result = REAL  …..84
!Z = ‘$!X’ + ‘$!Y’ Result = STRING  …..3252