请教vfp高手:这样代码重复性极大的程序段如何简化?

needacoder 2008-08-23 12:01:40
**messagebox(DATE()-cjkb.jksj)
SET TALK OFF
CLEAR
*SET STEP ON
jxsj=DATE()
SELECT yhb
SCAN
SELECT jkb
SCAN for cid=yhb.cid
SELECT hkb
LOCATE for cid=jkb.cid .and. jkid=jkb.jkid
IF FOUND()
STORE 0 to 正常利息,过期罚息,挪用罚息
CALCULATE MAX(hksj) to maxhksj for cid=jkb.cid .and. jkid=jkb.jkid
LOCATE for hksj=maxhksj .and. cid=jkb.cid .and. jkid=jkb.jkid
zzqje=qje
scan for cid=jkb.cid .and. jkid=jkb.jkid
b0=hkb.shksj
e0=hkb.hksj
p0='hkb.sqje'
IF jxsj<=b0
EXIT
ENDIF
IF jxsj>b0 .and. jxsj<e0
e0=jxsj
ENDIF
SELECT qnlxb
item='正常利息'
SCAN for cid=jkb.cid .and. jkid=jkb.jkid
IF b0<=qr .and. e0>=zr
b=qr
e=zr
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF b0>qr .and. e0<zr
b=b0
e=e0
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF (b0>qr .and. b0<zr) .and. e0>=zr
b=b0
e=zr
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF b0<=qr .and. (e0>qr .and. e0<zr)
b=qr
e=e0
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
ENDSCAN
SELECT gqlxb
item='过期罚息'
SCAN for cid=jkb.cid .and. jkid=jkb.jkid
IF b0<=qr .and. e0>=zr
b=qr
e=zr
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF b0>qr .and. e0<zr
b=b0
e=e0
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF (b0>qr .and. b0<zr) .and. e0>=zr
b=b0
e=zr
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF b0<=qr .and. (e0>qr .and. e0<zr)
b=qr
e=e0
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
ENDSCAN
SELECT fxb
item='挪用罚息'
SCAN for cid=jkb.cid .and. jkid=jkb.jkid
IF b0<=qr .and. e0>=zr
b=qr
e=zr
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF b0>qr .and. e0<zr
b=b0
e=e0
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF (b0>qr .and. b0<zr) .and. e0>=zr
b=b0
e=zr
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF b0<=qr .and. (e0>qr .and. e0<zr)
b=qr
e=e0
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
ENDSCAN
SELECT hkb
REPLACE zclx with 正常利息,gqfx with 过期罚息,nyfx with 挪用罚息,zlx with zclx+gqfx+nyfx
ENDSCAN
*★★★
IF jxsj>maxhksj
b0=maxhksj
e0=jxsj
p0='zzqje'
SELECT qnlxb
item='正常利息'
SCAN for cid=jkb.cid .and. jkid=jkb.jkid
IF b0<=qr .and. e0>=zr
b=qr
e=zr
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF b0>qr .and. e0<zr
b=b0
e=e0
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF (b0>qr .and. b0<zr) .and. e0>=zr
b=b0
e=zr
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF b0<=qr .and. (e0>qr .and. e0<zr)
b=qr
e=e0
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
ENDSCAN
SELECT gqlxb
item='过期罚息'
SCAN for cid=jkb.cid .and. jkid=jkb.jkid
IF b0<=qr .and. e0>=zr
b=qr
e=zr
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF b0>qr .and. e0<zr
b=b0
e=e0
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF (b0>qr .and. b0<zr) .and. e0>=zr
b=b0
e=zr
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF b0<=qr .and. (e0>qr .and. e0<zr)
b=qr
e=e0
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
ENDSCAN
SELECT fxb
item='挪用罚息'
SCAN for cid=jkb.cid .and. jkid=jkb.jkid
IF b0<=qr .and. e0>=zr
b=qr
e=zr
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF b0>qr .and. e0<zr
b=b0
e=e0
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF (b0>qr .and. b0<zr) .and. e0>=zr
b=b0
e=zr
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF b0<=qr .and. (e0>qr .and. e0<zr)
b=qr
e=e0
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
ENDSCAN
ENDIF
SELECT jkb
REPLACE zclx with 正常利息,gqfx with 过期罚息,nyfx with 挪用罚息,zlx with zclx+gqfx+nyfx
...全文
170 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
都市夜猫 2008-08-25
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 unlist 的回复:]
我认为,数据库编程,
关注的是资料表->数据(id),而不是指针,
你利用指针来定位,这样不利于模块化编程,
知识有限,请大家指教...
[/Quote]

