在 SAS 中派生唯一的 libref and/or fileref

Derive unique libref and/or fileref in SAS

我经常需要分配(和取消分配)临时 librefs/filerefs 作为实用程序宏的一部分 - 因此我需要避免与任何现有 librefs/filerefs 的命名冲突。我知道我可以查询 sashelp 或字典表并使用条件逻辑进行迭代,直到找到一个未分配的表,但我想知道是否有更简单的方法?

例如,以下将在工作库中创建一个唯一命名的数据集:

data;run;

librefs/filerefs 是否有一些等价物?

实际上写一个相当简单,并且不涉及查询(昂贵的)字典 table:

libname mcore0 (work);
libname mcore1 (work);
libname mcore2 (work);

%macro mf_getuniquelibref(prefix=mcore,maxtries=1000);
%local x;
%let x=0;
%do x=0 %to &maxtries;
 %if %sysfunc(libref(&prefix&x)) ne 0 %then %do;
    %put Libref &prefix&x is available!;
    &prefix&x
    %return;
 %end;
%end;
%put unable to find available libref in range &prefix.0-&maxtries;
%mend;

%let libref=%mf_getuniquelibref();
%put &=libref;

哪个returns;

更新:

我已经将这两个的宏添加到 MacroCore 库中,它们可以按如下方式使用:

filename mc url "https://raw.githubusercontent.com/sasjs/core/main/macrocore.sas";
%inc mc;

%let libref=%mf_getuniquelibref();
%let fileref=%mf_getuniquefileref();

FILENAME() 函数已经为此提供了一个方法。当您使用文件引用的缺失值调用它时,它会使用格式 #LNnnnnn.

生成一个
6     data test;
7       length fileref  ;
8       rc=filename(fileref,,'temp');
9       put rc= fileref=;
10    run;

rc=0 fileref=#LN00056
NOTE: The data set WORK.TEST has 1 observations and 2 variables.
NOTE: DATA statement used (Total process time):
      real time           0.02 seconds
      cpu time            0.01 seconds


11    %global fileref ;
12    %let rc=%sysfunc(filename(fileref,,temp));
13    %put &=rc &=fileref ;
RC=0 FILEREF=#LN00058

在打开执行 space 中调用的未记录的 monotonic 函数对于获取未使用的值非常方便。

libname mylib "C:\temp\sandbox";

data mylib.data%sysfunc(monotonic());
  … 
run;

或者编写一个宏来为 libref 提供一个名称。如果需要,宏还可以检查是否存在:

%macro nextName(lib=,base=data,check=1);
  %local index name;
  %if %length(&lib) %then %let lib=&lib..;/* handle non-empty lib */
  %do %until (&check and not %sysfunc(exist(&name,data)));
    %let name = &lib.&base.%sysfunc(monotonic());
  %end;
  &name
%mend;

data data3;run;
data data4;run;

%put %nextName();
%put %nextName();
%put %nextName();
%put %nextName();

proc sort data=sashelp.class out=%nextname();
  by age;
run;

您可以进行稳健的宏实施并测试 lib 是否存在和有效的 check 值。

LIBNAME 函数具有与 FILENAME 类似的功能,但它不像 FILENAME 那样填充引用名称变量。我能想到的唯一方法是比较 SASHELP.VLIBNAM 前后。库引用格式为 WC00000n。

79   data _null_;
80      length libref .;
81      libref = ' ';
82      rc = libname(libref,'.');
83      msg = sysmsg();
84      put _all_;
85      run;

libref=  rc=-70004 msg=NOTE: Libref  refers to the same physical library as WC000004. _ERROR_=0 _N_=1