VFP中使用Grid控件设计通用录入界面_第1页
VFP中使用Grid控件设计通用录入界面_第2页
VFP中使用Grid控件设计通用录入界面_第3页
VFP中使用Grid控件设计通用录入界面_第4页
VFP中使用Grid控件设计通用录入界面_第5页
已阅读5页,还剩6页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Grid是VFP功能强大的表格(或者说网格)控件,它提供了比Browse窗口强大得多的控制方式。Grid是包含列对象的容器对象,而列对象包含了列标题对象及列控件对象,均有各自相应的属性集,因此我们可以完全控制表格中的任何一个元素,设计出通用的报表录入界面。

下面我们就详细讨论如何使用Grid控件设计通用录入界面,并解决几个设计过程中经常碰到的问题。

一、基本原理思路

设计灵活性、通用性较强的录入界面较为合适的方法是:采用数据表(DBF文件)控制Grid控件的行列显示信息、显示方式。因此,我们将Grid控件的数据源RecordSource设为数据表(DBF文件),其数据格式、显示方式及行列提示信息则分别由数据表RowMsg.DBF(控制表格的行即记录方面信息)、ColMsg.DBF(数据格式并控制Grid控件的列方面信息)进行控制。另外,一般来说指定Grid控件第一列显示行提示信息,若有多个提示信息字段,可连接处理为一列。

二、前期准备工作

1.创建表RowMsg.DBF,该表有2个字段,用于显示Grid控件行信息:

Create

Table

RowMsg(Code

C(5),Name

C(33))

2.

创建表ColMsg.DBF,该表有6个字段,用于控制、显示表格各列信息:

Create

Table

ColMsg(Code

C(5),Name

C(20),NeedIn

L(1),Field_Name

C(10),Field_Type

C(1),Field_Len

N(3),Field_Dec

N(3))

3.创建表单In_Grid,将其属性Name改为“FrmGrid”,

Caption改为“数据录入/修改窗口”;在表单上放置Grid控件,将其属性Name改为“GridDat”;在表单上放置Command控件,将其属性Name改为“CmdExit”,

Caption改为“关闭退出”。

三、初步设计工作

1.先在表单的Init事件中写入如下代码:

Set

Talk

Off

Set

Safe

Off

CLOSE

ALL

With

ThisForm

.AutoCenter=.T.

&&表单自动居中

.ControlBox=.F.

&&去除表单的控制框

.Width=_Screen.Width

&&表单宽度同屏幕

EndWith

**/由ColMsg.DBF生成输入数据表Dat.DBF

**/

Sele

0

Use

ColMsg

Copy

To

TmpStru

Field

Field_Name,Field_Type,Field_Len,Field_Dec

Copy

To

TmpColMsg

For

NeedIn

Create

Dat

From

TmpStru

&&生成Dat.DBF

Eras

TmpStru.DBF

Sele

0

Use

TmpColMsg

Alias

ColMsg

Sele

0

Use

RowMsg

Index

On

AllTrim(Code)

To

TmpRowMsg

Scan

Insert

Into

Dat(Code)

Values

(RowMsg.Code)

&&由RowMsg.DBF生成Dat.DBF的所有记录

EndScan

Sele

Dat

Go

Top

Set

Rela

To

AllTrim(Code)

Into

RowMsg

With

ThisForm.GridDat

.FontName="宋体"

.FontSize=10

.DeleteMark=.F.

&&去除Grid的删除标记列,以美化界面

.RecordMark=.F.

&&去除Grid的记录选择标记列,以美化界面

.ScrollBars=0

&&去除Grid的水平及垂直滚动条,以美化界面

.AllowHeaderSizing=.F.&&设定Grid的标题栏的高度不可改变

.AllowRowSizing=.F.

&&设定Grid的各行高度不可改变

.ColumnCount=Recc("ColMsg")+1

.RecordSourceType=2

.RecordSource="Dat"

