VFP9的10件酷事(1) 文本框自动完成

shanjuhua 2004-10-27 09:23:54
加精
VFP9的10件酷事
David Stevenson著
RMH译

这是 FOXTALK杂志6月刊 提供的一篇免费文章,我们把她翻译出来,更多的译文资料在: http://foxer.xicp.net
象VFP8一样,VFP9的许多改进建议也是来自全球的各个VFP社区。(大大小小的建议,很难知道是谁提出了这些好建议)。不过尽管改进很多,我们也必须承认,VFP的很多方面还没被照顾到。
总的看来,VFP9带给我们的是:修补了很多BUG;弥补了一些功能的缺陷或实现了过去曾提出过的一些设想;某些功能被重写发生了翻天覆地的变化……当然,你所渴望的某些功能或许在或许不在这个版本里面,但可以确定你能从那个“What's New”文档中发现一些有价值的东西。记住,尝试测试版总要带点探险精神的。 我写这篇文章的时候,是在VFP测试版发布前的几个星期,VFP文档有些地方跟不上VFP软件的更新,这就意味着你拿到的测试版拷贝会和文档有些出入,所以很自然,尝试测试版软件总要带点探险精神的,呵呵。

正式的官方文档还在继续完善,不过其中“What's New”的一部分现在已经展现在我面前了。花了4页纸用以赤裸裸地展示了 数据增强 部分,IDE增强 用了2页,语言增强 用了10页 等等…… 实际上提供给官方内部测试者的 版本声明 和 开发文档 有1英寸多厚,就这还不包括新的报表设计部分!报表设计器焕然一新。与报表编辑器的大幅度改动相比,其它所有的改进和新功能都变得黯然失色。尽管保持了向后兼容,VFP 开发组还是从底层完全重写了 VFP 的报表编辑器,给了它一个新的引擎,该引擎能够让你从外部用自己的代码来与它提供的 GDI+ 表现界面进行交互,并为你自己的代码提供了钩子(hook)。
按照VFP惯例,几个以下划线开头的系统变量将粉墨登场(_ReportBuilder, _ReportOutput, 和 _ReportPreview),这些都是外挂的报表模块,你可以用自己的模块来代替他们。你还可以使用一个名叫“ReportListener”的基类,可以直接使用它,可以在预览/打印行为中使用它,或者把它提供给其它的用户反馈表单。你甚至可以把几个“ReportListener”连在一起,控制多个输出和反馈。
FOXTALK杂志将会在接下来的几个月讲述VFP9报表系统改良的优越性,期间你会碰到一些新概念,比如ReportListener,一开始完全掌握它们会有点难度,你得呆在这儿连续阅读,最好跟着试验下。一旦这些概念注入你的大脑,我想你会吃惊、感叹的。让我们来看看这十件酷事 老实说要在这个文档中挑选10个新特征来举例真不容易,因为这里有上百个新特性供选,我眼花花,比如,也许我该选这个?:如何在BROWSE窗口显示MEMO提示(移动鼠标到MEMO字段上面显示4095个字符);如何禁止打开表对话框并返回一个错误(SET TABLEPROMPT OFF);如何用 SET REFRESH 指定更快的刷新率;如何在 命令按钮/选项按钮/检查框 中隐藏CAPTION后还能使用热键/图像(通过设置一个新的属性PicturePosition=14-No Text)。嗯……或者我应该介绍这个?:为CURSOR对象提供的新属性 OrderDirection ,在数据环境中将它设为 升序 或 降序;工具栏纵横向改变时动态调整分隔对象;用 Listbox.AutoHideScrollBar 属性来隐藏滚动条。
我苦思冥想,因为我要从这个万众瞩目的VFP9.0中选出10个典型的特性来阐述。 注:因为这篇文章基于VFP9的一个早期测试版,所以有的特征可能和现在有点出入。

