Hallo zusammen,
SAS-AutoCall-Makros werden nur beim Start des EG eingelesen/definiert.
Bei der Entwicklung / Korrektur von beim Start existierenden AutoCall-Makros muss ich den EG aktuell neu starten.
Kann ich dies umgehen? Gibt es eine Art %reset, %init etc.?
Beste Grüße
Wolfgang Müller
Hallo Herr Müller,
SAS-AutoCall-Makros werden nur beim Start des EG eingelesen/definiert.
Also das würde ich im Standard so nicht unterschreiben.
Es sei denn das ist bei Ihnen speziell eingerichtet.
In der Regel sucht die Macro Facility zunächst in der aktiven SAS-Session nach Macros (Katalog "work.sasmacr"). Danach wird in den Autocall-Macros gesucht. Dies aber nicht zum Start des EG, sondern bei Aufruf eines Macros, also wenn ein Programm gestartet wird.
Mir erschließt sich daher die Problematik nicht ganz.
Falls Autocall-Macros angepasst werden, sollten diese anschließend neu aufgerufen werden, indem der entsprechende Code aufgerufen wird. Der EG muss dazu nicht neu gestartet werden.
Ich konnte online einen Hinweis finden, der vielleicht das Problem beschreibt, bzw. löst:
https://marc.info/?l=sas-l&m=134400252002392
[...] already defined macros are not searched to see if these have been altered. In any case, you don't have to quit EG to use the modified macro. Just include it or open it and run it. If the macro is in an autocall directory with fileref project, you can re-read the macro with: %inc project(mymacro); No need to type ".sas" or the full path.
In diesem Fall (Macro wurde geändert, aber nicht neu ausgeführt) wird mit einem Fileref (project) gearbeitet, um das Macro neu aufzurufen.
Denkbar wäre auch, dass bei Ihnen verschiedene Optionen in der Bearbeitung von Macros stören:
MSTORED: https://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/viewer.htm#a000543663.htm
MRECALL: https://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/viewer.htm#a000543651.htm
Beste Grüße
Michael
Wie kann denn der Inhalt des Katalogs "work.sasmacr" angezeigt werden?
PROC CATALOG CATALOG = WORK.SASMACR ; CONTENTS; RUN ;
liefert
ERROR: Catalog WORK.SASMACR does not exist.
WARNING: Command CONTENTS not processed because of errors noted above.
Und unter Server/SASApp/WORK ist auch kein entsprechender Table.
Gruß
Wolfgang Müller
Wenn Autocall-Makros neu definiert wurden, befinden sich die neu definierten Makros im Katalog work.sasmacr.
Man könnte jetzt versuchen, die dort befindlichen Makros zu löschen und neu aus dem Original-(Autocall)Verzeichnis zu %INCLUDEn.
Ich würde einfach vorschlagen sich im EG unter Ansicht --> Serverliste die SAS Server anzeigen zu lassen.
Mit Rechtsklick auf den Ausführungsserver kann die Verbindung geschlossen werden. Bei der nächsten Ausführung von SAS Code wird der Server neu gestartet und verwendet wieder die ursprünglichen Makros.
EG muss hierfür nicht neu gestartet werden, sondern nur der SAS Server!
Grüße,
Andreas
Das Einbinden über FileHandle ist mir bisher nicht elegant gelungen, da der Code hierzu nur einmal aufgerufen werden darf,
ansonsten folgt Fehlermeldung, dass FH bereits existiert.
Den Server neu zu starten ist leicht besser als den EG neu zu starten. Nichtsdestotrotz die temporären Tables im WORK sind dann weg, oder?
Beste Grüße
Wolfgang Müller
Statt per Filehandle kann der Code natürlich auch direkt inkludiert werden, dann eben mit voller Pfadangabe. Das dürfte für Entwicklungs-Zwecke auch praktikabel sein.
Wenn im EG die Verbindung getrennt wird, wird nicht der Server neu gestartet. Lediglich die Verbindung dahin und somit die Session wird beendet. Damit werden in der Regel auch alle work-Tabellen gelöscht.
Meines Wissens soll es in neuen SAS-Versionen eine Option geben mit den bestehenden Work-Tabellen weiter zu arbeiten, wenn der selbe User wieder eine Session startet. Das ist wahrscheinlich aber noch nicht die Regel. 😉
Jedem sas-macro kan auf neues compiliert werden durch:
- die sas-code mit die macro an zu rufen
%include <fileref>(<macro>) ;
Hallo Herr Müller,
SAS Makros werden - wie von den Kollegen schon geschrieben - üblicherweise in einem temporären Katalog in Work.Sasmacr gespeichert. Die Autocall-Facility sorgt dafür, dass in einem bestimmten Suchpfad gespeicherte Programme, die Makros enthalten, beim ersten Aufruf des Makros im Hintergrund inkludiert und kompiliert werden (wodurch sie im genannten Katalog landen).
Wenn Sie ein Makro im EG aktiv überschreiben, überschreiben Sie die kompilierte Version im Katalog und können zunächst nicht mehr auf die Originalversion zurück.
Wenn Sie diese Originalversion wieder verwenden möchten ohne den darunterliegenden SAS-Prozess neu zu starten, können Sie die aktuelle Version des Makros aus dem Katalog löschen, beim nächsten Aufruf wird dann wieder automatisch im Hintergrund die Originalversion vom Server geladen und kompiliert.
Um diesen Vorgang einfacher zu machen, wurde mit 9.3 das Makro-Statement %SysMacDelete eingeführt, hier ein Beispiel:
%print(sashelp.class);
%Macro print(table);
Ods text=" autocall makro ueberschrieben (&table)...";
%Mend;
%print(sashelp.class);
%SysmacDelete print;
%print(sashelp.class);
Das auf dem Server abgelegte Autocall-Makro PRINT hat folgenden Code:
%Macro print(table);
Title "autocall macro print";
Proc Print data=&table(obs=3);
Run;
%Mend;
Das Ergebnis sieht dann so aus:
Hoffe, die Info hilft weiter, viele Grüße,
Grischa Pfister
Das ist ein guter Hinweis! Das Makro
%SysmacDelete
kannte ich nicht. Nun brauche ich nur noch eine Schleife über alle Einträge aus dem Katalog work.sasmcr, dann
kann ich alle AutoCallMacros mit einem Makro wieder "neu" laden/kompilieren.
Gruß
Wolfgang
Hallo Wolfgang,
es gibt einen View in den SQL Dictionary Tables aus dem sich die Liste der vorhandenen Macros erstellen lässt. Das aktuell ausgeführte Makro sollte allerdings vom Löschen ausgenommen werden, weil (ohne /nowarn bei %SysMacDelete) sonst eine Fehlermeldung im LOG kommt.
Ich habe hier mal eine Version eines Löschen-Makros erstellt, %DeleteMacros(list), das noch eine Liste von Makronamen als Parameter hat, die nicht gelöscht werden sollen. Diese "Positiv-Liste" enthält einfach die Namen durch Leerzeichen getrennt. Im Code werden dann um die einzelnen Namen noch Anführungszeichen ergänzt und das ganze in einen IN (liste) Operator eingebaut - hier wird mit &SYSMACRONAME auch der Name des gerade laufenden Makros vom Löschen ausgenommen.
Im anschließenden Loop werden die Makros dann gelöscht.
* GP Loeschen von Makros aus dem Catalog Work.Sasmacr*;
Options mcompilenote = all;
%Macro DeleteMacros(listExclude);
%Local listMacros listExclude2 curMacro i;
%Let listExclude2 = "%Upcase(%Scan(&listExclude,1))";
%If ( %Length(&listExclude) > 1) %Then %Do i=2 %To %Sysfunc(countw(&listExclude));
%Let listExclude2 = &listExclude2 "%Upcase(%Scan(&listExclude,&i))";
%End;
Proc Sql noprint ;
Select objname Into :listMacros Separated By " "
From Dictionary.catalogs
Where libname = "WORK" And memname = "SASMACR" And objtype = "MACRO"
and objname Not In ("&SysMacroName" &listExclude2)
;
Quit;
%If ( %Symexist(debug) ) %Then %If ( &debug ) %Then %Put NOTE: [DeleteMacros] Macros to delete: &listMacros;
%Do i=1 %To &sqlobs;
%Let curMacro = %Scan(&listMacros,&i);
%If ( %Symexist(debug) ) %Then %If ( &debug ) %Then %Put NOTE: [DeleteMacros] Deleting &curMacro....;
%SysMacDelete &curMacro;
%End;
%If ( %Symexist(debug) ) %Then %If ( &debug ) %Then %Put NOTE: [DeleteMacros] done.;
%Mend;
%Macro test;
%Put test;
%Mend;
%Macro abc;
%Put abc;
%Mend;
%Macro aaa;
%Put aaa;
%Mend;
%DeleteMacros(aaa bbb);
%Let debug = 1;
%DeleteMacros();
Wird eine Globale MVAR DEBUG (auf 1) gesetzt, gibt das Makro noch ein paar Infos aus, was es gerade tut.
Hoffe, das hilft wieder einen Schritt weiter,
viele Grüße,
Grischa
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!