弹出窗口:messagebox()

基本写法:Messagebox('标题','内容')

完整写法: MessageBox ( '标题','内容',图标,按键,默认值)

(1)其中标题与内容为要显示的字符串,不可省略,但可以省略,即什么也不显示,例如Messagebox('','')这样也是正确的单里面的东西一样也不能少!
   (2)图标可选值: Question!或None! 或Information!或 StopSign! 或 Exclamation!(默认图标) 
   (3)按键可选值: OK! (默认方式)或 OKCancel! 或 YesNo! 或YesNoCancel! 或RetryCancel! 或AbortRetryIgnore!
   (4)默认值为可选: 1 (默认选择)或 2 或 3(即弹出消息框时的默认选择按钮)

该函数有返回值,1,2,3对选择的按键。

基本写法事例: MessageBox('此处为标题,'此处为内容')
完整写法事例: 
if MessageBox('提示信息','是否删除?',&Question! ,OKCancel! , 1 ) = 1 then//选择确定
MessageBox('提示信息', '你选择了删除')
else//选择取消
   MessageBox('提示信息','你选择了不删除')
end if

设置焦点:setfocus()
对象名.setfocus
sle_1.setfocus()

用format菜单下的tab order命令可以修改焦点顺序。把用户名和密码框分别设为10,20,确定按钮设为30就行了。也可以用控件的setfocus()方法设置焦点。

触发事件:triggerevent()
对象名.triggerevent()
(1)函数作用:触发指定对象的指定事件,并且立即执行该事件中的脚本。注意该函数和PostEvent的区别。PostEvent不是立即执行,TriggerEvent是立即执行触发事件的脚本。
(2)函数语法:objectname.TriggerEvent ( event{, word, long } )
     z objectname:PB中任何对象或者控件,只要有可以触发的事件就可以。
     z event:要触发的事件。可以是枚举类型或者String类型。PB提供的事件可以使用枚举或者String类型来表示,比如Clicked!或者‘Clicked’都可以代表Clicked事件;自定义的用户事件只能使用String来表示。需要注意的是,这里的事件应该提供了脚本。
     z word:该参数不是必需的。当需要传递数据给被触发的事件时使用word和long参数。这两个参数都可以传递long类型的数据,但是参数long还可以传递string类型的数据,而该参数仅能传递long类型的。如果使用了该参数,在被触发的事件中使用Message.WordParm接收传递过去的数据。如果不使用该参数传递数据而是使用参数long进行传递,则将该参数设置为0。
    z long:该参数也不是必须的,用来传递long或者string类型的数据。使用Message.LongParm接收传递的数据。当传递string类型的数据时,对象Message.LongParm中保存的是所传数据的存储地址,必须使用string(XX,’address’)来读取该地址中的string类型数据。
返回值:Integer类型。如果返回1,表示该函数执行成功;如果指定事件中没有脚本或者

函数执行错误,则返回-1。当任意参数为Null时,函数返回Null。
代码实例:
例子1,触发缺省事件:
cb_1.TriggerEvent(Clicked!)
等价于:
cb_1.TriggerEvent(“Clicked”)
例子2,触发用户自定义事件:
w_main.TriggerEvent(“ue_open”)
例子3,传递信息和接收信息:
w_main.TriggerEvent(“ue_open”,0,’test’)
在用户自定义事件ue_open中接收数据:
string ls_msg
ls_msg = String(Message.LongParm,’address’)
例子4,传递long数据:
w_main.TriggerEvent(‘ue_open’,100,0)
在用户自定义事件ue_open中接收数据:
long ll_msg
ll_msg = Message.WordParm

关闭窗口:Close()和CloseQuery()
   这两个事件是比较重要的事件,尤其对于进行数据处理的窗口。在这两个事件中编写脚本可以避免用户因疏忽退出窗口而丢掉在数据窗口中的修改数据。

Close事件在触发Deconstructor之前所执行的最后一个事件,CloseQuery事件在Close事件触发之前发生。设置CloseQuery事件是为了增强可靠性。通常在CloseQuery事件中判断某些工作是否完成,并显示一个提示窗口询问用户,根据用户的确认,返回一个值来决定是否触发窗口的Close事件。返回值为1,表示取消关闭动作;返回值为0,表示继续执行Close事件。

比如,可以在CloseQuery事件中编写如下脚本,判断是否保存了数据窗口中的修改,并询问用户是否保存数据,根据用户的回答决定是否触发Close事件。在“关闭”按钮上编写脚本Close(parent),然后在CloseQuery中编写如下脚本:

Int li_flag

//如果数据窗口中没有修改,则允许执行Close,直接返回

If dw_1.ModifiedCount() <= 0 Anddw_1.DeletedCount() <= 0 Then Return 0

//如果数据窗口有修改,询问用户是否保存

li_flag = MessageBox("提示","数据已经修改,是否保存?",Question!,YesNoCancel!,1)

Choose Caseflag_i                //根据用户选择执行

Case1                 //用户选择要保存数据

Ifdw_1.Update() = 1 Then            //如果修改数据成功

Commit;                                 //提交

Return0                                 //继续执行Close事件

Else            //修改数据不成功

rollback;              //回退事务

li_flag= MessageBox("提示","数据错误,是否继续关闭!",&

Question!,YesNoCancel!,2)         //显示错误

Ifli_flag = 1 Then

Return0                  //允许关闭

Else

Return1              //不允许关闭

EndIf

EndIf

Case2                 //用户选择不保存数据

Rollback;             //回退事务

Return0              //允许执行Close事件

Case3                 //用户选择取消

Return1              //不允许关闭

EndChoose         //用户所有的选择情况处理完毕

通过上面的脚本,可以为用户提供一个很健壮的数据处理窗口。即使直接关闭该窗口,在数据窗口中所做的数据修改也不会丢失,除非用户自己想放弃。

另外,需要注意的是,在其他事件中调用或者触发(使用TriggerEvent函数、PostEvent函数或者是对象名称.Event 事件名称格式调用事件)Close事件,都只是执行该事件中的脚本,并不真正关闭窗口。也就是说,应该区别事件和事件处理脚本,这两者虽然有很多的联系但并不相同。 PB中的所有事件和事件处理脚本都是有区别的。

默认数据库链接变量:sqlca
dw_name.settransobject(sqlca)链接数据库
sqlca.sqlcode = 0 有数据\\ = 100 无数据
链接数据库
connect;一般用于程序open的时候,跟在数据库链接代码后面
打开窗口:open( )
open(windowname)
在Application中联上数据库。。
// Profile djerp1
SQLCA.DBMS = "ODBC"
SQLCA.AutoCommit = False
SQLCA.DBParm = "ConnectString='DSN=djerp;UID=sa;PWD=djerp'"
connect;
if SQLCA.SQLCODE <> 0 then
MessageBox("提示","数据库连接错误!")
Return

Elseif SQLCA.sqlcode = 0 Then
  Open(w_main) //打开主操作窗口
end if

关闭应用:halt close()
halt close

halt 直接结束应用程序

halt close 会执行application对象中的Close 事件的代码,会在结束应用程序,前释放所有的实例
从ini配置文件中提取string数据
profilestring('文件名,可以包含路径','主要字节','在主要字节下的关键字','如果找不到数据则返回的数据')

断开链接
disconnect;一般用于程序close的时候
是否修改过:isrowmodified()
if dw_1.modifiedcount()+dw_1.deletedcount()>0 then
.......//数据窗口处于修改状态
end if

是否新增的:isrownew()
数据窗口中的if函数
if(true\false,'为true时返回的值','为false时返回的值',)
如:if(isrownew(),'新',if(isrowmodified(),'改','旧'))

插入空行:insertrow(0)
dw_name.insertrow(0)   
通常配合插入行使用的是滚动行  
dw_name.scrolltorow(dw_name.insertrow(0)) \\滚动到插入行
比如:int row

row = dw_1.insertrow(0)

//显示

dw_1.scrolltorow(row)

//使用

dw_1.object.column[row]

从数据窗口中提取数据:getitem( )
dw_name.getitem\\string\date\......(row,'数据来源控件名')
string dwcontrol.GetItemString ( long row,integer column {, DWBuffer dwbuffer, boolean originalvalue } )

String dwcontrol.GetItemString ( long row, string column {,DWBuffer dwbuffer, boolean originalvalue } )

getitem首先根据数据窗口不同的字段类型,有不同的函数。比如对于字符型使用getitemstring,对于数字,getitemnumber,对于日期gettiemdatetime。

设置数据窗口的数据:函数setItem()
   (1).dw_name.setitem(row,'要设置的控件名','要设置进去的数据')
   (2).函数作用:给指定的数据窗口或者Datastore中的、指定单元设置数据,通过行和列来确定哪个单元。该函数直接修改缓冲区中的数据,而不是针对显示界面进行修改,修改成功之后,数据窗口控件上会自动反映出最新的内容来。而函数SetText则针对显示界面进行修改,如果能够通过字段的校验规则,才能够进入到数据窗口对应的缓冲区中。注意这两个函数的区别。

(3).函数语法:integer dwcontrol.SetItem (long row, integer column, any value )

integer dwcontrol.SetItem ( long row, string column,any value )

dwcontrol:要设置数据的数据窗口控件、DataStore或者子数据窗口的名称。

row:要设置数据的行,为long类型。

column:要设置数据的列,可以是string类型的列名称,也可以是integer类型的列号。

lvalue:要设置的数据。类型根据数据列而定,两者的数据类型应该保持一致。

返 回 值:integer类型,1表示函数执行成功,-1表示函数执行失败。如果有任意一个参数为Null,则函数返回Null。

(4).代码实例:

例子1,下面脚本在第一行的hire_date列中设置数据:

dw_order.SetItem(1, "hire_date", 1993-06-07)

例子2,当用户在数值类型的字段中输入内容,然后又删除后要离开该单元时,数据窗口尝试着将‘’赋值给该单元,这时会导致内容不能通过校验规则而产生错误。解决的办法就是在数据窗口控件的ItemError事件中编写下面的脚本:

integer li_Null

String ls_type

ls_type = This.Describe(dwo.name + '.ColType')

ls_type = Left(Lower(Trim(ls_type)),3)

choose case ls_type

case 'dec','int','lon','num','rea','ulo'

This.SetItem(Row,integer(dwo.ID),li_Null)

end choose

return 2

窗口与窗口之间的传值,子窗口
closewithreturn(主窗口,'返回给主窗口的值')
接收子窗口返回的值 = message.stringparm

string as_cpbh 
long ll_row 
ll_row=dw_1.getrow() 
if ll_row>0 then 
as_cpbh=dw_1.object.cpbh[ll_row] 
openwithparm(w_ylxx,as_cpbh) 
else 
messagebox("系统提示","请选择记录!") 
end if 
接收窗口的open事件如下: 
string as_cpbh 
as_cpbh=message.StringParm 
//is_cpbh=as_cpbh 
DW_1.Settransobject(sqlca) 
dw_1.retrieve(as_cpbh)

转换大小写:Lower()&Upper()
lower(string)转换为小写的;upper(string)转换为大写的;
(1)函数功能:将字符串中的大写字母转换为小写字母。

(2)函数语法Lower  (   string   )

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

(1)   功能将字符串中的小写字母转换为大写字母。

(2)   语法Upper(   string   )

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

为数据窗口设置事物对象
dw_name.settransobject(sqlca\也可以是自己定义的)
settrans():用指定的事务对象来设置数据窗口控件内部事务对象的值。
settransobject():给数据窗口控件设置事务对象,并提供控制事务的能力,包括程序中提交事务的能力

清零数据:reset()
dw_name.reset()
dw_1.reset():  将数据窗口控件dw_1中的数据清除。

检索数据:retrieve()
dw_name.retrieve(里面可以有参数变量不过要与数据窗口中定义的类型与顺序一样)
dw_1.retrieve():强制dw_1数据窗口控件从数据库读数据,即从数据库中检索数据。

注:retrieve之前要settransobject()和reset()一下datawindow
过滤数据:setfilter(),filter()
dw_name.setfilter(string类型\\"name ='"+ls_name+"'")
dw_name.filter()
(1)函数作用:为DataWindow或者DataStore指定数据过滤规则。通常在调用该函数前使用函数Retrieve将数据检索到客户端,该函数可以决定检索到客户端的这些数据哪些可以显示,哪些不能显示。该函数对客户端的数据进行操作,和后台数据库没有任何关系。在设置完过滤规则后使用函数Retrieve检索数据是不合理的,每次设置过滤规则后都检索数据,这样的执行效率很低。需要注意的是,该函数紧紧是设置过滤规则,并不进行过滤。函数Filter是进行过滤的,使用最近设置好的过滤规则对数据进行过滤。
(2)函数语法:integer dwcontrol.SetFilter ( stringformat )
(3)ldwcontrol:要为其设定过滤规则的DataWindow、DataStore或者下拉子数据窗口控件的名称;
lformat:作为过滤规则的表达式,该表达式的返回值应该是Boolean类型,或者是True、或者是False。如果表达式返回值为Null,则在执行函数Filter时自动弹出对话框让用户指定过滤规则。在表达式中可以使用数据窗口对象函数、列名、列号、数字、字符串等。如果用到了列号,则应该以‘#’开头、后面紧跟数字来表示。多个条件可以使用逻辑运算符进行联结,一个非常良好的习惯是每个条件都应该使用括号。这样既可以保证表达式的清晰,又可以避免一些Bug。后面的代码实例中会讲到。
返回值:数字类型,1表示执行成功,-1表示执行失败。该函数的返回值没有多大意义,很少在程序中使用该返回值。
(4)代码实例:
例1:使用列名进行过滤。
string ls_filter

ls_filter ="cust_qty > 100 and cust_code >30"
dw_Employee.SetFilter(ls_filter)
dw_Employee.Filter( )
例2:必须使用括号的情况。下面的脚本在逻辑上看起来没有什么问题:
String ls_filter

ls_filter =“(name like ‘张%’) and (article_title like ‘%计算机%’)”
dw_1.SetFilter()
dw_1.Filter()

例3:取消过滤规则。下面两个语句都能实现:
语句1:dw_1.SetFilter(“”)
语句2:dw_1.SetFilter(“1=1”)
例4:下面的语句在运行时可以让用户自己指定过滤规则:
String ls_null

SetNull(ls_null)
dw_1.SetFilter(ls_null)
dw_1.Filter()
例5:下面脚本可以判断数据窗口中是否有主键重复的数据。假设数据窗口中的主键是dept_id:
string ls_fieldname//主键名称
long ll_rc//数据窗口中总的数据行数

ls_fieldname ="dept_id"
dw_1.SetFilter("1=1")//取消过滤规则,显示全部的数据
dw_1.Filter()//过滤
ll_rc = dw_1.RowCount()//保存数据行数
dw_1.SetSort(ls_fieldname + " A")//用主键进行排序
dw_1.Sort()

//下面语句是核心语句。该过滤规则的含义是:只显示相邻行不同的数据。
dw_1.SetFilter(ls_fieldname + " <> " + ls_fieldname +"[-1] or GetRow() =1")
dw_1.Filter()
if dw_1.RowCount() < ll_rc then
MessageBox("提示",ls_fieldname + "列中存在重复的数据!",StopSign!)
end if

注:取消过滤为dw_name.setfilter("1=1")
数据排序:setsort(),sort()
dw_name.setsort(string类型\\"name a\d" :其中a为升序,的d为降序)
dw_name.sort()
(1)函数语法:dwcontrol.SetSort ( format )

z dwcontrol:数据窗口控件名

z format:string 类型,其值是有效的排序条件。排序条件中可以使用列名或列号,使用列号时,在列号前加上个#符号。如果 format 参数的值为 NULL,那么程序运行时 PowerBuilder 会提醒用户输入排序条件

返回值: Integer。函数执行成功时返回 1,发生错误时返回-1。

使用说明:在定义数据窗口对象时,可以同时定义排序条件。当使用函数 SetSort()定义新的

排序条件后,新的排序条件将取代原有的排序条件。但是,执行 SetSort()函数后,数据窗口并没有真正排序数据。要完成排序工作,需要执行数据窗口控件的对象函数 Sort()。

按某列排序时,在排序条件中放上列名或列号,后跟上“A”或“D”指明排序方式。其中“A”表示升序,“D”表示降序。要按多个列排序时,在每个列的排序条件之间用逗号(,)分隔。下面是两个排序条件示例:

"emp_lname A" "emp_lnameA, dept_id D" 如果想让用户在程序运行时指定排序条件,那么可以这样做:以空值作为

SetSort() 函数的参数来调用 SetSort() 。程序运行时, PowerBuilder 会显示“SpecifySortColumns”对话框,让用户指定排序方式。之后调用 Sort()函数完成实际排序。

代码实例:

例 1. 下面的语句为数据窗口控件 dw_employee 定义排序条件,该条件的意义为:按 emp_status 列升序排序,按emp_salary 列降序排序:

dw_employee.SetSort("emp_status A,emp_salary D")

示例 2. 下面的语句为数据窗口控件 dw_emp 设置了按 emp_status 列升序排序、按 emp_salary 列降序排序的排序条件,然后调用 Sort()函数完成实际排序工作:

string ls_newsort

数据分组:groupcalc()
dw_name.groupcalc()重新分组一般都是在filter()或sort()后面,以确保分组的正确性
当应用程序使用FILTER()函数过滤带有分组的数据窗口后,如果想继续保持分组特性,那么需要执行FILTER()函数后调用GroupCalc() 函数。 
当用户或者应用程序在数据窗口控件中增加了某些行或者修改了某些数据后,原有的分组情况可能不在符合现有的分组原则了,此时,应用程序可以调用GroupCalc () 函数来强制数据窗口重新分组。 
GroupCalc () 函数在重新分组之前并不重新排序数据,因此,如果数据窗口没有定义排序方式,那么在执行GroupCalc ()函数之前应该首先执行数据窗口控件的Sort()对象函数进行排序。

如:

dw_stat.SetRedraw(false)   
dw_stat.setsort("acptsiteid,mophonecode") 
dw_stat.sort() 
dw_stat.GroupCalc()//重新计算分组   
dw_stat.SetRedraw(true)

防止刷新,提高效率
dw_name.setredraw(false)
dw_name.reset()\retrieve()\filter()\sort()\groupcalc():中间是数据操作
dw_name.setredraw(true)
校验数据:accepttext()
dw_name.accepttext() = 1为通过检验 <>1为不通过
一般写在要对数据窗口进行操作取数的时候,写在这些动作前面
AcceptText()
功能
 将“漂浮”在数据窗口控件上编辑框的内容放入到数据窗口控件的当前项中(主缓区中)。在将数据放入到当前项之前,编辑框中的数据必须通过有效性规则检查
语法
  dwcontrol.AcceptText ( )
参数
  dwcontrol:数据窗口控件名返回值
  Integer。函数执行成功时返回1,出现错误(比如数据不满足有效性规则)时返回-1。
  如果dwcontrol为NULL,则AcceptText()函数返回NULL。用法当用户在数据窗口中从一个项移动到另一个项时,数据窗口检查用户输入或修改数据项数据值的有效性并把这些数据放入到数据窗口控件的主缓冲区中。如果用户修改了数据窗口的某个数据项后立刻把输入焦点移动到同一个窗口的其它控件,那么数据窗口控件并没有把用户新修改的数据放入到数据窗口控件的主缓冲区,这些数据依然保存在“漂浮”在数据窗口控件当前项上面的编辑框中。这种情况下,使用AcceptText()函数把用户新修改的数据放入到数据窗口控件的主缓冲区中。调用AcceptText()函数的典型地方是在用户自定义事件中,该事件可通过在数据窗口控件的LoseFocus事件处理程序中调用PostEvent()函数来触发。
   需要注意的是,不要在数据窗口控件的ItemChanged事件处理程序中调用AcceptText()函数。AcceptText()函数还可能触发数据窗口控件的ItemChanged或ItemError事件。
示例1. 下面的代码是命令按钮Clicked事件处理程序的一部分,它读入用
户对数据窗口控件dw_Emp中当前数据的修改,并计算balance列值大于0的行数:
integer i, 
Countdw_employee.AcceptText()  //接收编辑控件中用户修改的数据
FOR i = 1 to dw_employee.RowCount()
  IF dw_employee.GetItemNumber(i,'balance') > 0 THEN
     Count = Count + 1
  END IF
NEXT

修改的行数:modifiedcount()
dw_name.modifiedcount()
ModifiedCount()函数是确定DataWindow中被修改的行数(包括插入行),比如:dw_text.ModifiedCount() 如果自前一次更新(如果没有更新,则从上一次检索)后没有修改行或插入行,则返回0,出错返回-1

删除的行数:deletedcount()

如果deletedcount()+modifiedcount()> 0 则表明数据窗口有操作

统计行数:.rowcount()
dw_name.rowcount()

(1)函数作用:返回数据窗口控件当前可用行数(提取的所有行数减去删除的行数,加上插入的 行数,再减去过滤掉的行数,即当前主缓冲区中数据行数)。

(2)函数语法: dwcontrol.RowCount()

参数: dwcontrol:数据窗口控件名

返 回 值: Long。函数执行成功时返回主缓冲区中数据行数,发生错误时返回-1。如果

dwcontrol 的值为 NULL,则 RowCount()函数返回 NULL。

使用说明:数据窗口控件主缓冲区中的数据行显示在数据窗口中,用户能够操作或打印它们。 这部分数据的数据行数可以使用 RowCount()函数得到。主缓冲区中数据的行数等 于提取的所有行数减去删除的行数,加上插入的行数,再减去过滤掉的行数。删 除的数据行和过滤掉的数据行分别保存在数据窗口控件的删除缓冲区和过滤缓冲 区中。

(3)代码实例:

例 1. 下面的代码得到数据窗口控件 dw_Employee 中当前可用行的行数:

long NbrRowsNbrRows = dw_Employee.RowCount()

例 2. 下面的代码检测用户是否已经滚动到数据窗口控件的末尾。它通过将数据窗 口主缓冲区中的行数与数据窗口对象的 LastRowOnPage 属性相比较来得到:

dw_1.ScrollNextPage()

IF dw_1.RowCount() = Integer(dw_1.Describe( &

"DataWindow.LastRowOnPage")) THEN

. . . //  所需的其它处理

END IF

保存数据:update()
if dw_name.update()=1 then \\= 1为成功
  commit using sqlca; --提交数据
else
  rollback using sqlca; --回滚数据
end if   
选择行:selectrow()
dw_name.selectrow(row,true\false)
(1)函数作用:选中或者取消选中数据窗口、DataStore中的一行或者所有行数据。该函数的执行不会改变当前数据行。也就是说,如果第2行是当前数据行,执行完该函数,比如dw_1.SelectRow(5),第2行仍然是当前数据行。

(2)函数语法:integer dwcontrol.SelectRow ( long row, boolean select)

ldwcontrol:数据窗口、DataStore或者子数据窗口。

lrow:long类型,要选中或者取消选中的数据行行号。如果该参数为0,表示对所有的数据行进行操作。

lselect:Boolean类型,取值为True表示要选中指定的数据行(不管在执行函数之前是否是选中的);取值为False表示要取消选中指定的数据行(不管执行函数之前是否没有选中)。

返 回 值:函数执行成功返回1,执行错误返回-1,任何参数为空则返回Null。

(3) 代码实例:

例1:数据窗口中多行选中程序。

首先定义窗口实例变量:

long il_LastSelectedRow = 1

然后开始编写多行选中程序。程序算法描述如下:

1)、如果按下了Control键,如果是在选中行上,取消该行,否则,选中该行,记录当前到窗口实例变量中

