Peter Kellberg Det vidste du ikke om et EG projekt! SAS Forum 2010
Spørgsmål? Kan tanker om sex få én til at nyse? Ja! Journal of the Royal Society of Medicine
Det vigtigste først Er sex overhovedet relevant for en SAS-udvikler? 1) Ja 2) Nej 3) Sex, hvad er det?
Hvad betyder det ord egentlig? Simplicity EXclusion www.kenrockwell.com
Hvad betyder det ord egentlig?
Hvad betyder det ord egentlig?
Hvad betyder det ord egentlig? Det er variabel nr. 2 i SASHELP.CLASS
Rotating plot
Nyt navn på Server Context EG 4.1 (SAS 9.1.3) EG 4.2 (SAS 9.2) SASMain SASApp
Fodaftryk fra SASMain i EG 4.1
At åbne et EG 4.1 projekt i EG 4.2
At åbne et EG 4.1 projekt i EG 4.2
At få rettet SASMain til SASApp
At få rettet SASMain til SASApp
At få rettet SASMain til SASApp
Alternativ måde Migration Wizard C:\Programmer\SAS\EnterpriseGuide\4.2\MigrationWizard.exe
Migration Wizard
Migration Wizard
Migration Wizard
Migration Wizard
Migration Wizard
Migration Wizard
Migration Wizard
Efter Migration Wizard SASMain erstattet med SASApp Er nu i EG 4.2 format
At lede efter SASMain...
Åbenbaringen
Et EG projekt er en ZIP-fil!!
XML-filen
Fra AHA til idé En EGP-fil er en ZIP-fil som indeholder en XML-fil med alle oplysninger Vi kan udpakke XML-filen og rette i den, det jo er bare en tekstfil Vi kan lægge den tilbage igen og så kan man køre i SAS 9.2
Problemstillinger At kunne få en oversigt over EGP-filer SAS Udføre en systemkommando (DIR) Vi skal kunne hive ud/lægge ind fra en ZIP-fil SAS Et eksternt program WZUNZIP.EXE WZZIP.EXE Rette i en fil Direkte (SHAREBUFFERS) Danne en ny udgave
Få en oversigt over EG-filer (SAS) DOPEN åbn en mappe DNUM antal elementer (filer, undermapper) DREAD navn på element DCLOSE når vi er færdige med mappen
Få en oversigt over EG-filer (SAS) %let rc=%sysfunc(filename(mappe,h:\)); /* opret et fileref */ %let did=%sysfunc(dopen(&mappe)); /* åbn mappe */ %let antmembers=%sysfunc(dnum(&did)); /* find antal elementer */ %do i=1 %to &antmembers; /* gå mappen igennem */ %let memname=%sysfunc(dread(&did,&i)); /* find navnet */ %put memname=&memname; %end; %let rc=%sysfunc(dclose(&did)); /* luk adgang til mappe */ Det bliver for bøvlet især rekursivitet (undermapper)
Få en oversigt over EG-filer (DIR) c:\> dir /s h:\eg\*.egp
Få en oversigt over EG-filer (DIR) H:\>dir /s "h:\test det nu\*.egp" Disken i drev H er FS1FCNAS1 Diskens serienummer er 91C8-4F01 Indhold af h:\test det nu 26-01-2010 11:41 173.104 æøåæøå.egp 1 fil(er) 173.104 byte Indhold af h:\test det nu\bettina tradsborg 01-02-2010 16:56 258.294 Produkter.egp 1 fil(er) 258.294 byte Antal filer i alt: 2 fil(er) 431.398 byte 0 mappe(r) 462.208.733.184 byte ledig
Få en oversigt over EG-filer (DIR) Hvordan fanger man så outputtet? c:\> dir h:\eg\*.egp > c:\temp\dirlist.txt Man kan så indlæse tekstfilen i SAS
Få en oversigt over EG-filer (DIR) DATA Step Funktioner CALL SYSTEM SYSTEM Makro sætning %SYSEXEC SAS sætning X-statement SAS kommando X-kommando
Vigtige options XCMD XMIN XSYNC NOXWAIT The X Command is valid in this SAS session X-commands launch in a minimized nonactive state. X-commands execute synchronously. X-commands do not wait for 'exit' before returning to SAS.
Unnamed pipe Det er nemmere, end det lyder Det blinker ikke så meget Outputtet kan indlæses direkte i et DATA Step Er uafhængig af disse options: (NO)XWAIT, (NO)XSYNC, (NO)XMIN
Unnamed pipe filename dirlist pipe "dir /s h:\*.egp"; H:\>dir /s "h:\test det nu\*.egp" Disken i drev H er FS1FCNAS1 Diskens serienummer er 91C8-4F01 Indhold af h:\test det nu 26-01-2010 11:41 173.104 æøåæøå.egp 1 fil(er) 173.104 byte Indhold af h:\test det nu\bettina tradsborg 01-02-2010 16:56 258.294 Produkter.egp 1 fil(er) 258.294 byte Antal filer i alt: 2 fil(er) 431.398 byte 0 mappe(r) 462.208.733.184 byte ledig
Unnamed pipe filename dirlist pipe "dir ""h:\enterprise Guide\*.egp"" "; data EG_oversigt; retain path ; infile dirlist length=reclen ; input line $varying256. reclen ; if reclen = 0 then delete ; if scan(line, 1,' ') = 'Indhold' then path=substr(line,13); if substr(line,2,6) = 'Disken' or scan( line,1,' ') = 'Antal' or scan( line,2,' ') = 'fil(er)' or scan( line,2,' ') = 'mappe(r)' or scan( line,3,' ') = '<DIR>' or scan(line, 1,' ') = 'Indhold' then delete ; filnavn=substr(line,37); drop line; run; Æ, Ø og Å? encoding=pcoem865
Unnamed pipe filename dirlist pipe "dir bla bla"; data _null_; infile dirlist length=reclen ; file &fileref; input line $varying256. reclen ; put line $varying256. reclen; run; Æ, Ø og Å? encoding=pcoem865 data _null_; infile &fileref encoding=pcoem865 length=reclen ; input line $varying256. reclen ;...... run;
Unnamed pipe filename pipecmd pipe del /q h:\test\*.egp ; data _null_; infile pipecmd; input; run; En kommando uden output
Unnamed pipe
Forberedelse til systematik counter+1; call symputx(cats('path',counter),path); call symputx(cats('filename',counter),filnavn); call symputx('counter',counter); PATH1 H:\TEST FILENAME1 LEDIGE.EGP PATH2 H:\TEST FILENAME2 FINANS.EGP...... %do i=1 %to &counter; %egkonvert_doit(eg_folder=&&path&i, eg_file=&&filename&i); %end;
Forberedelse til systematik &&filename&i && filename &i &filename3 Beskæftigede.egp
Udpakning af XML-filen SASZIPAM access method filename zipfil saszipam 'C:\temp\test.zip'; Bruge et WINZIP program WZUNZIP WZZIP (kommandolinje baserede)
Udpakning af XML-filen %let UNZIP_FOLDER=%sysfunc(pathname(WORK)); %let UNZIPEXE=\\nas2\apps\sas server\winzip\wzunzip.exe; /* Dan UNZIP CMD-fil */ data _null_; file "&UNZIP_FOLDER\unzip.cmd"; put """&UNZIPEXE"" -o ""&EG_FOLDER\&EG_FILE"" ""&UNZIP_FOLDER"" PROJECT.XML" ; run; /* Udfør UNZIP CMD-fil */ filename _zip PIPE "&UNZIP_FOLDER\unzip.cmd"; data _null_; infile _zip; input; run;
Har dette EG projekt brug for at blive rettet? /* Find ud af, om der skal rettes (ordet SASMain findes) */ %let NeedsConversion=N; data _null_; infile "&UNZIP_FOLDER\PROJECT.XML" lrecl=3000 ENCODING="UTF-16"; input; /* led efter sasmain og ignore case */ if FIND(_infile_,'sasmain','i') ne 0 then do; call symputx('needsconversion','y'); stop; end; run;
OK det skal rettes! Hm!
OK det skal rettes! /* Opret et SAS/datasæt med indholdet */ data xml_utf16; length linje $3000; infile "&UNZIP_FOLDER\PROJECT.XML ENCODING="UTF-16 lrecl=3000 missover pad; input linje $char3000.; %erstatord(var=linje,soeg=sasmain,erstat=sasapp); run; $CHAR Undgå venstrestilling af tekst
OK det skal rettes! %macro erstatord(var=,soeg=,erstat=); %* Filosofien er først at erstatte søgeordet med et soltegn efterfulgt af blanktegn, så længden passer med søgeordet fx En lille historie om Lille Claus bliver til En historie om Claus ; Herefter lader vi TRANWRD om at erstatte. Så slipper vi for bøvlet med skubning af tekst (hvis erstat ordet er længere end soeg ordet og omvendt) findindex_=1; findpos_=find(&var, "&soeg",'i',1); do while (findpos_ ne 0); substr(&var,findpos_,length("&soeg"))=" "; findindex_+1; findpos_=find(&var, "&soeg",'i',findindex_); end; _soegcopy_="&soeg"; * _soegcopy_ får samme længde som &soeg; _soegcopy_=" "; * _soegcopy_ bliver et soltegn efterfulgt af blanke; &var=tranwrd(&var,_soegcopy_,"&erstat"); drop findpos_ findindex soegcopy_; %mend;
OK det skal rettes! /* Overskriv XML filen med det rettede indhold */ data _null_; set utf16fil end=slut; length char $1; file "&UNZIP_FOLDER\PROJECT.XML ENCODING="UTF-16" recfm=n; do i=1 to lengthn(linje); char=substr(linje,i,1); put char $1.; end; run; if not slut then do; put '0D'x; put '0A'x; end; RECFM=N Binær læsning/skrivning
Sharebuffers /* Ret XML filen in-place */ data _null_; infile "&UNZIP_FOLDER\PROJECT.XML" ENCODING="UTF-16" lrecl=3000 sharebuffers; file "&UNZIP_FOLDER\PROJECT.XML"; run; input; %erstatord(var=_infile_,soeg=sasmain,erstat=sasapp);
Så skal XML-filen ind i EGP-filen /* Dan ZIP CMD-fil */ data _null_; file "&UNZIP_FOLDER\zip.cmd"; put """&ZIPEXE"" -a ""&EG_FOLDER\&EG_FILE" ""&UNZIP_FOLDER\PROJECT.XML"" " ; run; /* Udfør ZIP CMD-fil */ filename _zip PIPE "&UNZIP_FOLDER\zip.cmd"; data _null_; infile _zip; input; run;
Så skal XML-filen ind i EGP-filen /* Dan ZIP CMD-fil */ data _null_; file "&UNZIP_FOLDER\zip.cmd"; put """&ZIPEXE"" -a ""&EG_FOLDER\&EG_FILE" ""&UNZIP_FOLDER\PROJECT.XML"" " ; run; /* Udfør ZIP CMD-fil */ data _null_; call system("&unzip_folder\zip.cmd"); run;
Skal alle så have WZZIP/WZUNZIP? %let UNZIPEXE=\\nas2\apps\sas server\winzip\wzunzip.exe; %let ZIPEXE=\\nas2\apps\sas server\winzip\wzzip.exe;
Hvad sker der nu?
Hvad er vores makro god til? God til at foretage standardiserede rettelser Kan ordne en mappe + evt. undermapper
Perspektiv? Du kan rette hvad som helst i en EGP-fil Det skal gøres med sikker hånd!
Spørgsmål? pke@dst.dk