[PB]-数据窗口对象(一)

PB 专栏收录该内容
175 篇文章 8 订阅

[PB]-数据窗口对象(一)

数据窗口对象的数据源
----------
PB提供5种数据源:Quick Select(快速选择类型)、SQL Select(SQL选择类型)、Query(查询类型)、External(外部类型)和Stored Procedure(存储过程类型)
----------
Quick Select
只能从一个数据表或者视图中选取数据(无关联的表或者视图)??
----------
SQL Select
1、选择表
可以一次选择多个表
2、选择字段
Select All //选择所有字段
Select Tables //重新选择表
Convert to Syntax //进入SQL语法状态
Compute //计算字段,右键->Columns //选择字段
      右键->Functions //选择函数
3、指定检索条件
Retrieval Arguments //定义检索参数变量的类型和名称
where //检索条件,右键->Columns //选择字段
      右键->Functions //选择函数
      右键->Arguments //选择参数
      右键->Value   //选择值
      右键->Select //从其他表中选择
----------
Query
PB可以将特定的SQL语句保存为Query对象,不同的Query数据源的数据窗口都可以使用这些已经保存好的SQL语句来提取数据
----------
External
当和不存在于数据库中的数据打交道或者要利用数据窗口的某些特性但不进行数据处理时,使用此数据源。无SQL语句。
----------
Stored Procedure
使用已经定义好的存储过程来做数据源
----------


数据窗口对象的显示样式
----------
数据窗口对象显示样式有11种:Grid、Tabular、Group、Freefrom、Label、N-Up、Crosstab、Graph、Composite、RichText、OLE2.0
----------
Grid:
字段横向排列在detail band中,标签横向排列在header band中,和字段相对应,字段和字段之间有网格线分隔,类似于电子表格。在数据窗口的预览状态下可以调整字段的顺序,并且自动反馈到数据窗口的设计状态中,调整字段顺序时,对应的标签顺序也相应地自动调整。缺省情况下,字段不能随意移动,只能在detail band中做上下移动。这种显示样式的数据窗口布局整齐,但不能灵活地安排字段、标签、表头的布局,所以常用来显示数据或录入数据,而很少用来做报表。Grid显示样式的数据窗口中,表头只能和标签放置在同一个header band中,在放置表头处仍然有网格线。
----------
Tabular:
当刚刚创建这种样式的数据窗口时,字段、标签的布局和 Grid显示样式的数据窗口相同,都是横向排列的,但是字段之间没有网格线分隔。字段和标签的布局可以随意调整,在header band中的标签可以随意拖放到detail band中,detail band中的字段也可以拖动到header band中。这种显示格式的数据窗口布局安排非常灵活,开发人员可以根据需要设计字段和标签的布局,然后手工画线制作表格,在制作中国式
报表时经常使用,虽然比较烦琐,但是表格比较美观,比较适合中国式报表的要求,另外,这种格式的数据窗口在数据录入、查询时也经常使用。
----------
Group:
Group分组显示样式的数据窗口可以指定按哪个(或哪些)字段进行分组,可以用指定的分组条件将数据分组显示,并且允许为每组指定一些计算。例如,要显示某公司在各地区的销售数据,可以按地区分组,为每个分组指定统计计算,在地区改变时显示地区的销售总金额。
当选择多个字段时,这几个字段共同作为分组的条件,而不是以每个字段都创建一个分组。使用Group类型只能创建一个分组,要创建多个分组必须在DataWindow画板中完成。
----------
Freefrom:
前面讨论的三种显示样式都是一次可以显示多行数据的。对于比较重要的数据,用户可能需要一次只编辑一行这时可以使用Freefrom显示样式的数据窗口。该类型的数据窗口将标签放置在字段的左例,字段和标签放置在同一个detail band中,先从上到下再从左到右依次排列。实际上,这种显示样式的数据窗口布局也很灵活,可以随意安排字段和标签的位置。这种显示样式的数据窗口在卡片式数据的录入和显示方面也经常使用。
----------
Label:
如果用户想要生成邮件标签,可以使用Label显示样式的数据窗口来实现。
----------
N-Up:
这是可以在同一页上显示多列相同字段的一种特殊的显示样式。当要显示的字段比较少或者不同行之间的数据需要做比较时,经常使用这种显示样式。使用向导可以创建N-up显示样式的数据窗口,需要指定的一个重要参数是每行重复显示的字段的次数,也就是Number of rows per detail band,缺省为2。该参数的大小视需要显示的字段总长度和报表使用的打印纸宽度而定。N-up显示样式的数据从左到右显示。另外,当选中行数据时,并不能选中实际上看到的一整行,而是逻辑上的一行。
----------
CrossTab:
当需要做数据统计和分析时,最好使用CrossTab显示样式的数据窗口,虽然报表在显示格式方面不适合中国人的口味,但还没有哪个C/S数据库开发软件将数据统计分析做得如此之好。使用CrossTab显示样式可以创建复杂的分类统计表,不管是表头分类还是行分类。
创建CrossTab显示样式的数据窗口时,有几个重要参数需要指定。这些重要参数是行、列和统计值。每个参数可以指定多个字段,也可以使用表达式。当指定多个字段(或表达式)时,字段的顺序决定在表中的分组顺序。比如,统计某销售公司某年各个月份各种产品、不同花色在各个地区的销售情况,可以用月份和地区作为列,用产品名称和花色作为行。在Columns列表框中按Month、Region的顺序加入字段,没有Month可以使用表达式Month(sales_date)来获取销售时的月份。Rows列表框中的字段对应数据窗口中左侧的表头,Columns列表框中的字段对应数据窗口中上面 表头,Values是出现在数据窗口表格单元中的统计值;Source Data列表框中是可以使用的字段,使用鼠标选中并拖动到相应的列表框即可。在Rows、Columns、Values三个列表框中都可以用鼠标双击已有字段,可以在接下来的对话框中输入组合表达式。比如,使用year作为Columns是可以的,也可以双击然后在上面的窗口中输入下面的表达式:year+"年"
----------
Graph:
Graph显示样式的数据窗口可以以多种图形样式将数据显示出来,例如饼图、柱状图、折线图等。Graph显示样式的数据窗口给用户的感觉是使用方便、表达直观。从开发者的角度来讲,创建Graph显示样式的数据窗口也是很简单的事情,所以在开发应用程序时不要忘记这费力不多却很受用户欢迎的显示样式。
创建Graph显示样式的数据窗口时,最重要的参数是Category、Values及Series。在创建向导中可以指定这几个参数。指明这三个参数的操作很简单,在下拉列表框中选择合适的字段即可。Category可以理解成显示在横向坐标铀上的字段,Values可以理解成显示在纵向坐标轴上的字段,而Series是横向坐标轴上同组比较时的分组标准。
----------
Composite:
    这种显示样式的数据窗口可以将多种类型的、多个逻辑上毫不相关的数据窗口放置到一起,是一种灵活的数据表现形式。因为Composite显示样式的数据窗口不允许修改其中的数据,所以不能用于数据录入和数据修改,只能在报表时使用这种显示祥式的数据窗口。使用这种显示样式的数据窗口创建报表,经常将对同一问题不同表现形式的数据窗口或者是关系紧密的数据放到一起。例如,将几个关键数据的统计结果以Graph显示样式显示在最上面,用CrossTab类型的数据窗口将比较详细的数据统计结果显示在中间,然后是Grid类型的详细数据,这样的报表数据表现能力要比任何单一的一种数据窗口要强得多。
----------
RichText:
RichText祥式的数据窗口使数据库中的数据和文字可以在一起排版,可以方便地特数据库中的数据和文字内容一起形成文档、报告等;提供了很强的文字编辑处理能力,可以很方便地处理文字的多种格式:可以开发更有表现力的应用系统,自动生成报告、文档资料,省去了使用PowerBuilder的应用程序却需要切换到其他文字处理软件中的麻烦。
----------
OLE 2.0:
OLE是Object Link and Embedding的字头缩写,表示对象链接和嵌入。使用这种技术,可以将其他软件的功能引入到PowerBuilder开发的应用程序中。PowerBuilder中不仅提供了OLE 2.0显示样式的数据窗口,而且在窗口中提供了OLE 2.0控件。例如,在数据库中保存的图像在OLE 2.0显示样式的数据窗口中,可以借助一些专门的图像处理软件来处理,并可以把处理结果返回保存到数据库中。
只有当数据库的表中包含blob类型的字段时,才有必要使用OLE 2.0显示样式的数据窗口。将blob类型的字段作为OLE 2.0列,在处理其中的数据时,可以直接触发调用相关的软件进行处理,并能够将处理结果返回保存到数据库中。例如,某字段中保存的是Excel文档,可以创建OLE 2.0显示样式的数据窗口,当双击该字段时可以调用Excel,然后在Excel中编辑处理数据,保存编辑结果返回到数据窗口时,可以将结果反映到数据窗口中。
创建OLE 2.0显示样式的数据窗口,需要指定三类参数。Source Data框中显示的是所有可用字段,可以使用鼠标选中并拖动到其他两个列表框中;Group by列表框中显示的是用来分组的字段,由于OLE 2.0数据窗口的特殊性,它的分组不在设计时创建,只能在向导中创建;Target Data框中显示的是在数据窗口中要显示的字段,使用了分组,则对该框中的字段做统计(字符串型的列将统计记录数,数值型的列将统计累加和),没有使用分组,则直接显示它们的值。接下来要设置的是和OLE对象关系紧密的内容
----------


数据窗口对象的画板、band和层次
----------
数据窗口画板
整个数据窗口画板由6个视窗构成,分别是:
Design:设计数据窗口对象视窗,可以使用菜单Design-Options来改变Design窗口的外观
Preview:预览数据窗口的外观,显示相应表中的对应的数据,及对数据的各种操作
Control List:数据窗口中所有的部件构成的一个列表
Data:显示此数据窗口对象所对应的表中的各个字段的值
Properties:属性
Column Specification:该视窗是个比较重要的视窗,可以增加、删除、修改列的初始值、检验表达式或者校验信息
----------
数据窗口对象的band
数据窗口用带-band将其分隔成四部分:
Header:出现在每页的顶端,用于显示标题和列的题头
Detail:包含了数据窗口对象的主体,显示了各行的数据和相关的标签。在DataWindow对象高度的范围内,细节条能够按照需要自动扩大任意倍
Footer:出现在每页的底端,用来显示文本和页号
Summary:出现在DataWindow对象的最后一页,用来为整个数据窗口对象显示总计和总和
----------
数据窗口对象的层次
数据窗口分为三个层次,即背景层(background)、带层(band)和前景层(foreground)。在数据窗口上放置的部件可以属于任意一个层次,但如果设计不当,数据显示会凌乱不堪。通常情况下,背景层放置绘图对象以设置漂亮的背景;带层放置字段、计算域、标签等和报表内容紧密相关的内容,在运行状态下,PowerBuilder会自动格式化带层;前景层放置一些无需打印的内容,最典型的是Graph部件。
    设置部件属于哪个层的方法是首先选中部件,然后在属性视窗中进入到Positon属性页,修改该部件的Layer属性,在Layer下拉列表框中选择适当的层即可。
    不管哪个层上的对象,鼠标右键弹出菜单中都有Send to Back和Bring to Font两个选项。这两个功能和层之间有什么关系呢?没有任何关系!不管部件属于哪个层,都可以使用这两个菜单项,使用完后部件也不会属于其他的层,只是重叠部件的前后关系发生了变化。所以当部件没有重叠时,使用这两个菜单选项没有什么意义,虽然这两个菜单选项也可以使用。
    选中数据窗口上的部件不区分层。也就是说,选中操作不受层的影响,可以同时选中不同层上的部件。当设置了较大的背景图片时,可能不能使用拖动鼠标来直接选中多个对象,因为拖动时,鼠标的起点可能就在背景图片上。解决方法是在所有操作都完成后再放置背景图片,也可首先将背景图片剪切掉,进行其他操作后再粘贴图片,或者先将背景图片拖到没有其他对象的位置上,操作完成后再将图片背景拖放到原来位置
