Automic Workload Automation

Expand all | Collapse all

How to test whether a variable is set

  • 1.  How to test whether a variable is set

    Posted Oct 07, 2013 11:18 AM
    Question: Is there a way in AE scripting to test whether a script/object variable has already been set?
    Short answer: No. However, it is possible to read the contents of a variable whether or not it has been set. To do this, first simply set the variable to its own current value.  E.g.: :SET &VAR1# = &VAR1#
    (Thanks to FrankMuffke for this solution.)
    Long answer:
    See this comment below.

    Original post:
    The UC4 scripting language does not appear to provide a direct method for determining whether a variable is set or not. In one job or workflow, a variable may be set, but in another, that variable may not be set. By finding a way to check whether a variable is set or not, we can avoid syntax/runtime errors, and make modular and reusable units of UC4 scripting that may be incorporated as include files (JOBI objects) in a broader range of objects.

    I found a way to work around this limitation; some of you may have noticed that I employed this work-around in my SET_FILE_MODE solution.
    :SET &RUNID# = SYS_ACT_ME_NR() :SET &MY_VAR_NAME# = "MY_VAR#" :SET &MY_VAR_TMP# = GET_PUBLISHED_VALUE(&RUNID#,&MY_VAR_NAME#) :SET &VAR_LENGTH# = STR_LENGTH(&MY_VAR_TMP#) :SET &VAR_LENGTH# = FORMAT(&VAR_LENGTH#) :PRINT "Contents of &&MY_VAR_TMP# : '&MY_VAR_TMP#'" :PRINT "Length of &&MY_VAR_TMP#   : &VAR_LENGTH#" :IF &VAR_LENGTH# = 1 :  IF &MY_VAR_TMP# = '' :    PRINT "Variable &&MY_VAR# is not set" :  ENDIF :ELSE :  PRINT "Variable &&MY_VAR# is set" :ENDIF
    In the above example, &MY_VAR# is the name of the variable being tested. (The GET_PUBLISHED_VALUE statement expects the name of this variable without the leading ampersand.) I stored the name of the variable in another variable just to demonstrate that indirect referencing is feasible. This means that this solution is more generalizable. You could conceivably even put it inside a :WHILE loop, and generate variable names dynamically or pull them from an outside source. The main problem with this approach is that you must avoid all direct references to the variables in the rest of the script, and instead refer to the variables by their stand-in _TMP equivalents. This means that it is necessary to set one _TMP variable for each variable you want to test.

    Has anyone found a better solution to this?


  • 2.  How to test whether a variable is set

    Posted Oct 08, 2013 07:42 PM
    Like you said no direct way. One of the SPs in V9 added a GET_SCRIPT_VAR command and you can use something like :SET &VAR# = GET_SCRIPT_VAR("VAR#") which will set the value to an empty string it is not defined (or if the variable contains an empty string in the first place Since 6.00 i've been using another similar workaround that behaves the same as above :SET &VAR# =  STR_CAT(&VAR#,"") This apparently bypasses the error that &VAR# isn't defined an is sets it to an empty string


  • 3.  How to test whether a variable is set

    Posted Oct 09, 2013 03:37 AM
    One of the SPs in V9 added a GET_SCRIPT_VAR command ... which will set the value to an empty string it is not defined (or if the variable contains an empty string in the first place
    That is simpler than using GET_PUBLISHED_VALUE. Thanks.


  • 4.  How to test whether a variable is set

    Posted Oct 10, 2013 05:21 PM
    Along those same lines I sometimes need to add new script variables to existing Include objects to handle increased functionality.  These Includes are usually generalized for use by many other objects and the new variable may cause those other objects to fail since they do not necessarily reference or set the newly added variable. I have gotten around that by inserting an “initialization” SET for the new variable in the Include object that is never actually executed.  I’m guessing that the script interpreter builds some type of internal variable dictionary and this references is enough to satisfy the requirement that all variables are predefined.  These can then be set and or tested in subsequent logic as needed. For example:
    ! THE_INCLUDE_OBJECT ! :IF 0 EQ 1 ! “Initialize” new variables. : SET &new_var1 = “” : SET &new_var2 = “” : ENDIF ! ! Existing and new logic using the new variables. : . . . : . . .
    p.s. I'm not certain if this is obvious to all as a technique; it certainly wasn't to me!  This occurred to me as something to attempt since I experienced something similar with another interpreted language and son of a gun it worked for UC4..


  • 5.  How to test whether a variable is set

    Posted Oct 11, 2013 03:13 AM
    I have gotten around that by inserting an “initialization” SET for the new variable in the Include object that is never actually executed.
    Clever! Your approach seems to do a good job of preventing errors like this: U0021719 Syntax error in object 'UC0.MAL.SCRI.SET_1', line '00009'. 'U1001308 Variable 'VAR3#' has not yet been defined.'. Some quick testing suggests that you are right about how the variables are initialized. The Automation Engine appears to scan the script for :SET statements (and similar statements) before execution. Later references to variables that are initialized but not actually set return null values. Many (but not all) references to uninitialized variables result in a syntax error like the one above. This prevents processing of the script or job. My experience suggests that the depth in the script of the variables references may impact whether references to uninitialized variables triggers a syntax error. In other words, if the references to unset variables are inside several nested :IF or :SWITCH loops, they may not trigger an error. Perhaps the initialization scan of the code is somewhat superficial. The Inside UC4 Guide would be a great place to see details about this mechanism documented!


  • 6.  How to test whether a variable is set

    Posted Feb 19, 2014 05:30 PM

    In version 8 I used to define parameter variables in includes simply with the following two steps.

    Step 1: Define the variable and save an existing value.

    :set &var#=&var# 

    Step 2: Check if empty and give them an initial value.

    :if "" = &var#

    :     set &var# = "initial value"

    :endif

    If the variable was not defined it get by step 1 the value "" (empty string) without an error.

    Otherwise the value of the variable remains unchanged.



  • 7.  How to test whether a variable is set

    Posted Jun 02, 2017 03:01 AM
    This is four years ago now but just wanted to thank Mark Hadler for his suggestion.

    I have an include script that I wanted to use for some jobs with varying numbers of variables.

    Mark's suggestion allows me to "define" all the potential variables knowing that the ones not actually supplied will be null and it won't complain that they're missing.

    Thanks Mark!

    Mike



  • 8.  How to test whether a variable is set

    Posted Jun 02, 2017 12:14 PM
    SIDEBAR:

    The script above uses SYS_ACT_ME_NR().  This function always returns the RUNID of the original activation of the object.  In most applications, it is better to use SYS_ACT_RESTART_ME_NR()


  • 9.  How to test whether a variable is set

    Posted Jun 02, 2017 05:11 PM
    My colleague (a real genius) has a simple method for that:

    :SET &SCRIPTVARA# = "&SCRIPTVARA#"

    So you avoid any error messages of unset VARAs, either it has a value or its ""


  • 10.  How to test whether a variable is set

    Posted Jun 02, 2017 07:28 PM
    My colleague (a real genius) has a simple method for that:
    :SET &SCRIPTVARA# = "&SCRIPTVARA#"
    So you avoid any error messages of unset VARAs, either it has a value or its ""
    This approach is so simple that it never occurred to me that it might work until someone else told me it did.


  • 11.  How to test whether a variable is set

    Posted Jun 03, 2017 03:41 PM
    Yeah thats why I think my colleague is a genius - I never would have had this idea.
    More simple is not possible :-)


  • 12.  How to test whether a variable is set

    Posted Oct 18, 2017 12:33 PM
    I know it's been a while since nobody comment on this one, but I really need to know if there is a way to test if the variable is not set before executing the script. The solution used here is OK, but lets say the code receive a empty value.
    Is there a way to run a script without setting a value to a variable? Or another way to avoid error U1001308 Variable '&var#' has not yet been defined.


  • 13.  How to test whether a variable is set

    Posted Oct 18, 2017 01:13 PM
    This thread pretty much covers all of your viable options. There is still no way to check for the existence of a variable. I've got plenty of scripts that start out with a :SET &VAR1 = &VAR1 statement.  It avoids "has not yet been defined".  Then a following statement can check the contents of &VAR1 to to see if anything was passed.

    I don't remember, but I think if the variable does not exist and you execute :set &var1 = "&var1", it may populate it with a single space?  If so, then you could use this fact to your advantage.

    EDIT:
    I just tested my theory, and I was wrong.  ;set &var1 = "&var1" results in an empty variable.


  • 14.  How to test whether a variable is set

    Posted Oct 19, 2017 04:04 AM
    As standard check if a Variable is set (as mentioned above) we use:
    :SET &SCRIPTVARA# = "&SCRIPTVARA#"
    :IF
    &SCRIPTVARA# = "" OR " "
    !   FURTHER CODE to avoid an unset (=empty) Scriptvara
    :ENDIF

    The additional check for " " is necessary because some Automic script functions return a blank instead of an empty Varaiable............




  • 15.  How to test whether a variable is set

    Posted Oct 19, 2017 04:46 AM
    Wolfgang Brueckler wrote:
    As standard check if a Variable is set (as mentioned above) we use:
    :SET &SCRIPTVARA# = "&SCRIPTVARA#"
    :IF
    &SCRIPTVARA# = "" OR " "
    !   FURTHER CODE to avoid an unset (=empty) Scriptvara
    :ENDIF
    The additional check for " " is necessary because some Automic script functions return a blank instead of an empty Varaiable.
    So, to answer Paulo_PG’s question, there is no way to reliably distinguish a variable that was not set from a variable that was set to an empty string.

    Also, because string comparison operations implicitly trim trailing spaces from both operands, if one wishes to distinguish an empty string from a string containing a single space (or only spaces), one must explicitly check the length of the string. (See my next comment.)


  • 16.  How to test whether a variable is set

    Posted Oct 19, 2017 05:54 AM
      |   view attached
    There are several limitations of the Automation Engine that come into play here:
    1. The only way to perform operations (e.g., comparisons) on a string that may or may not have been set (e.g., in a parent task) is to explicitly set it to its current value (E.g.,:SET &VAR1# = &VAR1#).
    2. The AE makes no distinction between a null value and an empty (zero-length) string. They are the same thing.
    3. String comparison operations implicitly trim trailing spaces from both operands.
    To demonstrate these limitations, create the following JOBI and SCRI.

    UC0.MAL.IS_VARIABLE_SET.JOBI
    :SET &SGLQUOTE# = "'"
    :SET &BDLQUOTE# = '"'
    :SET &VAR_CONTENT# = GET_SCRIPT_VAR(&VAR_NAME#)
    :PRINT
    :PRINT "Processing variable &&&VAR_NAME#."
    :PRINT " Content of variable &&&VAR_NAME#: &BDLQUOTE#&VAR_CONTENT#&BDLQUOTE#"
    :SET &VAR_LENGTH# = STR_LENGTH(&VAR_CONTENT#)
    :SWITCH &VAR_LENGTH#
    :CASE 0
    :  PRINT " Variable &&&VAR_NAME# has zero length."
    :CASE 1
    :  PRINT " Variable &&&VAR_NAME# has a length of 1."
    :OTHER
    :  PRINT " Variable &&&VAR_NAME# has a length other than 0 or 1."
    :ENDSWITCH
    :IF &VAR_CONTENT# = ""
    :  PRINT " Comparison &SGLQUOTE#&&&VAR_NAME# = &BDLQUOTE#&BDLQUOTE#&SGLQUOTE#  returned TRUE."
    :ENDIF
    :IF &VAR_CONTENT# = " "
    :  PRINT " Comparison &SGLQUOTE#&&&VAR_NAME# = &BDLQUOTE# &BDLQUOTE#&SGLQUOTE# returned TRUE."
    :ENDIF
    :IF &VAR_LENGTH# = 0
    :  IF &VAR_CONTENT# = ""
    :    PRINT " Variable &&&VAR_NAME# is a zero-length string."
    :  ENDIF
    :ENDIF
    :IF &VAR_LENGTH# = 1
    :  IF &VAR_CONTENT# = ""
    :    PRINT " Variable &&&VAR_NAME# contains a single blank space."
    :  ENDIF
    :ENDIF
    :IF &VAR_LENGTH# > 1
    :  IF &VAR_CONTENT# = ""
    :    PRINT " Variable &&&VAR_NAME# is a string of >1 blank spaces."
    :  ENDIF
    :ENDIF
    UC0.MAL.IS_VARIABLE_SET.SCRI
    :RSET &VAR1# = &VAR1#
    :RSET &VAR2# = ""
    :RSET &VAR3# = " "
    :RSET &VAR4# = "  "
    :SET &VAR_NAME# = "VAR1#"
    :INC UC0.MAL.IS_VARIABLE_SET.JOBI
    :SET &VAR_NAME# = "VAR2#"
    :INC UC0.MAL.IS_VARIABLE_SET.JOBI
    :SET &VAR_NAME# = "VAR3#"
    :INC UC0.MAL.IS_VARIABLE_SET.JOBI
    :SET &VAR_NAME# = "VAR4#"
    :INC UC0.MAL.IS_VARIABLE_SET.JOBI
    Run the script and you should see this in the Activation log:
    U00020237 The object variable '&VAR1#' in object: 'UC0.MAL.IS_VARIABLE_SET.SCRI', line: '00001' (RunID: '0119803449') has been created with the value '' by  using the command :RSET.
    U00020206 Variable '&VAR1#' was stored with value ''.
    U00020237 The object variable '&VAR2#' in object: 'UC0.MAL.IS_VARIABLE_SET.SCRI', line: '00002' (RunID: '0119803449') has been created with the value '' by  using the command :RSET.
    U00020206 Variable '&VAR2#' was stored with value ''.
    U00020237 The object variable '&VAR3#' in object: 'UC0.MAL.IS_VARIABLE_SET.SCRI', line: '00003' (RunID: '0119803449') has been created with the value ' ' by  using the command :RSET.
    U00020206 Variable '&VAR3#' was stored with value ' '.
    U00020237 The object variable '&VAR4#' in object: 'UC0.MAL.IS_VARIABLE_SET.SCRI', line: '00004' (RunID: '0119803449') has been created with the value '  ' by  using the command :RSET.
    U00020206 Variable '&VAR4#' was stored with value '  '.
    U00020408
    U00020408 Processing variable &VAR1#.
    U00020408  Content of variable &VAR1#: ""
    U00020408  Variable &VAR1# has zero length.
    U00020408  Comparison '&VAR1# = ""'  returned TRUE.
    U00020408  Comparison '&VAR1# = " "' returned TRUE.
    U00020408  Variable &VAR1# is a zero-length string.
    U00020408
    U00020408 Processing variable &VAR2#.
    U00020408  Content of variable &VAR2#: ""
    U00020408  Variable &VAR2# has zero length.
    U00020408  Comparison '&VAR2# = ""'  returned TRUE.
    U00020408  Comparison '&VAR2# = " "' returned TRUE.
    U00020408  Variable &VAR2# is a zero-length string.
    U00020408
    U00020408 Processing variable &VAR3#.
    U00020408  Content of variable &VAR3#: " "
    U00020408  Variable &VAR3# has a length of 1.
    U00020408  Comparison '&VAR3# = ""'  returned TRUE.
    U00020408  Comparison '&VAR3# = " "' returned TRUE.
    U00020408  Variable &VAR3# contains a single blank space.
    U00020408
    U00020408 Processing variable &VAR4#.
    U00020408  Content of variable &VAR4#: "  "
    U00020408  Variable &VAR4# has a length other than 0 or 1.
    U00020408  Comparison '&VAR4# = ""'  returned TRUE.
    U00020408  Comparison '&VAR4# = " "' returned TRUE.
    Note that the string comparisons always return TRUE, regardless of whether the variable contains an empty string, a single space, or more than one space. Thus, comparisons like :IF &VAR1# = "" OR " " are superfluous; :IF &VAR1# = "" is sufficient in these situations. The only way to distinguish two strings consisting of zero or more spaces is to explicitly check their lengths.

    I have attached an XML export of the two objects.

    Attachment(s)



  • 17.  How to test whether a variable is set

    Posted Feb 06, 2018 09:39 AM
    Hello.  I'm using a JMS Receiver that churns through a bunch of messages on ActiveMQ with values stored in JSON.  I'm using a similar approach to this one given in the Automic Guide.  
    https://docs.automic.com/documentation/webhelp/english/ALL/components/RA_JMS/latest/Agent%20Guide/help_en.htm#RA/JMS/AWI/Receiving_Multiple_Messages_with_a_Single_JMS_Receiver_Job.htm%3FTocPath%3DRA%2520JMS%25C2%25A0Agent%2520Jobs%7CCreating%2520RA%2520JMS%25C2%25A0Agent%2520Receiver%2520Jobs%7C_____4

    This creates script vars and processes the messages in bulk happily in the post_process_script.  Until someone creates a dodgy message that isn't JSON in to the queue, and the whole queue processing fails as get_script_var can't find the variable.  Currently I need to manually remove the test message and then the JMS receiver carries on processing messages. 

    Perhaps I could create the full 400 or so script variables up front rather than just letting the JMS receiver create them on demand. I'll see if the tips above help too.
    Thanks



  • 18.  Re: How to test whether a variable is set

    Posted Jan 18, 2019 12:56 AM

    It would be nice to have a script function like "EXIST" or "FIND" that could give a return code for any objects existence.   I did not find any of the replies worked for my situation.   I need another solution to suits my needs which is to lookup a variable for details about a failing job.  The details may or may not exist.  So I create the variable and if it does not exist it is created, if it does exist the script continues on and reads the variable. This prevents the script from getting FAULT_OTHER due to missing VARA object. If the VARA did not exist before then it can be removed at end. 

    e.g. 

     

    :read &UC_CAUSE_NAME,,

    :SET &GROUP# = "XYZ"

    :SET &SCRIPTVARA# = "VARA.&GROUP#"

    :SET &VAR# = CREATE_OBJECT("VARA","&SCRIPTVARA#","COMMON","Variable for &GROUP#","I","C","FREE")
    :SET &VAR_CHK# = FORMAT(&VAR#,"00000")
    :IF &VAR_CHK# = "20644"
    :  SET &GROUP_DATA# = GET_VAR(&SCRIPTVARA#, "&UC_CAUSE_NAME")

    :  ELSE

    :  PRINT "Variable &SCRIPTVARA# did not exist and is now created in folder COMMON"

    : SET &RMVARA# = REMOVE_OBJECT ("&SCRIPTVARA#")

    : ENDIF