2)、如果按下了Shift键,取消所有选中行,选中上次点击行和当前行之间的所有数据,记录当前到窗口实例变量中

3)、如果没有按键,如果点击行为选中行,不执行任何操作, 否则,取消所有选中行,选中当前行,记录当前到窗口实例变量中

比如,我们在窗口dw_1的Clicked事件中编写该脚本,程序如下:

long ll_Start, ll_End, ll_index

if Row < 1 then return

if KeyDown(KeyControl!) then

ifThis.IsSelected(Row) then

This.SelectRow(Row,False)

else

This.SelectRow(Row,True)

end if

elseif KeyDown(KeyShift!) then

if Row <il_LastSelectedRow then

ll_Start =Row

ll_End =il_LastSelectedRow

else

ll_Start =il_LastSelectedRow

ll_End = Row

end if

已选择行:isselected( )
dw_name.isselected(用循环语句检查每一行是否被选择li_row)
实例:
integer li_currow
boolean lb_result

li_currow = dw_name.getrow()
lb_result = dw_name.isselected(li_currow)
if lb_result then
  dw_name.selectrow(li_currow,false)
else
  dw_name.selectrow(li_currow,true)
end if
当前行:getrow()
dw_name.getrow()
删除行:DeleteRow(row)
(1)函数功能:删除行, 将被删除的数据从数据窗口的主缓存区移放到删除缓冲区

