一、连接数据库
连接数据库也就是指定事务对象。PowerBuilder提供了两个函数:SetTrans()和SetTransObject()。
语法格式:
dw_control.SetTrans(TransactionObject)
dw_control.SetTransObject(TransactionObject)
其中,dw_control是所使用的数据窗口控件,transactionObject是所要指定的事务对象。
这两个函数有一个重要的区别就是在使用SetTrans()函数时,用户不需做任何数据初始化或事务对象初始化工作。用户只需要在这里填充一个事务对象,PB就会自动完成对该事物对象的初始化以及和数据库连接的工作。而使用SetTransObject()函数时,用户必须首先把所用的事务对象连接到数据库上。
但是,这并不意味着SetTrans()函数比SetTransObject()函数更好,使用SetTrans()函数时,每调用一次函数必须连接一次数据库,因为这个函数在每个事务处理的末端都会执行Disconnect语句。与此相反,使用SetTransObject()函数可以为数据库维持一个开放性的连接。因此在一般情况下,为了提高效率,总是采用SetTransObject()函数。
这两个函数都是成功时返回1,发生错误时返回-1。
二、检索数据
用于检索数据的函数只有一个,就是Retrieve()函数。
语法格式:
dw_control.Retrieve()
如果数据窗口控件上的数据窗口对象是有检索参数的,就要在这个函数调用时加上检索参数。而且检索参数必须和数据窗口对象中定义顺序一致。
此函数返回一个长整型的数据,代表检索出来的数据行数。如果发生错误,将返回-1。
三、更新数据
当用户对数据窗口对象内的数据修改后,想把这些修改反映到数据库中去时,必须使用Update()函数。
语法格式:
dw_control.Update()
这个更新可能成功,也可能失败。一般在这个函数被调用之后,总是要做一个检查。请看下面的例子:
Int li_return
li_return = dw_1.Update()
IF li_return = 1 THEN
COMMIT USING SQLCA;
ELSE
ROLLBACK USING SQLCA;
END IF
在这段代码中,首先对数据窗口控件进行更新操作。但是更新只是把数据写入到客户机的内存,并没有提交到数据库中。如果更新成功,就把它提交到数据库中,如果更新失败,就回滚到当前的事务。
行操作
行操作的函数主要是对数据库中的数据进行插入、删除或选择操作。
一、插入行
在DataWindow中插入一行,可以使用InsertRow()函数。
语法格式:
dw_control.InsertRow(rownumber)
dw_control是数据窗口控件名,rownumber是要插入行的的行号。如果这个参数为0,代表在当前DataWindow的最后一行插入一空行。
InsertRow()函数返回一个长整型值,以此来代表插入的行号。如果插入失败,则返回-1。
二、删除行
要删除DataWindow内的一行数据,则要使用DeleteRow()函数。
语法格式:
dw_control.DeleteRow(rownumber)
其中rownumber是要删除的行号。如果该值为0,表示删除当前行。如果删除成功,返回1,失败则返回-1。
三、设置当前行
如果要设置DataWindow中的某行为当前行,可以使用SetRow()函数。
语法格式:
dw_control.SetRow(rownumber)
其中rownumber是要设置为当前行的行号。如果函数返回1表示成功,返回-1代表失败。
四、获取当前行
如果想要获取DataWindow中的某行为当前行,可以使用GetRow()函数。
语法格式:
dw_control.GetRow()
该函数没有参数,它返回一个长整型,代表当前行号。如果返回-1代表失败。如果返回0代表没有选中任何行。
五、选择行
如果想要在DataWindow中加亮显示某一行或取消加亮显示某一行,可以使用SelectRow()函数。
语法格式:
dw_control.SelectRow(rownumber,select)
其中,rownumber表示要加亮或者取消加这显示的行号,0表示所有行。select是一个布尔类型的值,TRUE表示加亮,FALSE表示取消加亮显示。该函数返回1时表示成功,返回-1时表示失败。
如果想要直接设置某一行为加亮,需要首先取消其它行的加亮显示状态,采用如下的两行代码:
dw_1.SelectRow(0,FALSE)
dw_1.SelectRow(rownumber,TRUE)
六、获取选择行
如果想要获取当前DataWindow中加亮显示的行,可以使用GetSelectRow()函数。
语法格式:
dw_control.GetSelectRow(rownumber)
其中,rownumber为开始查找的行的行号,0表示从头开始查找。该函数返回一个长整数,表示从rownumber开始查找第一个加亮显示的行的行号。如果失败返回0。
七、滚动行
如果在DataWindow的末尾插入一行数据,而当前行是在DataWindow的中央,那么这种插入可能不会被用户觉察。为了改变这种情况,可以滚动行到DataWindow的末尾,这样用户就能发现新的改变。要滚动行,可以使用ScrollToRow()函数。
语法格式:
dw_control.ScrollToRow(rownumber)
该函数返回1时表示成功,返回-1时表示失败。
与ScrollToRow()函数据功能相关的还有如下几个函数:
ScrollPriorRow():向上滚动一行
ScrollNextRow():向下滚动一行
列操作
列操作类的函数主要是选择指定的列和获取列的信息。
一、获取列
如果要获取当前的列号,可以使用GetColumn()函数,如果要获取当前的列名,可以使用GetColumnName()函数。
语法格式:
dw_control.GetColumn()
dw_control.GetColumnName()
这两个函数都没有参数,GetColumn()函数返回一个长整型值,代表当前的列号,GetColumnName()函数返回当前列的列名。如果返回0,表示当前没有任何列被选择返回-1表示失败。
二、设置列
要设置某一列为DataWindow中的当前列,可以使用SetColumn()函数。
语法格式:
dw_control.SetColumn(column)
其中column既可以是列号,也可以是列名。当该函数返回1时表示成功,返回-1时表示失败。
数据操作
数据操作类的函数主要是对DataWindow中的数据进行获取、设置。
一、获取数据
如果要从DataWindow的指定行和列中获取数据,就要使用GetItem系列的函数。这个系列的函数共有五个,分别是对字符串、数字、日期、日期时间和小数。
语法格式:
dw_control.GetItemString(rownumber,column)
dw_control.GetItemNumber(rownumber,column)
dw_control.GetItemDate(rownumber,column)
dw_control.GetItemDateTime(rownumber,column)
dw_control.GetItemDecimal(rownumber,column)
其中,rownumber参数表示行号,column可以是列号或列名。
二、设置数据
与获取数据所用的函数不同,设置DataWindow内指定行列处的数据只要使用一个SetItem()函数就可以了。
语法格式:
dw_control.SetItem(rownumber, column, value)
其中rownumber表示行号,column可以是列号,也可以是列名,value表示要设置的值。但是该必须与DataWindow中指定的行列处的数据类型一致,不然PowerBuilder会报错。
SetItem()函数返回1时表示成功,返回-1时表示失败。
三、数据排序
如果希望对DataWindow内的数据进行重新排序,而又不想重新从数据库中检索数据,可以使用SetSort()和Sort()函数。这两个函数一起完成对DataWindow进行排序的功能。其中SetSort()函数用于设置如何排序,Sort()函数用于对DataWindow实际进行排序。
语法格式:
dw_control.SetSort(expression)
dw_control.Sort()
其中expression是一个字符串,表示排序的表达式,它的具体值是一个列名后面加一个空格,然后是"A",表示升序,或"D",表示降序。如果有多个列要同时进行排序,它们之间用逗号隔开。
例:dw_1.SetSort("name A,xh D")
这两个函数都是返回1表示成功,返回-1表示失败。
四、数据过滤
如果希望对DataWindow内的数据进行过滤而不重新从数据库中检索数据,可以使用SetFilter()和Filter()函数。它们一起完成对数据的过滤功能。其中SetFilter()函数用来设置过滤条件,Filter()函数用于对DataWindow进行过滤。
语法格式:
dw_control.SetFiter(expression)
dw_control.Fiter()
其中expression是一个字符串,表示过滤的条件,它实际是一个逻辑表达式。
例:
dw_1.SetFilter("id>\'003\' AND name like\'王%\'")
dw_1.Filter()
这两个函数都是返回1表示成功,返回-1表示失败。
五、数据检查
PowerBuilder提供了两个函数用于数据的检查,它们是DeleteCount()和ModifiedCount(),其作用分别是检查DataWindow中的数据自上一次更新到现在,被删除的行数和被修改的行数。它们一般在窗口的CloseQuery事件中使用,用来检查该窗口的DataWindow中的数据是否有尚未保存的修改。
语法格式:
dw_control.DeleteCount()
dw.control.ModifiedCount()
它们分别返回从上一次更新到现在,DataWindow中被删除和被修改的行数。如果没有行被删除或被修改,那么它们返回0。如果出现错误则返回-1。
一般情况下,如果窗口中含有可供修改的数据窗口对象,那么在窗口的CloseQuery事件中通常使用如下代码检查数据窗口对象中是否有尚未保存的数据:
Int li_return
IF dw_1.ModifiedCount() > 0 OR dw_1.DeletedCount() >0 THEN
li_return = MessageBox("提示","数据尚未保存,是否保存?",Question!,YesNoCancel!,3)
CHOOSE CASE li_return
CASE 1
TriggerEvent(\'ue_save\')
RETURN 0
CASE 2
RETURN 0
CASE 3
RETURN 1
END CHOOSE
END IF
★SetTransObject
语法:dwcontrol.SetTransObject ( transaction )
功能:给数据窗口或者datastore控件dwcontrol设置事务对象transaction,缺省事务对象是SQLCA。
返回值:成功设置事务对象则返回1,执行过程中发生了错误则返回-1,有任意参数为Null时返回Null。
★Retrieve
语法:dwcontrol.Retrieve ( {, argument, argument . . . } )
功能:使用数据窗口控件的当前事务对象检索数据库中的数据。如果数据窗口控件对应的数据窗口对象定义了检索参数,则应该在该函数中指定检索参数,参数的个数和数据窗口对象的检索变量个数相等,对应的数据类型相兼容。
返回值:返回数据窗口控件主缓存区(PrimaryBuffer)中的记录数,如果检索数据时发生错误则返回-1,如果任意参数为Null则返回Null
*该函数的参数和数据窗口对象定义的参数的顺序要相同,类型要兼容。个数不能少于数据窗口对象定义的参数,即可以等于和多于数据窗口对象定义的参数,多的参数忽略。
★DeleteRow
语法:dwcontrol.DeleteRow ( row )
功能:删除数据窗口dwcontrol中的第row行数据,如果row为0则表示删除当前行的数据。
返回值:执行成功则返回1,执行错误则返回-1,如果任意参数为Null则返回Null。
*该函数执行后只是将被删除的数据从数据窗口的主缓存区移放到Deleted缓冲区,在数据库中并没有真正删除数据,当正确执行了Update函数并且使用commit语句提交了事务后,才真正从数据库中删除该数据
★InsertRow
语法:dwcontrol.InsertRow ( row )
功能:在数据窗口dwcontrol的第row行前插入一行空白数据。当指定row为0时,表示在当前行之前插入一行空白数据。
返回值:返回插入的数据的行号,如果执行过程中发生错误则返回-1,如果任意参数为Null则返回Null
★Update
语法:dwcontrol.Update ( { accept {, resetflag } } )
功能:提交数据窗口或者datastore中的数据。如果accept为True,表示在提交数据之前自动执行AccpetText函数,否则不执行该函数,该参数缺省为True;如果resetflag为True,表示数据提交后自动清除修改标识,该参数缺省为True。
返回值:执行成功则返回1,发生错误则返回-1,如果dwcontrol为Null则返回Null
★AcceptText
语法:dwcontrol.AcceptText ( )
功能:该函数执行时,首先对当前编辑框中的内容进行对应字段的校验规则,能够通过校验规则,则保存在对应字段中,否则显示校验信息提示错误。需要执行该函数的原因是,当在某字段上的编辑框中输入内容而没有移动光标到别的字段上时,其他控件获得焦点,此时编辑框中的内容不能被保存到字段中,所以就应该在数据窗口失去焦点时执行该函数。
返回值:执行成功则返回1,执行过程中发生错误则返回-1,如果dwcontrol为Null则返回Null。
*该函数在数据窗口的ItemChanged事件中不起作用,因为项目改变是发生在接受编辑框中内容之后
★ModifiedCount
语法:dwcontrol.ModifiedCount ( )
功能:获取数据窗口或者Datastore中被修改过但还没有提交到数据库中的记录数。
返回值:返回long类型的数据窗口控件中被修改过的记录数,如果没有记录被修改过或者修改后都已经保存到了数据库中则返回0,执行过程中如果发生错误则返回-1,如果dwcontrol为Null则返回Null。
*该函数获得的修改过的记录数包括主缓存区和Filter缓存区的被修改过的和新添加到数据窗口中的记录数
★DeletedCount
语法:dwcontrol.DeletedCount ( )
功能:获取数据窗口控件或者datastore控件dwcontrol中被删除的记录数。
返回值:返回long类型的已经被删除但还没有提交到数据库中的记录数,如果执行过程中发生了错误则返回-1,如果dwcontrol为Null则返回Null,如果没有删除过记录则返回0
★RowsMove
它可以将数据从一个缓冲区移动到另外缓冲区中。该函数的语法是:
dwcontrol.RowsMove ( startrow, endrow, movebuffer, targetdw, beforerow, targetbuffer )
其中,dwcontrol是进行移动操作的源数据窗口;startrow和endrow是要移动数据的范围(包括这两个行号的数据);movebuffer指要从哪个缓存区移出数据,可以是Primary!、Delete!、Filter!;targetdw是目标数据窗口控件名称;beforerow表示在目标数据窗口的哪一行之前插入移入的数据,如果该数值比目标数据窗口的行数大,则在最后插入移入的数据;targetbuffer是目标缓存区,取值同movebuffer一样。
★GetItemStatus和SetItemStatus
使用函数dwcontrol.GetItemStatus ( row, column, Primary! )可以获取该缓冲区内指定单元的状态,当参数column为0时,表示读取整个行的修改状态。有以下状态。
NotModified! :指定单元的数据和原始数据相同,没有修改过。
DataModified!:指定单元的数据和原始数据不同,修改过。
New!:该数据行是新增加的,但还没有在该行上输入数据。
NewModified!:该数据行是新增加的,并且已经在该行上录入了数据。
这些修改标识都是由数据窗口自动维护的,一般情况下没有必要编写脚本修改这些标记,但并不是说就不能修改。PowerBuilder提供了函数SetItemStatus,它的语法是:
dwcontrol.SetItemStatus ( row, column, dwbuffer, status )
其中,row参数指定将要修改状态的行;column参数指定将要修改状态的列(可以是整型的列号,也可以是string类型的列名),当列号为0时表示要修改row指定的整行的状态;dwbuffer指定要修改哪个缓冲区(肯定不能是original),status为上面的四个取值中的一个,但不是任意的取值,因为有些状态不能用该函数设置成另外一种状态,必须是能够转换的状态。下面列出了能够转换的状态。
期望的状态 New! NewModified! DataModified! NotModified!
当前状态
New! \ Yes Yes No
NewModified! No \ Yes New
DataModified! NewModified! Yes \ Yes
NotModified! Yes Yes Yes \
表中的Yes表示可以使用SetItemStatus进行该状态设置,No表示不会产生预期的状态,如果标明了某个特定的状态,则说明是新的状态,而不是期望的状态。例如,数据窗口dw_1的第1行第1列的当前状态为DataModified!,使用函数dw_1.SetItemStatus(1,1,New!)后,第1行第1列的状态改变为NewModified!。同样对于该数据窗口dw_1,如果使用函数dw_1.SetItemStatus(1,1,NotModified!),则会将其状态改变为NotModified!。当从一种状态不允许转变到另一种状态时,可以修改成其他一个中间状态,然后再进行一次转换。例如,要从new!改成NotModified,应该首先转换到DataModified!
★GetItemX
读取数据窗口中的数据
dwcontrol.GetItemX( row, column {, dwbuffer, originalvalue } )
其中的X可以替换成Date、DateTime、Decimal、Number、String、Time,所以读取数据的函数有6个。参数row表示要读取哪行的数据,是一个long类型数值。column代表列,可以是string型的列名,也可以是整型的列号。dwbuffer是DWBuffer枚举型,取值Primary!、Delete!、Filter!分别代表主缓冲区、删除缓冲区和过滤缓冲区。originalvalue为Boolean型,表示是否读取最近一次检索时检索到的初始值,当指定dwbuffer时必须指定该参数,该参数和dwbuffer都是可选的。函数正确执行则返回对应类型的数据,执行过程中发生错误则返回空值(""),任何参数为Null则返回Null
★SetItem和SetText
函数SetItem的语法格式是:
dwcontrol.SetItem ( row, column, value )
各个参数的含义如下。
dwcontrol:数据窗口或datastore控件名称。
row:要设置的数据所在行。
column:要设置的数据所在的列。可以用整型列号,也可以用string型列名。
value:要设置的值,应该和要设置的列的类型一致。
函数正确执行则返回1,这时数据窗口中row行column列显示的数据是刚刚用该函数设定的数据,如果函数执行过程中发生错误则返回-1。注意,该函数执行时仅仅检查函数中指定数据的类型和字段的类型是否一致,不会进行有效性校验,包括在数据窗口中设置的校验规则、在ItemChanged事件中编写的校验规则、在ItemChanged调用的校验规则都不会执行。
函数SetText的语法格式是:
integer dwcontrol.SetText ( string text )
功能是设置当前编辑框中的内容。注意,当编辑框离开当前单元时要进行有效性校验,如果校验数据正确,则当前字段接受该数据,否则触发ItemError事件。所以,可以使用该函数给带有校验规则的字段设置数据。
EG:
int li_i
dw_1.SetColumn("name") //使name列成为当前列
For li_i = 1 To dw_1.RowCount()
dw_1.SetRow(li_i) //使第I行成为当前行
dw_1.SetText("屁") //向当前编辑框中写入内容
Next
dw_1.SetColumn("sex") //选中性别列,保证最后一个也要通过校验规则
★SetColumn、SetRow和GetColumn、GetRow和GetClickedColumn、GetClickedRow和GetColumnName
设置当前列
integer dwcontrol.SetColumn ( string column)
integer dwcontrol.SetColumn ( integer column)
设置当前行
integer dwcontrol.SetRow ( long row )
得到当前列
integer dwcontrol.GetColumn ( )
得到当前行
long dwcontrol.GetRow ( )
得到用户单击的列
integer dwcontrol.GetClickedColumn ( )
得到用户单击的行
long dwcontrol.GetClickedRow ( )
得到当前列的名
string dwcontrol.GetColumnName ( )
★SetFilter、Filter和Find
这两个函数必须配对使用,首先使用函数SetFilter设置过滤规则,然后用函数Filter进行过滤。过滤规则是boolean类型的表达式,能够使用过滤规则的,将表达式为True的数据行显示在数据窗口中,使其为False的数据行被移送到数据窗口的Filter!缓存区。在设计数据窗口对象时也可以定义过滤规则,使用这两个函数可以根据需要来动态改变过滤规则。在设计时,指定了过滤规则的数据窗口可以使用这两个函数再进行过滤。每次过滤都是对数据窗口的Original!缓存区进行的,而不是在前一次过滤出来的数据基础上再次过滤。
函数SetFilter的语法是:
dwcontrol.SetFilter ( format )
其中,dwcontrol是要进行过滤的数据窗口控件名称。format是过滤规则,string类型。过滤规则是由字段、常量、运算符、函数构成的boolean表达式。需要取消过滤规则显示所有的数据时,可以指定过滤规则为空(""),如果让用户可以随便指定过滤规则,则可以使用Null的过滤表达式,这时PowerBuilder提供一个和数据窗口设计时相同的过滤规则指定窗口。该函数正确执行返回1,否则返回-1。执行完后,数据窗口中显示的数据没有发生变化,只有当执行了Filter函数后才按照刚刚指定的过滤规则显示数据。
该函数的语法是:
dwcontrol.Filter ( )
dwcontrol是和SetFilter中同名的数据窗口控件名称。该函数执行正确则返回1,否则返回-1,如果dwcontrol为Null则返回Null。
函数Find也可以用来进行查询。该函数可以在数据窗口中的指定范围查找符合某些条件的数据。该函数的语法格式是:
dwcontrol.Find ( expression_r, start, end )
其中,dwcontrol是要进行查找的数据窗口控件名称,expression_r是表达式,含义和注意事项同SetFilter中的完全相同。start和end都是long类型变量,用行号表示的查找范围,它们之间没有大小约束。函数返回的是在指定范围内找到的第一个符合条件的记录号,如果没有找到或发生了错误则返回0,如果参数有Null的则返回Null
★SetSort和Sort
数据的排序可以在数据窗口对象设计时就指定排序规则,也可以在脚本中动态指定。使用函数SetSort和Sort可以完成这一任务,它们和SetFilter、Filter一样也必须配对使用。函数SetSort设置排序的规则,不改变数据的显示,只有当执行了函数Sort时,数据才真正进行重新排列。
函数SetSort的语法是:
dwcontrol.SetSort ( format )
其中,dwcontrol为要进行排序的数据窗口控件的名称;format为排序规则,是string类型,由字段、函数、ASC或DESC、逻辑联结符、常数构成。可以使用字段名,也可以使用字段号来表示字段,字段号的格式是#X,其中X为正整数。该函数正确执行返回1,否则返回-1。
和SetFilter函数类似,当指定format为空("")时,可以取消排序,当指定format为Null时,可以由用户指定排序规则。
使用函数SetSort后,再使用Sort函数才能重新排列数据。
该函数的格式是:
dwcontrol.Sort ( )
其中,dwcontrol是和SetSort中同名的数据窗口控件名称。该函数正确执行则返回1,否则返回-1,如果参数dwcontrol为Null,则返回Null。
★SelectRow
选中指定的行
dwcontrol.SelectRow ( row, boolean )
其中,dwcontrol是数据窗口控件的名称;row是行号,该参数为0则表示是对数据窗口中的所有数据行进行操作;boolean表示是否选中,如果是True,表示选中行号row的数据行,如果是False则取消。该函数正确执行返回1,发生错误返回-1,如果参数有Null则返回Null。
★PrintSetup、Print、PrintOpen、PrintDatawindow、PrintClose、PrintCancel
PrintSetup():
打印设置
PrintOpen():
启动打印作业
PrintOpen函数用来打开一个作业,并返回当前可以使用的打印作业号,该打印作业号可以标识当前的打印工作。该函数的语法是:
PrintOpen ( { jobname } )
如果发生错误,该函数返回-1。打印作业名称是可选的,名字在打印队列中。在打印作业的最后必须关闭打印作业,使PowerBuilder和Windows清除打印作业所占用的所有资源。因此,每个启动作业的语句都有一个关闭作业的语句相对应。
PrintClose()、PrintCancel():
关闭打印作业
有两个函数可以用来关闭打印作业。PrintClose()函数把当前页传送给打印机,并关闭当前打印作业。语法格式为:
PrintClose(printjobnumber)
函数PrintCancel()取消打印作业并删除当前的打印文件。这个函数可以与Print或者PrintDataWindow()函数组合使用。用于PrintDatawindow()的语法是:
DatawindowControl.PrintCancel()
用于Print()的语法是:
PrintCancel(printjobnumber)
PrintClose()函数和PrintCancel()函数是互相排斥的,成功调用过一个以后,不要在没有再次打开打印作业时调用另一个函数。
PrintDatawindow():
该函数是以单个打印作业的形式打印数据窗口控件中的内容。PowerBuilder使用数据窗口对象中定义的字体和布局进行打印。用这个函数可以在一个打印作业中打印多个数据窗口,但是每个数据窗口控件都从新的一页开始打印;如果要让几个数据窗口打印在同一页中,则需要利用底层的打印函数或将要打印在同一页中的数据窗口,创建成一个composite显示样式的数据窗口。PrintDatawindow函数的语法是:
PrintDatawindow(printjobnumber,datawindow)
其中,printjobnumber是PrintOpen函数返回的打印作业号,datawindow是要打印的数据窗口控件的名称。除了能够和Printopen()、PrintClose()函数共同使用外,其他函数都不能和PrintDatawindow共同使用。下面是一个完整地使用函数PrintDatawindow()进行数据窗口打印的例子,该例子中同时打印三个数据窗口:
Long ll_job
Ll_job = PrintOpen("数据窗口打印")
PrintDatawindow(ll_job,dw_1)
PrintDatawindow(ll_job,dw_2)
PrintDatawindow(ll_job,dw_3)
PrintClose(ll_job) //关闭打印作业
Print():
该函数是一个通用的函数,可以用来打印PowerBuilder中许多可视对象。下面介绍打印数据窗口时的语法,格式如下:
datawindowname.Print ( { canceldialog } )
datawindowname为要打印的数据窗口控件名称,canceldialog是一个boolean型变量,指示在打印时是否显示一个无模式的可以随时取消打印的窗口,该变量缺省为True。该函数正确执行则返回1,执行过程中发生错误则返回-1。
*虽然该函数和PrintDatawindow一样都可以打印数据窗口,但是它们之间是有区别的。Print函数使用设置在数据窗口对象的打印规范来打印数据窗口,而PrintDatawindow函数使用打印机当前的设置来打印数据窗口。