----------


数据窗口对象及字段的修改属性
数据窗口只能修改一个数据表。当数据窗口的数据来源于不止一个数据表时,可以用脚本控制数据窗口的修改属性来对数据表逐个进行修改。
当数据窗口是用来接受用户的手工录入数据时,应该设置两方面的属性才能确保数据窗口能够用来修改数据表。一个是修改数据窗口的修改属性,另一个是用户可以修改的字段的相关属性值
----------
数据窗口对象的修改属性
Rows->Update Properties
如果数据窗口对应的数据表中定义了主键或者唯一性索引,则数据窗口创建时默认的就是允许修改,并且正确设置了所有的修改属性。否则就需要手工进行设置。当增加、删除、或者重新选择了字段时,PB将数据窗口的的修改属性为不允许,这时也应该进行手工设置。
Allow Updates:允许更新。
Table to Update:指定要被更新的表。
Where Clause for Update/Delete:配置如何在Update和Delete SQL语句中构造where子句
1、Key Columns 当开发单用户应用程序或者用户都以加锁方式访问数据库时可以选中该选项。该选项表示数据窗口只使用在“Unique Key Column”列表框中指定的唯一列进行数据更新。使用这种方式来修改数据库,并发性很高,不同的用户都可以并发地访问数据库,但是数据的完整性却非常差。因此要保护数据完整性,只有在单用户程序或者加锁访问方式下才使用这种修改方式。如:在add_book(通讯录)数据表中定义了4个字段,id为主键,name,address,telephone三个字段为可修改字段,有如下一条数据(001,陈,杭州,1395813)。若想把name改为“万”,数据窗口产生如下的update语句:update add_book set name = '万' where id = '001'
2、Key and Updateable Columns 这种修改方式是默认的修改方式,它用主键列和可以修改的列来创建where子句,具有很高的数据完整性,但是并发性不是太好。推荐使用这种修改方式。保存数据时将产生如下的SQL语句:update add_book set name = '万' where id = '001' and name = '陈' and address = '杭州' and telephone = '1395813'
3、Key and Modified Columns 该方法是上面两种方法的折中,当不同的用户并发修改同一行数据的不同字段时,都能成功修改,所以它的并发性有了一定的限制,数据的完整性比第一种修改方式有所提高。这种修改方式使用主键和数据发生了变化的列来产生where子句。保存数据时产生如下的SQL语句:update add_book set name = '万' where id = '001' and name = '陈'
Key Modification:该组框用来指定当用户修改了主键时,数据窗口如何来更新数据表中的主键字段。有两种选择Use Delete then Insert和Use Update。第一个选项是先删除原有的主键值,然后再使用新的主键值插入一个完整的行。使用这种更新主键的方式可以减少组织数据的工作量,但在数据库中各个数据表之间存在父子制约关系,并且依赖该主键的外部键被指定为级联删除时,操作就不会成功的。因为级联删除方式要求当依赖主键的外部键有数据时就不能删除主键。当DBMS允许更新主键列时,可以使用第二个选项,该选项直接修改主键值,所以防止了级联删除带来的操作不成功的问题。
Updateable Columns:指定被更新的字段。当数据窗口中的字段来自不止一个数据表时,这时一定要选择同一个表中的字段,因为一个数据窗口一次只能更新一个数据表,当数据窗口中增添了字段时,新增添的字段往往是不允许修改的,一定要在该列表框中选择该字段。
Unique Key Column:选择唯一标识一行的列。如果在定义数据表时定义了主键,单击右面的“Primary Key”按钮可以在该列表框中选中主键。
Identity Column:该下拉列表框用于为下拉列表框中所指定的列(通常是主键列)生成序号,当且仅当DBMS支持序号生成时该作用才有效
----------
数据窗口对象字段的修改属性
**相关属性
数据窗口中字段的相关属性:
1、字段的Tab Order值
2、字段的Protect属性
3、字段的DisplayOnly属性
4、字段的Visible属性
    上述属性前3个中任意一个都可以让用户无法修改字段中的数据:最后一个属性决定字段是否可见,不可见的字段不管其他属性如何设置.用户都无法修改字段中的数据。
    当字段的Tab Order值为0时,肯定不能获得焦点,但是非0时也不一定能获得焦点,还得看字段的Protect属性是否设置为1;当字段的Tab Order值不为0,Protect属性不为1并且字段的Visible属性为True时,肯定可以获得焦点。DisplayOnly属性和焦点是否能够获得无关(即选中Displayonly时可以选中字段,可以复制,但不能更新)。

**数据保护
可以用以下三种方法将字段设置为用户不可修改的字段:
(1)在数据窗口设计时将这些字段的TabOrder值置为0,以使该字段不能获得焦点,用户无法选中和编辑该字段。
(2)将字段的DisplayOnly属性设置为True。该字段可以获得焦点,可以选中该字段,还可以拷贝复制该字段的内容,但不能编辑该字段中的内容。
(3)设置字段的Protect属性。字段的Protect属性如果设置为“1”,则该字段的TabOrder值即使不是0也不会得到焦点。使用该属性可以保护一些重要的数据。
----------


数据窗口对象的字段操作
----------
字段的编辑类型
PB提供了六种编辑类型:
1)Edit是字段的缺省编辑类型,可以用于所有类型的字段上。
2)CheckBox编辑类型在这里是一种状态选择,可以为其规定选中和非选中状态时的文字,当字段的输入内容非此即彼时,可以使用这种编辑类型。
3)DropDownDW是一种用来限制用户输入数据的非常好的编辑方式,用户只能通过选择录入数据,并且选择的数据来自其他数据窗口的某字段,从而可以确保数据的一致性和正确性。当录入外部键时,经常使用这种编辑类型。使用这种方式可以增强程序的适应性和灵活性。
4)DropDownListBox在外观上和DropDownDW类型相同,但它的数据不会发生变化,是固定的,适合用来录入诸如学历、省份、月份等范围固定的数据项。
5)EditMask经常用来录入整型或日期型数据。它底优势在于可以给用户提供清晰的数据格式,对用户的操作有很强的提示性;还可以为该编辑类型设置Spin,以便用鼠标单击上下箭头来增大或减小数据。
6)Radio Buttons在录入取值为比较小范围内的数据经常使用,用户使用鼠标进行选择操作即可录入数据,操作比较方便。
----------
字段的编辑格式
1、Limit - 限制输入长度
可以规定在该字段中输入的信息长度,缺省是字段在数据表中定义的长度。如果在数据窗口创建以后又添加了字段,这时缺省长度是0,这时用户所能输入的长度取决于编辑框的长度(如果没有设置字段的AutoHorz Scroll属性或者设置了该属性并且Limit属性为0,则用户输入的最大长度取决于编辑框所能接受的最大长度),应该手工修改其限制长度为字段在表中定义的长度。修改方法是,在字段属性窗口的Edit页Limited输入框中输入一个整数即可

2、Display Only - 不允许用户修改
选中字段对应属性窗口中的Display Only选项即可。在程序运行时,该字段中的内容可以显示,并且可以获得焦点,但是用户不能修改字段的内容,从而起到保护数据的作用。建议使用这种方式来保护字段中的数据,虽然不能编辑字段内容,但可以选中并复制,比设置字段的Tab Order值有更多的灵活性

3、Required - 必须输入
有些信息要求用户必须输入,这时可以选中字段的Required属性。不输入数据就无法离开该字段。

4、Password - 密码输入
选中字段属性窗口中Edit页上的Password属性即可,字段上数据显示为“*”号

5、Format - 格式
属性视图中Edit属性页中包含Format属性,并且还有一个专门的Format属性页。Edit属性页的Format属性可以设置字段编辑时的显示格式,Format属性页中的Format设置字段不被编辑时的显示格式。

Format的设置:

Numbers:可以使用“0”、“#”、“.”和一些算术符号来表示,使用保留字“[general]”或者“[Currency]”时,PB将使用操作系统的设置格式。关于操作系统的格式,Windows可以在控制面板的区域设置中修改。
[General]   5   -5   0.5
   5   -5   1
0.00    5.00   -5.00   0.50
#,##0    5   -5   1
#,##0.00   5.00   -5.00   0.50
$#,##0;($#,##0)   $5   ($5)   $1
$#,##0;-$#,##0   $5   -$5   $1
$#,##0;[RED]($#,##0) $5   ($5)   $1
$#,##0.00;($#,##0.00) $5.00   ($5.00)   $0.50
$#,##0.00;[RED]($#,##0.00)$5.00   ($5.00)   $0.50
0%    500%   -500%   50%
0.00%    500.00%   -500.00% 50.00%
0.00E+00   5.00E+00 -5.00E+00 5.00E-01

Strings:可以用两部分来表示该类型数据的显示,前面是必需部分,后面是NULL时表示。“@”代表一个字符。如:"[red](@@@)@@@-@@@@"

Dates:使用几个特定的字母代表特定的含义,它们的组合构成Data类型的格式。
d 表示天的数字,没有前缀0   9
dd 表示天的数字,有前缀0   09
ddd 星期几的英文缩写   Mon
dddd 星期几的英文全称   Monday
m 没有前缀0的月份    6
mm 有前缀0的月份    06
mmm 月份的英文缩写    Jun
mmmm 月份的英文全称    June
yy 两位数字表示的年份   97
yyyy 四位数字表示的年份   1997
两位的年份如果小于50,PB则认为是21世纪;大于50则认为是20世纪。比如,“85”表示的年份PB认为是“1985”年;“40”表示的年份PB认为是“2040”。