1、 文本框自动完成
你是否曾梦想过给文本框添加一种看起来更流行的“输入常用的单词或短语就出现一个下拉列表”的外观?通过使用 VFP 智能感知的核心引擎,VFP 开发组给了我们这样一种很酷的新功能,并且不但令人惊讶的易于使用,而且完全可以扩充。 让我们来尝试一下,将一个文本框拖放到表单上(或者打开一个有文本框的任何一个表单),将文本框新的 AutoComplete 属性设置为一个非零值,这样就搞定了!运行几次这个表单,在文本框里输入一些内容,然后就看魔术表演吧!你也可以用下面这样的代码来让表格中的文本框支持 AutoComplete: THISFORM.Grid1.Column1.Text1.AutoComplete = 1 AutoComplete 属性控制着自动完成的行为表现,可用的值如下:
※ 0 —— 不使用自动完成;
※ 1 —— 按字母顺序;
※ 2 —— 最常用的;
※ 3 —— 最近使用的;
※ 4 —— 用户自定义的加权排序(Weighted Order);
这些选项中的最后一个需要特别注意一下。当 AutoComplete 的值在 1-3 之间的时候,自动完成的功能是系统自维护的,而用户自定义加权排序的值4则让你可以通过给 AutoComp.DBF 表中的 Weight 字段赋以一个数值型值来指定各个数据项的显示顺序(最大的 Weight值显示在下拉列表的顶部)。 默认的 AutoComp.DBF 表位于 HOME(7) 目录下(译者注:使用参数7,该函数返回用户应用程序的数据目录。),但你可以通过在全局的层次上设置 _SCREEN.AutoCompTable、或者在单个文本框的层次上设置 Text1.AutoCompTable来覆盖默认的设置。不管你在哪个属性中指定一个表,如果这个表不存在,则系统会自动为你新建一个。你可以同时拥有多个AutoComp表,而每个表也可以服务于一个或多个文本框,VFP会管理这些在一个隐藏的数据工作期内的表的打开和关闭。 在 AutoComp 表中,除非你给文本框设置了 AutoCompSource 属性,否则这个文本框的 Name 将作为决定显示哪些数据项的查询关键字,反之,则使用 AutoCompSource 属性指定的值。要想让多个文本框共享自动完成提供的值的话,只要简单的把这些文本框的 AutoCompSouce 属性设置为相同的值就可以里,例如设置为 NameAutoComp或者Cities。 通过在运行时将 AutoCompSource 动态的设置为一个代表某个用户的特定代码的字符串、或者在属性表中设置如下的代码,你甚至可以为你所在组织中的每个人启用独特的自动完成列表: = "Custs_" + LoginName 不过,如果采用了这种办法,你需要注意的是在 AutoComp 表中作为搜索关键字的 Source 字段只有 20个字符大小。当然,你可以自己建一个有着更大长度的 Source 字段的表作为 AutoComp 表,可是如果在为一个特定的文本框初次使用AutoComplete功能的时候你让 VFP 自动为你建立这个表,那么这个表中的 Source 字段的长度默认就是 20个字符。 要在测试的时候看看 AutoComp 表中发生了什么事情,你可以从 VFP 的另一个数据工作期内共享打开这个表来浏览它的内容,或者也可以在命令窗口中执行如下代码:
USE HOME(7) + "autocomp.dbf" SHARED IN 0
SELECT autocomp
BROWSE

...全文
1018 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
LAIYANGPJ 2004-10-27
  • 打赏
  • 举报
回复
班竹辛苦了,没帮上忙.呵呵....顶一下吧!
JohnShen 2004-10-27
  • 打赏
  • 举报
回复
帮楼主整理了一下,好作为精华贴
JohnShen 2004-10-27
  • 打赏
  • 举报
回复
10、 为了能使用户更好的对数据类型进行控制
VFP增加了CAST()函数, 无论是作为单独的函数使用还是内嵌入SQL语句中他都可以对不同的数据类型进行转换,他很简单,这似乎难以置信,不过在应用情况下它却是非常的强大。 SELECT unit_price, ;
CAST(unit_price AS Integer) AS IntPrice, ;
CAST(unit_price AS N(12,6)) AS NumPrice ;
FROM (_samples+"tastrade\data\products")

11、 超级SYS(1037,1)
USE report1.frx
SYS(1037,1) &&自动读取report1.frx里面的打印环境
确定一下看看,**!
SYS(1037,1)的设置自动保存到report1.frx里面呢
哎,红雨的打印设置表单又白做呢