dw_name.deleterow(row\\当前行的话为0,其它的为行数)
row—要删除的行号,row=0时删除当前行。成功时返回1,失败时返回-1

(2)实例:删除数据窗口控件的dw_1中的第10行: dw_1.DeleteRow(10)

去掉数据两边的空格:Trim()
trim(string) //trimw()为有中英双字节输入的时候用的
(1)功能:删除字符串首部和尾部的空格。

(2)语法:Trim ( string )

参数string:

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

获得字符长度:Len()
len(string) 
(1)功  能:得到Blob类型变量的数据长度,以字节为单位。 
 (2)语  法:Len ( blob ) 
(3)参  数:blob:Blob类型变量。
返回值:Long。函数执行成功时返回blob变量的长度,发生错误时返回-1。如果任何参数的值为NULL,则Len()函数返回NULL。
(4)用  法:如果在说明Blob类型的变量时指定了变量长度,那么对该变量来说,Len()函数得到的就是这个指定的长度。如果在变量说明时未指定变量长度,那么PowerBuilder在赋值时调整长度,未赋值Blob类型变量的长度为0。

获得指定字符--string
mid('string//为要从获取数据的来源','从第几个字符开始','要获得的字符长度')
midw()为有中英双字节输入的时候用的
替换指定字符:replace( )
replace('string//被替换的','开始的地方','替换的长度','string//要替换的内容')
注:如果开始的地方大于被替换的字符,则在被替换的字符后面加上要替换的内容
(1) 功  能:将一个字符串中指定个数的字符串替换为另一个字符串。