Times:使用几个特定的字母代表特定的含义,它们的组合构成Time类型的格式。
h 没有前缀0的表示小时的数字
hh 有前缀0的表示小时的数字
m 没有前缀0的表示分钟的数字,必须出现在h或者hh之后
mm 有前缀0的表示分钟的数字,必须出现在h或者hh之后
s 没有前缀0的表示秒的数字,必须出现在m或者mm之后
ss 有前缀0的表示秒的数字,必须出现在m或者mm之后
ffffff 没有0前缀的毫秒,必须出现在s或者ss之后
AM/PM 两个大写的缩写字母,代表上午和下午
am/pm 两个小写的缩写字母,代表上午和下午
A/P 一个大写的缩写字母,代表上午和下午
a/p 一个小写的缩写字母,代表上午和下午

6、Auto Selection - 自动选中
当字段获得焦点时,自动选中当前行字段中的内容,这在需要删除或者拷贝时用处比较大。选中字段对应属性窗口中Edit页上的auto selection即可。

7、设置滚动条
Auto Horz Scroll--自动横向滚动
Auto Vert Scroll--自动纵向滚动
Horz Scroll Bar --横向滚动条
Vert Scroll Bar --纵向滚动条

8、Use Code Table - 使用Code Table
使用Code Table可以自动转换用户的输入信息,也可以校验用户的输入信息是否正确。
a)选中字段的Use Code Table属性
b)在Code Table中定义代码表,该输入框中包括两列,Display Value用来进行显示,Data Value是和该显示值对应的实际值,是保存在数据库中的值。
c)选中Validate选项,从而可以确保用户的输入必须是代码表中定义了的,否则就出现报错信息。

9、Show Focus Rectangle - 显示焦点边框
焦点边框就是当字段获得焦点时,在字段编辑框的周围显示一个矩形边框,可以醒目地提醒用户当前的输入位置,这是一个比较好的界面,建议使用该属性。选中字段对应届性窗口Edit页中的Show Focus Rectangle即可。Tabular默认选中

10、Accelerator - 设置加速度
可以为字段设置加速键,以便很快捷地定位到特定的字段上。只要在字段对应属性窗口Edit页的Accelerator编辑框中输入字母或数字即可,只能输入一个字符。加速键由Alt和所输入的字母或数字构成。程序运行时,使用加速键可以将焦点马上转移到有该加速键的字段上。

11、Case - 选择大小写
可以给字符型字段指定大写、小写、还是原样显示输入内容。在字段对应的属性窗口Edit页中的Case下拉列表框中选择即可。Up代表始终大写,Any代表原样,Lower代表小写。
----------
增加和删除字段
进入数据窗口对象的SQL Select画板后可以对字段进行以下三种操作:
1、增加字段
2、删除字段
3、重选字段。取消某字段,再重新选中该字段。这看起来好像没有什么作用。实际上,这样做可以同步数据窗口对象和数据表的定义。当创建了数据窗口后又修改了该数据窗口对象对应数据表中某字段的定义,例如,增加了字段的长度,这是应该保证字段和数据窗口中的定义一致,使用上面的方法就可以做到数据的一致
*当添加字段时,PB不能正确设定新添加字段的默认属性,必须认真检查新添加的属性,最重要的属性是Limit的大小以及Show Focus Rectangle、Auto Selection和Auto Horz Scroll属性是否选中。如果数据窗口对应的数据表中既没有定义主键也没有定义唯一性索引,并且数据窗口还是用来进行数据录入的,这时不管是删除了数据窗口中的字段或添加了字段,还是重新选择了字段,都要仔细检查并重新设置数据窗口的Update属性了,如果数据表中定义了主键或者唯一性索引,就不用考虑这个问题了。
----------
字段的显示顺序
在大多数显示样式的数据窗口中都可以使用鼠标拖放直接改变字段的位置,惟独grid类型的数据窗口在Design窗口中不能。解决方法是,在预览窗口中拖动字段到适当的位置,Design窗口中的字段顺序就会自动做相应的调整。
    可以用字段名或者字段号来标识一个字段。例如,产生数据窗口的SQL语句是:
    select name,sex,address from addr_book;
    在该数据窗口中,name和#1都是指同一个字段。显示位置的调整不会影响字段号,字段号和产生数据窗口的SQL语句中字段的顺序相对应,在SQL语句中,第一个字段对应的字段号为#1,依次增加一个。要调整字段号的顺序,可以进入到SQL select画板,取消所有字段,再按照正确的字段顺序重新选择字段;或者切换到语法状态,手工修改SQL语法中字段的顺序。经过这样的调整后,可能字段在数据窗口中显示的顺序没有变化,但是字段号却进行了重新分配。因为在窗口脚本中引用数据窗口的数据时,有可能用到字段号,在数据窗口的计算域中也有可能用到字段号,所以要保证字段号正确设定,尤其是习惯使用字段号引用数据时。
----------


计算域是指在数据窗口的设计状态下添加到数据窗口中的Computed Field部件,它是一个数据窗口部件,具有部件的属性特征。计算字段是指在数据窗口对应的SQL语句中添加的表达式,计算字段是一个字段,它具有字段的属性特征。它们的区别主要体现在脚本中。计算字段因为具有字段的特征,所以SetItem等对字段操作的函数可以用来操作计算字段而不能来操作计算域,当需要在程序中动态设置值时,就应该使用计算字段而不能使用计算域,典型情况是对计算出来的值进行误差校正。这两个对象都可以使用GetItem一类的函数来读取取值。

常用函数:
条件判断
If ( boolean, truevalue, falsevalue )
Case ( column WHEN value1 THEN result1 { WHEN value2 THEN result2 { ... } } { ELSE resultelse } )

累积,(表格最右面一列各行是某列对应行前面所有行的累加和)
CumulativeSum(column{for range})
其中,column是列名、列号,或者是由列名、列号、常量、运算符,甚至其他函数构成的表达式,但取值必须是数值型的。For range是进行累积的范围。大多数显示样式的数据窗口都可以使用如下内容。
All:缺省值,累积指定列的所有取值
Group n:在指定的分组内对指定字段进行累积运算。Group是保留字,n代表组号,如1。
Page:在页范围内进行累积运算。

百分比
Percent ( column { FOR range { DISTINCT { expres1 {, expres2 {, ... } } } } } )
Percent可以用来计算某字段在指定范围内当前行的取值占该范围内该字段累计和的比例。
其中,column以及For range和上面CumulativeSum函数中的完全相同。选项DISTINCT用来指定只统计不相等的字段,表达式expresX是用来区分行是否相同的标准。该函数和表达式column/sum(column for range)是等价的。
CumulativePercent(column{FOR range})
用来计算当前的累积和占总和的比例
其中的column和for range和上面的相同。该函数和下面的表达式是等价的:
CumulativeSum(column for range)/sum(column for range)

引用不同行的数据
在数据窗口的表达式中,可以直接使用列名数组引用不同行的字段值,下标是一个相对数,相对于当前行而言的。例如,假设在数据窗口中有一列名为product_id,在数据窗口表达式中,product_id和product_id[0]是指当前行的product_id值。product_id[-1]是指前面一行的product_id值,product_id[1]是指下一行的product_id值。
    使用这种引用方法,可以很简洁地提供更友好的数据显示格式。例如,当product_id改变时,用另外一种颜色显示月份、销售量、库存量等,可以修改这些字段的颜色表达式(应该以product_id排序):
    if(getrow()=1,rgb(255,0,0),if(product_id = product_id[-1],rgb(255,0,0),rgb(255,255,255)))

数据行的修改状态
isRowNew()
isRowModified()
if(isRowNew(),'新',if(isRowModified(),'改','旧'))

其他
date
isSelected
average
count
sum


排序、过滤和分组
----------
排序
Rows->Sort
*双击Columns列表框中的字段或表达式,进入Modify Expression窗口,可以进行表达式定义,表示要使用该表达式进行排序。
上面的方法定义的排序是在客户端执行的,要在服务器端进行数据排序,可以通过修改数据窗口对应的SQL来实现。
----------
过滤
Rows->Filter
在对话框中输入表达式,在定义表达式时,有些经常使用的运算符,如like、betweem、in、match等需要特别关注一下。*特别是match具体可以在程序中测试,具体见PB帮助-match。
上面的方法同排序是在客户端执行的,要在服务器端进行数据排序,可以通过SQL语句中使用where子句,然后用带参数的retrieve来过滤。
----------
分组
Rows->Create Group
*双击“Columns”列表框中的字段或表达式,进入Modify Expression窗口,进行表达式定义。创建分组后,数据窗口中又增加了两个带(band),Header group name用来先死组名,放置用来分组的表达式或者字段;Trailer group name放置分组的总结信息。
数据窗口创建后定义的分组和使用分组样式创建的数据窗口在显示效果上相同,区别在于前面一中方式是在数据完全从服务器端传送到客户端后进行的,后一种是直接在服务器按照分组取出数据的。
*最后介绍一种方法,同样可以达到Group的效果。比如,显示各个地区产品销售情况的数据,应该使用地区作为分组。在数据窗口画板中选择窗口菜单Rows->Sort,选择以字段“region”进行排序;然后再选择窗口菜单Rows->Supress Reapting values…,指定压缩字段“region”的重复值即可。
----------


其他
----------
数据窗口中的当前页和总共页
string ls_currentPageNo
string ls_totalPage
ls_currentPageNo = dw_1.Describe("evalue('page()',1)") // ?? 获取当前页号
ls_totalPage = dw_1.Describe("evalue('PageCount()',1)") //获取总共多少页
----------
数据窗口对象的中备份和恢复数据
备份:File->Save Rows As //或Preview窗口中右键->Save Rows As
恢复:Rows->Import
[PB]-数据窗口对象(二)

获取数据窗口信息

※函数Describe
使用函数Describe可以获取数据窗口对象中的信息。该函数语法是:
dwcontrol.Describe(propertylist)
其中,dwcontrol是数据窗口控件名称,propertylist是以空格分隔的特性或运算表达式列表,它用来报告列与图形对象的属性值。表达式可以用特定行与列的值进行运算。Describe函数返回的是一个字符串,该字符串是对指定属性的描述,不同的属性占用不同的行(不同属性用~n分隔)。如果有无效属性则返回该属性之前的属性取值和一个惊叹号(!)。如果某个属性没有值,则返回一个问号(?)。
如:
dw_1.describe("datawindow.bands datawindow.objects")
header~tdetail~tsummary~tfooter~nemp_id~temp_id
dw_1.describe("datawindow.band datawindow.objects")
!
dw_1.describe("datawindow.bands datawindow.object")
header~tdetail~tsummary~tfooter!
如果特性值容易引起混淆,例如,带有感叹号、问号、Tab键或换行符,这些符号在返回字符串中将用引号括起来。为了测试这种情况,先给数据窗口中的标签name_t中输入内容为name?,然后使用下面的语句:
dw_1.describe("name_t.text")
上面的语句显示"name?",这是因为如果值列表中的第一个值用引号引着,那么该特性列表中的剩余值也用引号引着。
*标签name_t和addr_t中分别输入内容为name?和zjhz
dw_1.describe("name_t.text addr_t.text")-------"name?" zjhz
dw_1.describe("addr_t.text name_t.text")-------zjhz "name?"
*最后不显示空格(~n)