12、 在WITH … ENDWITH 和FOR EACH … ENDFOR中支持智能感应
为在WITH ... ENDWITH 和FOR EACH ... ENDFOR中支持IntelliSense,这两个命令的语法格式增加了AS Type子句,如下所示:
WITH ObjectName [AS Type [OF ClassLibrary]]
Commands
ENDWITH
FOR EACH ObjectName [AS Type [OF ClassLibrary]] IN Group
Commands
[EXIT]
[LOOP]
ENDFOR
Type 可以引用任何有效类型,包括数据类型、类类型或ProgID,如果类名称无法找到,Visual FoxPro将忽略该类名称并不显示IntelliSense。
注意:Type引用不影响运行时应用程序的实际功能,这种引用仅是为了使用IntelliSense。ObjectName 表达式可以引用一个内存变量或数组。
ClassLibrary参数指定的类库需要在可以被Visual FoxPro发现的路径中,如果指定的类库不能发现,IntelliSense不显示。
输入特定的ProgIDs和类库不需要引号围住它们,除非在名称中包含有空格。当输入了一个关键词, IntelliSense将显示一个在FoxCode (Type="T")中注册的类型列表。如果指定了一个有效类型,在WITH ... ENDWITH 或FOR EACH ... ENDFOR中输入一个圆点,将显示对于该对象的IntelliSens。
必须指定一个有效类库,对已存在对象引用则无效,例如下面的语句不支持IntelliSense:
WITH THISFORM AS APPLICATION
ENDWITH
WITH THISFORM AT THIS
ENDWITH
有效的书写方式如下:
WITH This AS Form &&在一个表单事件中书写
.Caption="标题"
ENDWITH
又如:
WITH This.Pageframe1.Page1 AS Page
.Caption="页框1"
ENDWITH
Visual FoxPro支持嵌套WITH ... ENDWITH和FOR EACH ... ENDFOR命令,下面是在一个叫Program1.prg的.prg中定义类中的嵌套WITH ... ENDWITH命令。在做这个示例前,首先需要在磁盘中保存一下Program1.prg文件,然后重新打开,可以在WITH和ENDWITH之间输入一个圆点,然后就可以看见IntelliSense,如图5所示。
DEFINE CLASS f1 AS form
MyVar1 = 123
ADD OBJECT t1 AS mytext
PROCEDURE Init
WITH THIS AS f1 OF program1.prg
WITH .t1 AS mytext OF program1.prg
ENDWITH
ENDWITH
ENDPROC
ENDDEFINE
DEFINE CLASS mytext as textbox
MyVar2 = 123
ENDDEFINE

13、 报表可以有多个细节区了



14、 控件的Anchor属性
Anchor属性的意思,它有0-9十种值,各自代表的意思如下:
以下是我做测试的结果:
DH:表单高度的增量
DW:表单宽度的增量
测试过程:用代码把按钮的left和top各加80,长和高各加10后,再调整表单大小,再观察按钮的位置和大小
old值
oldtop=50
oldleft=50
oldheight=27
oldwidth=84
new值
newtop=130
newleft=130
newheight=37
newwidth=94
0:NULL
1:height和top变回old值,left和width为130和94(而且在再度移动按钮位置和改变大小前,再调整表单,按钮不再受影响)
2:和1相反,是left和width变回old值,height和top为37、130(而且在再度移动按钮位置和改变大小前,再调整表单,按钮不再受影响)
3:left、top、height、width都变为原来的值
4:height为oldheight,width、left为new值,top为oldtop+DH,即保持和表单底部的距离保持在设计阶段的值
5:top为oldtop,left、width为new值,height为oldheight+DH,即表单的高度增加多少,控件的高度也增加多少
6:left、width、height均为old值,只是height为oldheight+DH,即表单的高度增加多少,控件的高度也增加多少
7:top、left、widht均为OLD值,只是height为oldheight+DH,即表单的高度增加多少,控件的高度也增加多少
8:top、height均为new值,width就为old值,left就是oldleft+DW,就是控件保持和表单右边的距离不变
9:top、height、width均为old值,left就是oldleft+DW,就是控件保持和表单右边的距离不变
注意:它的十个可用的值要加起来用的,比如,现在我有一个Listview,我要让它在表单缩放时,Top和left保持不变,右边界和底部边界跟随表单一起缩放,那么就要用到Anchor中的四个值:
1——顶部绝对,即距表单顶部的距离保持不变;
2——左边绝对,即距表单左边的距离保持不变;
4——底部绝对,即距表单底部的距离保持不变;
8——右边绝对,即距表单右边的距离保持不变;
现在,把Listview的anchor设置为15(1+2+4+8),缩放表单时Listview就跟着自动缩放了。

15、 自定义Memo编辑窗口
textbox.openwindow=.t.
textbox.memowidow="窗口名"
二个属性的意思是:
如果这个textbox是关联到一个memo字段时,双击这个控件,会自动跳到memowindow中指定的窗口中去。条件是该窗口必须事先打开。
用此功能我们可以自定义Memo编辑窗口,而不是使用默认的那个土土的。
16、 画多边形
Shape和Line控件的PolyPoint属性用来画多边形
定义一个二维数组,(x,y)代表每个顶点的x,y值,然后把数组名放进PolyPoint属性,这二个控件就会画一个多边形了,还可以使用Rotation进行旋转。但此时只能是Plain而不能是3D了。
比如:
DIMENSION poly[5,2]
poly[1,1]= 0
poly[1,2]= 50
poly[2,1]= 50
poly[2,2]= 100
poly[3,1]= 100
poly[3,2]= 50
poly[4,1]= 50
poly[4,2]= 0
poly[5,1]=0
poly[5,2]=50
这个数组就会画一个菱形
17、
18、 q
19、 q
20、 q
21、






VFP9.0Bata 新增的98個函數和命令

(3)
_MEMBERDATA
_MENUDESIGNER
_REPORTBUILDER

