Sep 12, 2016

Convert Numeric Amount to Text in Dunamics NAV

This is done using stranded code taken  from Report-1401-Check.
Modification done mainly to get the Cents value from text. And includes some other formatting options.

Call the function "FormatNoText" with following  parameters
"NoText"               Text(80) array length of 3 which returns the text.
"No"                      Amount or the number needs to be converted.
"CurrencyCode"  Currency Code if any, if not keep it blank.
"IsUpperCase"     if "TRUE" text will return in UPPERCASE, if "FALSE" first letter of                                                                 each word in UPPERCASE.
"StartStar"           if "TRUE", "***" will print at the begin.
"EndStar"             if "TRUE", "***" will print at the end.

This funtion use "AddToNoText" & "GetAmtDecimalPosition" local functions.
Complete Code is given bellow


OBJECT Codeunit 50008 SRDS
{
  OBJECT-PROPERTIES
  {
    Date=09/12/16;
    Time=[ 1:13:16 PM];
    Modified=Yes;
    Version List=SRDS/SLT;
  }
  PROPERTIES
  {
    OnRun=BEGIN
          END;

  }
  CODE
  {

    PROCEDURE FormatNoText@13(VAR NoText@1000 : ARRAY [3] OF Text[80];No@1001 : Decimal;CurrencyCode@1002 : Code[10];IsUpperCase@1053 : Boolean;StartStar@1058 : Boolean;EndStar@1059 : Boolean);
    VAR
      PrintExponent@1003 : Boolean;
      Ones@1004 : Integer;
      Tens@1005 : Integer;
      Hundreds@1006 : Integer;
      Exponent@1007 : Integer;
      NoTextIndex@1008 : Integer;
      DecimalPosition@1010 : Decimal;
      Cents_@1009 : Integer;
      Text026@1046 : TextConst 'ENU=Zero';
      Text027@1045 : TextConst 'ENU=Hundred';
      Text028@1044 : TextConst 'ENU=And';
      Text029@1043 : TextConst 'ENU=%1 results in a written number that is too long.';
      Text030@1042 : TextConst 'ENU=" is already applied to %1 %2 for customer %3."';
      Text031@1041 : TextConst 'ENU=" is already applied to %1 %2 for vendor %3."';
      Text032@1040 : TextConst 'ENU=One';
      Text033@1039 : TextConst 'ENU=Two';
      Text034@1038 : TextConst 'ENU=Three';
      Text035@1037 : TextConst 'ENU=Four';
      Text036@1036 : TextConst 'ENU=Five';
      Text037@1035 : TextConst 'ENU=Six';
      Text038@1034 : TextConst 'ENU=Seven';
      Text039@1033 : TextConst 'ENU=Eight';
      Text040@1032 : TextConst 'ENU=Nine';
      Text041@1031 : TextConst 'ENU=Ten';
      Text042@1030 : TextConst 'ENU=Eleven';
      Text043@1029 : TextConst 'ENU=Twelve';
      Text044@1028 : TextConst 'ENU=Thirteen';
      Text045@1027 : TextConst 'ENU=Fourteen';
      Text046@1026 : TextConst 'ENU=Fifteen';
      Text047@1025 : TextConst 'ENU=Sixteen';
      Text048@1024 : TextConst 'ENU=Seventeen';
      Text049@1023 : TextConst 'ENU=Eighteen';
      Text050@1022 : TextConst 'ENU=Nineteen';
      Text051@1021 : TextConst 'ENU=Twenty';
      Text052@1020 : TextConst 'ENU=Thirty';
      Text053@1019 : TextConst 'ENU=Forty';
      Text054@1018 : TextConst 'ENU=Fifty';
      Text055@1017 : TextConst 'ENU=Sixty';
      Text056@1016 : TextConst 'ENU=Seventy';
      Text057@1015 : TextConst 'ENU=Eighty';
      Text058@1014 : TextConst 'ENU=Ninety';
      Text059@1013 : TextConst 'ENU=Thousand';
      Text060@1012 : TextConst 'ENU=Million';
      Text061@1011 : TextConst 'ENU=Billion';
      OnesText@1052 : ARRAY [20] OF Text[30];
      TensText@1051 : ARRAY [10] OF Text[30];
      ExponentText@1050 : ARRAY [5] OF Text[30];
      DescriptionLine@1049 : ARRAY [3] OF Text[80];
      TensDec@1048 : Integer;
      OnesDec@1047 : Integer;
      CentsText@1054 : Text;
      Text062@1055 : TextConst 'ENU=Cents Only';
      TextEmpty@1056 : TextConst;
      TextStarSign@1057 : TextConst 'ENU=***';
      ZeroText@1060 : Text;
      HundredText@1061 : Text;
      AndText@1062 : Text;
    BEGIN
      /// <summary>
      /// This function converts a number to text format.
      /// This funtion use "AddToNoText" & "GetAmtDecimalPosition" local functions.
      ///
      /// </summary>
      /// <param name="NoText">Text(80) array length of 3 which returns the text</param>
      /// <param name="No">Amount or the number needs to be converted</param>
      /// <param name="CurrencyCode">Currency Code if any, if not keep it blank</param>
      /// <param name="IsUpperCase">if "TRUE" text will return in UPPERCASE, if "FALSE" first letter of each word in UPPERCASE</param>
      /// <param name="StartStar">if "TRUE", "***" will print at the begin</param>
      /// <param name="EndStar">if "TRUE", "***" will print at the end</param>
      /// <returns></returns>

      // InitTextVariable --- START
      IF IsUpperCase THEN BEGIN

        OnesText[1] := UPPERCASE(Text032);
        OnesText[2] := UPPERCASE(Text033);
        OnesText[3] := UPPERCASE(Text034);
        OnesText[4] := UPPERCASE(Text035);
        OnesText[5] := UPPERCASE(Text036);
        OnesText[6] := UPPERCASE(Text037);
        OnesText[7] := UPPERCASE(Text038);
        OnesText[8] := UPPERCASE(Text039);
        OnesText[9] := UPPERCASE(Text040);
        OnesText[10] := UPPERCASE(Text041);
        OnesText[11] := UPPERCASE(Text042);
        OnesText[12] := UPPERCASE(Text043);
        OnesText[13] := UPPERCASE(Text044);
        OnesText[14] := UPPERCASE(Text045);
        OnesText[15] := UPPERCASE(Text046);
        OnesText[16] := UPPERCASE(Text047);
        OnesText[17] := UPPERCASE(Text048);
        OnesText[18] := UPPERCASE(Text049);
        OnesText[19] := UPPERCASE(Text050);

        TensText[1] := TextEmpty;
        TensText[2] := UPPERCASE(Text051);
        TensText[3] := UPPERCASE(Text052);
        TensText[4] := UPPERCASE(Text053);
        TensText[5] := UPPERCASE(Text054);
        TensText[6] := UPPERCASE(Text055);
        TensText[7] := UPPERCASE(Text056);
        TensText[8] := UPPERCASE(Text057);
        TensText[9] := UPPERCASE(Text058);

        ExponentText[1] := TextEmpty;
        ExponentText[2] := UPPERCASE(Text059);
        ExponentText[3] := UPPERCASE(Text060);
        ExponentText[4] := UPPERCASE(Text061);

        CentsText   := UPPERCASE(Text062);
        ZeroText    := UPPERCASE(Text026);
        HundredText := UPPERCASE(Text027);
        AndText    := UPPERCASE(Text028);

      END ELSE BEGIN
        OnesText[1] := Text032;
        OnesText[2] := Text033;
        OnesText[3] := Text034;
        OnesText[4] := Text035;
        OnesText[5] := Text036;
        OnesText[6] := Text037;
        OnesText[7] := Text038;
        OnesText[8] := Text039;
        OnesText[9] := Text040;
        OnesText[10] := Text041;
        OnesText[11] := Text042;
        OnesText[12] := Text043;
        OnesText[13] := Text044;
        OnesText[14] := Text045;
        OnesText[15] := Text046;
        OnesText[16] := Text047;
        OnesText[17] := Text048;
        OnesText[18] := Text049;
        OnesText[19] := Text050;

        TensText[1] := TextEmpty;
        TensText[2] := Text051;
        TensText[3] := Text052;
        TensText[4] := Text053;
        TensText[5] := Text054;
        TensText[6] := Text055;
        TensText[7] := Text056;
        TensText[8] := Text057;
        TensText[9] := Text058;

        ExponentText[1] := TextEmpty;
        ExponentText[2] := Text059;
        ExponentText[3] := Text060;
        ExponentText[4] := Text061;

        CentsText   := Text062;
        ZeroText    := Text026;
        HundredText := Text027;
        AndText    := Text028;
      END;
      // InitTextVariable ---  END

      CLEAR(NoText);
      NoTextIndex := 1;

      IF StartStar THEN
        NoText[1] := TextStarSign
      ELSE
        NoText[1] := TextEmpty;

      IF No < 1 THEN
        AddToNoText(NoText,NoTextIndex,PrintExponent,ZeroText)
      ELSE
        FOR Exponent := 4 DOWNTO 1 DO BEGIN
          PrintExponent := FALSE;
          Ones := No DIV POWER(1000,Exponent - 1);
          Hundreds := Ones DIV 100;
          Tens := (Ones MOD 100) DIV 10;
          Ones := Ones MOD 10;
          IF Hundreds > 0 THEN BEGIN
            AddToNoText(NoText,NoTextIndex,PrintExponent,OnesText[Hundreds]);
            AddToNoText(NoText,NoTextIndex,PrintExponent,HundredText);
          END;
          IF Tens >= 2 THEN BEGIN
            AddToNoText(NoText,NoTextIndex,PrintExponent,TensText[Tens]);
            IF Ones > 0 THEN
              AddToNoText(NoText,NoTextIndex,PrintExponent,OnesText[Ones]);
          END ELSE
            IF (Tens * 10 + Ones) > 0 THEN
              AddToNoText(NoText,NoTextIndex,PrintExponent,OnesText[Tens * 10 + Ones]);
          IF PrintExponent AND (Exponent > 1) THEN
            AddToNoText(NoText,NoTextIndex,PrintExponent,ExponentText[Exponent]);
          No := No - (Hundreds * 100 + Tens * 10 + Ones) * POWER(1000,Exponent - 1);
        END;

      AddToNoText(NoText,NoTextIndex,PrintExponent,AndText);
      DecimalPosition := GetAmtDecimalPosition(CurrencyCode);

      IF CurrencyCode <> '' THEN
        AddToNoText(NoText,NoTextIndex,PrintExponent,CurrencyCode);

      // --- Display Cents ----------------------------------
      TensDec := ((No * 100) MOD 100) DIV 10;
      OnesDec := (No * 100) MOD 10;
      IF TensDec >= 2 THEN BEGIN
        AddToNoText(NoText,NoTextIndex,PrintExponent,TensText[TensDec]);
        IF OnesDec > 0 THEN
          AddToNoText(NoText,NoTextIndex,PrintExponent,OnesText[OnesDec]);
      END ELSE
        IF (TensDec * 10 + OnesDec) > 0 THEN
          AddToNoText(NoText,NoTextIndex,PrintExponent,OnesText[TensDec * 10 + OnesDec])
        ELSE
          AddToNoText(NoText,NoTextIndex,PrintExponent,ZeroText);

      IF EndStar THEN
        AddToNoText(NoText,NoTextIndex,PrintExponent,CentsText+TextEmpty+TextStarSign)
      ELSE
        AddToNoText(NoText,NoTextIndex,PrintExponent,CentsText);
    END;

    LOCAL PROCEDURE AddToNoText@11(VAR NoText@1000 : ARRAY [2] OF Text[80];VAR NoTextIndex@1001 : Integer;VAR PrintExponent@1002 : Boolean;AddText@1003 : Text[30]);
    VAR
      Text_@1004 : Text;
      Text01@1005 : TextConst 'ENU=%1 results in a written number that is too long.';
      Text02@1006 : TextConst 'ENU=" "';
    BEGIN
      /// <summary>
      /// This function used to create the text.
      /// Calles inside the "FormatNoText" Function.
      /// </summary>

      PrintExponent := TRUE;

      WHILE STRLEN(NoText[NoTextIndex] + Text02 + AddText) > MAXSTRLEN(NoText[1]) DO BEGIN
        NoTextIndex := NoTextIndex + 1;
        IF NoTextIndex > ARRAYLEN(NoText) THEN
          ERROR(Text01,AddText);
      END;

      NoText[NoTextIndex] := NoText[NoTextIndex] + Text02 + AddText
    END;

    LOCAL PROCEDURE GetAmtDecimalPosition@22(CurrCode@1001 : Code[10]) : Decimal;
    VAR
      Currency@1000 : Record 4;
    BEGIN
      /// <summary>
      /// This function used to get the decimal points according to currency code.
      /// Calles inside the "FormatNoText" Function.
      /// </summary>

      IF CurrCode = '' THEN
        Currency.InitRoundingPrecision
      ELSE BEGIN
        Currency.GET(CurrCode);
        Currency.TESTFIELD("Amount Rounding Precision");
      END;
      EXIT(1 / Currency."Amount Rounding Precision");
    END;

    BEGIN
    END.
  }
}

No comments:

Post a Comment