有一定道理,也值得商榷

1. 利用指针定位不利用模块化。模块化编程是指程序结构,而非数据结构。使用记录指针丝毫不影响代码的结构化
2. 关注的是数据 id,而非指针。这要看使用的语言和数据库的能力,非 vfp 类语言只能使用 mssql/mysql 等外部数据库,操作数据库的语言非 sql 莫属,而 sql 是面向记录集的,或者说对数据库的“操作粒度”只在表级,而 vfp 提供给使用者的语句大部分是面向记录的,也即粒度在记录级上;即算 sql 有提供“游标”,其作用也不是用来提高操作效率的,情况恰恰相反,只能使数据库性能变坏,不得已时才会使用;而 vfp 的非 sql 语句只要你使用得当,可以成百上千倍的提高数据查询/维护效率。

面向记录的操作对其它语言来说是不可想象的,它们的运行效率完全依赖于良好的数据结构,以及数据库系统本身,高手与初学者的区别主要也体现在数据库设计和事务分割/处理上,在实现一个查询的 sql 代码上你无法分辨出高手与初学者的差别;而 vfp 的查询代码(如果不使用 sql 语句的话),只要看看数据库/表的构造,大都能看出水平的高低。

要说使用记录指针的坏处,就是当你专用其它语言并使用 xxSQL 时,可能会因为没有它而感到无所是从。

每个变更了数据表指针的函数/过程都应该在出口处恢复它,这也是模块化编程的基本要求:保存和恢复现场。不光是指针,工作区、索引、关系、SET 状态也一样,只要你改变了,就应该恢复;当然,有意为之的除外。

unlist 2008-08-25
  • 打赏
  • 举报
回复
我认为,数据库编程,
关注的是资料表->数据(id),而不是指针,
你利用指针来定位,这样不利于模块化编程,
知识有限,请大家指教...
jack_wang0823 2008-08-25
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 needacoder 的回复:]
引用 4 楼 unlist 的回复:
建议-正常利息,过期罚息,挪用罚息分别建成函数,
这样你自己明白,那些地方是可以共用的,就可以简化了

这个办法应该是最好的,但是我一直有疑虑:
代码重复的部分建函数的话,环境怎么管理?也就是说,是不是得注意不能让函数影响调用前后相关库的指针?函数是处于循环语句中,如果改变了被循环的数据库的指针的话,循环就被破坏了。这样使用函数得注意什么?
[/Quote]

调用函数之前,保存记录指针到一个变量...
就您这段代码来讲,也用不着保存记录指针, 因为没一次计算都已经历便整个表了,....
needacoder 2008-08-24
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 unlist 的回复:]
建议-正常利息,过期罚息,挪用罚息分别建成函数,
这样你自己明白,那些地方是可以共用的,就可以简化了
[/Quote]
这个办法应该是最好的,但是我一直有疑虑:
代码重复的部分建函数的话,环境怎么管理?也就是说,是不是得注意不能让函数影响调用前后相关库的指针?函数是处于循环语句中,如果改变了被循环的数据库的指针的话,循环就被破坏了。这样使用函数得注意什么?
needacoder 2008-08-24
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 qd163 的回复:]
用vfp9.0版本,有一个icase()函数,好好学习一下应该可以解决您的大部分代码重复的问题.

在vfp9.0中可以使用icase函数,具体用法为:

ICASE( lCondition1, eResult1 [, lCondition2, eResult2] ...
[, eOtherwiseResult])


参数
lCondition
指定一个作为逻辑表达式被计算的条件。如果 lCondition 计算为假(.F.),ICASE( ) 继续计算下一个条件并为计算为真(.T.)的条件返回相应的 eResult。如果 lCondition 计算…
[/Quote]
不想用vfp9,太大,我移动工作,到哪里都得装vfp,vfp9不好带,安装慢,它的新功能也没什么太多有用的。
needacoder 2008-08-23
  • 打赏
  • 举报
回复
唉,csdn为什么总是把我排好的缩进格式忽略不计呢?
怕是没人能看出我的程序结构了…………
needacoder 2008-08-23
  • 打赏
  • 举报
