Haben Sie schon einmal versucht beliebige Dateien mit Hilfe von SAS-Code zu kopieren? Oftmals werden hierzu Methoden verwendet die Systembefehle wie %sysexec, system oder X verwenden.
Was aber tun wenn diese Befehle aus Sicherheitsgründen gesperrt sind? Dann kommt in der Regel bei der Fehlermeldung
an.
Das kopieren einzelner Dateien ist relativ leicht mit Hilfe von Fcopy möglich. Was aber wenn man auch eine Liste von Dateien kopieren möchte und dazu auch den * als Wildcard verwenden möchte.
Hierzu habe ich folgendes Makro geschrieben, dass für Windowssysteme gedacht ist.
Makro Filecopy
%MACRO filecopy(indir, outdir, filedesc);
/* * Wildcard wird in PROC SQL Wildcard % umgewandelt */
DATA TEST2;
filedesc = "&filedesc";
IF FIND(filedesc,"*") THEN
DO;
filedesc = TRANWRD(filedesc,"*","%");
CALL SYMPUTX ("filedesc",CATS("'",filedesc,"'"));
END;
RUN;
data DIRCONTENTS;
keep Verzeichnis Dateiname Endung InNameUndPfad OutNameUndPfad;
length Verzeichnis $40 fref $8 Dateiname $80 Endung $30
PfadundName OutNameUndPfad $200
;
rc = filename(fref, "&indir");
if rc = 0 then
do;
did = dopen(fref);
rc = filename(fref);
end;
else
do;
length msg $200.;
msg = sysmsg();
put msg=;
did = .;
end;
if did <= 0 then
putlog 'ERR' 'OR: Unable to open directory.';
dnum = dnum(did);
do i = 1 to dnum;
Verzeichnis = "&indir";
Dateiname = dread(did, i);
Endung = LOWCASE(SUBSTR(Dateiname,Find(Dateiname,".")+1));
/* Ausgabe falls Eintrag eine Datei ist. Falls eintrag ein Unterverzeichnis, nicht ausgeben.*/
fid = mopen(did, Dateiname);
/* In- und Outputdateien */
InNameUndPfad = "&indir"||STRIP(Dateiname);
OutNameUndPfad = "&outdir"||STRIP(Dateiname);
if fid > 0 then
output;
end;
rc = dclose(did);
;
run;
/* Filterung ggf. mit SQL Wildcards */
PROC SQL NOWARN;
CREATE TABLE COPYLIST
AS SELECT
*
FROM DIRCONTENTS
WHERE Dateiname LIKE &filedesc;
RUN;
DATA _NULL_;
SET COPYLIST END=eof;
CALL SYMPUTX("INFI"||LEFT(_N_),InNameUndPfad);
CALL SYMPUTX("OUTFI"||LEFT(_N_),OutNameUndPfad);
IF eof THEN
CALL SYMPUTX("ANZAHL_DATEIEN",_N_);
RUN;
%PUT NOTE: Anzahl zu kopierender Dateien: &ANZAHL_DATEIEN..;
%DO i=1 %TO &ANZAHL_DATEIEN;
%PUT NOTE: &i.. Datei &&INFI&i wird kopiert.;
filename _bcin "&&infi&i" recfm=n
/* RECFM=N needed for a binary copy */;
filename _bcout "&&outfi&i" recfm=n;
data _null_;
length msg $ 384;
rc=fcopy('_bcin', '_bcout');
if rc=0 then
put "Copied &&infi&i to &&outfi&i..";
else
do;
msg=sysmsg();
put rc= msg=;
end;
run;
%END;
%MEND;
Beispielaufrufe
%filecopy(C:\dir\, C:\dir\Subdir1\,CC_inp_23_2023_02.csv);
%filecopy(C:\dir\, C:\dir\Subdir1\,CC_inp_*_2023_*.csv);
%filecopy(C:\dir\, C:\dir\Subdir1\,*.xls*);
%filecopy(C:\dir\, C:\dir\Subdir1\,*.pdf);