进一步谈progress

来源:互联网 发布:午后淡茶 4js 微博 编辑:程序博客网 时间:2024/05/16 10:53

progress中的变量以及数据类型。

有一点我觉得和别的语言不一样的就是progress中的变量名的定义很随便, 就是说语言内置的关键字也可以用来做变量名。当然了以数字或者特殊符号开头也是不允许的。


比如说,它的定义变量的语法是这样的,(这里我只是给出最常用的方式,这个语句其实很复杂,有点儿像是unix/linux下的命令行命令,带有各种各样的参数选项,但是常用的就那么几个):
define variable your-avr-name as data-type no-undo.

define variable是必需的,因为除了变量,你还可以定义别的东西。
这里的变量类型可以是:
character或者简写作char。这里它实际上是一个长度不限的字符串。
date,日期类型
decimal,小数最多可以包括50位以及小数点后10位
integer,
logical,就是布尔变量,其值可以是true/false或者yes/no
handle,句柄
com-handle,专门为com控件而用的句柄
widget-handle,progress自身的窗体控件句柄
recid,一个数据库记录id,类似于rowid
memptr,内存指针
raw,原始数据

 

下边说一说常用的句型表达式。
1。判断分支语句
if [expression] then
   [statement]
else if [expression] then
   [statement]
...
else
   [statement]

如果有多个语句组成一个语句块儿的话,要用
do:
[statements]
end.框起来,就像c语言里的{}一样。

当然了如果只有一个表达式的话,do: end.是不需要的,可以直接这样:
if [expression] then
   statement.

分支语句是:
case [expression]:
    when [value] or when [value] or when... then:
       [statement]
    when ... then:
       [statement]
    otherwise
       [statement]
end (case)

 

2.循环语句是:
[label:]
do [variable] = [expression1] to [expression2] [by [step]]:
[block]
end.
或者是:
do while [expression]:
[block]
end.

当然了调处循环就是 leave [label].

还有一种就是repeat ...end.格式. 和do..end.差不多,但是还是有区别。

 

progress里的子过程和函数的定义也很简单。
function [function-name] return [return-type]
(input param1 as dataType,...):
[block]
end function.

 

procedure [procedure-name]:
define input parameter [param1] as [dataType] no-undo.
define output parameter [param2] as [dataType] no-undo.
define input-output parameter [param3] as [dataType] no-undo.
define...
[block]
end procedure.

 

输出可以用display [variable] 或者message [variable]


输出到文件是:
output to value(your-file-name).
display ...
message ...
output close.

 

上边的都是最简单的用法。要知道的是几乎所有的语句都会带有大量的属性。

下面我附上我的一个计算等本递减法还贷的小程序。 很容易就看懂了吧。其实progress最大的优点在于数据库,以后会慢慢的讲到。
---------------------------------------------------------------------------
DEF VAR rate AS DEC NO-UNDO. /*定义利率*/
DEF VAR principal AS DEC NO-UNDO. /*定义总贷款额度*/
DEF VAR lentDate AS CHAR NO-UNDO. /*定义借款日期*/
DEF VAR years AS INT NO-UNDO. /*定义贷款年数*/
DEF VAR returnDay AS INT NO-UNDO. /*定义还款日*/
DEF VAR firstMonth AS LOG NO-UNDO. /**/


DEF VAR totalPeriods AS INT NO-UNDO. /*总的期数*/
DEF VAR monthReturn  AS DEC NO-UNDO.

/*预先声明函数,有一个forward关键字*/
FUNCTION calcInterest RETURN DEC ( INPUT n AS INT ) FORWARD.
FUNCTION getPayDateOfPeriod RETURNS CHAR ( INPUT n AS INT) FORWARD.
FUNCTION getp1days RETURNS CHAR  FORWARD.
FUNCTION date2period RETURNS INT ( INPUT pdate AS CHAR) FORWARD.
FUNCTION getValidDate RETURNS DATE ( INPUT strDate AS CHAR ) FORWARD.
FUNCTION GenDate RETURNS CHARACTER ( INPUT pDate AS DATE ) FORWARD.
FUNCTION GetDateOther RETURNS DATE ( INPUT oDate AS DATE, INPUT dType AS CHAR, INPUT n AS INT ) FORWARD.

rate = 0.003825.
principal = 220000.
lentdate = "20070313".
returnday = 15.
firstMonth = FALSE. /*借款当月不还款,从下一月开始*/
years = 12.
totalperiods =  years * 12.
monthreturn = round(principal / totalperiods, 2). /*每月应还本金*//*round内置函数,四舍五入,这里是两位有效数字*/

 
/*输出标题*/
 DEF VAR i AS INT.
 i = 1.
