Macro XAMINE (from Fraktal SAS Programming): Unterschied zwischen den Versionen

Aus phenixxenia.org
Zur Navigation springen Zur Suche springen
K
K
 
(4 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
 
[[Kategorie:Zazy]]
 
[[Kategorie:Zazy]]
 
{{SeitenNavigation1
 
{{SeitenNavigation1
|hoch=Duck_zazy_com.png
+
|hoch=call a macro bubble 0.png
 
|links=xx_left.png
 
|links=xx_left.png
 
|rechts=xx_right.png
 
|rechts=xx_right.png
Zeile 8: Zeile 8:
 
|vorwärts=Macro XSET (from Fraktal SAS Programming)
 
|vorwärts=Macro XSET (from Fraktal SAS Programming)
 
}}
 
}}
 +
 +
== What it does ==
 +
 +
This multilevel structured macro combines the simpler ones from above to perform adapted processing of entries from a specified path 'XPATH'. Behavior depends on filter arguments supplied by a segmented parameter 'ETYPE'.
 +
* Segments are limited hardcoded with an underscore ('_').
 +
** 1st segment arguments are processed as SAS program code and copied into the SAS DMS Program Editor.
 +
** 2nd segment arguments are processed as Text and passed to the Wordpad text processor from the MS-Windows accessories collection.
 +
 +
== Annotated Code ==
  
 
{| class="wikitable"
 
{| class="wikitable"
Zeile 23: Zeile 32:
 
:%GLOBAL ne ie dir;
 
:%GLOBAL ne ie dir;
 
</font>  
 
</font>  
|
+
|Declare global macro variables for communication with called macros
 
|-
 
|-
 
|
 
|
Zeile 29: Zeile 38:
 
:%LOCAL xpath xentry entry etype;
 
:%LOCAL xpath xentry entry etype;
 
</font>  
 
</font>  
|
+
|Declare local macro variables
 
|-
 
|-
 
|
 
|
Zeile 35: Zeile 44:
 
;filename entries pipe "dir /b &XPATH." lrecl = 256;
 
;filename entries pipe "dir /b &XPATH." lrecl = 256;
 
</font>  
 
</font>  
|
+
|Open access path to listing of OS directory content
 
|-
 
|-
 
|
 
|
Zeile 41: Zeile 50:
 
;filename dirs pipe "dir /b /ad &XPATH." lrecl = 256;  
 
;filename dirs pipe "dir /b /ad &XPATH." lrecl = 256;  
 
</font>  
 
</font>  
|
+
|Open access path to listing of OS directory content of type 'dir'
 
|-
 
|-
 
|
 
|
Zeile 47: Zeile 56:
 
;data entries;
 
;data entries;
 
</font>  
 
</font>  
|
+
|Initiate data step to access OS directory content
 
|-
 
|-
 
|
 
|
Zeile 53: Zeile 62:
 
:length entry $256;
 
:length entry $256;
 
</font>  
 
</font>  
|
+
|Declare length of data field 'entry'
 
|-
 
|-
 
|
 
|
Zeile 59: Zeile 68:
 
:infile entries length = lrecl end = EOF;
 
:infile entries length = lrecl end = EOF;
 
</font>  
 
</font>  
|
+
|Set pointer to access path 'entries'
 
|-
 
|-
 
|
 
|
Zeile 65: Zeile 74:
 
:input entry $varying256. lrecl;
 
:input entry $varying256. lrecl;
 
</font>  
 
</font>  
|
+
|Read from 'entries' with variable field length
 
|-
 
|-
 
|
 
|
Zeile 71: Zeile 80:
 
:if EOF then call symput('ne',trim(left(put(_N_,8.))));
 
:if EOF then call symput('ne',trim(left(put(_N_,8.))));
 
</font>  
 
</font>  
|
+
|Write count of entries to macro variable 'ne'
 
|-
 
|-
 
|
 
|
Zeile 77: Zeile 86:
 
;run;
 
;run;
 
</font>  
 
</font>  
|
+
|Terminate data step
 
|-
 
|-
 
|
 
|
Zeile 83: Zeile 92:
 
;data dirs;
 
;data dirs;
 
</font>  
 
</font>  
|
+
|Initiate data step to access OS directories listing
 
|-
 
|-
 
|
 
|
Zeile 89: Zeile 98:
 
:length dir $256;
 
:length dir $256;
 
</font>  
 
</font>  
|
+
|Declare length of data field 'dir'
 
|-
 
|-
 
|
 
|
Zeile 95: Zeile 104:
 
:infile dirs length = lrecl end = EOF;
 
:infile dirs length = lrecl end = EOF;
 
</font>  
 
</font>  
|
+
|Set pointer to access path 'dirs'
 
|-
 
|-
 
|
 
|
Zeile 101: Zeile 110:
 
:input dir $varying256. lrecl;
 
:input dir $varying256. lrecl;
 
</font>  
 
</font>  
|
+
|Read from 'dirs' with variable field length
 
|-
 
|-
 
|
 
|
Zeile 107: Zeile 116:
 
;run;
 
;run;
 
</font>  
 
</font>  
|
+
|Terminate data step
 
|-
 
|-
 
|
 
|
Zeile 113: Zeile 122:
 
;%DO ie = 1 %TO &NE.;
 
;%DO ie = 1 %TO &NE.;
 
</font>  
 
</font>  
|
+
|Start macro loop to process entries one by one with loop index 'ie'
 
|-
 
|-
 
|
 
|
Zeile 119: Zeile 128:
 
;data _NULL_;
 
;data _NULL_;
 
</font>  
 
</font>  
|
+
|Initiate data step without creating a dataset
 
|-
 
|-
 
|
 
|
Zeile 125: Zeile 134:
 
:set entries(firstobs = &IE. obs = &IE.);
 
:set entries(firstobs = &IE. obs = &IE.);
 
</font>  
 
</font>  
|
+
|Read row number 'ie' from dataset 'entries'
 
|-
 
|-
 
|
 
|
Zeile 131: Zeile 140:
 
:call symput('entry',compress(translate(entry,'_','(-)')));
 
:call symput('entry',compress(translate(entry,'_','(-)')));
 
</font>  
 
</font>  
|
+
|Write value from read row to macro variable 'entry' with intermediate name processing
 
|-
 
|-
 
|
 
|
Zeile 137: Zeile 146:
 
:call symput('xentry',trim(left(entry)));
 
:call symput('xentry',trim(left(entry)));
 
</font>  
 
</font>  
|
+
|Write value from read row to macro variable 'xentry'
 
|-
 
|-
 
|
 
|
Zeile 143: Zeile 152:
 
;run;
 
;run;
 
</font>  
 
</font>  
|
+
|Terminate data step
 
|-
 
|-
 
|
 
|
Zeile 149: Zeile 158:
 
:%PUT |;
 
:%PUT |;
 
</font>  
 
</font>  
|
+
|Write string '|' to the LOG
 
|-
 
|-
 
|
 
|
Zeile 155: Zeile 164:
 
:%PUT &XPATH.&XENTRY.;
 
:%PUT &XPATH.&XENTRY.;
 
</font>  
 
</font>  
|
+
|Write full path and filename to the LOG
 
|-
 
|-
 
|
 
|
Zeile 161: Zeile 170:
 
:%LET dir =;
 
:%LET dir =;
 
</font>  
 
</font>  
|
+
|Reset value for macro variable 'dir'
 
|-
 
|-
 
|
 
|
Zeile 167: Zeile 176:
 
;data _NULL_;
 
;data _NULL_;
 
</font>  
 
</font>  
|
+
|Initiate data step without creating a dataset
 
|-
 
|-
 
|
 
|
Zeile 173: Zeile 182:
 
: set dirs(where = (dir = "&XENTRY.")) end = EOF;
 
: set dirs(where = (dir = "&XENTRY.")) end = EOF;
 
</font>  
 
</font>  
|
+
|Read row from dataset 'dirs' with value equal to content of macro variable 'xentry'
 
|-
 
|-
 
|
 
|
Zeile 179: Zeile 188:
 
:if EOF then call symput('dir',trim(left(put(_N_,8.))));
 
:if EOF then call symput('dir',trim(left(put(_N_,8.))));
 
</font>  
 
</font>  
|
+
|Write count of read rows to macro variable 'dir'
 
|-
 
|-
 
|
 
|
Zeile 185: Zeile 194:
 
;run;
 
;run;
 
</font>  
 
</font>  
|
+
|Terminate data step
 
|-
 
|-
 
|
 
|
Zeile 191: Zeile 200:
 
;%IF &DIR. = 1 %THEN %DO;
 
;%IF &DIR. = 1 %THEN %DO;
 
</font>  
 
</font>  
|
+
|Start macro branch to directory processing
 
|-
 
|-
 
|
 
|
Zeile 197: Zeile 206:
 
:%PUT +----;
 
:%PUT +----;
 
</font>  
 
</font>  
|
+
|Write string '+----' to the LOG
 
|-
 
|-
 
|
 
|
Zeile 203: Zeile 212:
 
:%XDIR(&XPATH.&XENTRY.);
 
:%XDIR(&XPATH.&XENTRY.);
 
</font>  
 
</font>  
|
+
|Use macro 'xdir' to write list of directory content to the LOG
 
|-
 
|-
 
|
 
|
Zeile 209: Zeile 218:
 
:%PUT +----;
 
:%PUT +----;
 
</font>  
 
</font>  
|
+
|Write string '+----' to the LOG
 
|-
 
|-
 
|
 
|
Zeile 215: Zeile 224:
 
;%END;
 
;%END;
 
</font>  
 
</font>  
|
+
|End macro branch for directory processing
 
|-
 
|-
 
|
 
|
Zeile 221: Zeile 230:
 
;%ELSE %DO;
 
;%ELSE %DO;
 
</font>  
 
</font>  
|
+
|Start macro branch for non-directory processing
 
|-
 
|-
 
|
 
|
Zeile 227: Zeile 236:
 
;%IF %LENGTH(&ETYPE.) ne 0 %THEN %DO;
 
;%IF %LENGTH(&ETYPE.) ne 0 %THEN %DO;
 
</font>  
 
</font>  
|
+
|Start macro branch for supplied positional parameter 'etype'
 
|-
 
|-
 
|
 
|
Zeile 233: Zeile 242:
 
;%IF %INDEX(%SCAN(&ETYPE.,2,_),%SCAN(&XENTRY,2,.)) != 0 %THEN %DO;
 
;%IF %INDEX(%SCAN(&ETYPE.,2,_),%SCAN(&XENTRY,2,.)) != 0 %THEN %DO;
 
</font>  
 
</font>  
|
+
|Start macro branch for extension of macro variable 'xentry' is found in 2nd delimited segment of macro variable 'etype'
 
|-
 
|-
 
|
 
|
Zeile 239: Zeile 248:
 
:%GLOBAL windir;
 
:%GLOBAL windir;
 
</font>  
 
</font>  
|
+
|Declare macro variable 'windir' to be global
 
|-
 
|-
 
|
 
|
Zeile 245: Zeile 254:
 
:%XSET(windir);
 
:%XSET(windir);
 
</font>  
 
</font>  
|
+
|Call macro 'xset' to populate macro variable 'windir' from OS environment variable 'windir'
 
|-
 
|-
 
|
 
|
Zeile 251: Zeile 260:
 
:%PUT +----;
 
:%PUT +----;
 
</font>  
 
</font>  
|
+
|Write string '+----' to the LOG
 
|-
 
|-
 
|
 
|
Zeile 257: Zeile 266:
 
:%PUT | File &XENTRY. opened in external editor WordPad.;
 
:%PUT | File &XENTRY. opened in external editor WordPad.;
 
</font>  
 
</font>  
|
+
|Write string '|' followed by a message to the LOG
 
|-
 
|-
 
|
 
|
Zeile 263: Zeile 272:
 
:SYSTASK command "&WINDIR.\write.exe ""&XPATH.\&XENTRY.""";
 
:SYSTASK command "&WINDIR.\write.exe ""&XPATH.\&XENTRY.""";
 
</font>  
 
</font>  
|
+
|Call external program 'write.exe' to open currently processed file
 
|-
 
|-
 
|
 
|
Zeile 269: Zeile 278:
 
:%PUT +----;
 
:%PUT +----;
 
</font>  
 
</font>  
|
+
|Write string '+----' to the LOG
 
|-
 
|-
 
|
 
|
Zeile 275: Zeile 284:
 
;%END;
 
;%END;
 
</font>  
 
</font>  
|
+
|End macro branch for extension of macro variable 'xentry' is found in 2nd delimited segment of macro variable 'etype'
 
|-
 
|-
 
|
 
|
Zeile 281: Zeile 290:
 
;%IF %INDEX(%SCAN(&ETYPE.,1,_),%SCAN(&XENTRY,2,.)) != 0 %THEN %DO;
 
;%IF %INDEX(%SCAN(&ETYPE.,1,_),%SCAN(&XENTRY,2,.)) != 0 %THEN %DO;
 
</font>  
 
</font>  
|
+
|Start macro branch for extension of macro variable 'xentry' is found in 1st delimited segment of macro variable 'etype'
 
|-
 
|-
 
|
 
|
Zeile 287: Zeile 296:
 
:%PUT +----;
 
:%PUT +----;
 
</font>  
 
</font>  
|
+
|Write string '+----' to the LOG
 
|-
 
|-
 
|
 
|
Zeile 293: Zeile 302:
 
:%PUT | File &XENTRY. opened in SAS program editor window.;
 
:%PUT | File &XENTRY. opened in SAS program editor window.;
 
</font>  
 
</font>  
|
+
|Write string '|' followed by a message to the LOG
 
|-
 
|-
 
|
 
|
Zeile 299: Zeile 308:
 
:%XEDIT(&XENTRY.,&XPATH.);
 
:%XEDIT(&XENTRY.,&XPATH.);
 
</font>  
 
</font>  
|
+
|Call macro 'xedit' to open currently processed file in SAS DMS Program Editor
 
|-
 
|-
 
|
 
|
Zeile 305: Zeile 314:
 
:%PUT +----;
 
:%PUT +----;
 
</font>  
 
</font>  
|
+
|Write string '+----' to the LOG
 
|-
 
|-
 
|
 
|
Zeile 311: Zeile 320:
 
;%END;
 
;%END;
 
</font>  
 
</font>  
|
+
|End macro branch for extension of macro variable 'xentry' is found in 1st delimited segment of macro variable 'etype'
 
|-
 
|-
 
|
 
|
Zeile 317: Zeile 326:
 
;%END;
 
;%END;
 
</font>  
 
</font>  
|
+
|End macro branch for supplied positional parameter 'etype'
 
|-
 
|-
 
|
 
|
Zeile 323: Zeile 332:
 
;%END;
 
;%END;
 
</font>  
 
</font>  
|
+
|End macro branch for non-directory processing
 
|-
 
|-
 
|
 
|
Zeile 329: Zeile 338:
 
;%END;
 
;%END;
 
</font>  
 
</font>  
|
+
|End macro loop to process entries one by one with loop index 'ie'
 
|-
 
|-
 
|
 
|
Zeile 335: Zeile 344:
 
;proc sql;
 
;proc sql;
 
</font>  
 
</font>  
|
+
|Invoke the SAS SQL procedure
 
|-
 
|-
 
|
 
|
Zeile 341: Zeile 350:
 
:drop table dirs;
 
:drop table dirs;
 
</font>  
 
</font>  
|
+
|Delete table 'dirs'
 
|-
 
|-
 
|
 
|
Zeile 347: Zeile 356:
 
:drop table entries;
 
:drop table entries;
 
</font>  
 
</font>  
|
+
|Delete table 'entries'
 
|-
 
|-
 
|
 
|
Zeile 353: Zeile 362:
 
;quit;
 
;quit;
 
</font>  
 
</font>  
|
+
|Terminate the SAS SQL procedure
 
|-
 
|-
 
|
 
|
Zeile 359: Zeile 368:
 
;filename entries clear;
 
;filename entries clear;
 
</font>  
 
</font>  
|
+
|Close access path to listing of OS directory content
 
|-
 
|-
 
|
 
|
Zeile 365: Zeile 374:
 
;filename dirs clear;
 
;filename dirs clear;
 
</font>  
 
</font>  
|
+
|Close access path to listing of OS directory content of type 'dir'
 
|-
 
|-
 
|
 
|
Zeile 373: Zeile 382:
 
|End Macro definition with name
 
|End Macro definition with name
 
|}
 
|}
 +
 +
== Special Effects ==
 +
 +
# The macro makes use of the 'pipe' type file reference. When used appropriately, this returns a list that is instantly generated by an OS command that is given as the statement's argument.
 +
# As an alternate text processing instance the macro uses a SYSTASK statement to call the windows component 'Wordpad'. Since each paticular windows installation uses its own path structure, the macro makes use of the 'windir' environment variable.
  
 
{{SeitenNavigation1
 
{{SeitenNavigation1
|hoch=Duck_zazy_com.png
+
|hoch=call a macro bubble 0.png
 
|links=xx_left.png
 
|links=xx_left.png
 
|rechts=xx_right.png
 
|rechts=xx_right.png

Aktuelle Version vom 6. Januar 2016, 18:39 Uhr

Zurück

Übersicht

Vorwärts

What it does

This multilevel structured macro combines the simpler ones from above to perform adapted processing of entries from a specified path 'XPATH'. Behavior depends on filter arguments supplied by a segmented parameter 'ETYPE'.

  • Segments are limited hardcoded with an underscore ('_').
    • 1st segment arguments are processed as SAS program code and copied into the SAS DMS Program Editor.
    • 2nd segment arguments are processed as Text and passed to the Wordpad text processor from the MS-Windows accessories collection.

Annotated Code

Code executed Function performed

%MACRO xamine(xpath,etype);

Start Macro definition with name and positional parameters xpath and etype

%GLOBAL ne ie dir;

Declare global macro variables for communication with called macros

%LOCAL xpath xentry entry etype;

Declare local macro variables

filename entries pipe "dir /b &XPATH." lrecl = 256;

Open access path to listing of OS directory content

filename dirs pipe "dir /b /ad &XPATH." lrecl = 256;

Open access path to listing of OS directory content of type 'dir'

data entries;

Initiate data step to access OS directory content

length entry $256;

Declare length of data field 'entry'

infile entries length = lrecl end = EOF;

Set pointer to access path 'entries'

input entry $varying256. lrecl;

Read from 'entries' with variable field length

if EOF then call symput('ne',trim(left(put(_N_,8.))));

Write count of entries to macro variable 'ne'

run;

Terminate data step

data dirs;

Initiate data step to access OS directories listing

length dir $256;

Declare length of data field 'dir'

infile dirs length = lrecl end = EOF;

Set pointer to access path 'dirs'

input dir $varying256. lrecl;

Read from 'dirs' with variable field length

run;

Terminate data step

%DO ie = 1 %TO &NE.;

Start macro loop to process entries one by one with loop index 'ie'

data _NULL_;

Initiate data step without creating a dataset

set entries(firstobs = &IE. obs = &IE.);

Read row number 'ie' from dataset 'entries'

call symput('entry',compress(translate(entry,'_','(-)')));

Write value from read row to macro variable 'entry' with intermediate name processing

call symput('xentry',trim(left(entry)));

Write value from read row to macro variable 'xentry'

run;

Terminate data step

%PUT |;

' to the LOG

%PUT &XPATH.&XENTRY.;

Write full path and filename to the LOG

%LET dir =;

Reset value for macro variable 'dir'

data _NULL_;

Initiate data step without creating a dataset

set dirs(where = (dir = "&XENTRY.")) end = EOF;

Read row from dataset 'dirs' with value equal to content of macro variable 'xentry'

if EOF then call symput('dir',trim(left(put(_N_,8.))));

Write count of read rows to macro variable 'dir'

run;

Terminate data step

%IF &DIR. = 1 %THEN %DO;

Start macro branch to directory processing

%PUT +----;

Write string '+----' to the LOG

%XDIR(&XPATH.&XENTRY.);

Use macro 'xdir' to write list of directory content to the LOG

%PUT +----;

Write string '+----' to the LOG

%END;

End macro branch for directory processing

%ELSE %DO;

Start macro branch for non-directory processing

%IF %LENGTH(&ETYPE.) ne 0 %THEN %DO;

Start macro branch for supplied positional parameter 'etype'

%IF %INDEX(%SCAN(&ETYPE.,2,_),%SCAN(&XENTRY,2,.)) != 0 %THEN %DO;

Start macro branch for extension of macro variable 'xentry' is found in 2nd delimited segment of macro variable 'etype'

%GLOBAL windir;

Declare macro variable 'windir' to be global

%XSET(windir);

Call macro 'xset' to populate macro variable 'windir' from OS environment variable 'windir'

%PUT +----;

Write string '+----' to the LOG

%PUT | File &XENTRY. opened in external editor WordPad.;

' followed by a message to the LOG

SYSTASK command "&WINDIR.\write.exe ""&XPATH.\&XENTRY.""";

Call external program 'write.exe' to open currently processed file

%PUT +----;

Write string '+----' to the LOG

%END;

End macro branch for extension of macro variable 'xentry' is found in 2nd delimited segment of macro variable 'etype'

%IF %INDEX(%SCAN(&ETYPE.,1,_),%SCAN(&XENTRY,2,.)) != 0 %THEN %DO;

Start macro branch for extension of macro variable 'xentry' is found in 1st delimited segment of macro variable 'etype'

%PUT +----;

Write string '+----' to the LOG

%PUT | File &XENTRY. opened in SAS program editor window.;

' followed by a message to the LOG

%XEDIT(&XENTRY.,&XPATH.);

Call macro 'xedit' to open currently processed file in SAS DMS Program Editor

%PUT +----;

Write string '+----' to the LOG

%END;

End macro branch for extension of macro variable 'xentry' is found in 1st delimited segment of macro variable 'etype'

%END;

End macro branch for supplied positional parameter 'etype'

%END;

End macro branch for non-directory processing

%END;

End macro loop to process entries one by one with loop index 'ie'

proc sql;

Invoke the SAS SQL procedure

drop table dirs;

Delete table 'dirs'

drop table entries;

Delete table 'entries'

quit;

Terminate the SAS SQL procedure

filename entries clear;

Close access path to listing of OS directory content

filename dirs clear;

Close access path to listing of OS directory content of type 'dir'

%MEND xamine;

End Macro definition with name

Special Effects

  1. The macro makes use of the 'pipe' type file reference. When used appropriately, this returns a list that is instantly generated by an OS command that is given as the statement's argument.
  2. As an alternate text processing instance the macro uses a SYSTASK statement to call the windows component 'Wordpad'. Since each paticular windows installation uses its own path structure, the macro makes use of the 'windir' environment variable.

Zurück

Übersicht

Vorwärts