2017-12-01 6 views
1

Ich habe ein sehr großes SAS-Programm mit etwa 50 Unterprogrammen, von denen jedes viele Schritte aufweist. Im Moment wird es bis zum Abschluss ausgeführt, unabhängig davon, ob ein Fehler vorliegt. Ich möchte, dass es anhält und beendet wird, wenn ein Fehler auftritt.Großes SAS-Programm effizient stoppen

Beachten Sie, dass das Makro SYSERR für diese Aufgabe ungeeignet ist, da ich SYSERR am Ende jedes einzelnen Schritts überprüfen muss (zB nach jedem DATA- oder PROC-Schritt), da SYSERR nach jedem Schritt zurückgesetzt wird Grenze; Dies wäre eine sehr zeitraubende und fehleranfällige Aufgabe, da es in jedem meiner 50 Unterprogramme Tausende verschiedener Stufengrenzen gibt.

Die Lösung, die ich mir vorstelle, würde bedeuten, die von jedem der 50 Unterprogramme erstellte Protokolldatei unmittelbar nach der Ausführung zu überprüfen und dann anzuhalten, wenn ein Fehler in der Protokolldatei auftaucht nächstes Unterprogramm, wenn kein Fehler vorliegt). Ich kann mir jedoch nicht vorstellen, wie ich das machen soll. Vielen Dank im Voraus.

+1

Haben Sie eine SAS/Connect-Lizenz? Vielleicht könnten Sie jedes der Unterprogramme als Aufgaben oder rsubmit Blöcke spawnen? – Tom

+0

Ich habe eine SAS-Lizenz, also könnte ich das versuchen (ich bin relativ neu in SAS, also muss ich in diese Methode schauen). –

+0

Mögliches Duplikat von [Gibt es eine Möglichkeit, SAS nach der ersten Warnung oder dem ersten Fehler anzuhalten?] (Https://stackoverflow.com/questions/9009944/is-there-a-way-to-make-sas-stop- nach der ersten Warnung oder Fehler –

Antwort

0

Ihre Lösung, um das Protokoll zu überprüfen, glaube ich, ist das gute. Weil Sie die Log-Wörter wie "WARNUNG" und "FEHLER" oder "FEHLER:" filtern können. Sie können ein Protokoll nach Excel kopieren und filtern, wenn die Zeilen diese Fehlerschlüsselwörter enthalten.

Allerdings habe ich eine Lösung in SAS hier

1) Erstellung des Protokolls mit proc printto 2)

Hier die proc printto Umleitung 3) Analyse der Log automatisch mit SAS schließen ist der Code für die Makrofunktion:

/** 
* 
* @dev Function to create a log for a program 
* @param job The name of the job to be logged 
* 
*/ 

%macro runjob(job /*Enter the name of the job to log Ex: myjob*/); 
    option fullstimer; 

    %let runjob=%sysfunc(compress(&job._%sysfunc(datetime(),b8601dt))); 
    data _null_; 
     call symputx("runjob","&runjob.",'G'); 
    run; 

    filename logfile "C:\LOG\&runjob..log"; 

    proc printto log=logfile new; 
    run; 

%mend runjob; /* %runjob(myjob); */ 


/** 
* 
* @dev Funtion to check if a table is empty 
* @param inset The name of dataset to be checked 
* 
*/ 

%macro checkTableIfEmpty(inset /* Write the name of your dataset (ex: checklog) */); 
    %let dsid = %sysfunc (open(&inset)); 


    %if &dsid ge 0 %then 
     %let dsid = 1; 
    %let anyobs = %sysfunc (attrn(&dsid,ANY)); 
    %let dsid = %sysfunc (close(&dsid)); 

    %put anyobs=&anyobs; 

    %if &anyobs = 1 %then 
     %do; 

      data _null_; 
       call symputx('checkTableIfEmpty',0,'G'); 
      run; 

     %end; 
    %else 
     %do; 

      data _null_; 
       call symputx('checkTableIfEmpty',1,'G'); 
      run; 

     %end; 
%mend checkTableIfEmpty; /* %checkTableIfEmpty(checklog); */ 


/** 
* 
* @dev Function to filter a log file from SAS with words like "warning" and "error" 
* @param inp The pathname of the log to be checked 
* 
*/ 

%macro checkLog(inp /* Write the pathname of the log to be checked (ex: myjob_20170818T161545.log) */); 

    data empty_marker; 
     length MSG $200; 
     MSG='No error(s)/warning(s).'; 
    run; 

    DATA CHECKLOG; 
     LENGTH ROWS $200; 
     LABEL ROWS = 'Messages from LOG'; 
     INFILE "&inp" TRUNCOVER; 
     INPUT ROWS &; 
     LINE = _N_; 

     IF SUBSTR(ROWS,1,5)='ERROR' OR SUBSTR(ROWS,1,7)='WARNING' THEN 
      OUTPUT; 
    RUN; 

    %checkTableIfEmpty(checklog); 

    ODS HTML BODY="C:\LOG\log.html" STYLE=sasweb; 
    TITLE1 "Messages from LOG"; 

    %if &checkTableIfEmpty = 0 %then 
     %do; 
      proc sql; 
       select distinct(rows) from checklog; 
      run; 

     %end; 
    %else 
     %do; 

      proc print data=empty_marker; 
      run; 

     %end; 

    ODS HTML CLOSE; 
%mend checkLog; /* %checkLog(c:\LOG\myjob_20170818T161545.log); */ 

Sie dann diese Funktionen in einem Programm wie die

verwenden können 10
%let jobname=myjob; 
/* START */ 
%runjob(&jobname); 

... 

/*END*/ 
proc printto; 
run; 

%checkLog(C:\LOG\&runjob..log); 

Sie eine HTML-Datei in C erhalten: \ LOG \ log.html

Messages from LOG 
ERROR: Ambiguous reference, column DateSent is in more than one table. 
ERROR: Ambiguous reference, column Operation_date is in more than one table. 
ERROR: Expression using equals (=) has components that are of different data types. 
ERROR: Expression using less than or equal (<=) has components that are of different data types. 

Die Duplikate Zeilen gelöscht werden, wegen einer "deutlichen" Auswahl. Es wird wirklich einfacher sein, mit jedem Protokoll jedes Unterprogramms zu debuggen.

Grüße,

+0

Vielen Dank für Ihre Antwort! Ich bin auf halbem Weg durch die Umsetzung Ihrer Methode! –