(2) 语  法:Replace ( string1, start, n, string2 )

(3) 参  数:string1:string类型,指定要使用string2替换其中一部分内容的字符串;

start:long类型,指定要从哪个字符位置开始替换字符串,字符串中第一个字符的位置为1;

n:long类型,指定要替换多少个字符;

string2:string类型,指定用哪个字符串替换string1的部分字符。

返回值:String。函数执行成功时返回替换后的字符串,发生错误时返回空字符串("")。如果任           何参数的值为NULL,Replace()函数返回NULL。

(4) 代码实例:把Name变量的值”春眠不倔小”替换为”春眠不觉晓”。

Stringname

Name= ”春眠不倔小”

Name= Replace(Name , 7 , 4 , “觉晓”)

从左边获得指定字符:Left ()
left('string\\来源','长度')
leftw()为有中英双字节输入的时候用的
(1) 功能:得到字符串左部指定个数的字符。

(2)语法:Left ( string, n)

(3)参数  string:string类型,指定要提取子串的字符串。

n:long类型,指定子串长度。

函数执行成功时返回string字符串左边n个字符,发生错误时返回空字符串("")。如果任何参数的值为NULL,Left()函数返回NULL。如果n的值大于string字符串的长度,那么Left()函数返回整个string字符串,但并不增加其它字符。

