2016-05-02 9 views
0

Ich verwende den folgenden Code, um ein Verzeichnis durchzulaufen und alle .xlsx-Dateien in jedem Unterordner zu finden. Ich muss es anpassen, um den Pfad zu jeder gefundenen Datei zu übernehmen und sie während der Ausführung in ein Dataset zu stapeln.Durchlaufen Sie Verzeichnisse mit SAS und geben Sie bestimmte Dateinamen in ein Dataset ein

data thisfile; 
    set _NULL_; 
run; 
%macro drive(dir,ext);                             
%local filrf rc did memcnt name i;                          

    /* Assigns a fileref to the directory and opens the directory */               
    %let rc=%sysfunc(filename(filrf,&dir));                        
    %let did=%sysfunc(dopen(&filrf));                          

    /* Make sure directory can be open */                         
    %if &did eq 0 %then %do;                            
    %put Directory &dir cannot be open or does not exist;                     
    %return;                                
    %end;                                 

    /* Loops through entire directory */                         
    %do i = 1 %to %sysfunc(dnum(&did));                         

    /* Retrieve name of each file */                         
    %let name=%qsysfunc(dread(&did,&i));                        

/* Checks to see if the extension matches the parameter value */                 
/* If condition is true print the full name to the log  */                 
    %if %qupcase(%qscan(&name,-1,.)) = %upcase(&ext) %then %do;                  
    %put &dir\&name; 

    data thisfile_&i.; 
    format filename $100.; 
     set thisfile; 
    filename = "&dir.\&name."; 
    run;                             
    %end;                                
/* If directory name call macro again */                       
    %else %if %qscan(&name,2,.) = %then %do;                       
    %drive(&dir\%unquote(&name),&ext)                        
    %end;                                

    %end;                                 

/* Closes the directory and clear the fileref */                      
%let rc=%sysfunc(dclose(&did));                          
%let rc=%sysfunc(filename(filrf));                          

%mend drive;                                

/* First parameter is the directory of where your files are stored. */                 
/* Second parameter is the extension you are looking for.   */                 
%drive(v:\,xlsx) 

Der Code funktioniert wie beabsichtigt, aber ich brauche das Ergebnis der Zeile ‚% setzte & dir \ &name;‘ in einen Datensatz zu füttern, anstatt nur den Druck in das Protokoll, so dass, wenn der Code ausgeführt wird ausgeführt Ich werde einen Datensatz mit einer Beobachtung für jede .xlsx-Datei haben.

Diese einfache scheint genug, aber wenn ich es schaffen einen Datensatz und initialisieren eine ‚Dateiname‘ Variable & dir \ & Namen zu haben versucht, erhalte ich einen Datensatz mit null Beobachtungen. Meine log Ergebnisse zeigen, das Makro-Argument richtig funktioniert, aber es schreibt nicht eine Beobachtung:

MPRINT(DRIVE): data thisfile_1; 
MPRINT(DRIVE): format filename $100.; 
MPRINT(DRIVE): set thisfile; 
MPRINT(DRIVE): filename = "v:\\MYFILENAME.xlsx"; 
MPRINT(DRIVE): run; 

NOTE: There were 0 observations read from the data set WORK.THISFILE. 
NOTE: The data set WORK.THISFILE_1 has 0 observations and 1 variables. 
NOTE: DATA statement used (Total process time): 
     real time   0.03 seconds 
     cpu time   0.01 seconds 

Ich weiß, dass der Code geschrieben wird nicht ‚Stack‘ alle meine Ergebnisse in einem Satz, aber ich habe nur versucht, um es in Gang zu bringen.

+0

Eine Sache, die Sie beim Importieren von Excel-Dateien bekommen, ist, dass SAS die Variablentypen schätzt. Wenn Ihre Daten überhaupt mehrdeutig sind, kann ein Import für eine Datei eine Variable als Zeichen lesen und ein Import für eine andere Datei liest die Variable als numerisch. Dies wird Ihnen Probleme verursachen :( – Reeza

+0

Warum verwenden Sie Makro-Code, um die Dateinamen zu lesen. Rufen Sie einfach die Funktionen in einem Datenschritt. Dann müssen Sie nur die gewünschten Beobachtungen ausgeben. – Tom

Antwort

1

Warum haben Sie überhaupt ein `SET '? Entfernen Sie das und versuchen Sie zu sehen, ob Ihre Daten so erstellt werden, wie Sie es möchten. Sie können am Ende einen Prozeduranhang hinzufügen, um alle Datensätze anzufügen, oder verwenden Sie den Verknüpfungsdatenverweis thisfile: um sie anzufügen.

data thisfile_&i.; 
format filename $100.; 
filename = "&dir.\&name."; 
run; 

Außerhalb Makro:

data all_files; 
set thisfile:; 
run; 
+0

Entfernen der SET-Anweisung erlaubt die Daten zu Ich würde gerne herausfinden, wie man den Code in der anderen Antwort benutzt, um rekursiv zu recherchieren (da es insgesamt weniger Code gibt), aber diese Antwort hat sich als äußerst nützlich erwiesen. Danke! – Crazysasman

0

Wenn Sie die Ergebnisse in einem Datum Schritt haben wollen, dann rufen Sie einfach die Funktionen in den Daten Schritt.

%macro drive(dir,ext,dsn); 
data &dsn ; 
    length dname $256 fname $256 ; 
    keep dname fname ; 
    dname=symget('dir'); 
    length filrf $8 ; 
    rc=filename(filrf,dname); 
    did=dopen(filrf); 
    if did then do i=1 to dnum(did); 
    fname=dread(did,i); 
    if index(fname,'.') and upcase(scan(fname,-1,'.'))=%upcase("&ext") then output; 
    end; 
    else put 'ERROR: Directory ' dname=:$quote. 'cannot be opened.'; 
    rc=filename(filrf); 
run; 
%mend drive; 

%drive(dir=~/test,ext=xlsx,dsn=out) 
+0

Ich habe diesen Code von der SAS-Website ausgeliehen, und wie es jetzt wahrscheinlich klar ist, habe ich nur ein oberflächliches Verständnis davon, wie es funktioniert.Ich habe das obige ausgeführt, aber keine Ergebnisse erhalten und bin mir (natürlich) nicht sicher, warum? Der Code überprüft nur das angegebene Verzeichnis, aber keine Unterordner? Vielen Dank für Ihre Hilfe. – Crazysasman

Verwandte Themen