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?
3 Réponses :
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;
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 code > 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.
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');
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;
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' code> 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 ...
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 dansWORK.SASMACR
.