**/下面指定表格第一列显示行提示信息,并设置该列有关属性。/**

.Column1.ControlSource="Code+RowMsg.Name"

&&将2个提示信息字段连接处理为一列

.Column1.Enabled=.F.

&&该列不能编辑,焦点也不能移入

.Column1.Width=300

.Column1.BackColor=RGB(192,192,192)

.Column1.Header1.Caption="指标代码及名称"

**/下面指定表格其他列及其标题,并设置有关属性。/**

Sele

ColMsg

Scan

lcCol=AllTrim(Str(Recn()+1,5))

With

.Column&lcCol.

.ControlSource="Dat."+Alltrim(Field_Name)

.Header1.Caption=AllTrim(Name)

.Width=90

EndWith

EndScan

**/下面设置表格宽度,并使其水平居中。/**

lnGridLen=.Column1.Width+Recc("ColMsg")*.Column2.Width+10

.Width=IIF(m.lnGridLen>ThisForm.Width*0.95,ThisForm.Width*0.95,m.lnGridLen)

.Left=(ThisForm.Width

-

.Width)/2

ThisForm.CmdExit.Left=

(ThisForm.Width

-

ThisForm.CmdExit.Width)/2

&&使命令按钮水平居中

EndWith

2.在命令按钮CmdExit的Click事件中写入代码:ThisForm.Release

至此,

该表单已可顺利运行。

四、进一步完善

该表单虽已可顺利运行,但却存在着如下两个主要不足之处:

1.输入焦点不能自动下移,即在第一行最后一个字段上打回车键,焦点不能自动转到下一行的第一个字段上,而是回到第一行的第一个字段上。

2.信息提示列(最左一列)无法固定,即随着输入焦点的右移,信息提示列将移出屏幕而不再可见,失去其信息提示的作用。

下面我们就来详细讨论并解决这两个难题。

(一)

输入焦点自动下移

解决此问题可用的方法较多。经过多方比较、测试,我们认为采用表单的KeyPress事件解决这个问题较为合适(当然采用Grid控件的BeforeRowColChange事件或AfterRowColChange事件也完全可以)。KeyPress事件在用户按下并释放某键时发生,由具有焦点的对象接收。表单可在下列两种情况下接收KeyPress事件:

(1)表单中不包含任何控件或所有控件都不可见或都未激活。(2)表单的KeyPreview

属性设置为.T.。

显然本例不适用情况(1),只适用情况(2)。为此,需在表单的Init事件代码中增加如下代码:

ThisForm.KeyPreview=.T.

然后在表单的KeyPress事件中写入如下代码:

LPARAMETERS

nKeyCode,

nShiftAltCtrl

&&这行代码由系统自动产生,不必录入

**/判断当前焦点是否在Grid控件上及按键是否是回车键或TAB键**/

With

ThisForm.ActiveControl

IF

Upper(.Name)=’GRIDDAT’

And

(m.nKeyCode=13

OR

m.nKeyCode=9)

if

.ActiveColumn=Recc("ColMsg")+1

&&判断当前焦点是否在Grid控件的最后一个字段上

KeyBoard

"{DnArrow}"

Plain

&&是则下移一行

Endif

ENDIF

EndWith

至此,

输入焦点自动下移的问题基本解决。(二)

固定信息提示列(最左一列)

一般情况下,第一列往往是整条记录的提示信息。Foxpro的Browse命令有Lock参数,可指定在浏览窗口左分区中可见字段数,这样在数据浏览时,可保证当发生水平滚动而使最左几列不可见时,仍能在浏览窗口的左分区中看到这几列的内容。这在输入带有较多字段的数据情况下非常有用。

在Grid控件中可通过设置其Panel、Partition及PanelLink属性解决这个问题。这里我们要解决更难些的问题:

当Grid控件右面板的第一列可见时,左面板第一列消失,因为这时不需要显示两个第一列;而当Grid控件右面板的第一列不可见时,左面板显示第一列的内容。也即所谓的固定信息提示列(最左一列)。

解决此问题的方法也很多,为简化编程,我们仍采用表单的Init事件及KeyPress事件(当然也可采用Grid控件的BeforeRowColChange事件或AfterRowColChange事件)。

在表单的Init事件代码中增加如下代码:

注:Partition属性指定一个表格是否拆分为两个分区,并且指定相对于表格左分区的拆分位置。当Partition设置为零时,表示不拆分表格;为非零时表示拆分位置的值(实际上就是左分区的宽度)。这里我们判断一下该Grid控件的宽度是否超过表单宽度(实际上是表单宽度乘0.95,以使Grid左右留有一定空白,以美化界面),是则Partition设置为信息提示列的宽度,以适应前面提出的固定信息提示列的要求;否则Partition设置为零(因为此时已不需要分区)。

(三)其他细节问题

经过上述一系列改进后,报表通用录入界面已基本实现,但仍存在着几个细节问题:

(1)

初始进入该界面及录完一行进入下一行时,信息提示列会出现重复显示,如附图1示,解决方法:分别在表单的Init事件及KeyPress事件代码中适当位置增加如下代码即可:

KeyBoard

"{TAB}{BACKTAB}"

Plain

(2)

我们希望在最后一行的最后一列数据在打回车后,焦点能自动移到命令按钮上,以便我们选择进行下一步工作,

如”存盘退出”.

“继续录入”.

“放弃关闭”等等,实践中发现在KeyPress事件代码中适当位置增加ThisForm.CmdExit.SetFocus()不行,只能用KeyBoard

"{Ctrl+Tab}"

Plain实现。

(3)

不设置水平及垂直滚动条的优点显而易见,一是界面简洁美观,如附图2示,

