Inappropriate data type of macro variable
I am trying to create a simple macro that checks for the absence or absence of a specific macro variable. Typically this would require two operators: a %symexist
, and if it exists, additional logic is added to determine if it is null. The following code combines it all into one.
%macro isnull(macvar); %sysevalf(%superq(%superq(macvar)) NE %str(), boolean); %mend isnull;
Problem
I cannot use %isNull()
in a statement %if
because the return value always appears to be a symbol. This behavior is different if it is in open source or within the macro itself.
What i tried
I narrowed it down to a macro that did not resolve as a numeric value. I've tried everything from %sysfunc(putn())
to %cmpres()
to %sysfunc(compress())
. If it is in open source, it is numeric. If it's in another macro, it's a symbol. You can see it with this code:
/* Miss2 resolves incorrectly as character */
%macro check;
%let miss1=%sysevalf(%superq(asdf) =, boolean);
%let miss2=%isNull(asdf);
%put Miss1: %datatyp(&miss1);
%put Miss2: %datatyp(&miss2);
%mend;
%check;
/* Miss2 resolves correctly as numeric */
%let miss1=%sysevalf(%superq(asdf) =, boolean);
%let miss2=%isNull(asdf);
%put Miss1: %datatyp(&miss1);
%put Miss2: %datatyp(&miss2);
Want to
I want to be able to use this in a statement %if
to check if a macro exists and is not empty.
%macro foo;
%if(%isNull(sysuserid) = 1) %then %put sysuserid exists;
%if(%isNull(asdffdsa) = 0) %then %put asdffdsa does not exist;
%if(%isNull(sysuserid) > 0) %then %put this should resolve;
%if(%isNull(asdffdsa) > 0) %then %put this should not resolve;
%mend;
%foo;
source to share
The problem is that your macro has a semicolon. See this:
174 %macro check;
175 %let miss1=%sysevalf(%superq(asdf) NE %str(), boolean);
176 %let miss2=%missm(asdf);
177
178 %put &miss1. Miss1: %datatyp(&miss1);
179 %put &miss2. Miss2: %datatyp(%unquote(&miss2));
180 %mend;
181 %check;
WARNING: Apparent symbolic reference ASDF not resolved.
WARNING: Apparent symbolic reference ASDF not resolved.
0 Miss1: NUMERIC
0; Miss2: CHAR
Pay attention to ;
? Compile this instead:
%macro missm(macvar); %sysevalf(%superq(%superq(macvar)) NE %str(), boolean) %mend missm;
and you get:
185 %macro check;
186 %let miss1=%sysevalf(%superq(asdf) NE %str(), boolean);
187 %let miss2=%missm(asdf);
188
189 %put &miss1. Miss1: %datatyp(&miss1);
190 %put &miss2. Miss2: %datatyp(%unquote(&miss2));
191 %mend;
192 %check;
WARNING: Apparent symbolic reference ASDF not resolved.
WARNING: Apparent symbolic reference ASDF not resolved.
0 Miss1: NUMERIC
0 Miss2: NUMERIC
I'll also add that I think you shouldn't miss %symexist
. You get a warning in the log like you do here, which is easy to avoid.
%macro missm(macvar);
%if %symexist(&macvar.) %then
%sysevalf(%superq(%superq(macvar)) NE , boolean)
%else
0
%mend missm;
You will also notice that I am deleting the unneeded %str()
one that doesn't really do anything. See Chang Chung's original article, Is this macro parameter empty , what for (and for more details if you haven't read it yet).
Finally - I think I suggest renaming your macro and / or changing direction. %if %missm
tells me "if this macro variable is missing", which is the opposite of what you say: TRUE is returned if it is NOT missing. %missm
must return true for EQ [blank], or NOT %symexist
; it must return false for [is defined and contains a value].
source to share