概述

  • Programmable Macro Language可编程宏语言
  • PML2基于面向对象(Object Oriented)概念的编程语言
  • 支持用户可自定义对象类型(Object Types)
  • 简单易学,与PDMS无缝连接
  • 丰富的内置函数,方法及对象
  • 最简单的对话框,菜单编写语言

PML构成

  • Macros
    • Macros是包含PDMS命令序列的ASCII文件
    • Macros在PDMS中通过$m /FILENAME来执行
  • PML
    • 变量(Variables)
    • 判断语句(if Constrcuct)
    • 循环(Do loops)
    • 错误处理(Error Handling)
    • 文件处理(Files and Directories)
  • 窗体和菜单
    • PDMS大多数应用程序都由对话框(Forms)和菜单(Menus)来驱动

简单示例

简单的宏

  宏是包含PDMS命令序列的一个文本文件。以下宏创建了一个EQUIP

1
2
3
4
5
NEW EQUIP /FRED
NEW BOX
XLEN 300 YLEN 400 ZLEN 600
NEW CYL DIA 400 HEI 600
CONN P1 TO P2 OF PREV

  运行宏

1
$M /MyFile

CurrentElement选中为ZONE上,以正确的创建EQUIP

参数化宏

  宏可以参数化

1
2
3
4
5
NEW EQUIP /$1
NEW BOX
XLEN $2 YLEN $3 ZLEN $4
NEW CYL DIA $3 HEI $4
CONN P1 TO P2 OF PREV

  文件名后面的字符串是参数(parameters)

1
$M /MyFile FRED 300 400 600

  宏的参数:

  1. Macros可以有多达9个由空格分隔的参数
  2. 文本字符串可以以单个参数输入
  3. $<$>是分隔符,在它们之间的任何字符都被认为是单个参数
1
$M /MyFile $< Hello World $>

宏内的$1~$9类似于参数的插槽

变量

基本概念

变量的基本概念

  • 变量用于存储数值
  • 变量必须有名字
  • 变量的数值可以改变,但变量名固定

PML变量

  在PML2中变量是一个对象(Objects)

  • 每一个对象(变量)有一个唯一的名字
  • 每个对象都有一套函数与之相关联,这些函数称为方法(Methods),方法用于处理对象中的数据
  • 生成对象时必须指明对象类型(Object type),不同的对象类型对应不同的方法

变量类型

  • 内置(Build-in)的对象类型
    • 字符串类型(String)
    • 实数类型(Real)
    • 布尔类型(Boolean)
    • 数组类型(Array)
  • 系统定义(System-defined)的对象类型
  • 用户自定义(User-defined)的对象类型

变量操作

  以下统一采用String类型的Msg变量作为演示

变量声明

直接声明变量类型

1
!Msg = String()

通过赋值声明变量类型

1
!Msg = 'Hello,World'

变量值修改

1
!Msg = 'Hello,PML'

变量类型一旦声明则不允许修改

查询变量

1
Q VAR !Msg

查询不存在的变量会输出 Undefined

变量删除

1
!Msg.delete()

如果变量名不存在会报错

变量命名规则

  1. 局部变量(Local)和全局变量(Global)

    • !SurfaceArea !表示局部变量
    • !!Area !!表示全局变量
  2. 变量名最长16个字符(不包括!!!),变量名可以包含字母和数字

  3. 变量名不能用数字和点(.)开头

  4. 变量名的大小写不敏感

建议: 一个变量一个用途,最好给变量名一个有意义的名字,并且区分大小写

属性

PDMS属性类型-系统定义变量类型
变量类型 示例属性
字符串(String) Name、Description、Function
实数(Real) Angle、Temperature
布尔(Boolean) Lock、Shop、Built
数组(Array) Level
参考(Reference) Spref、Catref、Lstube
关键字(Word) Type、Purpose
位置(Position) Position、Hpsoition
方位(Orientation) Orientation
方向(Direction) HDirection

变量提取属性

用变量提取属性值,变量名 = 属性名

1
2
3
4
5
!Name = Name
!Desc = Description
!Pspec = Pspec
!Temp = Temp
!Purp = Purp

查询属性类型

1
2
3
!Ref = Ref

Q Var !Ref

变量给属性赋值

  属性名 $变量名,其中 $ 表示将变量的值转换成字符串,PDMS命令行只接受字符串的值

- 给名字赋值,第一个字符必须是 /

1
2
!Name = '/NewName'
Name $!Name
  • 给字符串赋值,必须用单引号括起来
1
Desc '$!Desc'
  • 给实数赋值
1
Temp $!Temp
  • 给参考赋值,参考元素必须存在
1
Pspec $!Pspec
  • 给关键字赋值,只提前四个字符,不用括号
1
Purp $!Purp