A (12)
ADJUSTOBJECTSIZE
AFTERBAND
AFTERRECORDREFRESH
AFTERREPORT
ALLOWMODALMESSAGES
ANCHOR
APPSTATE
ASQLHANDLES
AUTOCOMPLETE
AUTOCOMPSOURCE
AUTOCOMPTABLE
AUTOHIDESCROLLBAR

B (4)
BEFOREBAND
BEFORERECORDREFRESH
BEFOREREPORT
BLOB

C (9)
CANCELREPORT
CAST
CLEARRESULTSET
CLEARSTATUS
COMMANDCLAUSES
CONFLICTCHECKCMD
CONFLICTCHECKTYPE
CURRENTDATASESSION
CURRENTPASS

D (6)
DECLAREXMLPREFIX
DELAYEDMEMOFETCH
DOCKABLE
DOMESSAGE
DOSTATUS
DYNAMICLINEHEIGHT

E (1)
EVALUATECONTENTS

F (6)
FETCHMEMOCMDLIST
FETCHMEMODATASOURCE
FETCHMEMODATASOURCETYPE
FIRSTNESTEDTABLE
FRXCURSOR
FRXDATASESSION

G (5)
GDIPLUSGRAPHICS
GETAUTOINCvalue
GETDOCKSTATE
GETPAGEWIDTH
GETRESULTSET

H (0)

I (6)
ICASE
INCLUDEPAGEINOUTPUT
INSERTCMDREFRESHCMD
INSERTCMDREFRESHFIELDLIST
INSERTCMDREFRESHKEYFIELDLIST
ISMEMOFETCHED

J (0)

K (0)

L (2)
LISTENERTYPE
LOADREPORT

M (2)
MAPBINARY
MAPVARCHAR

N (3)
NEST
NESTEDINTO
NEXTSIBLINGTABLE

O (3)
ONPREVIEWCLOSE
ORDERDIRECTION
OUTPUTPAGE

P (6)
PAGENO
PAGETOTAL
PICTUREMARGIN
PICTURESPACING
POLYPOINTS
PREVIEWCONTAINER

Q (1)
QUIETMODE

R (11)
RECORDREFRESH
REFRESHALIAS
REFRESHCMD
REFRESHCMDDATASOURCE
REFRESHCMDDATASOURCETYPE
REFRESHIGNOREFIELDLIST
REFRESHTIMESTAMP
RENDER
REPORTLISTENER
RESPECTNESTING
ROTATION

S (6)
SELECTIONNAMESPACES
SENDIMAGEINFO
SESSIONDATA
SETRESULTSET
SQLIDLEDISCONNECT
SUPPORTSLISTENERTYPE

T (2)
TIMESTAMPFIELDLIST
TWOPASSPROCESS

U (7)
UNLOADREPORT
UPDATECMDREFRESHCMD
UPDATECMDREFRESHFIELDLIST
UPDATECMDREFRESHKEYFIELDLIST
UPDATESTATUS
USECODEPAGE
USECURSORSCHEMA

V (2)
VARBINARY
VARCHAR

W (0)

X (1)
XMLNAMEISXPATH

Y (0)

Z (0)


JohnShen 2004-10-27
  • 打赏
  • 举报
回复
9、 在事务处理中可以包含自由表和cursors
现在通过使用心得MAKETRANSACTABLE()函数,你可以在一个具有完善回滚能力的事务处理中包含自有表和CURSOR,运行下列代码,在每一个等待窗口后按回 键,注意事务处理在最后一步从cursor完全恢复期间的记录插入。
如果已经调用 MAKETRANSACTABLE()对表进行事务处理,那么使得这个表不被处理的唯一方法就是在所有的数据工作器中关闭并重新打开这个表,当在一个数据工作期中开始事务处理以后,这个表就会变得在所有的工作期中都可以进行处理,直到关闭。 CREATE CURSOR MyCursor (id i, name c(20))
WAIT WINDOW "Table is "+ ;
IIF(ISTRANS (),[],[not ])+"transactable. " +;
TRANSFORM(RECCOUNT())+" records."
MAKETRANSACTABLE()
BEGIN TRANSACTION
INSERT INTO MyCursor valueS (1, "Fox")
WAIT WINDOW "Table is "+ ;
IIF(ISTRANS (),[],[not ])+"transactable. " +;
TRANSFORM(RECCOUNT())+" records."
ROLLBACK
WAIT WINDOW "Table is "+ ;
IIF(ISTRANS (),[],[not ])+"transactable. " +;
TRANSFORM(RECCOUNT())+" records."
JohnShen 2004-10-27
  • 打赏
  • 举报
回复
8、 使用新的数据浏览面板
VFP9增加了一个新的而且非常有用的数据浏览面板(如图3),通过这个面板,你就可以来配置一些你常用的VFP数据库、自由表以及SQL SEVER数据库.你可以很容易的找到这一项,点击[TOOLS]菜单里的[Task Pane],然后选择[Data Explorer](也许你必须通过点击">>"按钮才能看到)。点击[Add Connection]按钮,然后指定数据源,完后就可以浏览了。右键点击每个数据库或表,在弹出菜单中包含一个[RUN QUERY]项,点击这一项会出现查询界面,这样就可以进行数据查询及浏览了。 图表3说明:

数据浏览面板显示了VFP的[Tastrade]数据库的细节信息,同时右边的查询界面部分(通过右键点击Northwind数据库可以调出)则显示了SQL SERVER数据库Northwind的查询结果。
JohnShen 2004-10-27
  • 打赏
  • 举报
回复
7、 停靠你的表单
你现在可以用新的表单Dockable属性把停靠行为加入到你的程序中。默认的Dockable值是0,跟以前版本的行为一致。然而,如果你把Dockable设为1或2,表单的标题栏高度就会变成原来的一半,这时表单就支持停靠了(设为1表示表单已停靠)。
表单支持停靠(Dockable设为1或2)后,你可以用WINDOWS菜单的Dockable项或在表单的标题栏点击鼠标右键来切换这2种设置。当Dockable=1时,你可以将表单拖放到可停靠的位置,你也可以用以下代码实现停靠: * 1=top, 2=left, 3=right, 4=bottom
THISFORM.Dock(nPosition)
* tab-dock to another form
THISFORM.Dock(4, oFormTarget)
* tab-dock to a window
DOCK NAME oFormRef POSITION 4 WINDOW WindowName 一个已停靠的表单也可以通过WINDOWS菜单的Dockable项或在表单的标题栏点击鼠标右键来终止停靠,或用以下的代码: * set form to "supports docking, but not docked"
THISFORM.Dockable = 2
* or call the form's dock method
THISFORM.Dock(-1) 你可以运行下面的代码看看停靠的过程。这些代码建了3个表单,并设定了TOP/LEFT,然后把它们停靠到COMMAND窗口上。你可以用上面的Dock/Undock按钮来实现表单的停靠/不停靠,点击3个中任一一个表单的X按钮会关闭演示。
选中一个表单后,你可以用菜单来切换它的Dockable属性,当表单处于可停靠状态时,你可以把它拖放到屏幕上的任一个可停靠的位置。图2显示了3个可互相切换的已停靠表单。
图二:

LOCAL oform1 as Myform
oform1=CREATEOBJECT("Myform")
oform1.Caption="Customers"
oform1.lblName.Caption = "Customers"
oform1.top = 100
oform1.left = 0
LOCAL oform2 as Myform
oform2=CREATEOBJECT("Myform")
oform2.Caption="Employees"
oform2.lblName.Caption = "Employees"
oform2.top = 100
oform2.left = 325
LOCAL oform3 as Myform
oform3=CREATEOBJECT("Myform")
oform3.Caption="Invoices"
oform3.lblName.Caption = "Invoices"
oform3.top = 275
oform3.left = 0
DOCK NAME oform1 POSITION 4 WINDOW Command
DOCK NAME oform2 POSITION 4 WINDOW Command
DOCK NAME oform3 POSITION 4 WINDOW Command
oform1.show()
oform2.show()
oform3.Show()
READ EVENTS
DEFINE CLASS MyForm AS Form
Dockable = 1 && supports docking and is dockable
Height = 150
Width = 300
ADD OBJECT lblName AS MyLabel
ADD OBJECT btnUndock AS MyUndockButton
FUNCTION Destroy()
CLEAR EVENTS
ENDDEFINE DEFINE CLASS MyUndockButton AS CommandButton
Height = 25
Width = 100
Left = 180
Top = 100
Anchor = 12 && fixed distance bottom/right
Caption = "Dock/Undock"
FUNCTION Click()
IF THISFORM.Docked
THISFORM.Dock(-1)
ELSE
IF THISFORM.Dockable = 1
* error if not dockable
DOCK NAME THISFORM POSITION 4 WINDOW Command
ENDIF
ENDIF
ENDDEFINE
DEFINE CLASS MyLabel AS Label
FontSize= 18
Height = 50
Width = 150
Top = 50
Left = 75
Alignment = 2
Anchor = 240 && relative on all sides
Caption = []
FontSize = 14
FontBold = .T.
FontName = "Verdana"
ENDDEFINE

JohnShen 2004-10-27
  • 打赏
  • 举报