(4) 示例1. 下面的代码返回“ABCD”

Left("ABCD EFGH", 4)

从右边获得指定字符:Right()

right('string\\来源','长度')
rightw()为有中英双字节输入的时候用的

(1) 功能从字符串右端取指定个数字符。

(2) 语法Right ( string, n )

(3) 参数string:string类型,指定要提取子串的字符串n:long类型,指定子串长度返回值String。

函数执行成功时返回string字符串右边n个字符,发生错误时返回空字符串("")。如果任何参数的值为NULL,Right()函数返回NULL。如果n的值大于string字符串的长度,那么Right()函数返回整个string字符串,但并不增加其它字符。
在一字符中找另一字符的位置:Pos()  
pos('string\\要从这个字符中寻找','stirng\\这个字符是要寻找的内容',long\\起始位置从第几个字符开始找)
(1) 功能在1个字符串中查找所包含的另1个字符串的起始位置。

(2) 语法Pos ( String1,String2 {, start } )

(3) 参数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""。

在规定的时间内触发某事件
idle(60) \\如果60秒没有操作的话就触发application对象的idle事件
timer(60) \\每隔60秒就触发一次窗口的timer事件
判断是否为空
isnull(any) \\为空 not isnull(any)\\不为空 setnull(any)\\设置为空
类型转换: String( )
要转换类型(被转换的类型)如string(any)
还可以定义格式如string(date,'yyyy-mm-dd')
(1)函数作用:该函数有两种用法,一种是进行类型转换,见语法格式二;另一种是进行类型转换的同时还进行数据格式的转换,见语法格式一。重点是格式一的学习和理解。

(2) 函数语法: 格式一:String ( data, { format } )

格式二:String ( Blob )

data:要进行类型和格式转换的数据;可以是date、DateTime、数字类型、time或者string类型。

format:格式串,用来指定参数data的显示格式。根据参数data的数据类型的不同而不同。当参数data为String类型时,该参数是必需的,否则就没有必要使用该函数了。

返 回 值: String。函数执行成功时返回以字符串方式表示的指定数据,如果data参数的数据类型与format参数指定的格式不匹配、format参数指定的格式无效、或data参数不是前面提到的适宜数据类型时,String()函数返回空字符串("")。

使用说明:format是个用掩码表示的字符串,参数data的类型不同有不同的用法:

对data参数为数值类型的情况来说,格式为:

正数格式;负数格式;零的显示格式;

(4)代码实例:

例1、下面的语句将指定日期转换为: Jan 1,1998的格式:

string(1998-01-31,”mmmm dd,yyyy”)

例2、下面的语句把DateTime类型的值转换为:Jan 1,1998 6 hrs and 8 min的字符串:

string(DateTime(1998-01-31,06:08:00),’mmmm dd,yyyy h“hrs and” m ”min”’)

例3、下面的语句把string1设置为0123:

integer li_num = 123

string ls_temp

ls_temp = string(li_num,”0000;(000);****;空”)  

滚动页
dw_name.scrollpriorpage() \\向前滚动一页
dw_name.scrollnextpage() \\向后滚动一页
获得数据窗口有多少个列:
dw_name.object.datawindow.column.count
实例:获得数据窗口的列名
integer li_index
for li_index = 1 to integer(dw_name.object.datawindow.column.count)
 messagebox(stirng(li_index),dw_name.describe("#"+string(li_index)+".name"))