※对列的引用
在属性描述时,经常要对列进行引用。引用列的方法有两种,或者使用列名,或者使用列号。应尽量避免使用列号,因为列号是和创建数据窗口时选择字段的顺序相对应的。在以后的修改中很有可能取消某些字段或者调整字段的选择顺序,或者改变数据源,这时就很容易出现错误,更糟糕的是这时很有可能没有错误信息,张冠李戴了。
下面是一个使用列号进行属性描述的语句:
dw_1.describe("#5.coltype")
这种语法可以和函数getcolumn搭配使用,用来检索当前列号。下面是一个显示数据窗口中所有字段类型的例程:
integer li_count,li_index
li_count = integer(dw_1.describe("datawindow.column.count"))
for li_index = 1 to li_count
messagebox(string(li_index),dw_1.describe("#" + string(li_index) + "coltype"))
next

※函数Evaluate
在使用Describe描述数据窗口对象中的相关信息时,有一个非常重要的函数不能不掌握,就是Evaluate。虽然函数Describe可以获取对象的信息,但是表达式的取值就不能正常读取了,而这又是经常遇到的。所以,函数Evaluate非常重要,它可以使函数Describe获取表达式的取值。该函数的语法是:
Evalute('expression',rowno)
其中,expression是属性表达式,rowno是要描述的行号。该函数放置在Describe的属性列表中。例如,判断第3行的salary工资是否大于1000,如果大于则返回1,否则返回0,
可以使用下面的语句:
dw_1.describe("evaluate('if(salary > 1000,1,0)',3)")
而使用下面的语法就是错误的:
dw_1.describe("if(salary > 1000,1,0)")
*单行(如第二行)
dw_1.describe("evaluate('if(isnull(emp_no) or emp_no = '',~~'*~~',emp_no)',2)")
*多行
long ll_i
string ls_emp
for ll_i = 1 to dw_1.rowcount()
ls_emp = dw_1.describe("evaluate('if(isnull(emp_no),~~'NULL~~',emp_no)'," + string(ll_i) + ")")
dw_1.setitem(ll_i,'emp_no',ls_emp)
next

※函数LookUpDisplay
字段使用了下拉列表框、下拉数据窗口和单选按钮等有代码表的编辑风格时,在数据窗口控件上显示的值和字段实际得到的值并不相同,使用函数GetItemX只能读取这样的字段的真实取值,而不是用户看到的值。如何才能读取用户看到的值?可以使用函数LookUpDisplay。
LookUpDisplay函数不能直接从PowerScript调用,可以在Describe和Evaluate函数配合使用。因为函数LookUpDisplay不能指定对哪行数据进行操作,它的参数只有一个字段名称,所以必须和Evaluate函数配合使用。该函数的语法是:
    LookUpDisplay(columnname)
其中,参数columnname是字段的名称,而不是一个字符串。函数执行错误则返回空字符串。
    下面是一个和函数GetItemString相比较的例子。假设在一个数据窗口中定义字段sex的编辑风格为DropDownListBox,定义该字段使用编码表,编码表的定义是显示值“Male”,“Female”分别对应“男”和“女”。然后,在某个按钮的clicked事件中编写如下脚本:
messagebox("getitemstring:"+dw_1.getitemstring(1,"sex"),"lookupdispaly:"+dw_1.describe("evaluate('lookupdisplay(sex)',1)"))
::getitemstring:男
::lookupdisplay:male


〓修改数据窗口信息
为了在运行时修改数据窗口对象特征,应该使用Modify函数,而不是直接访问语法。该函数的语法如下:
dwcontrol.Modify(modstring)
其中,dwcontrol是数据窗口控件名称,既可以是数据窗口也可以是子数据窗口,还可以是datastore对象。modstring是修改字符串,用来指示要修改哪些对象的哪些属性。如果修改成功函数则返回空字符串,如果修改的语法错误则返回对错误的描述,格式是:line n Column incorrect syntax,这里是第n列是从modstring开始计数的错误位置。
数据窗口对象可以在运行时使用合适的语法修改其外观、行为和数据库信息。通过提供完整的对象规范,甚至可以在数据窗口对象内部创建和删除对象。
使用modstring参数可以指定Create、Destroy和Attribute alteration三种类型的语句。

※创建对象
可以使用下面的语法来添加对象(如文本、计算域以及位图):
Create object(settings)
其中,settings为将要创建的对象定义的一组特性和值,定义对象时,用户必须提供足够的信息。
想要得到某个对象的正确语法的最好的方法就是导出一个包含对象的简单的数据窗口。然后就能把对象的语法剪切并粘贴到应用程序中。另一种办法是使用那些能成为数据窗口内特定对象显示语法的许多工具之一(它们正变得越来越商业化)。
下面的示例用来说明这种格式,假设用户刚刚从头开始动态地创建了一个完全新的数据窗口,现在需要在标题头放置一个公司标志,其语法是:
string ls_modify,ls_result
ls_modify = "Create bitmap(band = background filename = 'c:\logo.bmp' x = '60' y = '8' width = '1308' height = '513' border = '0' name = logo)"
ls_result = dw_1.modify(ls_modify)
if ls_result <> "" then
messagebox("提示",ls_result)
end if
这段代码为用户刚刚创建的报表数据窗口在恰当的位置创建标识。

※删除对象
除了可以在数据窗口内创建对象外,还可以使用下面语法删除对象:
Destroy [Column] object
这里的object是数据窗口对象内要删除对象的名字。若要把列和列的数据从缓冲区中删除,需要指定Column关键字。
例如,上一个示例中向动态创建的报表中添加了一个公司标志。如果用户把这一功能作为运行时的选项,比如说通过复选框,那么就不仅需要能够创建对象而且还需要删除该对象。下面是用于删除的代码:
string ls_result
ls_result = dw_1.modify("destroy logo")
if ls_result <> "" then
messagebox("错误",ls_result)
end if
下面的示例使用这种modify格式删除列及其相关的标签:
string ls_result
ls_result = dw_1.modify("destory column salary destroy salary_t")
if ls_result <> "" then
messagebox("错误",ls_result)
end if

※特性修改
Attribute alteration 类型的语句格式是modify三种格式中最常用的一种,这种语法的格式如下:
objectname.attribute = value
按照被影响的attribute的不同,value可以是下面类型中的任何一种:
a)常量:指简单的、不使用表达式的特性修改值。如:
columnname.band = footer
b)带引号的常量:也是指简单的特性修改值。如:
columname.height = '65'
c)表达式:由一个默认值及其后的表达式组成,它的返回值与特性的数据类型相同。如:
'167725~tif(emp_status=~'A~',255,16777215)'
请注意这种表达式的格式。整个表达式括在单引号中,表达式需要缺省值,而且该值通过Tab键(~t)与余下的表达式隔开。表达式返回0或者1,它们是特性的有效值。
在实际使用时,这种格式的语句经常简单写成属性访问格式。如:
dw_1.modify("oval_1.background.color = rgb(255,0,128)")
和以下直接属性访问方式是等价的:
dw_1.object.oval_1.background.color = rgb(255,0,128)


〓字段和计算域的属性-更多见帮助(DataWindow object properties)

*获取字段的类型(Coltype属性)
字段的ColType属性是一个非常有用的属性,使用该属性可以在程序运行时获取字段的类型。但是不能在运行时修改该属性。下面是它的语法:
直接引用:dw_1.object.object.objectname.coltype
在Describe函数中:"objectname.coltype"
不管使用哪种方式,对同一个字段获得的类型都相同。字段类型有char(n),date,datetime,decimal(n),int,long,number,real,time,timestamp及ulong共11种,其中的n代表字符的长度或者小数后的精度。
如:
ls_coltype = dw_1.objcet.emp_id.coltype
ls_coltype = dw_1.describe("emp_id.coltype")
在实际编程中,获取字段的类型后,紧接着使用choose case语句针对不同的类型进行相关的处理。

*背景属性(background.property)
在运行时修改字段的背景,这是标识特殊数据行的一种手段。使用该属性可以在程序运行时获取字段的背景,也可以修改字段的背景。它的语法如下:
直接引用:dw_1.object.objectname.background.property
在Describe和Modify函数中:"objectname.background.property{ ='value'}"
其中,property可以是color或者mode。当为color时取值应该是长格式表示的颜色,或者使用RGB函数中红、绿、蓝表示的颜色;当为mode时,0表示将背景设置为不透明的(即可以显示背景颜色),1表示背景为透明的。
实际上,字段的背景属性也可以在数据窗口画板中进行设定。下面是修改和读取字段背景属性的实例:
//修改字段的背景颜色
dw_1.object.oval_1.background.color = rgb(255,0,128)
dw_1.modify("emp_name.background.color = '11665407'") //这里好象不能用rgb()
//读取字段的背景颜色
ls_data = dw_1.describe("oval_1.background.color")
//读取字段的背景模式
ls_data = dw_1.describe("emp_name.background.mode")
//设置字段的背景模式
dw_1.modify("emp_name.background.mode = '1'")
dw_1.modify("mdrect_1.background.mode = '0'")

*指定检索规则(Criteria.property属性)
在脚本运行时,可以控制是否显示检索规则窗口或者读取数据窗口这方面的信息。语法如下:
直接引用:dw_1.object.columnname.criteria.property
在describe和modify函数中:"columnname.criteria.property{ = value}"
其中,dw_1是数据窗口控件名称,columnname是要获取或者设置检索规则的字段名称,value为yes或者no,property是以下属性:
a)Dialog:是否显示检索规则窗口。取值为yes则显示,取值为no则不显示。如,在一个数据窗口中放置了字段name,可以编写如下脚本:
dw_1.modify("name.criteria.dialog = yes sex.criteria.override_edit = yes")
dw_1.retrieve()
脚本运行,显示检索规则输入窗口
b)override_edit:是否用户必须在检索规则窗口中输入数据。取值为yes则用户必须输入数据,取值为no时用户可以不输入数据。
c)required:是否用户只能使用等号进行查询。如果取值为yes则用户的输入只能是等号,如果取值为no则用户可以使用各种符号,包括=、<>、>、>=、<=、<等。

