PB他人经验

1、自定义下Setfilter()的使用是如果没有按照某项字段排序,在条件筛选后行的顺序会发生改变,这样不利于TXT文本形式保存后能同原始文本行顺序一致,如果有次需求可以通过定义字段排序或是没有字段排序的通过FIND遍历窗口来获得同样效果,避免行序改变,影响其他统计运算

2、得到文件夹下某个类型文件的文件数:通过ddlb_1.dirlist(ls_path+'\*.*',3)然后用函数得到ddlb_1的列数量就可以,详情看dirlist函数说明

3、datawindow里将字段设成 DropDownListBox 类型,在语句中修改、清空、列表内容可以用dw_1.modify("列名.values = '是~t是/否~t否/无~t无/其它~t8'")来实现,其中~t是标识符,前面的是显示值后面的是实际值,多行值时通过/来分割

4、数据窗口中关于重复行解决:对于数据窗口中某字段判断是否有重复行,可以通过比较上下排序的对应该列行值是否相等或是是否只有一行来SETFILTER一下,即:
首先dw_1.SetSort(你的字段名 + " A")
dw_1.Sort()
然后根据你排序的字段进行条件筛选
dw_1.SetFilter(你的字段名 + " <> " + 你的字段名 + "[-1] or GetRow() =1")
dw_1.Filter()
if dw_1.RowCount() < 原来的 then
MessageBox("注意",你的字段名 + "列中存在重复的数据!")
end if

这个可以应用于自定义数据窗口中导入不重复的数值,如果单纯判断某数据窗口中某字段是否有重复行可以直接应用dw中的内部cloumn中object的条件设置来判断,具体如下
if long(dw_1.describe("evaluate('count(l列名 for all distinct)',1)"))有重复的
end if
在这里evaluate('expression', rownumber)函数(脚本中中调用datawindow 表达式的方法)是对一指定的rownumber进行'expression'表达式的调用,然后通过describe()函数(描述数据窗口对象中的相关信息)来获取表达式的取值,上例中因为表达式中用到了ALL,所以其后的rownumber无所谓是否DW_1.ROWCOUNT(),如果是别的表达式针对某一行的话则须要准确地ROW,不过习惯好的还是要用DW_1.ROWCOUNT()
evaluate()函数解释:在脚本中中调用datawindow 表达式的方法,通过describe()函数返回值返回类型是字符,如果错误类型返回‘!’ 如果没有数值返回‘?’
举例:
比如你的数据窗口是DW_1,有一个字段是COL1,而且你的COL1是用的一个下拉数据窗口做的,如果你想知道COL1第12行记录的真正的值,则用dw_1.Object.col1[12]就可以得到,如果你想知道COL1第12行记录的显示的值,则用dw_1.Describe("Evaluate('LookUpDisplay(col1)', 12)")可以得到。
就是在PB SCRIPT中去执行PAINTER FUNCTION,否则是不能直接在PB SCRIPT中去执行PAINTER FUNCTION的。
5、关于数据窗口中GROUP分组形式

的datawindows如果显示各个分组的独力序号:
1、如何显示各个分组的序号:
建一个计算列,EXPRESSION设为countcumulativeSum(1 for all distinct 要分组的列名)
或者cumulativeSum(if(city = city[-1], 0, 1) for all)

2、如何设置datawindow分组后每个分组中的记录号?
建立一个计算列,expression为 getrow() - first(getrow() for group 1)+1
first(getrow() for group 1)这句话要好好理解,它其实是求的该分组当中的第一行,相当
于min(getrow() for group 1),同理last(getrow() for group 1)、max(getrow() for group 1)则
表示该分组当中的最后一行的行号。
要得到分组数量:
如何获取总分组数:
1、方法一:
建一个计算列,EXPRESSION设为"count(要分组的列名 for all distinct)"
2、方法二:
dw_1.describe("evaluate('count(要分组的列名 for all distinct)',"+string(dw_1.rowcount())+")")
不能直接用ROWCOUNT()函数,:)
或:
dw_1.describe("evaluate('countcumulativeSum(1 for all distinct 要分组的列名)',"+string(dw_1.rowcount())+")")