next
获得数据窗口的对象描述
dw_name.describe(datawindow.table.select) \\获得数据窗口的sql语句
dw_name.Describe( "Evaluate( 'LookupDisplay(列名) ', 行数) " ) //获得下拉数据窗口的显示值
......
获得与数据窗口中列相对应的数据表中的字段名称dbname
integer li_index
for li_index = 1 to integer(dw_name.object.datawindow.column.count)
 messagebox(stirng(li_index),dw_name.describe("#"+string(li_index)+".dbname"))
next
获得数据窗口的sql语句
dw_name.getsqlselect()
设置数据窗口的sql语句
dw_name.setsqlselect()
注:重设sql语句的时候列与类型必须要与原来的一样,where与group by和order by可以不一样
实例:
ls_oldsql = dw_name.getsqlselect()
ls_newsql = left(ls_oldsql,pos(lower(ls_oldsql),'where')) +'NewWhereSql'......
dw_name.setsqlselect(ls_newsql)
dw_name.retrieve()
另存为:.saveas( )
dw_name.saveas(名字可含路径,另存为的类型,是否显示列标题)
如:dw_name.saveas("g:\1.txt",Text!,false)

53.动态数据窗口syntaxfromsql
sqlca.syntaxfromsql(sqlselect一条sql语句,窗口风格,报错信息)
创建create()
动态创建数据窗口对象:
ls_syntax = 动态数据窗口syntaxfromsql
dw_name.create(ls_syntax,自定义报错信息)
创建非可视系统对象类型:
transaction dbtrans
dbtrans = create transaction
dbtrans.dbms = 'odbc'
释放destroy
由create创建非可视系统对象类型用完以后要及时释放,让内存资源得到更好的使用
destroy dbtrans
修改数据窗口: modify( )
dw_name.modify(string\\"name = '"+Tom+"'") \\更多例子请看pb帮助
移动行rowsmove( )
dw_name.rowsmove(开始行,结束行,缓冲区,要移动到的另一窗口名,在哪一行前面插入,插入哪个缓冲区)
rowsmove还可以在同一数据窗口的不同缓冲区进行移动行
如从删除缓冲区移动行到主缓冲区实现恢复功能:
dw_name.rowsmove(1,dw_name.deletedcrount(),delete!,dw_name,1,primary!)
复制行rowscopy( )--基本用法和移动行差不多
dw_name.rowscopy(开始行,结束行,缓冲区,要复制到的另一窗口名,在哪一行前面插入,插入哪个缓冲区)
获得数据窗口的状态getitemstatus
dw_name.getitemstatus(row\\第几行,哪一列,哪个缓冲区)
缓冲区有三种:应该有四种的,不过另一种原始缓冲区不常用
primary! delete! filter!
状态有四种:
datamodified! new! newmodified! notmodified!
设置数据窗口状态setitemstatus
dw_name.setitemstatus(row\\第几行,哪一列,哪个缓冲区,设置为哪个状态)
共享数据:sharedata()
CONNECT USING SQLCA;
dw_employee.SetTransObject(SQLCA)
dw_employee.Retrieve()
dw_employee.ShareData(dw_dept)
要结束共享数据用sharedataoff()

  共享数据窗口的概念,共享数据窗口的实现非常简单,只需一条Shar eData()。例如在Window对象上的两个数据窗口dw-p和dw-s,则可以用dw-p.ShareDat a(dw-s)实现二者的数据共 享,dw-p称为主数据窗口,而dw-s称为从数据窗口。从原理上讲,二者实际上所共享的是数据的缓冲区。缓冲区中的数据首先要从数据库中检索(通过数据窗口Retrieve()函数),而数据库的检索是一种较为" 昂贵"的操作,它会加重数据库和网络传输的负荷。在共享数据窗口情况下,只有主数据窗口检索数据,而从数据窗口通过共享获得数据,无须再检索数据库,

  在下拉数据窗口中的应用

  下拉数据窗口(DropDownDatawindow)作为一种编辑风格在数据窗口中有着广泛的应用,如果将数据窗口字段的编辑网络设为下拉数据窗口,则执行数据窗口的Retrieve()函数时,如果其所包含的下拉数据窗口为空(RowCount()=0),则自动为所含下拉数据窗口检索数据。如果一个数据窗口中包含多个下拉数据窗口字段,则在其每次打开关闭时(如常用的查询界面),所包含的下拉数据窗口都重复检索数据库。

  考虑到包含下拉数据窗口的字段内容在一次应用中通常是不变的 ,所以多次检索数据库也是不必要的。这一问题可以通过共享数据窗口解决,具体做法是:先建立一个专用的窗口对象w-ddw完成预先检索任务,即在w-ddw上放置一个数据窗口dw-1,其字段为下拉数据窗口编辑风格,对应于后面用到的下拉数据窗口。w-ddw的open事件脚本 为:

  //w-ddw's open event

  dw-1.DataObject="dw-ddw"

  dw-1.Retrieve()

  其中dw-ddw是包含下拉数据窗口的数据窗口对象,这样为后面所要用到的下拉数据窗口检索到数据,后续的数据窗口包含下拉数据窗口时,下拉数据窗口可以共享这一检索结果而无须再对数据库检索。

  考虑到对象的通用性,将w-ddw设计为一个专用对象,在其窗口级设计了一个函数wf-ddw-load(dw-app,col-src,col-dst),用于实现某一数据窗口(dw-app)中某字段所对应的下拉数据窗口的共享 。

  //wf-ddw-load function

  DataWindowsChild dwc-src,dwc-dst

  dw-1.GetChild(col-src,dwc-src)

  dw-app.GetChild(col-dst,dwc-dst)

  if dwc-src.ShareData(dwc-dst)=-1 then

   MessageBox("错误","数据共享错误!")

  end if

  如果考虑到某一字段内容可能更新,再设计一个字段更新函数:

  wf-Update(col)

  //wf-Update()function

  DataWindowChild dwc

  dw-1.GetChild(col,dwc)

  dwc.SetTransObject(SQLCA)

  dwc.Retrieve()

  在应用的开始打开w-ddw,w-ddw设计为不可见的(Visible属性 为False),如果某一数据窗口(例如名为dw-app)中的下拉数据窗口共享w-ddw中的数据窗口数据,则可以在其所在的window的open事件编写脚本:

  //This's open event

  dw-app.SetTransObject(SQLCA)

  w-ddw.wf-ddw-load(dw-app,'groups','groups')

  dw-app.Retrieve()

  由于下拉数据窗口通过共享已经装载数据,所以在以后的多次打开时,dw-app检索数据库时不会再为其检索,在应用的最后关闭w-dd w。

 

  在数据窗口打印中的应用

  数据窗口最简单的打印方法为:dw.print(),但是在实际应用中, 屏幕上用于显示的数据窗口通常与打印要求的格式不同,如有两个数据窗口,dw-1(用于显示)和dw-2(用于打印),使用数据窗口共享技术可以很简单地解决问题,否则就必须对dw-2进行数据库检索。

    PowerBuilder中的合成式数据窗口(Composite)是处理多数据窗口的有力工具,可以设计一个合成数据窗口dw-prt用于打印。dw-pr t所含两个数据窗口与dw-1和dw-2兼容。如果采用数据共享方法,dw -prt就不用执行带参数的Retrieve(parm),可以直接打印当前查询结果。下面说明具体的实现方法。

  要实现数据共享,就必须能够引用合成数据窗口中所包含的两个数据窗口的名字,在数据窗口画板上双击内含Report对象,在出现的Re port Name中输入名字,假设分别为rpt -1和rpt-2,定义一个用户事 件ue-print,当触该事件时执行下列脚本:

  //ue-print

  //dw-1 contains department and dw-2 contains emp

  DatawindowChild dwc-1,dwc-2

  dw-prt.SetTransObject(SQLCA)

  dw-prt.GetChild("rpt-1",dwc-1)

  dw-prt.GetChild("rpt-2",dwc-2)

  dw-1.ShareData(dwc-1)

  dw-2.ShareData(dwc-2)

  dw-prt.Print()