*Edit风格的字段属性(Edit.property属性)
编辑风格为Edit类型的字段,可以通过edit.property来获取其相关信息或者设置其外观及动作。下面是它的语法:
直接引用:dw_1.object.columnname.edit.property
在describe和modify函数中:"columnname.edit.property{ =value}"
其中,columnname是哟啊读取或者设置属性的字段名称,value根据property不同而可以使用不同类型的值。property可以有17个取值,其中:
a)和滚动控制有关的有AutoHScroll,AutoVScroll,HscrollBar和VscrollBar,它们的取值都是yes或者no,表示是否显示该滚动条。
b)和显示的内容有关的属性有Case,CodeTable,Format,NillsNull和Password,这些属性用来控制字段中的内容如何显示。Case的取值为Any,Upper,Lower与Painter,表示不管用户在该字段上输入的大小写,都按照该属性自动进行转换。CodeTable的取值为yes或者no,表示该字段是否有代码表。Format规定对用户输入的内容进行格式化时应该采用的格式。NillsNull的取值为yes或者no,表示当用户在字段中不输入内容而离开该字段时,是否将该字段中的内容自动置为NULL。Password属性的取值也是yes或者no,表示是否将用户的输入作为密码样式显示,如果作为密码则用户的输入内容作为*号显示,显示的个数和用户输入字符个数相等。
c)和编辑控制有关的属性有AutoSelect,DisplayOn1y,FocusRectangle,Limit,Required,Style和ValidateCode,除了Limit取值为正整数、Stylee取值为String类型外,其他属性的取值都是yes或者no。AutoSelect属性表示当字段获得焦点时是否自动选中该单元中的内容。Display0nly表示是否允许用户修改该字段中的内容,如果取值为yes,则用户虽然可以选中该字段中的内容但是不能修改。FocusRectangle表示当字段获得焦点时是否显示矩形的边框,以表示当前焦点的位置。Limit是一个相当重要的属性,用来限制用户可以输入字符的长度。Required属性如果为yes,则在获得焦点后用户不输入内容就休想离开。虽然该属性可以很好地保证非空字段不为空,但该属性非常不友好,建议慎重使用。Style属性在程序运行时不能修改,只能读取其中的信息。该属性返回的是关于字段的编辑风格。ValidateCode属性表示是否使用代码表进行有效性校验。该属性当CodeTable属性为yes时才有效。
下面是关于该属性的一些实例:
ls_setting = dw_1.objcet.emp_name.edit.autohscroll //是否允许自动横向滚动
ls_setting = dw_1.describe("emp_name.edit.Autohscroll") //同上
dw_1.object.emp_name.edit.required = "no" //将字段设置成必须输入的字段
dw_1.modify("emp_name.edit.required = no") //同上

*字段的显示格式(Format属性)
可以使用Format属性来指定字段的显示格式。但是,在实际编程中使用更多的是函数GetFormat或者SetFormat,以取代Modify或者Descrie来设置字段的显示格式。
该语法使用时的重点在于格式串的使用。下面是相关的语法:
直接引用:dw_1.object.objectname.format
在函数describe和modify中:"objectname.format{='value'}"
其中,objectname是字段或者计算字段或者计算域的名称value是字符型的表达式,取值是一种格式串。下面是一些使用实例:
ls_setting = dw_1.object.phone.format //读取字段的电话显示格式
ls_setting = dw_1.describe("phone.format")
dw_1.object.shipdate.format = "yyyy-mm-dd" //设置日期格式
dw_1.modify("shipdate.format = 'yyyy-mm-dd'")

*设置数据窗口修改时的主键(key属性)
该属性在一个数据窗口修改多个表时非常有用,因为这时必须根据要修改的表动态修改主键,属性key就可以实现该功能。该属性使用时的语法如下:
直接引用:dw_1.object.columnname.key
在函数modify或者describe中:"columnname.key{=value}"
其中,columnname是要作为主键的字段名,或者是要判断是否为主键的字段的名称;value取值为yes或者no。如:
ls_setting = dw_1.object.empid.key //判断字段empid是否为主键
ls_setting = dw_1.describe("empid.key")
dw_1.object.empid.key = "yes" //将字段empid作为主键
dw_1.modify("empid.key = yes")

*字段名称(name属性)
使用name属性可以获取字段的名称。可以使用字段号或者字段名称来标识一个字段,但使用字段号不太安全,所以用获取字段名比较好一些。语法如下:
直接引用:dw_1.object.objectname.name
在函数describe中:"objectname.name"
其中,objectname是要获取名称的控件标识,因为在数据窗口对象中有很多控件有多种标识方法。如,下面可以获取字段号为1的字段的名称:
dw_1.describe("#1.name")

*字段中的数据保护(protect属性)
该属性表示是否对字段中的数据进行保护,取值为0或者1。1表示实行保护,0表示不保护。当进行数据保护时,即使字段的TabOrder值大于0用户也不能对字段进行编辑,并且该字段都不能获得焦点(和TabOrder取值为0时的表现完全相同)。下面是该属性使用时的语法:
直接引用:dw_1.object.columnname.protect
在函数describe和modify中:"columnname.protect{='integer'}"
其中,columnname是要获取或者设置protect属性的字段的标识,integer取值为0或者1。
下面是使用实例:
ls_setting = dw_1.object.emp_start.protect //获取字段emp_start的protect属性取值
ls_setting = dw_1.describe("emp_start.protect")
dw_1.object.emp_start.protect = 1 //设置字段emp_start的protect属性
dw_1.modify("emp_start.protect = 1")
dw_1.modify("emp_start.protect = '1~tif(isrownew(),0,1)'")
//设置protect属性为表达式,含义是:如果是新数据行则将protect设置为0,否则设置为1//,缺省为1。

*字段的滑动属性(slideleft和slideup)
使用字段的滑动属性可以更好地根据运动时的情况安排数据的布局。有两个和滑动有关的属性,SlideLeft表示当左面空白时是否向左滑动,SlideUp表示当上面出现空白时是否向上滑动。使用该属性的语法是:
直接引用:
dw_1.object.objectname.slideleft
dw_1.object.objectname.slideup
在函数describe和modify中:
"objectname.slideleft{='value'}"
"objectname.slideup{='value'}"
其中,slideleft中的value取值为yes或者no。slideup中的value取值为:
a)AllAbove:当上面数据行中的所有 对象都为空时向上滑动
b)DirectlyAbove:当上面和本对象对应位置的对象为空时向上滑动
c)No:不进行滑动
下面是应用的实例:
dw_1.object.emp_lname.slideup = 'no'
ls_setting = dw_1.describe("graph_1.slideup")
dw_1.modify("emp_lname.slideup = no")

*字段的TabOrder值(TabSequence属性)
字段的TabOrder值是一个比较重要的属性,取值大于0时用户可以编辑该字段,等于0时无法编辑该字段。在运行时,根据程序的运行情况有可能动态修改字段的TabOrder值,这时可以使用TabSequence属性。该属性应用时的语法如下:
直接引用:dw_1.object.columnname.TabSequence
在函数modify或Describe中:"columnname.TabSequence{=number}"
其中,number为从0到32000的正整数,当为0时表示字段不允许编辑。下面是使用实例:
ls_setting = dw_1.object.emp_name.tabsequence //获取字段的TabOrder值
ls_setting = dw_1.Describe("emp_name.tabsequence")
dw_1.object.emp_name.tabsequence = 10 //设置字段的taborder值
dw_1.modify("emp_name.tabsequence = 10")
实际上,在编程时经常使用函数SetTabOrder来设置或者获取字段的TabOrder值,因为该函数正确执行后,字段被设置成指定的TabOrder值,并且返回设置之前的TabOrder值。

*用户是否可以保存字段内容(update属性)
当数据窗口中的数据提交时,可以修改的字段及其对应的数据用来产生update SQL语句,使用该SQL语句进行数据的保护。所以,在程序运行时,如果不希望用户保存某字段中的数据,可以修改字段的update属性。下面是该属性的语法:
直接引用:dw_1.object.columnname.update
在函数modify或者describe中:"columnname.update{=value}"
其中,value的取值为yes或者no。下面是使用实例:
ls_setting = dw_1.object.emp_name.update //获取字段是否可以修改
ls_setting = dw_1.describe("emp_name.update")
dw_1.object.emp_name.update = "no" //使字段emp_name不能修改
dw_1.modify("emp_name.update = no")
在应用时,可以根据用户的权限,或者根据用户的录入数据是否齐全(通常需要保证数据一致性)来动态修改某些字段的update属性。另外,在一个数据窗口修改多个数据表时也经常使用该属性。

*字段校验(Validation和ValidationMsg属性)
字段的校验规则在数据窗口画板中可以指定,但有时需要在程序运行时动态地修改,可以使用Validation和ValidationMsg属性来指定。属性Validation使用时的语法如下:
直接引用:dw_1.object.columnname.validation
在函数describe和modify中:"columnname.validation{='validationstring'}"
其中,validaionstring是一个包含校验规则的字符串,该字符串的结果或者是True或者是False。下面是使用实例:
ls_setting = dw_1.object.emp_status.validation //获取字段的校验规则
ls_setting = dw_1.describe("emp_status.validation")
dw_1.modify("sex.validation = 'sex = ~~~'f~~~' or sex = ~~~'m~~~''") //设置规则
dw_1.object.sex.validation="sex='f' or sex='m'"
字段的校验规则设置好后,用户在该字段上输入数据并要离开时,如果数据不能通过校验则显示错误信息,采用系统缺省的错误信息不太友好。这时,可以通过设置validationgMsg属性来指定错误信息。该属性使用时的语法如下:
直接引用:dw_1.object.columnname.validationMsg
在函数describe和Modify中:"columname.validationMsg{='string'}"
其中,string为数据不能通过校验规则时要提示的信息。如:
dw_1.object.sex.validationgmsg = "性别必须为f或者m!"
实际上,当用户输入的数据不能通过校验规则时将触发数据窗口控件的itemerror事件,该事件的返回值可以决定是否显示错误信息提示窗口。如果在itemerror事件中也编写了错误信息提示脚本,该脚本能够正常执行并且用validationgmsg属性定义的错误信息也会显示。

*计算域的属性
计算域除了具有上面介绍的属性外,还有一个重要属性Expression。使用这个属性可以根据用户的执行情况来更好地调整程序的动作,下面是其使用时的语法:
直接引用:dw_1.object.computename.expression
在函数modify和describe中:"computename,expression{='string'}"
其中,computename是计算域的名称,string是字符串,它应该包含合法的表达式。如:
ls_setting = dw_1.object.comp_1.expression //获取表达式
ls_setting = dw_1.describe("comp_1.expression")
dw_1.object.comp_1.expression = "avg(salart for all)" //设置表达式
dw_1.modify("comp_1.expression = 'avg(salary for all)'")


