Expertentipp:

Wussten Sie schon, wie Sie mit einem SAS Programm auf ein ZIP-File zugreifen können?

Und so geht’s:
Seit SAS9.4 gibt es die Möglichkeit, auf ein ZIP-File einen Filename zu definieren, um damit direkt aus einem SAS Programm heraus auf das ZIP-File zugreifen zu können.

Zuerst müssen wir ermitteln, was überhaupt in dem ZIP-File enthalten ist.

Nehmen wir an, wir haben das folgende Beispiel-ZIP-File data.zip, das insgesamt 2 Dateien und einen Unterordner enthält:


data.zip
  |__ sas_tech_talks_15.xlsx
  |__ sas/
      |__ instanttitles.sas7bdat

Mit folgendem SAS Programm ermitteln wir, welche Elemente in dem ZIP-File enthalten sind und speichern die Namen der enthaltenen Elemente sowie ein Kennzeichen, ob es sich um ein Verzeichnis handelt oder nicht, in die SAS Datei contents. Dafür definieren wir einen Filename auf die ZIP-Datei:


filename inzip ZIP "c:\projects\data.zip";
 
/* Read the "members" (files) from the ZIP file */
data contents(keep=memname isFolder);
 length memname $200 isFolder 8;
 fid=dopen("inzip");
 if fid=0 then
  stop;
 memcount=dnum(fid);
 do i=1 to memcount;
  memname=dread(fid,i);
  /* check for trailing / in folder name */
  isFolder = (first(reverse(trim(memname)))='/');
  output;
 end;
 rc=dclose(fid);
run;
 
/* create a report of the ZIP contents */
title "Files in the ZIP file";
proc print data=contents noobs N;
run;

Mit PROC PRINT wird das Ergebnis folgendermaßen aufgelistet:


Files in the ZIP file                                         
 memname                       isFolder
 sas/                             1  
 sas/instanttitles.sas7bdat       0  
 sas_tech_talks_15.xlsx           0  
                N = 3

Mit dieser Information können wir die XLSX-Datei aus dem ZIP-File kopieren und in eine SAS Datei importieren. Beachten Sie, wie in der INFILE-Anweisung der Name der innerhalb der mit dem Filename adressierten ZIP-Datei zu adressierenden XLSX-Datei in Klammern angegeben wird.


/* identify a temp folder in the WORK directory */
filename xl "%sysfunc(getoption(work))/sas_tech_talks_15.xlsx" ;
 
/* hat tip: "data _null_" on SAS-L */
data _null_;
   /* using member syntax here */
   infile inzip(sas_tech_talks_15.xlsx) 
       lrecl=256 recfm=F length=length eof=eof unbuf;
   file   xl lrecl=256 recfm=N;
   input;
   put _infile_ $varying256. length;
   return;
 eof:
   stop;
run;
 
proc import datafile=xl dbms=xlsx out=confirmed replace;
  sheet=confirmed;
run;

Beispielausgabe im SAS Log:


NOTE: The infile INZIP(sas_tech_talks_15.xlsx) is:
      Filename=c:\projects\data.zip,
      Member Name=sas_tech_talks_15.xlsx

NOTE: UNBUFFERED is the default with RECFM=N.
NOTE: The file XL is:
      Filename=C:\SAS Temporary Files\_TD396_\Prc2\sas_tech_talks_15.xlsx,
      RECFM=N,LRECL=256,File Size (bytes)=0,
      Last Modified=11May2015:11:38:59,
      Create Time=11May2015:11:20:23

NOTE: A total of 55 records were read from the infile library INZIP.
NOTE: 55 records were read from the infile INZIP(sas_tech_talks_15.xlsx).
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

Um auf die SAS Datei in dem ZIP-File zuzugreifen, kopieren wir sie in ein Verzeichnis, das als Bibliothek zugewiesen ist. Hier wird wieder die Bibliothek WORK verwendet. Weil die SAS Datei im ZIP-File im Unterordner sas liegt, wird dieser Unterordner in der INFILE-Anweisung mit angegeben.


/* Copy a zipped data set into the WORK library */
filename ds "%sysfunc(getoption(work))/instanttitles. sas7bdat" ;
 
data _null_;
   /* reference the member name WITH folder path */
   infile inzip(sas/instanttitles.sas7bdat) 
	  lrecl=256 recfm=F length=length eof=eof unbuf;
   file   ds lrecl=256 recfm=N;
   input;
   put _infile_ $varying256. length;
   return;
 eof:
   stop;
run;
 
proc contents data=work.instanttitles;
run;

Auszug aus der PROC CONTENTS-Ausgabe:


                             Files in the ZIP file                          
                             The CONTENTS Procedure

 Data Set Name     WORK.INSTANTTITLES         Observations          1475
 Member Type       DATA                       Variables             6   
 Engine            V9                         Indexes               0   
 Created           01/29/2015 15:09:54        Observation Length    248 
 Last Modified     01/29/2015 15:09:54        Deleted Observations  0   
 Protection                                   Compressed            NO  
 Data Set Type                                Sorted                NO  
 Label                                                                        
 Data Representation WINDOWS_64                                              
 Encoding             wlatin1 Western (Windows)                              

 

Dieser Prozess kann natürlich automatisiert werden, um z. B. alle Dateien innerhalb eines ZIP-Files zu lesen.

Diesen und weitere Tipps zum Thema erhalten Sie im Kurs SAS® Programmierung 3: effiziente Techniken des Datenmanagements .