Check if a variable exists

Post any question you may have in regards to GoAnywhere Director and let our talented support staff and other users assist you.
13 posts Page 1 of 2

mattolsen

Posts: 10
Joined: Tue May 06, 2014 7:03 pm

Post by mattolsen » Tue Jul 29, 2014 7:08 pm
Is there a good way to check if a variable exists before I try to use it, and if it doesn't exist, do something else?

Support_Rick

Support Specialist
Posts: 590
Joined: Tue Jul 17, 2012 2:12 pm
Location: Phoenix, AZ

Post by Support_Rick » Thu Jul 31, 2014 10:52 am
Matt,

Not sure of the context of this question, but having a variable available to you can be controlled. If you're addressing a Variable being passed into your Project, then... pre-define the variable (Right click on the Project Level and add the variable) and set the initial contents to empty ${system.emptyString} or just '' (quote/quote).

Then, inside your Project, test to see if the variable is empty ... If ${ IsEmpty( VarName ) }...

Under most conditions, that should take care of your "is variable defined" issue.
Rick Elliott
Lead Solutions Consultant
(402) 944.4242
(800) 949-4696

mattolsen

Posts: 10
Joined: Tue May 06, 2014 7:03 pm

Post by mattolsen » Thu Jul 31, 2014 11:42 am
The basis for the question is the difference between running a project manually as opposed to running it through a monitor. When I run it through a monitor, the monitor by default sets a variable called 'files' with the list of files it found. I can then set my project to do something with those files. If I run the same project manually, though, the 'files' variable won't exist and it will crash.

The way I ended up fixing this is by using a 'SetVariable' task to set a variable called 'filesCount' to the value of '${files:size}' and set the 'On Error' portion of the task to 'setVariable:filesCount=-1'. If the variable exists then 'filesCount' gets the length. If 'files' doesn't exist, though, then 'filesCount' gets a value of -1. The next task checks to see if 'filesCount' is -1, and if it is, it manually gets the list of files .

The one drawback of this approach is the manual process monitor may not get the same list of files that the monitor gets due to the way monitors handle keeping track of what they have already pulled, but it gets us close enough.

What would be nice, though, is some way to force a monitor to run a single time without having to go change the schedule that it is using. Sometimes we need to check for a file outside of the normal monitor hours, but to do this we have to change the schedule time. This is fine except in those instances where we forget to change it back. Having a button or menu item we could use to run the monitor would be a great help.

Support_Rick

Support Specialist
Posts: 590
Joined: Tue Jul 17, 2012 2:12 pm
Location: Phoenix, AZ

Post by Support_Rick » Thu Jul 31, 2014 12:01 pm
Matt,

That scenario is exactly like I was addressing above.

Add a variable to your Project called "Files" and set it to an empty value. When the monitor runs, it will overwrite the "empty value" with the File List created by the Monitor.

In your Project, just check to see if Files is not empty or equal to QuoteQuote. Then, if it already has a value assigned, it was called by the Monitor and it has a file list attached.

If you check the files variable and it's empty, you'll know the job is being executed interactively (or more specifically, not from the Monitor) and it will need to generate the file list.

Hope this makes sense...
Rick Elliott
Lead Solutions Consultant
(402) 944.4242
(800) 949-4696

mattolsen

Posts: 10
Joined: Tue May 06, 2014 7:03 pm

Post by mattolsen » Thu Jul 31, 2014 12:35 pm
I believe I correctly made the changes you suggested, and when I run the project manually it works great, but when I run it using a monitor I get an exception:

ERROR [8099 - ftp] An unexpected error occurred.
Function 'IsEmpty': Parameter '1' must be a string value. Function definition: 'IsEmpty(text) returns boolean'

It appears that since the string 'Files' is getting overwritten by the FileList 'Files' I can't do a IsEmpty() on it anymore. Would it work to do a 'Files:class=....' to check what type of object 'Files' really is, or is there a better way?

Support_Rick

Support Specialist
Posts: 590
Joined: Tue Jul 17, 2012 2:12 pm
Location: Phoenix, AZ

Post by Support_Rick » Thu Jul 31, 2014 3:47 pm
Matt,

