2
votes

Comment dire à SAS de compiler une macro chaque fois qu'elle est appelée au lieu de le faire manuellement

Contexte: Nous utilisons SAS 9.4 et Enterprise Guide 7.15 . Actuellement, nous implémentons de nouvelles macros et, bien sûr, nous devons beaucoup changer en cours de route. Des changements parfois plus petits, parfois plus importants. Le problème est que pour que les modifications fonctionnent, SAS a besoin de nous pour compiler manuellement le code de la macro ou pour redémarrer la session, ce qui est un peu fastidieux.

Voici la configuration actuelle dans notre fichier principal (qui appelle toutes les macros):

/* Macro options */
     MAUTOSOURCE  sasautos = "<path to macro>" mlogic mlogicnest mprint mprintnest MRECALL

Est-ce possible, en utilisant le MAUTOSOURCE * / sasautos = "" , pour indiquer à SAS à chaque fois que la macro est appelée de compiler également la macro au lieu d'utiliser la macro stockée en session? Idéalement, la macro ne serait compilée que lorsque toute la ligne de code du fichier principal ( MAUTOSOURCE * / sasautos = "" etc.) est exécutée, sinon elle devrait conserver une version compilée dans la session.

J'ai trouvé ça papier (The Autocall Macro Facility dans l'environnement SAS pour Windows) qui indique dans la conclusion

Après cela, SAS utilisera le code qui a déjà été compilé. Si des modifications sont apportées à la macro, elle doit être compilé à nouveau avant que les modifications n'entrent en vigueur.

ce qui, je l'espère, ne signifie pas que je dois le faire manuellement . Y a-t-il une option de macro à définir?


2 commentaires

Combien de temps gardez-vous votre session SAS active? Utilisez-vous uniquement EG comme interface utilisateur ou certains utilisateurs appellent-ils directement SAS soit en tant que travaux par lots / en arrière-plan, soit en utilisant SAS Display Manger?


@Tom Fondamentalement, je ne quitte jamais la session sauf si je dois le faire. J'utilise principalement EG (en combinaison avec VS Code mais cela ne devrait pas avoir d'importance je suppose) et oui, nous utilisons SAS Server, donc d'autres utilisateurs appellent également SAS. Je viens de trouver une option % SYSMACDELETE macro_name; qui semble faire ce que je veux - semble aussi la même que les données null suggèrent ... néanmoins je me demande pourquoi je ne peux pas trouvez la macro compilée dans WORK.SASMACR .


3 Réponses :


3
votes

Si vous supprimez la macro compilée de WORK, SASMACR SAS devra recompiler la macro lorsque vous l'appelez à nouveau.

proc catalog c=work.sasmacr;
   *contents;
   delete your-macro-to-recompile.macro;
   run;
   quit;


4 commentaires

Thx, juste pour clarifier: j'ai trouvé la fonction macro % SYSMACDELETE qui au moins semble faire exactement ce que je veux quand elle est placée dans l'en-tête de mon fichier principal d'exécution. Cette fonction et votre suggestion fonctionnent-elles de la même manière?


Oui, la documentation indique exactement cela: supprime une définition de macro du catalogue Work.SASMacr.