方法和函数

  • 函数(Function)是执行特定功能的子程序
  • 方法(Method)是对象(变量)的函数
    • 在PML2中变量是一个对象(Objects)
      • 每一个对象(变量)有一个唯一的名字
      • 每一个对象都有一套函数与之相关联,这些函数称为方法(Methods),方法用于处理对象中的数据
      • 生成对象时必须指明对象类型(Object tyep),不同的对象类型对应不同的方法
    • 方法并不改变对象的类型和对象中的值

字符串方法

常用字符串方法
方法名 描述
Length() 字符串长度
Real()、Position()、Boolean 类型转换
LowCase()、UpCase() 大小写转换
After(str2)、Before(str2)、Substring(index) 两端截取
Substring(index,nchars) 中间截取
Part(nth)、Part(nth,delim) 分隔符截取
Replace(str2,str3) 替换
Match(str2)、MatchWild(str2) 匹配
Split() 分割
Trim()、Trim(option) 修剪

  使用示例

1
2
3
4
5
!str = 'hello how are you'
!msg = !str.after('hello').trim().upcase()
q var !msg

<String> 'HOW ARE YOU'

标准函数

常用标准函数
函数名 描述
SIN、COS、TAN、ASIN、ACOS、ATAN 三角函数
SQR、POW、ABS 开方、次方、绝对值
LOG、ALONG 对数、取对数
INT NINT 取整、四舍五入取整
MATCH、DMATCH 匹配、中文字符匹配
MAX、MIN 最大值、最小值

  使用示例

1
2
3
4
5
6
!s = 30 * sin(45)
!len = Length('abcdef')
!t = pow(20,2)
!sqr = SQR(4)
!m = match('abcdef','cd')
!f = (match(Func of Zone,'Piping') gt 0)

自定义函数

函数定义

  将函数定义成全局变量

1
2
3
4
define function !!Area(!Length is REAL, !Weight is REAL) is REAL
!Area = !Length * !Width
return !Area
Endfunction

  文件命名和存放位置

文件名必须与函数名一样,后缀是小写的pmlfnc

函数调用

  1. 将新建函数加到索引文件Pml.index
1
Pml Rehash All
  1. 调用函数并且得到返回值
1
!MyArea = !!Area(6,4)

表达式

  表达式运算符(Expression operators):

  • 算术运算符
    • +
    • -
    • *
    • /
  • 和并符
    • &
  • 比较运算符
    • EQ
    • NE
    • LT
    • LE
    • GT
    • GE
  • 布尔运算符
    • NOT
    • AND
    • OR

表达式说明

  • 表达式可以嵌套
  • 表达式前后的类型必须一致
1
2
3
4
5
6
7
!X = 64
!Y = 32
!Z = !X + !Y $* !Z = 96

!A = 'Hello'
!B = 'World'
!C = !A + !B $* !C = 'HelloWorld'

逻辑控制

分支语句

语法

1
2
3
4
5
6
7
IF () THEN
...
ELSEIF () THEN
...
ELSE
...
ENDIF

示例

1
2
3
4
5
6
7
8
9
!Type = Type
!OwnType = Type of Owner
IF (!Type eq 'BRAN') THEN
$P CE is Branch.
ELSEIF (!OwnType eq 'BRAN') THEN
$P CE is Branch member.
ELSE
$P CE is $Type,Pls select Branch.
ENDIF

循环语句

语法

1
2
3
Do Condition
...
Enddo

示例

1
2
3
4
5
!SUM = 0
Do !i From 1 To 100
!SUM = !SUM + !i
Enddo
$P $!SUM

中断循环(Break)

1
2
3
4
5
6
7
8
!SUM = 0
Do !i From 1 To 100
!SUM = !SUM + !i
If(!SUM gt 500) then $* SUM > 500
Break
Endif
Enddo
$P $!SUM

跳过循环(Skip)

1
2
3
4
5
6
7
8
!SUM = 0
Do !i From 1 To 100
If(Int(!i / 2) NE (!i / 2)) then $* 跳过奇数(求所有偶数和)
Skip
Endif
!SUM = !SUM + !i
Enddo
$P $!SUM

跳转语句

语法

1
2
3
Label /标记             $* 设置标记
...
GoLabel /标记 $* 跳转标记
  • golabel可以跳转到标记行,不限制前后顺序
  • Label名最长16个字符,不包括/

示例

1
2
3
4
5
6
!Total = 0
GoLabel /illegal $* 不进入Do循环中
Do !x from 1 to 5 by 1
!Total = !Total + !x
Label /illegal
Enddo

错误处理

错误提示

错误格式

1
(2,113) List exhausted
  • 2 代表错误出现在PDMS中的哪个模块
  • 113 是错误代码

  出现错误通常有三种结果

  • 出现一个警告框,用户必须确认
  • 输出一个错误信息
  • 从当前运行的程序中退出

错误处理