Your XML should look something like this:
Code: Select all
<project...>

	<variable name="MyFileList" value="" />

	<module name="Main">

		<if label="Check for Empty File List" condition="${ ISEmpty( MyFileList ) }">

			<print version="1.0">
				<![CDATA[It's Empty]]>
			</print>


			<exitModule version="1.0" />

		</if>

      </module>
</project>
Rick Elliott
Lead Solutions Consultant
(402) 944.4242
(800) 949-4696

WallyD444

Posts: 10
Joined: Wed Sep 17, 2014 8:38 am

Post by WallyD444 » Wed Jul 01, 2015 7:50 am
I'm trying the same thing, I have a variable 'fileList' that is a filelist and I'm receiving this error:

[8099 - Create File List] An unexpected error occurred. Function 'IsEmpty': Parameter '1' must be a string value. Function definition: 'IsEmpty(text) returns boolean'

here is my XML:
Code: Select all
<project name="FileList Test" mainModule="Main" version="2.0" logLevel="debug">
	<variable name="homeFolder" value="/home"/>
	<variable name="subFolder" value="/preprocess" />
	<variable name="destFolder" value="/in" />

	<module name="Main">
		<callModule label="Call Create File List" module="Create File List" version="1.0" />
		<callModule label="Call Read Files" module="Read Files" version="1.0" />
	</module>
	<module name="Create File List">
		<createFileList label="Create File List" fileListVariable="fileList" version="1.0">
			<fileset dir="${homeFolder}${subFolder}">
				<wildcardFilter>
					<include pattern="*.xlsx" caseSensitive="false" />
				</wildcardFilter>
			</fileset>
		</createFileList>

		<if label="Check for Files" condition="${ISEmpty(fileList)}">
			<else>

				<exitProject version="1.0" />

			</else>

			<print label="Print" version="1.0">
				<![CDATA[it worked!]]>
			</print>

		</if>
	</module>

</project>

Support_Rick

Support Specialist
Posts: 590
Joined: Tue Jul 17, 2012 2:12 pm
Location: Phoenix, AZ

Post by Support_Rick » Wed Jul 01, 2015 8:15 am
Wally,

Modify your project just a bit to get the variable for Number of Files added to the FileList variable:

numFilesFoundVariable="NoFilesFound"
Code: Select all
<createFileList label="Create File List" fileListVariable="fileList" numFilesFoundVariable="NoFilesFound" version="1.0">
	<fileset dir="${homeFolder}${subFolder}">
		<wildcardFilter>
			<include pattern="*.xlsx" caseSensitive="false" />
		</wildcardFilter>
	</fileset>
</createFileList>

<exitProject version="1.0" executeOnlyIf="${NoFilesFound == 0}" />


<print label="Print" version="1.0">
	<![CDATA[it worked!]]>
</print>
Rick Elliott
Lead Solutions Consultant
(402) 944.4242
(800) 949-4696

WallyD444

Posts: 10
Joined: Wed Sep 17, 2014 8:38 am

Post by WallyD444 » Thu Jul 02, 2015 12:08 pm
Thanks Rick, that worked perfectly!

atarrant

Posts: 10
Joined: Tue Mar 27, 2012 7:59 pm

Post by atarrant » Tue Jan 05, 2016 10:08 am
I've been using the suggested method of creating a Variable entry for every variable that might be used. I've run into some complications with doing it this way though so a way to check the existence of a variable would be nice.
1) It gets a bit messy particularly when I need to create Variable entries for system variables like: system.job.error
2) I've had some issues with creating a Variable entry in child projects inadvertantly wiping out values set in the parent project. Simplified code snippet below.
ParentProject
Code: Select all
<project name="ParentProject" mainModule="Main" version="2.0" logLevel="verbose">
	<description>This demonstrates the variable value loss issue.</description>
	<module name="Main">
		<setVariable label="(Variable) ERROR" name="ERROR" value="5" version="2.0" />
		<callProject label="(Project) ChildProject" project="ChildProject" runInSameJob="true" inheritUserVariables="false" returnUserVariables="true" version="1.0" />
		<!--ERROR is blank here-->
	</module>
</project>
ChildProject
Code: Select all
<project name="ChildProject" mainModule="Main" version="2.0" logLevel="verbose">
	<description>Child project for ParentProject</description>
	<variable name="ERROR" value="" />
	<module name="Main" />
</project>
13 posts Page 1 of 2