回复
<接上页>
ELSE
*
SELECT jkb
b0=jksj
e0=jxsj
p0='jkb.jkje'
SELECT qnlxb
item='正常利息'
SCAN for cid=jkb.cid .and. jkid=jkb.jkid
IF b0<=qr .and. e0>=zr
b=qr
e=zr
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF b0>qr .and. e0<zr
b=b0
e=e0
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF (b0>qr .and. b0<zr) .and. e0>=zr
b=b0
e=zr
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF b0<=qr .and. (e0>qr .and. e0<zr)
b=qr
e=e0
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
ENDSCAN
SELECT gqlxb
item='过期罚息'
SCAN for cid=jkb.cid .and. jkid=jkb.jkid
IF b0<=qr .and. e0>=zr
b=qr
e=zr
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF b0>qr .and. e0<zr
b=b0
e=e0
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF (b0>qr .and. b0<zr) .and. e0>=zr
b=b0
e=zr
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF b0<=qr .and. (e0>qr .and. e0<zr)
b=qr
e=e0
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
ENDSCAN
SELECT fxb
item='挪用罚息'
SCAN for cid=jkb.cid .and. jkid=jkb.jkid
IF b0<=qr .and. e0>=zr
b=qr
e=zr
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF b0>qr .and. e0<zr
b=b0
e=e0
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF (b0>qr .and. b0<zr) .and. e0>=zr
b=b0
e=zr
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
IF b0<=qr .and. (e0>qr .and. e0<zr)
b=qr
e=e0
&item=&item+(e-b)*ll*&p0/100
?item,jkb.cid,jkb.jkid,yhb.xm,b,e,e-b,(e-b)*ll*&p0/100,ll/100,&p0
ENDIF
ENDSCAN
*
ENDIF
SELECT jkb
ENDSCAN
SELECT yhb
ENDSCAN
RETURN
unlist 2008-08-23
  • 打赏
  • 举报
回复
建议-正常利息,过期罚息,挪用罚息分别建成函数,
这样你自己明白,那些地方是可以共用的,就可以简化了
qd163 2008-08-23
  • 打赏
  • 举报
回复
用vfp9.0版本,有一个icase()函数,好好学习一下应该可以解决您的大部分代码重复的问题.

在vfp9.0中可以使用icase函数,具体用法为:

ICASE( lCondition1, eResult1 [, lCondition2, eResult2] ...
[, eOtherwiseResult])


参数
lCondition
指定一个作为逻辑表达式被计算的条件。如果 lCondition 计算为假(.F.),ICASE( ) 继续计算下一个条件并为计算为真(.T.)的条件返回相应的 eResult。如果 lCondition 计算为空(.NULL.),Visual FoxPro 对待 lCondition 作为它计算为假(.F.)。
eResult
指定如果 lCondition 计算为真(.T.)时的返回结果。
eOtherwiseResult
包含如果所有条件都计算为假(.F.)时返回的结果。
返回值
一旦 lCondition 计算为真(.T.),ICASE( ) 就返回当前第一个 eResult。

如果所有条件都计算为假(.F.),ICASE( ) 返回 eOtherwiseResult。

如果省略 eOtherwiseResult,并且所有的条件都计算为假(.F.),则 ICASE( ) 返回空(.NULL.)。

说明
必须总是两个一组地传递参数给 ICASE( )。如果传递了一个奇数数量的参数,则最后一个参数被当作 eOtherwiseResult 返回值。

ICASE( ) 最多可以传递 100 对参数。

如果在筛选表达式中使用一个长的 ICASE( ) 表达式,象在一个 FOR 或 WHERE 子句中,确保 SYS(3055) 设置到一个适当的复杂性层次以避免发生错误。更多的信息,请参见 SYS(3055) - FOR 和 WHERE 子句的复杂性。


示例
下面的例子示范了使用 ICASE( ) 计算表达式并返回基于哪些表达式结果特定值的不同情况。

下面的代码行显示"First is true",因为第一个表达式计算为真(.T.)。


? ICASE(1+1=2,"First is true",1+1=3,"Second is false","None are true")


下面的代码行显示"Second is true",因为第一个表达式计算为假(.F.),但第二个表达式计算为真(.T.)。


? ICASE(1+2=2,"First is false",1+2=3,"Second is true","None are true")


下面的代码行显示"None are true",那是被指定的最后结果,因为第一个和第二个表达式都计算为假(.F.)。


? ICASE(1+2=2,"First is false",1+1=3,"Second is false","None are true")

2,722

社区成员

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

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