Sun Jun 20, 2021 10:16 pm
Login Register Lost Password? Contact Us

Viewing ECL generated by MACROs

Share ideas, code, best practices and techniques with other community members

Wed Mar 27, 2019 11:31 am Change Time Zone

For a long time one of my problems in using MACROS was that I could not see the ECL generated by the MACRO. If I could do that, developing MACROS would be a whole lot easier.
Anyway this has bugged me enough that I've worked on a solution. I expect its bugged others so I put it out here for use and comment. (Perhaps there is an easier way than I give here, in which case PLEASE post a reply.)
The secret is to generate the ECL as a STRING then #EXPAND the STRING outside the MACRO.
Doing that allows you to do one run to output the STRING. One can then cut-and-paste the resultant STRING into its own BWR window, syntax check, or even run the ECL, from that BWR to find any problems. It then becomes a trivial task to correct the MACRO.
I've even known people to dispense with the MACRO completely once the generated ECL runs correctly.
Any way here is an example, of a fairly complex little MACRO where its easy to miss a bracket or something.
Code: Select all
EXPORT GenerateStatReport_Macro(d,outAttrib) := FUNCTIONMACRO


    Stats(dinner,AttributeName) := FUNCTIONMACRO

        RETURN 'ROW({'+#TEXT(AttributeName)
                   +',(STRING) COUNT('+dinner+'('+AttributeName+' = \'Y\'))'
                   +',(STRING) '+%'GetPercent'%+'(COUNT('+dinner+'('
                   +AttributeName+' = \'Y\')))'
                   +' STRING AttributeName'
                   +',STRING Match'
                   +',STRING Match_Percentage'

    RFlat := RECORDOF(d);

    #EXPORTXML(out, RFlat);


    #SET(str,%'totalNumberOfRecords'%+' := COUNT('+#TEXT(d)+');\n'
            +'(INTEGER iCnt) := (DECIMAL5_2) (( iCnt/'

        #FOR (out)
          #FOR (Field)
        Res := %'str'%+';';
    RETURN Res;


Note the return type is a STRING. #EXPAND not done in the FUNCTIONMACRO itself.
To see if the generated ECL is correct, one first runs:
Code: Select all
InData := DATASET([{'Y','N','Y'}
                  ],{STRING Included,STRING OutLier,STRING Extra});


This will produce an output of:
Code: Select all
__totalNumberOfRecords__6591__ := COUNT(InData);
__GetPercent__6592__(INTEGER iCnt) := (DECIMAL5_2) (( iCnt/__totalNumberOfRecords__6591__)*100)+'%';
res:=ROW({'included',(STRING) COUNT(InData(included = 'Y')),(STRING) __GetPercent__6592__(COUNT(InData(included = 'Y')))},{ STRING AttributeName,STRING Match,STRING Match_Percentage})
&ROW({'outlier',(STRING) COUNT(InData(outlier = 'Y')),(STRING) __GetPercent__6592__(COUNT(InData(outlier = 'Y')))},{ STRING AttributeName,STRING Match,STRING Match_Percentage})
&ROW({'extra',(STRING) COUNT(InData(extra = 'Y')),(STRING) __GetPercent__6592__(COUNT(InData(extra = 'Y')))},{ STRING AttributeName,STRING Match,STRING Match_Percentage})

cut-and-paste this into a builder window, along with the definition of the input dataset and syntax that to find the errors.
Once the MACRO is generating the correct ECL one can then change to use:
Code: Select all

To do the actual job.
By the way I use #UNIQUENAME to allow the MACRO to be used multiple times in one compilation.

I hope this will help people


Posts: 435
Joined: Sat Oct 01, 2011 7:26 pm

Return to Tips & Tricks

Who is online

Users browsing this forum: No registered users and 1 guest