OUTPUT TO VALUE("c:/interest.txt").
 DO i = 1 TO totalperiods:
     MESSAGE getpaydateofperiod(i) + "      " + string(calcinterest(i) + monthreturn,">>>9.99") + "       " +
                    string(monthreturn,">>>9.99") + "     " + string(calcinterest(i),">>>9.99") + "      " + STRING(principal - monthreturn * i, "->>>>>>9.99")  + CHR(10).
 END.

OUTPUT CLOSE.

 

 

/*计算第n期应还利息
*entry(position,string-list,seperate-char)内置函数,例如entry(2,"year,month,day",",")返回"month"
*int()内置函数,转换为整数
*
*/
FUNCTION calcInterest RETURN DEC
    (INPUT n AS INT):
DEF VAR lre AS DEC.
DEF VAR nm AS INT.
DEF VAR nd AS INT.
DEF VAR ts AS CHAR.
DEFINE VAR interest AS DEC.
IF n = 1 THEN
DO:
    ts = getp1days().
    nm = INT(ENTRY(1, ts, ",")).
    nd = INT(ENTRY(2, ts, ",")).

    interest = principal * rate * nm + principal * rate * nd / 30.
END.
ELSE IF n > 1 AND n <= totalperiods THEN
    interest = monthreturn * ( totalperiods - n + 1) * rate.

interest = round(interest, 2).
RETURN interest.
END FUNCTION.


/*************************************************
**************************************************/
/** 返回第n期还款的日子
*
*  substring(string,startPosition,length)内置函数, 如 substring(abcdefg,2,3) = "bcd"
*  string()内置函数把给定数据转换为字符串,相当于sprintf
*
*/
FUNCTION getPayDateOfPeriod RETURNS CHAR
    (INPUT n AS INTEGER) :
DEF VAR p1date AS CHAR NO-UNDO.
DEF VAR tdate AS DATE NO-UNDO.
 
IF n < 1 THEN
    RETURN "19000101".
IF n > totalperiods THEN
    RETURN "30000101".

 
p1date = SUBSTRING(lentdate,1,4) + SUBSTRING(lentdate,5,2) + STRING(returnday,"99").
IF DAY(getvaliddate(lentdate)) < returnday AND firstMonth = TRUE THEN
     .
ELSE
DO:
  tdate = getvaliddate(p1date).
  p1date = gendate( getdateother(tdate, "M", 1)).
END.
 
IF n = 1 THEN RETURN p1date.

tdate = getvaliddate(p1date).
tdate = getdateother(tdate, "M", n - 1 ).
 
RETURN gendate(tdate).
END FUNCTION.


/************************************
*************************************/
/** 返回第一期的还款日,没有用到
*
*
*/
FUNCTION getp1days RETURNS CHAR:
DEF VAR d1 AS DATE.
DEF VAR d2 AS DATE.
DEF VAR nm AS INT.
DEF VAR nd AS INT.
d1 = getvaliddate(getpaydateofperiod(1)).
d2 = getvaliddate(lentdate).
IF DAY(d2) < returnday AND firstmonth THEN
DO:
   nm = 0.
   nd = returnday - DAY(d2).
END.
ELSE
DO:
    IF DAY(d2) <= returnday THEN
    DO:
        nm = 1.
        nd = returnday - DAY(d2).
    END.
    ELSE
    DO:
        nm = 0.
        nd = 30 - ( DAY(d2) - returnday).
    END.
END.

RETURN STRING(nm) + "," + STRING(nd).
 
END FUNCTION.

/**********************************
**********************************/

/*有给定的日期得到期数*/   
FUNCTION date2period RETURNS INT
    (INPUT pdate AS CHAR) :

 DEF VAR mdate1 AS DATE NO-UNDO.
 DEF VAR mdate2 AS DATE NO-UNDO.

 mdate1 = getvaliddate(pdate).
 mdate2 = getvaliddate(lentdate).


 IF mdate1 < mdate2  THEN RETURN -1.
 IF mdate1 > getvaliddate(getpaydateofperiod(totalperiods)) THEN RETURN totalperiods.

 mdate2 = getvaliddate(getpaydateofperiod(1)).
 IF mdate1 < mdate2 THEN RETURN 0.

 DEF VAR np AS INT NO-UNDO.
 np = (YEAR(mdate1) - YEAR(mdate2)) * 12 + MONTH(mdate1) - MONTH(mdate2) + 1 .
 IF DAY(mdate1) >= returnday THEN np = np + 1.

 RETURN np.

END FUNCTION.