回复
6、 用新的ICASE()函数一行搞定
当一个判断点出现在你的程序中(特别是SQL SELECT命令),你以前只能用一连串的IIF()来解决。
新的ICASE()函数可以让你建立更可靠更优雅的代码,它允许你使用包括OTHERWISE在内的100个条件。比如,在你的SQL SELECT查询中要用到一个字符串,这个字符串是根据销售员的业绩得出的一系列结果,代码如下: CREATE TABLE lineitems (custcode I, purchases N)
FOR i = 1 TO 10
INSERT INTO lineitems valueS (i,800*(i-2))
ENDFOR
SELECT li.custcode, li.purchases, ;
PADR( ;
ICASE( li.purchases <= 0, "Drag on Profits", ;
li.purchases < 500, "Bread and Butter", ;
li.purchases < 2000, "Send Gift Box", ;
li.purchases < 5000, "Take to Ballgame", ;
"Trip to Hawaii" ;
), 20) AS CustStatus ;
FROM lineitems li 我指定了4个条件组,最后的那个"Trip to Hawaii"是OTHERWISE段。而且我把返回值用空格填充到固定的20个字符,因为在SQL SELECT中有时需要这么做。另外,不管你有偶数个参数还是奇数个参数,每个CASE段的最后一个参数就是OTHERWISE的值。
JohnShen 2004-10-27
  • 打赏
  • 举报
回复
5、 使用新的超小型二进制索引
VFP9引进了一个新的索引类型---二进制索引,它可以在任何逻辑表达式中被使用。据一些测试者讲,这种新型索引的访问速度和一般索引差不多,但是它的大小比一般索引要小90%,插入记录时要快80%。
要建二进制索引标志,你要在表设计器中设置索引类型为二进制,或者在Index命令中加入关键字BINARY:
INDEX ON MyNonNullableLogicalExpression TAG MyBinary BINARY
INDEX ON DELETED() TAG DELETED BINARY
要注意的是,你建二进制索引或索引TAG的时候,不要 包含FOR子句 或 INDEX ON一个会得出NULL值的表达式。你也不能在SEEK或SET ORDER TO语句中使用二进制索引。不过你可以在优化的FILTER条件和SQL SELECT的WHERE子句中使用并得到好处。
为了配合新的二进制索引,VFP9.0在SET DELETED ON环境中优化了DELETED()。因为二进制索引已经是“位”级了,VFP可以在内存中更快地建立Rushmore,并且使用更少的局域网数据流量,从而大大提高了查询的性能。现在你可以拿几个变量和别人讨论下在索引中使用DELETED()究竟会降低还是提高性能了。
JohnShen 2004-10-27
  • 打赏
  • 举报
回复
楼下的帮忙拷贝一下
JohnShen 2004-10-27
  • 打赏
  • 举报
回复
4、 将报表保存为图形文件
ReportListener 的另一种很大的用途是通过在你专门的子类中覆盖 OutputPage 方法来将一个报表保存为图形文件。可以保存的图形文件格式包括 EMF、JPEG、GIF、PNG、BMP、TIFF、以及多页的 TIFF(这种格式对于用传真发送报表来说特别有用)。 注意,在这个示例的代码中,我将 ListenerType 属性设置为了2,这意味着让你自己来控制输出,每次用参数 nDeviceType = -1 调用 OutputPage 方法就打印一页,但并不将输出发送到一个打印设备。MyReportListener 有一个自定义的 OutputPage 方法,它先检查 nDeviceType 的参数是否为 -1,然后再次调用 OutputPage 方法(给方法传递一个文件名和图形文件类型),再执行一个 NODEFAULT。这个示例在生成第一页的时候建立一个 TIFF 文件,然后将其它的页添加到同一个图形文件中去。 LOCAL olistener * 建立一个 ReportListener 的实例
olistener = CREATEOBJECT("MyTiffListener")
olistener.tifffilename = "c:\tifftest.tif" * 运行一个将会引用我们设置好了的 Listener的 报表
REPORT FORM (_samples+"solution\reports\invoice.frx") ;
OBJECT olistener RANGE 1,2 * 在浏览器中显示结果
RUN /n Explorer.exe c:\tifftest.tif DEFINE CLASS MyTiffListener AS ReportListener
tifffilename = []
listenertype = 2 && 一次一页,不输出 FUNCTION OutputPage(nPageNo, eDevice, nDeviceType)
* 由于 ListenerType 指定了 "不打印输出"
* 在报表引擎调用这个方法的时候,nDeviceType 将会是 -1
* 而我们现在则捕捉这个条件,然后自己来调用
* OutputPage 方法,调用时带上文件名和图形类型参数
IF nDeviceType = -1 ;
AND NOT EMPTY(THIS.tifffilename)
IF nPageNo = 1
* 如果是第一页,则建立TIFF文件
THIS.OutputPage(nPageNo, THIS.tifffilename, 101)
ELSE
* 否则,则向 TIFF 文件添加剩下的页
* (这段代码要运行,首先 TIFF 文件必须已经存在)
THIS.OutputPage(nPageNo, THIS.tifffilename, 201)
ENDIF
* 我们已经用需要的设置调用过 OutputPage 方法了
NODEFAULT
ENDIF
ENDDEFINE
JohnShen 2004-10-27
  • 打赏
  • 举报