〓Button重要属性
*Action属性
该属性是Button控件最重要的一个属性。在数据窗口画板中,可以选择一个按钮有哪个动作。可选的动作都是事先定义好的,开发人员没有机会精确定义某个动作的执行,只能在运行时动态改变按钮的动作。
    可以在设计时指定按钮的动作。在按钮属性窗口的General属性页,下拉列表框Action
中可以选择可用的动作。
    在程序运行时可以使用Action属性来获取或者修改按钮的动作。该属性使用时的语法如
下:
    直接引用:dw_1.object.buttonname.action
    在函数Describe和Modify中:"buttonname.action{='value'}"
其中,buttonname是要获取或者设置动作的按钮的名称;value是动作代码,可以是下拉列表框Action中的值。
代码 动作   解释     返回值
11 AppendRow 在最后增加一空白行   新增加行的行号
3 Cancel   取消使用了yield函数的检索过程 0
10 DeleteRow 如果按钮在detail带中则删除按钮 成功返回1,否则-1
    ,否则删除当前数据行。
9 Filter   显示Filter对话框,   过滤掉的数据行数。
    并在指定条件后进行检索   如果发生错误则返回小于0的数
12 InsertRow 如果按钮在detail带中,则以按钮 新插入行的行号
    所在行为参数插入数据,否则在当
    前行插入一空白行
6 PageFirst 翻到第一页    成功返回1,否则返回-1
7 PageLast 翻到最后一页    最后一页中第一行的行号。
        如果失败则返回-1
4 PageNext 翻到下一页    同上
5 PagePrior 翻到前一页    同上
16 Preview   进入、退出预览状态   0
17 PreviewWithRulers 打开或者关闭标尺   0
15 Print   打印一份数据窗口   0
20 QueryClear 删除where子句    0
18 QueryMode 进入、退出查询模式   0
19 QuerySort 指定查询时的排序规则   0
2 Retrieve 从数据库中检索数据   检索到的记录数
1 Retrieve(Yield) 从数据库中检索数据,并随时允许 检索到的记录数
    用户终止
14 SaveRowsAs 以用户指定的格式保存数据 记录数
8 Sort   显示排序窗口并按指定规则排序 成功则返回1,否则-1
13 Update   将修改了的数据保存到数据库。修 成功则返回1,否则-1
    改成功则自动执行commit,否则执
    行rollback
0 UserDefined 允许为按钮的ButtonClicked和 用户脚本中定义的返回值
    ButtonClicking事件编写脚本

*SuppressEventProcessing属性
SuppressEventProcessing属性用于是否触发ButtonClicked事件或者ButtonClicking事件。
语法格式是:
直接引用:dw_1.object.buttonname.suppresseventprocessing
在函数describe和modify中:"buttonname.suppresseventprocessing{='value'}"
其中,value的取值为yes或者no,表示是否触发事件。如:
dw_1.object.b_name.suppresseventprocessing = 'yes'
dw_1.modify("b_name.suppresseventprocessing = 'no'")
ls_setting = dw_1.describe("b_name.suppresseventprocessing")

*Text属性
通过Text属性可以获取或者设置按钮上的文字。当运行时,如果要动态修改按狃的Action属性,就应该利用Text属性修改。该属性使用时的语法如下:
直接引用:dw_1.object.textname.text
在函数modify和describe中:"textname.text{='string'}"
其中,string是一个字符串或者表达式,如果要给按钮设置快捷键,可以在字符串中使用&符号。如:
ls_setting = dw_1.object.text_1.text //获取按钮上的文字
ls_setting = dw_1.describe("text_1.text")
dw_1.object.text_1.text = "employee &Name" //给按钮设置文字,并有快捷键
dw_1.modify("text_1.text = 'employee &Name'")

=====================================

powerbuilder数据窗口技巧(一)

1 使DataWindow列只能追加不能修改
如何使DataWindow中的数据只能追加新记录而不能修改,利用 Column 的 Protect 属性可以很方便的做到这一点,方法如下:
将每一列的 Protect 属性设置为:
If( IsRowNew(), 0, 1) )
在 PowerScript 中可以动态修改 Protect 属性:
dw_1.Modify("column_name_here.Protect='1~tIf(IsRowNew(),0,1)'")
这样,DataWindow 中只有新追加的记录可修改,而其他记录是只读的。

2 如何在DataWindow中实现列的自动折行
我们在PowerBuilder应用程序的开发过程中, 使用DataWindow时, 经常会遇
到某列的数据太长, 不能同时全部显示的情况. 若采用自动水平滚动, 操作起
来又不够简便. 下面介绍一种方法, 实现列数据多行显示, 即实现列数据的自
动折行.具体步骤如下:
1) 在DataWindow Painter中打开此DataWindow.
2) 在需设定自动折行的列上双击鼠标, 弹开此列的属性窗口.
3) 选择Position标签, 选中Autosize Height 多选框.
4) 选择Edit标签, 不选中Auto Horz Scroll多选框.
5) 单击OK按钮, 保存所做的修改.
6) 点中Detail Band (即写有Detail的灰色长带), 单击鼠标右键, 选择
Properties... 菜单项.
7) 选中Autosize Height多选框.
8) 单击OK按钮, 保存所做的修改.
9) 保存此DataWindow.
注意:
连在一起的汉字(中间没有标点或空格分隔), 系统将认为是一个单词, 不
会自动进行折行.

3 在数据窗口中实现动画
要实现动画,必须要有定时器,在数据窗口中已经有了一个定时器,双击数据窗口将弹出的对话框,在Timer Interval中定义大于零的值就有定时器(可以精确到毫秒),有了这个定时器就可以实现动画了。比如要改变某字段的背景颜色,可设
ackgound.color=RGB(Integer(Right(string(now(),'hhmmssf'),1))*256/10,Integer(Right(string(now(),'hhmmssf'),1))*256/10,0)
  当然,您不仅可以改变背景颜色,而且可以改变字体等等任何属性,使他可以动起来!

4 使数据窗口中的被选中行具有更好的外观
大家都知道,在选择数据窗口中的某一行时,如果使用pb提供的选择函数SelectRow(),那么的外观真是不能恭维,单调而古板的蓝色背景,可能和您的漂亮而生动的应用程序格格不入。有没有办法改变呢?当然有啰,请听我慢慢道来。
   改变某一行的背景比较简单,改变每一列的背景属性(backgroundcolor)即可,可要根据鼠标选择情况自动改变,并可以返回被选中的行可能还需要一定的技巧。下面分单行选择和多行选择分辨说明。
单行选择
  单行选择比较简单,我们只要将所有字段的背景色的表达式改为:
if(GetRow()=CurrentRow(),RGB(255,126,0),RGB(0,0,0))
  其中第一个颜色为被选中的颜色,第二个颜色未被选中的颜色。然后用GetRow()代替GetSelectedRow()函数来得到被选中的行。 
多行选择
  多行选择比较复杂,如果单纯依靠改变数据窗口的属性没法实现,我们必须使用数据窗口属性和代码结合起来才能实现
  首先,改变数据窗口的SQL语句,增加一个计算字段:0 as flag,Select 语句改为:
Select col1,col2 ,1 as flag from tablename where .....,
  当返回数据窗口painter时,您就会发现多了一个字段flag,我们就是利用这个字段保存行被选中的信息。
  其次,修改各个字段的背景颜色属性,设置为:if(flag=1,RGB(255,126,0),RGB(255,255,255))
  第三:在数据窗口控件中,增加对clicked 事件的处理,代码如下:
if row<1 then return // setredraw(false)
if this.o b j e c t.flag[row]=1 then //如果该行被选中,撤销选择,否则选中该行
 this.Object.flag[row]=0
else
 this.Object.flag[row]=1
end if
setredraw(true)

您还可以定制本选中行的字体,文本属性等等。原理相同,不再赘述。

5 将日期型字段初始化为当天的日期
   使用 Column Specifications 对话框来设置数据的初始值是一个比较好又比较通用的方法。 为了将日期型字段初始化为当天的日期,只要设置初始化值为today,而不是today()即可。同样设置初始值为NUll,可以使用null,而不是 null()。

6 在DataWindow中调整列顺序
在 Gird 风格的 DataWindow 中,列的排列顺序是按照你选择 Column 的顺序排列的,并且不能改变.要改变列的顺序则必须重新制作 DataWindow.
最近我发现一个办法可以改变列的顺序: 在 DataWindow 画板中打开要修改的 DataWindow,然后按 'Preview' 按钮切换到预览模式下,选择要移动的列标题并拖动到预定位置,然后返回 DataWindow 画板,存盘即可.

7 Retrieve时不清除原有Datawindow数据
当你调用Retrieve函数,PowerBuilder自动清除原有DataWindow然后Retrieve数据。在Datawindow RetrieveStart事件中,使用Return 2,这样PowerBuilder不会清除原有数据而是追加新数据。

8 美化DataWindow的显示效果
使DataWindow 的单双行显示颜色不同,不仅仅可以使你的应用程序更显专业性,并使数据的可读性增强。先调出你需要改动的DataWindow,在Detail band按下右键选择Properties,选择Tab页中的Expressions,在color属性中输入下面内容:(注意是在Detail明细显示 段按右键,而不是在Column上) IF(MOD(GETROW(),2)=0,RGB(192, 192, 192), RGB(255, 255, 255)) 马上Preview一下,看一看效果如何。

9 用Line建立漂亮的Grid DataWindow的技巧
虽然PowerBuilder有Grid风格的DataWindow,但不够灵活,如果想打印一张边框粗线条或双线,内框为细线条的表格直接使用Grid风 格的DataWindow就不能实现。因此许多人都用Tabular风格的DataWindow,然后自己用Line来实现Grid。 在调整线条位置是一个即伤脑筋又伤眼睛的事件,而一旦需要调整行高,所有工作都得重来,试一试用下面方法,会大大减轻你的工作量: 在vertical lines,改变它的属性,在Expressions Tab上,y1行上输入0,y2行上输入rowheight() - 1 在horizontal lines, 设置 y1 和 y2 = rowheight() - 5 这样PowerBuilder会自动调整线的坐标,你只需要设置横线的长度和x1,x2的坐标即可。 马上Preview一下,看一看效果! 你再也不需要因为行的高度发生改变而重新调整线条位置。

10 如何创建一个报表,如下形式
Quantity Running Total
5,000 5,000
2,500 7,500
3,000 10,500
12,000 22,500
  对于Running Total列,我们可使用计算列:CumulativeSum(Quantity for all),即可达到逐渐递增求和的功能。

11 数据窗口的数据送缓冲区之前确认的四个步骤 判断数据类型是否正确。如不正确则触发ItemError事件。判断数据是否符合有效性规则。如不符合有效性规则,同样触发ItemError事件。 判断是否有数据被改动。判断数据是否通过ItemChanged事件,如果数据和ItemChanged相斥,将触发ItemError事件。

