Showing posts with label macro. Show all posts
Showing posts with label macro. Show all posts

Tuesday, August 18, 2015

Listing all files that are located in a specific directory (update)

I prefer the codes independent on OS. It may save a lot of time to maintain. Based on SAS Note 25074, I have created the codes at below:
%macro readdir(indir=, outdsn=);
    data &outdsn (keep=name infoname infoval);
       rc=filename("mydir", "&indir");
       did=dopen("mydir");

        if did > 0 then do;
            memcnt = dnum(did);
            do i=1 to memcnt;
                name = dread(did, i);
                
                rc = filename("myfile", catx("/", "&indir", name));
                fid = fopen("myfile");
                if fid > 0 then do;
                    infonum=foptnum(fid);
                    do j=1 to infonum;
                        infoname=foptname(fid, j);
                        infoval=finfo(fid, infoname);
                        output;
                    end;
                end;
                else do;
                    msg = sysmsg();
                    put msg;
                end;
                rc = fclose(fid);
            end;
        end;
        else do;
            msg=sysmsg();
            put msg;
        end;

        rc = dclose(did);
        rc = filename("mydir");
    run;
%mend;

%readdir(indir=C:\test, outdsn=out)

Monday, July 5, 2010

Quick tip: %EVAL

Essentially, the value of all macro variables is character string.

Sometimes, we do need that macro variable has only numeric value.
We can use %EVAL to judge if the string is numeric value.


* Sample;
%let mv=1+a;

%let a=%eval(%scan(&mv, 1, +));
%let b=%eval(%scan(&mv, 2, +)); * Error occurs;

Wednesday, April 21, 2010

Re: Resolve a macro variable within single quotes

Frankly, it is a dup with new SAS sample code at http://support.sas.com/kb/25/076.html.
However, the sample looks not good. It seems that the author do not know exactly the macro quoting functions (%str, %nrbquote, and etc.).

With the code at below, the reader can get the meaning of macro quoting better.

%let name=Fred;

/* resolve the MV at compilation time */
%put %str(%'&name%');

/* resolve the MV at execution time */
/* Please use %nrbquote or %bquote, NOT %quote. */
%put %unquote(%nrbquote('&a'));

Monday, November 16, 2009

Logical expression play differently between %eval and DATA step

When programming macro, It is helpful to complete it in a DATA step and then port the code to macro. However, not all tricks in DATA step work in macro world.

Below is one tip for that:

data _null_;
do a=1 to 4;
if 1 < a < 3 then put a= "is between 1 and 3";
end;
run;

%macro test();
%put Wrong example:;
%do a=1 %to 4;
%if %eval(1 < &a < 3) %then
%put a=&a is between 1 and 3;
%end;

%put Correct example:;
%do a=1 %to 4;
%if %eval(1 < &a and &a < 3) %then
%put a=&a is between 1 and 3;
%end;
%mend;

%test()

Wednesday, July 1, 2009

%LOCAL secrete

When programming, we always put the %LOCAL and %GLOBAL statement at the top of macro definition.

Why?
In this way, we can guarant that same LOCAL/GLOBAL mv is always in effect in macro execution. If %LOCAL is in the middle, the global mv is probably in use.


*%LOCAL secrete sample;
%let test = global;
%macro test();
%put Before %nrstr(%local): "&test";

%local test;
%put After %nrstr(%local): "&test";
%mend;

%test()

Sunday, June 21, 2009

How to position the macro problem at runtime

Macro programming is error-prone. It is easy to debug the Macro compile error.
However, it is not intuitive to debug Macro runtime error since we can not get correct postion information from SAS log.

For example:

%macro test;
data a;
a=1;
b="1";
if a=b then put "Here!";
run;
%mend;

%test

SAS log:
NOTE: Character values have been converted to numeric values at the places given by: (Line):(Column).
1:51
Although SAS log give out the postion "1:51", we can not trace the issue in Macro.

Here is one key to the issue. We can save the Macro output as SAS program, position the issue in SAS program and track back to Macro.
Please see the sample code at below:


filename mprint temp;
options mprint mfile;

%test

%include mprint / source2;
options nomprint nomfile;
filename mprint clear;

Sunday, March 1, 2009

macro invocation to CALL routines

In macro world, we have to use %sysfunc to call SAS functions.
Accordingly, %syscall is the door to SAS CALL routines.

%let pattern = %sysfunc(prxparse(/test/i));
%let rc = %sysfunc(prxmatch(&pattern, %str(this is a test)));
%syscall prxfree(pattern);

Wednesday, January 21, 2009

a special function for %sysfunc world: filename function

Below are the code from SAS online doc:
%let filrf=myfile;
%let rc=%sysfunc(filename(filrf, physical-filename));
%if &rc ne 0 %then
%put %sysfunc(sysmsg());
%let rc=%sysfunc(filename(filrf));

It should be noted that the fileref is "myfile", not "filerf". That means the macro variable "filerf" contains the ACTUAL fileref.
When the macro variable does not exist, the system generates a fileref automatically.

It seems that it is unique to filename function.
For now, I have not found any other functions which can take the similar behavior.

Note that it will not work if the fileref has been assigned. For more information, please see http://support.sas.com/kb/6/567.html

Thursday, January 15, 2009

macro autocall

Here are sample codes for macro autocall.
Personally, I perfer "fileref" type because it is flexible.

/* fileref */
filename utility catalog "lib.catalog";
*filename utility "c:\utility";
options mautosource mrecall sasautos=(sasautos utility);

/* libref */
libname utility "c:\utility";
options mautosource mrecall sasautos=(sasautos utility);

/* host-specific path;*/
options mautosource mrecall sasautos=(sasautos "c:\utility");