回复
3、 组合多个 ReportListener 以提供多种输出
从前面的例子上再走远一点,让我们来看看你可以怎样通过组合多个 ReportListener 来实现在同一个运行中的报表上提供多种输出方案。在默认的 ReportOutput.app(以及在新的 _reportListerer.vcx FFC 基础类库中)提供的 ReportListener 的子类有一个属性叫 Successor,可以用这个属性记录下对另一个个 ReportListener 实例的引用,而个被引用的实例将被挂钩到报表生成引擎上,因而是起着主导作用的“主控 Listener”。 在下面的示例中,我通过执行 DO (_reportoutput) 两次来建立两个 listener,每次执行的时候都传递给它一个变量,以返回一个对带有正确的输出类型的Listener的对象引用,输出类型是 (_reportoutput)程序决定的。在下面的代码中,olistener 接收到一个对一个输出类型为 0 (打印输出)的 listener 的对象引用,而 olistener2 则接收到一个输出类型为4的 XMLListener对象的引用。 现在,我们有一个全局的集合(_oReportOutput),该集合中拥有对缓存中的打印和XML两个Listener的引用,而我们则将这两个 Listener 引用为 olistener 和 olistener2。现在,为了演示从 ReportOutput.app 来取得一个 ReportListener 的引用的另一种办法,我们象这样给集合添加另一个将被放入缓存中的 HTMLListener 的实例:DO (_reportoutput) WITH 5 注意,现在我们可以通过集合引用的办法来操作 HTMLListener 的属性,象这样: _ReportOutput("5").targetfilename = "c:\htmltest2.htm" 现在剩下的活是将这三个 Listener 象链条一样的串连起来,输出类型为0的打印Listener放在链条的最前面。这个 Listener 将是我们在使用 REPORT FROM 命令的时候放在 OBJECT 子句里面去的那个,这样一来,它就变成了一个“驱动,或者主控”listener,而它会与另外两个与它在一条链条上的 listener 进行通讯。将它们链接起来的代码是: olistener.successor = olistener2
olistener2.successor = _oReportOutput("5") 就是这样。现在,运行这个报表,从同一次运行你就会获得三种类型的输出——在默认打印机上的一个报表、一个只带着数据的 XML 文件、以及一个显示着报表的 HTML 页面。 LOCAL olistener, olistener2 * 获得一个对打印类的引用
DO (_reportoutput) WITH 0, olistener * 获得一个对 XMLListener 类的引用
DO (_reportoutput) WITH 4, olistener2 * 关闭用户界面的返回和提示
olistener2.quietmode=.T. * 只包含数据,不带布局信息
olistener2.xmlmode=0 * 指定文件名和路径,并关闭文件名提示
olistener2.targetfilename = "c:\xmltest2.xml"
olistener2.quietmode=.T. * 现在为 HTML 输出做准备,但使用另一种办法来从全局的
* _oreportoutput 集合中获得一个对listener 的引用
DO (_reportoutput) WITH 5 * 通过集合引用来设置 HTMLListener 的属性
_oReportOutput("5").targetfilename = "c:\htmltest2.htm"
_oReportOutput("5").quietmode=.T. * 把三个 listeners 象链条一样的链接在一起
* 其中,用打印 listener 作为驱动
olistener.successor = olistener2
olistener2.successor = _oReportOutput("5") * 运行一个雇员电话号码列表,引用在列表中的第一个 listener
REPORT FORM (_samples+"solution\reports\ledger.frx") ;
OBJECT olistener * 在浏览器中显示 XML 和 HTML 结果
* 并在打印机上打印报表
RUN /n Explorer.exe c:\xmltest2.xml
RUN /n Explorer.exe c:\htmltest2.htm
JohnShen 2004-10-27
  • 打赏
  • 举报
回复
2、 使用新的报表引擎来建立 HTML 或者 XML
由于新设计的报表编辑器引擎使用了一个 GDI+ 输出接口而不是旧的 GDI 技术,并且由于该引擎的那些表现部分的彻底改变,当使用新样式的报表输出的时候,你会发现在那些报表数据项的位置上的细微区别。你还将发现在输出质量的增强。但这一切首先有个前提,你必须执行一个命令来启用新样式输出,因为 VFP 开发组为了向后兼容的目的默认使用的是老样式的输出。 这意味着你不需要对已有的报表做任何改动就可以在 VFP 9.0 中照样使用它们,或者你也可以通过这行下面的命令来切换到使用新样式的输出: SET REPORTBEHAVIOR 90 用下面的命令可以切换回使用旧的样式: SET REPROTBEHAVIOR 80 此外,当你在 REPORT 命令中使用了象 OBJECT TYPE 4 或者 OBJECT ox 这样的需要新行为特性的任何一个命令行选项参数的时候,系统会动态切换到使用新样式的报表。这里是一个示例,你可以试一下它来把你的报表内容输出到一个 HTML 文件: REPORT FROM (HOME(1)+ "tools\filespec\90frx.frx") ;
OBJECT TYPE 5 当这个命令运行的时候,VFP 将切换为使用 90 样式的报表引擎,并使用由 ReportOutput.app 提供的 HTMLListener 类来将你的报表输出为一个位于你的个人 Temp 目录中的 HTML 文件,并提示你文件名。单击 Yes 将文件名保存在 _CLIPTEXT 系统变量中,然后打开浏览器,按下 CTRL + V 将这个文件名粘贴到 URL 文本框中取,按下回车就会看到 9.0 版 FRX 表定义的上佳 HTML 表现。 你可以通过首先要求 VFP 将一个对 HTMLListener 的对象引用放入到一个你已经初始化的变量中去来获得对 HTMLListener 的更多控制权。然后就可以设置它的各种属性了,如下所示: LOCAL olistener

