Sas 宏变量数据类型不一致

Sas 宏变量数据类型不一致,sas,sas-macro,Sas,Sas Macro,我试图制作一个简单的宏来检查特定的宏变量是否丢失或不存在。通常,这需要两条语句:a%symexist,如果它确实存在,则需要附加逻辑来检测它是否为空值。下面的代码将所有这些合并为一个 %macro isnull(macvar); %sysevalf(%superq(%superq(macvar)) NE %str(), boolean); %mend isnull; 问题 我不能在%if语句中使用%isNull(),因为返回的值似乎总是一个字符。如果在开放代码中或宏本身中,此行为会有所

我试图制作一个简单的宏来检查特定的宏变量是否丢失或不存在。通常,这需要两条语句:a
%symexist
,如果它确实存在,则需要附加逻辑来检测它是否为空值。下面的代码将所有这些合并为一个

%macro isnull(macvar);
    %sysevalf(%superq(%superq(macvar)) NE %str(), boolean);
%mend isnull;
问题

我不能在
%if
语句中使用
%isNull()
,因为返回的值似乎总是一个字符。如果在开放代码中或宏本身中,此行为会有所不同

我尝试过的

我已经把范围缩小到了不解析为数值的宏。我尝试了所有方法,从用
%sysfunc(putn())
封装到
%cmpres()
%sysfunc(compress())
。如果是开放代码,则为数字。如果它在另一个宏中,则是字符。您可以通过以下代码看到它:

/* 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);
想要

我希望能够在
%if
语句中使用它来检查宏是否同时存在且不为空

%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;

这里的问题是宏中有一个分号。见此:

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
注意
?改为编译此文件:

%macro missm(macvar);
    %sysevalf(%superq(%superq(macvar)) NE %str(), boolean)
%mend missm;
你会得到:

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
我还要补充一点,我认为您不应该跳过
%symexist
。你在日志中得到一个警告,你在这里做的方式,这是很容易避免的

%macro missm(macvar);
  %if %symexist(&macvar.) %then
    %sysevalf(%superq(%superq(macvar)) NE , boolean)
  %else
    0 
%mend missm;
您还将注意到,我删除了不必要的
%str()
,它实际上没有任何作用。请参阅张忠的开创性论文,了解原因(如果你还没有读过,还可以了解更多的信息)


最后-我想我建议重命名宏和/或反转方向<代码>%if%missm
对我说“如果此宏变量丢失”,这与您所说的相反:如果未丢失,则返回TRUE<代码>%missm对于等式[blank]应返回true,或者不返回
%symexist
;对于[defined and contains a value],它应该返回false。

查看一下,但首先是一个误解,宏变量没有“类型”-它们都是文本。如果要将%MISSM()视为一个函数,它无法生成分号!!分号再次出现。回答得很好,谢谢@StuSztukowski如果你打算对它进行重命名以使其更清晰,我非常喜欢使用
isMissing()
is_missing
这样的名称,因此当它们遵循
If
语句时,读起来几乎像是简单的英语。我已经做了建议的更改并编辑了原始问题。谢谢