测试是否为有效值:IsDate()
isdate(),isnumber()......有效的话返回true
功能检测指定的字符串是否包含有效的日期。
语法IsDate (datevalue )
参数datevalue:string类型,指定要检测的字符串返回值Boolean。如果datevalue包含了有效的日期,则IsDate()函数返回TRUE,否则返回FALSE。如果datevalue参数的值为NULL,则IsDate()函数返回NULL。

查找数据窗口中第一个被选中的行getselectedrow()
dw_name.getselectedrow(row\\从第几行开始找,第一行开始的话设为0)
dwo对象
dwo是一个泛指对象,包括文本对象,按钮对象等等
DWO 全称 DataWindowObject 。它指的是 DataWindow 中的一个对象。例如一个计算列、Text 框、Picture Box 等等

如:
数据窗口即写即现
string ls_name,ls_staffcode

choose case dwo.name
  case 'xf_staffcode'
  ls_staffcode = trim(data) 
  If gnv_data.of_HaveValue( ls_staffcode ) Then
  select xf_name into :ls_name
  from xf_staff
   where xf_staffcode = :ls_staffcode
  using itrans_current;
  this.setitem(row,'xf_name',ls_name)
end choose

DataWindow常用函数

1、插入一条记录:dw_1.insertrow(cur_row)其中,dw_1为datawindow控件名,cur_row为一具体的行号,在该行前插入一新行。

例如:dw_1.insertrow(4)表示将在第4行前插入一条空记录。该函数有一个返回值,该值为新插入这条记录的行号。

2、删除一条记录:dw_1.deleterow(del_row)其中,dw_1为datawindow控件名,del_row为一具体的行,将该行删除。该函数有一个返回值,删除成功返回1,出错返回-1

例如:dw_1.deleterow(23)将第23条记录删除。

3、返回当前行行号:dw_1.getrow() 其中,dw_1为datawindow控件名,注意:当前行并不一定就是屏幕上显示的。比如用户鼠标点击了第5行12列中的单元格,然后拖动滚动栏,当前屏幕上显示第23到45行,可当前行仍然是第5行,除非用户鼠标点击了其他行。

4、取出某一单元格子的数据:dw_1.object.col[rownum]其中,dw_1为datawindow控件名,

Object为固定写法,col为列名,rownum为行号。

例如:需要将第34行列名为xm的值取出来,放在一个字符串变量ls_name中,写法如下:

String Ls_name 定义一个字符串变量ls_name

Ls_name = dw_1.object.xm[34] 将第34行xm列中的值取出放入Ls_name变量中。

如果需要将对某一单元格子赋值,可以用下面的方法:

比如要将45行xm列的值赋为“张三“

Dw_1.object.xm[45]= “张三“

 5、过滤数据:dw_1.setfilter(ls_tj)其中,dw_1为datawindow控件名.ls_tj为过滤条件字符串。

比如:某数据窗口对象中某一列名为id, 需要将id>5 并且id<12的数据过滤出来

Dw_1.setfilter(“id>5 andic<12”);  设置过滤条件“id>5 and ic<12”

Dw_1.filter( );   过滤

6、排序数据:dw_1.setsort(ls_sort)其中,dw_1为datawindow控件名.ls_sort为排序条件字符串。

比如:某数据窗口对象中某一列名为nl, 需要按nl升序的顺序排序。

Dw_1.setsort(“nl asc”);  设置排序条件“nl asc”(升序用asc,降序用desc)

Dw_1.sort( );   过滤

7、返回记录数:dw_1.rowcount( )其中,dw_1为datawindow控件名.

例如:longll_r     定义一个长整形变量ll_r

ll_r =dw_1.rowcount( )   得到控件dw_1中datawindow数据总记录数放入变量ll_r中

8、text、excel、dbase格式文件导入datawindow以及datawindow中的数据导出text、excel、dbase格式文件。导入:dw_1.importfile(type, filename, startrow , endrow, startcolumn, endcolumn, ldwstartcolumn ) 其中,dw_1为datawindow控件名, type为导入的文件类型。Filename为文件名,startrow为该文件的开始行,endrow为该文件的结束行。Startcolumn为该文件的开始列,endcolumn为该文件的结束列,ldwstartcolumn为datawindow的开始列。

例如:将c盘test.txt文件的第2到8行的第3至第6列导入到datawindow中,并且导入数据放到datawindow中的第45行后面。