** 取得一个对 HTMLListener 类的引用
DO (_reportoutput) WITH 5, olistener ** 在执行下面的命令后会关闭用户界面的返回和提示
olistener.quietmode = .T. ** 指定自己的文件名和目录
olistener.targetfilename = "c:\htmltest.htm" ** 运行一个将会引用我们已经设置好了的 listener 的报表
REPORT FROM (_samples + "solution\reports\ledger.frx") ;
OBJECT olistener ** 在浏览器中显示结果
RUN /n Explorer.exe c:\htmltest.htm 你可以用类似的途径来使用 XMLListener 以建立一个带有所有数据的 XML 文件。 注意:由于 _reportoutput 也许并非总是指向默认的 ReportOutput.app,所以,更安全的办法是从FFC基础类库中新的 _reportlistener.vcx 类库来建立 XMLListener 或者 HTMLListener 的实例,入下面的示例所示: ** 在我手里的 Beta 版需要 Set safety off
SET SAFETY OFF
LOCAL olistener

** 获得对 FFC 基础类库中的 _Reportlistener.vcx
** 类库中的 XMLListener 类的一个引用
olistener = NEWOBJECT("XMLListener", ;
HOME(0) + "ffc\_reportlistener.vcx")

** 在执行下面的命令后会关闭用户界面的返回和提示
olistener.quietmode = .T. ** 只包含数据,不带布局信息
olistener.xmlmode = 0 && 只包含数据 ** 指定自己的文件名和路径
olistener.targetfilename = "c:\xmltest.xml" ** 运行一个将会引用已经设置好了的 listener 的报表
REPORT FROM (_samples + "solution\reports\ledger.frx") ;
OBJECT olistener ** 在浏览器中显示结果
RUN /n Explorer.exe c:\xmltest.xml 当 XML 数据弹出在浏览器中的时候,注意它的 <Data>段,其中包含着许多表示报表中原有的带区的标志,例如<PH>表示页标头,<D>表示细节带区,而<PF>则表示页注脚。这些东西会很有用的,例如可以将你自己的 XSLT 样式表应用给这个 XML 文件,以通过高度自定义的布局来展示数据。 此外,你还可以通过在前面的代码中改变这一行来获得与报表布局一样的 XML 表现: olistener.xmlmode = 1 && 只用报表布局 报表布局的信息在一个名为 <VFP-RDL> 的 XML 段中,也许你已经猜到了这个名字所代表的意思:“Visual FoxPro 报表定义语言”。这一段的 XML 包含大量的 <VFPFRXLayoutObject>标记,它描述了定义在报表的 FRX 中的所有显示元素,并可以通过如下设置来选择包含关于数据来源的信息: olistener.IncludeDataSourceInVFPRDL = .T. 下面这行代码可以一次就返回同时包含了 <VFP-RDL>报表布局段和 <Data> 段的一个XML文件: olistener.xmlmode = 2 && 报表布局和数据 还要等一段时间才会知道微软是否会提供某种能够将 VFP-RDL 定义转换为SQL Server新的报表服务使用的RDL格式的转换工具。不过,即使没有,VFP 9.0 也已经给了你足够让你自己实现它的资料和工具! 这两个演示 VFP 报表新的输出能力的示例只是冰山的一角。我希望你明白,你完全可以使用自己的 ReportListener 子类来超越 VFP 自带的 listener 类的能力,并通过在报表引擎中使用钩子(hook)来驱动你自己的输出、预览以及用户返回的行为特性。是的,它仍然可以运行你已有的报表。惊讶吧?但这是真的。
JohnShen 2004-10-27
  • 打赏
  • 举报
回复
好!

2,727

社区成员

发帖
与我相关
我的任务
社区描述
VFP,是Microsoft公司推出的数据库开发软件,用它来开发数据库,既简单又方便。
社区管理员
  • VFP社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