转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 电脑应用 >> 电脑技术 >> 正文
Visual Foxpro中的多用户及数据缓冲问题         ★★★

Visual Foxpro中的多用户及数据缓冲问题

作者:闵涛 文章来源:闵涛的学习笔记 点击数:2015 更新时间:2006/7/27

主题:Visual Foxpro中的多用户及数据缓冲问题

绍 

很多狐友(Foxers)都是从Dbase―FoxBase―Foxpro―VFP这样一条路走过来的,如果说从FoxBase 到Foxpro是一次飞跃,那么从Foxpro到VFP就是一次升华。漫漫编程路上的两次大变化都伴随着升级的兴奋与适应的痛苦,惯性思维往往使我们容易忽略新版本的新内容。我们先来看看下面这个在表单中编辑记录的例子:

在Foxpro 2.X时代,我是这样设计的:

1、   在屏幕上放置与表中字段对应的文本框(TEXT)控件,用来存放相应的内存变量(如M.CUST_IDT和M.NAME等);

2、   当用户将表的指针定位到某一特定记录时(比如按了"下一个记录"按钮),就用scatter memvar 语句把该记录的所有字段传给相应的内存变量,再用show get来刷新屏幕上的文本框中显示的值。在这一时刻,用户是不能编辑这些变量的(此时文本框或者被设置为不可用(Disabled),或者其when子句返回的是.F.值),因为用户处在"浏览"状态。

3、   当用户选择了"编辑"按钮时,程序就锁定该记录(如果无法锁定,则显示提示信息),然后检测每个字段值和相应的内存变量值(如果有不同的,说明一定是有其它用户在我们进入编辑状态后修改并保存了记录,在这种情况下,要显示提示信息),之后再用scatter memvar和show get语句刷新,这样用户就看到记录中的当前值了;

4、   如果所有字段和相应的内存变量完全匹配,就把变量所在的文本框控件都设置为可用(Enabled)或都让when子句返回.T.,以便让用户可以来编辑这些变量;

5、   当用户选择了"保存"按钮时,根据一定的规则对输入的数据进行检验,然后用gatter memvar语句将内存变量写回到记录中,并对记录解锁(unlock),再把所有的内存变量所在文本框设置为不可用(Disabled),或者让其when子句返回.F.值,这时,用户又回到了"浏览"状态。

请注意,在这一过程中我们没有直接读写记录,而是先将各字段值赋给同名内存变量,再让用户编辑这些内存变量,如果一切正常再把这些内存变量写回到记录当中。之所以用这种方法主要是为了保护表,如果不符合验证规则,就不允许数据回存到表中。另一点要注意的就是,当用户编辑记录时要对记录加锁(lock),这样就防止了其它用户在同一时间编辑同一条记录。但是,这种方法有一个很大的缺点:假设一个用户开始编辑某一记录,在他按下"保存"按钮前,记录一直处于锁定状态,如果此时该用户有事暂时外出,如午餐,那么其它用户就不能对该记录进行编辑了L。

当然,你可以不在进入"编辑"状态时加锁,而只在"保存"记录之前加锁,保存完后马上解锁,这样可以使记录被锁定时间最短,以便其它用户有充分的时间编辑该记录。但是这也有缺点,试想:如果用户编辑了内存变量,这后点击"保存",可如果其它用户在你点"保存"之前也编辑了这条记录,并且还没保存,这时会发生什么现象呢?你的保存要覆盖他人的修改吗?要放弃你的修改吗?这些都是我们要在设计时认真考虑的问题。

我们如此费尽心机地设计,其目的都是为了保护数据。如果你写的程序只是你一人使用,那设计起来可能会简单得多:你可以直接读取记录中的字段,比如你可以直接在屏幕中browse一个表,这样你输入的内容就直接写进记录了。但是,我们不能担保那些最终用户也象您一样都清楚能输入什么不能输入什么,我们不得不在用户与数据表之间建立一个"防火墙"来保护数据。在Foxpro 2.X中创建这样的"防火墙"要写一大堆的代码!

值得我们高兴的是,VFP提供了内建的"防火墙"机制,它有两方面的作用:一是可直接读取记录,二是只允许通过所有检验规则的数据被写回。这一机制就是缓冲。

缓冲

