【问题标题】:Counting the leading 0's and printing them计算前导 0 并打印它们
【发布时间】:2013-11-05 21:52:20
【问题描述】:

我处于需要计算变量的前导 0 并使用 4GL 代码将它们放在另一个变量中的场景中。

例如,如果变量 i(整数)是 '00000546' 那么

  1. 我需要数它们,因为它是 5
  2. 将它们放在另一个变量 b(字符)中,例如 '00000' + '546'

请给我建议。

【问题讨论】:

  • 整数没有前导零,因此这必须是作为字符传递的整数。如果它是一个整数,您所做的就是获取整数的长度,然后从您允许该整数的最大长度中减去该长度,您将看到有多少前导零。

标签: progress-4gl openedge


【解决方案1】:

计算前导零的最简单方法:

DEF VAR iNum AS INTEGER NO-UNDO.
DEF VAR cValue AS CHAR NO-UNDO.
DEF VAR iLeadZero AS INTEGER NO-UNDO.

ASSIGN 
  cValue = '00000546'
  iNum = INTEGER(cValue)
  iLeadZero = LENGTH(cValue) - LENGTH(STRING(iNum)). 

也可以作为一个函数来完成(没有错误处理):

FUNCTION cntLeadZeros RETURNS INTEGER
    (INPUT pcValue AS CHARACTER):
    DEF VAR iNum AS INTEGER NO-UNDO.
    DEF VAR iLeadZero AS INTEGER NO-UNDO.

    ASSIGN 
      iNum = INTEGER(pcValue)
      iLeadZero = LENGTH(pcValue) - LENGTH(string(iNum)). 

    RETURN iLeadZero.
END FUNCTION. /* cntLeadZeros */

具有错误处理功能,因此如果人们通过非整数值传递。

FUNCTION cntLeadZeros2 RETURNS INTEGER
    (INPUT pcValue AS CHARACTER):
    DEF VAR iNum AS INTEGER NO-UNDO.
    DEF VAR iLeadZero AS INTEGER NO-UNDO.

    ASSIGN 
      iNum = INTEGER(pcValue)
      iLeadZero = LENGTH(pcValue) - LENGTH(string(iNum)). 

    IF ERROR-STATUS:ERROR THEN
        RETURN ?.

    RETURN iLeadZero.
END FUNCTION. /* cntLeadZeros2 */ 

【讨论】:

  • 我喜欢小写的关键字。
  • 但现在我让它更符合预期,而不是太棒了:-)
【解决方案2】:

好的,所以 i 是一个整数。需要确定 i 的格式,用于创建默认字符串,然后将其拆分为零和非零。

这个怎么样:

DEFINE VARIABLE i AS INTEGER     NO-UNDO
    FORMAT "9999999999".

DEFINE VARIABLE vcINoLeading AS CHARACTER   NO-UNDO.
DEFINE VARIABLE vcIDefault AS CHARACTER   NO-UNDO.
DEFINE VARIABLE vcIZeros AS CHARACTER   NO-UNDO.

DEFINE FRAME bogus
    i.

i = 1234.

vcIDefault = STRING(i,i:FORMAT).
vcINoLeading = STRING(i).
vciZeros = REPLACE(vcIDefault,vcINoLeading,"").

MESSAGE vcIDefault SKIP vcINoLeading SKIP vciZeros VIEW-AS ALERT-BOX.

vcINoLeading 仅包含非零数字,而 vciZeros 包含所有零。

【讨论】:

    【解决方案3】:

    这是一种可以完成的方法,遍历字符:

    def var a as char no-undo.
    def var b as char no-undo.
    def var c as char no-undo.
    def var v as int  no-undo.
    
    assign a = '00000546'.
    
    do v = 1 to length(a):
    
       assign c = substring(a,v,1).
    
       if c ne "0" then leave.
    
    end.
    
    assign b = substring(a,v).
    
    disp fill("0", v - 1) b.
    

    【讨论】:

    • +1 表示 ABL 的小写缩写。
    【解决方案4】:

    问题中唯一棘手的部分是他提到“i”是一个整数。因此,前导零必须来自“i”的格式,而不是字符串的一部分。幸运的是,我们可以检查“i”的格式并使用它来确定显示了多少前导零。

    DEFINE VARIABLE i      AS INTEGER   FORMAT '9999999999' NO-UNDO.
    DEFINE VARIABLE cZeros AS CHARACTER FORMAT 'X(9)'       NO-UNDO.
    
    DEFINE FRAME iFrame
        i.
    
    i = 6123455.
    
    cZeros = FILL('0',LENGTH(i:FORMAT) - LENGTH(STRING(i))).
    
    DISPLAY
        i
        cZeros
    WITH FRAME iFrame.
    

    【讨论】:

      【解决方案5】:

      我不明白您为什么要像您描述的那样设置新变量,但您可能有充分的理由。或许你可以解释更多?

      无论如何,我应该这样做:

      DEFINE VARIABLE a  AS CHARACTER NO-UNDO.
      DEFINE VARIABLE nr AS INTEGER   NO-UNDO.
      DEFINE VARIABLE b  AS CHARACTER NO-UNDO.
      
      a = STRING(546,"99999999").
      nr = LENGTH(a) - LENGTH(LEFT-TRIM(a,"0")).
      b = FILL("0",nr) + LEFT-TRIM(a,"0").
      
      MESSAGE a SKIP nr SKIP b
          VIEW-AS ALERT-BOX INFO BUTTONS OK.
      

      【讨论】:

      • “原因”对我来说就像“面试问题”;)
      【解决方案6】:

      整数数据类型没有前导零,因此您不需要计算零。您可以简单地使用 STRING 函数,如下例所示。在下面的示例中,我认为您的字符串具有固定长度。

      DEFINE VARIABLE i-test  AS INTEGER INITIAL 546.
      DEFINE VARIABLE c-test  AS CHARACTER.
      
      ASSIGN c-test = STRING(i-test,"99999999").
      
      MESSAGE c-test VIEW-AS ALERT-BOX.
      

      消息将返回:00000546

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-09-14
        • 2021-03-01
        • 1970-01-01
        • 2013-03-20
        • 2014-06-17
        • 2017-12-01
        • 1970-01-01
        相关资源
        最近更新 更多