1 Reply Latest reply: Jul 22, 2017 5:04 PM by Narayana Reddy RSS

    Subroutine-local variables in Qlik script

    Angus Monro

      For all my fellow software engineers who have yearned for being able to declare local variables in Qlik script subroutines, I have found a workaround for achieving this: declare them as parameters in the SUB's parameter list; like this:

      /* SUB printTriangularNumber (pN) - print the (pN)th triangular number
           Outputs pN x (pN+1) / 2.
           @param pN
      */
      SUB printTriangularNumber (pN, /* local variables: */ lTriangularNumber )
          LET lTriangularNumber=(pN+1)*pN/2;
          TRACE $(lTriangularNumber);
      END SUB
      
      CALL printTriangularNumber( (5) );
      
      

      Notes:

      • The CALL has fewer parameters than the SUB declaration, but the QlikView engine nevertheless matches the two and initialises the missing parameters (lTriangularNumber, in this case) to null().
      • Style: I've used variable prefixes (p and l) and an inline comment to distinguish the genuine parameters from the local variables in the subroutine's signature; but have omitted the local variables in the comment block explaining the subroutine.  This makes it as easy as possible for the maintainer to understand what is going on.
      • Like any other SUB parameter, there is no need to "clean-up" lTriangularNumber with a "SET lTriangularNumber=;" statement - the variable will be automatically deleted on return from the subroutine.
      • EXCEPTION: this technique does not work if there are no genuine parameters for the subroutine (i.e. the subroutine's signature contains only 'local' variables or you call it with no parameters: in these cases, the QlikView engine will create the variables at global scope and not dispose of them when it reaches ENDSUB.  (Add that to the case file of Qlik's poor language design decisions that make it harder to easily create defect-free code.)
      • Qlik script behaves correctly when a SUB with a given parameter is called from a SUB that has a parameter with exactly the same name: it will indeed treat the outer subroutine's parameter and the inner subroutine's namesake parameter as two distinct variables, even if it's a recursive call.
      • I've put extra parentheses around the '5' in the CALL to force the QlikView engine to treat this as an expression.  Without this, the QlikView engine will create a variable named '5' (yes, really!). (See previous comment about language design).

       

      Message was edited by: Angus Monro - * added Exception dot point re this technique not working when the subroutine's CALL passes no parameters; * altered the recommended style - previous I'd demarcated the local variables in the SUB signature with an inline comment both before and after the list of local variables; but having a comment at the end of the list is redundant, since all variables through to the end of the signature will be 'local' when this technique is used. * added a couple of self-indulgent rants about Qlik's language design. It's an ongoing issue and I wish they'd take a community-consultative approach so that impacts of design choices can be assessed.  Argh!  There I go again!

        • Re: Subroutine-local variables in Qlik script
          Narayana Reddy

          SUB printTriangularNumber(pN,lTriangularNumber)

          LET lTriangularNumber = (pN+1)*(pN/2);

          TRACE $(lTriangularNumber);

          ENDSUB

           

           

          CALL printTriangularNumber((5));

           

           

          TRACE Accessing out of >End sub< $(lTriangularNumber);

           

          Capture.PNG

           

          I am able to accessing SUB local variable as globally...As you said above the local variable will be automatically deleted on return from the subroutine....