1
votes

Dériver libref et / ou fileref unique dans SAS

J'ai souvent besoin d'assigner (et de désaffecter) des librefs / filerefs temporaires dans le cadre des macros utilitaires - et donc je dois éviter les conflits de noms avec les libresfs / filerefs existants. Je sais que je pourrais interroger les tables d'aide ou de dictionnaire et utiliser la logique conditionnelle pour itérer jusqu'à ce que j'en trouve une qui n'est pas attribuée, mais je me suis demandé s'il y avait un moyen plus simple?

Par exemple, ce qui suit va créer un jeu de données au nom unique dans la bibliothèque de travail:

data;run;

Existe-t-il un équivalent pour librefs / filerefs?


2 commentaires

Avez-vous essayé d'utiliser & SYSINDEX pour générer un libref?


^^ gentil, je ne connaissais pas sysindex !


4 Réponses :


1
votes

En fait, en écrire un était assez simple et n'impliquait pas d'interroger la table de dictionnaire (coûteuse):

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

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

qui renvoie;

 entrez la description de l'image ici

UPDATE:[

J'ai ajouté des macros pour les deux dans le MacroCore et ils peuvent être utilisés comme suit:

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;


0 commentaires

2
votes

La fonction FILENAME () fournit déjà une méthode pour cela. Lorsque vous l'appelez avec une valeur manquante pour le fichier, il en génère une au format #LNnnnnn.

6     data test;
7       length fileref $8 ;
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


3 commentaires

Ajoutez-le avec la fonction LIBNAME () et vous êtes prêt à partir :)


Je ne pense pas que la fonction LIBNAME () offre cette capacité. Vous devez lui donner un nom réel à utiliser pour la bibliothèque. De plus, le # utilisé dans les noms générés par FILENAME () n'est pas valide pour une utilisation dans un libref.


c'est le genre de chose que je cherchais!



1
votes

La fonction monotone non documentée, appelée dans l'espace d'exécution ouvert, est très pratique pour obtenir une valeur inutilisée.

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

Ou codez une macro pour fournir un nom pour un libref. La macro peut également vérifier l'existence si vous le souhaitez:

libname mylib "C:\temp\sandbox";

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

Vous pouvez utiliser une implémentation de macro robuste et tester l'existence de lib et une vérification valide valeur.


1 commentaires

très agréable! Pas sûr que je puisse l'utiliser dans ce cas car il ne garantirait pas l'unicité (au-delà de l'approche itérative) .. Mais quand même, pratique à avoir dans la boîte à outils!



1
votes

La fonction LIBNAME a une fonctionnalité similaire à FILENAME mais elle ne remplit pas la variable de nom de référence comme avec FILENAME. La seule façon dont je peux penser serait de comparer SASHELP.VLIBNAM avant et après. Les librefs sont sous la forme WC00000n.

79   data _null_;
80      length libref $32.;
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


1 commentaires

ou scannez la réponse sysmsg ! Génial! Je savais que cela devait être possible :-)