处理特定错误,使程序继续执行

1
2
3
4
5
Next
Handle (2,113)
$P Last Element
EndHandle
$P OK

处理任何可能的错误

1
2
3
4
Next
Handle Any
EndHandle
$P OK

通用功能

注释

  • 单行注释
1
2
-- 单行注释
$* 单行注释
  • 段落注释
1
2
3
4
$(
段落注释
段落注释
$)

打印

1
$P This text will be output to the screen       $* 该文本将输出到屏幕上

换行

1
$P this is an example of a much longer message $ that will be output to the screen

数组

数组创建

从字符串创建数组

1
2
3
4
5
6
7
8
!Str = 'Benz,Bmw,Audi'
!BestCar = !Str.Split(',')
Q var !BestCar

<ARRAY>
[1] <STRING> 'Benz'
[2] <STRING> 'Bmw'
[3] <STRING> 'Audi' $* 数组元素,索引号

逐个元素添加

元素索引不需要依次顺序

1
!BestCar[4] = 'Cadillac'

数组追加

1
!BestCar.Append('Lincoln')   $* 数组必须存在,否则提前声明

数组方法

数组常用方法
方法 描述
Size() 数组元素数量
Append(value) 追加元素
AppendArray(Array) 追加数组
Clear() 删除全部元素
!MyArray[N].Delete() 删除单个元素
Delete() 删除数组
Compress() 压缩数组
Sort() 排序
Invert() 倒序
Find(value)、FindFirst(value) 搜索
Unique() 合并重复项

数组循环

赋值循环(Do value)

1
2
3
Do !Name values !BestCar
$P Array element is $!Name
Enddo

索引循环(Do indices)

1
2
3
4
Do !i indices !BestCar
!Car = !BestCar[!i]
$P Array element $!i is $!Car
Enddo

特殊方法生成数组

  生成的!PipeComps是数组,保存的是元素的参考号

基本用法

1
Var !PipeComps Collect all Branch members For CE
常用类型
类型 描述
ALL 所有元素
ALL Pipe 所有的Pipe
BRANCH MEMBERS 所有管件,不包括Tube
ALL BRANCH MEMBERS 所有管件,包括Tube
ITEMS OF EQUI /D1201 设备中的所有基本体

限制条件

With后面的是一个表达式

1
Var !Elbows Coll All Elbow With (Abor gt 100) for CE

限制区域

1
2
3
Var !Elbows Coll All Elbow Within W0N0U0 to W2000N2000U2000

Var !Elbows Coll All Elbow Exclusive Within Volume /D1201 1500

追加

1
Var !Elbows Append Coll all Bend for CE

求值

管道排序,倒序输出所有Pipe的名称

1
2
3
4
5
6
7
Var !Pipes Coll all Pipe for CE
Var !Names Eval name for all from !Pipes
!Names.sort().invert()
Do !i indices !Names
reorder $!Names[$!i] before $!i
Enddo
Q Var !Names

文件处理

 读写文件

1
2
3
4
5
6
7
8
9
!Input = object FILE('%pdmsexe%abc.txt')
!Lines = !Input.ReadFile() $* ReadFile将文件内容写到字符串数组中
!ResultArray = Array() $* 声明新数组
Do !Line values !Lines
!Col = !Line.Part(1)
!ResultArray.Append(!Col)
Enddo
!Output = object FILE('%pdmsexe%abc_copy.txt')
!Output.WriteFile('WRITE',!ResultArray) $* WriteFile将数组写到文件
  • ReadFile()方法可以自动打开(Open)和关闭(Close)文件
  • 写文件还有覆盖模式OVERWRITE和追加模式APPEND

全局变量

CE

  一个特殊的PML GLOBAL variable(全程变量)!!CE常常是指向当前的PDMS元件以及它的属性:

1
2
3
!BranchHeadBore = !!CE.Hbore
!HeadPosition = !!CE.Hposition
!Easting = !HeadPosition.East

  相对于其他元件的位置

1
!PosWRTValue = !HeadPosition.WRT(!Value)

Alert

  用于在PDMS中的弹窗提示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$* 基本用法
!!Alert.Error('You cannot do this!')
!!Alert.Message('Saving your data now')
!!Alert.Warning('Do not press this button again!')

$* 指定其在屏幕上的位置
!!Alert.Error('You cannot do this!',0.25,0.1)

$* 确认框 (YES/NO)
!Answer = !!Alert.Confirm('Are you sure!')

$* 确认框 (YES/NO/CANCEL)
!Answer = !!Alert.Question('OK to delete Site?')

$* 输入框 (参数2为默认值)
!Answer = !!Alert.Input('Enter Width of Floor','10')

Forms

  • Forms是由全局变量表示的一种对象类型
  • 查询Forms
1
Q VAR !!formname                $* 将列出form的所有属性以及所有gadget成员
  • 查询gadget
