文档库 最新最全的文档下载
当前位置:文档库 › PB读写TXT文件

PB读写TXT文件

可以用读\写ini文件一样的方式,用profilestring()和fileopen()函数来实现.

PB中有这些函数
FileExists ( filename ) 判断文件是否存在
FileRead ( file#, variable ) 读取文件

int filemum
string filedata
filenum = fileopen( 'c:\pb.txt ',linemode!,write!)//没有文件的话自动创建
fileread(filenum,filedata)
..

fileclose(filenum)




对我有用[0] 丢个板砖[0] 引用 举报 管理 TOP 精华推荐:数据窗口有哪些常见问题?使用技巧?

yangxiaowenbing

(xiaobing)

等 级:

#4楼 得分:0回复于:2004-03-30 13:13:11li_num=fileopen(ls_file,linemode!,write!)
for ll_row=1 to ll_count

filewrite(li_num, "AA ")
next


对我有用[0] 丢个板砖[0] 引用 举报 管理 TOP 精华推荐:回复:死守pb,死路一条 PB将会带来新的Web开发的狂潮,4GL语言的王者风范唯有PB具备!

yangxiaowenbing

(xiaobing)

等 级:

#5楼 得分:5回复于:2004-03-30 13:15:33li_num=fileopen(ls_file,linemode!,write!)
for ll_row=1 to ll_count
ls_ss=dw_1.object.aa[ll_row]
filewrite(li_num,ls_ss)
next
fileclose(li_num)




//读取文件
integer li_FileNum
string ls_Emp_Input
long ll_FLength

li_FileNum = FileOpen("e:\aa.txt", StreamMode!, Read! , LockWrite!, Replace!)
ll_FLength = FileLength("e:\aa.txt")
IF ll_FLength < 32767 THEN
FileRead(li_FileNum, ls_Emp_Input)
END IF
FileClose(li_FileNum)

//保存到数组
ls_Emp_Input=trim(ls_Emp_Input)
ll_FLength=len(ls_Emp_Input)
string aa[10]
long ll_start,ll_pos,i
ll_start=1
ll_pos=1
i=1
do while ll_FLength>0
ll_pos=pos(ls_Emp_Input,' ',ll_start)
if ll_pos>0 then
aa[i]=mid(ls_Emp_Input,ll_start,ll_pos - ll_start)
i++

ls_Emp_Input=trim(mid(ls_Emp_Input,ll_pos +1))
ll_FLength=len(ls_Emp_Input)
else
aa[i]=ls_Emp_Input
exit
end if
loop


pb函数库之文件操作函数
FileClose()
功能关闭先前用FileOpen()函数打开的文件。
语法FileClose ( fileno )
参数fileno:integer,指定要关闭文件的文件句柄,该句柄使用FileOpen()函数打开文件时得到返回值Integer。函数执行成功时返回1,发生错误时返回-1。如果fileno参数的值为NULL,那么FileClose()函数返回NULL。
--------------------------------------------------------------------------------

FileDelete()
功能删除指定的文件。
语法FileDelete ( filename )
参数filename:string类型,指定要删除文件的文件名,其中可以包含路径返回值Boolean。函数执行成功时返回TRUE,发生错误时返回FALSE。如果filename参数的值为NULL,那么FileDelete()函数返回NULL。
--------------------------------------------------------------------------------

FileExists()
功能检查指定的文件是否存在。
语法FileExists ( filename )
参数filename:string

类型,指定要检查存在性的文件的文件名,其中可以包含路径返回值Boolean。如果指定文件存在时返回TRUE,不存在时返回FALSE。如果filename参数的值为NULL,那么FileExists()函数返回NULL。用法如果filename参数指定的文件被另一个应用加锁锁住,那么FileExists()函数也将返回FALSE。
--------------------------------------------------------------------------------

FileLength()
功能得到指定文件的长度(以字节为单位)。
语法FileLength ( filename )
参数filename:string类型,指定要得到其长度的文件的文件名,其中可以包含路径返回值Long。函数执行成功时返回指定文件的长度(以字节为单位)。如果指定的文件不存在,函数返回-1。如果filename参数的值为NULL,那么FileLength()函数返回NULL。
--------------------------------------------------------------------------------

FileOpen()
功能以指定的读写方式打开指定的文件,同时返回该文件的句柄。
语法FileOpen(filename{,filemode{,fileaccess{,filelock{,writemode,{creator,filetype}}}}})
参数filename:string类型,指定要打开文件的名称,其中可以包含路径 filemode:FileMode枚举类型,可选项,指定文件打开方式。有效取值为:?LineMode! - 缺省值,行模式;?StreamMode! - 流模式fileaccess:FileAccess枚举类型,可选项,指定文件访问方式。有效取值为:?Read! - 缺省值,只读方式,这样打开的文件只能进行读操作;?Write! - 只写方式,这样打开的文件只能进行写操作?filelock:FileLock枚举类型,可选项,指定文件加锁方式。有效取值为:n LockReadWrite! - 缺省值,只有打开该文件的用户能够访问该文件,其它用 户对该文件的访问均被拒绝;n LockRead! - 只有打开该文件的用户能够读该文件,但其它任何用户均可写该文件;n LockWrite! - 只有打开该文件的用户能够写该文件,但其它任何用户均可读该文件;n Shared! - 所有用户均可读写该文件writemode:WriteMode枚举类型,可选项,当fileaccess参数指定为Write!时,该参数指定在指定文件已经存在时数据的添加方式。有效取值为:?Append! - 缺省值,将数据添加到原文件尾部;?Replace! - 覆盖原有数据creator:可选项,用于Macintosh机,使用四个字符的字符串指定文件的创建者。指定该参数后,必须同时指定filetype参数filetype:可选项,用于Macintosh机,使用四个字符的字符串指定文件类型返回值Integer。函数执行成功时返回打开文件的句柄,随后的文件操作函数利用该句柄完成对文件的操作。发生错误时函数返回-1。如果任何参数的值为NULL,那么FileOpen()函数返回NULL。用法当文件以行模式打开时,每执行一次FileRead()函数读取一行数据;每执行一次FileWrite()函数,该函

数自动在写出的字符串末尾增加一个回车(CR)换行(LF)符(这是应用程序在Windows 系统中运行时的情况,在UNIX下只加一个换行字符)。当文件以流模式打开时,执行一次FileRead()函数读取32,765个字节的数据,如果余下数据没有这么多,那么FileRead()函数就读取所有余下的数据;执行一次FileWrite()函数时,最多可写入32,765个字节的数据,并且不添加回车换行字符。当文件以写方式使用FileOpen()函数打开时,如果指定的文件不存在,那么FileOpen()函数创建该文件。
--------------------------------------------------------------------------------

FileRead()
功能从指定文件中读取数据。
语法FileRead ( fileno, variable )
参数fileno:integer类型,指定文件句柄(由FileOpen()函数得到)variable:string或blob类型的变量,用于保存读取的数据返回值Integer。函数执行成功时返回读取的字符数或字节数;如果在读取任何字符前读到了文件结束符(EOF),则FileRead()函数返回-100;当指定文件以行模式打开时,如果在读取任何字符之前遇到了回车(CR)或换行(LF)字符,则FileRead()函数返回0。如果发生其它错误,FileRead()函数返回-1。如果任何参数的值为NULL,那么FileRead()函数返回NULL。用法当指定文件以行模式(Line Mode)打开时,FileRead()函数一次读取一行数据,并把它保存到参数variable中,然后跳过行结束符(回车换行符,操作系统不同,使用的字符也不同),把文件指针移动到下一行的起始位置。当文件以流模式(Stream Mode)打开时,FileRead()函数或一直读取到文件结尾,或读取32,765字节的数据,决定于两者哪个数据长度更短些。
--------------------------------------------------------------------------------

FileSeek()
功能将文件指针移动到指定位置。读写文件时相应函数会自动移动文件指针。
语法FileSeek ( fileno, position, origin )
参数fileno:integer类型,指定文件句柄(由FileOpen()函数得到)position:long类型,指定相对于origin参数指定位置的新位置偏移量,以字节为单位origin:SeekType枚举类型,指定从哪里开始移动文件指针,即指针移动的基准。有效取值为:?FromBeginning! - 缺省值,从文件开头移动指针;?FromCurrent! - 从当前位置移动文件指针;?FromEnd! - 从文件结尾处移动文件指针返回值Long。函数执行成功时返回指针移动后的指针位置。如果任何参数的值为NULL,那么FileSeek()函数返回NULL。
--------------------------------------------------------------------------------

FileWrite()
功能向指定文件中写数据。
语法FileWrite (fileno , variable )
参数fileno:integer类型,指定文件句柄(由FileOpen()函数得到)variable:string或blob类型,其值

将写入fileno参数指定的文件返回值Integer。函数执行成功时返回写入文件的字符或字节数,发生错误时返回-1。如果任何参数的值为NULL,那么FileWrite()函数返回NULL。用法FileWrite()函数从当前文件指针开始写入指定数据,写入之后,将文件指针调整到刚刚写入数据的下一个字节位置。当文件以writemode参数设置为Replace!方式打开时,文件指针最初位于文件的开头位置;当文件以writemode参数设置为Append!方式打开时,文件指针最初位于文件的结尾位置。当文件以行模式打开时,执行FileWrite()函数时,该函数自动在每次写入数据的后面加上回车换行符,并把文件指针移动到回车换行符后面。当文件以流模式打开时,FileWrite()函数一次最多写入32,765个字节。如果variable参数中数据的长度超过了32,765个字节,那么FileWrite()函数只向文件中写入前32,765个字符并返回32,765。
--------------------------------------------------------------------------------

GetFileOpenName()
功能显示打开文件对话框,让用户选择要打开的文件。
语法GetFileOpenName(title,pathname,filename{,extension{,filter}})
参数title:string类型,指定对话框的标题pathname:string类型变量,用于保存该对话框返回的文件路径及文件名filename:string类型变量,用于保存该对话框返回的文件名extension:string类型,可选项,使用1到3个字符指定缺省的扩展文件名 filter:string类型,可选项,其值为文件名掩码,指定显示在该对话框的列表框中供用户选择的文件名满足的条件(比如*.*,*.TXT,*.EXE等)返回值Integer。函数执行成功时返回1;当用户单击了对话框上的“Cancel”按钮时函数返回0;发生错误时返回-1。如果任何参数的值为NULL,那么GetFileOpenName()函数返回NULL。
用法filter参数的格式为:description,*. ext缺省值为:"All Files (*.*),*.*"其中,description说明扩展名的意义,比如“所有文件”、“文本文件”等。你可以根据需要指定在打开文件对话框中显示的文件名类型。当需要指定多种文件类型时,各类型之间使用逗号分隔,例如:"PIF 文件, *.PIF, 批处理文件, *.BAT"需要注意的是,该函数只是得到一个文件名,而并没有打开文件,需要打开文件时,依然需要使用FileOpen()函数。
--------------------------------------------------------------------------------

GetFileSaveName()
功能显示保存文件对话框,让用户选择要保存到的文件。
语法GetFileSaveName(title,pathname,filename{,extension{,filter}})
参数title:string类型,指定对话框的标题pathname:string类型变量,用于保存该对话框返回的文件路径及文件名filename:string类型变量,用于保存该对话框返回的文件名extension:string类型,可

选项,使用1到3个字符指定缺省的扩展文件名filter:string类型,可选项,其值为文件名掩码,指定显示在该对话框的列表框中供用户选择的文件名满足的条件(比如*.*,*.TXT,*.EXE等)返回值Integer。函数执行成功时返回1;当用户单击了对话框上的“Cancel”按钮时函数返回0;发生错误时返回-1。如果任何参数的值为NULL,那么GetFileSaveName()函数返回NULL。
用法filter参数的格式为:description,*. ext缺省值为:"All Files (*.*),*.*"其中,description说明扩展名的意义,比如“所有文件”、“文本文件”等。你可以根据需要指定在打开文件对话框中显示的文件名类型。当需要指定多种文件类型时,各类型之间使用逗号分隔,例如:"PIF 文件, *.PIF, 批处理文件, *.BAT"需要注意的是,该函数只是得到一个文件名,而并没有打开文件,需要打开文件时,依然需要使用FileOpen()函数。


pb函数库之字符串操作函数
Fill()
功能建立一个由指定字符串填充的指定长度的字符串。
语法Fill ( chars, n )
参数chars:string类型,指定用于重复填充的字符串n:long类型,指定由该函数返回的字符串的长度返回值String。函数执行成功时返回n个字符的字符串,该字符串以参数chars中的字符串重复填充而成。如果参数chars中的字符个数多于n个,那么使用chars字符串的前n个字符填充函数返回的字符串;如果参数chars中的字符个数少于n个,那么使用chars字符串反复填充,直到返回的字符串长度达到n为止。如果任何参数的值为NULL,Fill()函数返回NULL。
--------------------------------------------------------------------------------

Left()
功能得到字符串左部指定个数的字符。
语法Left ( string, n )
参数string:string类型,指定要提取子串的字符串n:long类型,指定子串长度返回值String。函数执行成功时返回string字符串左边n个字符,发生错误时返回空字符串("")。如果任何参数的值为NULL,Left()函数返回NULL。如果n的值大于string字符串的长度,那么Left()函数返回整个string字符串,但并不增加其它字符。
--------------------------------------------------------------------------------

LeftTrim()
功能返回指定字符串删除了左部空格后的字符串。
语法LeftTrim ( string )
参数string:string类型,指定要删除左部空格的字符串返回值String。函数执行成功时返回删除了string字符串左部空格的字符串,发生错误时返回空字符串("")。如果任何参数的值为NULL,LeftTrim()函数返回NULL。
--------------------------------------------------------------------------------

Len()
功能得到字符串的长度。
语法Len (string)
参数string:string类型变量返回值Long。函数执行成功时返回

字符串的长度,发生错误时返回-1。如果任何参数的值为NULL,则Len()函数返回NULL。
--------------------------------------------------------------------------------

Lower()
功能将字符串中的大写字母转换为小写字母。
语法Lower ( string )
参数string:要将其中的大写字母转换为小写字母的字符串返回值String。函数执行成功时返回将大写字母转换为小写字母后的字符串,发生错误时返回空字符串("")。如果string参数的值为NULL,Lower()函数返回NULL。
--------------------------------------------------------------------------------

Match()
功能确定字符串中是否包含指定模式的字符。
语法Match ( string, textpattern )
参数string:string类型,指定要检查是否匹配指定模式的字符串textpattern:string类型,指定文本匹配模式返回值Boolean:如果字符串string与模式textpattern相匹配,则函数返回TRUE,否则返回FALSE。如果指定的匹配模式无效或上述两个参数中的任何一个未曾赋值,那么Match()函数返回FALSE。如果任何参数的值为NULL,Match()函数返回NULL。
用法textpattern参数的写法与正则表达式十分相似,它由元字符和普通字符组成。每个元字符都有不同的匹配含义,普通字符则与其自身相匹配。下面是匹配模式中使用的元字符及其意义:
^指示字符串的开始,例如,^asd表示以asd开头的字符串,字符串asdfgh与模式^asd匹配,而字符串basdfg与模式^asd不匹配。
$指示字符串的结束,例如,red$表示所有以red结束的字符串均与该模式匹配,而redo与模式red$不匹配。
.匹配任意单个字符,例如,^&&$匹配任何六个字符组成的字符串。
[]匹配括号中列出的字符,例如,^[ABC]$匹配由一个字符组成的字符串,其值只能是A或B或C。
-与方括号一起,指定匹配字符的范围,例如,^[A-Z]$只匹配那些由一个大写字母组成的字符串。方括号里还可以使用^字符,表示匹配不在指定范围内的任何字符,例如,[^0-9]匹配除数字外的任何字符。
*,+,?这些符号跟在一个字符后面表示该字符可以出现的次数。星号(*)表示可以出现0次或任意次;加号(+)表示可以出现多次,但至少出现一次;问号(?)表示出现0次或一次。例如,A*匹配0个或多个A(没有A、A、AA、AAA、AAAA、**);A+匹配1个或多个A(A、AA、AAA、AAAA、**);A?匹配空串或1个A。
\斜杠(\)是转义字符,它去掉特殊字符的特殊含义,比如,模式\$匹配字符$,模式\\匹配字符\。
--------------------------------------------------------------------------------

Mid()
功能取字符串的子串。
语法Mid ( string, start {, length } )
参数string:string类型,指定要从中提取子串的字符串start:long类型,指定子串

第一个字符在string字符串中的位置,第一个位置为1length:long类型,可选项,指定子串的长度返回值String。函数执行成功时返回string字符串中从start位置开始、长度为length的子串。如果start参数的值大于string中字符个数,那么Mid()函数返回空字符串。如果省略了length参数或length参数的值大于从start开始、string字符串中余下字符的长度,那么Mid()函数返回所有余下的字符。如果任何参数的值为NULL,Mid()函数返回NULL。
--------------------------------------------------------------------------------

Pos()
功能在一个字符串中查找所包含的另一个字符串的起始位置。
语法Pos ( string1, string2 {, start } )
参数string1:string类型,指定要从中查找子串string2的字符串string2:string类型,指定要在string1中查找的字符串start:long类型,可选项,指定从string1的第几个字符开始查找。缺省值为1返回值Long。函数执行成功时返回在start位置后string2在string1中第一次出现的起始位置。如果在string1中按指定要求未找到string2、或start的值超过了string1的长度,那么Pos()函数返回0。如果任何参数的值为NULL,Pos()函数返回NULL。
用法Pos()函数在字符串查找时区分大小写,因此,"aa"不匹配"AA"。
--------------------------------------------------------------------------------

Replace()
功能将一个字符串中指定个数的字符串替换为另一个字符串。
语法Replace ( string1, start, n, string2 )
参数string1:string类型,指定要使用string2替换其中一部分内容的字符串start:long类型,指定要从哪个字符位置开始替换字符串,字符串中第一个字符的位置为1n:long类型,指定要替换多少个字符string2:string类型,指定用哪个字符串替换string1的部分字符返回值String。函数执行成功时返回替换后的字符串,发生错误时返回空字符串("")。如果任何参数的值为NULL,Replace()函数返回NULL。用法如果start参数指定的位置超过了string1的长度,那么Replace()函数把将string2拼接到string1的后面形成的字符串返回。如果n的值为0,那么Replace()函数把string2插入到string1指定位置后形成的字符串返回。
--------------------------------------------------------------------------------

Right()
功能从字符串右端取指定个数字符。
语法Right ( string, n )
参数string:string类型,指定要提取子串的字符串n:long类型,指定子串长度返回值String。函数执行成功时返回string字符串右边n个字符,发生错误时返回空字符串("")。如果任何参数的值为NULL,Right()函数返回NULL。如果n的值大于string字符串的长度,那么Right()函数返回整个string字符串,但并不增加其它字符。
--------------------------------------------

------------------------------------

RightTrim()
功能删除字符串尾部空格。
语法RightTrim ( string )
参数string:string类型,指定要删除右部空格的字符串返回值String。函数执行成功时返回删除了string字符串右部空格的字符串,发生错误时返回空字符串("")。如果任何参数的值为NULL,RightTrim()函数返回NULL。
--------------------------------------------------------------------------------

Space()
功能生成一个由空格组成的指定字符个数的字符串。
语法Space ( n )
参数n:long类型,指定要填充的空格个数,也就是填充后返回的字符串的长度返回值String。函数执行成功时返回由n个空格组成的字符串,发生错误时返回空字符串。如果参数n的值为NULL,Space()函数返回NULL。
--------------------------------------------------------------------------------

Trim()
功能删除字符串首部和尾部的空格。
语法Trim ( string )
参数string:string类型,指定要删除首部和尾部空格的字符串返回值String。函数执行成功时返回删除了string字符串首部和尾部空格的字符串,发生错误时返回空字符串("")。如果任何参数的值为NULL,Trim()函数返回NULL。
--------------------------------------------------------------------------------

Upper()
功能将字符串中的小写字母转换为大写字母。
语法Upper( string )
参数string:要将其中的小写字母转换为大写字母的字符串返回值String。函数执行成功时返回将小写字母转换为大写字母后的字符串,发生错误时返回空字符串("")。如果string参数的值为NULL,Upper()函数返回NULL。


PB编程技巧实例
PB编程技巧实例

随着数据库技术在各行各业的广泛应用,作为企业级数据库前端开发工具的Power Builder日益成为开发人员的得力助手。PowerBuilder以其开放的体系结构,友好的用户界面和简洁高效的开发环境赢得了众多程序员的喜爱,连续多年被评为美国计算机界的年度风云产品,在数据库开发工具领域占据了高达44%的市场份额。PowerBuilder进入我国的时间不长,许多编程人员希望了解并掌握这一先进工具。在这里,笔者将自己平日用PowerBuilder作开发的一些体会整理出来,奉献给大家。
PowerBuilder是由多个功能模块组成的可视化集成开发环境,是面向对象的开发工具,用它可以方便地建立起基于Windows的分布式数据库应用。其功能模块分别完成应用管理、窗口对象设计、菜单对象设计、数据窗对象设计和数据库查询等工作,这些功能模块由于PowerBuilder提供的色彩丰富的工具条而被称作"Painter"(画板)。下文便依据各模块作大的分类介绍相应的编程技巧。

一、有关应用的编程技巧仅让应用程序运行一次

的技巧:

有时需要限制一个PowerBuilder应用同时运行的实例(Instance)个数或仅让应用运行一次,我们可以通过调用WindowsSDK函数或使用PowerBuilder的Handle()函数来实现。
先谈调用SDK函数的方法。为了调用SDK函数,需要在ApplicationPainter的菜单项Declare\GlobalExternalFunctions中定义:
FunctionuintGetModuleHandle(stringModuleName)Library"Kernel.exe" FunctionuintGetModuleUsage(uintModuleHandle)Library"Kernel.exe"

下面这段程序写在Application的Open事件中。它先通过调用SDK函数GetModuleHandle()获得指定应用程序的句柄,然后调用GetModuleUsage()函数确定应用程序同时运行的实例个数。
uint IApplHandle
int App_num
IApplHandle=GetModuleHandle("ocmis.exe")
if IApplHandle>0 then
App_num=GetModuleUsage(IApplHandle)
if App_num>1 then
Messagebox("注意","本程序已经运行!",Stopsign!)
return
endif
endif
Open(w_main)
若需要限制应用同时运行的实例个数,比如仅允许同时运行N个实例,那么将上述程序中的语句 “if App_num>1 then”改为“if App_num>N then”即可。
采用Handle()函数的方法更简洁一些,代码如下:
int hand
hand=Handle(this,TRUE)
If hand>0 then
Messagebox("注意","本程序已经运行!",Stopsign!)
Halt
else
Open(w_main)
endif

二、有关窗口的编程技巧

1、提供实时帮助条

中文之星2.0版的链形菜单管理器提供了实时帮助条,增强了系统的易用性,在PowerBuilder中也可以实现类似的功能。当鼠标移动到窗口中的某些控制(Control),如编辑器、图片等时,会在鼠标附近自动产生帮助条,实时地提示操作要领。

首先在窗口w_main中任意位置定义一个黄底黑字的静态文本st_help,设定st_help.visible=false,st_help.text=&Help;然后在该窗口模块的Declare\WindowFunctions...下定义函数show_help(),其参数只有一个,参数名为text,类型为string,通过传值方式接收参数;无返值。show_help()代码如下:
if st_help.visible then
return
endif
st_help.text=text
st_help.width=Len(st_help.text)*38
st_help.x=w_main.PointerX()
st_help.y=w_main.PointerY()+50
if st_help.x+st_help.width>w_main.Workspacewidth() then
st_help.x=w_main.Workspacewidth()-st_help.width
endif
if st_help.y+st_help.height>w_main.Workspaceheight()
then st_help.y=w_main.Workspaceheight()-st_help.height
endif
st_help.visible=true
接下来,我们就可以调用show_help()函数了。但PowerBuilder提供的所有控制均缺乏当鼠标移至其上就触发的事件,显然,需要定义相应的用户事件。先选中准备定义用户事件的控制,如某个单行编辑器,然后在窗口模块的菜单Declare\UserEvents...下,双击PasteEventID:中的pbm_mousemove条目,将其拷贝至EventID下,取EventName为Mouseon,这样,我们就定

义好了相应控制的用户事件Mouseon。我们可以在该控制的用户事件Mouseon下,写下调用函数show_help()的语句:
if st_help.visible then
Hide(st_help)
show_help("瞧!这便是实时帮助条!")
endif

2、“跑马灯”的实现技巧

有时需要用一矩形条显示少量用户特别关心的信息,这条信息串首尾相连,向一个方向循环滚动,我们通常将其称作“跑马灯”。证券业中常用“跑马灯”来显示不断变化的股票行情;实际应用中也常通过“跑马灯”来监视是否死机。我们可以写一个简单的函数running_horse()来实现“跑马灯”的显示。
running_horse有两个参数,
第一个参数的参数名为textline,类型为string,传值;
第二个参数的参数名为num,类型为int,传值;函数返值类型为string。
该函数的代码仅一句:
returnMid(textline,(num+1))+Left(textline,num)
下面就可以调用running_horse()函数了。先在一个窗口里定义好单行编辑器sle_running_horse,在该窗口的Open事件下写上: sle_running_horse.text="Iamtestingrunning_horse!"
Timer(0.2)
然后在该窗口的Timer事件下调running_horse(),代码如下: sle_running_horse.text=running_horse(sle_running_horse.text,1) 这样,当你打开这个窗口时,“跑马灯”便会运转起来。可以在程序中加些语句,适时地增减sle_running_horse.text中的内容,你便会在“跑马灯”中看到相应变化的信息。

三、有关菜单的编程技巧右键菜单的实现技巧:


当你在相应的窗口或控制上按鼠标右键时,就会在鼠标所指位置弹出菜单,这就是右键菜单。程序中支持右键菜单会为用户的操作带来许多方便,同时鼠标右键可以分担部分左键的功能。右键菜单在证券期货业中的许多大型行情分析软件中得到了广泛的应用。在PowerBuilder中实现右键菜单非常简单,仅两个步骤:1.设计相应菜单;2.在窗口或控制的Rbuttondown事件下写上调用语句。

先在MenuPainter中创建菜单rbuttonpop,rbuttonpop有一个菜单条目(Menuitem)m_choice。然后在需要调用该菜单的窗口或控制的Rbuttondown事件下写上:
m_rbutton popNewMenu
NewMenu=Createm_rbuttonpop
NewMenu.m_choice.PopMenu(PointerX(),PointerY())
至此,右键菜单制作完毕。上述语句中的NewMenu的数据类型为m_rbuttonpop,当你在相应位置按鼠标右键时,弹出的菜单NewMenu是菜单m_rbuttonpop的一个实例(Instance)。

四、有关数据窗口的编程技巧

数据窗对象是PowerBuilder中最重要的概念之一,它是PowerBuilder应用区别于其它Windows应用的重要特征,同时也是PowerBuilder的价值所在。PowerBuilder应用通常通过数据窗对象从数据库或其它数据源取得数据并加以显示,其数据的输入、添加、修改和删除也

大都通过数据窗对象来实现。故理解并掌握数据窗概念对于用好PowerBuilder具有重要意义。下面给出了有关数据窗的几个编程技巧。

1、自动调整大小的数据窗

在PowerBuilder应用运行过程中,常常会用鼠标拖动窗口角以改变窗口大小,尤其是在多文档窗口(MDI)中,通常有多个sheet存在的情况下,有时为了察看后面窗口中的数据而将前面窗口缩小,但窗口缩小了,其中的数据窗并没有缩小,由此而不能方便地使用数据窗的卷滚条,那么怎样使前面窗口中的数据窗大小随窗口的大小自动调整呢?

很简单,我们只需要在数据窗所在窗口的Resize事件下写上一句话:
Resize(dw_datamon,this.Workspacewidth()-50,this.Workspaceheight()-50)
其中dw_datamon是数据窗的名字,数字50可以调整。这样,你就拥有了一个会随窗口大小变化而自动调整大小的数据窗了。卷滚条用起来很方便,不信试试。

2、Retrieve后不回卷的数据窗

我们经常面对一大堆数据,其具体体现就是数据窗很长,需要拉动垂直卷滚条才能看到后面的数据,当你在包含长数据窗的窗口的Timer事件中写下Retrieve()语句后,令人气恼的事情就会发生:Timer事件一执行,数据窗就翻回第一页;如果Timer事件执行的时间间歇很短,那我们就永远没有足够的时间来察看后面的数据了。下面我们着手解决这个问题。可能你已经注意到了,每个数据窗都拥有两个与Retrieve有关的事件:Retrievestart和Retrieveend,它们分别允许我们在Retrieve的前后干一些事,这正是我们所需要的。实际上,就这两个事件,我们已经能够提出两个解决方案了。
其一,在Retrievestart事件中,保存当前数据窗中可见的数据行;然后Retrieve;接着在Retrieveend事件中,恢复先前保存的数据行。
其二,在Retrievestart事件中,保存当前垂直卷滚块的位置;Retrieve后再恢复其位置。后者使用了动态数据窗函数,实现起来更简洁一些,下面详细探讨。假设你已设计好了一个在窗口w_datamon中的数据窗dw_datamon,现在可以先定义一个保存垂直卷滚块位置的类型为string的Globle变量old_vspos,然后在该数据窗的Retrievestart事件下输入以下语句以保存其位置: old_vspos=this.dwDescribe("DataWindow.VerticalScrollPosition")
dw_datamon.SetRedraw(false)
在相应的Retrieveend事件下输入恢复垂直卷滚块位置的语句:
this.dwModify("DataWindow.VerticalScrollPosition="+old_vspos)
dw_datamon.SetRedraw(true)
这样,数据窗上的工作已做完。下面是相应窗口上的工作。该窗口的Open事件下:
dw_datamon.Settrans(sqlca)
dw_datamon.Retrieve()
timer(6)
该窗口的Timer事件下:
Setfocus(w_datamon)
Retrieve(dw_datamon)
至此,Retrieve后不会回卷的

数据窗dw_datamon已经可以工作了。值得注意的是,数据窗的排序分类等操作应在Retrieve前就在数据库表中完成,否则Retrievestart事件保存的卷滚块位置很可能并不是你所期待的,换句话说,Retrievestart事件应发生在所有数据窗操作之后;另外,在每次Retrieve后,应将处于该数据窗上的Focus移开,以免具有焦点的数据窗的第一行第一列总要显示,故在窗口w_datamon的Timer事件中设置了Setfocus(w_datamon)这条语句。

3、依据条件改变数据颜色

依据条件改变数据颜色是许多场合都要用到的重要功能,数据颜色的改变不仅引人注目,而且能起到暗示作用,清楚地告诉用户价位的涨跌或状态的改变等。大多数证券期货实时行情显示软件都提供了这种功能。在当前价位比其前一价位高时,当前价位数据颜色变红,表示价位上涨;反之,颜色变绿,表示价位下跌;若当前价位与其前一价位相等,则数据颜色不变。PowerBuilder没有提供解决这一问题的捷径,但我们仍可利用动态数据窗来实现。先考虑一下实现的步骤,在Retrieve前需要把有关列的数据先保存起来;Retrieve后我们获得了相应列的新数据;我们需要将上述二者作一比较,以确定颜色的变化。值得指出的是,由于动态数据窗函数dwModify()只能用描述数据窗的模式串作参数,不能接收变量作参数,故我们得想法把比较的结果传递给数据窗。为解决这个问题,可以在定义数据窗时多定义几个空列,这几列不与数据库表中的列相对应,它们作为存放比较结果的缓冲区。原则上若需要N列实时地变色,则需要N列缓冲区,就应该多定义N个空列。下面给出了一个例子具体说明。 这段程序写在某窗口的Timer事件中,该窗口内有数据窗dw_infor,其"buy"、"sell"列分别表示买价和卖价,需要实时地变颜色。为此,我们在数据窗dw_infor中多定义了"buybuf"和"sellbuf"两列,分别存放"buy"列和"sell"列Retrieve前后数据比较的结果。
//Red=255;Green=65280
int i,infor_rownum decimalbuy_old[],sell_old[],buy_new[],sell_new[]
dw_infor.SetRedraw(false)
infor_rownum=dw_infor.RowCount()
FOR i=1 To infor_rownum
buy_old[i]=dw_infor.GetitemNumber(i,"buy")
sell_old[i]=dw_infor.GetitemNumber(i,"sell")
NEXT
dw_infor.retrieve()
FOR i=1 TO infor_rownum
buy_new[i]=dw_infor.GetitemNumber(i,"buy")
sell_new[i]=dw_infor.GetitemNumber(i,"sell")
NEXT
FOR i=1 TO infor_rownum
dw_infor.Setitem(i,"buybuf",buy_new[i]-buy_old[i])
dw_infor.Setitem(i,"sellbuf",sell_new[i]-sell_old[i])
NEXT
dw_infor.dwModify("buy.color='0~tif(buybuf>0,255,if(buybuf<0,65280,0))'")
dw_infor.dwmodify("sell.color="0~tif(sellbuf>0,255,if(sellbuf<0,65280,0))'")
dw_infor.setredraw(true)
我们看到,程序在Retrieve前后分别将"buy"和"sell"

;列的数据写进与其类型匹配的数组中,然后将比较的结果分别写入"buybuf"和"sellbuf"列,最后用函数dwModify()改变有关列的颜色。记住在该窗口的Open事件中设置事务对象并激活Timer事件。此外,还有一些方法可以改变颜色,比如先在某些需要变颜色的行或列设置带颜色的长方形,同时将其上面的数据窗中的数据设置成透明的,当条件改变时,可以通过改变数据窗后的长方形的颜色来实现。

4、用Enter键替代Tab键切换栏目的数据窗

许多情况下,PowerBuilder应用的数据是通过数据窗输入的,而且输入的数据是单纯的数字数据,也就是说,输入内容完全可以通过敲击键盘右面的数字小键盘来完成。但在实际使用中,数据窗栏目间的切换却要通过按键盘最左边的Tab键来实现,既不方便又影响录入速度。如果能用Enter键替代Tab键切换栏目就好了。由于按Enter键是Windows直接支持的消息,故我们可以使用用户事件来解决问题。在用户事件中,PowerBuilder提供的一条pbm_事件对应Windows的一条或几条消息。我们在数据窗dw_datamon的用户事件中选择pbm_dwnProcessEnter并命名为Enterkeydown。在该事件下写代码:
Send(Handle(this),256,9,Long(0,0))
This.SetActionCode(1)
这将把消息传递给Tab键,同时忽略Enter键的处理。下面是一段用数据窗接收数据的完整的程序段,其中采用了用Enter键替代Tab键的代码。当光标在每行最后一列时按Enter键,光标会移至下一行第一列;当光标在最后一行的最后一列时按Enter键,会自动产生新行并将光标置于该行的第一列;在其它情况下按Enter键,光标会移至当前行的下一列。这段程序仍然写在与pbm_dwn ProcessEnter相对应的用户事件Enterkeydown下:
IF This.AcceptText()<0 then
this.setactioncode(1) return
endif
if this.getcolumn()=Long(This.DwDescribe("datawindow.column.count")) then
if this.getrow()=This.RowCount() then
this.insertrow(0)
this.scrolltorow(this.getrow()+1)
this.setcolumn(1)
this.setactioncode(1)
return
endif
endif
send(handle(this),256,9,long(0,0))
this.setactioncode(1)

5、数据从文本文件写入数据库表的捷径

许多情况下,文本文件中的数据排列顺序与数据库表中列的顺序一致,并且其数据类型与数据库表中对应列的一致,要做的就是将该文件中的内容存入对应数据库表中。例如在点对点通讯的情况下,一方把数据库表中的数据以文本文件格式存储并传送给另一方,另一方要做的工作就是将收到的数据存入相同的数据库表中。PowerBuilder有多种方式与文本文件打交道,比如使用ODBC的文本文件驱动器、采用DDE(动态数据交换)方式、采用OLE方式或使用Cursor将文本文件逐行逐列读取并写入数据库表等。

但在这种情况下,还有一种更快捷的方法:使用ImportFile()函数将文本文件内容直接倒入数据库表中。该函数用法为: datawindowname.ImportFile(filename{,startrow{,endrow& {,startcolumn{,endcolumn{,dwstartcolumn}}}}}) ImportFile()函数要求数据窗列的数据类型和列的排列顺序必须与文本文件中的数据相匹配。在存储文本文件时要注意接收数据库对表的格式要求,比如在SYBASE中,表格的列与列间是采用Tab键区分的,所以如果要用ImportFile()函数将文件内容写入SYBASE表中,就要将相应文本文件的列与列间加入Tab键——这在文件形成时即可加入。下面的代码将文件infor.txt写入数据窗dw_infor,并将与dw_infor对应的数据库表更新:
int impt
if (FileLength("c:\data\infor.txt")>0) then
impt=dw_infor.ImportFile("c:\data\infor.txt")
if impt>0 then
dw_infor.settrans(sqlca)
update(dw_infor)
commit;
If sqlca.sqlcode=-1 then
messagebox("SQLERROR",sqlca.sqlerrtext)
endif
else
messagebox("注意","文件infor.txt写入失败!")
endif
endif
此外,ImportFile()函数还支持从文本文件的指定开始行列到结束行列读取并写入数据;并且支持.dbf(dBase)文件的读写,这给原有台式数据库数据文件向新的分布式数据库表中转换带来了极大的方便。

五、有关文件输出的编程技巧

1、打印前的模拟显示的编程技巧
在制作完一段文档或表格后,我们在正式打印输出前总希望看一下模拟显示的效果,看看是否需要调整打印参数等。笔者在调试一个标签打印程序时就遇到了这个问题,标签文档的输出格式正确与否、标签间的横竖间距恰当与否等均可通过模拟显示直观地看到。总之,我们需要打印前的模拟显示。单纯写一段模拟显示程序并不难,但多思考一下往往能找到好方法。在文件读写时需要有文件号、在用Socket编程时涉及到Socket号,同样,多任务的操作系统管理进程时也采用了进程号——显然,整个软件系统都是采用一些数据类型为整型的变量来管理它要处理的逻辑对象的。一台打印机有它的逻辑文件名,在操作系统看来,它和磁盘上的一个文本文件没有两样。这样,向打印机输出与向磁盘文件输出就统一起来了,我们就依据这个想法来写模拟显示程序。大家知道,打印机的逻辑名是"PRN",我们可以对此作与磁盘文件相同的处理。下面的程序可写于按钮cb_print的Click事件下:
int retn,fileno
string filename,write_string
retn=Messagebox("提示","输出至打印机选,~r~n模拟显示(c:\simulate.txt)选,~r~n取消选! " ,Information!,YesNoCancel!,1) Choose Case retn
Case 1
sle_help.text="请准备好打印机!" filename="PRN"
Case 2
filename="c:\simulate.txt"
Case else
Return
End Choose
fileno=FileOpen(filename,line

mode!,write!,lockwrite!,replace!)
if fileno=-1 then
Messagebox("警告","设备文件<打印机>打开失败!",information!,ok!)
Return
endif
write_string="打印前的模拟显示!"
FileWrite(fileno,write_string)
FileClose(fileno)
if Upper(filename)="PRN" then
sle_help.text="文件打印完毕!"
else
Run("Notepad.exec:\simulate.txt",maximized!)
sle_help.text="模拟显示文件输出完毕!"
endif
这样,当需要模拟显示时,write_string被送往磁盘文件c:\simulate.txt,并调用Notepad将其显示出来;当需要打印时,write_string被送往打印机。 六、结语写作本文不仅想与读者交流编程技巧,还希望向读者提供一些有用的思路。PowerBuilder不仅支持ODBC,而且支持MAPI,是企业级信息管理系统和Intranet应用开发的强大工具。笔者深信,PowerBuilder的应用范围将更加广泛,随着应用的深化,必定会涌现出更多优秀的PowerBuilder应用,并将在各行各业充分发挥作用。

PB中如何控制判断大写以及小键盘指示灯是否开启并与按键协调工作
近日看到很多网友都在询问是否有办法在PB 中控制判断Caps Lock键和Num Lock键的按下状态,以及按键大写和小键盘是否开启。网上有VB实现的相关的说明,感觉很容易。
那在PB中怎么实现呢?因为PB中有判断按键功能的事件以及相关函数。但是自身没有办法捕捉键盘已有的状态,如小键盘的指示灯是否开启,大写指示灯是否已经开启,很容易让我们想到Windows API,老实说PB调用Windows API还是很方便的。通过网络上的信息我找到了如下API函数:GetKeyState,关于其具体说明在此不做冗叙述,感兴趣的朋友上网上Search一下很多,我们看一下它的PB声明:

Function int GetKeyState(integer VirtualKeycode) Library "User32.dll"

该API函数只有一个参数 integer VirtualKeycode ,如果返回值为0的时候表示没有按下,返回值为1的时候表示已经按下。VirtualKeycode表示的是键盘上的按键所对应的虚拟按键码,我们都知道A=65,几经周折我发现了Caps Lock对应的虚拟按键码是 20 ,Num Lock的虚拟按键码是 144,知道这个我们就可以Go on了。做个实验我们在一个窗口上方式两个st控件 st_1,st_2,在窗口打开的时候分别存放显示判断大写键盘指示灯 和 数字键盘指示灯开启状况。在窗体的Open事件中写下:

int rtn
rtn = GetKeyState(20)
if rtn = 0 then
st_1.text="没有开启大写指示灯"
else
st_1.text="已经开启大写指示灯"
end if

int rtn1
rtn1 = GetKeyState(144)
if rtn1 = 0 then
st_2.text="没有开启小键盘"
else
st_2.text="已经开启小键盘"
end if
到此OK,判断指示灯开启状态已经完成。

还有一个问题就是我们如何在按键切换 Caps Lock 或Num Lock的同时刷新st_1,st

_2 的显示内容让其谁着指示灯的状态而改变呢?
实现方法就容易了许多,我们知道PB中有Key事件是在键盘按下时触发,所以只需要在按键的时候判断出按键判断出指示灯的状态就可以了。代码如下:
int rtn
rtn = GetKeyState(20)
if rtn=0 or rtn = -128 then //按键的时候如果为-128则为没有开启 -127表示开启
st_1.text="没有开启大写指示灯"
else
st_1.text="已经开启大写指示灯"
end if

int rtn1
rtn1 = GetKeyState(144)
if rtn1=0 or rtn1 = -128 then
st_2.text="没有开启小键盘"
else
st_2.text="已经开启小键盘"
end if

pb函数库之日期、时间函数
Day()
功能得到日期型数据中的号数(1到31之间的整数值)。
语法Day ( date )
参数date:要得到号数的日期值返回值 Integer。函数执行成功时返回号数(1到31之间的整数值)。如果date参数的值为NULL,则Day()函数返回NULL。
--------------------------------------------------------------------------------

DayName()
功能得到指定日期是一周中的星期几(例如,Sunday, Monday...)。
语法DayName ( date )
参数date:date类型值或变量返回值String。函数执行成功时返回指定日期的星期表示(例如,Sunday, Monday...)。如果date参数的值为NULL,则DayName()函数返回NULL。
--------------------------------------------------------------------------------

DayNumber()
功能得到日期型数据是一星期中的第几天(用1到7之间的整数表示,星期天为1,星期一为2,...)。
语法DayNumber ( date )
参数date:date类型值或变量返回值Integer。函数执行成功时返回指定日期是一星期中的第几天(用1~7表示,星期天为1,星期一为2,...)。如果date参数的值为NULL,则DayNumber()函数返回NULL。
--------------------------------------------------------------------------------

DaysAfter()
功能得到两个日期间的天数。
语法DaysAfter ( date1, date2 )
参数date1:date类型,指定起始日期date2:date类型,指定终止日期返回值Long。函数执行成功时得到两个日期之间的天数。如果date2的日期在date1的前面,那么DaysAfter()函数返回负值。如果任何参数的值为NULL,则DaysAfter()函数返回NULL。
--------------------------------------------------------------------------------

Hour()
功能得到时间值中的小时,采用24小时制。
语法Hour ( time )
参数time:time类型的值返回值Integer。函数执行成功时得到time参数中的小时(00到23之间)。如果time参数的值为NULL,则Hour()函数返回NULL。
--------------------------------------------------------------------------------

Minute()
功能得到时间值中的分钟,有效值在00~59之间。
语法Minute ( time )
参数time:time类型的值返回值Integer。函数执行成功时得到time参数中的分钟(00到59之间

)。如果time参数的值为NULL,则Minute()函数返回NULL。
--------------------------------------------------------------------------------

Month()
功能得到日期值中的月份,有效值在1~12之间。
语法Month ( date )
参数date:date类型的值返回值Integer。函数执行成功时得到date参数中的月份(1到12之间)。如果date参数的值为NULL,则Month()函数返回NULL。
--------------------------------------------------------------------------------

Now()
功能得到客户机的当前系统时间,返回值为Time类型。
语法Now()返回值Time。该函数返回客户机的当前系统时间。
--------------------------------------------------------------------------------

RelativeDate()
功能得到指定日期前多少天或后多少天的日期。
语法RelativeDate(date,n)
参数date:Date类型,指定基准日期n:integer类型,指定天数返回值Date。当n的值大于0时返回参数date指定日期后第n天的日期;当n的值小于0时返回参数date指定日期前第n天的日期。如果任何参数的值为NULL,则RelativeDate()函数返回NULL。
--------------------------------------------------------------------------------

RelativeTime()
功能得到指定时间前多少秒或后多少秒的时间,采用24小时制。
语法RelativeTime ( time, n )参数time:time类型,指定基准时间n:long类型,指定秒数返回值Time。当n的值大于0时返回参数time指定时间后第n秒的时间;当n的值小于0时返回参数time指定时间前第n秒的时间。如果任何参数的值为NULL,则RelativeTime()函数返回NULL。
--------------------------------------------------------------------------------

Second()
功能得到时间值中的秒,有效值在00~59之间。
语法Second ( time )
参数time:time类型的值返回值Integer。函数执行成功时得到time参数中的秒(00到59之间)。如果time参数的值为NULL,则Second()函数返回NULL。
--------------------------------------------------------------------------------

Today()
功能得到当前系统日期,在某些情况下,同时得到当前系统时间。
语法Today()返回值Date。该函数返回当前系统日期。用法单独调用Today()函数时,该函数总是返回当前系统日期,但是,虽然Today()函数的返回值类型为Date,在该函数用做某些函数的参数、而该参数要求DateTime类型的值时,Today()函数也能够在返回当前系统日期的同时返回当前系统时间。再如,Today()函数作为数据窗口控件SetItem()函数的参数,该函数参数中指定的数据窗口列的数据类型为DateTime,那么当前系统日期和时间将同时设置到数据窗口指定项中。
--------------------------------------------------------------------------------

Year()
功能得到日期值中的年度(有效取值1000到3000)。
语法Year(date)

参数date:date类型的值返回值Integer。函数执行成功时得到date参数中的年份(采用四位数字),发生错误时返回1900,如果date参数的值为NULL,则Year()函数返回NULL。用法当应用程序把有两位数字表示年份的字符串转换成日期时,PowerBuilder根据下述规则选择世纪:如果年份值在00到49之间,PowerBuilder将年份中的世纪(前两位数字)当作20;如果年份值在50到99之间,PowerBuilder将年份中的世纪(前两位数字)当作19。比如,字符串"20-10-25"被PowerBuilder转换为2020-10-25;字符串"98-10-25"被PowerBuilder转换为1998-10-25。因此,如果应用程序中需要指定1950年之前的日期,应该使用四位数字表示年份,以避免引起歧义。PowerBuilder能够处理的年份从1000到3000之间。


相关文档