Dw_1.importfile (Text!,”c:/test.txt”,2,8,3,6,46)

导出:dw_1.saveas(filename,saveastype, colheading ) 其中,dw_1为datawindow控件名, filename为导出的文件名, saveastype为导出的文件类型,colheading为是否保存标题。

例如:将数据窗口中的数据保存到d盘,取名为cs的文件。要求带标题。

Dw_1.saveas(“d:\cs.txt”,text!,true) true为带标题。False为不带标题。

9、数据窗口中数据的保存。Dw_1.update( ) 其中,dw_1为datawindow控件名

例如:数据修改后,需要对数据进行保存。用该语句实现。

Dw_1.update( ) 该语句有返回值,如果返回1表示更新成功,返回-1表示出错。

10、弹出消息框。MessageBox ( title, text, icon, button, default ),title为标题,text为消息内容,icon为图标,button为显示按钮,delfault表示默认按钮。

例如:弹出一个消息框,标题为:删除确认,内容为:确认要删除该条记录吗,图标为询问图标,按钮为ok和cancel,默认为cancel按钮。

MessageBox ( “删除确认”, “确认要删除该条记录吗”,question!,OKCancel!, 2)

11、查找函数。Dw_1.find(expression,start, end), 其中,dw_1为datawindow控件名, expression为查找条件表达式,start为开始行,end为结束行。

例如:查找列名id等于8的记录,从前10行中查找。

Dw_1.find(“id=8”,1,10) 返回找到行的行号

PB常用函数的更多相关文章

  1. PB之常用函数

    原文网址:https://www.cnblogs.com/zhaoxiong/p/8082523.html PB之常用函数 弹出窗口:messagebox() 基本写法:Messagebox('标题' ...

  2. 非常实用的PHP常用函数汇总

    这篇文章主要介绍了非常实用的PHP常用函数,汇总了加密解密.字符串操作.文件操作.SQL注入等函数的实例与用法说明,在PHP项目开发中非常具有实用价值,需要的朋友可以参考下 本文实例总结了一些在php ...

  3. java 多线程总结篇2之——Thread类及常用函数

    此片文章主要总结的是Thread类及相关的基础概念和API,首先需要厘清线程调度中的几个基本概念: 一.线程调度的基本方法 1.调整线程优先级:Java线程有优先级,优先级高的线程会获得较多的运行机会 ...

  4. oracle常用函数及示例

    学习oracle也有一段时间了,发现oracle中的函数好多,对于做后台的程序猿来说,大把大把的时间还要学习很多其他的新东西,再把这些函数也都记住是不太现实的,所以总结了一下oracle中的一些常用函 ...

  5. 总结js常用函数和常用技巧(持续更新)

    学习和工作的过程中总结的干货,包括常用函数.常用js技巧.常用正则表达式.git笔记等.为刚接触前端的童鞋们提供一个简单的查询的途径,也以此来缅怀我的前端学习之路. PS:此文档,我会持续更新. Aj ...

  6. [转]SQL 常用函数及示例

    原文地址:http://www.cnblogs.com/canyangfeixue/archive/2013/07/21/3203588.html --SQL 基础-->常用函数 --===== ...

  7. PHP常用函数、数组方法

    常用函数:rand(); 生成随机数rand(0,50); 范围随机数时间:time(); 取当前时间戳date("Y-m-d H:i:s"); Y:年 m:月份 d:天 H:当前 ...

  8. Oracle常用函数

    前一段时间学习Oracle 时做的学习笔记,整理了一下,下面是分享的Oracle常用函数的部分笔记,以后还会分享其他部分的笔记,请大家批评指正. 1.Oracle 数据库中的to_date()函数的使 ...

  9. Thinkcmf:页面常用函数

    Thinkcmf:页面常用函数 全站seo: 文章列表: {$site_seo_title}        <!--SEO标题--> {$site_seo_keywords}   < ...

随机推荐

  1. c#不同数组之间的转换【转载,消化自动删除】

    c#中从string数组转换到int数组 string[] input = { "1", "2", "3", "4", ...

  2. Numpy 学习 array np.where lexsort 切片 按行按列求平均mean

    array 的创建可以通过list给 array print出来像一个表格,可以按行按列来观察. 原来是一个list相当于一行 np.where用于寻找一个condition下的坐标,返回的是一个2个 ...

  3. 会调色了不起吗? SORRY,会调色真的了不起!

    其实,现实的世界,大部分都是非常普通和常见的.所以调色师才有他们发挥的空间.如何把镜头中的世界变成梦幻一般. 把画面的颜色统一之后,逼格马上提升了很多! 发现表情不对,从其他照片把表情P回来,哈哈 这 ...

  4. 当前页面刷新和动态添加控件的jquery事件绑定on

    当前页面刷新(console): location.reload() 给动态添加的控件添加js事件(委托): <ul> <li>菜单一</li> <li> ...

  5. L与_T

    https://www.cnblogs.com/xxn-180727/p/9378519.html _T( ) 是一个适配的宏,当工程采用Unicode字符时 _T()就是 L,会将多字节的字符串转化 ...

  6. [FreeMind] 绘制思维时遇到的常见问题解决办法

    如何改变节点的摆放方向? 如果是新建节点,选择要放置节点的那一侧,按enter键,或者鼠标右键,插入平行节点即可. 如果是已经建好的节点,可以用ctrl+x, ctrl+v粘贴到另一边,或者选中子节点 ...

  7. 2017/2/13:springMVC拦截器的使用

    一.定义Interceptor实现类(主要是实现Handlerceptor接口) SpringMVC 中的Interceptor 拦截请求是通过HandlerInterceptor 来实现的.在Spr ...

  8. 2017年7月25日多校一Function

    Function这道题我当时一直很迷,到底怎么来的啊,为什么会这样啊?? 然后看了题解才知道,原来是找循环啊. 已知f(i)=b[f(a(i)],则 f(0) = b[f(a[0])] = b[f(2 ...

  9. canvas 实现赛车小游戏

    一:样式 <style> #btn{ width: 60px; height: 30px; line-height: 30px; background: #7EC0EE; border: ...

  10. django之http

    一 http协议介绍 http协议(Hyper Text Transfer Protocol):超文本传输协议,是基于应用层的面向对象协议,靠tcp协议和IP来传输数据,请求和响应是http协议的基本 ...