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;

      

+3


source to share


1 answer


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].

+2


source







All Articles