带有水平及垂直滚动条的录入界面显得不简洁,有些拖泥带水,且右分区的左下端垂直滚动条上的那个细黑条是分区标志,拉动它可以重新调整左右分区,以致破坏业已设计好的录入界面;二是编程大大简化,如单击水平滚动条时左右分区的拆分会出现问题(当然可通过Grid控件的Scrolled事件编程解决)。但不可否认也带来上下左右翻屏的不便,主要是上下翻屏的不便(左右滚屏可通过连续按TAB键、Shift+TAB组合键实现)。上下翻屏原可通过PgUp/PgDn键解决,但此时使用PgUp/PgDn会出现信息提示列与右分区的数据列不相对应的情况,因此我们重新定义PgUp/PgDn键,在表单的Init事件代码中增加如下2行代码:

ON

KEY

LABEL

PgUp

IIF(Bof("Dat"),Application.DoCmd("=MessAgeBox(’已是第一条记录!’,;

’提示信息’)"),Application.DoCmd("SKIP

-12"))

ON

KEY

LABEL

PgDn

IIF(EoF("Dat"),Application.DoCmd("=MessAgeBox(‘已是最后一条记录!’,;

’提示信息’)"),Application.DoCmd("SKIP

12"))

注:通过DoCmd函数、MessageBox函数实现以下功能:

按PgUp向上滚动12行,若已到首行则提示“已是第一条记录!”;按PgDn向下滚动12行,若已到末行则提示“已是最后一条记录!”。

五、结束语

至此,我们已较为圆满的实现了使用Grid控件设计通用录入界面。应该指出的是,可以进一步完善的地方仍很多:

1.信息提示列及各数据列的宽度设置。可用RowMsg.DBF及ColMsg.DBF中的相应字段长度乘上某一系数得到,也可在RowMsg.DBF及ColMsg.DBF中设置相应字段直接确定其宽度。我们采用了前法。

2.水平及垂直滚动条的设置。当数据列超过30列后,有水平滚动条就显得较为方便。遗憾的是,VFP本身未提供单独的滚动条控件(当然损失一些界面的美观简洁,使用Grid控件自身的滚动条完全可以实现),因此,我们只能使用OLE控件,如MicroSoft

Forms

2.0

ScrollBar,并通过设置其相应的属性及事件编程,解决这个问题。本文限于篇幅,不再讨论。另外,不使用Grid控件而直接使用已较好解决这些问题第三方OLE控件,如TrueDBGrid、FlexGrid、MicroSoft

DataGrid

Control等等,也是一种解决方法,但已不属本文范围,不再讨论。

本例在Windows9x/WindowsXP、Visual

Foxpro

5.0/6.0下调试通过。本例所有事件的完整代码附下。表单的Init事件完整代码如下:

Set

Talk

Off

Set

Safe

Off

CLOSE

ALL

ON

KEY

LABEL

PgUp

IIF(Bof("Dat"),Application.DoCmd("=MessAgeBox(’已是第一条记录!’,’提示信息’)"),Application.DoCmd("SKIP

-12"))

ON

KEY

LABEL

PgDn

IIF(EoF("Dat"),Application.DoCmd("=MessAgeBox(‘已是最后一条记录!’,’提示信息’)"),Application.DoCmd("SKIP

12"))

With

ThisForm

.KeyPreview=.T.

.AutoCenter=.T.

.ControlBox=.F.

.Width=_Screen.Width

EndWith

Sele

0

Use

ColMsg

Copy

To

TmpStru

Field

Field_Name,Field_Type,Field_Len,Field_Dec

Copy

To

TmpColMsg

For

NeedIn

Create

Dat

From

TmpStru

Eras

TmpStru.DBF

Sele

0

Use

TmpColMsg

Alias

ColMsg

Sele

0

Use

RowMsg

Index

On

AllTrim(Code)

To

TmpRowMsg

Scan

Insert

Into

Dat(Code)

Values

(RowMsg.Code)

EndScan

Sele

Dat

Go

Top

Set

Rela

To

AllTrim(Code)

Into

RowMsg

With

ThisForm.GridDat

.FontName="宋体"

.FontSize=10

.DeleteMark=.F.

.ScrollBars=0

.ColumnCount=Recc("ColMsg")+1

.RecordSourceType=2

.RecordSource="Dat"

.Column1.ControlSource="Code+RowMsg.Name"

.Column1.Enabled=.F.

.Column1.Width=Len(Code+RowMsg.Name)*8

.Column1.BackColor=RGB(192,192,192)

.Column1.Header1.Caption="

指标代码及名称

"

.Panel=1

.PanelLink=.T.

lnGridLen=.Column1.Width+10

Sele

ColMsg

Scan

lcCol=AllTrim(Str(Recn()+1,5))

With

.Column&lcCol.

.ControlSource="Dat."+Alltrim(Field_Name)

.Header1.Caption=AllTrim(Name)

.Width=Len(.Header1.Caption)*7

lnGridLen=m.lnGri

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论