1
2
Q Var !!formname.gadgetname
Q Var !!formname.gadgetname.val

FORM定义

1
2
3
4
5
6
7
8
9
10
setup form !!myform
Title 'My Form Title'
Icontitle 'Myform'
!!myform.initcall = '!this.init()'
...
exit

define method .init()
...
endmethod

显示和隐藏Forms

  • 新的搜索机制,不需要预先加载
  • 显示FORM:
1
2
$* 显示Forms
show !!formname
  • 加载FORM,而不显示
1
loadform !!formname

Forms内置方法

  • 显示form
1
!!Myform.Show()
  • 隐藏form
1
!!Myform.Hide()
  • 查询FORM是否隐藏
1
2
3
if(!!Myform.Shown()) then
...
endif

Gadgets

  • 在form中定义gadgets,通常有两个目的
    • 定义gadgets在form中的区域
    • 如果gadgets被选择,定义它的调用执行
    • 每个gadgets的大小和位置决定其占据的区域
  • GadgetCALLBACK来启动gadgets的调用执行

内置方法

  • Gadgets是有许多Members的Object,可使用许多有用的内置方法
  • 禁用一个gadgets
1
!!Myform.GradgetName.Active = false
  • 使键盘键入收敛在某个gadget
1
!!Myform.GadgetName.SetFocus()

Callbacks调用

  • 任何一个可选择的gadget在它创建时都有一个callback
  • 这个callback可执行以下三种功能
    • 显示一个form
    • 执行执行一条命令
    • 调用一个函数function或方法method

简单的Forms示例

1
2
3
4
5
6
setup form !!hello
Title 'My Form Title'
Icontitle 'Myform'
paragraph .Message text 'HelloWorld'
button .bye 'Goodbye' OK
exit

Gadgets定义

  • Gadgets are positioned on a form from top left Gradgets原点在FORM的左上角
  • 每个Gadget有四个定位点 (XMIN、XMAX、YMIN、YMAX)
  • 可用以下语法定义Gadgets
1
2
3
At Xmin .apply Ymax -0.5
at ymin
at xmax .frame1 + 4
  • 定位Gadgets在FORM的右下角
1
at xmax from - size

Gadgets的相对布置

  • 相对上一个Gadget
1
Toggle .OnOff at XMIN YMAX+1
  • 相对一个指定的Gadget
1
Toggle .OnOff at XMIN .Gadget1-size YMAX .Gadget1+1

Gadget布置

  • Path命令可用来定位下一个Gadget的逻辑位置
    • PATH DOWN表示下一个Gadget在当前Gadget的下方
    • PATH RIGHT表示下一个Gadget在当前Gadget右方
  • gadgets之间的垂直和水平间距由VDISTHDIST控制
  • 可用HALIGNVALIGN来水平方向和垂直方向对齐
    • 选项LEFTRIGHTTOPBOTTOM控制上、下、左、右对齐
    • 例如:HALIGN LEFT水平对齐
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
button .Bu1
PATH down

HALIGN centre
VDIST 2

paragraph .Par2 width 3 height 2
toggle .Tog3

PATH right
HDIST 3.0
VALIGN bottom

list .Lis4 width 2 height 3

PATH up
HALIGN right

paragraph .Par5 width 3 height 3

常用Gadgets

Paragraph

  Paragraph是一个简单的命名的gadgets,它用来在FORM上显示文本或图片

1
Para .cwd at 0 0 Text 'Current Directory'
Button
1
2
3
4
5
6
7
8
Button .Button 'Pop Form' FROM !!PopForm
Button .Calculate 'Calculate' Callback '!!MyFunctionName()'
Button .Apply 'Apply' Callback '!!MyFunction()'
Button .ok 'OK' Callback '!!MyFunction' OK
Button .cancel 'Cancel' '!!MyFunction' OK
Button .reset 'Reset' Callback '!!MyFunction' RESET
Button .help 'Help' Callback '!!MyFunction' HELP
Button .dismiss 'Dismiss' ok

改变button的背景颜色

1
!!Workbench.Apply.Background = 2

为button增加一个图片

1
Button.Apply pixmap /c:/pml/aveva.bmp
Frame
  • Frame 类似一个镜框,包含一些相似的gadgets.
  • FRAME 的语法:
1
2
3
4
FRAME .MYFRAME AT 0 3 'My Frame'
Button .B1 'Press Here'
Button .B2 'Or Press Here'
EXIT
Text

Text Input gadget 提供用户输入值的位置

1
Text .DirName callback '!This.TopDir()' AT X 0 Width 50 is String
Textpane

TEXTPANE 提供一个可编辑多行文本的区域,可以从区域内剪切、粘贴、删除文本

1
Textpane .textp 'My Textpane' at x 3 y 6 width 50 hei 6