/***************************************************************************
***************************************************************************/
/*判断一个给定的日期字符串是不是一个有效的日期
*
*  int()内置函数,转换为整数
*  substring(string,startPosition,length)内置函数, 如 substring(abcdefg,2,3) = "bcd"
*  lookup(str,str-list,char)内置函数,查找str-list(以字符char分割的串列,缺省逗号分割)里有没有str,没有返回0。 如 lookup("year","year,month,day",",") = 1
*  modulo 取模操作符,类似c里的 %。 5%2 = 1
*  date(month,day,year) 返回日期,内置函数
*  if...else...then 也可以做一个表达式,vb也有的,类似于c里的 ?:表达式。
*/
FUNCTION getValidDate RETURNS DATE
  ( INPUT strDate AS CHAR )  :
/*------------------------------------------------------------------------------
  Purpose: 
    Notes:
    The input strDate is formatted as "yyyymmdd"
------------------------------------------------------------------------------*/
  DEFINE VARIABLE lDate AS DATE.
  DEFINE VARIABLE iy AS INT.
  DEFINE VARIABLE im AS INT.
  DEFINE VARIABLE id AS INT.

  ldate = ?.
  iy = INT(SUBSTRING(strdate,1,4)).
  im = INT (SUBSTRING(strdate, 5,2)).
  id = INT(SUBSTRING(strdate, 7,2)).

  IF id < 1 OR id > 31 OR im < 1 OR im > 12 THEN
  RETURN ldate.
   
  IF id = 31 AND  LOOKUP(string(im) , "1,3,5,7,8,10,12") = 0  THEN
          id = 30.

  IF id = 30 AND im = 2 THEN
      id = IF ((( iy MODULO 4 = 0 ) AND (iy MODULO 100 <> 0 )) OR (iy MODULO 400 = 0 )) THEN 29 ELSE 28.

  ldate = DATE( im, id, iy ).
  RETURN ldate.

END FUNCTION.


/*把一个日期转换为"yyyymmdd"格式的字符串*/
/*
*  string()内置函数把给定数据转换为字符串,相当于sprintf
*/
FUNCTION GenDate RETURNS CHARACTER
  ( INPUT pDate AS DATE )  :
/*------------------------------------------------------------------------------
  Purpose: 
    Notes: 
------------------------------------------------------------------------------*/
 DEFINE VARIABLE cDate AS CHAR.

 cDate = STRING(YEAR(pDate),"9999") + STRING(MONTH(pDate),"99") + STRING(DAY(pDate),"99").

  RETURN cDate.  
END FUNCTION.


/*此函数得回给定年/月/的以前或以后的同一天的日期,比如一月以前的今天*/
/*
*  year(pdate as DATE)是一个内置函数,返回年份
*  month(pdate as DATE)是一个内置函数,返回月份
*  day(pdate as DATE)是一个内置函数,返回日子
*  truncate是一个和round类似的函数,不过不四舍五入,直接丢弃
*  date(month,day,year) 返回日期,内置函数
*/
FUNCTION GetDateOther RETURNS DATE
  ( INPUT oDate AS DATE, INPUT dType AS CHAR, INPUT n AS INT )  :
/*------------------------------------------------------------------------------
  Purpose:  used to get one months ago in the same day,...
    Notes: 
    dType: it can be "Y","M","D" which means the unit is year,month,day
    n       : It can be positive or negative. positive means after the oDate, future
------------------------------------------------------------------------------*/
  DEFINE VARIABLE newDate AS DATE.
  DEFINE VARIABLE ny AS INT.
  DEFINE VARIABLE nm AS INT.
  DEFINE VARIABLE nd AS INT.
  DEFINE VARIABLE ycount AS INT.
  DEFINE VARIABLE mcount AS INT.

  newDate = oDate.
  ny = YEAR(oDate).
  nm = MONTH(odate).
  nd = DAY(odate).

  CASE dType:
      WHEN "Y" THEN
          ny = ny + n.
      WHEN "M" THEN
      DO:
          ycount = TRUNCATE(n / 12 , 0 ).
          mcount = n - ycount * 12.
          ny = ny + ycount.
          nm = nm + mcount.

          IF nm <= 0  THEN
          DO:
              nm = 12 + nm.
              ny = ny - 1.
          END.
          ELSE IF nm > 12 THEN
          DO:
              nm = nm - 12.
              ny = ny + 1.
          END.
      END.
      WHEN "D" THEN
          newDate = oDate + n.
         
  END CASE.
 
IF dtype = "Y" OR dtype = "M" THEN
      newDate = DATE( nm, nd, ny).

  RETURN newdate.   /* Function return value. */

END FUNCTION.