Omnis经验备忘
Omnis经验备忘
语言基础
#F只能存0,1,kTrue,kFalse这四种值,可以与数值直接相加
几种CRUD返回值:
. 原生的$update, $insert, $delete返回0,1(可存入integar或boolean)
. SNF.t_Oracle.$update返回kTrue, kFalse
. list.$fetch(n)返回kFetchXXX(只能存入integar类型中,如#1)
. statement.$fetch(list)返回0,1
. list.$dowork(), list.$doupdates(), list.$dodeletes(), list.$doinserts(), list.$select()返回kTrue, kFalse
各数据类型之间的等值比较
. kFetchFinished (0x1) ---> "kFetchFinished" === kFetchFinished
. kTrue ---> "true" === kTrue
. 1 ---> "1" !== kTrue
Ctrl+Break可中止循环运行
需要在Text:中使用"["、"]“字符
使用 [[var] 即可
current task和active task
- active task —> own topmost Window / menu / toolbar
- current task —> own current exceuting method
- $active() , $deactive(), $root.$activetask <==> 会引起active task更改
- $suspend, $resume <==> 会引起current task更改 当调用code, method时,current task不会更改,所以在$sqlerror中可以用$cinst.$val来引用sql中绑定变量@[var]的var值。
运行时entry的内容
除了用绑定的变量获取外,还可以用$contents属性。注意不是$text。
$cinst与$cwind的区别
- $cinst — The instance which contains the current exec method
- $cwind — The current open window instance 由于始终只会有一个$cinst,因此当运行的窗口有父类时,$cinst为当前的子类窗口,此时在父类窗口中使用$cinst便会出错。
$merge和$assignrow
$merge结合selected可以一次性赋值多行给一个列表,但只能是完整的行;$assignrow可以给一个列表的部分列一次性赋值。
列表相关
List.$filter()
List.$filter()是保留match filter的行,而且List要是smart list。
List.$unfilter()
List.$unfilter()不带参数是清除最后一次filter,unfilter(1)是清除所有除了第一个filter,unfilter(0)是清除所有。
统计选中的行数
lList.COL1.$count(kTrue)是不符合语法的,要用lList.$cols.COL1.$count(kTrue)
lList.$search($ref.COL1=lList.COL1)
这是不符合语法的,只能先将本行的lList.COL1暂存起来:
```Calculate lCOL1 AS lList.COL1
lList.$search($ref.COL1=lCOL1)
```
List和Row的$fetch()比较
. row.$fetch()不出错时,若查询结果不为空,则只能返回kFetchOK(不管fetch有没有后续结果,也不管fetch(n)中的n为多少);若查询结果为空,才会返回kFetchFinished.
.list.$fetch()不出错时,fetch(1)只能返回kFetchOK(不管fetch有没有后续结果);fetch(n) (当n>1时)才可能能返回kFetchFinished。为什么要在$selectToList中返回status是因为如果需要分页,那么kFetchOK状态必不可少。
**综合来讲,对row,kFetchFinished意味着找不到记录;kFetchOK意味着可以找到,但可能是多条之一。因此用$rowfetched来判断是否找到更准确,语义也更清晰,另外用$rowsfetched而不用$linecount是因为前者才能体现从数据库中fetched的行数,后者只是总行数。**
Grid(data或string)只有当$dataname为手动declare的list(通过$define)而非查询得到的list(通过$definefromclass)时,$extendable才会有效。
Popup List的多选特性
. 当不开启multiplselect时,由current line来决定在哪一行上显示选中标志,已选中的将无法再次响应evClick。
. 当开启multiplselect时,由selected line来决定在哪一行上显示选中标志,已选中的仍然可以再次响应evClick,current line为当前点击的那一行。
遍历效率
两个列表keepList和oldList,keepList有50000行,oldList有200000行
- 遍历oldList每行去$search keepList 耗时 72m
- 遍历keepList每行去$search oldList 耗时 63m
- 结论$search比遍历略快
$filter()和$search()的效率
当Omnis中的list的数量达到几千条时,$filter的效率会很低,如果是在循环中不断$filter、$unfilter可能效率比连到数据库查询还要慢。但$search的效率很高,因此如果仅仅是判断是否存在,尽量应该用$search,如果还需要一些只有$filter才能完成的功能,比如看满足条件的记录数量,如$linecount,可以先用$search来select记录,然后将标记为selected的记录merge到另一个新的list中,在那个list中再做filter,效率会提高很多。
*(2019年11月25日补充)见27条,可以先$search,然后用$count。*
SQL相关
sql变量绑定
在Sta:sql中使用变量绑定时(@[var])要注意,字符型var的subtype不能使用默认的100000000(1E8),否则Omnis会自动使用CBLOB类型来绑定,而CBLOB在WHERE条件中是不支持的,从而导致prepare()正常,execute()出错。
sql变量绑定LIKE
Omnis中Sta:sql中的变量绑定不支持LIKE @[con(var,’%’)],因此需要使用Oracle的字符连接操作:LIKE @[var] || ‘%’ 。
其它
Omnis中的Event流向
field —> $cwind.$control —> $ctask.$control
Clock Control是阻塞的
Clock Control是阻塞的,比如evSecondChange,当事件触发时,如果上一个事件没有执行完,那么本次事件将被丢弃。
Omnis生成PDF似乎是异步的
因此会导致如果立即发送PDF,PDF可能是不完整的,可以用sleep来等待。
常量kAutoxl…
要避免使用此类COM常量,因为当Excel COM未初始化时,kAutoxl... 全部为0。
Excel Interactive属性
如果处于交互模式,则该属性值为True;如果设置该属性为False,则Excel将禁止所有的键盘输入和鼠标输入(由代码显示的对话框的输入除外)。说明:禁止用户输入将使用户不能干预宏移动或者激活Excel对象。**如果正使用DDE或者OLE自动化从其他应用程序和Excel进行通信,则该属性很有用。**如果将该属性设为False记注要将它设回True。如果在代码的运行过程中不想用户干预的话,把该属性设置为False非常不错的选择,但切记在代码结束前恢复为True。
TCP接收消息时
TCP接收消息时,在server端接收client的消息是非阻塞的,而在client端接收server端的消息是阻塞的。
对于Excel的OLE调用
Excel作为OLE服务被调用时,会可能因此各种原因阻塞,从而抛出0x800AC472错误,对支持异常的语言,可以不断循环测试此异常,直到阻塞解除。对Omnis不行,只能尽量将对excel的同仁操作尽量延后,将其它功能性操作提前。
重命名Class
要重命名Class,需要先copy,paste,然后将新Class check in到VCS,然后Check out新Class,这样可以保留一份最新备份,以备回滚。
大量数据遍历
如果使用引用来遍历$cols信息会变很慢(w_Delayed_Orders中的export),此时不如空间换时间,不用引用,直接遍历原数据。