12 如何在DataWindow中用数据类型为Datetime的列为条件进行查找
  1.当要查找的日期条件是一常数时使用如下表达式:
   ls_Find = "datetime_col
    = DateTime ('1/1/1999')"
  2.当要查找的日期条件是一个变量时使用如下的表达式:
   ls_Find = "datetime_col = DateTime ('" + ls_Date + "')"
  3.当要查找的日期条件是一个DateTime数据类型时使用如下表达式:
   ls_Find = "datetime_col = DateTime ('" + String (ldt_DateTime) + "')"

13 设置数据窗口Boolean型属性的三种方法
  PowerBuilder提供了三种方法设置数据窗口的布尔型属性,分别是True/False, 1/0, 'Yes'/'No'。例如:
dw_1.Object.address.Visible = 0 dw_1.Object.address.Visible = False dw_1.Object.address.Visible = 'No'
  PowerBuilder在处理上以字符串的形式保存属性,而不考虑属性值是布尔型、长整型或是字符型。
为了进一步理解,可以导出一个数据窗口并查看它的原码,可以发现即使是列的颜色属性它也是使用带双引
号的数字来表达。

14 如何在DataWindow中快速删除多行
  在开发过程中可能经常有要进行多行删除的操作,一般都使用循环语句进行操作:
FOR ll_RowOn = 1 TO dw_1.RowCount() dw_1.DeleteRow(ll_RowOn) NEXT
  一个快速的删除方法是把要删除的行从主缓冲区中移到删除缓冲区中。例如,删除缓冲区中所有的行:
dw_1.RowsMove(dw_1, 1, dw_1.RowCount, Primary!, dw_1, 1, Delete!)
  不过不要忘了过滤的行在不同的缓冲区中。

15 如何在DataWindow的SQL语法中不使用SELECT DISTINCT实现删除重复的行
  起先对你要显示唯一值的列进行排序:"city A",然后增加如下过滤字符串:" city < > city [-1] or GetRow () = 1"

16 如何在分组形式的DataWindow中分别显示各组的行号
  当我们为Datawindow的每一行显示行号时,可以简单的放一个表达式为GetRow()计算列。但是对于分组的Datawindow,要分别显示各组的行号,则应使用表达式为
GetRow() - First(GetRow() for Group 1) + 1的计算列。

17 如何改变列的字体颜色,提醒用户此列已做修改
  在列的Color属性中,输入如下表达式
IF (column_name < >column_name.Original, RGB(255, 0, 0), RGB(0, 0, 0))。
  在这个条件中,如果此列已改变,则显示红色字体,否则显示黑色字体。这个表达式主要用column_name < > column_name.Original比较当前列的值和原始列的值是否相同来达到判断的目的。

18 在数据窗口中移走行,但不是去做过滤或删除操作
  RowsDiscard()函数可做到这一点,它在数据窗口中执行移除工作,但被移走的行它不可被删除或做任何修改性的保存。

19 如何在多行显示的DataWindow 中的Footer Band中显示当前数据的首行和最后行的行号
  我们先看两个计算列的表达式: IF (GetRow() = First(GetRow() FOR Page), 1, 0) // 1 为当前页的第一行
IF (GetRow() < > 1 AND GetRow() = Last(GetRow() FOR Page), 1, 0) // 1 为当前页的最后一行
  由上面可知,在Footer Band中设置如下计算列表达式:
'Rows ' + String(First(GetRow() FOR Page)) + ' to ' + String(Last(GetRow() FOR Page)) + ' are displayed'。
即可达到这项功能。

20 使可编辑的数据窗口只读
有时,你可能需要将一个用于编程的数据窗口用作显示目的,可以有以下几种方法来实现这一要求:
1.建立两个数据窗口,一个用于编辑,一个用于显示
2.将数据窗口中的全部对象的taborder设置为0.
3.也可以将数据窗口中的列的protect属性设为On或Off,但你不能使用protect属性进行编辑操作
4.数据窗口有一个将datawindow设为只读的属性(readonly),使用它最方便。

 

powerbuilder数据窗口技巧(二)

21 数据窗口检查重复行
dw_1.SetSort ("user_id A")
dw_1.Sort()
dw_1.SetFilter ("user_id = user_id[-1]")
dw_1.Filter()
if dw_1.RowCount() > 0 then
Messagebox("注意", "用户编码重复.")
end if
dw_1.SetFilter ("")
dw_1.Filter()

22 如何在分组形式的DataWindow中分别显示各组的行号
---- 当我们为Datawindow的每一行显示行号时,可以简单的放一个表达式为GetRow()
---- 计算列。但是对于分组的Datawindow,要分别显示各组的行号,则应使用表达式为
GetRow() - First(GetRow() for Group 1) + 1的计算列。

23 如何能让数据窗口的某几列在其他列横拉时固定不动
           
// 功能说明:用于冻结左边的滚动栏
// 变更记录: 变更或版本更新的时候
//   

int i
if pane = 1 then
i = integer(this.o b j e c t.datawindow.horizontalscrollposition 2)
if i < 1 or isnull(i) then return
if scrollpos > 0 then
this.o b j e c t.datawindow.horizontalScrollPosition  = 0
end if
else
i = integer(this.Object.DataWindow.HorizontalScrollSplit)
if i < 1 or isnull(i) then return
if i > scrollpos then
this.o b j e c t.datawindow.horizontalScrollPosition 2 = i
end if
end if

24 在数据窗口中如果要使其中一列的属性为只读,也就是不允许用户修改,那么只需简单地将这一列的Table Order 设置成0就可。然而,在有些情况下
需要对这一列的某些行修改,而某些行不能修改,这就要用到这一列的protect属性了。打开列的属性中的Expressions,在protect中输入条件判别
式。例如:允许用户修改新增加的记录,而检索出来的记录则不允许修改。条件判别式可以写成如下:
if(isRowNew(),0,1) 
在 PowerScript 中可以动态修改 Protect 属性:
dw_1.Modify("column_name_here.Protect='1~tIf(IsRowNew(),0,1)'")
这样,DataWindow 中只有新追加的记录可修改,而其他记录是只读的。

25 控制DATAWINDOW里每页显示的行数
1、在Datawindow中增加一个计算域,起名为:ceil_page,此计算域必须放在Detail段中,
Expression中输入 ceiling(getrow()/25) 25表示每页打印25行,也可以是一个参数。
2、分组,选择菜单RowsCreate Group,选择ceil_page
按ceil_page分组,并选中New Page On Group Break(意思是新组开始时换页)。
3、将此计算域设为隐藏(在属性页中的expression页中在visible属性中写0)。
4、补空行:
在窗口的open事件中写如下代码:
long li_count,li_i
li_count=dw_1.retrieve()
if mod(li_count,25)<>0 then
for li_i=1 to 25 - mod(li_count,25)
dw_1.insertrow(0)
next
end if

26 数据窗口的closeQuery事件:提示保存数据
dw_1.AcceptText()
IF dw_1.ModifiedCount() + dw_1.DeletedCount() > 0 THEN
CHOOSE CASE MessageBox("操作提示","数据已经发生变化,是否保存?",Question!,YesNoCancel!,1)
CASE 1
cb_save.TriggerEvent(clicked!)
CASE 2
Return 0//不做任何操作直接关闭窗口
CASE 3
Return 1//不会运行Close Event,维持原来的情况
END CHOOSE
END IF

27 Getchild函数主要被用来得到一个数据窗口的子数据窗口
该函数在两种情况下可以使用,1、取出数据窗口对象的下拉式数据窗口;
                            2、取出复合风格(composite)数据窗口对象里所嵌入的子数据窗口对象。
语法:integer dwcontrol.GetChild (string name, REF DataWindowChild
     dwchildvariable )

例子1 这段程序取出一个composite数据窗口对象的两个子数据窗口,并对他们进行过滤,和排序的操作。

 

String ls_filter
DataWindowChild dwc_czrw,dwc_czx//定义子数据窗口变量
dw_dy.Settranso b j e c t(sqlca)
dw_dy.Retrieve()
dw_dy.GetChild("dw_2",dwc_czrw)
dw_dy.Getchild("dw_1",dwc_czx)
ls_filter = "czrw_bh = '"+dw_3.GetItemString(dw_3.GetRow(),"czrw_bh")+"'"//过滤条件
dwc_czrw.SetFilter(ls_filter)
dwc_czrw.Filter()
ls_filter = "czx_rwbh = '"+dw_3.GetItemString(dw_3.GetRow(),"czrw_bh")+"'"
dwc_czx.SetSort("czx_sx A")
dwc_czx.Sort()
dwc_czx.SetFilter(ls_filter)
dwc_czx.filter()
当然也可以通过数据共享(ShareData)等方式操作子数据窗口中的数据。
访问复合数据窗口对象.方法 :dw_dy.o b j e c t.dw_1.o b j e c t.对象
例子2   下拉数据窗口动态过滤
在数据窗口dw_1的ItemFocusChanged事件中写入如下脚本:
Integer rtncode
String ls_nowFld,ls_deptid,ls_sql
DataWindowChild fld_child
rtncode = dw_1.GetChild("Unit_id",fld_child) //获得Unit_id字段名下拉数据窗口的句柄
If rtncode = -1 Then MessageBox("错误!", "不是下拉数据窗口!")
fld_child.SetTransObject(SQLCA) //设置事务对象
ls_sql = Lower(fld_child.GetSQLSelect())// 获得DDDW的SQL语句
// 去除Sql 语句中的Where条件子句, 如原Sql 语句中须有Where条件子句,此处则需进行较
//复杂的处理,应视具体情况而定。
if Pos(ls_sql, " where ")>0 then ls_sql = Left(ls_sql,Pos(ls_sql, " where "))
//重新设置Sql 语句中的Where条件子句
ls_deptid=dw_1.Object.dept_id[GetRow()] //取得当前dept_id选定值
ls_sql = ls_sql + " Where dept_id = '" +Trim(ls_deptid)+"'"
//重新设置Sql 语句
fld_child.SetSQLSelect(ls_sql)
fld_child.Retrieve()//取得满足条件的数据

28 从数据窗口中获取数据
   单条:假设我们要读取dept_id字段的第一笔数据,可以用下列方式表示∶li_id = dw_1.o b j e c t.dept_id[1]
假设我们要读取第一行中第二个字段的数据,可以用下列方式表示∶ls_name = dw_1.o b j e c t.DATA[1,2]
假设我们要读取dept_id字段的所有数据,可以用下列方式表示∶li_array = dw_1.o b j e c t.dept_id.CURRENT
假设我们要读取过滤缓冲区 (filter buffer) 内dept_id字段的第一笔数据,可以用下列方式表示∶li_id = dw_1.o b j e c t.dept_id.Filter
[1]
假设我们要读取从第二笔数据的第一个字段到第三笔数据的二个字段之间的数据,表示∶lstr_array = dw_1.o b j e c t.DATA[2,1,3,2]
假设我们要读取整个第二笔的数据,可以用下列方式表示∶lstr_dept = dw_1.o b j e c t.DATA[2]
       使用GetItemX ( )函数 x为string number等 