在刚才我们讲到的例子中,是通过内存变量存贮记录内容,这种方法可以被认为是手工建立了一个数据缓冲器,通过使用scatter memvar把数据从记录中传送到"缓冲"中,再用gather memvar从"缓冲"中传回到记录。

VFP不仅能自动进行单条记录的缓冲(称为行缓冲或记录缓冲),而且还支持另一种类型的缓冲,即表缓冲,表缓冲可通过缓冲器存取多条记录。行缓冲一般用于一次存取一个记录时,这种机制普遍应用于数据录入,就象前文提到的那样:用户可以在表单中显示或编辑单条记录。表缓冲则适用于一次更新多条记录,比如一张订货单的明细录入屏幕,通过对物品明细表使用表缓冲,可以允许用户编辑多条明细记录,最后一次性地将所有明细记录保存或放弃。

除了两种缓冲机制,VFP还有两种锁定机制。前文讲述的那种在Foxpro 2.X中的加锁方式被称为保守式锁定法(或悲观锁定法)――当用户选择"编辑"时加锁,直到用户选择了"保存"后再解锁。这种加锁机制确保了当本用户修改记录时其它用户都不能修改该记录,但这样做有利有弊,视具体情况而定。前文所讲的另一种加锁方式叫做开放式加锁法(或乐观锁定法)――只有在写回记录时才锁定该记录,然后马上解锁。这种加锁机制虽然使记录最大时间内可给别的用户使用,但我们必须处理当两个用户同时编辑记录时所造成的冲突。正如我们下面将要看到的,这对于VFP来说真是太简单了,在VFP中大多数的情况下都选用开放式缓冲机制。

因为在VFP中记录可以被自动缓冲,所以就不必再用"人工缓冲"机制了,换句话说,现在我们可以直接读记录中的字段而不必关心为每个字段设内存变量。要保存修改,我们只要简单地告诉VFP将缓冲器中的内容写到表中即可,若是取消修改,告诉VFP不写入即可。过会儿我们将看到这是如何操作的。

当打开一个表时,VFP创建一个"临时表"(cursor)作为缓冲器,这个"临时表"用来定义表的属性。对于本地表来说,"临时表"的唯一属性是用来定义缓冲方式的的,视图和远程表还有一些本文讨论范围之外的其它属性,这些属性的值用CursorSetProp()函数设置,用CursorGetProp()取得。我们过会儿将看到如何使用这些函数。

当追加记录时,表缓冲有一个有趣的特性:随着记录添加到缓部器中,它们被赋予一个负记录号,第一个加入的记录,recno()返回值为-1,第二个返回值为-2,依此类推。你可以用一个带负数的go命令在缓冲中定位到追加的记录上。这在处理记录号时很有用,比如为了确认变量InRecno是否为一个可用的记录号,在缓冲状态下,要检测between(InRecno,1,reccount()) OR InRecno<0 而不能只用between(InRecno,1,reccount())。

使用缓冲

缺省情况下缓冲器是关闭的,这种情况下在更新表时VFP和Foxpro 2.X是一样的,要使用缓冲你必需将它打开。缓冲适用于自由表及数据库中的表。要用缓冲还要set multilocks on,因为multilocks缺省值是OFF,如果你忘了设置其值为ON,会出现错误信息。你可以把multilocks=ON加入到CONFIG.FPW文件中,或是用"工具"栏下的"选项"功能保存其值为ON。

我们通过cursorsetprop(‘Buffering’,<n>,<Alias>)来定义缓冲方式。如果是对当前表设置缓冲,不必定义<Alias>,根据你想要的缓冲及锁定方式<n>为下列值: 

缓冲及锁定法
<n>值

无缓冲
1

保守式行缓冲
2

开放式行缓冲
3

保守式表缓冲
4

开放式表缓冲
5


例如,要将当前表设置为开放式行缓冲,用cursorsetprop(‘Buffering’,3),要取得当前正打开的表的缓冲方式,用cursorgetprop(‘Buffering’)。

要设置一个表单的缓冲方式,你可以在表单的Load事件中用cursorsetprop()定义所有用到的表,但最好的方法是直接设置表单的BufferMode属性来决定是开放式还是保守式(缺省值为"无"),这样设置后,该表单就会自动对绑定到网格(Grid)中的表使用表缓冲,对其它表则使用行缓冲。如果你的表单使用了数据环境,你可以对某一个表的BufferModeOverride属性按你的意图设置缓冲,以取代表单的BufferMode属性。