J'ai lu la définition aussi mais une chose que je n'arrive pas à comprendre (Tom l'a mentionné): mes MAcros ne finissent pas dans WORK.SASMACR mais plutôt dans WORK.SASMAC1 donc techniquement la fonction ne doit rien supprimer simplement parce que le catalogue WORK.SASMACR n'existe même pas (si vous changez sasmacr en sasmac1 votre La réponse fonctionne parfaitement.)


Oui, vous devez supprimer la macro du catalogue où elle est stockée.



3
votes

Pour vos utilisateurs normaux, vous devez définir un calendrier de publication des modifications. Les utilisateurs sauront qu'ils doivent redémarrer une nouvelle session après la publication.

Pour vos développeurs qui testent les changements au fur et à mesure qu'ils sont effectués, il leur suffit d'utiliser% INCLUDE pour recompiler la macro. Donc, si vous savez que la macro XYZ est modifiée, exécutez simplement:

%let s_eg_save= checkfmt checkhotfix
  eclibassign eclibunassign enterpriseguide gaccessible
  _eg_conditional_dropds
;

Ou vous pouvez la forcer brutalement et recompiler toutes les macros de votre bibliothèque d'appels automatiques.

XXX

Vous pourriez devenir plus sophistiqué et créer une macro qui nettoie le catalogue actuel des macros compilées. Quelque chose comme:

%macro clean_autocall;
proc catalog force c=work.sasmacr;
 save clean_autocall /et=macro;
quit;
options mrecall mautosource;
%mend clean_autocall;

Mais si vous utilisez Enterprise Guide, il y a deux problèmes.

Premièrement, pour une raison quelconque, il utilise un catalogue différent pour stocker les macros compilées. (Pourquoi?) Je pense que c'est WORK.SASMAC1 au lieu de WORK.SASMACR.

Le deuxième EG compilera manuellement un tas de macros d'aide dont il a besoin. Je ne sais pas s'il existe une source officielle pour la liste complète de ces macros? Vous pouvez essayer d'ajouter du code à votre projet pour créer automatiquement la liste en fonction des entrées du catalogue au démarrage de votre projet. Voici une liste que j'ai faite il y a plus de 10 ans lorsque j'ai essayé d'utiliser EG avec un environnement de production. Mais je suis sûr qu'il est dépassé.

%incldue maclib('*.sas');


0 commentaires

5
votes

Dans SAS 9.3, ils ont ajouté la fonction macro % SYSMACDELETE . Donc, si vous voulez simplement laisser l'autocall redéfinir une seule macro, utilisez-la pour supprimer la définition actuelle.

 97         %macro test1; %mend;
 98         %macro test2; %mend;
 99         %macro test3; %mend;
 100        %macro test4; %mend;
 101        %macdelete(test1 test3);
 Removing TEST1 from WORK catalog SASMAC1
 Removing TEST3 from WORK catalog SASMAC1

Voici une macro utilitaire qui interrogera la vue SASHELP.VCATALG pour trouver les macros compilées dans le WORK et supprimez-les. Il propose des options pour répertorier les noms des macros à supprimer ou à conserver. Notez que les sessions SAS normales utilisent WORK.SASMACR pour stocker les macros compilées. Mais SAS / Studio et EG (et peut-être d'autres manières d'exécuter SAS) utilisent WORK.SASMAC1 à la place.

https://github.com/sasutils/macros/blob/master/macdelete.sas

3348  %macro test1; %mend;
3349  %macro test2; %mend;
3350  %macro test3; %mend;
3351  %macro test4; %mend;
3352  %macdelete(test1 test3);
Removing TEST1 from WORK catalog SASMACR
Removing TEST3 from WORK catalog SASMACR
3353  %macdelete(keep=test2);
Removing TEST4 from WORK catalog SASMACR

Exemple:

%macro macdelete(delete,keep);
/*----------------------------------------------------------------------------
Remove compiled macros using %SYSMACDELETE macro statement.

Use DELETE parameter to list macro names to delete.
Use KEEP parameter to list macro names to NOT delete.
Calling it with no values will delete all macros not currently running.
----------------------------------------------------------------------------*/
%local libname memname objname objtype fid i;
%do i=1 %to %sysmexecdepth;
  %let keep=%sysmexecname(&i) &keep;
%end;
%if %length(&delete) %then %let delete=and findw("&delete",objname,',','sit');
%let fid=%sysfunc(open( sashelp.vcatalg(keep=libname memname objname objtype
 where=(libname='WORK' and objtype='MACRO' and memname like 'SASMAC_'
   and not findw("&keep",objname,',','sit') &delete))));
%if (&fid) %then %do;
  %syscall set(fid);
  %do %while(0=%sysfunc(fetch(&fid)));
    %put %sysfunc(compbl(Removing &objname from &libname catalog &memname));
    %sysmacdelete &objname;
  %end;
  %let fid=%sysfunc(close(&fid));
%end;
%else %put %qsysfunc(sysmsg());
%mend macdelete;

Exemple lors de l'exécution de SAS / Studio ou Enterprise Guide:

%symacdelete mymacro;


5 commentaires

Génial! J'aime vraiment vos deux réponses. À l'heure actuelle, la situation n'est pas aussi complexe, donc nous allons probablement nous en tenir à un simple appel de % SYSMACDELETE macro_name; ou % include 'path_to_macro' mais je veillerai à conserver une copie de votre macro utilitaire, très pratique! BTW vous aviez raison, le catalogue est WORK.SASMAC1 . Avez-vous une idée de la raison pour laquelle % SYSMACDELETE macro_name; supprime également dans ce catalogue bien qu'il soit indiqué différemment dans la documentation (seul WORK.SASMACR doit être affecté)?


Certains comment la façon dont EG et SAS / Studio exécutent SAS le fait utiliser WORK.SASMAC1. Je n'ai jamais trouvé de référence à eux dans les manuels.


Ensuite, je le prends tel quel (bien qu'ils devraient vraiment l'ajouter). BTW Votre dernier exemple est probablement exécuté dans EG au lieu de SAS / Studio?


EG utilise également WORK.SASMAC1, mais je n'utilise plus EG.


Je voulais dire dans votre réponse ("Exemple lors de l'exécution de SAS / Studio:"): Ne devrait-il pas être WORK.SASMAC1 uniquement lorsque vous utilisez EG? Je ne l'ai pas testé dans SAS / Studio cependant ...