lstr_name = dw_1.getitemstring (li_count , "emp_name") li_count为哪一条
多条:string ls_name[ ]
       ls_name = dw_ 1.o b j e c t.emp_name.current
数据的读取   一般格式∶数据窗口控件.Retrieve ( ) 返回个数 ,-1为错误
增加数据    数据窗口控件.InsertRow (行数)   参数为0加到最后
数据的删除        数据窗口控件.Deleterow (行数)
数据的过滤l   数据窗口控件.SetFilter (条件字符串).   
数据窗口控件.Filter ( ) 用法∶将主要缓冲区 (Primary Buffer) 内不符合过滤条件的数据移到过滤缓冲区 (Filter Buffer)
内。
             例子:string ls_exp   ls_exp = "dept_id = 100"   dw_1.SetFilter (ls_exp)      dw_1.Filter ( )
排序    dw_1.SetSort ("dept_id")     dw_1.Sort ( )
将数据从所有的缓冲区 (Buffer) 中清除    dw_1.ReSet ( )
计算数据数目。例如∶dw_1.Rowcount ( ) 类似: .DeletedCount ( ) .ModifiedCount ( ) .FilteredCount ( )
数据窗口的滚动 数据窗口控件.ScrollToRow (行数)

29 数据窗口属性改变:
   描述数据窗口对象本身颜色,可以表示如下∶long ll_color    ll_color = dw_emplist.Describe ("DataWindow.Color")
    描述数据窗口对象内标题 dept_id_t 的颜色,可以表示如下∶long ll_color   ll_color = dw_emplist.Describe ("dept_id_t.Color")
    修改数据窗口对象本身颜色,可以表示如下:dw_emplist.Modify ("DataWindow.Color = 255")
    修改数据窗口对象内标题 dept_id 的颜色,可以表示如下∶dw_emplist.Modify ("dept_id_t.Color = 255")
    假设当我们希望在程序运行阶段才给予下行条件∶薪水超过 50000 时显示红色,低于 50000 时显示黑色。程序的写法如下∶
       ls_modstring = "Salary.Color = '0~tIf (Salary > 50000,255,0) '"
       dw_1.modify (ls_modstring)

30 得到当前鼠标所指对象所在的带区
string str_band
str_band=GetBandAtPointer() //得到当前鼠标所指对象所在的带区
str_band=left(str_band,(pos(str_band,'~t') - 1))//得到"header"、"detail"等
        if str_band<>'header' then return //单击非头区,退出
31 得到鼠标指向的列对象名
str_o b j e c t=GetObjectAtPointer() //得到当前鼠标所指对象名
str_o b j e c t=left(str_o b j e c t,(pos(str_o b j e c t,'~t') - 1))
        //得到列对象名(默认为列名_t为列标题)
str_column=left(str_o b j e c t,(len(str_title) - 2))
//判断该名称是否为列名字
if this.describe(str_column+".band")='!' then return //非是列名,即列标题不是按正常规律起名的。
                                                             
32 得到当前行、列,总行、列 //this 针对数据窗口而言
        li_col      = this.GetColumn()
        li_ColCount = long(describe(this,"datawindow.column.count"))
        ll_row    = this.GetRow()
   ll_RowCount = this.RowCount()
       //设置当前行、列
       scrolltorow(this,ll_Row)
       setrow(this,ll_Row)
       setcolumn(this,li_col)
       this.SetFocus()

33得到所有列标题
ll_colnum = Long(dw_1.o b j e c t.datawindow.column.count)
        for i = 1 to ll_colnum
//得到标题头的名字
ls_colname = dw_1.describe('#' + string(i) + ".name") + "_t"
           ls_value = dw_1.describe(ls_colname + ".text")
next

34 如何用代码取得数据窗口汇总带计算列的值?  
   String ls_value
ls_value = dw_1.Describe("Evaluate("'compute_1',1)")
如果是数值型,要转换。

35 取得单击的列标题、列名、数据库字段名
string ls_dwo
long ll_pos
string ls_type
string ls_title
string ls_column
string ls_dbname
if Not KeyDown(KeyControl!) then return
ls_dwo = dwo.Name
if trim(ls_dwo) = '' or isnull(ls_dwo) then return
ls_type = This.describe(ls_dwo + '.type')
if ls_type = 'column' then
ls_title = This.describe(ls_dwo + '_t.text')//标题
ls_column = This.describe(ls_dwo + '.Name') //数据窗口列名
ls_dbname = This.describe(ls_dwo + '.dbname') //数据库中字段名
messagebox('信息',    '标 题 文 本   :' + ls_title + &
       '~r~n数据窗口列名 :' + ls_column + &
       '~r~n数据库中字段名:' + ls_dbname )
end if

36 窗口为w_gcde内,放入一个DW_1,如何得到dw_1内的某列值yuonghu_id列的内容
方法:
long lng_column_count
   integer i
   string str_column[]         //列名
   string str_column_text[]  //text的名字
  //得到数据窗口的总列数
  lng_column_count = long(dw_1.Describe("DataWindow.Column.Count"))
  //循环依次读取
  for i = 1 to lng_column_count
     str_column[i] = dw_1.Describe("#"+string(i)+".name")
      str_column_text[i] = dw_1.Describe(str_column[i] + "_t.text")
  next

37 在DDDW中实现当前高亮行随鼠标移动
DataWindowChild ldwc_Child
String ls_Pointer
Long ll_Row

GetChild( "dept_id", ldwc_Child ) // Replace the column name "dept_id" as you needed

IF hwndchild = Handle( ldwc_child ) THEN
    if notificationcode = 2311 then //DDDW的mousemove事件
        //得到鼠标所在行
        ls_Pointer = ldwc_Child.GetObjectAtPointer()
        ll_Row=Long( Mid( ls_Pointer, Pos( ls_Pointer, "~t" ) + 1 ))
        //移到鼠标所在行
        IF ldwc_Child.GetRow() <> ll_Row AND ll_Row > 0 THEN
            ldwc_Child.ScrollToRow( ll_Row )
        END IF
    end if
END IF

38 实现打印完一个DataWindow后不换页
首先将datawindow的print输出到一个打印文件中,把其他的print也输入这个prn,然后,打印这个打印文件就行了。
如:
datawindow_control1.object.datawindow.print.filename="c:printfilepathexam_1.prn"
datawindow_control2.object.datawindow.print.filename="c:printfilepathexam_1.prn"
dw_1.print()
dw_2.print()
run("print //d:\printservenamesharename "c:printfilepathexam_1.prn")
//d:\printservenamesharename打印机名

 

PB中的Describe,Evaluatate,LookUpDisplay小结

Describe 可以描述DW中某个对象的某个属性的取值,虽然函数Describe可以获取对象的信息,但是表达式的取值就不能正常读取了,而这又是经常遇到的. Evaluate 如果想获取数据窗口对象中由属性、函数等构成的表达式的取值时,必须在函数Describe中使用函数Evaluate,LookUpDisplay   在数据窗口控件上显示的值和字段实际得到的值并不相同,使用函数GetItemX只能读取这样的字段的真实取值,而不是用户看到的值。如何才能读取用户看到的值?可以使用此函数,LookUpDisplay函数不能直接从PowerScript调用,可以在Describe中和Evaluate函数配合使用。因为函数Lookupdisplay不能指定对哪行数据进行操作,它的参数只有一个字段名称,所以必须和Evaluate函数配合使用。该函数的语法是:Lookupdisplay(columnname)参数columnname是字段的名称,而不是一个字符串。函数执行错误则返回空字符串。

例一:

ls_1 = dw_1.Describe("dw_1.cb_4.text")ls_2 = This.Describe(dwo.name + ".ColType")语法: value = datawindow.Describe(string ls)

例二:

判断第3行的sex是否为1,如果是则返回男,否则返回女dw_1.Describe("Evaluate('If(sex = 1, 男, 女) ', 3)")

语法: Evalute('expression',rowno)其中,expression是属性表达式,rowno是要描述的行号。该函数放置在Describe的属性列表中。

例三:dw_1.Describe("Evaluate('Lookupdisplay(column)'," + string (row number) + ")")

在dw_1 里面有一个gxbm字段的edit属性页下面:dataWindow:d_dmzd_gxbm,Display Column:dmmc,data Column:gxbm.在显示时:不是显示gxbm的值,而是显示dmmc的值,但我们用getitemstring(row,"gxbm")时,得到的是gxbm的值,而不是显示的dmmc值,如果我们想得到显示的dmmc值,那就用lookupdisplay来用:ls_1 = dw_1.describe( "Evaluate('lookupdisplay(gxbm)'," + string(1) + ")")

另: 在用代码学PB中有这样一段代码,值得关注:
integer li_PageCount

//*******分页
li_PageCount = integer(dw_1.describe("evaluate('pagecount()',1)"))
i_int_currentpage = integer(dw_1.describe("evaluate('page()',1)"))
st_page.Text = "第"+String( i_int_currentpage ) + "页(共" + String( li_PageCount )+"页)"

动态设置下拉数据窗口

动态设置字段的下拉窗口如下:
dw_1.modify("column_result.dddw.name='" + ls_dataobject + "'")//设置数据窗口
dw_1.Modify("column_result.dddw.DisplayColumn ='" + ls_display + "'")//设置显示字段
dw_1.modify("column_result.dddw.DataColumn='" + ls_data + "'")//设置数据字段
dw_1.modify('column_result.dddw.Autohscroll=yes')
dw_1.modify('column_result.dddw.Allowedit=yes ')
dw_1.modify("column_result.dddw.VScrollBar=yes")
dw_1.modify('column_result.dddw.useasborder=yes')
dw_1.modify('column_result.dddw.ShowList=yes')
     
dw_1.GetChild("column_result",ldwc_childdw)//获取下拉数据窗口
ldwc_childdw.settransobject(sqlca)
ldwc_childdw.retrieve()//刷新下拉数据窗口的值

================================================================
动态为下拉数据窗口添加数据如下:
dw_1.GetChild("column_result",ldwc_childdw)//获取下拉数据窗口
ls_display = dw_1.describe('column_result.dddw.DisplayColumn')
ls_data = dw_1.describe('column_result.dddw.DataColumn')
ldwc_childdw.settransobject(sqlca)
ll_row = ldwc_childdw.insertrow(0)//新增行
ldwc_childdw.setitem(ll_row,ls_display,"显示数据")//填写数据
ldwc_childdw.setitem(ll_row,ls_data,"1")//填写数据

  • 0
    点赞
  • 0
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值