如果有用户正在修改缓冲记录中的数据(此时用户处在"编辑"状态),你不仅可以取得他们输入到每个字段中的值,还能取得每个字段的初始值和当前值(此值为磁盘中的实际值),为此VFP提供了oldval()和curval()函数。 

要得到:
使用:

用户输入值(缓冲的数据)
<fieldname> OR <alias.fieldname>

用户未做任何改动之前的值
Oldval(‘<fieldname>’)

当前记录中的值
Curval(‘<fieldname>’)


注: curval()和oldval()仅用于开放式缓冲。

你可能搞不懂curval()返回值和oldval()返回值有什么不同,如果是在单用户程序中,二者之间是没什么区别,但是如果是在网络中,在开放式锁定下,很可能在本用户编辑一条记录时,另一个用户也编辑同一条记录,并在本用户"保存"之前进行了"保存",下面是一个例子:

郑某将CONTACTS.DBF指针定位到第2条记录,并点击了"编辑"按钮: 

字段
缓冲值

初始值
Oldval()
当前值Curval()

姓名
李达

李达

李达

公司名称
狐友技术开发公司

狐友技术开发公司

狐友技术开发公司


然后,郑某将公司名称改为"狐友俱乐部",但还没有保存记录: 

字段
缓冲值

初始值
Oldval()
当前值Curval()

姓名
李达

李达

李达

公司名称
狐友俱乐部

狐友技术开发公司

狐友技术开发公司


就在此时,于某也将CONTACTS.DBF指针定位到第2条记录,并点击了"编辑"按钮,他改变了公司名称为"猎狐者俱乐部",并保存。此时在郑某的机器上会看到如下结果: 

字段
缓冲值

初始值
Oldval()
当前值Curval()

姓名
李达

李达

李达

公司名称
狐友俱乐部

狐友技术开发公司

猎狐者俱乐部


注意:在上表中CONTACTS.公司名称、oldval(‘公司名称’)以及curval(‘公司名称’)将返回不同的值。访问记录中各字段的初始值、缓冲值和当前值,你可以:

l      通过比较缓冲值和初始值来确定哪些字段被用户修改了;

l      通过比较初始值和当前值来检测在开始编辑后,网络中是否有其它用户修改了同一条记录。 如果你不关心初始值和当前值,而只是希望检测到某个字段中的内容是否被修改过,可以用getfldstate()函数。这个函数返回一个数值,指出当前记录是否被做了修改。Getfldstate()按以下格式调用:

getfldstate( <fieldName> | <FieldNumber> [ , <Alias> | <WorkArea> ] )

返回值及其意义如下表所示: 

返回值
意义

1
没改变

2
字段被编辑或者记录的删除标记被改变

3
添加了一条新记录但没编辑字段,以及记录的删除记录未改变

4
添加了一条新记录并编辑了字段,或者记录的删除标记被改变


记录的删除标记被改变,是指删除记录或恢复(recall)记录。值得注意的是:对记录删除后又马上进行了恢复,尽管对记录来说没影响,但是其删除标记被改变过,因此,getfldstate()函数会返回2或4。

如果你没有定义别名或工作区,getfldstate()将对当前打开的表进行操作。将<FieldNumber>定义为0,该函数返回当前记录的添加及删除状态,如果定义为-1,将返回一个字符串,在这个字符串中,第一个数字反映整个表的状态,以后每个数字返映的是各字段的状态。

[1] [2] [3]  下一页


[系统软件]Visual Studio 2005 Express Beta Products 下载链…  [系统软件]曝光Visual Foxpro 9.0 最新秘密
[系统软件]FOXPRO 系统指标  [系统软件]Visual FoxPro9.0中扩展报表系统功能
[系统软件]Visual FoxPro:我是旁观者  [系统软件]Visual Studio 2005 Express Editions Beta 2 下载…
[系统软件]ASP对FoxPro自由表(DBF文件)的操作  [系统软件]Boost库在XP+Visual C++.net中的安装
[系统软件]Visual Studio 2005 Express Edition 正式版下载地…  [常用软件]Visual Foxpro通用报表打印程序
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · 电脑技术  · 操作系统
    · 磁盘工具  · 视音频技术
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台