| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1553 人关注过本帖
标题:实践:关系数据库的规范化
只看楼主 加入收藏
lyxc34
Rank: 2
等 级:论坛游民
帖 子:139
专家分:50
注 册:2011-7-3
收藏
得分:0 
嗯。对于自定义函数和过程,以及表单里面的新建属性和方法,我都不熟,所以很少想到用这个方法,现在记住了,我再去看看资料。
2011-07-09 18:37
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
不用什麽都建在表單對象上的,FP最經典的SET PROCEDURE TO命令,不要忘了!

寫在表單上的過程、函數,只有這個表單能用,其它表單要用,就得引用這個表單的對象,比如Form1.ReadExcel()這樣的格式,但是這是不規範的,把別處表單的東西拿來就用,等於當公共變量使喚,恰恰面向對象編程思維是最忌諱這種用法的,否則C++不用出現“類”這個概念。在VFP中,“類”就是面向對象的東西,它是一個黑箱,裏面的東西是私有的,除非顯式對外開放,否則外層代碼無法使用裏面的任何數據、代碼(VFP與C++相反的一點,就是類中的東西默認爲對外開放,但C++是默認隱蔽,所以我寫類代碼時都會考慮什麽屬性、過程、函數可以被外部調用,否則,應加上PROTECTED表明爲本類專用)。

因此,公共過程、函數的最佳位置,是外部的PRG文件。用一個PRG文件把所有公共的過程、函數寫在一起,啓動程序時SET PROCEDURE TO 這個文件,就可以隨時使用了。這在經典的dBASE、FP中,叫“模塊化編程”,是結構化語言最普遍的用法。C、Pascal、BASIC、dBASE、FoxBase、FoxPro等,都是這般用。面向對象的語言,是在結構化語言的基礎上發展起來的,首先也是結構化的,然後有所擴展,增加了面向對象的概念。不要以為面向對象的VFP就沒有FoxBase的東西了,一樣有的,仍然要用。

[ 本帖最后由 TonyDeng 于 2011-7-9 21:27 编辑 ]

授人以渔,不授人以鱼。
2011-07-09 21:25
lyxc34
Rank: 2
等 级:论坛游民
帖 子:139
专家分:50
注 册:2011-7-3
收藏
得分:0 
回复 12楼 TonyDeng
  感觉我要达到你说的这水平,需要很长的时间,我现在连自定义函数和过程都不熟,毕竟没有系统的学过理论。现在的短期目标只是把手上的学生信息管理系统做出来,争取开学就能用。现在是越做问题越多,关是如何建表和导入数据大概就花了近一个星期,改了好几次。
  晚上用了三个多小时的时间,把前面说的数据格式重排程序整合成了一个程序,里面定义了三个过程,代码如下,请指教!
程序代码:
R=272
C=11
SELECT C06,C01,C03,C07,C04,C05,C02,C09,C08,C51,C52 FROM cjb20.dbf INTO ARRAY ARRA1
SELECT xh FROM cjb20.dbf INTO ARRAY ARRA2
DIMENSION ARRA3(C)
ARRA3(1)="C06"
ARRA3(2)="C01"
ARRA3(3)="C03"
ARRA3(4)="C07"
ARRA3(5)="C04"
ARRA3(6)="C05"
ARRA3(7)="C02"
ARRA3(8)="C09"
ARRA3(9)="C08"
ARRA3(10)="C51"
ARRA3(11)="C52"

DO Cj WITH R,C,ARRA1
DO XH WITH R,C,ARRA2
DO KC WITH R,C,ARRA3


PROCEDURE CJ
  LPARAMETERS Row,Colu,Arra
  LOCAL NewArra(Row*Colu)
i=1
j=1
FOR n=1 TO Row*Colu
  IF i<=Row
    IF j<=Colu
    NewArra(n)=Arra(i,j)
    ELSE
    i=i+1
    j=1
    NewArra(n)=Arra(i,j)
    ENDIF
    j=j+1
  ENDIF
ENDFOR

USE data\tables\cjk.dbf
SELECT cjk
FOR k=1 TO Row*Colu
  GO BOTTOM
  APPEND BLANK
  REPLACE cj WITH NewArra(k)
  IF EOF()
    EXIT
  ENDIF
  SKIP
ENDFOR

RETURN
ENDPROC


PROCEDURE XH
  LPARAMETERS Row,Colu,Arra
a=RECCOUNT()-Row*Colu
USE h:\vfp\data\tables\cjk.dbf
SELECT cjk
GO a+1
FOR k=1 TO Row
  FOR n=1 TO Colu
  REPLACE xh WITH Arra(k)
  IF EOF()
  EXIT
  ENDIF
  SKIP
  ENDFOR
ENDFOR

RETURN
ENDPROC


PROCEDURE KC
  LPARAMETERS Row,Colu,Arra
a=RECCOUNT()-Row*Colu
USE h:\vfp\data\tables\cjk.dbf
SELECT cjk
GO a+1
FOR k=1 TO Row
  FOR n=1 TO Colu
    REPLACE kch WITH Arra(n)
    IF EOF()
      EXIT
    ENDIF
    SKIP
  ENDFOR
ENDFOR

RETURN
ENDPROC

  需要接受的变量就是R、A和数组ARR,这三个需要根据不同的表手动去改,如果不是因为ARR需要用SELECT语句传递数据,应该就可以做成一个方法,然后在表单里面去引用,实现格式的自动转化。这个思路是否能实现?    如果能实现的话这是不是就是你说的“黑箱”,也就是类?