6、 对于DDLB下拉窗口,有时候需要通过ENTER键来实现无鼠标操作,可是当焦点移到其上时,通过键盘的上下键不能实现弹出下拉框来选择,而是单行单行显示所选值,用户界面不友好,所以需要通过触发鼠标左键点击ddlb的下拉动作,这里可以通过WINDOWS的send(handl(message),#,#,#)来实现相应某个WINDOWS事件,这里发出send()动作时具体通知的message是通过$+10进制数字表达来传递给WIN窗口一个动作,这里就是按下鼠标左键的动作,例如:
if key = keyenter! then
Send(handle(ddlb),513,0,0 ) //这里513就是对应send() API中的参数$0201 (表示点击鼠标左键)
return 1
end if




窗口使用技巧系列文章--增强窗口显示效果2006-11-06 17:52
一、窗口最小化时设置动态图标

二、放置闪烁文字

三、提高窗口的打开速度

四、移动不带标题栏的窗口

五、闪烁窗口标题栏

六、给窗口添加自动滚动条功能

窗口是应用程序中一个非常重要的界面,界面设计的大部分工作体现在窗口界面的设计中。所以,在不影响功能的前提下,提倡给用户提供更有提示性的、更美观的界面。常用的手段是动画、声音等,下面介绍这些常用的方法。

一、窗口最小化时设置动态图标

当应用程序最小化时,程序的图标如果是动画的,肯定更能吸引用户的注意,视觉效果会更好。方法是通过动态修改程序的图标来实现。

当程序最小化时打开timer(在deactive中加入timer(1)语句),并在timer事件中编写如下程序:

If This.Icon = "appico.ico" Then

This.Icon = "reverse.ico"

Else

This.Icon = "appico.ico"

End If

程序激活时关闭Timer事

件(在Active事件中加入timer(0)语句)。

需要注意,要将上面用到的两个ico文件放到当前应用程序的目录中。

二、放置闪烁文字

以闪烁文字显示重要信息可以吸引用户的注意力,避免这些重要信息被忽略。通过周期性修改visible属性,可以实现闪烁效果。

在窗口中,假设放置一个静态文本st_1,在窗口的Open事件中定义Timer事件的间隔:

Timer(1)

然后,在窗口的Timer事件中定期修改静态文本的visible属性:

If Mod(Second(Now()),2) = 1 Then

st_1.visible = False

Else

st_1.Visible = True

End If

这样就可以实现闪烁效果。当然也可以在适当的时候使用timer(1),并在适当的时候关闭Timer事件。

三、提高窗口的打开速度

在窗口的Open事件中经常编写脚本来进行初始处理工作,如果这些工作花费的时间比较长,在窗口显示之前用户就得等待很长的时间。友好的界面应该马上显示窗口界面,然后让用户等待,并且设置鼠标形状表示当前正在进行处理,以免用户焦急。可以使用用户自定义事件和PostEvent函数来解决这个问题。比如,下面是一个检索大量数据的窗口编程:

在窗口中定义自定义事件ue_openpost(映射PowerBuilder的任意一个CusTom事件),在窗口的Open事件中编写如下脚本:

PostEvent("ue_openpost")

然后在窗口的自定义事件ue_openpost中编写如下脚本:

SetPoInter(HourGlass!)

dw_1.SetTransObject(SQLCA)

dw_1.Retrieve()

SetPoInter(Arrow!)

使用函数PostEvent和TriggerEvent都可以触发其他的事件,但是两者是有区别的。PostEvent触发的事件不是马上执行,而 TriggerEvent触发的事件马上执行。PostEvent向消息队列中发送消息,等当前脚本执行完毕再触发消息队列中等待状态事件的脚本;而 TriggerEvent函数可以中断当前执行的脚本,转向被触发事件,等执行完被触发事件的脚本后再返回到当前脚本继续执行。所以,当需要马上执行被触发的事件时使用函数TriggerEvent;当执行完当前脚本后需要触发某个事件时使用函数PostEvent。但是,当在脚本最后触发其他事件时不论使用哪个函数,效果都相同。例如,上面例子中可以在窗口的Open事件中用下面脚本替换:

TriggerEvent("ue_openpost")

为了进一步提高窗口打开的速度,可以在数据窗口检索数据之前禁止数据窗口刷新。在窗口的Open事件中编写如下脚本:

dw_1.SetRedraw(False)

TriggerEvent("ue_openpost")

Dw_1.SetRedraw(True)

在窗口的自定义事件ue_openpost中,脚本不变。这时,上面的函数就不能用PostEvent来替换了。

四、移动不带标题栏的窗口

在开发应用程序中,可能要用到不带标题栏的窗口,而带有标题栏的窗口可以

通过拖动标题栏来移动窗口,如何移动没有标题栏窗口呢?这需要编写代码来解决。

在要拖动窗口的MouseDown事件中编写脚本,给窗口发送消息WM_SYSCOMMAND,并将Wordparm设置成SC_MOVE+1,这两个常数的取值分别为274和61 457。脚本如下:

Send(handle(this),274,61458,0)

这将通知窗口在鼠标移动时跟随它一起移动。

五、闪烁窗口标题栏

可以使用API函数FlashWindow来实现闪烁窗口标题栏的功能,使用该功能可以在重要窗口或者特殊情况下吸引用户的注意力。首先声明Locat External Function,语句如下:

Function boolean FlashWindow (Uint handle, boolean flash) Library "user.exe"

然后在适当的时候(比如,用户点击了某个按键后)使用下面语句设置Timer事件的间隔:

Timer(1)

然后在窗口的Timer事件中编写如下脚本:

FlashWindow(Handle(This),True)

在适当的时候使用timer(0)语句关闭Timer事件。

六、给窗口添加自动滚动条功能

因为窗口没有自动滚动条功能,如果设置窗口的HScrollBar或者VScrollBar属性,在不需要滚动条时也显示滚动条,很不美观。可以在窗口的 Resize事件中编写脚本,根据当前窗口的大小来设置是否显示滚动条。如果用户调整窗口的宽度,当小于打开时的宽度时显示水平滚动条,当大于打开时的宽度时,如果有水平滚动条,则取消该滚动条;如果用户调整窗口的高度,当小于打开时的高度时显示垂直滚动条,当大于打开时的高度时,如果有垂直滚动条,则取消该滚动条。

脚本主要编写在窗口的Resize事件中,需要两个判断滚动条滚动范围和滚动条当前位置的API函数,声明这两个本地外部函数的语句是:

Subroutine GetScrollRange(Uint hWindow,Int nScrollBarFlag,ref Int nMin,ref Int nMax) &

Library "user.exe"

Function Int GetScrollPos(Uint hWindow,Int nScrollBarFlag) Library "user.exe"

是否需要显示滚动条,可以通过和窗口刚打开时的宽度、高度相比较来判断。所以,定义两个实例变量:

Int ii_width,ii_height

在窗口的Open事件中初始化这两个变量:

ii_width = This.Width

ii_height = This.Height

然后是脚本的主要部分,在窗口的Resize事件中实现。脚本如下:

Uint hwindow

Int nScrollPos,nMinPos,nMaxPos



If This.WindowState = Minimized! Then //如果正在进行最小化,则直接返回

Return

End If



HWindow = Handle(This) //获取当前窗口的句柄

//下面开始处理水平滚动条

If This.Width < i_Width Then //如果小于打开时的宽度

This.HscrollBar = True //则显示水平滚动条

Elseif This.HscrollBar Then //如果大于或等于打开时的宽度,并且已经有滚动条

NScrollPos = GetScrollPos(hwindow,0) //使用API函数获取当前滚

动条位置

GetScrollRange(hwindow,0,nMinPos,nMaxPos) //使用API函数获取滚动范围

If nScrollPos > nMinPos Then //如果用户滚动了滚动条并且此时不需要显示滚动条

Post(hwindow,276,6,0) //则在水平方向调整窗口中的内容到原来的位置

End If

This.HscrollBar = False //取消滚动条特性

End If

//下面开始处理垂直滚动条

If This.Height < i_Height Then //如果小于打开时的高度

This.VscrollBar = True //则显示垂直滚动条

Elseif This.VscrollBar Then //如果大于或等于打开时的高度,并且已经有滚动条

NScrollPos = GetScrollPos(hWindow,1) //使用API函数获取当前滚动条位置

GetScrollRange(hwindow,1,nMinpos,nMaxPos) //使用API函数获取滚动范围

If nScrollPos > nMinPos Then //如果用户滚动了垂直滚动条且不需再显示

Post(hwindow,277,6,0) //则垂直调整窗口中的内容到原来的位置

End If

This.VscrollBar = False //取消滚动条特性

End If


相关文档
最新文档