PB是由Sybase公司推出的一个快速数据库前台开发软件,
它以强大的数据窗口技术和数据库访问能力而陪受广大程序员青睐。
在数据窗口中有一个描述数据行和列状态的枚举变量DWItemStatus,但在实际开发中往往忽视了它的存在。
本人根据它的工作机理和相应的操作函数在实际开发中灵活应用,完善软件产品的功能。
(二)工作机理
DWItemStatus是表示DataWindow中的数据行和列修改状态和如何写入数据库中的一个枚举类型变量
这个枚举变量有四个值:NotModified!, DataModified!, New!, NewModified!。
◆ NotModified! 表示数据窗口中从数据源中检索出的行数据和列数据没有发生改变。
◆ DatModified! 表示数据窗口中从数据源中检索出的行数据和列数据发生了改变。
◆ New! 表示数据窗口中某一行数据是新插入而且没有修改过。
◆ NewModified! 表示数据窗口中某一行数据是新插入但是被修改过。
以上所说的修改包括手工输入和用SetItem函数设置。
在这四个值中 NotModifed!、DataModified!可以表示行和列的状态,
但 New!和NewModified!只可以表示行的状态。
◆当数据被检索时:
数据窗口检索到数据以后,所有的行和列的状态被初始化为NotModified!.
一旦某一行中的一列数据被手工输入修改或被程序修改后,这一列的状态变成了DataModified!.
一行中只要有一列状态是DataModified!,那这一行状态也就变成DataModified!.
◆当数据被插入时:
数据窗口中插入一行后,这一行的状态初始化为New!,这一行中的所有列状态被初始化为NotModified!.
一旦这一行中的一列数据被手工输入修改或被程序修改后,这一列的状态变成DataModified!。
新插入的一行中只要有一列状态是DataModified!,那这一行状态就变为NewModified!。
如果在数据窗口设计时为某一列设置了默认值,那新插入行时,这一列不会变成DataModified!
◆生成sql语句:
在数据窗口保存数据时,行的状态就决定了如何生成sql语句。
如果行的状态是NewModified!,那就生成insert语句在数据库中插入一行数据。
如果行的状态是DataModified!,那就生成update语句在数据窗口中更新相应数据。
(三)操作函数说明
1. 获取行和列的状态
在程序中可以用数据窗口的GetItemStatus方法来获取行或列的状态。函数原形如下:
DWItemStatus DwControl.GetItemStatus(long row,integer column,DWBuffer DWBuffer) DWItemStatus DwControl.GetItemStatus(long row,string column,DWBuffer DWBuffer)
参数说明:
◆ row: 获取状态的行。
◆ column: 获取状态的列,如果是整行的状态,这个参数设置为0。
◆ DWBuffer: 行所在的缓冲区。
◆ 返回值:指定行或列的状态枚举值。任一参数为null时,返回null。
2. 改变行或列状态
在程序中可以用数据窗口的SetItemStatus方法改变行或列的状态。函数原形如下:
integer DwControl.SetItemStatus(long row,integer column,DWBuffer DWBuffer,DWItemStatus status) integer DwControl.SetItemStatus(long row,string column,DWBuffer DWBuffer,DWItemStatus status)
参数说明:
◆ row: 设置状态的行
◆ column: 设置状态的列。如果是整行的状态,这个参数设置为0。
◆ DWBuffer: 行所在的缓冲区。
◆ status: 要设置的新状态。
◆ 返回值:如果成功执行返回1,出现错误时返回-1。任一参数为null时,返回null。
调用SetItemStatus可以将列的状态由DataModified!,改为NotModified!,反之也可。
但是如果想改变行的状态就要麻烦多了,以下是一个行状态的变换表:
原状态 指定新状态
- New! New Modified! Data Modified! Not Modified! New! - Yes Yes No NewModified! No - Yes New! DataModified! NewModified! Yes - Yes NotModified! Yes Yes Yes -
◆表中的yes意味着改变是可行的。例如将某一行当前状态是NotModified!,调用SetItemStatus将行状态改为New!是可以的,改变可以成功。
◆表中的no意味着改变是不可行的。例如将某一行当前状态是NewModified!,调用SetItemStatus将行状态改为New!是不可以的,改变将不会成功。
◆表中不是yes也不是no的单元表示改变的具体结果。例如将某一行当前状态是NewModified!,调用SetItemStatus将行状态改为noModified!时,行状态既不是NewModified!,也不是noModified!,而是变成了New!。
◆如果某一行的状态变为noModified!或New!,则这一行的所有列的状态将变为noModified!。
◆当表中的一些状态改变是被禁止时,可以分几步来完成这个过程。如:可以先将New!改变为DataModified!,再变为not Modified!。
(三)下面举两个实际开发中运用DWItemStatus的例子
例子一:
在实际开发中,为了提醒用户在关闭窗口前保存修改过的数据而在窗口的closequery事件中写如下代码:
int li_ret if ( dw_1.deletedcount() + dw_1.Modifiedcount() ) > 0 then li_ret = messagebox( "注意!", "数据已经被修改,是否存盘?", question!, yesnocancel! ) if li_ret=1 then if dw_1.update() = 1 then commit ; return 0 else rollback; messagebox( "出错!", "存盘时出错!,请检查数据的正确性!" ) return 1 end if elseif li_ret = 2 then return 0 elseif li_ret = 3 then return 1 end if end if
这样确实可以提醒用户保存数据,但是如果在数据窗口中插入一行后,调用了SetItem函数来设置这一行中某些字段的值,即使用户没有做任何的修改,
程序也会提醒用户保存。当出现这种情况时,用户常常感到莫名其妙,不知所措。
怎样才能在程序中避免这种情况的出现呢?
一个办法就是在调用了SetItem后,再用SetItemStatus将新插入行的状态重新设置为NotModified!(对应上表,可知结果为New!),
这样在ModifiedCount函数对改动数据行进行统计时就不会计入这一行。具体代码如下:
int li_Newrow li_Newrow = dw_1.insertrow(0) dw_1.SetItem(li_Newrow,"sex",1) dw_1.SetItem(li_Newrow,"birth",today()) dw_1.SetItem(li_Newrow,0,primary!,NotModified!)
例子二:
当用户在保存数据时,为了告诉用户保存了多少条数据,经常在程序中返回sqlca的
sqlnrows的值。代码如下:
if dw_1.update() = 1 then li_updatenum = sqlca.sqlnrows commit using sqlca; messagebox("提示", "保存了" + string(sqlca.sqlreturndata)) + "条记录!" ) else rollback using sqlca; messagebox("提示", "保存时出现错误,没有数据被保存!" ) end if
虽然这样可以告诉用户有多少记录保存,但是这样不是很精确。有时用户想更清楚地知道更新了多少记录,新插入了多少记录,删除了多少记录。
这个时候就需要根据数据行的状态来统计更新了多少记录,新插入了多少记录。
具体的办法是在保存前,遍历所有数据行统计NewModified!状态行和DataModified!状态行,
前者就是新插入的数据行,后者就是更新的数据行,再通过DeletedCount()函数获取删除的记录数量,详细的代码如下:
int li_newnow = 0, li_updaterow = 0, li_delrow, i = 1 DWItemStatus l_status dw_1.accepttext() do while i <= dw_1.rowcount() l_status = dw_1.GetItemStatus( i, 0, primary! ) i++ if l_status = DataModified! then li_updaterow ++ elseif l_status = NewModified! then li_newnow ++ end if loop li_delrow = dw_1.deletedcount( ) if dw_1.update() = 1 then commit using sqlca; if li_updaterow > 0 or li_newnow > 0 or li_delrow > 0 then messagebox( "提示", "保存成功!~r~n更新了"& + string(li_updaterow) + "条记录!~r~n"& + "新增了" + string(li_newnow)+"条记录!~r~n"& + "删除了" + string(li_delrow)+"条记录!") else messagebox("提示","没有数据被保存!") end if else rollback using sqlca; messagebox("提示","保存时出现错误,没有数据被保存!") end if
利用以上代码,可以准确地告诉用户更新了多少条记录,新增了多少条记录。这样用户可以更加清楚自己的操作。