[ 本帖最后由 lyxc34 于 2011-7-9 23:29 编辑 ]
2011-07-09 23:10
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
寫自定義函數,應仔細斟酌參數的傳遞。函數(過程)的動作是雷同的,那麽可變部分就由參數來控制。你的函數,需要傳遞的,一個是表名,一個是SELECT命令。對SELECT命令,可以用字符串傳送,比如令s="SELECT * ……",在函數中,通過宏代換來執行。

你現在將三個字段的處理分為三個函數,雖然是可以的,但不夠好,因為三個函數執行的動作仍然是雷同的,可以考慮合併爲同一個函數,這樣將來變動,只改一個函數就可以了,不用改多個函數。事實上,FP類的宏代換是別的語言很難實現的優勢,把字段也宏代換了,則函數的動作就是統一的。

我最近在忙着做一個系統,暫時不能仔細推敲你的程序,大致思路就是上面說的,你自己摸索一下吧。有需求就有動力,借一個實用的系統來學習,是難得的機會。當年,我也是在單位真正要用的項目上邊學邊做的,學校那些東西,根本不足以應付。這是一定要經歷的過程。

授人以渔,不授人以鱼。
2011-07-09 23:42
lyxc34
Rank: 2
等 级:论坛游民
帖 子:139
专家分:50
注 册:2011-7-3
收藏
得分:0 
  对哦,我忘记R和C只要有表就可以用函数来获取,那最后就只有2个变量了。我今天才在别人的讨论中才知道有Afield()这个函数,以前一直不知道怎么引用字段名,用这个函数就可以解决R和C值的获取。
  字符串传送SELECT语句这倒是第一回听说,没想过这个用法,不大懂,个人理解难道是直接将整个语句当字母组合而不是值通过S传递给自定义函数(过程)?
  宏一直没太理解这个概念,第一次接触和用宏是在玩魔兽世界的时候里面做技能宏,现在的理解感觉宏就和按键精灵一样,记录下一串需要不停重复的连续动作,然后每次以这一“串”动作为单位来执行,不知道这个理解对不对。还有类这个概念也很模糊。
  再就是三个函数合并的实现,因为学号、课程号和成绩通过数组传递后排序的方式不一样,如果一个函数搞定的话需要考虑的太多了,分解来做的话每个函数的数据逻辑比较简单点,光是这个简单的就花了我老半天,我现在的水平还只能停留在循环套循环和循环套条件上面,再麻烦点我怕我脑子不够用。不怕你见笑,上面这几个循环我测试了快2天才测试成功,这几天满脑子都是这些变量在跳。
  做这个系统其实没什么利益可言的,只是看教务科的同事每个学期都花大量的时间来做一些无脑的数据处理工作,查一个学生的成绩,得打开无数层文件夹,然后在N个EXCEL表里面去找,经常连他自己都找不到在哪儿,而期末考试安排,成绩录入,成绩单打印这些更是花时间,太没效率了,希望做个系统能有所改进。也借这个机会来学习学习,毕竟个人对这一部分比较感兴趣。

[ 本帖最后由 lyxc34 于 2011-7-10 00:20 编辑 ]
2011-07-10 00:18
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
宏的用法,你看看教材,都很詳細的。其實就是將一個字符串的內容轉換爲命令執行。比如,你在文本框中接收一串文字,那可以是一條任意合法的VFP指令,只要用宏代換一下,VFP就執行你在文本框輸入的命令,而VFP自己是不知道你輸入了什麽命令的。

授人以渔,不授人以鱼。
2011-07-10 00:29
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
我在壇上貼過Excel和數據庫互相導入導出數據的程序的,就是樣板,你可以參考一下。那可是我自己寫的,不是抄別人的。

授人以渔,不授人以鱼。
2011-07-10 00:39
lyxc34
Rank: 2
等 级:论坛游民
帖 子:139
专家分:50
注 册:2011-7-3
收藏
得分:0 
在哪个论坛?这个论坛好像没有找到啊。
还有今天又碰到个问题,我定义数组,然后给数组赋值,用了个循环:
程序代码:
USE cjb.dbf
C=RECCOUNT()
DIMENSION ARRA(C)
FOR n=1 TO C
ARRA(n)=FIELD(n)
ENDFOR

结果提示“找不到变量”,出错在ARR3(n)=FIELD(n),FIELD(n)我用?显示是正常的,说明错误在ARRA(n),难道是数组下标不能用变量?我在帮助文件里面也没有找到相应的解释。
2011-07-10 20:23
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
就在這個壇中。

FIELD(n)是取表中第n個字段的字段名,但你定義數組時用的是RECCOUNT(),那是表的記錄數,記錄數通常大於字段數,你For n=1 TO C,是對記錄數循環,肯定錯了,當n>字段數時,就出錯。正確的取法是C=FCOUNT(),這個才是取字段數的函數,不是RECCCOUNT()。

授人以渔,不授人以鱼。
2011-07-10 20:39
lyxc34
Rank: 2
等 级:论坛游民
帖 子:139
专家分:50
注 册:2011-7-3
收藏
得分:0 
那直接改成FOR n=1 TO FCOUNT()就OK了。
我就说应该不会不能用变量,我定义数组的时候也用的变量。
发现编程序的时候,一个小小的失误就得整好长的时间。
2011-07-10 20:45
快速回复:实践:关系数据库的规范化
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.027861 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved